Arduino|Part6 -- 读取并发布多传感器数据(rosserial_arduino)

本篇将使用rosserial_arduino读取温湿度传感器(DHT11)和数字温度传感器(DS18B20)的值,并在终端打印出来。
解决方法有两种:
(1)创建多个发布者,并分别发布消息;
(2)自定义msg,就可以发布各传感器的消息。
1 软硬件准备 (1)硬件准备
Arduino控制板一个
DHT11温湿度传感器一个
面包板一个
杜邦线若干
(2)库文件
这里主要用到ros和DS18B20相关的库,可以先学习一下DS18B20数字温度传感器的使用和DHT11温湿度传感器的使用
【Arduino|Part6 -- 读取并发布多传感器数据(rosserial_arduino)】连线方式如下:
Arduino|Part6 -- 读取并发布多传感器数据(rosserial_arduino)
文章图片

2 使用std_msgs (1)程序

#include #include #include #include #include #define ONE_WIRE_BUS 21// DS18B20的数据口引脚号 #define dht11Pin4// DHT11的数据口引脚号ros::NodeHandle nh; std_msgs::Float32 data1; std_msgs::Float32 data2; std_msgs::Float32 data3; ros::Publisher chatter1("chatter1", &data1); ros::Publisher chatter2("chatter2", &data2); ros::Publisher chatter3("chatter3", &data3); OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); dht11 DHT11; void setup(void) { nh.initNode(); nh.advertise(chatter1); nh.advertise(chatter2); nh.advertise(chatter3); Serial.begin(57600); sensors.begin(); } void loop(void) { sensors.requestTemperatures(); // Send the command to get temperatures DHT11.read(dht11Pin); Serial.print("Temperature for the device 1 (index 0) is: "); Serial.println(sensors.getTempCByIndex(0)); Serial.print("Humidity (%): "); Serial.println((float)DHT11.humidity, 2); Serial.print("Temperature (oC): "); Serial.println((float)DHT11.temperature, 2); data1.data = https://www.it610.com/article/sensors.getTempCByIndex(0); data2.data = (float)DHT11.temperature; data3.data = (float)DHT11.humidity; chatter1.publish(&data1); chatter2.publish(&data2); chatter3.publish(&data3); nh.spinOnce(); delay(10); }

(3)测试
编译上面的代码,并分别在五个终端输入以下指令,
$ roscore $ rosrun rosserial_python serial_node.py /dev/ttyACM0 $ rostopic echo chatter1 $ rostopic echo chatter2 $ rostopic echo chatter3

结果如下:
Arduino|Part6 -- 读取并发布多传感器数据(rosserial_arduino)
文章图片

3 自定义数据类型 (1)自定义msg
这里使用了两个传感器,读取的数值均为float32类型,msg文件内容如下:
float32 DS18B20_temperature float32 DHT11_temperature float32 humidity

定义完成后,详细的编译过程可以参考:Arduino中如何使用ROS自定义的msg
注意: 在ROS中自定义的msg数据类型在Arduino下是不能直接使用的,每次定义新的msg,都需要编译后并重新生成Arduino IDE使用的ros_lib库。
(2)程序设计
参考代码如下:
// 导入库文件 #include #include #include #include #include #define ONE_WIRE_BUS 21// DS18B20的数据口引脚号 #define dht11Pin4// DHT11的数据口引脚号ros::NodeHandle nh; learning_test::sensor sensor_msg; // 使用自定义的数据类型 ros::Publisher pub("sensor", &sensor_msg); OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); dht11 DHT11; void setup(void) { nh.initNode(); nh.advertise(pub); Serial.begin(57600); sensors.begin(); } void loop(void) { sensors.requestTemperatures(); // Send the command to get temperatures DHT11.read(dht11Pin); Serial.print("Temperature for the device 1 (index 0) is: "); Serial.println(sensors.getTempCByIndex(0)); Serial.print("Humidity (%): "); Serial.println((float)DHT11.humidity, 2); Serial.print("Temperature (oC): "); Serial.println((float)DHT11.temperature, 2); sensor_msg.DS18B20_temperature = sensors.getTempCByIndex(0); sensor_msg.DHT11_temperature = (float)DHT11.temperature; sensor_msg.humidity = (float)DHT11.humidity; pub.publish(&sensor_msg); nh.spinOnce(); delay(10); }

需要注意的是,rosserial_python serial_node.py /dev/ttyACM0中的波特率是57600,所以在使用串口打印时波特率最好也设置成57600。
(3)测试
编译上面的代码,并分别在三个终端输入以下指令,
$ roscore $ rosrun rosserial_python serial_node.py /dev/ttyACM0 $ rostopic echo sensor

结果如下:
Arduino|Part6 -- 读取并发布多传感器数据(rosserial_arduino)
文章图片

    推荐阅读