“我们的动力源于对电子的热爱”

为大家详细介绍最近的语音台灯,不用了解各种通讯协议,直接调用函数,小白也会!

链接:https://pan.baidu.com/s/12m0TMhjH7SR9DHA_pTowBg?pwd=m4zf 
提取码:m4zf

目录

想法的产生

软件描写

使用Blinker.app

将设备接入米家

Arduino IDE

环境搭建:

EC11编码按键

WS2812

工程代码

代码详解

硬件搭建

灯板

台灯主板

亮度控制

电池充电芯片4056

灯板供电升压 芯片XL6007E1

ESP-12S

供电切换

WS2812焊接

外壳

工程链接


想法的产生

刷B站时发现一位博主 用8266+blinker库制作了一个语音台灯,讲解的非常详细

原视频链接:

ESP8266联动小爱同学/点灯科技远程控灯,小白也能轻松搞定。_哔哩哔哩_bilibili

会用到的点灯科技公司网址:点灯科技-点灯物联网解决方案

有不懂的可以直接查看开发文档,遇到的问题都可以在论坛上查到

我能不能做一个像米家台灯一样的物联网台灯呢,于是就有了这个项目

台灯要可以小爱同学语音控制,还可以在手机上查看台灯的状态信息,还有实体按键控制

8266-12s + EC11编码按钮 + WS2812

软件描写

使用Blinker.app

需要到点灯科技官网下载

注册好后进入此界面(台灯是我已经注册好的) ,点击右上角+添加设备,点击独立设备

我用的ESP8266,所以选择网络接入,接下来生成密钥(设备身份证)

界面就会生成新的设备了, 可以点击编辑按钮添加组件,当组件触发后只需要在8266中的回调函数执行相应任务就行了

将设备接入米家

需要8266烧入代码,点灯科技有示例代码,认真看就懂

#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT  //小爱同学light接口函数#include <Blinker.h>char auth[] = "********";              //换成APP获取到的密匙
char ssid[] = "********";              //WiFi账号
char pswd[] = "********";              //WIFI密码

Blinker库下载:https://github.com/blinker-iot/blinker-library/archive/master.zip

只能说人家介绍的非常详细:点灯科技-点灯物联网解决方案

看不明白的也可以跟着视频:ESP8266联动小爱同学/点灯科技远程控灯,小白也能轻松搞定。_哔哩哔哩_bilibili

进入米家APP>我的>其他平台设备>添加,找到电灯科技,返回时就会看到绑定的点灯科技了,点击同步设备就可以看到我们的台灯了

Arduino IDE

环境搭建:

本次的台灯用到了两个库

#include <FastLED.h>
//下载地址:https://github.com/blinker-iot/blinker-library/archive/master.zip#include <Blinker.h>
//可直接在IDE > 项目 > 加载库 > 添加库 里面找到

EC11编码按键

我自己写的不太好用,这位老师讲的好,编码器代码源于:

【Arduino实验篇】第29课 旋转编码器实验_哔哩哔哩_bilibili

int getEncodeTurn(void)   //按键编码器
{static int oldA = HIGH;static int oldB = HIGH;static int swcount = 0;           //按键开关延时int result = 0;int newA = digitalRead(add);      //add.cut.sw是自己定义的引脚int newB = digitalRead(cut);if(newA != oldA || newB != oldB){if(oldA == HIGH && newA == oldA){result = (oldB * 2 - 1);}}oldA = newA;oldB = newB;if(!digitalRead(sw)){               //按压检测,开关台灯delay(30);if(!digitalRead(sw)){while(!digitalRead(sw)){;}     //松手检测,长按就会触发看门狗,重启,替代复位开关if(LED!=0){LED = 0;}else {LED = startled;}         //开启时等于初始亮度delay(100);}   }return result;
}

WS2812

我的指示灯灯珠的IN脚接的是GPIO16,好像用常见的库点不亮灯,找问题花了一点时间,发现FastLED.h可以驱动.我需要自己调颜色,用到了一下操作:

跟多使用方法可以看看:FastLED库 – 太极创客 (taichi-maker.com)

#include <FastLED.h>#define LED_PIN     16     //我的LED信号线IN接在16引脚
#define NUM_LEDS    1    //我的灯带一共级联了1颗LED
CRGB leds[NUM_LEDS];void setup() {FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);FastLED.setBrightness(100);  //可以设置全局亮度,调低亮度不刺眼
}void loop() {leds[0].r = 0;     leds[0].g = 100;   leds[0].b = 30;     FastLED.show();delay(1000);leds[0].r = 100;    leds[0].g = 20;    leds[0].b = 0;     FastLED.show();delay(1000);leds[0].r = 0;    leds[0].g = 80;    leds[0].b = 100;   FastLED.show();delay(1000);
}

工程代码

直接粘,省的下载

#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT  //小爱同学light接口函数#include <FastLED.h>
#include <Blinker.h>char auth[] = "**********";               //换成APP获取到的密匙
char ssid[] = "**********";               //WiFi账号
char pswd[] = "**********";               //WIFI密码#define LED_PIN     16    //我的LED信号线IN接在16引脚
#define NUM_LEDS    1     //我的灯带一共级联了1颗LED
CRGB leds[NUM_LEDS];#define add    4    //+
#define sw     2    //sw
#define cut    5    //-
#define stdby  14   //充电停止
#define chrg   12   //充电检测
#define pwm    13   //pwm输出引脚#define BUTTON_1 "ButtonKey"
#define Slider_1 "SliderKey"
#define Slider_2 "SliderKey"BlinkerButton Button1("sw");     //按钮名称”sw“
BlinkerSlider Slider1("lightw"); //滑块名称”lightw“
BlinkerSlider Slider2("timing"); //滑块名称”timing“
BlinkerNumber NMU1("runtime");   //文本显示运行时间,"runtime"为文本框名称
BlinkerNumber NMU2("battery");   //文本显示电压,"battery"为文本框名称
BlinkerImage  Image1("charge");  //APP充电图标显示int LED = 0;               //LED亮度1-100
int startled = 20;         //台灯开启的初始亮度
int timeoff = 0;           //台灯关闭时间
int timestart;             //记录定时开始的时间
int chstate = 8;           //供电状态,控制指示灯颜色和app图片
float batteryv = 0;        //电池电压
bool oState = false;
bool blinkerrun = true;    //按键是否有触发判断
bool Mi_get = false;       //小爱同学是否触发//·································································//
void button1_callback(const String & state)    //APP按钮控制开关
{BLINKER_LOG("get button state: ", state);Blinker.vibrate();        //手机震动if (state=="on") {    if(LED == 0){                //灯已经打开就不操作LED = startled;            //开灯占空比设置为20}Button1.print("on");       // 反馈给APP按键开关状态   } else if(state=="off"){LED = 0;                   //占空比为0,实现关灯Button1.print("off");      // 反馈给APP按键开关状态  timeoff = 0;               //台灯关闭时间清零Slider2.print(0);          //调整定时滑块 }     Slider1.print(LED);         //调整亮度滑块
}
void slider1_callback(int32_t value)           //滑块亮度控制
{    LED=value;   //接收亮度值if(LED == 0){Button1.print("off");      // 反馈给APP按键开关状态  timeoff = 0;               //台灯关闭时间清零Slider2.print(0);          //调整定时滑块 }else{Button1.print("on");       // 反馈给APP按键开关状态  }Slider1.print(LED);             //调整亮度滑块 }
void slider2_callback(int32_t value)           //APP滑块定时
{    BLINKER_LOG("get slider value: ", value);if(value!= 0){timeoff = value;                //接收台灯关闭时间timestart = Blinker.runTime();  //记录开始时间,单位sif(LED == 0){                   //如果灯还未开,启动定时器并开灯LED = startled;  Button1.print("on");          // 反馈给APP按键开关状态   Slider1.print(LED);           // 调整亮度滑块 }             }
}
void timing(void)                              //定时处理
{if(timeoff > 0){if(Blinker.runTime() - timestart == 60){  //一分钟进入一次timeoff--;Slider2.print(timeoff);           //调整滑块      if(timeoff == 0){LED = 0;                        //关闭灯Button1.print("off");           //反馈给APP按键开关状态Slider1.print(LED);             //调整亮度滑块               }}}
}
void miotPowerState(const String & state)//小爱同学语音控制开关
{Mi_get = true;   //小爱同学触发标志if (state == BLINKER_CMD_OFF) {     LED = 0;          //占空比为0,实现关灯       BlinkerMIOT.powerState("off");BlinkerMIOT.print();}else if (state == BLINKER_CMD_ON) {if(LED == 0){LED = startled;          //如果灯是关闭的,开灯占空比设置为20     } BlinkerMIOT.powerState("on");    BlinkerMIOT.print();}
}
void miotBright(const String & bright)   //小爱同学亮度控制的回调函数
{Mi_get = true;   //小爱同学触发标志LED = bright.toInt();BlinkerMIOT.brightness(LED);BlinkerMIOT.print();
}
void miotQuery(int32_t queryCode)        // 查询设备状态回调函数
{Mi_get = true;   //小爱同学触发标志switch (queryCode){case BLINKER_CMD_QUERY_ALL_NUMBER :         // 查询所有设备BLINKER_LOG("MIOT Query All");BlinkerMIOT.powerState(oState ? "on" : "off");          BlinkerMIOT.brightness(LED);            //小爱同学查询亮度BlinkerMIOT.print();break;case BLINKER_CMD_QUERY_POWERSTATE_NUMBER :  // 查询电源类设备BLINKER_LOG("MIOT Query Power State");BlinkerMIOT.powerState(oState ? "on" : "off");BlinkerMIOT.print();break;default :                                   // 查询其他设备BlinkerMIOT.powerState(oState ? "on" : "off");BlinkerMIOT.print();break;}
}
void miotMode(uint8_t mode)              //小爱同学模式控制
{Mi_get = true;   //小爱同学触发标志if (mode == BLINKER_CMD_MIOT_NIGHT) {LED = 5;  // 夜光模式} else if (mode == BLINKER_CMD_MIOT_READING) {LED = 60;   // 阅读模式}else if (mode == BLINKER_CMD_MIOT_COMPUTER) {LED = 20;  // 电脑模式}BlinkerMIOT.mode(mode);BlinkerMIOT.print();
}
void Mi_ser()                            //小爱同学触发处理
{static int count = 0;if(Mi_get){count++;if(count >= 500){Mi_get = false;  //小爱同学触发标志count = 0; if(LED==0){Button1.print("off");      // 反馈给APP按键开关状态  timeoff = 0;               //台灯关闭时间清零Slider2.print(timeoff);    //调整定时滑块 }else{Button1.print("on");  Slider1.print(LED);         //调整亮度滑块 }}}
}
void heartbeat()          //心跳包数据同步,30-60s上传一次,包含运行时间数据
{ int runtime = 0;           //台灯运行时间runtime = Blinker.runTime();    //Blinker.runTime()单位为sNMU1.print(runtime / 60);       //上传台灯运行时间Slider1.print(LED);             //调整亮度滑块    Image1.print(chstate);          //供电状态  NMU2.print(batteryv);           //上传电池电压
}
void charge_ser()         //指示灯颜色,含有电池电压检测
{ static bool flag = true;batteryv = 6.0*analogRead(A0)/1024-0.18;if(!digitalRead(stdby)){           //充满电,低电平有效chstate = 2;     leds[0].r = 0;      //绿色leds[0].g = 50;  leds[0].b = 15;   FastLED.show();     }      else if(!digitalRead(chrg)){       //充电chstate = 3;    leds[0].r = 40;      //橙色leds[0].g = 10;  leds[0].b = 0;   FastLED.show();}   else if(batteryv < 3.4  && digitalRead(chrg)){chstate = 1;leds[0].r = 40;      //红色leds[0].g = 0;  leds[0].b = 0;   FastLED.show();}else if(digitalRead(stdby) && digitalRead(chrg) //电池供电&& batteryv >= 3.4){chstate = 0;if(LED == 0){leds[0].r = 0;     leds[0].g = 0;  leds[0].b = 0;   FastLED.show();}else{leds[0].r = 0;      //蓝色leds[0].g = 40;  leds[0].b = 50;   FastLED.show();}}
}
void bright_led()         //输出PWM波
{static int  showled;static int  first;static int  lon;static bool flag = false;if(first != LED){    //检测变化first = LED;flag = true;}if(showled > LED*9){if(flag){lon = (showled - LED*9)/15;  //将一次变化分为20次执行flag = false;}showled -=lon; if(showled < LED*9){showled = LED*9;}   //防止偏差过大}else if(showled < LED*9){if(flag){lon = (LED*9 - showled)/15;flag = false;}showled += lon; if(showled > LED*9){showled = LED*9;} }Serial.println(showled);analogWrite(pwm,showled);  //输出PWM波
}
int getEncodeTurn(void)   //按键编码器
{static int oldA = HIGH;static int oldB = HIGH;static int swcount = 0;           //按键开关延时int result = 0;int newA = digitalRead(add);int newB = digitalRead(cut);swcount++;if(swcount > 3000){   //延时swcount=0;           blinkerrun = true;        //按键编码器发后,blinker禁用一段时间  Slider1.print(LED);         //调整亮度滑块if(LED==0){Button1.print("off");}     // 反馈给APP按键开关状态  else{Button1.print("on");}  }if(newA != oldA || newB != oldB){swcount=0;           blinkerrun = false;if(oldA == HIGH && newA == oldA){result = (oldB * 2 - 1);Serial.println(result);  }}oldA = newA;oldB = newB;if(!digitalRead(sw)){       //按压检测,开关台灯blinkerrun = false;          //按键操作时,禁用blinker操作swcount=0;   delay(30);if(!digitalRead(sw)){while(!digitalRead(sw)){;}     //松手检测,长按就会触发看门狗,重启if(LED!=0){LED = 0;}else {LED = startled;}       //开启时等于初始亮度delay(100);}   }return result;
}
void setup()
{  Serial.begin(115200);FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);FastLED.setBrightness(50);  //可以设置全局亮度,调低亮度不刺眼pinMode(add,INPUT);  //+pinMode(sw,INPUT); //swpinMode(cut,INPUT);  //- pinMode(stdby,INPUT); //充电停止pinMode(chrg,INPUT); //充电检测  pinMode(pwm, OUTPUT);  //亮度analogWriteFreq(25000);   //输出pwm频率为25kHz Blinker.begin(auth, ssid, pswd);Button1.attach(button1_callback);             // 按键回调Slider1.attach(slider1_callback);             // 滑块回调Slider2.attach(slider2_callback);             // 滑块回调BlinkerMIOT.attachBrightness(miotBright);     // 灯光亮度控制回调BlinkerMIOT.attachMode(miotMode);             // 模式控制回调BlinkerMIOT.attachPowerState(miotPowerState); // 电源控制回调BlinkerMIOT.attachQuery(miotQuery);           // 查询设备状态回调Blinker.attachHeartbeat(heartbeat);           // 心跳包回调}
void loop()
{if(blinkerrun){  //blinkerrun来源于getEncodeTurn(); 按键编码器触发标志Blinker.run(); timing();           //定时处理   charge_ser();       //指示灯Mi_ser();           //小爱同学触发处理Serial.println("run!");  } int change = getEncodeTurn();  //获得编码器信息LED = LED + change;if(LED<0){LED = 0;}if(LED>100){LED = 100;}bright_led();     //PWM输出 Serial.print("LED:"); Serial.println(LED); }

代码详解

举一个按钮的例子:

按钮名称要和点灯APP上的名称一致,例如我将按钮组件命为“SW”,

BlinkerButton Button1("sw");     //按钮名称”sw“

然后在setup里面注册一下按钮的回调函数

Button1.attach(button1_callback);             // 按键回调

当APP组件触发后就会执行回调函数里面的内容,我创建的是一个开关按钮,所以它会返回state状态值"on"或"off"

void button1_callback(const String & state)    //APP按钮控制开关
{  if (state=="on") {    } else if(state=="off"){}
}

我们也可以从设备端将状态传给APP上的按钮,按钮就会呈现"on"或"off"状态

Button1.print("on");
Button1.print("off");

实验代码:

#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT  //小爱同学light接口函数#include <Blinker.h>char auth[] = "**********";               //换成APP获取到的密匙
char ssid[] = "**********";               //WiFi账号
char pswd[] = "**********";               //WIFI密码#define BUTTON_1 "ButtonKey"BlinkerButton Button1("sw");     //按钮名称”sw“void button1_callback(const String & state)    //APP按钮控制开关
{  if (state=="on") {    } else if(state=="off"){}
}void setup() {Serial.begin(115200);Blinker.begin(auth, ssid, pswd);Button1.attach(button1_callback);             // 按键回调
}void loop() {Blinker.run();}

话不多说,其他函数点灯科技里介绍很详细:点灯科技-点灯物联网解决方案

硬件搭建

灯板

我采用了3串4并的模式,用的5050灯珠,在嘉立创开的铝基板(白色阻焊不能白嫖,用丝印代替) ,供电电压达到9v就很亮了

台灯主板

焊接好的实物

亮度控制

采用8266直接控制MOS管,这个不太严谨,但能用

也就是台灯是PWM控制亮度的,开关频率达到了30kHz,一点也不晃眼

电池充电芯片4056

最大充电电流可达1A,可以通过调节,就是图中的R1,我选取1.2K,充电电流实测可达0.9A

并且4056有两个引脚输出充电状态,可以用8266检测,并将信息有一个2812指示灯显示

灯板供电升压 芯片XL6007E1

灯板供电实际8.5V左右,升压可以通过图中 R25 R24比值决定,但要注意此芯片最多输出2A电流

ESP-12S

第一版用的三色RGB灯,需要三个io口,就导致GPIO0 GPIO15也使用上了,出现了一些问题。后面用到2812就解决问题了。IO口注意事项如下:

用了8266的ADC检测电池电压,8266有10位ADC,输入最高1V。用了10k,2k电阻分压。

供电切换

简易的供电切换电路,有外部供电时就用外部供电并为电池充电。

开关用的是,需要将一个引脚剪掉,节省空间,放下电池(家里有条件的可以加两节18650)

WS2812焊接

需要将灯直立起来,且只需要焊接 三个引脚

外壳

为了打印出外壳,终于去学了下Solid Works,比原来的建模软件好用多了!

支撑的杆用的是PVC管子:粗杆用的外经10mm,壁厚1mm,细杆用的外经8mm,壁厚1mm

为大家整理好了:

工程链接

链接:https://pan.baidu.com/s/12m0TMhjH7SR9DHA_pTowBg?pwd=m4zf 
提取码:m4zf

小爱同学+8266的小爱语音台灯,基于Blinker库相关推荐

  1. 手把手带你把小爱同学装进你的台灯

    手把手带你把小爱同学装进你的台灯 一.硬件 1.硬件准备 2.pcb板 二.软件 1.配置好Arduino开发环境 2.获取秘钥 2.代码烧录 三.实物演示 一.硬件 1.硬件准备 1.8266开发板 ...

  2. 小爱同学调用系统接口,语音下发任务

    需求很简单,就是语音对话小爱,调用系统接口,达到下发任务的目的 1.立即开发 2.开始创建技能 3.点击自定义技能 4.技能名称随便定义,面向设备,这边的需求是小爱音响 5.设置调用名称,上传图标,必 ...

  3. 怎么使用小爱同学音响_小爱音箱mini怎么样如何使用 小爱音箱mini使用方法详细介绍...

    小爱音箱mini怎么样如何使用?相信小伙伴们一定很好奇,小米音响mini首发仅需99元,下面小编为大家带来了小爱音箱mini使用方法详细介绍,感兴趣的小伙伴赶紧跟着小编一起来看看吧. 小爱音箱mini ...

  4. Win10通过蓝牙连接小爱同学后,小爱同学无法作为音频设备输出声音

    "声音"显示小爱同学已断开连接,但  设置--设备--音频  中显示仍然连接. 1.win+r,输入regedit,打开注册表编辑器 2.进入路径:计算机\HKEY_LOCAL_M ...

  5. 利用esp8266接入小爱同学,实现智能台灯的改造物联网初识

    硬件准备 1.继电器WIFI智能插座模块 2.USB转ESP8266WIFI模块 3.ESP8266模块 软件环境搭建 1.小爱同学app,或者米家app,点灯 Blinker app 2.Ardun ...

  6. html5 语音唤醒,真正实现息屏语音唤醒小爱同学!释放你的双手,逼格满满哦!...

    不知道大家发现没有,MIUI9.5稳定版更新后,小米的语音助手正式更名为小爱同学! 对,就是和那个能讲故事.能播放歌曲和天气预报.控制家电的智能语音音箱同名的"小爱同学"! 然而, ...

  7. 使用小爱同学语音控制电脑关机 - Winform C#

    使用小爱同学语音控制电脑变关机 前言 实现原理 准备 注册巴法云账号 接入巴法云 接入米家 编写程序 连接TCP 接收信息并运行关机指令 发送指令订阅主题 添加心跳机制 后台运行 阻止默认关闭窗口事件 ...

  8. 小爱同学定制语音包分享_小爱同学音色定制链接

    小爱同学音色定制链接是小爱同学最新推出的一款语音包,有一个非常多的明星语音资源包,帮大家都可以来进行自由的设置,第1个语音高设置拥有详细的教程,可以快速的帮助你进行设置完成,喜欢的朋友们赶紧来下载吧, ...

  9. stm32l0的停止模式怎么唤醒_小米小爱同学新增支持播放网易云音乐,语音唤醒覆盖更多机型...

    最近,小米发布了最新版本的小爱同学,在App设置内或者小米应用商店即可更新到最新版本,最新版本新增了一些实用新功能,其中就包括大家期待已久的支持播放网易云音乐功能. 打开小爱同学App,进入设置,找到 ...

最新文章

  1. Ubuntu 18.04搭建Git服务器
  2. 什么样的鼠标对程序员最有用,超级提高开发效率
  3. CRM_DOC_FLOW_READ_DB debug
  4. DoS攻击、CC攻击的攻击方式和防御方法
  5. 如何提高kettle在大数据量下的读写速度
  6. MySQL数据库基本操作,命令行创建数据库、数据表,查询语句,模糊查询、范围查询、判断查询
  7. 联想IBM ThinkPad 笔记本BIOS设置手册
  8. 七个技巧!Godaddy域名安全指数提高N倍
  9. 《我爱我的祖国》受捧 再现专线另类舌尖上中国
  10. python培训班时间 费用-python培训班要多少钱?
  11. 超文本标记语言是指Java_超文本标记语言(HTML)
  12. JAVA实现Excel模板导入案例分析
  13. Super Hide IP 3.4.7.8允许您以匿名方式进行网上冲浪、 保持隐藏您的 IP 地址
  14. python反编译luac_Lua程序逆向之为Luac编写IDA Pro处理器模块
  15. 奥迪A4显示服务器出故障,奥迪A4变速箱锁挡、没倒挡、红屏、传感器故障维修总结...
  16. Java动物声音模拟器
  17. 在CSDN博客里保持代码格式的方法
  18. java编译器会将java程序转换为_Java编译器会将Java程序转换为一种代码,该代码叫()。...
  19. (原)丰田生产方式与普通生产方式之间的对比(一)
  20. 金九银十面试整理:BAT大厂最爱问的Android核心面试百题详细解析!

热门文章

  1. 展讯LOG抓取及简单分析
  2. luogu P3398 仓鼠找sugar
  3. 计算机网络实验之Wireshark 实验
  4. 华工c++基础语言程序,华工c++随堂练习答案+2020春.pdf
  5. 软件测试怎么保证数据的准确性,在MT4软件EA测试过程中,如何获得99.9%的数据质量,提高EA测试的准确性 -...
  6. 搞大事! EABM社区和众多大牌经纪商强强联手合作
  7. VMware公司揭开NSX半边面纱,旨在推动DevOps能力
  8. iOS 面试题--转自唐巧
  9. 三维叉乘怎么算_自然资源管理,三维GIS能做什么?
  10. 高品质免费字体集锦:25款英文艺术字体下载