Part8 -- 读取并发布多传感器数据(rosserial_arduino)

        本篇将使用rosserial_arduino读取温湿度传感器(DHT11)和数字温度传感器(DS18B20)的值,并在终端打印出来。
        解决方法有两种:
            (1)创建多个发布者,并分别发布消息;
            (2)自定义msg,就可以发布各传感器的消息。

1 软硬件准备

(1)硬件准备
        Arduino控制板一个
        DHT11温湿度传感器一个
        面包板一个
        杜邦线若干
(2)库文件
        这里主要用到ros和DS18B20相关的库,可以先学习一下DS18B20数字温度传感器的使用DHT11温湿度传感器的使用

         连线方式如下:
Part8 -- 读取并发布多传感器数据(rosserial_arduino)

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

        结果如下:
Part8 -- 读取并发布多传感器数据(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 <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

        结果如下:
Part8 -- 读取并发布多传感器数据(rosserial_arduino)

上一篇:Windows系统下使用protobuf:protobuf的简介、安装、使用方法之详细攻略


下一篇:【mmwave】DeviceSurvey