Arduino Fast Serial Write
After a few weeks of wrangling with a microcontroller to squeeze out every ounce of processing power as possible for a drone flight controller, I thought I'd write up an article to help you find ways to improve the speed and efficiency of your own projects. Throughout this article, I'll be focusing on the Arduino. Arduino Projects. In this tutorial, we’re going to help you create a few simple arduino projects that are perfect for beginners. These basic projects will help you understand how to set up the Arduino software and then connect the components to perform a specific action.
4.0. Introduction Serial communications provide an easy and flexible way for your Arduino board to interact with your computer and other devices. This chapter explains how to send and receive information using this capability. Described how to connect the Arduino serial port to your computer to upload sketches. The upload process sends data from your computer to Arduino and Arduino sends status messages back to the computer to confirm the transfer is working.
The recipes here show how you can use this communication link to send and receive any information between Arduino and your computer or another serial device. Figure 4-1. Arduino Serial Monitor screen You can also send data from the Serial Monitor to Arduino by entering text in the text box to the left of the Send button. Baud rate (the speed at which data is transmitted, measured in bits per second) is selected using the drop-down box on the bottom right. You can use the drop down labeled “No line ending” to automatically send a carriage return or a combination of a carriage return and a line at the end of each message sent when clicking the Send button, by changing “No line ending” to your desired option. Your Arduino sketch can use the serial port to indirectly access (usually via a proxy program written in a language like Processing) all the resources (memory, screen, keyboard, mouse, network connectivity, etc.) that your computer has.
Your computer can also use the serial link to interact with sensors or other devices connected to Arduino. Implementing serial communications involves hardware and software. The hardware provides the electrical signaling between Arduino and the device it is talking to. The software uses the hardware to send bytes or bits that the connected hardware understands. The Arduino serial libraries insulate you from most of the hardware complexity, but it is helpful for you to understand the basics, especially if you need to troubleshoot any difficulties with serial communications in your projects.
Note Using 0 volts (for 0) and 5 volts (for 1) is very common. This is referred to as the TTL level because that was how signals were represented in one of the first implementations of digital logic, called Transistor-Transistor Logic (TTL). Boards including the Uno, Duemilanove, Diecimila, Nano, and Mega have a chip to convert the hardware serial port on the Arduino chip to Universal Serial Bus (USB) for connection to the hardware serial port. Other boards, such as the Mini, Pro, Pro Mini, Boarduino, Sanguino, and Modern Device Bare Bones Board, do not have USB support and require an adapter for connecting to your computer that converts TTL to USB. See for more details on these boards. Some popular USB adapters include.
Mini USB Adapter. USB Serial Light Adapter. FTDI USB TTL Adapter. Modern Device USB BUB board. Seeedstudio UartSBee Some serial devices use the RS-232 standard for serial connection.
These usually have a nine-pin connector, and an adapter is required to use them with the Arduino. RS-232 is an old and venerated communications protocol that uses voltage levels not compatible with Arduino digital pins. You can buy Arduino boards that are built for RS-232 signal levels, such as the Freeduino Serial v2.0. RS-232 adapters that connect RS-232 signals to Arduino 5V (or 3.3V) pins include the following. RS-232 to TTL 3V–5.5V adapter. P4 RS232 to TTL Serial Adapter Kits. RS232 Shifter SMD A standard Arduino has a single hardware serial port, but serial communication is also possible using software libraries to emulate additional ports (communication channels) to provide connectivity to more than one device.
Software serial requires a lot of help from the Arduino controller to send and receive data, so it’s not as fast or efficient as hardware serial. The Arduino Mega has four hardware serial ports that can communicate with up to four different serial devices. Only one of these has a USB adapter built in (you could wire a USB-TTL adapter to any of the other serial ports). Shows the port names and pins used for all of the Mega serial ports. Software Serial You will usually use the built-in Arduino Serial library to communicate with the hardware serial ports. Serial libraries simplify the use of the serial ports by insulating you from hardware complexities.
Sometimes you need more serial ports than the number of hardware serial ports available. If this is the case, you can use an additional library that uses software to emulate serial hardware. Recipes and show how to use a software serial library to communicate with multiple devices. Serial Message Protocol The hardware or software serial libraries handle sending and receiving information. This information often consists of groups of variables that need to be sent together. For the information to be interpreted correctly, the receiving side needs to recognize where each message begins and ends.
Meaningful serial communication, or any kind of machine-to-machine communication, can only be achieved if the sending and receiving sides fully agree how information is organized in the message. The formal organization of information in a message and the range of appropriate responses to requests is called a communications protocol.
Messages can contain one or more special characters that identify the start of the message—this is called the header. One or more characters can also be used to identify the end of a message—this is called the footer. The recipes in this chapter show examples of messages in which the values that make up the body of a message can be sent in either text or binary format. Sending and receiving messages in text format involves sending commands and numeric values as human-readable letters and words. Numbers are sent as the string of digits that represent the value.
For example, if the value is 1234, the characters 1, 2, 3, and 4 are sent as individual characters. Binary messages comprise the bytes that the computer uses to represent values. Binary data is usually more efficient (requiring fewer bytes to be sent), but the data is not as human-readable as text, which makes it more difficult to debug. For example, Arduino represents 1234 as the bytes 4 and 210 (4. 256 + 210 = 1234). If the device you are connecting to sends or receives only binary data, that is what you will have to use, but if you have the choice, text messages are easier to implement and debug. There are many ways to approach software problems, and some of the recipes in this chapter show two or three different ways to achieve a similar result.
The differences (e.g., sending text instead of raw binary data) may offer a different balance between simplicity and efficiency. Where choices are offered, pick the solution that you find easiest to understand and adapt—this will probably be the first solution covered.
Alternatives may be a little more efficient, or they may be more appropriate for a specific protocol that you want to connect to, but the “right way” is the one you find easiest to get working in your project. The Processing Development Environment Some of the examples in this chapter use the Processing language to send and receive serial messages on a computer talking to Arduino. Processing is a free open source tool that uses a similar development environment to Arduino, but instead of running your sketches on a microcontroller, your Processing sketches run on your computer.
You can read more about Processing and download everything you need at the. Processing is based on the Java language, but the Processing code samples in this book should be easy to translate into other environments that support serial communications. Processing comes with some example sketches illustrating communication between Arduino and Processing. SimpleRead is a Processing example that includes Arduino code. In Processing, select File →Examples →Libraries →Serial →SimpleRead to see an example that reads data from the serial port and changes the color of a rectangle when a switch connected to Arduino is pressed and released. Serial.flush now waits for all outgoing data to be sent rather than discarding received data.
You can use the following statement to discard all data in the receive buffer: while(Serial.read = 0); // flush the receive buffer. Serial.write and Serial.print do not block. Earlier code would wait until all characters were sent before returning. From 1.0, characters sent using Serial.write are transmitted in the background (from an interrupt handler) allowing your sketch code to immediately resume processing. This is usually a good thing (it can make the sketch more responsive) but sometimes you want to wait until all characters are sent. You can achieve this by calling Serial.flush immediately following Serial.write.
Serial print functions return the number of characters printed. This is useful when text output needs to be aligned or for applications that send data that includes the total number of characters sent. There is a built-in parsing capability for streams such as Serial to easily extract numbers and find text. See the Discussion section of for more on using this capability with Serial. The SoftwareSerial library bundled with Arduino has had significant enhancements; see Recipes and. A Serial.peek function has been added to let you ‘peek’ at the next character in the receive buffer.
Unlike Serial.read, the character is not removed from the buffer with Serial.peek. Figure 4-2. Arduino Serial Monitor screen Your sketch must call the Serial.begin function before it can use serial input or output. The function takes a single parameter: the desired communication speed.
You must use the same speed for the sending side and the receiving side, or you will see gobbledygook (or nothing at all) on the screen. This example and most of the others in this book use a speed of 9,600 baud ( baud is a measure of the number of bits transmitted per second).
The 9,600 baud rate is approximately 1,000 characters per second. You can send at lower or higher rates (the range is 300 to 115,200), but make sure both sides use the same speed. The Serial Monitor sets the speed using the baud rate drop down (at the bottom right of the Serial Monitor window in ).
If your output looks something like this: `3??f. Note If your send and receive serial speeds are set correctly but you are still getting unreadable text, check that you have the correct board selected in the IDE Tools →Board menu. There are chip speed variants of some boards, if you have selected the wrong one, change it to the correct one and upload to the board again. You can display text using the Serial.print function. Strings (text within double quotes) will be printed as is (but without the quotes).
For example, the following code: Serial.print('The number is '); prints this: The number is The values (numbers) that you print depend on the type of variable; see for more about this. For example, printing an integer will print its numeric value, so if the variable number is 1, the following code: Serial.println(number); will print this: 1 In the example sketch, the number printed will be 0 when the loop starts and will increase by one each time through the loop.
The ln at the end of println causes the next print statement to start on a new line. That should get you started printing text and the decimal value of integers. See for more detail on print formatting options. You may want to consider a third-party terminal program that has more features than Serial Monitor. Displaying data in text or binary format (or both), displaying control characters, and logging to a file are just a few of the additional capabilities available from the many third-party terminal programs. Here are some that have been recommended by Arduino users. An easy-to-use freeware terminal program for Windows, Mac, and Linux An open source terminal program for Linux A free executable for the PC An open source virtual screen management program that supports serial communications; included with Linux and Mac OS X Another open source terminal program for Linux An open source SSH program for Windows and Linux that supports serial communications An open source terminal program for the PC A shareware program for the Mac In addition, an article in the Arduino wiki explains how to configure Linux to communicate with Arduino using TTY (see ).
You can use a liquid crystal display as a serial output device, although it will be very limited in functionality. Check the documentation to see how your display handles carriage returns, as some displays may not automatically advance to a new line after println statements.
Discussion Printing a text string is simple: Serial.print('hello world'); sends the text string “hello world” to a device at the other end of the serial port. If you want your output to print a new line after the output, use Serial.println instead of Serial.print. Printing numeric values can be more complicated. The way that byte and integer values are printed depends on the type of variable and an optional formatting parameter. The Arduino language is very easygoing about how you can refer to the value of different data types (see for more on data types). But this flexibility can be confusing, because even when the numeric values are similar, the compiler considers them to be separate types with different behaviors.
Arduino Fast Serial Write Byte
For example, printing a char, byte, and int of the same value will not necessarily produce the same output. Here are some specific examples; all of them create variables that have similar values: char asciiValue = 'A'; // ASCII A has a value of 65 char chrValue = 65; // an 8 bit signed character, this also is ASCII 'A' byte byteValue = 65; // an 8 bit unsigned character, this also is ASCII 'A' int intValue = 65; // a 16 bit signed integer set to a value of 65 float floatValue = 65.0; // float with a value of 65 shows what you will see when you print variables using Arduino routines. Note The expression Serial.print(val,BYTE); is no longer supported in Arduino 1.0. If your code expects byte variables to behave the same as char variables (that is, for them to print as ASCII), you will need to change this to Serial.write(val).
The sketch in this recipe uses a separate line of source code for each print statement. This can make complex print statements bulky. For example, to print the following line: At 5 seconds: speed = 17, distance = 120 you’d typically have to code it like this: Serial.print('At '); Serial.print(t); Serial.print(' seconds: speed= '); Serial.print(s); Serial.print(', distance= '); Serial.println(d); That’s a lot of code lines for a single line of output. You could combine them like this: Serial.print('At '); Serial.print(t); Serial.print(' seconds, speed= '); Serial.print(s); Serial.print(', distance= ');Serial.println(d); Or you could use the insertion-style capability of the compiler used by Arduino to format your print statements.
You can take advantage of some advanced C capabilities (streaming insertion syntax and templates) that you can use if you declare a streaming template in your sketch. This is most easily achieved by including the Streaming library developed by Mikal Hart. You can read more about this library and download the code from. If you use the Streaming library, the following gives the same output as the lines shown earlier: Serial.