• TwitterFacebookGoogle PlusLinkedInRSS FeedEmail

Arduino Fast Serial Output

18.10.2019 

Updated Here we look at using serial communication on the Arduino. Serial UART is one of the various ways an Arduino can communicate with other devices.

  1. Arduino Serial Output To Excel
  2. Arduino No Serial Output

This includes a host PC and using the Arduino serial monitor is communicating with the PC using serial UART.If you are very new to Arduino try these simple examples to get you started. If you are already familiar with the serial monitor feel free to jump ahead.Arduino Serial MonitorThis is a basic example of displaying text in the serial monitor. Connect the Arduino to a PC, upload the following sketch, open the serial monitor and be amazed. // Add the SoftwareSerial library #include // Initiate an instance of the SoftwareSerial class.

Serial

This article describes my version of digital input/output functions for Arduino, which work faster than the 'built-in' functions while remaining as easy to use and portable as the original ones. If you just want to try the new functions, feel free to go directly to 'Using the code' section.

Requires the pin numbers used for RX and TX.SoftwareSerial swSerial ( 2, 3 ); // RX, TXSince SoftwareSerial comes with the IDE and because it can use most of the Arduino pins it is a very convenient solution but does have drawbacks. It is not reliable at very slow or very fast speeds and because of how it works it can cause problems with timings.SoftwareSerial uses pin-change interrupts when receiving data, and both receive and transmit use delay loops, and while it is delaying, interrupts are disabled.

This means it blocks the sketch. The code simply sits and waits for SoftwareSerial to finish before it can do anything else.Because interrupts are disabled, SoftwareSerial interferes with anything that uses interrupts.SoftwareSerial:– comes with the Arduino IDE as standard.– can be used with almost all pins (see below)– can not transmit and receive at the same time– can have multiple instances but only one instance can be active at one time– not very good at very slow or fast baud rates.

The baud rate should be kept in the range 9600 – 38400– requires a library which comes with the Arduino IDE by default. Begin ( 9600 );endend closes or disables serial. For hardware serial this is not normally required but can be used if you ever need to use the RX and TX pins for other things after using serial. The serial RX and TX pins, Pins D0 and D1, can be used as regular pins when not using serial. I can’t think of a reason why you would want to do this though. If you need to use pins 0 and 1 then you are highly unlikely to use them for serial communication.end can be useful when using software serial.

You can implement more than one software serial but can use only one channel at a time. This means you need to open and close channels as you want to use them. Int numChars = Serial. AvailableForWrite ( );Most people probably do not need to worry to much about this but it can be useful in situations where you must be sure all serial data has been sent before doing the next function. Remember, when using the hardware serial, serial data is sent in the background so as soon as the serial.print command has copied the data to the output buffer your code moves on. This means the next instructions in your code are being executed while data is still being sent. See also Serial.flush.readreads a single character or byte from the serial input buffer.

Data received over serial is stored in the buffer until the sketch reads them. If the buffer is empty read returns -1You can see an example of this is the serial pass through sketch above.

Int length = 10; char buffer 11 ; int numberOfBytes = Serial. ReadBytes (buffer, length ) // if numberOfBytes 0 we have data. // if numberOfBytes =10 we have all the data.As with all c arrays, make sure the array or buffer is large enough to hold the data you are copying to it. The compiler won’t tell you if you make a mistake the sketch will simply start acting strange.readBytesUntil(termChar,buffer,length)like readBytes but you can now specify a terminator character/byte. The terminating character is not copied to the buffer.For example, if you have data that always ends with a byte valued 13 you can use readBytesUntil:termChar is a char or bytebuffer is a char or byte array (char or byte )length is an int. Int length = 10; char buffer 11 ; char termChar = 13; int numberOfBytes = Serial. ReadBytesUntil (termChar,buffer, length ) // if numberOfBytes 0 we have data.This is a handy command if you do not always have the same length data.

The command simply reads the data until it finds the terminating character. You have to make sure the receiving buffer is large enough to accommodate the data though.The default timeout for readBytes and readBytesUntil is 1 second (1000ms). This can be changed with setTimeout.I personally do not like to use readBytes or readBytesUntil. They wait until all the bytes are available (or until they timeout) and while waiting they block the sketch. A better way, at least to me, is to create your own loop and use read to copy the data.

Arduino Serial Output To Excel

This allows you to check availability of data and only copy if data is there. If no data is available you can go and do other things. See examples of “Blink Without Delay” for examples of this technique.setTimeoutchange the timeout time used in readBytes and readBytesUntil. The time specified is in milliseconds.The value is a long ctype data value.Set the timeout to half a second (500ms). SetTimeout ( 500 );find(searchString)Serial.find checks the serial input buffer for a given string (char array). Returns TRUE if the string is found and FALSE if it is not found (times out).

There are a couple of things to be aware off:1 – it deletes data from the buffer as it searches.2 – it blocks the sketch while it is doing its thing.find reads the serial input buffer, removing characters as it goes, until it finds the search string or it fully empties the buffer and times out. If you have a search string “abc” and the buffer contains “”, find will empty the buffer, timeout, and then return FALSE.If the buffer contains “hello world” and you search for “world”, find runs through the buffer, deleting characters as it goes, until it finds “world”.

Find then returns “TRUE”. In the process of searching for “world” the function removes the string from the serial buffer. This means, if the buffer contains “hello world” and you search for “world”, the function will return TRUE but the serial buffer will be empty. Any data in the buffer after “world” will remain.find blocks all other operations on the Arduino while it is working and has to sit and wait until find is finished before moving to the next operation. Long parseIntValue = Serial. ParseInt ( );Always copy the return value into a long variable.parseFloatSerial.parseFloat returns the first valid ascii formated floating point number from the serial buffer. The function returns empty handed (0) if a floating point number is not found or the timeout is reached.

The data does not need to be in the buffer at the time the function is called but the function will block your code while it waits for data to arrive.parsefloat runs through the serial buffer deleting non floating point characters (non-numbers and non-minus sign) until it finds a number or minus sign. It then reads the floating point data until it reaches another non float character. It then converts the ascii formatted value in to an actual floating point value.If the serial buffer contains “abc3.1234abcdefg”. ParseFloat will delete the first “abc”, find the 3.1234 and leave “abcdefg” in the serial buffer.Serial.peekSerial.peek returns the next character in the serial buffer without removing it. It is like read except it does not delete anything.

Very useful if you want to create your own parser and need to see what the next character is without disturbing it.peek can only be used to read the first available character. Unlike read it does not increment the buffer pointer or change the buffer so successive peeks will return the same character.Serial.flushThis is a command many people get wrong, including myself when I first started with the Arduino. It is easy to assume you know what it does from the name especially if you have experience with other programming languages.The contains the sentence “Waits for the transmission of outgoing serial data to complete. (Prior to Arduino 1.0, this instead removed any buffered incoming serial data.).” Besides knowing that the function changed with IDE 1.0 the important bit is “Waits for the transmission of outgoing serial data to complete.”.

What does this mean? It means that your program stops and waits for all the current serial data to be sent. Serial.flush does not clear the buffer(s).Hardware serial works in the background, this is why you can use it while doing other things. When you use Serial.print(“HELLO WORLD”); the Arduino copies the “HELLO WORLD” data to the outpiuut buffer and then returns to your main code.

It then uses interrupts to actually send the data in the background while still processing your sketch. This is normally a good thing, but, sometimes it can be a problem and you may want to wait until all the data has been sent before continuing with your program. This is where Serial.flush can be used just keep in mind that the delay can be quite long.serialEventserialEvent is not really a Serial command. It is a function that is called once every loop when there is data in the serial input buffer. (The function is actually called outside of the loop function but that is not important here). It is like having a if(Serial.available) outside of the main loop function.

Arduino No Serial Output

In this application, I wanted to use an Arduino to track the current drawn by a drip sensor I built with a Promini style board. To do this I read the voltage drop across a shunt resistor with the UNO’s ADC.

The Arduino takes reading by comparing the analog input to it's own ground, so the black wire is needed to connect the two ground lines. Placing the shunt resistor on the low side line like this causes the Promini's effective ground line to move around as the current through the resistor changes, but in this case that 'floating ground line' should not cause problems.Another challenge of the shunt resistor method is balancing the ADCs resolution with the other limits imposed by the method itself. The Arduino’s native ADC delivers 10-bit readings, (ie 0-1023) with a default resolution of 4.8 millivolts.

Arduino

Even if you increase the sensitivity by changing to the internal 1.1 volt vref, you only reach 1.1v/1024 steps = 1 millivolt per bit.With an upper limit of 1.1v on the ADC input, and a potential 100mA peak current in the drip sensing datalogger during SD card writing events, the largest shunt resistor I can use is 1.1v/0.1a= 11Ω. But allowing the voltage drop on the shunt resistor to get that high imposes another challenge in that the drip logger would only be left with 4.5v (from the 3xAA battery) – 1.1v drop = 3.4v. That’s right at the minimum needed by the 3.3v regulator on the Arduino promini board, risking a potential brown-out in the middle of the SD card writing process. The drip loggers sleep at 0.2 mA x 11Ω shunt resistor = 2.2 mV - so at the low end of the scale we are right on the limit of the ADC's resolution.But hey, lets pop in some fresh batteries, and see what we get anyway. Not too bad, but that’s a noisy plot with lots of jitter on the base line.

Having 1-2 bits toggle like that is typical for ADC’s so there is probably nothing I can do to get rid of it. And the drip sensors resting state reads at zero when it should be registering at least two counts. It is also common for an ADC to under or over read by a few bits at the low end, so I added an offset adjustment into the code to bring that sleeping current baseline up to the 0.2 mA that I had already confirmed with a multimeter.Since I did not know how long the event would be I initially had a 400 us delay in the sampling loop. Here's what happened when I took that out and let the ADC run a full speed. That's over 8000 samples a second! Far too many readings for the serial plotter to handle if I want to look at longer events. But how do I maintain the Arduino’s ability to spot really short current peaks, but only send 500 readings to the screen?Adding long delays to the code would miss those brief events so I decided to create an “oversampling loop” that creates a kind of running average using a low pass filter, but also checks for peaks throughout the process.

You can dig into, but the basic idea that is if a peak occurs, then the highest reading in an interval becomes the final reading. If a decreasing trend is found, then the output from a leaky integrator becomes the final reading for that interval.

So the readings get smoothed on the way down, but not on the way up. Squashing more than 7000 raw readings into a 500 line display really starts to distort the curve, but everything is still recognizable, and more importantly, the peaks did not get chopped off like they would have if I just slowed down the sampling loop with delays.So this method lets you adjust the serial plotter’s display to match the timing of the event you are trying to see, provided you don’t over-interpret the accuracy of those heavily averaged interval numbers. Capturing longer records:Hopefully they will expand the plotter tool with export capabilities in the future, but for now you can manually move data out of the text monitor and simply paste it into Excel. Before you start a long run for export to a spreadsheet, comment out the extra constants that you were printing to stabilize the y – axis on the plotter, so that only the numbers you are interested in are sent to the serial text display. Then after your Arduino DAQ has been capturing events for a while, click inside the serial monitor window, select all the data and copy it (on a windows machine that would be CTRL+A followed by CTRL+C ) then open a new spreadsheet and simply paste the data into an empty column.This lets you compare the different events side by side. Note: The material I've posted here is an excerpt, where I also put a 15-bit ADS1115 ADC module through it's paces. Hop over there if you want to see how that compared to the Arduino's native ADC.

Serial

If you are curious about the platform pictured in this tutorial, you can read a paper about how we use these Arduino based data loggers for research at: which is an open access journal, so the PDF is free to download.And: The folks over at Measuring Stuff posted a great page called which provides more great background on the subject of using an Arduino in this kind of application.

2019 © nowbotbi