收藏官网首页
查看: 3182|回复: 0

转载:基于机智云的懒人声控灯

99

主题

123

帖子

1695

积分

金牌会员

Rank: 6Rank: 6

积分
1695
发表于 2019-5-27 14:50:00 | 显示全部楼层 |阅读模式
注册成为机智云开发者,手机加虚拟设备快速开发
作者:打包还是带走

         最近,接触到机智云智能硬件云服务平台(类似物联网),也花几天了解了平台的开发流程,搞清楚后就想搞事情,手头上剩了一些材料(元器件),反正也是闲着,搞点东东玩玩,娱乐一下枯燥乏味的生活。

         这个灯怎么来的,源于一句话:“我有一个大胆的想法!!!”,应该是这样,然后就有了这个灯。差不多花了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_SwitchSound_Switch,布尔类型,可写,

         将下载的代码文件夹Gizwits放入Arduino编程器文件目录libraries下。

                   如果开发流程不清楚可以详见官方开发流程!

         2.2.2下载ProtoThreads多线程的库,同上放入libraries

                   修改Gizwits文件夹下的Gizwits.h头文件,打开头文件,将公有成员函数void process(void);改为bool process(void);

                   同样,在Gizwits.cpp中将函数修改为bool类型,还需对代码修改,如下:
kittenblock中小学创客名师推荐的图形化编程软件

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的代码去掉(基本用不到),修改按键2D4,方便随时都配置网络。
  • 声音传感器使用中断触发的方式,连接在D3(外部中断1),使用计算时差的方式过滤掉一些杂音或避免多次重复触发开关。
  • 由于单片机的IO提供电流太小,所以LED灯通过继电器控制,继电器低电平驱动,连接在D5


         附上代码:

         kittenblock中小学创客名师推荐的图形化编程软件



#define PT_USE_TIMER//任务挂起要用

#include "pt.h"

#include <Gizwits.h>

#include <Wire.h>

#include <SoftwareSerial.h>

#define   KEY2              4

#define   KEY2_SHORT_PRESS  4

#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 init  OK \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灯的改造

         这是买来时的灯:

         

         拆了后如图:

         

         这样,把固定灯的环壳用钩刀裁剪下来

         

         LED灯板上用钻孔机(这个东西实验实有)钻两个孔,涂上硅脂,固定在散热块上

         

         最后,当当当~~~,拼装起来

         

         

         2.2外壳设计

         由于灯的最大直径为60mm,所以四面的长方形块大小为60x73mm,顶部的方形块大小为60x60mm,都用钩刀裁剪就可以了。

         2.3顶部电源设计

         如图想办法挖槽吧,用钻孔机+钩刀,是的,楼主我只有这些工具。

         

         然后把开关,按钮等东西用热熔胶粘上去

         

         Step 3 安装模型

         先用热熔胶粘两个侧面,然后固定LED灯。再把元器件也粘进去

         

         接下来把其它两块也粘上去,这样大体就差不多了

         

         以上步骤在做的时候边粘边连线的!最后,盖上顶部的盖子。

         

         ~~~酱紫的~~~

         

         现在轮到懒人支架上场表演了,先把脚跺了再说,如下图

         

         再把脚粘在灯的顶部

         

         Step 4 装饰一下

         以前做了个大别野,剩了点贴纸,就给敷上去了,字不重要,看下图

         


         说一下感悟吧:

         用心做好一个灯
         不只是电科的专业与执着
         更是使命
         用实在的原料
         佐以专业独运的焊接工艺
         所融入的不只是优美代码
         还有与之相得益彰的模型
         让人陶醉,更令人沉迷的
         电科精神

         打包,懒人声控致瞎灯
         以亚克力熔制的躯壳
         融入困、懒、惰、倦之气
         让每一次起床开关灯的想法万念俱灰
         声控也更为庸人自扰
         懒得到豆腐渣工艺
         更享受到无比诚意

         ——修改于匠汤海鲜面

         题外话:本来想做花样七彩+白色LED灯的(WS2812B RGB七彩转圈圈的,很漂亮,美滋滋),后来发现驱动RGB灯需要占用极大的CPU使用率,又由于Arduino 串口库的原因(不能中断收发数据,即实时性低),从而使得机制云传来的数据丢失或网络连接常断开或APP无法控制灯的开关,了用户的体验感,只能舍弃了。

         
         楼主我走过一些弯路,烧过一些芯片,这是取经之路必定会发生的事情,这是我完美的一面,为各位网友踮脚啦

         项目代码,ProtoThreads库源码打包下载: Code.zip (70.91 KB, 下载次数: 3)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2022 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表