1、Arduino和常见的传感器
传感器是把光,温度,湿度,气体浓度,压力强度,声强度等物理因素转化为电信号的器件。
1、蜂鸣器
蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音、报警音等提示信号
蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器
有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定
无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音
蜂鸣器有正负极,顶部印有+号的为正极,若蜂鸣器引脚没剪,则长的为正极
语法:tone(引脚,发声频率,发声时长)
int buzzerPin = 7; // 蜂鸣器连接的数字输出引脚
void setup() {
pinMode(buzzerPin, OUTPUT); // 设置蜂鸣器引脚为输出模式
}
void loop() {
// 产生蜂鸣器响声
tone(7,320,200); // 产生7,320,200Hz的音频信号
delay(1000); // 响声持续100毫秒
}
2、火焰传感器
原理:火焰传感器对火焰特别灵敏。它的原理是利用火焰产生的红外线对它非常敏感的特点,当火焰亮度变大时,发出的红外线越多,火焰传感器管脚间的阻抗变小,当火焰亮度变小时,发出的红外线越少,火焰传感器管脚间的阻抗变大。
小项目:火焰报警器
int buzzerPin=7; //设置蜂鸣器的数字引脚为7
int flamePin = 8; //设置火焰传感器的数字引脚为8
void setup() {
// put your setup code here, to run once:
pinMode(flamePin,INPUT);//将火焰传感器引脚设置为输入信号
pinMode(buzzerPin,OUTPUT);//将蜂鸣器引脚设置为输出信号
Serial.begin(9600);//设置波特率为9600
}
void loop() {
// put your main code here, to run repeatedly:
//读取火焰传感器的数字输出,高电平表示“1”,低电平表示“0”,以布尔值的形式储存在news变量中;
boolean news = digitalRead(flamePin);
if(news == 0)//感应到火焰!
{
Serial.println("警告,警告,发现火灾!");
tone(7,320,200);
delay(1000);
noTone(7);
}
else
{
Serial.println("正常!");
digitalWrite(buzzerPin, HIGH);
}
delay(500);
}
3、烟雾传感器
烟雾传感器对可燃气、烟雾等气体灵敏度高,烟雾传感器提供了两种输出方式:
数字量输出:通过板载电位器设定浓度阈值,当检测到环境气体浓度超过阈值时,通过数字引脚DO输出低电平。 模拟量输出:浓度越高,AO引脚输出的电压值越高,通过ADC采集的模拟值越高
#include <Arduino.h>
#define Sensor_AO A0
#define Sensor_DO 2
unsigned int sensorValue = 0;
const int flamePin = 8; //设置火焰传感器的数字引脚为8
const int buzzerPin=7; //设置蜂鸣器的数字引脚为7
//状态初始化
void setup()
{
pinMode(Sensor_DO, INPUT);
pinMode(flamePin,INPUT);//将8号引脚设置为输入信号
pinMode(buzzerPin,OUTPUT);//将7号引脚设置为输出信号
Serial.begin(9600);//设置波特率为9600
}
//循环执行
void loop()
{
//读取火焰传感器的数字输出,高电平表示“1”,低电平表示“0”,以布尔值的形式储存在news变量中;
boolean news = digitalRead(flamePin);
if(news == 0)//感应到火焰!
{
Serial.println("警告,警告,发现火灾!");
tone(7,320,200);
delay(1000);
digitalWrite(ledPin,LOW);
noTone(7);
}
else
{
Serial.println("B地区正常!");
digitalWrite(ledPin, LOW);
digitalWrite(buzzerPin, HIGH);
}
delay(500);
//读取连接到指定模拟引脚上的模拟传感器的模拟信号
sensorValue = analogRead(Sensor_AO);
Serial.print("烟雾浓度值 = ");
Serial.println(sensorValue);
if (digitalRead(Sensor_DO) == LOW)
{
Serial.println("危险!危险!发现烟雾");
tone(7,320,200);
}
else{
Serial.println("没有发现烟雾!");
}
delay(1000);
}
4、超声波传感器
由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如测距仪和物位测量仪等都可以通过超声波来实现。 HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。
超声波测距模块——触发信号后发射超声波,当超声波投射到物体而反射回来时,模块输出——回响信号,以触发信号和回响信号间的时间差,来判定物体的距离。
const int TrigPin = 3; //超声波的触发引脚连接引脚3
const int EchoPin = 2; //超声波的接受引脚连接引脚2
int distance; //定义全局变量,保存距离
void setup() {
Serial.begin(9600);
pinMode(TrigPin, OUTPUT);
pinMode(EchoPin, INPUT);
}
void loop() {
//将 TrigPin 设为低电平,然后延迟2微秒。将 TrigPin 设为高电平,延迟10微秒,然后再将其设为低电平。这个过程触发超声波传感器发射超声波信号。
digitalWrite(TrigPin, LOW);
delayMicroseconds(2); //微秒级别(1微秒 = 1/1,000,000秒)进行延迟
digitalWrite(TrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(TrigPin, LOW);
distance = pulseIn(EchoPin, HIGH) / 58.0; //使用 pulseIn() 函数测量 EchoPin 上的脉冲持续时间,该脉冲是超声波发射后接收到的回波信号的持续时间。实质是计算距离并换算成厘米
Serial.print(distance);
Serial.println("cm");
delay(100);用于在毫秒级别(1毫秒 = 1/1,000秒)进行延迟
}
2、Arduino和ROS
1、rosserial安装
rosserial提供的ROS通讯协议工作在Arduino的UART上,它让Arduino成为标准的ROS节点,可以发布和订阅ROS消息,发布TF转换,获取ROS系统时间
1、安装rosserial
sudo apt-get install ros-noetic-rosserial-arduino
sudo apt-get install ros-noetic-rosserial
rospack profile
2、安装ros_lib到Arduino IDE开发环境
cd Arduino/libraries
rm -rf ros_lib #如之前有,可以先删除
rosrun rosserial_arduino make_libraries.py .
3、检查ros_lib是否安装成功
-
重启Arduino IDE,查看文件->示例->ros_lib
2、发布订阅
1、(1)示例:arduino作为Publisher,发送hello world
Arduino端
/*
* rosserial Publisher Example
* Prints "hello world!"
*/
#include <ros.h>
#include <std_msgs/String.h>
ros::NodeHandle nh;
#创建发布或订阅
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
char hello[13] = "hello world!";
#实例化一个发布,主题叫chatter, 使用消息类型为std_msgs::String
void setup()
{
nh.initNode();
nh.advertise(chatter);
}
#Arduino的Setup函数,需要初始化ROS节点处理,并宣告所有的发布或订阅
void loop()
{
str_msg.data = hello;
chatter.publish( &str_msg );
nh.spinOnce();
delay(1000);
}
上位机端
1、运行roscore
roscore
2、新终端运行,/dev/ttyUSB0为Arduino设备
rosrun rosserial_python serial_node.py /dev/ttyUSB0
3、显示主题chatter,获取Arduino板反馈的信息
rostopic echo chatter
<launch>
<node pkg="rosserial_python" type="serial_node.py" name="serial_node" output="screen">
<param name="port" type="str" value="/dev/ttyUSB0"/>
</node>
<node pkg="rostopic" type="rostopic" name="echo_chatter" output="screen" args="echo chatter"/>
</launch>
3、示例:传感器数据的订阅
目前,这个代码中的消息不能是中文和标点符号,因为会出现乱码。目前没有找到解决方法。
#include <ros.h>
#include <std_msgs/String.h>
int buzzerPin = 7; //设置蜂鸣器的数字引脚为7
int flamePin = 8; //设置火焰传感器的数字引脚为8
ros::NodeHandle nh;
std_msgs::String flame_msg;
ros::Publisher flame_pub("flame_topic", &flame_msg);
void setup() {
// put your setup code here, to run once:
pinMode(flamePin, INPUT);//将火焰传感器引脚设置为输入信号
pinMode(buzzerPin, OUTPUT);//将蜂鸣器引脚设置为输出信号
Serial.begin(9600);//设置波特率为9600
nh.initNode();
nh.advertise(flame_pub);
}
void loop() {
// put your main code here, to run repeatedly:
boolean news = digitalRead(flamePin);
if(news == 0)//感应到火焰!
{
Serial.println("警告,警告,发现火灾!");
tone(7, 320, 200);
delay(1000);
noTone(7);
flame_msg.data = "Warning, warning, fire found";
flame_pub.publish(&flame_msg);
}
else
{
Serial.println("正常!");
digitalWrite(buzzerPin, HIGH);
flame_msg.data = "normal";
flame_pub.publish(&flame_msg);
}
nh.spinOnce();
delay(500);
}