自動開關燈裝置

 1、概述編程

1.實用意義

  目前安裝的燈開關常安置在牆壁上,每次開關燈須要起身到開關跟前纔可以進行開關燈,十分麻煩。故而旨在設計一款能夠藉助手機APP操控的自動開關燈裝置,同時不需拆裝原有開關,直接在原有開關上面添加便可,便捷實用。函數

2.功能概述

  開關燈功能經過舵機的擺動來實現,擺動角度經過測試獲得;oop

  爲了加強體驗感,在面板上方增長三個觸摸按鈕,能夠保證手觸碰開關燈功能學習

  爲了避免影響原有開關及減少佔據體積,裝置須要適應原有開關進行設計。測試

2、設計內容ui

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

  2.藍牙控制

  3.舵機角度調整

  4.觸摸開關控制舵機

3、實物拼裝this

1.外殼

   

  

 

2.觸摸開關

 

 

3.舵機位置

 

 

4、控制系統搭建spa

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),此處接D四、D六、D10.

5.SG90舵機連線

  舵機信號線分別接二、四、7,按顏色匹配接口。

 

5、程序編寫

 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路度數
 } }

 

6、運行測試

簡易版程序運行

#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讓舵機轉到指定位置
          }
     }
  }
}
相關文章
相關標籤/搜索