查看: 9821  |  回复: 13
参赛作品《WIFI智能插座》

主题

回复
发表于2017-05-31 16:55:04 | 只看该作者
1# 电梯直达

【报名阶段需要填写的内容】


1. 参赛者姓名(必填项):

陈占标

2. 单位或学校名称(必填项):

3. 当前职务或职称(必填项):

自由职业者

4. 参赛作品的名字(必填项):

基于stm32f103制作的wifi智能插座

5. 简要陈述您的idea和作品(必填项):

这款智能插座采用STM32F103C8T6+WIFI模块+云平台方案。主要功能有。插座的远程开关,定时,预约,电量统计,电压,电流,功率检测等。

6. 拟用到的立创商城在售物料(必填项):

单片机芯片STM32F103C8T6  电源芯片 LNK306  电量计芯片HLW8012   WIFI模块ESP-12S  继电器srd-05vdc-sl-c

7. 拟用到的非立创商城物料或其它补充(必填项):

三脚电源插座  外壳

【作品正式发表(报名成功后进入设计阶段)需要填写的内容】

一、作品简介


基本功能:

1、可实现外网、局域网手机APP遥控插座开关

2、定时开关,按星期自动循环开关,设置参数自动保存,不会丢失,离线也能控制。

3、预约开关,设置时间之后,进入倒计时状态。

4.、无限添加,账户可针对设备种类命名无限添加设备个数。

5、可对多个设备同时进行功率监测

6、手机号码注册+手机短信验证

7、可实现一对多、多对一、多对多同时控制

特点:

无变压器设计,利用市场公模+开源APP+开源数据库接口,方便DIY

  

  

     

 

  


  

二、系统构架图

 


三、硬件部分的描述

总述:

列出各模块的原理图:

电源模块

    

wifi模块

 

 单片机控制模块

  

电量计模块+继电器控制模块

   

按键+显示灯一体模块

 

 

   

四、材料清单(BOM列表)

核心清单:

单片机芯片STM32F103C8T6 *1

电源芯片 LNK306*1

电量计芯片HLW8012*1

WIFI模块ESP-12S*1

继电器srd-05vdc-sl-c*1

晶振8M*1

按键*1

ams1117*1

三孔插座*1

外壳*1

其余各类阻容


五、软件部分的描述(选填)

#include <string.h>
#include "gizwits_product.h"
#include "Hal_key/Hal_key.h"
#include "Hal_Usart/hal_uart.h"
#include "Hal_led/Hal_led.h"
#include "Hal_motor/Hal_motor.h"
#include "Hal_rgb_led/Hal_rgb_led.h"
#include "Hal_temp_hum/Hal_temp_hum.h"
#include "Hal_infrared/Hal_infrared.h"
#include "Hal_Watchdog/hal_watchdog.h"
#include "Hal_rtc/rtc.h"
#include "Hal_Flash/stmflash.h"
 #include "Hal_ADC/adc.h"
 #include "gizwits_protocol.h"
extern _calendar_obj calendar; //日历结构体
extern volatile CalendarClock_t CalendarClock;//日历时钟
extern volatile CountDowntime_t CountDowntime;//预约时间
extern gizwitsProtocol_t gizwitsProtocol;
//__packed typedef struct {
//    devStatus_t devStatus;
//}gizwitsReport_t;
volatile gizwitsReport_t reportData;//结构体 设备存储的状态
 u8 HEARTBEATFFlag;//心跳标志,超时就重启
//__packed typedef struct
//{
//    uint8_t          keyNum;
//    uint32_t         keyRccPeriph;
//    GPIO_TypeDef     *keyPort;
//    uint32_t         keyGpio;
//    gokitKeyFunction shortPress;
//    gokitKeyFunction longPress;
//}keyTypedef_t;
keyTypedef_t singleKey[2];//按键状态长按短按
//__packed typedef struct
//{
//    uint8_t      keyNum;
//    keyTypedef_t *singleKey;
//}keysTypedef_t;
keysTypedef_t keys;//包含上面keyTypedef_t
void userInit(void)//用户初始化
{
    delayInit(72);//延时初始化
    uartxInit();//串口初始化defined (Open_UART1)  #define Open_UART2
    rgbLedInit();
    ledGpioInit();
    rgbKeyGpioInit();
    //motorInit();
    //dht11Init();
    //irInit();
   RTC_Init();      //RTC初始化
    watchdogInit(4);    //5,625看门狗复位时间2s
   
    memset((uint8_t*)&reportData, 0, sizeof(gizwitsReport_t));//初始化为0
    //reportData.devStatus.Motor_Speed = protocolExchangeBytes(Y2X(MOTOR_SPEED_RATIO,MOTOR_SPEED_ADDITION,MOTOR_SPEED_DEFAULT));
    //motorStatus(MOTOR_SPEED_DEFAULT);
}
void userHandle(void)//用户处理
{
   u16 adcx;
 float temp;
 static uint32_t thLastTimer = 0;//保存最后进入时间,与系统时间之差为进入处理间隔
 static uint32_t uptimeLastTimer = 0;//保存最后进入时间,与系统时间之差为进入处理间隔
 static uint32_t HEARTBEATLastTimer=0;//WIFI心跳包检测,超过多少分钟就重启
 static u8 uptimeflag=0;
 static u8  uptimenum=0;
   //-----------------------------{
   if(CountDowntime.Calendar_min_flag)//如果启用了预约功能
   {
    CountDowntime.Calendar_min_flag=0;
    CountDowntime.CountDown_Minute_time--;
    if(CountDowntime.CountDown_Minute_time<=0)//减到0
    {
      TIM_Cmd(TIM4,DISABLE);  //失能TIMx外设
      CountDowntime.Calendar_time_min = 0;
       CountDowntime.Calendar_time_sec = 0;
      CountDowntime.CountDown_Minute_time = 0;
     if(reportData.devStatus.DEV_OnOff == START_OnOn)//如果当前是开的就关闭插座
     {
      ledOff(LED4);//插座开关指示灯 关
      ledOff(LED3);//PB12插座开关   关闭
      //ledRgbControl(0,0,0);       
      reportData.devStatus.DEV_OnOff = START_OnOff;//保存关的状态 
      CalendarClock.Calendar_OnOff  = START_OnOff;//保存关的状态      
     }
     else if(reportData.devStatus.DEV_OnOff == START_OnOff)//如果当前是关的就打开插座
     {
      ledOn(LED4);//插座开关指示灯 开
      ledOn(LED3);//PB12插座开关   打开
      //ledRgbControl(254,0,0);      
      reportData.devStatus.DEV_OnOff = START_OnOn;//保存开的状态
      CalendarClock.Calendar_OnOff  = START_OnOn; //保存开的状态
     } 
     reportData.devStatus.DEV_CountDown_OnOff = START_OnOff;//保存关的状态
     #ifdef  SAVEFLASH
     STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&CalendarClock,sizeof(CalendarClock_t)+1);//保存到FLASH里
     #endif
     GIZWITS_LOG("Evt: CountDown_Minute_time= %d Executed\r\n",CountDowntime.CountDown_Minute_time);
    }
    //把当前还剩余的时间返回给APP
   reportData.devStatus.DEV_CountDown_Minute= Y2X(COUNTDOWN_MINUTE_RATIO,COUNTDOWN_MINUTE_ADDITION,protocolExchangeBytes(CountDowntime.CountDown_Minute_time));
    
   }
   //-----------------------------}
   //-----------------------------{
   if((gizwitsGetTimerCount()-thLastTimer) > REPORT_TIME_MAX) //查询开关定时到了没有
    {
     if(CalendarClock.Calendar_onoffflag == START_OnOn)//如果打开了定时标志位才进入
     {
      if((CalendarClock.Calendar_Week & ( 1<<(calendar.week-1)))==( 1<<(calendar.week-1)))//先判断星期是否是设置的。然后判断小时,分钟
      {
       //printf("nowtime=%d,setontime=%d,setofftime=%d\r\n",(calendar.hour*60+calendar.min),CalendarClock.Calendar_Time_On_Minute,CalendarClock.Calendar_Time_Off_Minute);
       if(CalendarClock.Calendar_Time_On_Minute !=CalendarClock.Calendar_Time_Off_Minute)//如果定时开与定时关时间不同才能进入控制
       {
        if(CalendarClock.Calendar_Time_On_Minute==((calendar.hour*60)+calendar.min))//如果设置的小时数与现在的小时数相同 16进制表示
        {
         //ledRgbControl(254,0,0);        //开插座
         ledOn(LED4);//插座开关指示灯 开
         ledOn(LED3);//PB12插座开关  打开
         reportData.devStatus.DEV_OnOff = START_OnOn;//保存开的状态
         CalendarClock.Calendar_OnOff  = START_OnOn; //保存开的状态
         GIZWITS_LOG("Calendar_Time_On_Minute= %d Executed\r\n",CalendarClock.Calendar_Time_On_Minute);
        }
        else if(CalendarClock.Calendar_Time_Off_Minute==((calendar.hour*60)+calendar.min))
        {
         ledOff(LED4);//插座开关指示灯 关
         ledOff(LED3);//PB12插座开关   关闭
         //ledRgbControl(0,0,0);       
         reportData.devStatus.DEV_OnOff = START_OnOff;//保存关的状态
         CalendarClock.Calendar_OnOff  = START_OnOff;//保存关的状态
         GIZWITS_LOG("Calendar_Time_Off_Minute= %d Executed\r\n",CalendarClock.Calendar_Time_Off_Minute);
        }
     #ifdef  SAVEFLASH
     STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&CalendarClock,sizeof(CalendarClock_t)+1);//保存到FLASH里
     #endif
       }
      }
     }
     thLastTimer = gizwitsGetTimerCount();
    }
    //-----------------------------}
  if((gizwitsGetTimerCount()-uptimeLastTimer) > UPTIME_TIME_MAX) //0.5秒进入查询查询开关定时到了没有
  {
 
     //{ADC查询Vout = 2.5 + 0.1*Ip  没有电流在中间位置2.5V 正向电流 4.5V/20A   反向电流0.5V/20A
     if(reportData.devStatus.DEV_OnOff == START_OnOn)
     {
//      adcx=Get_Adc_Average(ADC_Channel_8,10);
//      temp=(float)adcx*(3.3/4096);
//      temp=(float)(int)(temp*1000)/1000;
//      if(temp > 2.54)
//      {
//       temp-=2.54;
//      }
//      else
//      {
//       temp=2.54-temp;
//      }    
//      printf("\r\n The current AD value = %f \r\n", temp);
//      if((temp > 0.03)&&(uptimenum==0))
//      {
//       uptimeflag=1;
//       uptimenum=1;
//       
//       reportData.devStatus.DEV_UpYear=protocolExchangeBytes(calendar.w_year);
//       reportData.devStatus.DEV_UpMonth=calendar.w_month;
//       reportData.devStatus.DEV_UpDay=calendar.w_date;
//       reportData.devStatus.DEV_UpTime=calendar.hour;
//       reportData.devStatus.DEV_UpMinute=calendar.min;
//       reportData.devStatus.DEV_UpSencond=calendar.sec;
//       reportData.devStatus.DEV_Consumption = (u16)protocolExchangeBytes((u16)(temp*1000));
//       printf("\r\n The current AD value on=  %f \r\n", temp);
//      }
//      else if((uptimeflag==1)&&(temp<0.01))
//      {
//       uptimeflag=0;
//       uptimenum=0;
//       reportData.devStatus.DEV_UpYear=protocolExchangeBytes(calendar.w_year);
//       reportData.devStatus.DEV_UpMonth=calendar.w_month;
//       reportData.devStatus.DEV_UpDay=calendar.w_date;
//       reportData.devStatus.DEV_UpTime=calendar.hour;
//       reportData.devStatus.DEV_UpMinute=calendar.min;
//       reportData.devStatus.DEV_UpSencond=calendar.sec;
//       reportData.devStatus.DEV_Consumption =(u16)protocolExchangeBytes((u16)(temp*1000));
//       printf("\r\n The current AD value off= %f \r\n", temp);
//      }
      
     }
 
  uptimeLastTimer = gizwitsGetTimerCount();
  }
  if((gizwitsGetTimerCount()-HEARTBEATLastTimer) > HEARTBEAT_TIME_MAX)//180秒进入一次
  {
   if(HEARTBEATFFlag==1)
   {
     GIZWITS_LOG("Info: 180sec HEARTBEAT_TIME_MAX wifi RESET\r\n");
     ledOff(ESPONOFF);//ESPwifi电源关闭
     ledOff(LED2);//PB14 LEDG 绿灯网络指示灯
     delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
     delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
     delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
     delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
     ledOn(ESPONOFF);//ESPwifi电源打开
   }
   HEARTBEATFFlag=1;
   HEARTBEATLastTimer=gizwitsGetTimerCount();//保存最后进入时间
  }
}
void key1ShortPress(void)
{
    printf("KEY1 PRESS\r\n");
       reportData.devStatus.DEV_UpYear=protocolExchangeBytes(calendar.w_year);
       reportData.devStatus.DEV_UpMonth=calendar.w_month;
       reportData.devStatus.DEV_UpDay=calendar.w_date;
       reportData.devStatus.DEV_UpTime=calendar.hour;
       reportData.devStatus.DEV_UpMinute=calendar.min;
       reportData.devStatus.DEV_UpSencond=calendar.sec;
 
reportData.devStatus.DEV_FittingaddrH=protocolExchangeBytes(1234);
reportData.devStatus.DEV_FittingaddrL=56;
 reportData.devStatus.DEV_Arm_Disarm_OnOff=1;
}
void key1LongPress(void)
{
    printf("KEY1 PRESS LONG ,Wifi Reset\r\n");
    gizwitsSetDefault();
}
void key2ShortPress(void)
{
    //Soft AP mode, RGB red
    //ledRgbControl(255, 0, 0);
    //gizwitsSetMode(SoftAp_Mode);ledOff(LED4);
 if(reportData.devStatus.DEV_OnOff == START_OnOn)//如果当前是开的就关闭插座
  {
   ledOff(LED4);//插座开关指示灯 关
   ledOff(LED3);//PB12插座开关   关闭
   //ledRgbControl(0,0,0);       
   reportData.devStatus.DEV_OnOff = START_OnOff;//保存关的状态
   CalendarClock.Calendar_OnOff  = START_OnOff;//保存关的状态
  }
  else if(reportData.devStatus.DEV_OnOff == START_OnOff)//如果当前是关的就打开插座
  {
   ledOn(LED4);//插座开关指示灯 开
   ledOn(LED3);//PB12插座开关  打开
   //ledRgbControl(254,0,0);      
   reportData.devStatus.DEV_OnOff = START_OnOn;//保存开的状态
   CalendarClock.Calendar_OnOff  = START_OnOn; //保存开的状态
  }
  #ifdef  SAVEFLASH
  STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&CalendarClock,sizeof(CalendarClock_t)+1);//保存到FLASH里
  #endif
  printf("KEY2 PRESS ,devStatus.DEV_OnOff = %d\r\n",reportData.devStatus.DEV_OnOff);
  
}
void key2LongPress(void)
{
    //AirLink mode, RGB Green
    printf("KEY2 PRESS LONG ,AirLink mode\r\n");
    //ledRgbControl(0, 128, 0);
  ledOn(LED1);//PB15LEDR 红灯 进入AirLink模式
    gizwitsSetMode(AirLink_Mode);
}
int main(void)
{
  //ledOn(ESPONOFF);//ESPwifi电源打开
    SystemInit();
  userInit();
  Adc_Init();
  ledOff(ESPONOFF);//ESPwifi电源关闭
  ledOn(LED1);//PB15LEDR 红灯 打开
 
  //PB10 GPIO_KEY1_PIN, PA8 GPIO_KEY2_PIN 初始化
    singleKey[0] = keyInitOne(0,RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_10, key1ShortPress, key1LongPress);
    keys.keyNum++;
    singleKey[1] = keyInitOne(1,RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_8, key2ShortPress, key2LongPress);
    keys.keyNum++;
    keys.singleKey = (keyTypedef_t *)&singleKey;
    keyParaInit(&keys);
    gizwitsInit();//初始化product.c里面的硬件
#ifdef  SAVEFLASH
STMFLASH_Read(FLASH_SAVE_ADDR,( u16*)&CalendarClock,sizeof(CalendarClock_t)+1);//从FLASH读取保存的数据
 if(reportData.devStatus.DEV_OnOff == START_OnOn)//上电 如果断电之前是开的,就打开插座
  {
   ledOn(LED4);//插座开关指示灯 开
   ledOn(LED3);//PB12插座开关  打开
  }
  else if(reportData.devStatus.DEV_OnOff == START_OnOff)//上电 如果断电之前是关的,就关闭插座
  {
   ledOff(LED4);//插座开关指示灯 关
   ledOff(LED3);//PB12插座开关   关闭
  }
  ledOff(ESPONOFF);//ESPwifi电源关闭
  ledOn(ESPONOFF);//ESPwifi电源打开
  ledOff(LED1);//PB15LEDR 红灯 关闭初始化完成
    printf("Gokit Init Success \r\n");
    while(1)
    {
        watchdogFeed();//喂狗
       
        userHandle();//一直查询//用户处理 状态变化
       
        gizwitsHandle((gizwitsReport_t *)&reportData);//一直查询WIFI发过来的数据
    }
}



六、作品演示

https://v.qq.com/x/page/c0540gvfetr.html


七、总结

1、想做好一个小东西,要花很多心思;

2、手工焊确实累人,期待立创这边能支持双面贴,外加加紧速度可贴商城所有器件进度;

3、团队的重要性,一个人做不了全能的东西,软件、硬件、APP、数据库全部要会,这个确实很难做到

4、【异想天开】要是力创能配套开设一个3D打印事业部就更好了,把设计好的外壳直接发出去打样打印,价格能做到pcb打样那样亲民就更佳了

5、99%器件设计选型都选用了立创商城现有的,方便了采购,也方便日后贴片。(除了三脚插座和外壳以外,其他的器件都是力创商城的)


声明:由于个人知识有限,自己申请的数据库没调试成功,最终APP和后台数据库使用的是市场现成的开源接口。


主题

回复
发表于2017-05-31 17:22:27   |  只看该作者
2#

报名成功!

您可以开始进行设计工作了。


主题

回复
发表于2017-06-02 17:19:04   |  只看该作者
3#

>楼主已完成主动传播,恭喜再获5分。

>参赛选手分值统计表及活动详细介绍见:http://www.szlcsc.com/go/17523dej

>报名成功后只需在朋友圈发布特定的图文内容即视为主动传播,这就是传说中的“送分题”,详询立创君微信号:LCSCSZ


主题

回复
发表于2017-06-11 22:07:57   |  只看该作者
4#
wifi开关插座是个不错而且实用的想法,期待楼主的作品

主题

回复
发表于2017-06-12 15:00:19   |  只看该作者
5#
发表于2017-06-11 22:07:57  4# wifi开关插座是个不错而且实用的想法,期待楼主的作品

欢迎期待,只做实用性较强产品,不浮夸!

软硬件差不多了,硬件第一版调试成功,现在第二版打样中;

最近在申请阿里云数据库,想自己搭建一个数据库,也是学习阶段,不知道能否搭建成功!


主题

回复
发表于2017-06-27 13:24:38   |  只看该作者
6#
说明:

调试过程借用别家的数据库,自己用还是可以的,由于注册需要短信验证,故有可能造成数据被别家收集,不保证安全,以此造成信息丢失,本楼主不负责,需要空板pcb的可联系我扣扣378241803

 

第一次打样的板子还有几个(只有那三脚插座的焊盘孔位大了,其他的没影响),免费送,运费到付!


主题

回复
发表于2017-08-24 21:53:14   |  只看该作者
9#
用现成的开源接口也不错啊,而且现在市场上也有很多WiFi插座,不知道你这个自己动手制作的话用了多少的成本啊,不过最主要还是想知道,最大支持多大功率的电器。

主题

回复
发表于2017-08-25 09:08:30   |  只看该作者
10#
 

主题

回复
发表于2017-08-25 10:20:02   |  只看该作者
11#
发表于2017-08-24 21:53:14  9# 用现成的开源接口也不错啊,而且现在市场上也有很多WiFi插座,不知道你这个自己动手制作的话用了多少的成本啊,不过最主要还...
核心清单:

单片机芯片STM32F103C8T6 *1=6.6

电源芯片 LNK306*1=3.35

电量计芯片HLW8012*1=2.38

WIFI模块ESP-12S*1=12.94

继电器srd-05vdc-sl-c*1=1.32

晶振8M*1=0.62

按键*1=0.5

ams1117*1=0.4

三孔插座*1=1.2

外壳*1=1

其余各类阻容=2

合计31.31

成本合计按照嘉立创商城提供的单价计算的,大批量采购的话,价格至少可以节省1/3。

现设计最大电流为10A,受限于继电器的限流值,可通过更换继电器,做到20A。


主题

回复
发表于2017-08-25 23:45:25   |  只看该作者
12#
没有自己的亮点,都是大杂烩,兄弟可以用STM32做采样计算电量,没有必要用电量计量芯片,单片机本身可以处理的何必再增加成本?同步采样精度足够你受用了

主题

回复
发表于2017-08-26 11:32:24   |  只看该作者
13#
发表于2017-08-25 23:45:25  12# 没有自己的亮点,都是大杂烩,兄弟可以用STM32做采样计算电量,没有必要用电量计量芯片,单片机本身可以处理的何必再增加成...
要是作为量产考虑成本的话,我建议把单片机也去掉,把控制程序直接写到wifi模块里

主题

回复
发表于2017-08-26 13:55:27   |  只看该作者
14#
恭喜楼主获得了第二届立创商城电子制作节入围奖,虽然距离30强还有些小差距,30强&入围奖名单:http://club.szlcsc.com/article/details_8910_1.html
但到明年的第三届电子制作节,带上您更成熟的作品参赛时,也许就能一举夺冠了呢,现在,有众多优秀作品让你参考,投票:http://club.szlcsc.com/article/details_8913_1.html

主题

回复
  • 温馨提示: 标题不合格、重复发帖、发布广告贴,将会被删除帖子或禁止发言。 详情请参考: 社区发帖规则
  • 您当前输入了 0 个文字。还可以输入 8000 个文字。 已添加复制上传图片功能,该功能目前仅支持chrome和火狐

禁言/删除

X
请选择禁言时长:
是否清除头像:
禁言/删除备注:
昵 称:
 
温馨提示:昵称只能设置一次,设置后无法修改。
只支持中文、英文和数字。

举报

X
请选择举报类型:
请输入详细内容:

顶部