ESP8266和ROS收发消息读取模拟量控制LED亮度

本文介绍了如何使用ESP8266微控制器与ROS进行通信,涉及WiFi连接、TCP/IP通信及ROS节点的创建。通过示例代码展示了发布和订阅节点的实现,用于控制PWM输出和读取模拟信号。测试环境为ROS melodic和noetic,通过rqt_graph和rosbag工具进行了功能验证和数据记录。

如果需要ESP8266和ROS通信先阅读如下博客:


这里测试环境melodic和noetic都可行。

源代码如下:

#if (ARDUINO >= 100)
 #include <Arduino.h>
#else
 #include <WProgram.h>
#endif
#include <ESP8266WiFi.h>
#include <ros.h>
#include <std_msgs/String.h>
#include <std_msgs/Int16.h>
#include <std_msgs/Float64.h>
#include <Servo.h>
#include <rosserial_arduino/Adc.h>

//////////////////////
// WiFi Definitions //
//////////////////////
const char* ssid = "HUAWEI_WiFi";
const char* password = "cslgcslg";

IPAddress server(192, 168, 3, 153); // ip of your ROS server
IPAddress ip_address;
int status = WL_IDLE_STATUS;

WiFiClient client;

class WiFiHardware {

  public:
  WiFiHardware() {};

  void init() {
    // do your initialization here. this probably includes TCP server/client setup
    client.connect(server, 11411);
  }

  // read a byte from the serial port. -1 = failure
  int read() {
    // implement this method so that it reads a byte from the TCP connection and returns it
    //  you may return -1 is there is an error; for example if the TCP connection is not open
    return client.read();         //will return -1 when it will works
  }

  // write data to the connection to ROS
  void write(uint8_t* data, int length) {
    // implement this so that it takes the arguments and writes or prints them to the TCP connection
    for(int i=0; i<length; i++)
      client.write(data[i]);
  }

  // returns milliseconds since start of program
  unsigned long time() {
     return millis(); // easy; did this one for you
  }
};

Servo s;
int i;

void chatterCallback(const std_msgs::String& msg) {
  i = atoi(msg.data);
  s.write(i);
}


std_msgs::String str_msg;
rosserial_arduino::Adc adc_msg;
ros::Publisher chatter("chatter", &str_msg);
ros::Publisher p("adc", &adc_msg);
ros::Subscriber<std_msgs::String> sub("message", &chatterCallback);
ros::NodeHandle_<WiFiHardware> nh;
char hello[20] = "ESP8266 wifi alive!";


void setupWiFi()
{
  WiFi.begin(ssid, password);
  Serial.print("\nConnecting to "); Serial.println(ssid);
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) delay(500);
  if(i == 21){
    Serial.print("Could not connect to"); Serial.println(ssid);
    while(1) delay(500);
  }
  Serial.print("Ready! Use ");
  Serial.print(WiFi.localIP());
  Serial.println(" to access client");
}

int averageAnalog(int pin){
  int v=0;
  for(int i=0; i<2; i++) v+= analogRead(pin);
  return v/2;
}

void setup() {
  Serial.begin(115200);
  setupWiFi();
  delay(2000);
  s.attach(13);  // PWM pin
  nh.initNode();
  nh.advertise(chatter);
  nh.subscribe(sub);
  nh.advertise(p);
}

void loop() {
  str_msg.data = hello;
  chatter.publish( &str_msg );
  adc_msg.adc0 = averageAnalog( 0 );
  p.publish( &adc_msg );
  nh.spinOnce();
  delay( 10 );
}

简单解释一下,发布节点chatter,adc,订阅节点message。

  1. message提取数值作为PWM波送到13脚控制LED亮度(占空比);
  2. adc采集模拟量绘制曲线;
  3. chatter只用作发布消息,告知主机连接成功。

使用如下命令启动wemos D1和ROS:

  • roscore
  • rosrun rosserial_python serial_node.py tcp
  • rostopic pub /message std_msgs/String "data: '10'"
  • rostopic echo /adc
  • rostopic echo /chatter

过程如下:

roscore

rosrun rosserial_python serial_node.py tcp

主题列表:

rostopic pub /message std_msgs/String "data: '10'"

使用rqt_graph查看所有节点状态:

使用rosbag记录ADC数据并使用plot查看曲线:

关闭所有节点,只留下roscore,使用rosbag play查看记录数据:

 所有Arduino,stm32等单片机都可以借助ROS实现物联网硬件功能。


-Fin-


 

<think>好的,我现在需要帮助用户了解ESP8266ROS通过串口通信的方法。首先,用户可能已经有一些硬件,比如ESP8266开发板,可能用的是NodeMCU或者其他型号。我需要先确认基本的硬件连接必要的软件环境。 首先,ESP8266ROS通信可以通过串口,所以用户需要确保ESP8266的串口引脚正确连接到电脑或上位机。通常,ESP8266的TXRX引脚需要连接到USB转TTL模块,或者直接通过开发板的USB接口进行通信。这部分可能需要检查硬件连接,比如使用正确的波特率,比如115200,这在示例代码中常见。 接下来是软件环境。用户需要在Arduino IDE中安装ESP8266的支持库,这可以通过 Boards Manager 添加。同时,ROS方面,用户可能需要安装rosserial包,因为rosserial提供了与微控制器通信的协议。但根据引用[4],用户提到了micro_ros,这可能是一个更好的选择,因为它专为嵌入式设备设计,支持ROS2,而传统的rosserial可能更适合ROS1。不过用户的问题是关于ROS,没有明确是ROS1还是ROS2,可能需要区分。 根据引用[4],micro_ros可以用于ESP32,但用户问的是ESP8266。需要确认micro_ros是否支持ESP8266。目前,micro_ros官方支持的硬件主要是ESP32,而ESP8266可能不支持,所以可能需要使用rosserial instead。这可能是一个需要注意的地方,用户可能需要使用rosserial_arduino库来实现。 所以,步骤可能是: 1. 在Arduino IDE中安装ESP8266支持。 2. 安装rosserial库到Arduino IDE。 3. 编写代码,设置ESP8266作为rosserial的节点,通过串口与ROS主机通信。 4. 在ROS主机上运行rosserial_python节点,监听串口数据。 现在需要参考用户提供的引用。引用[3]中的代码示例是用于WiFi连接的ROS节点,但用户现在需要的是串口通信。所以可能需要调整代码,去掉WiFi部分,直接使用Serial.begin()初始化串口,并通过rosserial的协议传输数据。 例如,用户需要在ESP8266的代码中包含ROS相关的库,比如#include <ros.h>,并定义发布者订阅者。然后在setup()中初始化串口ROS节点,并在loop()中处理ROS消息。 同时,ROS主机端需要运行rosserial_python的节点,例如: rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0 _baud:=115200 这里需要注意串口设备的路径波特率是否匹配。 可能的示例代码结构: #include <ros.h> #include <std_msgs/String.h> ros::NodeHandle nh; std_msgs::String str_msg; ros::Publisher chatter("chatter", &str_msg); void setup() { Serial.begin(115200); nh.getHardware()->setPort(&Serial); nh.initNode(); nh.advertise(chatter); } void loop() { str_msg.data = "Hello ROS!"; chatter.publish(&str_msg); nh.spinOnce(); delay(1000); } 但需要确认ESP8266是否支持rosserial_arduino库,因为有些库可能对硬件有限制。例如,ESP8266的硬件串口可能与其他Arduino板不同,或者内存限制可能导致问题。如果遇到内存不足的情况,可能需要优化代码,减少发布的数据量或频率。 另外,用户可能需要安装rosserial_arduino在ROS主机上,确保能够正确解析来自ESP8266的数据。同时,检查串口权限,比如在Linux下需要将用户添加到dialout组,或者使用sudo chmod命令。 总结步骤: 1. 硬件连接:ESP8266的串口连接到电脑。 2. Arduino环境配置,安装必要的库。 3. 编写ESP8266代码,初始化ROS节点并通过串口通信。 4. ROS主机运行rosserial节点,接收发送数据。 需要验证这些步骤是否可行,是否有常见的错误,例如波特率不匹配、库版本问题等。同时,引用[4]提到micro_ros可能更适合,但若ESP8266不支持,可能需要使用传统方法。因此,在回答中需要指出两种可能性,但主要针对用户的问题,即串口通信,可能rosserial是更直接的解决方案。</think>### ESP8266ROS通过串口通信的实现方法 #### 1. 硬件准备 - **ESP8266开发板**(如NodeMCU) - **USB转TTL模块**(若开发板无内置USB接口) - **连接方式**:ESP8266的`TX`引脚连接USB转TTL的`RX`,`RX`连接`TX`,确保共地(GND)[^1]。 #### 2. 软件环境配置 - **Arduino IDE**:安装ESP8266支持库(通过`开发板管理器`添加`esp8266`平台)[^1]。 - **ROS环境**(以ROS1为例): - 安装`rosserial`包: ```bash sudo apt-get install ros-<distro>-rosserial-arduino sudo apt-get install ros-<distro>-rosserial ``` #### 3. ESP8266代码编写 在Arduino IDE中编写以下代码(需包含`ros_lib`库): ```cpp #include <ros.h> #include <std_msgs/String.h> ros::NodeHandle nh; // 定义发布器 std_msgs::String str_msg; ros::Publisher chatter("chatter", &str_msg); void setup() { Serial.begin(115200); // 初始化串口通信,波特率需与ROS端一致 nh.getHardware()->setPort(&Serial); // 绑定串口到ROS节点 nh.initNode(); nh.advertise(chatter); // 注册发布器 } void loop() { str_msg.data = "Hello from ESP8266"; // 消息内容 chatter.publish(&str_msg); // 发布消息 nh.spinOnce(); // 处理ROS回调 delay(1000); // 控制发布频率 } ``` #### 4. ROS主机端配置 - 启动ROS核心: ```bash roscore ``` - 运行`rosserial`节点监听串口: ```bash rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0 _baud:=115200 ``` - 确保`/dev/ttyUSB0`与实际设备路径一致,波特率与代码中一致[^3]。 #### 5. 验证通信 - 查看ROS话题列表: ```bash rostopic list ``` - 应显示`/chatter`话题。 - 监听消息内容: ```bash rostopic echo /chatter ``` - 成功时每秒接收一次`Hello from ESP8266`[^2]。 #### 注意事项 - **内存限制**:ESP8266内存较小,需简化消息类型(如避免复杂消息结构)[^4]。 - **波特率匹配**:确保ESP8266ROS端的波特率设置相同。 - **权限问题**:Linux系统需赋予串口设备权限: ```bash sudo chmod 666 /dev/ttyUSB0 ``` --- ###
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangrelay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值