本篇将使用rosserial_arduino读取温湿度传感器(DHT11)和数字温度传感器(DS18B20)的值,并在终端打印出来。
解决方法有两种:
(1)创建多个发布者,并分别发布消息;
(2)自定义msg,就可以发布各传感器的消息。
1 软硬件准备
(1)硬件准备
Arduino控制板一个
DHT11温湿度传感器一个
面包板一个
杜邦线若干
(2)库文件
这里主要用到ros和DS18B20相关的库,可以先学习一下DS18B20数字温度传感器的使用和DHT11温湿度传感器的使用
连线方式如下:
2 使用std_msgs
(1)程序
#include <ros.h>
#include <std_msgs/Float32.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <dht11.h>
#define ONE_WIRE_BUS 21 // DS18B20的数据口引脚号
#define dht11Pin 4 // 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 = 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 <ros.h>
#include <learning_test/sensor.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <dht11.h>
#define ONE_WIRE_BUS 21 // DS18B20的数据口引脚号
#define dht11Pin 4 // 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
结果如下: