|
|
| #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);
|
| }
|
|
|