查看:
9914
|
回复:
13
|
参赛作品《WIFI智能插座》
|
chen
14
主题
218
回复 |
发表于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和后台数据库使用的是市场现成的开源接口。 |
仙人掌
3
主题
45
回复 |
发表于2017-06-11 22:07:57
|
显示全部楼层
4#
wifi开关插座是个不错而且实用的想法,期待楼主的作品
|
|