2025年2月24日 星期一 甲辰(龙)年 腊月廿四 设为首页 加入收藏
rss
您当前的位置:首页 > 电子 > 设计制造与封装测试

自动开关灯装置

时间:03-28来源:作者:点击数:37

一、概述

1.实用意义

目前安装的灯开关常安置在墙壁上,每次开关灯需要起身到开关跟前才能够进行开关灯,十分麻烦。故而旨在设计一款可以借助手机APP操控的自动开关灯装置,同时不需拆装原有开关,直接在原有开关上面添加即可,便捷实用。

2.功能概述

开关灯功能通过舵机的摆动来实现,摆动角度通过测试得到;

为了增强体验感,在面板上方增加三个触摸按钮,可以保证手触碰开关灯功能

为了不影响原有开关及减小占据体积,装置需要适应原有开关进行设计。

二、设计内容

1.舵机控制版控制三路舵机

2.蓝牙控制

3.舵机角度调整

4.触摸开关控制舵机

三、实物拼装

1.外壳

2.触摸开关

 

3.舵机位置

四、控制系统搭建

1.NANO板连接

NANO板

2.16路舵机控制器

图 舵机控制器实物图

PWM,即Pulse-width modulation,是用占空比不同的方波来模拟“模拟输出”的一种方式,舵机的转动角度是通过调节PEM(脉冲宽度调制)信号的占空比来实现的。需要使用ARArduino上的PWM口控制。

电压舵机供电5-7v,接受高一点的电压;逻辑电路电压:3-5V;通信接口:使用i2c通信,就是SCL、SDA引脚;其中SCL接A5,SDA接A4

OE反使能脚:这个引脚低电平使能,不接的话模块内部默认已经接地使能了,所以正常使用可以不接。

学习资料:https://learn.adafruit.com/16-channel-pwm-servo-driver?view=all

3.蓝牙模块接线

RX接TX,TX接RX,VCC接5V,GND接GND

4.触摸开关

—接GND,+接5V,S接信号端(D3-D13),此处接D4、D6、D10.

5.SG90舵机连线

舵机信号线分别接2、4、7,按颜色匹配接口。

五、程序编写

1.蓝牙AT模式设置

  • void setup() {
  • // put your setup code here, to run once:
  • Serial.begin(38400);
  • }
  • void sendcmd()
  • {
  • Serial.println("AT");
  • while(Serial.available())
  • {
  • char ch;
  • ch = Serial.read();
  • Serial.print(ch);
  • } // Get response: OK
  • delay(1000); // wait for printing
  • Serial.println("AT+NAME=Sonny");
  • while(Serial.available())
  • {
  • char ch;
  • ch = Serial.read();
  • Serial.print(ch);
  • }
  • delay(1000);
  • Serial.println("AT+ADDR?");
  • while(Serial.available())
  • {
  • char ch;
  • ch = Serial.read();
  • Serial.print(ch);
  • }
  • delay(1000);
  • Serial.println("AT+PSWD=2113");
  • while(Serial.available())
  • {
  • char ch;
  • ch = Serial.read();
  • Serial.print(ch);
  • }
  • delay(1000);
  • /*Serial.println("AT+PSWD?");
  • while(Serial.available())
  • {
  • char ch;
  • ch = Serial.read();
  • Serial.print(ch);
  • }
  • delay(1000);*/
  • }
  • void loop() {
  • sendcmd();
  • }

2.Adafruit_PWMServoDriver库下载

链接:https://pan.baidu.com/s/1nwniWXiRJ5x7yIPrK--Iuw

提取码:xp1t

常用编程语句:

(1)设置频率

  • setPWMFreq(freq)
  • eg: pwm.setPWMFreq(1000); // set the PWM frequency to the maximum value of 1000Hz
  • Description: 用来调节PWM频率,范围 freq:40-1000Hz

(2)设置高低脉宽

  • 以下示例将导致通道15从低电平开始,在脉冲中高达25%左右
  • (在4096中打勾1024),转换回脉冲的低75%(勾选3072),并保持低位
  • 对于最后25%的脉冲:
  • eg: setPWM(15, 1024, 3072);

(3)

  • Example 1: (assumes that the LED0 output is used and
  • (delay time) + (PWM duty cycle)  100 %)
  • Delay time = 10 %; PWM duty cycle = 20 % (LED on time = 20 %; LED off time = 80 %).
  • Delay time = 10 % = 409.6 ~ 410 counts = 19Ah.
  • Since the counter starts at 0 and ends at 4095, we will subtract 1, so delay time = 199h
  • counts.
  • LED0_ON_H = 1h; LED0_ON_L = 99h (LED start turn on after this delay count to 409)
  • LED on time = 20 % = 819.2 ~ 819 counts.
  • LED off time = 4CCh (decimal 410 + 8191 = 1228)
  • LED0_OFF_H = 4h; LED0_OFF_L = CCh (LED start turn off after this count to 1228)
  • /***************************************************
  • 这是16通道PWM和伺服驱动器的一个例子,驱动16个伺服电机
  • ****************************************************/
  • #include <Wire.h> //16路舵机控制板头文件
  • #include <Adafruit_PWMServoDriver.h> //16路舵机控制板头文件
  • Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();//以这种方式调用,它使用默认地址0x40。
  • //Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);//也可以用不同的地址调用它
  • void setServoPulse(uint8_t n, double pulse); //以秒为单位设置脉冲长度函数
  • void pwm_text(); //16路舵机控制板测试函数,效果是来回转动,16路同时
  • /*根据你的伺服制作,脉冲宽度最小和最大可能变化,你想要这些尽可能小大而不碰到
  • 硬停止,对于最大范围。你必须调整它们以匹配你的伺服系统!*/
  • #define SERVOMIN 102 //这是“最小”脉冲长度计数(在4096中)
  • #define SERVOMAX 408 //这是“最大”脉冲长度计数(在4096中)
  • void setup() {
  • Serial.begin(9600);
  • Serial.println("16 channel Servo test!");
  • pwm.begin();
  • pwm.setPWMFreq(60); //设置频率60Hz 可用50Hz 40-1000//测试对电机的速度没有影响
  • }
  • /********************主函数********************/
  • void loop() {
  • pwm_text(); //16路舵机控制板测试函数,效果是来回转动,16路同时
  • }
  • /********************************************/
  • void pwm_text(){ //16路舵机控制板测试函数,效果是来回转动,16路同时
  • //每次驱动一个伺服驱动器
  • for (uint16_t pulse = SERVOMIN; pulse < SERVOMAX; pulse++)
  • {
  • pwm.setPWM(15, 0, pulse); //pulse翻译为脉冲
  • }
  • delay(500);
  • for (uint16_t pulse = SERVOMAX; pulse > SERVOMIN; pulse--)
  • {
  • pwm.setPWM(15, 0, pulse); //pulse翻译为脉冲
  • }
  • delay(500);
  • }
  • //如果您想以秒为单位设置脉冲长度,则可以使用此函数。
  • //例如SET伺服脉冲(0,0.001)是一个1毫秒的脉冲宽度,但不精确!
  • void setServoPulse(uint8_t n, double pulse) //以秒为单位设置脉冲长度函数
  • {
  • double pulselength;//精度浮点数
  • pulselength = 1000000; // 1,000,000 us per second 每秒100万
  • pulselength /= 60; // 60 Hz
  • Serial.print(pulselength); Serial.println(" us per period");
  • pulselength /= 4096; // 12 bits of resolution 12位分辨率
  • Serial.print(pulselength); Serial.println(" us per bit");
  • pulse *= 1000;
  • pulse /= pulselength;
  • Serial.println(pulse);
  • pwm.setPWM(n, 0, pulse);
  • }

3.舵机驱动程序

(1)舵机频率设置

  • pwm.setPWMFreq(1000)

(2)

  • pwm.setPWM(15, 1024, 3072)

(3)

  • #include <Wire.h>
  • #include <Adafruit_PWMServoDriver.h>
  • //默认地址 0x40
  • Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
  • //9g舵机 高电平宽度在20ms内通过控制脉冲宽度范围0.5ms~2.5ms
  • #define SERVOMIN 102 // this is the 'minimum' pulse length count (out of 4096) 0度
  • #define SERVOMAX 512 // this is the 'maximum' pulse length count (out of 4096) 180度
  • void setup() {
  • Serial.begin(9600);
  • Serial.println("16 channel Servo test!");
  • pwm.begin();
  • pwm.setPWMFreq(50); //频率 50Hz,最高60Hz
  • }
  • void setServoPulse(uint8_t n, double pulse) {
  • double pulselength;
  • pulselength = 1000000; // 1,000,000 us per second
  • pulselength /= 50; // 50 Hz
  • Serial.print(pulselength); Serial.println(" us per period");
  • pulselength /= 4096; // 12 bits of resolution
  • Serial.print(pulselength); Serial.println(" us per bit");
  • pulse *= 1000;
  • pulse /= pulselength;
  • Serial.println(pulse);
  • pwm.setPWM(n, 0, pulse);
  • }
  • //设置9g舵机角度
  • void servo_9g_write(uint8_t n,int Angle)
  • {
  • double pulse = Angle;
  • pulse = pulse/90 + 0.5;
  • setServoPulse(n,pulse);//0到180度映射为0.5到2.5ms
  • }
  • void loop()
  • {
  • unsigned char serialRead;
  • if (Serial.available() > 0)
  • {
  • serialRead = Serial.read();
  • servo_9g_write(2,serialRead);//控制第1路度数
  • servo_9g_write(4,serialRead);//控制第2路度数
  • servo_9g_write(7,serialRead);//控制第3路度数
  • }
  • }

六、运行测试

简易版程序运行

  • #include <Servo.h>
  • Servo myservo1; // 创建一个舵机对象,左侧灯开关
  • Servo myservo2; // 创建一个舵机对象,中间灯
  • Servo myservo3; // 创建一个舵机对象,右侧灯开关
  • void setup()
  • {
  • pinMode(10,INPUT); //设置引脚 10 为输入模式,左开关
  • pinMode(6,INPUT); //设置引脚 6 为输入模式 ,中间开关
  • pinMode(4,INPUT); //设置引脚 4 为输入模式
  • Serial.begin(9600); //设置波特率为9600
  • myservo1.attach(2); // 将引脚9上的舵机与声明的舵机对象连接起来
  • myservo3.attach(12); // 将引脚9上的舵机与声明的舵机对象连接起来
  • myservo2.attach(3); // 将引脚9上的舵机与声明的舵机对象连接起来
  • }
  • void loop()
  • {
  • // put your main code here, to run repeatedly:
  • delay(200); //延时200毫秒
  • while(Serial.available())
  • {
  • char c=Serial.read();
  • Serial.println(c);
  • if(c=='0')
  • {
  • Serial.println("BT is ready!");
  • for(int pos = 0; pos < 45; pos += 1){ // 舵机从0°转到180°,每次增加1°
  • myservo1.write(pos); // 给舵机写入角度
  • delay(15); // 延时15ms让舵机转到指定位置
  • }
  • }
  • if(c=='1')
  • {
  • for(int pos = 45; pos>=1; pos-=1) { // 舵机从180°转回到0°,每次减小1°
  • myservo1.write(pos); // 写角度到舵机
  • delay(15); // 延时15ms让舵机转到指定位置
  • }
  • }
  • if(c=='2')
  • {
  • Serial.println("BT is ready!");
  • for(int pos = 0; pos < 180; pos += 1){ // 舵机从0°转到180°,每次增加1°
  • myservo2.write(pos); // 给舵机写入角度
  • delay(15); // 延时15ms让舵机转到指定位置
  • }
  • }
  • if(c=='3')
  • {
  • for(int pos = 180; pos>=1; pos-=1) { // 舵机从180°转回到0°,每次减小1°
  • myservo2.write(pos); // 写角度到舵机
  • delay(15); // 延时15ms让舵机转到指定位置
  • }
  • }
  • if(c=='4')
  • {
  • Serial.println("BT is ready!");
  • for(int pos = 0; pos < 180; pos += 1){ // 舵机从0°转到180°,每次增加1°
  • myservo3.write(pos); // 给舵机写入角度
  • delay(15); // 延时15ms让舵机转到指定位置
  • }
  • }
  • if(c=='5')
  • {
  • for(int pos = 180; pos>=1; pos-=1) { // 舵机从180°转回到0°,每次减小1°
  • myservo3.write(pos); // 写角度到舵机
  • delay(15); // 延时15ms让舵机转到指定位置
  • }
  • }
  • }
  • }
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门