仿照小米台灯做一款智能台灯
仿照小米台灯做一款智能台灯 学校电子电路设计大赛中有一题为设计一款智能台灯,思来想去想不出哪种外观比较好,最后决定copy一
仿照小米台灯做一款智能台灯
学校电子电路设计大赛中有一题为设计一款智能台灯,思来想去想不出哪种外观比较好,最后决定copy一下雷总的台灯外观。
一、准备
智能台灯系统基于Arduino平台,采用两块ATmega8主控芯片,综合运用物联网技术、传感技术。
需要使用[贝壳物联](https://www.bigiot.net/)注册一个账号,获得设备id和APIKEY
将获得id和apikey填入master主机代码中对应位置
二、功能
实现自动调光功能,人来灯亮,人走灯灭(热释电传感 器),并具有坐姿提醒功能,当使用者距离台灯太近时, 台灯能及时产生提示。
能够实时显示时间和日期,并具有闹铃提醒功能。
能够检测环境温度和电池电量,并实时显示,在电量不 足时能发出提示。
实现台灯定时开关。
可实现远程控制台灯亮灭,并能对亮度进行调整。
可实现对光的切换,如白光切换成暖光。
上述提醒功能均为语音提示,开关为触摸开关。
三、电路图
四、使用方法
在贝壳物联客户端输入5位数字 10XXX 调节冷光亮度,XXX从0到255
20XXX 调节暖光亮度,XXX从0到255
3XXXX 同时调节冷光和暖光,XXX从0到255
4XXXX 闹钟功能,XXXX为24小时制时间
5XXXX 定时打开台灯,XXXX为24小时制时间
6XXXX 定时关闭台灯,XXXX为24小时制时
7000X 人体感应功能,X为1表示打开,0为关闭
五、3D模型
台灯全部采用3D打印,打印文件可以从这里下载
六、实物照片
七、视频演示
https://www.zhihu.com/video/933037759271251968
外观
https://www.zhihu.com/video/933032345850761216
触摸开关
https://www.zhihu.com/video/933033160694960128
过近提醒
https://www.zhihu.com/video/933033191024070656
调光
https://www.zhihu.com/video/933034110826442752
定时开
https://www.zhihu.com/video/933034132100022272
定时关
https://www.zhihu.com/video/933034151179862016
闹钟
https://www.zhihu.com/video/933034179692736512
人体感应
八、代码
master主机arduino代码
#include <aJSON.h> n#include <dht11.h> // dht11头文件n#include <SPI.h> //=======================n#include <Wire.h> // Oledn#include <Adafruit_GFX.h> // 头文件n#include <Adafruit_SSD1306.h> //=======================nn#define LED_warm 5 // LED暖光正极连接针脚5n#define LED_cold 6 // LED冷光正极连接针脚6n#define Buzzer 7 //蜂鸣器n#define ADDRESS_DS1307 0x68 //I2C addressn#define Button 2 //The Touching Buttonn#define Pyro 3 //热释电n//============= BigIoT登录信息 ===========nString DEVICEID="3670"; //IDnString APIKEY="31166021a"; //APIKEYn//=========================================nn//================ BigIoT数据 =============nunsigned long lastCheckInTime = 0; //记录上次报到时间nconst unsigned long postingInterval = 20000; // 每隔20秒向服务器报到一次nunsigned long lastUpdateTime = 0;//上次上传数据时间nString inputString = ""; //从BigIoT获取的数据nboolean stringComplete = false;nboolean CONNECT = true; nchar* parseJson(char *jsonString);n//=========================================nn//========温度湿度=======ndht11 DHT11;n#define DHT11PIN 4n//=======================nn//======== 外部时钟 =====nbyte timeBcd[] = {0, 0, 0, 0, 0, 0, 0};nint Time[3]={0,0,0}; //hour,minute,secondn//time = {year, month, date, day, hours, minutes, seconds};n//=======================nn//====== Clock Time ====nint Clock[2]={24,61};n//======================nn//== 全局计时 ==nint count1=0;nint count2=0; //发送数据nint count3=0; //选择温湿度发送nint count4=0; //热释电延时n//==============nn//== 蜂鸣器开启 ==nbool BuzzerOpen=0;n//================nn//=== Timing ====nint Timing_Open[2]={24,60};nint Timing_Close[2]={24,60};n//===============nn//=== LED Control ====nint LED_warm_power=0;nint LED_cold_power=0;n//====================nn//==== Battery Voltage =====nfloat Battery=0.0;n//==========================nnvoid setup() n{n attachInterrupt(digitalPinToInterrupt(Button), Button_Pressed, FALLING);n attachInterrupt(digitalPinToInterrupt(Pyro), Pyro_Change, CHANGE);n pinMode(LED_warm, OUTPUT);n pinMode(LED_cold, OUTPUT);n pinMode(Buzzer, OUTPUT);n Serial.begin(115200);n Wire.begin(); // 加入 I2C 总线,作为主机n}nnvoid loop() n{n n Get_Time();n Clock_on();n Check_Battery();n Check_Timing();n n Wire.beginTransmission(7); //发送数据到设备号为7的从机n if(count1>900) //循环时间函数n {n count2++;n count4++;n count1=0;n Serial.println(count2);n Serial.print(Time[0]);Serial.print(':');Serial.print(Time[1]);Serial.print(':');Serial.println(Time[2]);n Serial.print("Battery: ");Serial.println(Battery);n Serial.print("Pyro: ");Serial.println(digitalRead(Pyro));n }nn if(count2>5) n {n checkIn(); //登陆函数n SendTempHum();n count2=0;n }n if (count4>60)n {n LED_warm_power=0;n LED_cold_power=0;n count4=0;n }n analogWrite(LED_warm,LED_warm_power);n analogWrite(LED_cold,LED_cold_power);nn F_BigIoT(); n count1++;n}nnvoid Check_Timing()n{n if (Timing_Open[0]==Time[0]&&Timing_Open[1]==Time[1])n {n LED_warm_power=255;n LED_cold_power=255;n count4=0;n }n if (Timing_Close[0]==Time[0]&&Timing_Close[1]==Time[1])n {n LED_warm_power=0;n LED_cold_power=0;n }n}nnvoid Pyro_Change()n{n if ((LED_warm_power==0)&&(LED_cold_power==0))n {n LED_warm_power=255;n LED_cold_power=255;n count4=0;n }n else count4=0;n}nnvoid Button_Pressed()n{n if (LED_warm_power!=255&&LED_warm_power!=204&&LED_warm_power!=153&&LED_warm_power!=102&&LED_warm_power!=51&&LED_warm_power!=0) LED_warm_power=306;n LED_warm_power-=51;n if (LED_warm_power<0) LED_warm_power=255;n if (LED_cold_power!=255&&LED_cold_power!=204&&LED_cold_power!=153&&LED_cold_power!=102&&LED_cold_power!=51&&LED_cold_power!=0) LED_cold_power=306;n LED_cold_power-=51;n if (LED_cold_power<0) LED_cold_power=255;n count4=0;n}nnvoid Check_Battery()n{n int sensorValue = analogRead(A0);n Battery = sensorValue * (5.0 / 1023.0);n if (Battery<3.4) digitalWrite(Buzzer,HIGH);n else digitalWrite(Buzzer,LOW);n}nnvoid Clock_on()n{n if (Clock[0]==Time[0]&&Clock[1]==Time[1]&&Time[3]%2==0) digitalWrite(Buzzer, HIGH);n else digitalWrite(Buzzer, LOW);n}nnvoid Get_Time()n{n Wire.beginTransmission(ADDRESS_DS1307);n Wire.write(0x00);n Wire.endTransmission();n Wire.requestFrom(ADDRESS_DS1307, 7);n if (Wire.available() >= 7)n {n for (int i = 0; i < 7; i++)n {n timeBcd[6-i] = Wire.read();n }n }n Time[0]=(timeBcd[4]/16)*10+timeBcd[4]%16;n Time[1]=(timeBcd[5]/16)*10+timeBcd[5]%16;n Time[2]=(timeBcd[6]/16)*10+timeBcd[6]%16;n}nnvoid SendTempHum() // 温湿度模块 n{n int chk = DHT11.read(DHT11PIN); n int Temperature_float=(float)DHT11.temperature; //温度n int Humidity_float=(float)DHT11.humidity; //湿度n if(count3==1)n update1(DEVICEID,"3382",Temperature_float); //上传温度 n if(count3==2) n update1(DEVICEID,"3384",Humidity_float); //上传湿度 nn char Sending[10]="";n char Temprature[2]="";n char Humidity[2]="";n char BatteryCent[2]="";n itoa(Temperature_float,Temprature,10);n itoa(Humidity_float,Humidity,10);n itoa(((Battery-3.5)/0.8)*100,BatteryCent,10);n if (Temperature_float<10.0)n {n Temprature[1]=Temprature[0];n Temprature[0]='0';n }n if (Humidity_float<10.0)n {n Humidity[1]=Humidity[0];n Humidity[0]='0';n }n if (((Battery-3.5)/0.8)*100<10.0)n {n BatteryCent[1]=BatteryCent[0];n BatteryCent[0]='0';n }n strcat(Sending,Temprature);n strcat(Sending,",");n strcat(Sending,Humidity);n strcat(Sending,",");n strcat(Sending,BatteryCent);n strcat(Sending,"n");n Serial.println(Sending);n Wire.beginTransmission(7); //发送数据到设备号为7的从机n Wire.write(Sending); // 发送变量n Wire.endTransmission(); // 停止发送n n if (count3==2) count3=0;n count3++;n}nnvoid checkIn() n{ n //登陆函数n if (!CONNECT) n {n Serial.print("+++");n delay(500); n Serial.print("rn"); n delay(1000);n Serial.print("AT+RSTrn"); n delay(6000);n CONNECT=true;n lastCheckInTime=0;n }n elsen {n Serial.print("{"M":"checkin","ID":"");n Serial.print(DEVICEID);n Serial.print("","K":"");n Serial.print(APIKEY);n Serial.print(""}rn");n lastCheckInTime = millis(); n }n}nnvoid processMessage(aJsonObject *msg)n{ //接受函数n aJsonObject* method = aJson.getObjectItem(msg, "M");n aJsonObject* content = aJson.getObjectItem(msg, "C"); n aJsonObject* client_id = aJson.getObjectItem(msg, "ID"); n if (!method) {n return;n }n String M=method->valuestring;n String C=content->valuestring;n String F_C_ID=client_id->valuestring;n if(M=="say")n { //接收字符串n long data=C.toInt();n switch (data/10000)n {n case 0:n LED_warm_power=LED_cold_power=0;n break;n case 1:n LED_warm_power=data%1000;n LED_cold_power=0;n break;n case 2:n LED_warm_power=0;n LED_cold_power=data%1000;n break;n case 3:n LED_warm_power=data%1000;n LED_cold_power=data%1000;n break;n case 4:n Clock[0]=(data%10000)/100;n Clock[1]=data%100;n break;n case 5:n Timing_Open[0]=(data%10000)/100;n Timing_Open[1]=data%100;n break;n case 6:n Timing_Close[0]=(data%10000)/100;n Timing_Close[1]=data%100;n break;n }n }n}nnvoid sayToClient(String client_id, String content)n{n Serial.print("{"M":"say","ID":"");n Serial.print(client_id);n Serial.print("","C":"");n Serial.print(content);n Serial.print(""}rn");n lastCheckInTime = millis();n}nnvoid update1(String did, String inputid, float value)n{ n //上传函数n Serial.print("{"M":"update","ID":"");n Serial.print(did);n Serial.print("","V":{"");n Serial.print(inputid);n Serial.print("":"");n Serial.print(value);n Serial.println(""}}");n lastCheckInTime = millis();n lastUpdateTime= millis(); n}nnvoid serialEvent() n{n while (Serial.available()) n {n char inChar = (char)Serial.read();n inputString += inChar;n if (inChar == 'n') n {n stringComplete = true;n }n }n}nnvoid F_BigIoT()n{n serialEvent();n if (stringComplete)n {n inputString.trim();n if(inputString=="CLOSED")n {n Serial.println("connect closed!");n CONNECT=false; n }n elsen {n int len = inputString.length()+1; n if(inputString.startsWith("{") && inputString.endsWith("}"))n {n char jsonString[len];n inputString.toCharArray(jsonString,len);n aJsonObject *msg = aJson.parse(jsonString);n processMessage(msg);n aJson.deleteItem(msg); n }n }n // clear the string:n inputString = "";n stringComplete = false; n }n}
slaver从机arduino代码
#include <Wire.h>//声明I2C库文件n#include <SPI.h>n#include <Wire.h>n#include <Adafruit_GFX.h>n#include <Adafruit_SSD1306.h>nbyte timeBcd[] = {0, 0, 0, 0, 0, 0, 0};n#define ADDRESS_DS1307 0x68nchar a[10]=" ";n#define OLED_RESET 4nAdafruit_SSD1306 display(OLED_RESET);n#define LOGO16_GLCD_HEIGHT 16 //定义显示高度 n#define LOGO16_GLCD_WIDTH 16 //定义显示宽度 nn#define Speaker_Dist 8nnnint x;//变量x值决定主机的LED是否点亮n//初始化n#if (SSD1306_LCDHEIGHT != 64)nerror("Height incorrect, please fix Adafruit_SSD1306.h!");n#endifnn//============= 超声波模块=================nconst int TrigPin = 2;nconst int EchoPin = 3;nfloat distance;n//=========================================nnvoid setup()n{ Serial.print(a[0]);n Wire.begin(7); // 加入 i2c 总线,设置从机地址为 #4n Wire.onReceive(receiveEvent); //注册接收到主机字符的事件n //Wire.onRequest(requestEvent); // 注册主机通知从机上传数据的事件n Serial.begin(115200);n display.begin(SSD1306_SWITCHCAPVCC, 0x3C);//设置串口波特率nnn pinMode(TrigPin, OUTPUT);n pinMode(EchoPin, INPUT);n pinMode(Speaker_Dist, OUTPUT);n digitalWrite(Speaker_Dist, LOW);n}n//主程序nchar c;nvoid loop()n{ n Serial.print(a[0]);n Wire.onReceive(receiveEvent);n //=========时间函数============n Wire.beginTransmission(ADDRESS_DS1307);n Wire.write(0x00);n Wire.endTransmission();n Wire.requestFrom(ADDRESS_DS1307, 7);n if (Wire.available() >= 7)n {n for (int i = 0; i < 7; i++)n {n timeBcd[6 - i] = Wire.read();n }n }nn//printn Serial.print("20"); Serial.print(timeBcd[0], HEX); Serial.print("/");n Serial.print(timeBcd[1], HEX); Serial.print("/"); Serial.print(timeBcd[2], HEX);n Serial.print(" "); n Serial.print(timeBcd[4], HEX); Serial.print(":");n Serial.print(timeBcd[5], HEX); Serial.print(":");n Serial.print(timeBcd[6], HEX); Serial.println();nn if (a[0]>1&&timeBcd[0]!=0)n {n display.clearDisplay();n display.setTextSize(1); //设置字体大小n display.setTextColor(WHITE); //设置字体颜色白色n display.setCursor(0, 0); //设置字体的起始位置n display.print("Temperature : ");n display.print(a[0]);//输出字符并换行n display.print(a[1]);n display.println(" C");n display.print("Humidity : ");n display.print(a[3]);n display.print(a[4]);n display.println("%");n display.print("BatteryCent : ");n display.print(a[6]);n display.print(a[7]);n display.println("%");n display.print("20"); display.print(timeBcd[0], HEX); display.print("/");n display.print(timeBcd[1], HEX); display.print("/"); display.print(timeBcd[2], HEX);n display.print(" ");n display.print(timeBcd[4], HEX); display.print(":");n display.print(timeBcd[5], HEX); display.print(":");n display.print(timeBcd[6], HEX); display.println();n display.display();n if(a[6]==0)n {n display.clearDisplay();n display.setTextSize(2); //设置字体大小n display.setTextColor(WHITE); //设置字体颜色白色n display.setCursor(0, 0); //设置字体的起始位置n display.println(" LOW");n display.println("BATTERY!!!");n display.display();n }nn }n AlarmDist();n}nn// 当从机接收到主机字符,执行该事件nvoid receiveEvent(int howMany)n{ n int i=0;n n while ( Wire.available() > 1) // 循环执行,直到数据包只剩下最后一个字符n { n c = Wire.read(); // 作为字符接收字节n Serial.println(c);n a[i]=c;n i++;// 把字符打印到串口监视器中n }n}nnvoid AlarmDist()n{n digitalWrite(TrigPin, LOW);n delayMicroseconds(2);n digitalWrite(TrigPin, HIGH);n delayMicroseconds(10);n digitalWrite(TrigPin, LOW);n n distance = pulseIn(EchoPin, HIGH) / 58.0;n if (distance<=20&&distance>0)n {n digitalWrite(Speaker_Dist, HIGH);n delayMicroseconds(2);n }n digitalWrite(Speaker_Dist, LOW);n}
九、配件清单
应评论区要求,附物品清单一份
欢迎访问我的网站
张世博的BLOG - 若不复为无益之事,何以悦有生之涯和我的github
h1997l1997 (BenBoErBa-ZhangShiBo)本项目相关文件下载
h1997l1997/Intelligent-desk-lamp感谢@裂帛碎玉 同学在演示视频中出演,和对我写的乱七八糟代码的优化(尤其是改了一大堆我随便起的变量名)
最后的最后,麻烦雷总给个小赞~
@雷军