问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Arduino结合超声波模块和舵机绘制二维图像

创作时间:
作者:
@小白创作中心

Arduino结合超声波模块和舵机绘制二维图像

引用
CSDN
1.
https://blog.csdn.net/opdog/article/details/139406865

Arduino结合超声波模块和舵机可以实现简单的二维图像绘制功能。本文将详细介绍如何通过Arduino控制舵机旋转并读取超声波模块的数据,最终在串口监视器中显示二维点阵图。

原理

舵机每次增加一度,读取当前的超声波模块值,得到一个携带障碍物坐标信息的极坐标系,并将极坐标系转为笛卡尔坐标系,打印在串口监视器或者可以发送给电脑使用MATLAB等软件处理。

模拟效果

设置距离为82厘米保持不动,舵机转一圈。得到的二维点阵图如下:

代码实现

第一步:控制舵机旋转

使用Arduino自带库控制舵机旋转180°。这里只是举例:

#include <Servo.h>

void setup() 
{
  myservo.attach(9);  // 舵机控制 9针脚
}

void loop()
{
  int pos; // 角度存储变量 
  for (pos = 0; pos <= 180; pos++) 
  {  
    myservo.write(pos); // 将舵机转动到指定角度 ()
    delay(15); // 稍微等待以确保舵机有时间移动到新位置  
  }
}

第二步:读取超声波模块距离

定义一个读取超声波模块距离的函数:

int read_distance()
{
  int distance; 
  digitalWrite(TrigPin, LOW);
  delayMicroseconds(2);   
  digitalWrite(TrigPin, HIGH);
  delayMicroseconds(10);  
  digitalWrite(TrigPin, LOW);
  distance = pulseIn(EchoPin, HIGH)/58.0;  
  return distance;
}

第三步:设置超声波模块针脚

setup()函数中添加针脚设置:

void setup() 
{
  Serial.begin(9600);
  pinMode(TrigPin, OUTPUT);
  pinMode(EchoPin, INPUT);
  myservo.attach(9);  // 控制线连接数字9
}

第四步:读取距离并转换坐标

loop()函数中添加读取距离的代码:

for (pos = 0; pos <= 180; pos++)
{
  myservo.write(pos); // 将舵机转动到指定角度 ()
  delay(15); // 稍微等待以确保舵机有时间移动到新位置  
  distance = read_distance(); // 读取距离  
}

将极坐标系转换为笛卡尔坐标系:

// 将角度转换为弧度,并计算x和y坐标  
rad = pos * (PI / 180.0);  
x = 13 + (int)(distance * cos(rad) / 8.0); // 假设除以8是一个合适的缩放 
//之所以x要+13,是因为我们的矩阵的宽度是27.这样可以x的起始坐标居中。
y = (int)(distance * sin(rad) / 16.0);     

第五步:记录坐标数据

创建一个27*27的二维数组来记录坐标数据:

int m[y][x];
//y与x的乘积<=27^2  

完整的loop()函数:

void loop() {  
  int distance;  
  int pos; // 角度存储变量  
  double rad;  
  
  for (pos = 0; pos <= 180; pos++) {  
    myservo.write(pos); // 将舵机转动到指定角度 ()
    delay(15); // 稍微等待以确保舵机有时间移动到新位置  
    distance = read_distance(); // 读取距离  
  
    // 将角度转换为弧度,并计算x和y坐标  
    rad = pos * (PI / 180.0);  
    x = 13 + (int)(distance * cos(rad) / 8.0); // 假设除以4是一个合适的缩放 
    y = (int)(distance * sin(rad) / 16.0); // 向下为正,所以需要减去  
  
    // 确保x和y在数组的有效范围内  
    if (x >= 0 && x < 27 && y >= 0 && y < 27) {  
      m[y][x] = 1; // 更新数组
    }  
  }
}

最终代码

完整的Arduino代码如下:

#include <Servo.h>  
#include <math.h>  
const int TrigPin = 3;  
const int EchoPin = 2;  

int read_distance()
{
  int distance; 
  digitalWrite(TrigPin, LOW);
  delayMicroseconds(2);   
  digitalWrite(TrigPin, HIGH);
  delayMicroseconds(10);  
  digitalWrite(TrigPin, LOW);
  distance = pulseIn(EchoPin, HIGH)/58.0;  
  return distance;
}

const int ServoPin = 9; // 控制线连接的数字引脚  
Servo myservo;  // 定义Servo对象来控制  
int m[27][27] = {0}; // 初始化二维数组  

void setup() 
{
  Serial.begin(9600);
  pinMode(TrigPin, OUTPUT);
  pinMode(EchoPin, INPUT);
  myservo.attach(9);  // 控制线连接数字9
}

void loop() {  
  int distance;  
  int pos; // 角度存储变量  
  double rad;  
  int x, y,i,j;  
  
  for (pos = 0; pos <= 180; pos++) {  
    myservo.write(pos); // 将舵机转动到指定角度 ()
    delay(15); // 稍微等待以确保舵机有时间移动到新位置  
    distance = read_distance(); // 读取距离  
  
    // 将角度转换为弧度,并计算x和y坐标  
    rad = pos * (PI / 180.0);  
    x = 13 + (int)(distance * cos(rad) / 8.0); // 假设除以4是一个合适的缩放 
    y = (int)(distance * sin(rad) / 16.0); // 向下为正,所以需要减去  
  
    // 确保x和y在数组的有效范围内  
    if (x >= 0 && x < 27 && y >= 0 && y < 27) {  
      m[y][x] = 1; // 更新数组
    }  
  
    // 打印当前角度和检测到的距离
    Serial.print("Angle: ");  
    Serial.print(pos);  
    Serial.print(", Distance: ");  
    Serial.println(distance);  
  }  

  // 打印m数组。
  for (i = 0; i < 26; i++) {
    for (j = 0; j < 28; j++) {
      Serial.print(".");
      if(m[i][j]==0)
      {
        Serial.print(".");
      } 
      else Serial.print(m[i][j]);
      m[i][j]={0};
    }
    Serial.println(";");
    delay(200);
    // 在每行末尾打印换行符
  }  

  myservo.write(0);//舵机归位
  delay(5000);//5秒后再次扫描。
}

通过以上步骤,你可以使用Arduino、超声波模块和舵机实现简单的二维图像绘制功能。这个项目不仅可以作为学习Arduino控制硬件的实践案例,还可以应用于机器人避障、环境监测等领域。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号