此项目名为智能城市设计,是本人物联网短距离通信技术的课程设计。它属于入门级别的设计,却在课程答辩时得到了老师和同学的一致好评,所以想分享给大家希望能够帮助更多的同道中人。但是仅适用新手入门小白,对于资深大佬而言较为简单。
一、项目介绍
智能城市项目共分为五个部分,即交通信号灯系统、火灾报警系统、环境监测系统、路灯控制系统和智能垃圾桶。在下打算用六篇文章来发布,分别对应这五个系统和最后的总结。在文章后面附上模块代码都可以单独编译上传,便于大家使用。本文章介绍第五个模块——智能垃圾桶。
二、模块介绍
智能垃圾桶使用了一个舵机、两个超声波传感器、一个红色提示灯。第一个超声波传感器放在垃圾桶外部用来检测人与垃圾桶的距离,当人靠近垃圾桶时,舵机转动打开垃圾桶。第二个超声波传感器用来检测垃圾桶是否装满,当桶内垃圾达到一定高度时,超声波传感器就会探测到垃圾,系统会认为垃圾桶已经装满。此时就会亮起提示灯,并且OLED显示屏上也会提示垃圾已经装满。这样以来就能动态检测城市内每个垃圾桶的状态,环卫工人就能定点清理城市内已装满的垃圾桶,使城市更加干净整洁。
三、所需材料
舵机SG90、两个HC-SR04超声波传感、红色LED发光二极管、蓝牙HC-06/HC-05、SSD1315 OLED显示屏、迷你垃圾桶、arduino uno r3开发板、杜邦线若干。还需要手机app“蓝牙调试器”来连接蓝牙查看数值,这个大家直接在CSDN上搜索下载即可。
四、接线
SG90引脚连接表:
引脚编号 | SG90 引脚名称 | Arduino Uno R3 引脚名称 |
1 | Vcc | 5V |
2 | D9(PWM) | D5 |
3 | GND | GND |
HC-SR04.1传感器引脚连接表:
引脚编号 | HC-SR04引脚名称 | Arduino Uno R3 引脚名称 |
1 | Vcc | 5V |
2 | TRIG | D3 |
3 | GND | GND |
4 | ECHO | D4 |
HC-SR04.2传感器引脚连接表:
引脚编号 | HC-SR04引脚名称 | Arduino Uno R3 引脚名称 |
1 | Vcc | 5V |
2 | TRIG | D7 |
3 | GND | GND |
4 | ECHO | D6 |
SSD1315 OLED显示屏引脚连接表:
引脚编号 | OLED显示引脚名称 | Arduino Uno R3 引脚名称 |
1 | Vcc | 3.3V |
2 | SCL | A5 |
3 | GND | GND |
4 | SDA | A4 |
LED发光二极管引脚连接表:
引脚编号 | LED发光二极管 引脚名称 | Arduino Uno R3 引脚名称 |
1 | Vcc | D11 |
3 | GND | GND |
五、代码
#include <Adafruit_SSD1306.h> // 引入Adafruit SSD1306 OLED显示屏库
#define SCREEN_WIDTH 128 // 定义OLED显示屏的宽度
#define SCREEN_HEIGHT 64 // 定义OLED显示屏的高度
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // 初始化OLED显示屏,使用I2C通信,-1表示复位引脚不使用
#include<Servo.h> // 引入Servo库
const int trigPin1 = 3; // 超声波传感器1的触发引脚
const int echoPin1 = 4; // 超声波传感器1的回声引脚
const int trigPin2 = 7; // 超声波传感器2的触发引脚
const int echoPin2 = 6; // 超声波传感器2的回声引脚
#define SERVO_PIN 5 // 舵机的控制引脚
#define OPEN_ANGLE 90 // 舵机打开的角度
#define CLOSE_ANGLE 0 // 舵机关闭的角度
#define THRESHOLD_CM 8 // 第一个传感器的距离阈值(厘米)
#define THRESHOLD1_CM 3 // 第二个传感器的距离阈值(厘米)
Servo myservo; // 创建Servo对象,控制舵机
int RED1 =11; // 定义红色LED引脚
long duration1, distance1; // 用于存储第一个传感器的测量时间和距离
long duration2, distance2; // 用于存储第二个传感器的测量时间和距离
void setup() {
// 初始化超声波传感器的引脚模式
pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(RED1, OUTPUT); // 初始化红色LED引脚模式
Serial.begin(9600); // 初始化串口通信
myservo.attach(SERVO_PIN); // 将舵机控制引脚连接到Servo对象
myservo.write(CLOSE_ANGLE); // 初始状态关闭舵机
// 注意:Serial.begin(9600); 被重复调用了,可以删除一行
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 初始化OLED显示屏
Serial.println(F("SSD1306 allocation failed")); // 如果初始化失败,打印错误信息
for(;;); // 初始化失败则无限循环
}
display.display(); // 显示OLED屏幕
delay(1000); // 延迟1秒
}
void loop() {
measureDistance(trigPin1, echoPin1, &distance1); // 测量第一个传感器的距离
measureDistance(trigPin2, echoPin2, &distance2); // 测量第二个传感器的距离
// 根据第一个传感器的距离控制舵机
if (distance1 < THRESHOLD_CM) {
myservo.write(OPEN_ANGLE); // 如果距离小于阈值,打开舵机
}
else {
myservo.write(CLOSE_ANGLE); // 否则关闭舵机
}
// 根据第二个传感器的距离控制红色LED
if (distance2 < THRESHOLD1_CM)
{
digitalWrite(11, HIGH); // 如果距离小于阈值,点亮红色LED
}
else {
digitalWrite(11, LOW); // 否则熄灭红色LED
}
// 通过串口打印两个传感器的距离
Serial.print("Distance1: ");
Serial.print(distance1);
Serial.println(" cm");
Serial.print("Distance2: ");
Serial.print(distance2);
Serial.println(" cm");
// 在OLED显示屏上显示信息
display.clearDisplay(); // 清除显示屏
display.setTextSize(1); // 设置文本大小为1
display.setTextColor(WHITE); // 设置文本颜色为白色
display.setCursor(0, 0); // 设置光标位置
display.print("Basurero: "); // 显示“Basurero: ”(垃圾桶)
if (distance2 < THRESHOLD1_CM) {
display.println("Llena"); // 如果第二个传感器的距离小于阈值,显示“Llena”(满的)
} else {
display.println("No llena"); // 否则显示“No llena”(不满的)
}
display.display(); // 更新OLED显示屏
delay(500); // 延迟500毫秒后继续循环
}
// 自定义函数,用于测量超声波传感器的距离
void measureDistance(int trigPin, int echoPin, long *distance) {
digitalWrite(trigPin, LOW); // 确保触发引脚为低电平
delayMicroseconds(2); // 等待2微秒
digitalWrite(trigPin, HIGH); // 发送10微秒的高电平脉冲到触发引脚
delayMicroseconds(10); // 等待10微秒
digitalWrite(trigPin, LOW); // 停止触发
*distance = pulseIn(echoPin, HIGH); // 读取Echo引脚上的脉冲持续时间
*distance = *distance * 0.0343/2; // 将微秒转换为厘米(声速约为343 m/s 或 0.0343 cm/us)
}