3

I would like to know if it would be somehow possible to handle a Serial.println() on an Arduino uno without holding up the main program.

Basically, I'm using the arduino to charge a 400V capacitor and the main program is opening and closing the gate on a MOSFET transistor for 15 and 20 microseconds respectively. I also have a voltage divider connected to the capacitor which I use to measure the voltage on the capacitor when its being charged with the Arduino. I use analogRead() to get the raw value on the pin, multiply the value by the required ratio and try to print that value to the serial console at the end of each cycle. The problem is, though, that in order for the capacitor to charge quickly, the delays need to be very small (in the range of microseconds) and the serial print command takes much longer than that to execute and therefore holds up the entire program.

My question therefore is wherther it would somehow be possible to get the command to execute on something like a different "thread" without holding up the main cycle. Is the 8bit AVR capable of doing something like this?

Thanks

dsolimano
  • 8,870
  • 3
  • 48
  • 63
user3066060
  • 120
  • 1
  • 2
  • 8

3 Answers3

2

Arduino does not support multithreading, but there are a few libraries that allow you to do the equivalent:

For more information, you can also visit this question: Does Arduino support threading?

Community
  • 1
  • 1
The Guy with The Hat
  • 10,836
  • 8
  • 57
  • 75
2

The basic Arduino serial print functions are blocking, They watch the TX Ready flag then load the next byte to transmit. This means if you send "Hello World" the print function will block for as long as it take to load the UART to send 10 characters at your selected baud rate.

One way to deal with this is using high baud rate so you don't wait long.

The better way is to use interrupt driven transmit. This way your string of data to send is buffered with each character sent when the UART can accept the character. The call to send data just loads the TX buffer, loads the first character into the UART to start the process then returns.

This bufferd approach will still block if you fill the TX buffer. The send method would have to wait to load more into the buffer. A good serial lib might give you an easy way to check the buffer status so you could implement your own extra buffering.

Here is a library that claims to be interrupt driven. I've not used it myself. Let us know if it works for you. https://code.google.com/p/arduino-buffered-serial/

dfowler7437
  • 461
  • 2
  • 9
  • 4
    per the release notes. This should be the case in the core library since IDE release 1.0.+ .. "Serial transmission is now asynchronous - that is, calls to Serial.print(), etc. add data to an outgoing buffer which is transmitted in the background." – mpflaga Jan 05 '14 at 01:14
  • I am glad to see that change. So Serial.print() will not block unless you fill the send buffer. – dfowler7437 Jan 06 '14 at 02:28
  • Yes, exactly. So don't disable all interrupts just after serial.print or in the above case send too much. I recall that there may be a way to poll the remaining available, etc.. but that is beyond this question. – mpflaga Jan 06 '14 at 04:09
0

I found this post: Serial output is now interrupt driven. Serial.print() just stuffs the data in a buffer. Interrupts have to happen for that data to actually be shifted out. posted: Nov 11, 2012. I have found that to be true BUT if you try to print more then the internal serial buffer will hold it will lock up until the buffer is at least partially emptied.

Gil
  • 126
  • 2