本篇将使用rosserial_arduino读取温湿度传感器(DHT11)和数字温度传感器(DS18B20)的值,并在终端打印出来。
解决方法有两种:
(1)创建多个发布者,并分别发布消息;
(2)自定义msg,就可以发布各传感器的消息。
1 软硬件准备 (1)硬件准备
Arduino控制板一个
DHT11温湿度传感器一个
面包板一个
杜邦线若干
(2)库文件
这里主要用到ros和DS18B20相关的库,可以先学习一下DS18B20数字温度传感器的使用和DHT11温湿度传感器的使用
【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
结果如下:
文章图片
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|Part5 -- 如何使用Arduino的IIC总线(Wire)
- ROS|10款最赞的ROS机器人操作系统课程+为何ROS不是必须的
- ROS|ROS机器人操作系统学习
- 笔记|Serial.println()里用和不用F()的区别
- ROS|ROS kinetic自定义路径规划算法
- COAP协议 - arduino ESP32 M2M(端对端)通讯与代码详解
- 华维单片机原创经验大全|Arduino和树莓派单片机,第一次学习如何选()
- Arduino|树莓派 VS Arduino
- 科普|虚拟机 Ubuntu20.04 ROS安装完整过程