-1

I want to connect my Arduino, which has a Bluetooth module, to my python.

I am having problems to choose fitting packages. Can any one please recommend me packages for both sides which are compatible for a serial communication? And if there is something I must pay attention to during the process.

LoukasPap
  • 1,244
  • 1
  • 8
  • 17

1 Answers1

1

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 string, 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.

N3ttX
  • 94
  • 1
  • 9