转载:基于机智云的懒人声控灯
作者:打包还是带走最近,接触到机智云智能硬件云服务平台(类似物联网),也花几天了解了平台的开发流程,搞清楚后就想搞事情,手头上剩了一些材料(元器件),反正也是闲着,搞点东东玩玩,娱乐一下枯燥乏味的生活。
这个灯怎么来的,源于一句话:“我有一个大胆的想法!!!”,应该是这样,然后就有了这个灯。差不多花了20天的时间,也没有20天,就是偶尔花点时间弄一下。先说下具体功能:
[*]离线按钮控制开关
[*]远程APP控制开关
[*]声控控制开关
[*]胶粘在了懒人支架上
[*]没有电池离电死(这也算功能吧)
以上可以说是非常的懒人了,灯度也很高,在测试声控的时候离得太近眼睛又对着灯,喊了一下差点瞎了,所以远离灯源,祝您心明眼亮。综上,“懒人声控致瞎灯”名字由此而来。
前方高能预警!注意!这不是演习!制作过程如下:
Step1 材料准备
1.1 主控:Arduino Pro mini以及FTD1232串口下载器
1.2 通信:正点原子ESP8266 WIFI模块
1.3 声控:声音检测模块
1.4 光源:5W 白灯10颗灯珠,5V供电
1.5 供电:DC 5V-2A 适配器
1.6 支架:懒人手机支架(后续改装用)
1.7 工具:电烙铁,热熔胶,钩刀,
1.8 模型:亚克力板20x30cm,厚度2mm
1.9 额外:1路继电器,轻触开关,自锁开关,洞洞板,火牛电源头,散热硅脂、铝制散热块各一个
Step2 固件烧录
2.1机智云烧录GoAgent固件方法参考:
http://club.gizwits.com/forum.php?mod=viewthread&tid=3551&highlight=8266
2.2主控烧录
2.2.1在机智云中添加两个数据点,LED_Switch,Sound_Switch,布尔类型,可写,
将下载的代码文件夹Gizwits放入Arduino编程器文件目录libraries下。
如果开发流程不清楚可以详见官方开发流程!
2.2.2下载ProtoThreads多线程的库,同上放入libraries。
修改Gizwits文件夹下的Gizwits.h头文件,打开头文件,将公有成员函数void process(void);改为bool process(void);
同样,在Gizwits.cpp中将函数修改为bool类型,还需对代码修改,如下:https://www.arduino.cn/images/2018/kit.pngkittenblock中小学创客名师推荐的图形化编程软件
bool Gizwits::process(void)
{
uint8_t readChar = 0;
uint16_t i=0,num = 0;
num = Serial.available();
if(0 < num)
{
for(i=0; i<num; i++)
{
readChar = Serial.read();
gizPutData(&readChar, 1);
}
gizwitsHandle((dataPoint_t *)¤tDataPoint);
return 1;
}
gizwitsHandle((dataPoint_t *)¤tDataPoint);
return 0;
}
解释一下为什么,在我的代码中有一行:
PT_WAIT_UNTIL(pt,myGizwits.process());
这个函数的第二个参数是布尔类型的参数,所以需要修改Gizwits的源代码,当串口无数据是该线程阻塞的,当串口接收到数据时,线程运行,这样可以节省CPU查询if语句的资源。
2.3总体代码
[*]移植networkConfig中的部分代码,按键1的代码去掉(基本用不到),修改按键2为D4,方便随时都配置网络。
[*]声音传感器使用中断触发的方式,连接在D3(外部中断1),使用计算时差的方式过滤掉一些杂音或避免多次重复触发开关。
[*]由于单片机的IO提供电流太小,所以LED灯通过继电器控制,继电器低电平驱动,连接在D5。
附上代码:
https://www.arduino.cn/images/2018/kit.pngkittenblock中小学创客名师推荐的图形化编程软件
#define PT_USE_TIMER//任务挂起要用
#include "pt.h"
#include <Gizwits.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#define KEY2 4
#define KEY2_SHORT_PRESS4
#define KEY2_LONG_PRESS 8
#define NO_KEY 0
#define KEY_LONG_TIMER 3 //约3秒
#define LED_PIN 5 //LED引脚
#define SND_PIN 3 //声音检测开关引脚
//实例化类
SoftwareSerial mySerial(A2, A3); // A2 -> RX, A3 -> TX
Gizwits myGizwits;
//**全局变量
static struct pt thread1,thread2;
unsigned long Last_KeyTime = 0;
unsigned long Last_SoundTime = 0;
bool varR_LED_Switch = 0;
bool varR_Sound_Switch = 0;
//秒获取
unsigned long gokit_time_s(void)
{
return millis() / 1000;
}
char gokit_key2down(void)
{
int unsigned long keep_time = 0;
if (digitalRead(KEY2) == 0)
{
delay(100);
if (digitalRead(KEY2) == 0)
{
keep_time = gokit_time_s();
while (digitalRead(KEY2) == 0) //until open the key
{
if ((gokit_time_s() - keep_time) > KEY_LONG_TIMER)
{
Last_KeyTime = gokit_time_s();
return KEY2_LONG_PRESS;
}
}
if ((gokit_time_s() - Last_KeyTime) > KEY_LONG_TIMER)
{
return KEY2_SHORT_PRESS;
}
return 0;
}
return 0;
}
return 0;
}
//只保留按键2的处理
char gokit_keydown(void)
{
char ret = 0;
ret |= gokit_key2down();
return ret;
}
//只保留了AirLink配网方式,SoftAP去掉,改为开关控制
void KEY_Handle(void)
{
/*Press for over than 3 second is Long Press*/
switch (gokit_keydown())
{
case KEY2_SHORT_PRESS://短按
if(varR_LED_Switch == 0)//若为关
{
digitalWrite(LED_PIN, 0);//则打开
varR_LED_Switch = 1;//标记为打开
}
else//若为开
{
digitalWrite(LED_PIN, 1);//则关闭
varR_LED_Switch = 0;//标记为关闭
}
break;
case KEY2_LONG_PRESS://长按
//mySerial.println(F("KEY2_LONG_PRESS ,AirLink mode"));
myGizwits.setBindMode(WIFI_AIRLINK_MODE);
//AirLink mode
break;
default:
break;
}
}
void setup() {
// put your setup code here, to run once:
mySerial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(KEY2, INPUT_PULLUP);//按键上拉输入
pinMode(5, OUTPUT);
digitalWrite(5, 1);//关闭继电器
myGizwits.begin();
mySerial.println("GoKit initOK \n");
//初始化线程
PT_INIT(&thread1);
PT_INIT(&thread2);
}
void SoundDetection()
{
int unsigned long start_time = 0;
detachInterrupt(1);//关中断
//可以试一下以下这个,要配合底部那句一起
//进入临界模式,所有中断关闭
//noInterrupts();
delay(3000);
if(digitalRead(SND_PIN) == LOW)
{
delay(1000);
if(digitalRead(SND_PIN) == LOW)
{
start_time = gokit_time_s();
if ((Last_SoundTime - start_time) > 0.1)//防止极短时间内重复开关
{
if(varR_LED_Switch == 0)//若为关
{
digitalWrite(LED_PIN, 0);//则打开
varR_LED_Switch = 1;//标记为打开
}
else//否则为开
{
digitalWrite(LED_PIN, 1);//则关闭
varR_LED_Switch = 0;//标记为关闭
}
Last_SoundTime = gokit_time_s();
}
}
}
attachInterrupt(1, SoundDetection, FALLING);//开中断
//退出临界模式
//interrupts();
}
//系统闪烁灯,按键处理
static int thread1_entry(struct pt *pt)
{
PT_BEGIN(pt);
while (1)
{
KEY_Handle();//按键处理,网络配置
digitalWrite(13,!digitalRead(13));
PT_TIMER_DELAY(pt,500);//挂起线程500ms
}
PT_END(pt);
}
//机智云串口数据处理
static int thread2_entry(struct pt *pt)
{
PT_BEGIN(pt);
while (1)
{
PT_WAIT_UNTIL(pt, myGizwits.process());
if(myGizwits.hasBeenSet(EVENT_LED_Switch))
{
myGizwits.read(EVENT_LED_Switch,&varR_LED_Switch);//Address for storing data
if(varR_LED_Switch == 1){
digitalWrite(5, 0);//开灯
}else{
digitalWrite(5, 1);//关灯
}
}
if(myGizwits.hasBeenSet(EVENT_Sound_Switch))
{
myGizwits.read(EVENT_Sound_Switch,&varR_Sound_Switch);//Address for storing data
if(varR_Sound_Switch == 1)
attachInterrupt(1, SoundDetection, FALLING);//开中断
else
detachInterrupt(1);//关中断
}
PT_TIMER_DELAY(pt,100);//挂起线程100ms
}
PT_END(pt);
}
void loop() {
//Check each thread by priority
thread1_entry(&thread1);
thread2_entry(&thread2);
}
烧录时由于Pro mini没有自带串口,所以要用FTD1232串口模块下载,若用其它的开发板可以不用FTD1232。
Step 2 模型设计
2.1灯的改造
这是买来时的灯:
https://www.arduino.cn/data/attachment/forum/201710/16/165251mws10zzwusigeroo.jpg
拆了后如图:
https://www.arduino.cn/data/attachment/forum/201710/16/165246pzpqezj6u0ykggbq.jpg
这样,把固定灯的环壳用钩刀裁剪下来
https://www.arduino.cn/data/attachment/forum/201710/16/165241ze985k8sszkync1n.jpghttps://www.arduino.cn/data/attachment/forum/201710/16/165243rnm7ijjunkl4lq5m.jpg
在LED灯板上用钻孔机(这个东西实验实有)钻两个孔,涂上硅脂,固定在散热块上
https://www.arduino.cn/data/attachment/forum/201710/16/165249v1px4js0stbphyzj.jpghttps://www.arduino.cn/data/attachment/forum/201710/16/165248unzus7mjsjjz3nuy.jpg
最后,当当当~~~,拼装起来
https://www.arduino.cn/data/attachment/forum/201710/16/165250u3mo6g1g1h8ddcmz.jpg
2.2外壳设计
由于灯的最大直径为60mm,所以四面的长方形块大小为60x73mm,顶部的方形块大小为60x60mm,都用钩刀裁剪就可以了。
2.3顶部电源设计
如图想办法挖槽吧,用钻孔机+钩刀,是的,楼主我只有这些工具。
https://www.arduino.cn/data/attachment/forum/201710/16/165244v6kitv306l13ttlp.jpg
然后把开关,按钮等东西用热熔胶粘上去
https://www.arduino.cn/data/attachment/forum/201710/16/165245m67zzzeo7y6s2i2u.jpg
Step 3 安装模型
先用热熔胶粘两个侧面,然后固定LED灯。再把元器件也粘进去
https://www.arduino.cn/data/attachment/forum/201710/16/165247ho2a8i5z58d24vb4.jpg
接下来把其它两块也粘上去,这样大体就差不多了
https://www.arduino.cn/data/attachment/forum/201710/16/165242obcwz0nztss2ov0b.jpg
以上步骤在做的时候边粘边连线的!最后,盖上顶部的盖子。
https://www.arduino.cn/data/attachment/forum/201710/16/165247dyx4w88fgr4xcjcj.jpg
呐~~~酱紫的~~~
https://www.arduino.cn/data/attachment/forum/201710/16/165249pbb87u8lyguxee8c.jpg
现在轮到懒人支架上场表演了,先把脚跺了再说,如下图
https://www.arduino.cn/data/attachment/forum/201710/16/165246affea1qj8a7l68dq.jpghttps://www.arduino.cn/data/attachment/forum/201710/16/165243x3exd3xekz9ke0hx.jpg
再把脚粘在灯的顶部
https://www.arduino.cn/data/attachment/forum/201710/16/165707nwjwwawlaicsznnl.jpg
Step 4 装饰一下
以前做了个大别野,剩了点贴纸,就给敷上去了,字不重要,看下图
https://www.arduino.cn/data/attachment/forum/201710/16/165250fcltt17e1lg1tkvz.jpg
说一下感悟吧:
用心做好一个灯 不只是电科的专业与执着 更是使命 用实在的原料 佐以专业独运的焊接工艺 所融入的不只是优美代码 还有与之相得益彰的模型 让人陶醉,更令人沉迷的 电科精神
打包,懒人声控致瞎灯 以亚克力熔制的躯壳 融入困、懒、惰、倦之气 让每一次起床开关灯的想法万念俱灰 声控也更为庸人自扰 懒得到豆腐渣工艺 更享受到无比诚意
——修改于匠汤海鲜面
题外话:本来想做花样七彩+白色LED灯的(WS2812B RGB七彩转圈圈的,很漂亮,美滋滋),后来发现驱动RGB灯需要占用极大的CPU使用率,又由于Arduino 串口库的原因(不能中断收发数据,即实时性低),从而使得机制云传来的数据丢失或网络连接常断开或APP无法控制灯的开关,了用户的体验感,只能舍弃了。
https://www.arduino.cn/data/attachment/forum/201710/16/170045d87aqr53lfvwqk75.jpg 楼主我走过一些弯路,烧过一些芯片,这是取经之路必定会发生的事情,这是我完美的一面,为各位网友踮脚啦
项目代码,ProtoThreads库源码打包下载:
视频地址:http://v.youku.com/v_show/id_XMzA4OTQzMzcwOA==.html
本帖子允许转载,务必注明作者以及来源。
这里开源给大家互相学习
页:
[1]