Go Down

Topic: Reading from Serial1 requires that I write to Serial. Solved (Read 1 time) previous topic - next topic

raacampbell

#15
Aug 16, 2013, 08:26 pm Last Edit: Aug 16, 2013, 08:32 pm by raacampbell Reason: 1
Ah, yes, it's not behaving as I thought it was. So basically you're saying that my while loop executes faster than the characters can come into the Serial port. Makes sense now that you say it! I think you've told me enough for me to now get rid of the delay. Thanks!

James C4S


So basically you're saying that my while loop executes faster than the characters can come into the Serial port.

Exactly.
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Nick Gammon

http://www.gammon.com.au/serial





Could you just explain one thing?

Why make a program so big it can't be posted that includes parts you do not have working, practiced understanding of?


I often wonder that, however I suspect that in many cases people copy large chunks of code from other examples, and bang them together. This will tend to lead to this effect. The smaller batches work on their own, but the large conglomerate doesn't.

In principle I totally agree with you, GoForSmoke. Let's say I am making a temperature sensor that reads the temperature and shows it on some LEDs, I will always test the sensor (via serial prints), the LEDs (with dummy data), and then once I am sure the "black boxes" work on their own, start connecting them together.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Delta_G

#18
Aug 16, 2013, 11:11 pm Last Edit: Aug 16, 2013, 11:15 pm by Delta_G Reason: 1


No, the delay() isn't necessary.  Waiting until a character is available is...

Instead you could call:
while(Serial1.avaialble() == 0 ); // this will block until the next character arrives.


Thanks, I can see how that should be the more elegant solution. I assume you mean me to replace the delay with the blocking while? Oddly, however, this doesn't work properly. If you're interested here's what I see: I send to Serial1 the message: "m12345" and see if it is read correctly using the code above, except that I modify doM() and test the delay vs the while by commenting out the lines as appropriate.

Code: [Select]

void doM(){
//while(Serial1.available() == 0 ){}//block until char arrives
delay(1);

while (Serial1.available()){
  char ch=Serial1.read();
  Serial.print(ch);
}
}


With only the delay uncommented (as shown above) I see the string "12345" displayed on the terminal listening to Serial. So that's correct. However, with only the while uncommented, I get back only the character "1". I don't understand why this would be. Whilst the 1ms delay feels like a hack, I think I will stick to it for now because it behaves as I expect and has no negative consequences. It would be nice to know why your solution isn't working for me. Probably I'm doing something silly: I've been programming for a good while but I'm new to C, mics, and a lot of this hardware stuff.



Go back and look at this and the post before it.  Notice the difference in the while statements?  You have the serial read inside the while loop, and that loop stops going as soon as the character arrives.  You've said, keep reading this character until it actually gets here, then ignore it and move on.  What you want to say is, hang up on this line until the serial character gets here, then move on to reading it.    See next post.

In the example in the post before the statement is:

Code: [Select]

while(Serial.available == 0);
char c = Serial.read();
Serial.println(c);


In this example, notice that there is a semicolon behind the while statement and the serial stuff isn't in curly braces.  This while loop says, while Serial.available == 0 do nothing and keeps doing nothing over and over again until that character arrives.

Notice

Delta_G

Ooops, read that first code wrong.  The code the OP wrote doesn't say keep reading until it gets there, it says keep reading as long as something is there. 

In this case, if the thing isn't there right at the beginning, then the while loop never gets executed because the condition fails the first time.  Leaves you in the same boat as if you hadn't changed anything.

GoForSmoke


http://www.gammon.com.au/serial





Could you just explain one thing?

Why make a program so big it can't be posted that includes parts you do not have working, practiced understanding of?


I often wonder that, however I suspect that in many cases people copy large chunks of code from other examples, and bang them together. This will tend to lead to this effect. The smaller batches work on their own, but the large conglomerate doesn't.

In principle I totally agree with you, GoForSmoke. Let's say I am making a temperature sensor that reads the temperature and shows it on some LEDs, I will always test the sensor (via serial prints), the LEDs (with dummy data), and then once I am sure the "black boxes" work on their own, start connecting them together.


Or is using strtok() for the first time I actually used strtok() in small code then twisted and bent the example to see how it broke... and finally rolled my own routine that did what I needed.
Not that I have anything against strtok() or atoi(). Or especially in almost all languages I've written, in the standard input routines. It's just that once I got a few years into coding I wanted and needed better is all. As a result my stuff read keys and didn't wait for complete entry to flag errors or find match words when possible. I find that easier and faster than a bunch of buffered text manipulation. To be honest though I did put in a good bit of thought and work getting the first drafts right, it runs counter to top-down thinking.
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Nick Gammon

You shouldn't need to delay, and you shouldn't need to "block". Read this:

http://www.gammon.com.au/serial
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

raacampbell


You shouldn't need to delay, and you shouldn't need to "block". Read this:

http://www.gammon.com.au/serial


Thanks, yes, now that I've understood what James was saying I've re-written my code in a way that removes the blocking and just reads until it hits the terminator. I think that's basically what's in the your link, too.

Go Up