Although it is often enough to use a single Arduino to read from a sensor and display the result in the serial window or on an LCD screen, sometimes this is just not enough, and you may want to split the task between 2 Arduinos. An example of this might be an Arduino sensing the rotation of a fuel flow meter turbine blades in a standby emergency diesel motor, (a fairly busy task), and then sending this as a periodic flow rate to a second Arduino in a control room.

In this tutorial, we are going to use an LM35 temperature sensor connected to one Arduino and then use a 3-wire connection (transmit, receive, and common ground) to relay this data to a second Arduino some distance away. If this distance is more than 10m, the wires should be twisted.

BONUS: I made a quick start guide for this tutorial that you can download and go back to later if you can’t set this up right now. It covers all of the steps, diagrams, and code you need to get started.

How the LM35 Works

The LM35 is a 3-pin temperature sensor. The outer 2 pins are connected to a supply voltage anywhere from 4V to 30V. The center Out pin is a voltage source giving 10mV per degree Celsius. In other words, 25 degrees C will produce 250mV on the Out pin. This is an analog voltage and so must be connected to an analog pin on the Arduino. The temperature range is -55 to +150 degrees C. The Arduino can convert this to a temperature in deg C as follows:

  • float tempC = analogRead(LM35_pin)
  • tempC = (tempC*500)/1023

or if you want it in Farenheight, convert as follows: tempF = (tempC*1.8) + 32.

Connecting Two Arduinos

Now, let’s try to build that LM35 and two Arduinos.

It might seem obvious to connect the Arduinos’ two serial ports together (data pins 0 and 1). However, if you will do this, your signal would clash with trying to program the Arduino from the USB port as well as the serial window which by default uses these pins. So instead, we will use the SoftwareSerial library that comes as default with the Arduino IDE and it will create a completely independent set of serial ports for us to use. We will connect the LM35 to the remote unit and a battery and the 3-wire link.

Some sage advice: never wire up anything other than a mains device with mains “cab-tyre” (blue, brown, green) cable.

For the local Arduino, just a power supply or battery, or the power from the USB port will do. The result will be showing on the serial monitor but you could use an LCD display.

How to Wire Up the LM35 to Two Arduinos

Note that the TX of one Arduino goes to the RX of the other and vice versa.

2 UNO’s Wired Together

Installing the Libraries

There is no library required for the LM35 and the SoftwareSerial library is already available as a default installed library.

Something to be aware of, the buffer size in the standard library is fairly small (64 bytes) and if you transmit long strings, you will see them truncated (ends cut off). This can be fixed by editing the SoftwareSerial.h file in C:\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\src but don’t do this unless you know what you are doing. (Make a copy of the file first!)

Note on Serial Comms: It is often easy to forget that serial ports (UARTS) are going to communicate asynchronously. This means data arriving at the receiver will be in its own time and not in time with the Arduino loop.

Arduino Code for the Master

Note that I am avoiding the problematic Arduino String object and using C-type char strings for greater stability. I have added a green LED to both to show the boards are running.

//Transmitter Code
 #include <SoftwareSerial.h>
 SoftwareSerial link(2, 3); // Rx, Tx
 byte lm35Pin = A0;
 float lm35V = 0;
 float tempC = 0;
 byte greenLED = 12;
 char text[20] ;
 char charVal[6];
  ////////////////////////////////////
  void setup() 
  {
    link.begin(9600);
    Serial.begin(9600);
    pinMode(greenLED, OUTPUT);
  }
  ///////////////////////////////////////////
  void loop()  
  {
   strcat(text, "Temp is: "); //append to empty string
   digitalWrite(greenLED, HIGH);
   delay(10);
   digitalWrite(greenLED, LOW);
   lm35V = analogRead(lm35Pin);
   tempC = (lm35V/1023) * 500;
   //this is a float we want it as a c-string:
   dtostrf(tempC, 5, 1, charVal);  
   //5 is min width, 1 is precision; float value is copied to charVal
   strcat(text, charVal); //append the value
   text[16] = 0; //terminate the cstring
   strcat(text, "C");  //append a C
   Serial.println(text); //print to local screen for debug
   link.println(text);
      
   delay(200);
  }
  ////////////////////////////////////////////////////

Arduino Code for the Slave

Take note of the first 4 commented outlines in the loop(). If you need to debug the connection, un-comment them and comment out the rest of the loop() code to get it up and running.

 //Receiver code
 #include <SoftwareSerial.h>
 SoftwareSerial link(2, 3); // Rx, Tx
  
  byte greenLED = 12;
  char cString[20];
  byte chPos = 0;
  byte ch = 0;
  char dataStr[6];
  ////////////////////////////////////////////
  void setup() 
  {
    link.begin(9600); //setup software serial
    Serial.begin(9600);    //setup serial monitor
    pinMode(greenLED, OUTPUT);
  }
  ////////////////////////////////////////////
  void loop()  
  {  
 // if (link.available())
 //     Serial.write(link.read());
 // if (Serial.available())
 //     link.write(Serial.read());  
   
   
   while(link.available())
   {
    //read incoming char by char:
     ch = link.read();
     cString[chPos] = ch;
     chPos++;     
     
   digitalWrite(greenLED, HIGH); //flash led to show data is arriving
   delay(10);
   digitalWrite(greenLED, LOW);
   }
   cString[chPos] = 0; //terminate cString
   chPos = 0;
   
   Serial.print(cString);
    
  }
  //////////////////////////////////////////////////////

Using the Project and Output of the Serial Window

If all has been wired correctly, pinch the LM35 with your fingers to make it change temperature. The serial window should show the following: