I would like to know how can we calculate the software acceptance filter mask for some set of standard CAN id.It would be great if some one can explain this with example.
And also please suggest some links/materials to learn the CAN stack software implementation.
Thanks in advance.
Let me explain this with an example:
Suppose the user wants to receive the messages only with IDs 0x8Z (where Z = 1,3,5,7) then here is how the value of Mask register and Acceptance register can be calculated:
0x81 = 1000 0001
0x83 = 1000 0011
0x85 = 1000 0101
0x87 = 1000 0111
Mask Register = 1111 1001
First compare the 0th bits of all the IDs, if its same then the corresponding bit for mask register will be "1" else it will be "0". Then compare the 1st bits, then 2nd bits and so on...
In our case only the 5th and 6th bits differ in all the IDs. This explains how we got "Mask Register" value.
For Acceptance register value, take any of the allowed message IDs and that will be the value of the Acceptance register value. In our case it could be 0x81 or 0x83 or 0x85 or 0x87
While programming it can be checked like this:
if((Incoming_ID && Mask_Register) == (Incoming_ID && Acceptance_Register))
{
//Receive Message
}
else
{
//Discard Message
}
Hope it helps.
Since this filtering is done in hardware it is fairly primitive. Usually the calculation involves two registers a mask and a filter. The equivalent logic in C would be:
/* dsPIC style; mask specifies "do care" bits */
if ((arbitrationId & mask) == filter) {
/* Message accepted; rx interrupt triggered */
}
/* Accept all */
mask = 0;
filter = 0;
/* Accept CANopen default connection set (excluding SYNC and NMT) */
mask = 0x7F;
filter = node_id;
Or
/* SJA 1000 style; mask specifies "do not care" bits */
if ((arbitrationId & ~mask) == filter) {
/* Message accepted; rx interrupt triggered */
}
/* Accept all */
mask = ~0;
filter = 0;
/* Accept CANopen default connection set (excluding SYNC and NMT) */
mask = ~0x7F;
filter = node_id;
The number of masks, the number of filters, if and how the filters are enabled, and the arrangement of ID bits within registers is all hardware dependent. To give you a more concrete answer would require details about the specific hardware being used.
Basic information on CANbus can be found here:
The repository of all human knowledge
Microcontroller.com tutorial
Related
I’m trying to make a basic simulation of a 16 bit computer with Swift. The computer will feature
An ALU
2 registers
That’s all. I have enough knowledge to create these parts visually and understand how they work, but it has become increasingly difficult to make larger components with more inputs while using my current approach.
My current approach has been to wrap each component in a struct. This worked early on, but is becoming increasingly difficult to manage multiple inputs while staying true to the principles of computer science.
The primary issue is that the components aren’t updating with the clock signal. I have the output of the component updating when get is called on the output variable, c. This, however, neglects the idea of a clock signal and will likely cause further problems later on.
It’s also difficult to make getters and setters for each variable without getting errors about mutability. Although I have worked through these errors, they are annoying and slow down the development process.
The last big issue is updating the output. The output doesn’t update when the inputs change; it updates when told to do so. This isn’t accurate to the qualities of real computers and is a fundamental error.
This is an example. It is the ALU I mentioned earlier. It takes two 16 bit inputs and outputs 16 bits. It has two unary ALUs, which can make a 16 bit number zero, negate it, or both. Lastly, it either adds or does a bit wise and comparison based on the f flag and inverts the output if the no flag is selected.
struct ALU {
//Operations are done in the order listed. For example, if zx and nx are 1, it first makes input 1 zero and then inverts it.
var x : [Int] //Input 1
var y : [Int] //Input 2
var zx : Int //Make input 1 zero
var zy : Int //Make input 2 zero
var nx : Int //Invert input 1
var ny : Int //Invert input 2
var f : Int //If 0, do a bitwise AND operation. If 1, add the inputs
var no : Int //Invert the output
public var c : [Int] { //Output
get {
//Numbers first go through unary ALUs. These can negate the input (and output the value), return 0, or return the inverse of 0. They then undergo the operation specified by f, either addition or a bitwise and operation, and are negated if n is 1.
var ux = UnaryALU(z: zx, n: nx, x: x).c //Unary ALU. See comments for more
var uy = UnaryALU(z: zy, n: ny, x: y).c
var fd = select16(s: f, d1: Add16(a: ux, b: uy).c, d0: and16(a: ux, b: uy).c).c //Adds a 16 bit number or does a bitwise and operation. For more on select16, see the line below.
var out = select16(s: no, d1: not16(a: fd).c, d0: fd).c //Selects a number. If s is 1, it returns d1. If s is 0, it returns d0. d0 is the value returned by fd, while d1 is the inverse.
return out
}
}
public init(x:[Int],y:[Int],zx:Int,zy:Int,nx:Int,ny:Int,f:Int,no:Int) {
self.x = x
self.y = y
self.zx = zx
self.zy = zy
self.nx = nx
self.ny = ny
self.f = f
self.no = no
}
}
I use c for the output variable, store values with multiple bits in Int arrays, and store single bits in Int values.
I’m doing this on Swift Playgrounds 3.0 with Swift 5.0 on a 6th generation iPad. I’m storing each component or set of components in a separate file in a module, which is why some variables and all structs are marked public. I would greatly appreciate any help. Thanks in advance.
So, I’ve completely redone my approach and have found a way to bypass the issues I was facing. What I’ve done is make what I call “tracker variables” for each input. When get is called for each variable, it returns that value of the tracker assigned to it. When set is called it calls an update() function that updates the output of the circuit. It also updates the value of the tracker. This essentially creates a ‘copy’ of each variable. I did this to prevent any infinite loops.
Trackers are unfortunately necessary here. I’ll demonstrate why
var variable : Type {
get {
return variable //Calls the getter again, resulting in an infinite loop
}
set {
//Do something
}
}
In order to make a setter, Swift requires a getter to be made as well. In this example, calling variable simply calls get again, resulting in a never-ending cascade of calls to get. Tracker variables are a workaround that use minimal extra code.
Using an update method makes sure the output responds to a change in any input. This also works with a clock signal, due to the architecture of the components themselves. Although it appears to act as the clock, it does not.
For example, in data flip-flops, the clock signal is passed into gates. All a clock signal does is deactivate a component when the signal is off. So, I can implement that within update() while remaining faithful to reality.
Here’s an example of a half adder. Note that the tracker variables I mentioned are marked by an underscore in front of their name. It has two inputs, x and y, which are 1 bit each. It also has two outputs, high and low, also known as carry and sum. The outputs are also one bit.
struct halfAdder {
private var _x : Bool //Tracker for x
public var x: Bool { //Input 1
get {
return _x //Return the tracker’s value
}
set {
_x = x //Set the tracker to x
update() //Update the output
}
}
private var _y : Bool //Tracker for y
public var y: Bool { //Input 2
get {
return _y
}
set {
_y = y
update()
}
}
public var high : Bool //High output, or ‘carry’
public var low : Bool //Low output, or ‘sum’
internal mutating func update(){ //Updates the output
high = x && y //AND gate, sets the high output
low = (x || y) && !(x && y) //XOR gate, sets the low output
}
public init(x:Bool, y:Bool){ //Initializer
self.high = false //This will change when the variables are set, ensuring a correct output.
self.low = false //See above
self._x = x //Setting trackers and variables
self._y = y
self.x = x
self.y = y
}
}
This is a very clean way, save for the trackers, do accomplish this task. It can trivially be expanded to fit any number of bits by using arrays of Bool instead of a single value. It respects the clock signal, updates the output when the inputs change, and is very similar to real computers.
I want to "translate" a Pine-Script to MQL4 but I get the wrong output in MQL4 compared to the Pine-Script in Trading-view.
I wrote the Indicator in Pine-Script since it seems fairly easy to do so.
After I got the result that I was looking for I shortened the Pine-Script.
Here the working Pine-Script:
// Pinescript - whole Code to recreate the Indicator
study( "Volume RSI", shorttitle = "VoRSI" )
periode = input( 3, title = "Periode", minval = 1 )
VoRSI = rsi( volume, periode )
plot( VoRSI, color = #000000, linewidth = 2 )
Now I want to translate that code to MQL4 but I keep getting different outputs.
Here is the MQL4 code I wrote so far:
// MQL4 Code
input int InpRSIPeriod = 3; // RSI Period
double sumn = 0.0;
double sump = 0.0;
double VoRSI = 0.0;
int i = 0;
void OnTick() {
for ( i; i < InpRSIPeriod; i++ ) {
// Check if the Volume is buy or sell
double close = iClose( Symbol(), 0, i );
double old_close = iClose( Symbol(), 0, i + 1 );
if ( close - old_close < 0 )
{
// If the Volume is positive, add it up to the positive sum "sump"
sump = sump + iVolume( Symbol(), 0, i + 1 );
}
else
{
// If the Volume is negative, add it up to the negative sum "sumn"
sumn = sumn + iVolume( Symbol(), 0, i + 1 );
}
}
// Get the MA of the sump and sumn for the Input Period
double Volume_p = sump / InpRSIPeriod;
double Volume_n = sumn / InpRSIPeriod;
// Calculate the RSI for the Volume
VoRSI = 100 - 100 / ( 1 + Volume_p / Volume_n );
// Print Volume RSI for comparison with Tradingview
Print( VoRSI );
// Reset the Variables for the next "OnTick" Event
i = 0;
sumn = 0;
sump = 0;
}
I already checked if the Period, Symbol and timeframe are the same and also have a Screenshoot of the different outputs.
I already tried to follow the function-explanations in the pine-script for the rsi, max, rma and sma function but I cant get any results that seem to be halfway running.
I expect to translate the Pine-Script into MQL4.
I do not want to draw the whole Volume RSI as a Indicator in the Chart.
I just want to calculate the value of the Volume RSI of the last whole periode (when new candel opens) to check if it reaches higher than 80.
After that I want to check when it comes back below 80 again and use that as a threshold wether a trade should be opened or not.
I want a simple function that gets the Period as an input and takes the current pair and Timeframe to return the desired value between 0 and 100.
Up to now my translation persists to provide the wrong output value.
What am I missing in the Calculation? Can someone tell me what is the right way to calculate my Tradingview-Indicator with MQL4?
Q : Can someone tell me what is the right way to calculate my Tradingview-Indicator with MQL4?
Your main miss of the target is in putting the code into a wrong type of MQL4-code. MetaTrader Terminal can place an indicator via a Custom Indicator-type of MQL4-code.
There you have to declare so called IndicatorBuffer(s), that contain pre-computed values of the said indicator and these buffers are separately mapped onto indicator-lines ( depending on the type of the GUI-presentation style - lines, area-between-lines, etc ).
In case you insist on having a Custom-Indicator-less indicator, which is pretty legal and needed in some use-cases, than you need to implement you own "mechanisation" of drawing lines into a separate sub-window of the GUI in the Expert-Advisor-code, where you will manage all the settings and plotting "manually" as you wish, segment by segment ( we use this for many reasons during prototyping, so as to avoid all the Custom-Indicator dependencies and calling-interface gritty-nitties during the complex trading exosystem integration - so pretty well sure about doability and performance benefits & costs of going this way ).
The decision is yours, MQL4 can do it either way.
Q : What am I missing in the Calculation?
BONUS PART : A hidden gem for improving The Performance ...
In either way of going via Custom-Indicator-type-of-MQL4-code or an Expert-Advisor-type-of-MQL4-code a decision it is possible to avoid a per-QUOTE-arrival re-calculation of the whole "depth" of the RSI. There is a frozen-part and a one, hot-end of the indicator line and performance-wise it is more than wise to keep static records of "old" and frozen data and just update the "live"-hot-end of the indicator-line. That saves a lot of the response-latency your GUI consumes from any real-time response-loop...
I am writing an MQL4 Custom Indicator that would tell how many bars ago a particular set of moving averages crossed.
To be specific, I want the output to show me that
"The 20 period MA( .. PRICE_OPEN ) is below MA( .. PRICE_CLOSE ) for the past 10 bars".
in a form of an int number.
double ma1 = iMA( Symbol(), 10080, 20, 0, 0, PRICE_OPEN, 0 );
double ma2 = iMA( Symbol(), 10080, 20, 0, 0, PRICE_CLOSE, 0 );
I want to find out that ma1 has been above or below ma2 for how many bars since the current bar.
TLDR;
MQL4 Custom Indicator design is a bit schizophrenic task with 2 parts
Once decided to design a Custom Indicator, one has to pay attention to both sides of the coin.
MQL4 code has a non-trivial signature for a caller-side( normally an
Expert Advisor or a Script type of MQL4 code )and
Custom Indicator, on it's own, operates in a special mode, where it calculates & store it's values into one or more arrays called IndexBuffer-s.
Phase I.: design Caller-side interface ( what all do we need to set / receive ? )
Phase II.: design Custom Indicator implementation side
This way, the given indicator shall
set just one parameter: a period ... 20
receive just one int a value of days { +:above | 0: xoss | -: under }
Phase I. : Design Caller-side interface
Given the above parametrisation and the MQL4 concept of Custom Indicator construction, the following universal template ( recommended to be routinely maintained as a commented section right in CustomIndicator-file ) reflects details needed for the Caller-side interface ( which one benefits from by just a copy-paste mechanics, while the implementation-integrity responsibility is born by the CustomIndicator maintainer ):
// CALL-er SIDE INTERFACE |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//
// #define sIndicatorPathNAME "#AliceInTheWonderlands_msMOD_0.00"
//
// //_____________________________________INPUT(s)
// // iMA_PERIOD:
// extern int iMA_PERIOD = 20;
//
// //_____________________________________OUTPUT(s):
// #define iOutputDoubleUpOrDnBUFFER 0
//
// //_____________________________________CALL-SIGNATURE:
//
// double iCustom( _Symbol, // string symbol, // symbol: Symbol name on the data of which the indicator will be calculated. NULL means the current symbol.
// PERIOD_W1, // int timeframe, // timeframe
// sIndicatorPathNAME, // string name, // path/name of the custom indicator compiled program: Custom indicator compiled program name, relative to the root indicators directory (MQL4/Indicators/). If the indicator is located in subdirectory, for example, in MQL4/Indicators/Examples, its name must be specified as "Examples\\indicator_name" (double backslash "\\"must be specified as separator instead of a single one).
// iMA_PERIOD, // ...[1] ..., // custom indicator [1]-st input parameter
// <<N/A>>, // ...[2+] // custom indicator further input parameters (if necessary)
// iOutputDoubleUpOrDnBUFFER, // int mode, // line index: Line index. Can be from 0 to 7 and must correspond with the index, specified in call of the SetIndexBuffer() function.
// i // int bar_shift // shift
// );
// ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Typical Expert Advisor call looks like this:
int anIndicatorVALUE = iCustom( _Symbol,
PERIOD_W1,
sIndicatorPathNAME,
iMA_PERIOD,
iOutputDoubleUpOrDnBUFFER,
aCurrentBarPTR
);
if ( 0 > anIndicatorVALUE ) // on "line" under for <anIndicatorVALUE> [PERIOD]-s
{ ...
}
Phase II. : Design Custom Indicator implementation side
Preset an overall capacity
#property indicator_buffers 1 // compile time directive
Allocate memory for IndexBuffer(s) needed
IndicatorBuffers( 1 ); // upper limit of 512 is "far" enough
Declare IndexBuffer
double UpOrDnBUFFER[]; // mandatory to be a double
Associate IndexBuffer with an index
SetIndexBuffer( 0, UpOrDnBUFFER ); // index 0: UpOrDnBUFFER[]
ArraySetAsSeries( UpOrDnBUFFER, True ); // reverse AFTER association
The core logic of any Custom Indicator is inside an OnCalculate() function, where you
- implement desired calculusand- store resulting values into respective cells of the UpOrDnBUFFER[];
Writing a fully fledged code upon request is not the key objective of StackOverflow, but let me sketch a few notes on this, as Custom Indicator implementation side requires a bit practice:
because Custom Indicator OnCalculate() operates "progressively", so do design your calculation strategy & keep in mind the state-less-ness between "blocks" of forward-progressive blocks of calculations.
as given, crosses are tri-state system, so watch issues on cases, where decisions are made on a "live" bar, where the state { above | cross | under } may change many times during the bar-evolution.
I'm working on an audio visualizer in C with OpenGL, Libsamplerate, portaudio, and libsndfile. I'm having difficulty using src_process correctly within my whole paradigm. My goal is to use src_process to achieve Vinyl Like varispeed in real time within the visualizer. Right now my implementation changes the pitch of the audio without changing the speed. It does so with lots of distortion due to what sounds like missing frames as when I lower the speed with the src_ratio it almost sounds granular like chopped up samples. Any help would be appreciated, I keep experimenting with my buffering chunks however 9 times out of 10 I get a libsamplerate error saying my input and output arrays are overlapping. I've also been looking at the speed change example that came with libsamplerate and I can't find where I went wrong. Any help would be appreciated.
Here's the code I believe is relevant. Thanks and let me know if I can be more specific, this semester was my first experience in C and programming.
#define FRAMES_PER_BUFFER 1024
#define ITEMS_PER_BUFFER (FRAMES_PER_BUFFER * 2)
float src_inBuffer[ITEMS_PER_BUFFER];
float src_outBuffer[ITEMS_PER_BUFFER];
void initialize_SRC_DATA()
{
data.src_ratio = 1; //Sets Default Playback Speed
/*---------------*/
data.src_data.data_in = data.src_inBuffer; //Point to SRC inBuffer
data.src_data.data_out = data.src_outBuffer; //Point to SRC OutBuffer
data.src_data.input_frames = 0; //Start with Zero to Force Load
data.src_data.output_frames = ITEMS_PER_BUFFER
/ data.sfinfo1.channels; //Number of Frames to Write Out
data.src_data.src_ratio = data.src_ratio; //Sets Default Playback Speed
}
/* Open audio stream */
err = Pa_OpenStream( &g_stream,
NULL,
&outputParameters,
data.sfinfo1.samplerate,
FRAMES_PER_BUFFER,
paNoFlag,
paCallback,
&data );
/* Read FramesPerBuffer Amount of Data from inFile into buffer[] */
numberOfFrames = sf_readf_float(data->inFile, data->src_inBuffer, framesPerBuffer);
/* Looping of inFile if EOF is Reached */
if (numberOfFrames < framesPerBuffer)
{
sf_seek(data->inFile, 0, SEEK_SET);
numberOfFrames = sf_readf_float(data->inFile,
data->src_inBuffer+(numberOfFrames*data->sfinfo1.channels),
framesPerBuffer-numberOfFrames);
}
/* Inform SRC Data How Many Input Frames To Process */
data->src_data.end_of_input = 0;
data->src_data.input_frames = numberOfFrames;
/* Perform SRC Modulation, Processed Samples are in src_outBuffer[] */
if ((data->src_error = src_process (data->src_state, &data->src_data))) {
printf ("\nError : %s\n\n", src_strerror (data->src_error)) ;
exit (1);
}
* Write Processed SRC Data to Audio Out and Visual Out */
for (i = 0; i < framesPerBuffer * data->sfinfo1.channels; i++)
{
// gl_audioBuffer[i] = data->src_outBuffer[i] * data->amplitude;
out[i] = data->src_outBuffer[i] * data->amplitude;
}
I figured out a solution that works well enough for me and am just going to explain it best I can for anyone else with a similar issue. So to get the Varispeed to work, the way the API works is you give it a certain number of frames, and it spits out a certain number of frames. So for a SRC ratio of 0.5, if you process 512 frames per loop you are feeding in 512/0.5 frames = 1024 frames. That way when the API runs its src_process function, it compresses those 1024 frames into 512, speeding up the samples. So I dont fully understand why it solved my issue, but the problem was if the ratio is say 0.7, you end up with a float number which doesn't work with the arrays indexed int values. Therefore there's missing samples unless the src ratio is eqaully divisble by the framesperbuffer potentially at the end of each block. So what I did was add +2 frames to be read if the framesperbuffer%src.ratio != 0 and it seemed to fix 99% of the glitches.
/* This if Statement Ensures Smooth VariSpeed Output */
if (fmod((double)framesPerBuffer, data->src_data.src_ratio) == 0)
{
numInFrames = framesPerBuffer;
}
else
numInFrames = (framesPerBuffer/data->src_data.src_ratio) + 2;
/* Read FramesPerBuffer Amount of Data from inFile into buffer[] */
numberOfFrames = sf_readf_float(data->inFile, data->src_inBuffer, numInFrames);
I currently have a setup where I send a char using a Tx of 434MHz and an Uno to a Mega with a Rx. The Mega counts how many times it receives the char and then if it falls below a certain number it triggers an alarm. Is this a viable way to measure the distance between two microcontrollers while indoors or is there a better way.
Transmitter (Mega)
#include <SoftwareSerial.h>
int rxPin=2; //Goes to the Receiver Pin
int txPin=5; //Make sure it is set to pin 5 going to input of receiver
SoftwareSerial txSerial = SoftwareSerial(rxPin, txPin);
SoftwareSerial rxSerial = SoftwareSerial(txPin, rxPin);
char sendChar ='H';
void setup() {
pinMode(rxPin, INPUT);
pinMode(txPin,OUTPUT);
txSerial.begin(2400);
rxSerial.begin(2400);
}
void loop() {
txSerial.println(sendChar);
Serial.print(sendChar);
}
Receiver
#include <SoftwareSerial.h>
//Make sure it is set to pin 5 going to the data input of the transmitter
int rxPin=5;
int txPin=3; //Don't need to make connections
int LED=13;
int BUZZ=9;
int t=0;
char incomingChar = 0;
int counter = 0;
SoftwareSerial rxSerial = SoftwareSerial(rxPin, txPin);
void setup() {
pinMode(rxPin, INPUT); //initilize rxpin as input
pinMode(BUZZ, OUTPUT); //initilize buzz for output
pinMode(LED, OUTPUT); //initilize led for output
rxSerial.begin(2400); //set baud rate for transmission
Serial.begin(2400); //see above
}
void loop() {
for(int i=0; i<200; i++) {
incomingChar = rxSerial.read(); //read incoming msg from tx
if (incomingChar =='H') {
counter++; //if we get bit "h" count it
}
delay(5); //delay of 10 secs
}
Serial.println(incomingChar);
Serial.println(counter); //prints the the bits we recieved
if(counter<55) {
//if we receive less than 100 bits than print out of range triggers alarm
Serial.println("out of range");
tone(BUZZ,5000,500);digitalWrite(LED,HIGH);
}
else {
noTone(BUZZ);digitalWrite(LED, LOW);
//if we get more than 100 bits than we are within range turn off alarm
Serial.println("in range");
}
counter = 0;
incomingChar=0;
}
In theory you could achieve distance measuring by making the uno send a message which the mega would echo back. That would give the uno a round-trip time for message propagation between the arduinos. You would have to approximate the processing delays. After that it is basic physics. That is basically the same as how radar works. The actual delay would be something like
troundtrip = tuno send + 2*tpropagation + tmega receive + tmega send + tuno receive
I am guessing the distance you are trying to achieve is in the order of meters. Required resolution is going to be an issue, because s = vt => t = s/v, where s is the distance between your arduinos and v = c in case of radio waves. As the transmission delays should stay constant, you have to be able to measure differences in the order of 1/c second intervals, basically. I am not very familiar with arduinos, so I do not know if they are capable of this kind of measurements.
I would suggest you use an ultrasonic range finder like the Maxbotix HRLV-EZ4 sold by Sparkfun.
It is within your price range and it should be able to measure distances up to 5m/195 inches with 1mm resolution.
It is actually possible to do it, I have seen it be done with other microcontrollers. Therefore using arduino you would have to solve the equations,fit in arduino language and make a lot of measurements to value discrepancies over communication itself. Do not forget about atmospheric attenuation wich need to be known and fit in the equations. Humidity may deviate electromagnetic waves.