PDA

View Full Version : delay (11); // It seems to need a delay here. When and Why ???



Tom_G_2010
12-03-2012, 01:42 PM
So, thanks to some great people here and some good online sources, I'm starting to get the hang of the scripting language for the Arduino. At least the basics. I'm part way through writing a sketch to control a few servo's and several annunciator panel LED's I've even managed to get an audible alarm with a timed silencer button to work. I'll post the sketch as soon as I get a few bugs worked out. I still need to add a few more annunciator lights and the OMI markers as well.

I've run into a question though that I have not been able to figure out looking at other sketches or reading doc's. If it's out there or on this forum I've managed to read right past it.

delay (11); // It seems to need a delay here. When and Why ???

I have had to add some delays because code was not working or was working intermittently, and doing so solved the issue at hand. But I only did so because I saw it done in other sketch examples. It seems that placing a delay in the correct place in the code allows more consistent execution, but I don't want just blindly pepper my sketch with unneeded delays, or spend hours of trial and error inserting them here or there if there's a more logical way to know where and when such delays are needed.

Any insights or clarification would be greatly appreciated!

zulucat
12-04-2012, 02:06 AM
Tom,

The reason for delay(11) is that Serial.read() is being used incorrectly. You should verify that a char is available for each one that you read. The code doesn't do this. Hence the need to delay an arbitrary amount of time for the data to arrive. I've included two examples. The first shows a snippit of code showing the current (incorrect) code. The 2nd piece of code shows a correct method for using Serial.read().



void loop()
{
if (Serial.available() > 0) { //if there is a charactor in the serial receive buffer then ,,,,
xx = Serial.read(); // read it.
if (xx == 'I'){ // Found the reading "Gear nose"
delay (11); // It seems to need a delay here
gearnose = ""; // Empty gearnose string
gearnose += char(Serial.read()); //Read the first charactor sent
gearnose += char(Serial.read()); //Read the second charactor sent and add it to the first
gearnose += char(Serial.read()); //Read the third charactor sent and add it to the other two.)

// ... remainder of code ...
}




void loop()
{
xx = getChar(); // read cmd char
if (xx == 'I'){ // Found the reading "Gear nose"
gearnose = ""; // Empty gearnose string
gearnose += getChar(); //Read the first charactor sent
gearnose += getChar(); //Read the second charactor sent and add it to the first
gearnose += getChar(); //Read the third charactor sent and add it to the other two.)

// ... remainder of code ...
}


char getChar()
{
while(Serial.available() == 0); // wait for data
return((char)Serial.read());
}


In the original code Serial.read() was being cast to a char. That's because it returns an int. That's not necessary in the 2nd example because getChar() does the casting and returns a char.

If you choose to convert to the 2nd method you can remove all delay() statements associated with using Serial.read().

BTW, Arduino code is written in the C programming language (not a scripting language). Arduino libraries are usually written in C++. This means that there are lots of books available that describe the language in detail should you want to know more about how the language works.

Doug -

Tom_G_2010
12-04-2012, 07:50 AM
Doug,

Thanks! I'm going to go through my code this evening and see if I can correct it to remove the delays.

Tom G.

Tom_G_2010
12-05-2012, 09:44 AM
Doug, it took a couple attempts, mostly because I'm thick headed, but using your getChar code example above I was able to eliminate all those delay statements. THANKS!

I'm now working on adding in the blinker while loops for my LEDs and other embellishments.

I had already coded a silencer or alarm acknowledge button to mute the audible alarm that is tripped with each annunciator and just had an epiphany over coffee this morning. I think I may try to condition the while loop for the blinking to stop the blinking and let the LED go steady when the acknowledge button is pressed . . . :idea:

zulucat
12-05-2012, 03:57 PM
Glad that you are up & running. Looking forward to seeing how all your hard work turns out!

Jim NZ
12-05-2012, 05:17 PM
Aaaah my innermost secret is out. !!! I make lousy Arduino code !!
It's actually not as bad as what it seems tho. When I decided to share what I was doing made me think of a "total newbie" attacking this with no knowledge at all of coding ,,, so my PDE's were made to read like a book ,,, from the top down with no loops or jumps ,, so hence the delays to make it work in the serial bit.

There is another "delay" that is self inflicked ,, and thats in the my code for LCD's ,,, EVERYONE else use 2 interrupts for LCD's but I changed the wiring to make it simpler (so all the wires were in one row) and this again bought in the need for a delay.

Once a "total newbie" gets something going then the sky's the limit on improvements from there. Obviously all code should be written avoiding "delays" but sometimes they are necessary.

Thanks for bringing this up Doug, and I'm amazed it's taken so long to surface ,, and Tom ,, take notice of what Doug says ,, he has years experience in this sort of stuff so he'll be a big help to you.
I'm actually looking forward to seeing more advanced PDE's than my "learner" ones.

Good luck with the journey Guys ,, Jim

Tom_G_2010
12-06-2012, 08:39 AM
Jim,

I was thinking about what you said and I think you're correct, as I get to understand how functions work this new setup makes sense, but when I first started I think it would have given me that head tilt expression you see with dogs so often.

I keep promising to post my new code, and I will, but it seems every evening I add that one more puzzle piece and decide it's not done yet, or worse, break it and have to do a bunch of debugging.

By the way, V3 is working great so far. Can't wait for V4!

Thanks!
Tom G.

AK Mongo
12-11-2012, 09:50 PM
I am trying to get my head around the proper way to use the serial read as you described zulucat. I have modified my vsi sketch per your example, but lack the ability to test it easily as my hardware is packed up for the moment. Would you take a look at it and see if there are glaring errors, or if I missed the point?



#include <Servo.h> //Add's the servo library
Servo vsi; // Names the servo
int j1; // Variable used by serial.read
String vertsp, vertspold; // variables used for vertical speed


void setup() // the set up loop
{
vsi.attach(9); // attaches the servo to pin 9
Serial.begin(115200); // sets up the serial port
}


void loop()
{
xx = getChar(); // read cmd char
if (xx == 'T'){ // Found the reading "Vertical Speed"
vertsp = ""; // Empty gearnose string
vertsp += getChar(); //Read the first charactor sent
vertsp += getChar(); //Read the second charactor sent and add it to the first
vertsp += getChar(); //Read the third charactor sent and add it to the other two.)
vertsp += getChar(); //4th character
vertsp += getChar(); //5th character
vertsp += getChar(); //6th character
if (vertsp != vertspold){ // checks to see if its different to the "old" reading
char carray[6]; //converting a string to number sequence
vertsp.toCharArray(carray, sizeof(carray)); //converting string to number sequence
int n = atoi(carray); //converting string to number sequence
n= n * 10; //Makes the reading more "sensitive"
n = map(n, -2000, 2000, 0, 179); //Maps the readings to the servo
vsi.write(n); //Sends the data to servo
delay (11); // Probably not neccesary
vertspold = vertsp; // Writes the current reading to the "old" string.
} // end of it's a different reading section
} // end of "found T" section
} // end of "if serial available" section
} // end of void loop ,,, it starts all over again



}




char getChar()
{
while(Serial.available() == 0); // wait for data
return((char)Serial.read());
}




Thanks,

Reid

zulucat
12-12-2012, 02:13 PM
...Would you take a look at it and see if there are glaring errors, or if I missed the point?
Nope. Your usage of getChar() looks fine. However, I did notice a few other problems.

Two of the problems you would have spotted as soon as you tried to compile (VERIFY) the sketch. You need to define "xx" before you use it and there are two too many closing braces ("}") at the end of loop().

The third problem involves carray[6] and vertsp.toCharArray() and is a bit more subtle. toCharArray() is taking the data stored in versp and placing that data into a C / C++ char array. A string in C / C++ is terminated by a NULL (0x00) char. That means that the array size to store 6 chars needs to be at least 7 chars long.

vertsp.toCharArray(), in an attempt to work, deletes one char at the end of the data in order to have room to store the NULL char. This in effect divides your value by 10! If you change carray[6] to carray[7] is should work properly. You can then delete the statement "n = n*10" because it's no longer needed.

Doug -

AK Mongo
12-12-2012, 02:33 PM
Doug,

Noob question, but what is an example of how I would define xx? Not sure about what it's function is....

Should I be referring back to j1?

Sorry if I seem dense, but I really am!

Thanks,

Reid

zulucat
12-12-2012, 02:59 PM
Noob question, but what is an example of how I would define xx? Not sure about what it's function is....

"xx" is used in loop() to store the cmd char. You need to define "xx" as a char.

--- Current Code ---



void loop()
{
xx = getChar(); // read cmd char
if (xx == 'T'){ // Found the reading "Vertical Speed"
// remainder of code
}


--- Revised Code ---



void loop()
{
char xx; // define xx

xx = getChar(); // read cmd char
if (xx == 'T'){ // Found the reading "Vertical Speed"
// remainder of code
}


Doug -