智能门禁系统2.0开发

继工作室装修以后,门禁系统1.0再度开发为2.0,这次与上次采用了不同的编程方案,虽然用的依然是机智云,但是采用的方案不同,
1、上次采用mcu方案,就是用的esp8266+arduino开发的,而这次我用的仅仅一块儿esp8266(nodemcu)搞定,
2、驱动电机的方式也有所改变,上次采用的继电器进行的电机转向,这次采用的l298N驱动,效果更好。
3、 同时也有很多细节发生了改变。


src="//player.bilibili.com/player.html?aid=29888278&cid=52057707&page=1" scrolling="no" border="0" allowfullscreen="true">


装机调试


src="//player.bilibili.com/player.html?aid=29961784&cid=52201449&page=1" scrolling="no" border="0" allowfullscreen="true">


代码部分


/**
************************************************************
* @file         user_main.c
* @brief        The program entry file
* @author       Gizwits
* @date         2017-07-19
* @version      V03030000
* @copyright    Gizwits
*
* @note         鏈烘櫤浜�.鍙负鏅鸿兘纭欢鑰岀敓
*               Gizwits Smart Cloud  for Smart Products
*               閾炬帴|澧炲�贾祙寮�鏀緗涓珛|瀹夊叏|鑷湁|鑷敱|鐢熸��
*               www.gizwits.com
*
***********************************************************/
#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"
#include "gagent_soc.h"
#include "user_devicefind.h"
#include "user_webserver.h"
#include "gizwits_product.h"
#include "driver/hal_key.h"
#if ESP_PLATFORM
#include "user_esp_platform.h"
#endif

#ifdef SERVER_SSL_ENABLE
#include "ssl/cert.h"
#include "ssl/private_key.h"
#else
#ifdef CLIENT_SSL_ENABLE
unsigned char *default_certificate;
unsigned int default_certificate_len = 0;
unsigned char *default_private_key;
unsigned int default_private_key_len = 0;
#endif
#endif
/**@} */ 

/**@name Key related definitions 
* @{
*/
#define GPIO_KEY_NUM                            2                           ///< Defines the total number of key members
#define KEY_0_IO_MUX                            PERIPHS_IO_MUX_GPIO0_U      ///< ESP8266 GPIO function
#define KEY_0_IO_NUM                            0                           ///< ESP8266 GPIO number
#define KEY_0_IO_FUNC                           FUNC_GPIO0                  ///< ESP8266 GPIO name
#define KEY_1_IO_MUX                            PERIPHS_IO_MUX_MTMS_U       ///< ESP8266 GPIO function
#define KEY_1_IO_NUM                            14                          ///< ESP8266 GPIO number
#define KEY_1_IO_FUNC                           FUNC_GPIO14                 ///< ESP8266 GPIO name
LOCAL key_typedef_t * singleKey[GPIO_KEY_NUM];                              ///< Defines a single key member array pointer
LOCAL keys_typedef_t keys;                                                  ///< Defines the overall key module structure pointer    
/**@} */
bool input_result;
/**
* Key1 key short press processing
* @param none
* @return none
*/
LOCAL void ICACHE_FLASH_ATTR key1ShortPress(void)
{
    GIZWITS_LOG("#### KEY1 short press ,Production Mode\n");

    gizwitsSetMode(WIFI_PRODUCTION_TEST);
}

/**
* Key1 key presses a long press
* @param none
* @return none
*/
LOCAL void ICACHE_FLASH_ATTR key1LongPress(void)
{
    GIZWITS_LOG("#### key1 long press, default setup\n");

    gizwitsSetMode(WIFI_RESET_MODE);
}

/**
* Key2 key to short press processing
* @param none
* @return none
*/
LOCAL void ICACHE_FLASH_ATTR key2ShortPress(void)
{
    GIZWITS_LOG("#### key2 short press, soft ap mode \n");

    gizwitsSetMode(WIFI_SOFTAP_MODE);
}

/**
* Key2 button long press
* @param none
* @return none
*/
LOCAL void ICACHE_FLASH_ATTR key2LongPress(void)
{
    GIZWITS_LOG("#### key2 long press, airlink mode\n");

    gizwitsSetMode(WIFI_AIRLINK_MODE);
}

/**
* Key to initialize
* @param none
* @return none
*/
LOCAL void ICACHE_FLASH_ATTR keyInit(void)
{
    singleKey[0] = keyInitOne(KEY_0_IO_NUM, KEY_0_IO_MUX, KEY_0_IO_FUNC,
                                key1LongPress, key1ShortPress);
    singleKey[1] = keyInitOne(KEY_1_IO_NUM, KEY_1_IO_MUX, KEY_1_IO_FUNC,
                                key2LongPress, key2ShortPress);
    keys.singleKey = singleKey;
    keyParaInit(&keys);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); //GPIO12初始化
    GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);//GPIO12 低电平输出
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13);
    GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 0);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_GPIO3);
    GPIO_OUTPUT_SET(GPIO_ID_PIN(3), 0);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);
    GPIO_DIS_OUTPUT(FUNC_GPIO4);
}

/**
* @brief user_rf_cal_sector_set

* Use the 636 sector (2544k ~ 2548k) in flash to store the RF_CAL parameter
* @param none
* @return none
*/
uint32_t ICACHE_FLASH_ATTR user_rf_cal_sector_set()
{
    return 636;
}




///
/**
* @brief program entry function
* In the function to complete the user-related initialization
* @param none
* @return none
*/
void ICACHE_FLASH_ATTR user_init(void)
{
    uint32_t system_free_size = 0;

    wifi_station_set_auto_connect(1);
    wifi_set_sleep_type(NONE_SLEEP_T);//set none sleep mode
    espconn_tcp_set_max_con(10);
    uart_init_3(9600,115200);
    UART_SetPrintPort(1);
    GIZWITS_LOG( "---------------SDK version:%s--------------\n", system_get_sdk_version());
    GIZWITS_LOG( "system_get_free_heap_size=%d\n",system_get_free_heap_size());

    struct rst_info *rtc_info = system_get_rst_info();
    GIZWITS_LOG( "reset reason: %x\n", rtc_info->reason);
    if (rtc_info->reason == REASON_WDT_RST ||
        rtc_info->reason == REASON_EXCEPTION_RST ||
        rtc_info->reason == REASON_SOFT_WDT_RST)
    {
        if (rtc_info->reason == REASON_EXCEPTION_RST)
        {
            GIZWITS_LOG("Fatal exception (%d):\n", rtc_info->exccause);
        }
        GIZWITS_LOG( "epc1=0x%08x, epc2=0x%08x, epc3=0x%08x, excvaddr=0x%08x, depc=0x%08x\n",
                rtc_info->epc1, rtc_info->epc2, rtc_info->epc3, rtc_info->excvaddr, rtc_info->depc);
    }

    if (system_upgrade_userbin_check() == UPGRADE_FW_BIN1)
    {
        GIZWITS_LOG( "---UPGRADE_FW_BIN1---\n");
    }
    else if (system_upgrade_userbin_check() == UPGRADE_FW_BIN2)
    {
        GIZWITS_LOG( "---UPGRADE_FW_BIN2---\n");
    }
    keyInit();
    gizwitsInit();  
    dh11Init();
    GIZWITS_LOG("--- system_free_size = %d ---\n", system_get_free_heap_size());
}

/**
************************************************************
* @file         gizwits_product.c
* @brief        Control protocol processing, and platform-related hardware initialization
* @author       Gizwits
* @date         2017-07-19
* @version      V03030000
* @copyright    Gizwits
*
* @note         鏈烘櫤浜�.鍙负鏅鸿兘纭欢鑰岀敓
*               Gizwits Smart Cloud  for Smart Products
*               閾炬帴|澧炲�贾祙寮�鏀緗涓珛|瀹夊叏|鑷湁|鑷敱|鐢熸��
*               www.gizwits.com
*
***********************************************************/
#include <stdio.h>
#include <string.h>
#include "gizwits_product.h"
#include "driver/hal_key.h"
#include "driver/hal_temp_hum.h"
/** User area The current device state structure */
dataPoint_t currentDataPoint;
bool isTimer;
long timer_timers;
long time_mills;//定义总秒数
static os_timer_t os_timer;
static os_timer_t delay_timer;

void stop(void){
    GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 0);
    GPIO_OUTPUT_SET(GPIO_ID_PIN(3), 0);
    GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);
}
void open(){
    GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 0);
    GPIO_OUTPUT_SET(GPIO_ID_PIN(3), 1);
}
void Led_Task_Run(void){
    //开门
    open();
    //开灯
 GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0);
 //根据继电器的种类和要定时的任务而定。这是低电平触发继电器的定时开机功能。
 isTimer=false;
 //执行完毕,我们要把定时时间设置0 ,定时使能状态为false
 timer_timers= 0;
}
void Led_Task_Off(void){
//开灯
 GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);
 //根据继电器的种类和要定时的任务而定。这是低电平触发继电器的定时关机功能。
 isTimer=false;
 //执行完毕,我们要把定时时间设置0 ,定时使能状态为false
 timer_timers= 0;
}

int8_t ICACHE_FLASH_ATTR gizwitsEventProcess(eventInfo_t *info, uint8_t *data, uint32_t len)
{
    uint8_t i = 0;
    dataPoint_t * dataPointPtr = (dataPoint_t *)data;
    moduleStatusInfo_t * wifiData = (moduleStatusInfo_t *)data;

    if((NULL == info) || (NULL == data))
    {
        GIZWITS_LOG("!!! gizwitsEventProcess Error \n");
        return -1;
    }
    for(i = 0; i < info->num; i++)
    {
        switch(info->event[i])
        {
        case EVENT_on_off :
            currentDataPoint.valueon_off = dataPointPtr->valueon_off;
            GIZWITS_LOG("Evt: EVENT_on_off %d \n", currentDataPoint.valueon_off);
            if(0x01 == currentDataPoint.valueon_off)
            {
                GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0);
                open();
            }
            else
            {
                GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);

            }
            break;
        case EVENT_T_on_off :
            currentDataPoint.valueT_on_off = dataPointPtr->valueT_on_off;
            GIZWITS_LOG("Evt: EVENT_T_on_off %d \n", currentDataPoint.valueT_on_off);
            if(0x01 == currentDataPoint.valueT_on_off)
            {
            isTimer=true;//开启定时器
            }
            else
            {
            /** 关闭该定时器 */
            os_timer_disarm( &os_timer );
            /** 定时器使能为false */
            isTimer=false;
            }
            break;
        case EVENT_time_h:
            currentDataPoint.valuetime_h= dataPointPtr->valuetime_h;
            GIZWITS_LOG("Evt:EVENT_time_h %d\n",currentDataPoint.valuetime_h);
            //user handle
            break;
        case EVENT_time_m:
            currentDataPoint.valuetime_m= dataPointPtr->valuetime_m;
            GIZWITS_LOG("Evt:EVENT_time_m %d\n",currentDataPoint.valuetime_m);
            //user handle
            if(isTimer){
                   if (currentDataPoint.valueon_off){  //判断继电器状态,如果原来是关闭状态,就定时开机,如果原来是开启状态,就定时关闭。
                /** 关闭该定时器 */
                os_timer_disarm( &os_timer );
                // 配置该定时器回调函数,指定的执行方法是: Led_Task_Run (),下面会提供代码
                os_timer_setfn( &os_timer, (ETSTimerFunc *) ( Led_Task_Off ), NULL );
                time_mills = (currentDataPoint.valuetime_h *60 + currentDataPoint.valuetime_m)*60000;
                /** 开启该定时器 :下发的是秒数,这里的单位是毫秒,要乘1000* ,后面false表示仅仅执行一次**/
                os_timer_arm( &os_timer, time_mills, false );
                /**赋值给timer_timers,方便会调用 */
                timer_timers=currentDataPoint.valuetime_m;
                }
                else
                {
                /** 关闭该定时器 */
                os_timer_disarm( &os_timer );
                // 配置该定时器回调函数,指定的执行方法是: Led_Task_Run (),下面会提供代码
                os_timer_setfn( &os_timer, (ETSTimerFunc *) ( Led_Task_Run ), NULL );
                time_mills = (currentDataPoint.valuetime_h *60 + currentDataPoint.valuetime_m)*60000;
                /** 开启该定时器 :下发的是秒数,这里的单位是毫秒,要乘1000* ,后面false表示仅仅执行一次**/
                os_timer_arm( &os_timer, time_mills, false );
                /**赋值给timer_timers,方便会调用 */
                timer_timers=currentDataPoint.valuetime_m;
                }
                }
            break;
        case WIFI_SOFTAP:
            break;
        case WIFI_AIRLINK:
            break;
        case WIFI_STATION:
            break;
        case WIFI_CON_ROUTER:
            GIZWITS_LOG("@@@@ connected router\n");
            break;
        case WIFI_DISCON_ROUTER:
            GIZWITS_LOG("@@@@ disconnected router\n");
            break;
        case WIFI_CON_M2M:
            GIZWITS_LOG("@@@@ connected m2m\n");
            setConnectM2MStatus(0x01);
            break;
        case WIFI_DISCON_M2M:
            GIZWITS_LOG("@@@@ disconnected m2m\n");
            setConnectM2MStatus(0x00);

            break;
        case WIFI_RSSI:
            GIZWITS_LOG("@@@@ RSSI %d\n", wifiData->rssi);
            break;
        case TRANSPARENT_DATA:
            GIZWITS_LOG("TRANSPARENT_DATA \n");
            //user handle , Fetch data from [data] , size is [len]
            break;
        case MODULE_INFO:
            GIZWITS_LOG("MODULE INFO ...\n");
            break;

        default:
            break;
        }
    }
    system_os_post(USER_TASK_PRIO_2, SIG_UPGRADE_DATA, 0);

    return 0; 
}


/**
* User data acquisition

* Here users need to achieve in addition to data points other than the collection of data collection, can be self-defined acquisition frequency and design data filtering algorithm

* @param none
* @return none
*/
void ICACHE_FLASH_ATTR userHandle(void)
{
    //明天待修改。
    if(GPIO_INPUT_GET(4) == 0 && GPIO_INPUT_GET(12) == 0 ){
            GPIO_OUTPUT_SET(GPIO_ID_PIN(13), 1);
            GPIO_OUTPUT_SET(GPIO_ID_PIN(3), 0);
            os_timer_disarm( &delay_timer );
            os_timer_setfn( &delay_timer, (os_timer_func_t *) ( stop ), NULL );
            os_timer_arm( &delay_timer, 1000, false );
        }
    currentDataPoint.valueback = time_mills ;
    currentDataPoint.valueon_off = !GPIO_INPUT_GET(12) ;
    //是否开启定时器的回调
    currentDataPoint.valueT_on_off =isTimer;
    if(isTimer){
     currentDataPoint.valuetime_m =timer_timers;
     }
    else
    {
        /*数据清零*/
      currentDataPoint.valuetime_m =0;
      currentDataPoint.valuetime_h =0;
      currentDataPoint.valueback =0;
     }
    uint8_t ret = 0;
    uint8_t curTemperature =0;
    uint8_t curHumidity = 0;
    ret = dh11Read(&curTemperature, &curHumidity);
     if(0 == ret){
         currentDataPoint.valueTH_h = curTemperature;
         currentDataPoint.valueTH_t = curHumidity;
         }
         else{
         os_printf("@@@@ dh11Read error ! \n");
         }

    system_os_post(USER_TASK_PRIO_2, SIG_UPGRADE_DATA, 0);
}
/**
* Data point initialization function
* In the function to complete the initial user-related data
* @param none
* @return none
* @note The developer can add a data point state initialization value within this function
*/
void ICACHE_FLASH_ATTR userInit(void)
{
    gizMemset((uint8_t *)¤tDataPoint, 0, sizeof(dataPoint_t));
    /** Warning !!! DataPoint Variables Init , Must Within The Data Range **/ 
    /*
        currentDataPoint.valueon_off =;
        currentDataPoint.valueT_on_off =;
        currentDataPoint.valuetime_h =;
        currentDataPoint.valuetime_m =;
        currentDataPoint.valueTH_h = ;
        currentDataPoint.valueTH_t = ;
        currentDataPoint.valueback = ;
    */
}