by Floris Wouterlood – The Netherlands – July 26, 2017
A previous project dealt with connecting two Arduino’s to each other via serial communication where Arduino #1 reads a temperature sensor and transmits the data via one of three available serial communication protocols to Arduino #2. The latter displays the data on an OLED display. In that project the value of only one variable was transmitted. Sending variables from different sensors is more challenging. The present report deals with data from a Si7021 combined temperature – relative humidity sensor. The two sensor readings are character coded by the first Arduino and then are transmitted as a long character string via standard serial communication to the second Arduino. The latter splits and decodes the string stream and displays the variables on a 20×4 LCD display.
Sometimes the number of available pins on an Arduino constrain a project. One example is the construction of a weather station that includes barometer, temperature and humidity probes while one wants to show the results simultaneously on a TFT display. Of course one can use an Arduino Mega that has lots more available pins than a humble Arduino, but the challenge is to get as much as possible out of what the standard Arduino offers. Fortunately every Arduino has serial communication pins that can be used to send data to another device, for instance a second Arduino. This functionality can be exploited to divide jobs over two Arduinos: number one measures and number two displays.
As parameters such as temperature and relative humidity typically involve decimals, the variables of choice are of the ‘float’ type. Sending floats’ over a serial connection is more challenging than sending integer values.
The Si7021 breakout board
In this project a Si7021 sensor breakout board is used connected to an Arduino Nano (Nano #1). The sensor is cheap and it has acceptable accuracy: relative humidity with 3% deviation and temperature with 0.5 oC deviation. The board communicates with Arduino #1 via the I2C protocol which means that there are four wires: 5V, GND, SDA and SCL.
The second Arduino (Nano #2) displays data via a standard HD44870 20×4 LCD display with parallel interface. I also connected the same LCD display via an I2C ‘backpack’ to Nano #2.
Serial communication of multiple ‘floats’
Serial connectivity protocols do not allow direct transfer of float variables as serial connectivity is designed to handle bytes, i.e., coded ASCII characters. The design of serial communication implies that it is relatively easy to send values between -127 and +127 through a serial communication line because their value can be expressed in one byte. Floats are different. One float variable needs 8 bytes of memory. One solution for serial transmission of floats is to code them as a series of ASCII characters. This series is sent to Arduino #2 where they are decoded and their value stored into floats. A flow scheme of this way of transferring data from multiple sensors is shown in Figure 1.
Figure 1: Communication of ‘float’ type data from one Arduino to the next via serial communication. The first Arduino (Nano #1) receives via I2C temperature and relative humidity data from a Si7021 sensor. Temperature and relative humidity values are coded as 5-character strings. The two strings are concatenated into one string that is transmitted via the serial port to Nano #2. The latter splits the incoming string, decodes the substrings, stores the data in float variables and displays the contents of these variables on a standard 20×4 LCD display.
Electronics and supplies
(Figure 2 shows the components and the wiring diagram). We need: 1 x breakout board with Si7012 temperature/relative humidity probe, 2x Arduino Nano microcontroller board, 1x 20×4 LCD display, 2x breadboard, 2x led, 3x 220Ω, 1x 10 kΩ pot meter, interruptor switch, jumper wires, one I2C LCD1602/2004 ‘backpack’.
Nano #1: As the Si7021 breakout board communicates via the I2C protocol, pins SCL and SDA from the probe are connected with pins A5 and A4, respectively, of the Nano. A led is connected to pin D8 of the Nano. Pins TX and RX are connected via the interruptor switch with the RX and TX pins of Nano #2. Several sources suggest 4.7 k Ω resistors between pins SDA, SCL on the breakout board and 5V, but since we are in this project working with one I2C device this is not necessary. Don’t forget to connect VIN and GND of the breakout board with 5V and GND of Nano #1. Serial communication requires GND of Nano #1 to be connected with GND of Nano #2 (common ground).
Nano #2: Pins TX and RX are connected to RX and TX of Nano#1. Pin D8 is connected to a led. Pins D11 and D12, and pins D2, D3, D4 and D5 of Nano #2 are wired to pins E, RS, D7, D6, D5 and D4 on the LCD (standard pin assignment), Of the remaining pins of the LCD, VSS is connected to GND, VDD to 5V, V0 to the wiper of the pot meter (LCD contrast), pin A via a 220Ω resistor to 5V, and pin K to GND.
Figure 2: Wiring of the two Arduinos. Nano #1 receives on its pins A4 and A5 data from an Si7021 I2C temperature/ relative humidity breakout board. The interruptor switch in the serial communication linehas the function of interrupting serial communication between the Nanos when the Nano’s usb port is used to upload a sketch to one of the Nanos.
Sketch running on Nano #1 (‘si_7021_serial_sender.ino’):
The following character arrays are declared: tempstring_arr , humstring_arr ) and sendstring . Size of each array is 10 characters which is more than enough since each float will be coded as 5 characters (two numbers, a period, and two decimals.
Via pins A4 and A5, temperature and humidity data is called via 2C from the SI7021 and stored in variables temp_fl and hum_fl. These variables are of the float type. Temperature is in degrees Celsius, humidity is relative humidity (% water vapor pressure at ambient temperature).
Via the instruction dtostrf (temp_fl, 0, 2, tempstring_arr); the value of float ‘temp_fl’ is coded as a 5-character string in the char array named ‘tempstring_arr’.
The same is done with the relative humidity: the instruction dtostrf (hum_fl, 0, 2, humstring_arr); forces the value of float ‘hum_fl’ into the 5-character string stored in humstring_arr.
The next important step is concatenation of the temperature and humidity strings into one long string simply named ‘sendstring’. This string has a length of 10 characters. Because this is a simple sketch there are no <begin of string> and <end of string> characters added to improve accuracy.
When the temperature is for example 18.22 oC and humidity is 60.44% this data will be coded in sendstring as “18.1160.44”. This string is sent to Nano #2 via the serial port. In this example we use the conventional 9.600 bps transmission speed of the serial port. For data such as environmental temperature and humidity It is not necessary to use high speed communication nor is it necessary to communicate all the time. Several ‘delay’ instructions (delay (1000);) slow down the loop of the sketch.
Figure 3: Wiring of the two Arduinos. Nano #1 receives on its pins A4 and A5 data from a Si7021 I2C temperature/ relative humidity breakout board. Here, Nano #2 sends data via an I2C ‘backpack’ to the LCD display. The interruptor switch in the serial communication line
has the function of interrupting serial communication between the Nanos when the Nano’s usb port is used to upload a sketch to one of the Nanos.
Sketch running on Nano #2:
This Nano has as task receive the strings arriving from Nano #1, decoding and controlling the output to the 20×4 LCD display.
As I tested the LCD display with parallel communication (wiring in Fig. 2) and with I2C via the ‘backpack’ intermediate breakout board (wiring in Fig. 3), a sketch was composed for the ‘parallel display’ solution and a sketch for the I2C ‘backpack’ display solution.
Name of the sketch supporting parallel LCD display: si_7021_serial_receiver_LCD
Name of the sketch supporting I2C LCD display: si_7021_serial_receiver_i2c_LCD
These sketches differ in the used libraries and initialization of the LCD display. The bodies of the sketches is identical.
Preparations in the sketches include declaring a string to hold the main received character string, two strings necessary when the main string is splitted, and two character arrays for processing into floats: receivestring, tempstring, humstring, tempstring_arr and humstring_arr.
Upon receiving characters via the serial port, these are lined up in receivestring until the port falls silent. Note that there is currently no control for an <end of string> character.
When a receivestring is filled, this string is split into the two substrings named tempstring and humstring. These are subsequently converted into the character arrays, tempstring_arr (serving temperature) and humstring_arr (serving humidity).
Decoding is preformed by the instruction atof (tempstring_arr). The result of the decoding step is stored in the float variable named temp_fl.
The same is done with the humidity: atof (humstring_arr), and the result is stored in the float variable hum_fl.
At this point Nano #2 has received, splitted, converted and decoded the received character string, The final step is to display the values of the temperature and humidity float variables in the proper cursor positions of the LCD display. The alternative sketches differ only in controlling the LCD display: one with a parallel interface (such as in Figure 2) and one with I2C backpack control of the LCD display (such as in Figure 3). Serial communication via TX-TX, and decoding is identical in these sketches.
The sketches can be downloaded from https://thesolaruniverse.wordpress.com as ‘Si-7021-serial-sender-receiver-sketches’
Transmitting ‘float’ values from one Arduino to the next seems at first hand complicated because serial communication is basically single byte-oriented while floats gobble up several bytes. Imagine a container shipping service from China to Europe. To transport a complete car factory from Europe to China you decide to build the factory in Europe, disassemble and load the components into containers, sail to China and upon arrival reassemble the factory. The solution is to work with pieces. A similar situation exists on the Internet where all server-client information is transmitted as bytes. The server sends series of ASCII coded instructions that are interpreted by a browser in the receiving computer in terms of makeup of a browser page. The individual images and sounds are sent to the receiving computer as bytes as well.
While the challenge in this project is to send the contents of ‘float’; variables from one Arduino to the next, one could ask whether it is necessary at all to send floats. A simple trick in Nano #1 could be to convert a variable from ‘float’ to ‘integer’ by multiplying with 100. Of course the integer in Arduino #2 has to be divided by 100 before sending it on the LCD for display. An advantage with this trick is that the decimal point disappears from the sendstring and that this string now will be 8 characters long instead of 10. Because the second decimal (1/100th) of a temperature reading and also in a humidity reading is completely unrealistic given the overall mediocre accuracy of the sensor, one can even multiply the float variable with 10, transmit a sendstring consisting of 6 characters, decode and display only one decimal on the LCD display attached to Nano #2. In fact this was done for the purpose of creating Figures 2 and 3.
The current sketches are simple sketches that do not contain instructions to verify the validity of the character strings sent via serial communication. There are no control characters added to the character string that Is sent via the line. If the frequency at which the character string is serially transmitted is increased (reduce the millis in the delay(nnnn) instructions, or if the baud rate of the serial transmission is increased, gibberish may be displayed on the LCD attached to Nano #2. Conversely, if the LCD display shows gibberish the first measure – after checking the wiring – is to reduce serial transmission speed and introduce a larger delay in the loops in the sketches running on both Arduinos. Experiment!
Sketches can be downloaded here (Si-7021-serial-sender-receiver-sketches)