Arduino
For Arduino's side, you don't have to use any extra libraries. A built-in Serial
is designed for this. In combination with String
data type, you can build up your data string, and then send the entire string using well known String.prinln();
. For data separation, you can select an arbitrary delimiter (let's do ;
for example).
Sending data
You might have a DHT22 (temperature and humidity) and BMP280 (atmospheric pressure) sensors hooked up, and you want to send data via serial to your python program, in that case, the code might look like this, bare in mind that the code is simplified:
// ...
// variables into which we'll store measured data
float temp;
float hum;
float press;
void setup() {
// start communication with baud=9600, this is important
Serial.begin(9600);
// initialize sensors
dht.begin();
bmp.begin();
}
void loop() {
// read all the sensors and store the data into variables we've defined earlier
temp = dht.readTemperature();
hum = dht.readHumidity();
press = bmp.readPressure();
// print the data into serial. Format of the data example:
// t=20.3;h=43.8;press=1000.8
// and the string is terminated using newline character
Serial.print("t=");
Serial.print(temp);
Serial.print(";h=");
Serial.print(hum);
Serial.print(";p=");
Serial.println(press);
delay(1000);
}
Receiving data
Reading data from the serial is easy too. You can look into one of my projects for reference, but essentially, this is the snippet you're interested in:
String serialReceive;
// ...
if(Serial.available() > 0) { //if any data is available in serial buffer
serialReceive = Serial.readString(); //read it as string and put into serialReceive variable
}
As we did in the sending example, I've set up the string in such I way, I can easily delimit the individual data parts either by using a delimit character, or more easily, in the python script I've padded all my data to equal length (i.e. 5 characters) and then I've used serialReceive.substring(0,5);
to get the first data part, etc.
Python
There is a library called pyserial
which does exactly what we need. Since serial on PC is a bit more complex, there is a bit more setting up needed, but the only thing you'll probably be changing is the baud rate. Then, since your PC has multiple (virtual or real) serial ports, you need to specify where to listen or send data. Where to find this depends a lot on your OS, it's different on Windows and Unix based systems. On Windows, you should be able to find your connected Arduino in Device Manager, marked as COMx. On Linux, it'll be one of /dev/ttyUSBx
, you can see it in Arduino IDE, that's the easiest way of determining, which COM
or ttyUSB
you need to use.
Sending data
Is a lot similar to Arduino, but with a bit of setting up to do. Follow this example:
import serial
# open serial port on /dev/ttyUSB0, with baud rate of 9600
ser = serial.Serial("/dev/ttyUSB0", 9600)
# write a string "data" to serial
ser.write(b"data")
# close the connection
ser.close()
It's really simple, and you can send any type of data (keep in mind that Arduino's serial buffer is only 64 bytes). Also notice, that I've prefixed the string with b
, which tells python that it should interpret the characters as byte string object, not just a string. You can read up more here.
Receiving data
The serial
library has a neat function called readline()
, which reads the data from serial until it gets a newline \n
character. That is extremely useful, since Arduino's Serial.println()
ends with newline. So the basic example looks like this:
import serial
ser = serial.Serial("/dev/ttyUSB0", 9600)
while True:
data = str(ser.readline())
Here, we are casting ser.readline()
to str
ing, since it arrives as byte-like object.
Following our Arduino example with sensors, we can utilize functions such as split
to delimit the incoming string into separate vlaues:
import serial
ser = serial.Serial("/dev/ttyUSB0", 9600)
while True:
data = str(ser.readline())
temp hum, press = data.split(";")
print(temp, hum, press)
And now, you have access to your data. You can then simply remove the t=
beginning part by just slicing the string, like so temp = temp[2:]
and then you can do whatever with your values.
That is pretty much the basics of sending and receiving data using Arduino and python. Everything around depends on your specific application.