Hi at all,
I have begun to work with file SHCustomProtocol.h.
My problem is this if add function delay at code and compiled, there isn't error of compilation but the board is unrecognized.
If I comment the function the board is recognized.
My code is:
void loop() {
int valSHGiriMotore = rpm;
//FlowSerialDebugPrintLn("valSH RPM : " + String(valSHGiriMotore));
valGiriMotore = map(valSHGiriMotore, 0, 3000, 0, 180);
//FlowSerialDebugPrintLn("val servo : " + String(valGiriMotore));
analogWrite(pinGiriMotore, valGiriMotore);
delay(1000);
}
Any idea?
Thanks
Best regards
Claudio
Hi !
Indeed delay is totally forbidden, you have the general rules in the top of the SHCustomProtocol.h file :
GENERAL RULES :
- ALWAYS BACKUP THIS FILE, reinstalling/updating SimHub would overwrite it with the default version.
- Read data AS FAST AS POSSIBLE in the read function
- NEVER block the arduino (using delay for instance)
- Make sure the data read in "read()" function READS ALL THE DATA from the serial port matching the custom protocol definition
- Idle function is called hundreds of times per second, never use it for slow code, arduino performances would fall
- If you use library suspending interrupts make sure to use it only in the "read" function when ALL data has been read from the serial port.
It is the only interrupt safe place
Hi,
Thanks
If I understand the Delay function correctly, I only have to put it inside the read function once I have read all the data I need, right?
Best regards
Claudio
@thundertrucks Is not that you should only set delay inside the read function once you have read all the data. You should never use delay, never at all.
Delay forces the microcontroller to stop processing, not only the current function but all the program itself. Only interrupts will be considered while delay is being processed.
So, coding a delay of 1 second inside the main loop (that is going to be processed more than once every milisecond) is basically the same as blocking your arduino 100% of the cycles.
It's not something you should have in mind when coding SimHub custom protocol, it's a general rule of any kind of AVR programming and basically all kinds of micro controller programs.
The way to achieve similar behavior without blocking the process line is to read the current time and save it to a variable. In the following cycles you check if the difference between the stored time and the current time is greater than that delay value you want to wait, and only if it is greater, you execute the functions again and store the current time again to "reset the counter".
So, your code above:
void loop() {
int valSHGiriMotore = rpm;
valGiriMotore = map(valSHGiriMotore, 0, 3000, 0, 180);
analogWrite(pinGiriMotore, valGiriMotore);
delay(1000);
}
Would look like this:
unsigned long lastTime;
void loop() {
if (millis() - lastTime > 1000) {
int valSHGiriMotore = rpm;
valGiriMotore = map(valSHGiriMotore, 0, 3000, 0, 180);
analogWrite(pinGiriMotore, valGiriMotore);
lastTime = millis();
}
}
It's not optimized to avoid multiple readings of millis() nor oriented to OOP inside a class... but you can see the concept.
Cheers
@thundertrucks fnf Is not that you should only set delay inside the read function once you have read all the data. You should never use delay, never at all.
Delay forces the microcontroller to stop processing, not only the current function but all the program itself. Only interrupts will be considered while delay is being processed.
So, coding a delay of 1 second inside the main loop (that is going to be processed more than once every milisecond) is basically the same as blocking your arduino 100% of the cycles.It's not something you should have in mind when coding SimHub custom protocol, it's a general rule of any kind of AVR programming and basically all kinds of micro controller programs.
The way to achieve similar behavior without blocking the process line is to read the current time and save it to a variable. In the following cycles you check if the difference between the stored time and the current time is greater than that delay value you want to wait, and only if it is greater, you execute the functions again and store the current time again to "reset the counter".
So, your code above:
void loop() {
int valSHGiriMotore = rpm;
valGiriMotore = map(valSHGiriMotore, 0, 3000, 0, 180);
analogWrite(pinGiriMotore, valGiriMotore);
delay(1000);
}Would look like this:
unsigned long lastTime;
void loop() {
if (millis() - lastTime > 1000) {
int valSHGiriMotore = rpm;
valGiriMotore = map(valSHGiriMotore, 0, 3000, 0, 180);
analogWrite(pinGiriMotore, valGiriMotore);
lastTime = millis();
}
}It's not optimized to avoid multiple readings of millis() nor oriented to OOP inside a class... but you can see the concept.
Cheers
Thank you for the further explanation of these.