Python与Arduino串行通信的包裹。

huangapple go评论78阅读模式
英文:

Packages for python-arduino serial communication

问题

我想将我的Arduino与蓝牙模块连接到我的Python。

我在选择合适的软件包方面遇到了问题。
请问有人可以推荐适用于串行通信的双方的软件包吗?在整个过程中是否需要注意什么?

英文:

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.

答案1

得分: 1

Arduino

对于Arduino部分,你不需要使用任何额外的库。内置的 Serial 已经为此设计好了。结合 String 数据类型,你可以构建你的数据字符串,然后使用众所周知的 String.prinln(); 发送整个字符串。为了数据分隔,你可以选择任意分隔符(例如,让我们使用 ;)。

发送数据

你可能连接了一个DHT22(温湿度)和BMP280(大气压力)传感器,并希望将数据通过串口发送到你的Python程序中,这种情况下,代码可能如下所示,记住代码被简化了:

// ...
// 变量,用于存储测量数据
float temp;
float hum;
float press;

void setup() {
	// 开始与波特率9600的通信,这很重要
	Serial.begin(9600);
	// 初始化传感器
	dht.begin();
	bmp.begin();
}

void loop() {
	// 读取所有传感器数据并将其存储到我们之前定义的变量中
	temp = dht.readTemperature();
	hum = dht.readHumidity();
	press = bmp.readPressure();
	
	// 将数据打印到串口。数据示例的格式如下:
	// t=20.3;h=43.8;press=1000.8
	// 字符串以换行字符结束
	Serial.print("t=");
	Serial.print(temp);
	Serial.print(";h=");
	Serial.print(hum);
	Serial.print(";p=");
	Serial.println(press);

    delay(1000);
}

接收数据

从串口读取数据也很容易。你可以参考我的项目之一,但基本上,你感兴趣的是以下代码片段:

String serialReceive;
// ...
if (Serial.available() > 0) { //如果串口缓冲区中有任何数据可用
    serialReceive = Serial.readString(); //将其读取为字符串并放入serialReceive变量中
}

与我们在发送示例中所做的一样,我已经设置了字符串,以便我可以轻松地通过使用分隔字符或更容易地在Python脚本中将所有数据填充为相等长度(例如5个字符)来分隔各个数据部分,然后我使用 serialReceive.substring(0,5); 来获取第一个数据部分等。

Python

有一个名为pyserial的库,它正是我们需要的。由于PC上的串口稍微复杂一些,需要进行一些设置,但你可能唯一需要更改的是波特率。然后,由于你的PC具有多个(虚拟或真实的)串口,你需要指定在哪里监听或发送数据。如何找到它取决于你的操作系统,Windows和基于Unix的系统不同。在Windows上,你应该能够在“设备管理器”中找到__已连接__的Arduino,标记为_COMx_。在Linux上,它将是/dev/ttyUSBx之一,你可以在Arduino IDE中看到它,这是确定需要使用哪个COMttyUSB的最简单方法。

发送数据

与Arduino非常相似,但需要进行一些设置。请按照以下示例操作:

import serial

# 在/dev/ttyUSB0上打开串口,波特率为9600
ser = serial.Serial("/dev/ttyUSB0", 9600)
# 向串口写入字符串"data"
ser.write(b"data")
# 关闭连接
ser.close()

这非常简单,你可以发送任何类型的数据(请注意,Arduino的串口缓冲区只有64字节)。还要注意,我在字符串前面加了 b,这告诉Python它应该将字符解释为字节字符串对象,而不仅仅是字符串。你可以在这里了解更多信息。

接收数据

serial库有一个很好的函数叫做readline(),它会读取串口中的数据,直到遇到换行符\n。这非常有用,因为Arduino的Serial.println()以换行符结束。所以基本示例如下:

import serial
ser = serial.Serial("/dev/ttyUSB0", 9600)

while True:
  data = str(ser.readline())

在这里,我们将ser.readline()强制转换为str,因为它以类似字节的对象的形式到达。
根据我们的Arduino示例,可以利用诸如split之类的函数将传入的字符串分隔为单独的值:

import serial
ser = serial.Serial("/dev/ttyUSB0", 9600)

while True:
  data = str(ser.readline())
  temp, hum, press = data.split(";")
  print(temp, hum, press)

现在,你可以访问你的数据。然后,你可以通过仅切片字符串来轻松删除以t=开头的部分,比如 temp = temp[2:],然后你可以对你的值进行任何操作。

这基本上就是使用Arduino和Python发送和接收数据的基础知识。其他所有内容都取决于你的具体应用程序。

英文:

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.

huangapple
  • 本文由 发表于 2023年6月8日 14:51:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76429278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定