开发快平台(M302I小e开发板系列教程)

时间:2023-03-09 07:34:18
开发快平台(M302I小e开发板系列教程)

开发快平台(M302I小e开发板系列教程)

开发块平台ESP8266模块相关理解

一. M302I小e开发板源码注释,源码基于:v1.4.0.8-u34.zip

1. user_main.c

 /******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*  
* FileName: user_main.c
*
* Description: entry file of user application
*
* Modification history:
* 2014/12/1, v1.0 create this file.
*******************************************************************************/
#include "esp_common.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h" #include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "driver/uart.h"
#include "espressif/esp_system.h"
#include "et_types.h" #include "driver/i2c_master.h"
#include "driver/OLED_I2C.h" #include "driver/RGB_light.h"
#include "driver/delay.h" #include "user_config.h"
#include "driver/gpio.h"
#include "espressif/smartconfig.h"
#include "driver/i2s.h"
#include "factory.h"
#include "et_api_compatible.h"
#ifdef IR_DEMO
#include "driver/ir.h"
#endif extern void et_user_main(void *pvParameters);
extern void read_uart_buf_task(void *pvParameters);
extern void send_to_mqtt_task(void *pvParameters); LOCAL os_timer_t test_timer;
LOCAL WORK_MODE_T work_mode = WORK_MODE_BUTT; extern et_cloud_handle g_cloud_handle;
extern et_int32 to_stop_app; et_int8 air_kiss_start_flag = ;
et_int8 user_main_start_flag = ;
et_int8 wifi_reconnect_start_flag = ; /******************************************************************************
* FunctionName : user_get_mode_str
* Description : Get mode string
* Parameters :
* Returns : NONE
*******************************************************************************/
et_uchar* ICACHE_FLASH_ATTR
user_get_mode_str(et_uint32 mode)
{
et_uchar *mode_str[] =
{
"DEFAULT",
"AUDIO",
"RGB",
"BAROMETRIC",
"OLED",
"INVALID"
}; return (WORK_MODE_BUTT <= mode ? mode_str[WORK_MODE_BUTT] : mode_str[mode]);
} /******************************************************************************
* FunctionName : user_esp_platform_check_ip
* Description : check whether get ip addr or not
* Parameters : none
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_esp_platform_check_ip(void)
{
static et_uint32 time = ;
et_uint32 connect_error_flag=;
struct ip_info ipconfig; os_timer_disarm(&test_timer);
//get ip info of ESP8266 station
wifi_get_ip_info(STATION_IF, &ipconfig);
if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != )
{
os_printf("got ip !!! \r\n");
if (user_main_start_flag == )
{
user_main_start_flag = ;
xTaskCreate(et_user_main, "et_user_main", , NULL, , NULL);
}
wifi_reconnect_start_flag = ;
}
else
{
if(wifi_station_get_connect_status() == STATION_WRONG_PASSWORD)
{
if ((system_get_time() - time) >= )
{
os_printf("connect fail, wrong password!!! \r\n");
time = system_get_time();
}
connect_error_flag = ;
}
else if(wifi_station_get_connect_status() == STATION_NO_AP_FOUND)
{
if ((system_get_time() - time) >= )
{
os_printf("connect fail, no AP found!!! \r\n");
time = system_get_time();
}
connect_error_flag = ;
}
else if(wifi_station_get_connect_status() == STATION_CONNECT_FAIL)
{
if ((system_get_time() - time) >= )
{
os_printf("connect fail, connect fail!!! \r\n");
time = system_get_time();
}
connect_error_flag = ;
} if(connect_error_flag == )
{
if (air_kiss_start_flag == )
{
wifi_station_set_reconnect_policy(false);
smartconfig_stop();
air_kiss_start_flag = ;
if(work_mode == WORK_MODE_OLED)
{
OLED_clear();
OLED_show_chn(, , ); //show 小e:
OLED_show_str(, , "e:", );
OLED_show_chn(, , ); //show 网络配置失败
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_str(, , " ", );
}
}
}
//re-arm timer to check ip
os_timer_setfn(&test_timer, (os_timer_func_t *)user_esp_platform_check_ip, NULL);
os_timer_arm(&test_timer, , );
}
} /******************************************************************************
* FunctionName : user_get_run_mode
* Description : Get the current working mode
* Parameters :
* Returns : NONE
*******************************************************************************/
et_uint32 ICACHE_FLASH_ATTR
user_get_run_mode()
{
return work_mode;
} void audio_init(void)
{
//audio_key_init(); // SPEAKER init
i2s_audio_init(); } /******************************************************************************
* FunctionName : user_init_work_mode
* Description : Initialization work mode
* Parameters :
* Returns : NONE
*******************************************************************************/
et_int32 ICACHE_FLASH_ATTR
user_init_work_mode(et_uint32 mode, et_uchar fac_norm_mode)
{
if (WORK_MODE_BUTT <= mode)
{
os_printf("The work mode=%u is invalid !!!\n", mode);
return RETURN_ERR;
} //#ifdef USER_PRINT_DEBUG
os_printf("get work mode=%s is success !!!\n", user_get_mode_str(mode));
//#endif switch (mode)
{
case WORK_MODE_DEFAULT:
DHT11_init();
break; case WORK_MODE_AUDIO:
DHT11_init();
audio_init();
break; case WORK_MODE_RGB:
RGB_light_init(); // RGB init
DHT11_init();
break; case WORK_MODE_BAROMETRIC:
i2c_master_gpio_init(); // BAROMETRIC init
DHT11_init(); // temperature init
break; case WORK_MODE_OLED:
i2c_master_gpio_init(); // I2C init
OLED_init(); // OLED init
OLED_clear();
DHT11_init();
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
break; default:
break;
} return RETURN_OK;
} /******************************************************************************
* FunctionName : user_get_work_mode
* Description : Get work mode from ADC
* Parameters :
* Returns : NONE
*******************************************************************************/
et_int32 ICACHE_FLASH_ATTR
user_get_work_mode(et_uint32 *mode)
{
et_uint32 adc = system_adc_read();
if (adc > )
{
os_printf("The adc value=%u is invalid !!!\n", adc);
return RETURN_ERR;
} #ifdef USER_PRINT_DEBUG
os_printf("get adc value=%u is success !!!\n", adc);
#endif // ADC turn into work mode
if(adc < )
{
*mode = WORK_MODE_DEFAULT;
}
else if (adc < )
{
*mode = WORK_MODE_AUDIO;
}
else if(adc < )
{
*mode = WORK_MODE_RGB;
}
else if(adc < )
{
*mode = WORK_MODE_BAROMETRIC;
}
else if(adc < )
{
*mode = WORK_MODE_OLED;
}
else
{
*mode = WORK_MODE_BUTT;
}
return RETURN_OK;
} void ICACHE_FLASH_ATTR
smartconfig_done(sc_status status, void *pdata)
{
switch(status)
{
case SC_STATUS_WAIT:
os_printf("SC_STATUS_WAIT\n");
break; case SC_STATUS_FIND_CHANNEL:
set_wifi_spark_timer();
os_printf("SC_STATUS_FIND_CHANNEL\n");
break; case SC_STATUS_GETTING_SSID_PSWD:
os_printf("SC_STATUS_GETTING_SSID_PSWD\n");
sc_type *type = pdata;
if (*type == SC_TYPE_ESPTOUCH)
{
os_printf("SC_TYPE:SC_TYPE_ESPTOUCH\n");
}
else
{
os_printf("SC_TYPE:SC_TYPE_AIRKISS\n");
}
break; case SC_STATUS_LINK:
{
os_printf("SC_STATUS_LINK\n");
struct station_config *sta_conf = pdata; wifi_station_set_config(sta_conf);
wifi_station_disconnect();
wifi_station_connect();
}
break; case SC_STATUS_LINK_OVER: {
os_printf("SC_STATUS_LINK_OVER\n");
smartconfig_stop();
if(work_mode == WORK_MODE_OLED)
{
OLED_clear();
OLED_show_chn(, , ); //show 小e:
OLED_show_str(, , "e:", );
OLED_show_chn(, , ); //show 网络配置完成
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_str(, , " ", );
}
delay_s();
system_restart();
break;
}
} } void airkiss_key_init(key_gpio_t*key)
{
et_uint32 io_reg;
io_reg = GPIO_PIN_REG(key->key_num); PIN_PULLUP_EN(io_reg);
PIN_FUNC_SELECT(io_reg, );
GPIO_AS_INPUT(key->key_gpio_pin);
} void ICACHE_FLASH_ATTR
airkiss_key_poll_task(void *pvParameters)
{
et_uint32 value, i; while()
{
value = gpio_get_value(AIRKISS_KEY_IO_NUM);
if(!air_kiss_start_flag && !value)
{
delay_s();
value = gpio_get_value(AIRKISS_KEY_IO_NUM);
if(!air_kiss_start_flag && !value)
{
os_printf("begin to airkiss\n");
air_kiss_start_flag = ;
os_timer_disarm(&test_timer);
to_stop_app = ; //in airkiss mode, stop et_user_main thread
if(g_cloud_handle != NULL)
{
et_logout_cloud(g_cloud_handle);
et_destroy_context(g_cloud_handle);
g_cloud_handle = NULL;
}
delay_s();
wifi_reconnect_start_flag = ;
smartconfig_start(smartconfig_done); //airkiss start
if(work_mode == WORK_MODE_OLED)
{
OLED_clear();
OLED_show_chn(, , ); //show 小e:
OLED_show_str(, , "e:", );
OLED_show_chn(, , ); //show 网络配置中...
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_chn(, , );
OLED_show_str(, , "...", );
}
os_timer_setfn(&test_timer, (os_timer_func_t *)user_esp_platform_check_ip, NULL);
os_timer_arm(&test_timer, , );
}
}
delay_ms();
}
os_printf("end airkiss\n");
vTaskDelete(NULL);
} void ICACHE_FLASH_ATTR
user_show_logo()
{
extern et_uchar BMP1[];
et_uint32 len = ; // BMP1 member i2c_master_gpio_init(); // I2C init
OLED_init(); // OLED init
OLED_clear(); // show logo
OLED_show_bmp(, , , , BMP1, len);
} void et_wifi_event_cb(System_Event_t *event)
{
switch(event->event_id)
{
case EVENT_STAMODE_SCAN_DONE: //ESP8266 station finish scanning AP break;
case EVENT_STAMODE_CONNECTED: //ESP8266 station connected to AP os_printf("et connect to ssid %s, channel %d\n", event->event_info.connected.ssid, event->event_info.connected.channel);
break;
case EVENT_STAMODE_DISCONNECTED: //ESP8266 station disconnected to AP
disarm_wifi_spark_timer();
wifi_led_off();
if(true != wifi_station_get_reconnect_policy())
{
os_printf("et wifi set to reconnect\n");
wifi_station_set_reconnect_policy(true);
}
//os_printf("et disconnect from ssid %s, reason %d\n", event->event_info.disconnected.ssid, event->event_info.disconnected.reason);
if(wifi_reconnect_start_flag != )
{
os_printf("airkiss start or start first don't restart %d\n",wifi_reconnect_start_flag);
}
else
{
os_printf("et wifi station connect status %d, restart system\n",wifi_station_get_connect_status());
system_restart();
}
break;
case EVENT_STAMODE_AUTHMODE_CHANGE: //the auth mode of AP connected by ESP8266 station changed
os_printf("mode: %d -> %d\n", event->event_info.auth_change.old_mode, event->event_info.auth_change.new_mode);
break;
case EVENT_STAMODE_GOT_IP: //ESP8266 station got IP from connected AP
set_wifi_spark_timer();
//os_printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR, IP2STR(&event->event_info.got_ip.ip), IP2STR(&event->event_info.got_ip.mask),
// IP2STR(&event->event_info.got_ip.gw));
break;
// case EVENT_STAMODE_DHCP_TIMEOUT: //ESP8266 station dhcp client got IP timeout
// break;
case EVENT_SOFTAPMODE_STACONNECTED: //a station connected to ESP8266 soft-AP
os_printf("et station: " MACSTR "join, AID = %d\n", MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid);
break;
case EVENT_SOFTAPMODE_STADISCONNECTED: //a station disconnected to ESP8266 soft-AP
os_printf("et station: " MACSTR "leave, AID = %d\n", MAC2STR(event->event_info.sta_disconnected.mac), event->event_info.sta_disconnected.aid);
break;
// case EVENT_SOFTAPMODE_PROBEREQRECVED:
// break;
// case EVENT_MAX:
// break;
default:
break;
}
} #ifdef IR_DEMO
void ir_tx_key(void *pvParameters)
{
et_uchar value=; ir_tx_msg_t tx_data;
tx_data.ir_tx_addr = 0x55;
tx_data.ir_tx_data = 0x28;
tx_data.ir_tx_rep = ; while()
{
value = gpio_get_value(AIRKISS_KEY_IO_NUM);
if(!value)
{
delay_ms();
value = gpio_get_value(AIRKISS_KEY_IO_NUM);
if(!value)
{ //Always press down
ir_tx_func(&tx_data);
}
}
delay_ms();
} vTaskDelete(NULL); }
#endif /******************************************************************************
* FunctionName : user_init
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void user_init(void)
{
os_printf("software version:%s\n", SOFTWARE_VERSION); //打印版本信息 et_uchar result=; if(get_fac_norm_mode(&result) != SPI_FLASH_RESULT_OK) //检测工作模式
{
os_printf("get_fac_norm_mode error, NORMAL mode\n");
} if(result == FAC_MODE) //运行在工厂模式
{
os_printf("run in factory mode\n");
uart_init_new_uart1(BIT_RATE_115200); //设置串口1工作模式
UART_SetPrintPort(UART1); //设置串口1为打印
uart_init_new(BIT_RATE_115200, result); //设置串口0工作模式
return;
} os_printf("run in normal mode\n"); //运行在正常模式 //if define IR_DEMO, ir rx or tx test //定义红外Demo测试
#ifdef IR_DEMO
struct station_config config; memset(&config, , sizeof(config));
wifi_set_opmode(STATION_MODE);
wifi_station_set_config_current(&config); //if define IR_RX, ir rx test
#ifdef IR_RX
ir_rx_init(); //ir tx test
#else
ir_tx_init();
xTaskCreate(ir_tx_key, "ir_tx_key", , NULL, , NULL);
#endif #else //没有定义红外Demo测试
key_gpio_t key;
struct station_config config;
struct ip_info info; // show logo
user_show_logo(); //OLED显示Logo if (RETURN_OK != user_get_work_mode(&work_mode)) //获取工作模式(因使用按键进行设置工作模式)
{
os_printf("get work mode fail !!!\n");
return;
} if (RETURN_OK != user_init_work_mode(work_mode, result)) //根据工作模式来对模块进行初始化操作
{
os_printf("init work mode fail !!!\n");
return;
} //wifi event handle
//WIFI 的配置,首先硬件查找一下FLASH里面有没有存储当前局域网有的WIFI有的话连接它,没有就执行下一步
wifi_set_event_handler_cb(et_wifi_event_cb); memset(&key, , sizeof(key_gpio_t));
key.key_gpio_pin = AIRKISS_KEY_IO_PIN;
key.key_num = AIRKISS_KEY_IO_NUM;
airkiss_key_init(&key);
//对 WIFI 考虑到了两种情况, 一种是当前smartconfig 软件配置一下。调用了一个任务函数, 用来连接网络,
wifi_set_opmode(STATION_MODE);
wifi_reconnect_start_flag = ;
xTaskCreate(airkiss_key_poll_task, "smartconfig_task", , NULL, , NULL); wifi_led_init();
memset(&config, , sizeof(struct station_config));
if(wifi_station_get_config_default(&config) == true)
{
os_printf("ssid=%s\n", config.ssid);
wifi_station_set_config_current(&config);
//for static ip set
/*wifi_station_dhcpc_stop();
IP4_ADDR(&info.ip, 192, 168, 1, 43);
IP4_ADDR(&info.gw, 192, 168, 1, 1);
IP4_ADDR(&info.netmask, 255, 255, 255, 0);
wifi_set_ip_info(STATION_IF, &info);*/
} os_timer_disarm(&test_timer);
os_timer_setfn(&test_timer, (os_timer_func_t *)user_esp_platform_check_ip, NULL);
os_timer_arm(&test_timer, , );
#endif
}

2. et_user_app.c

 /*******************************************************************************
* Copyright (c) 2012, 2013 Beidouapp Corp.
*
* All rights reserved.
*
* Contributors:
* Peter Peng - initial contribution
*******************************************************************************/ #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include "esp_common.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "driver/uart.h" #include "user_config.h"
#include "et_fifo.h"
#include "lwip/netdb.h"
#include "factory.h"
#include "espressif/upgrade.h"
#include "et_api_compatible.h" #define MAX_USER_ID 32
#define MAX_ILINK_CONNECT 5 et_char g_user_id[ET_USER_ID_LEN_MAX] = {};
et_char g_group_id[ET_USER_ID_LEN_MAX] = {};
et_uint32 g_group_message = ;
struct hostent *file_server_ip_addr = NULL;
msg_to_net_t msg={};
et_uchar code[]={};
extern et_int32 read_uart_data_flag;
extern xQueueHandle xQueueUart;
et_cloud_handle g_cloud_handle = NULL;
et_cloud_connect_type g_cloud_con_para = {ET_FALSE, ET_TRUE, };
et_uchar kick_out=;
et_dfs_file_info_type i_file_info; struct ilink_connect_client
{
et_int32 state;
et_char user_id[MAX_USER_ID]; }; static struct ilink_connect_client g_ilink_connect_clients[MAX_ILINK_CONNECT]; static et_uchar uart_recv_buff[UART_MAX_READ_BUFFER] = {};
static et_uchar uart_send_buff[UART_MAX_SEND_BUFFER] = {};
et_int32 to_stop_app = ; et_uint32 write_flash_end=;
et_int64 file_total_size=;
et_uint32 audio_voice_data=;
et_uint16 sector=AUDIO_FLASH_START_SECTOR; //打印16进制
void print_hex(et_uchar *label, et_uchar *str, et_int32 len)
{
et_int32 i; os_printf("%s : ", label);
for(i = ; i < len; i++)
os_printf("%02x ", str[i]);
os_printf("\n");
} //Check数据校验
et_uchar check_sum(et_uchar *buf, et_int32 len)
{
et_uchar bcc=;
et_int32 i; for(i = ; i < len; i ++)
bcc ^= buf[i]; return bcc;
} // ascii to 8421bcd,say 0x32 = 50
et_uint32 ascii_2_dec(et_int32 ascii)
{
et_int32 n =, dec=; while(ascii > )
{
dec += (ascii % ) * n;
ascii /=;
n *= ;
} return dec;
} //为服务器准备数据
static et_int32 ack_to_mqtt(et_uchar *msg_buf, et_uchar *ack_buf, et_int32 rc)
{
et_int32 len = START_LEN; ack_buf[] = 0xFF;
ack_buf[] = 0xFF;
ack_buf[] = 0x00;
ack_buf[] = ACK_ERROR_LEN;
ack_buf[] = msg_buf[] | 0x0F;
ack_buf[] = msg_buf[];
ack_buf[] = msg_buf[];
ack_buf[] = rc;
ack_buf[] = check_sum(&ack_buf[], ACK_ERROR_LEN + );
len += ACK_ERROR_LEN; return len; } //为服务器准备温湿度数据
static et_int32 ack_temp_hum_to_mqtt(et_uchar *msg_buf, et_uchar *temp_hum, et_uchar *ack_buf, et_uchar rc)
{
et_int32 len=START_LEN; ack_buf[] = 0xFF;
ack_buf[] = 0xFF;
ack_buf[] = 0x00;
ack_buf[] = ACK_TEMP_HUM_LEN;
ack_buf[] = msg_buf[] | 0x0F;
ack_buf[] = msg_buf[];
ack_buf[] = msg_buf[];
ack_buf[] = rc;
ack_buf[] = ascii_2_dec(temp_hum[]); //we transform to 8421bcd 0x50
ack_buf[] = ascii_2_dec(temp_hum[]);
ack_buf[] = ascii_2_dec(temp_hum[]);
ack_buf[] = ascii_2_dec(temp_hum[]);
ack_buf[] = check_sum(&ack_buf[], ACK_TEMP_HUM_LEN + );
len += ACK_TEMP_HUM_LEN; return len;
} //为服务器准备气压传感器数据
static et_int32 ack_barometric_to_mqtt(et_uchar *msg_buf, et_int32 barometric, et_int32 temp, et_uchar *ack_buf, et_uchar rc)
{
et_uchar baro[]={}, t;
et_int32 i, tmp, len=START_LEN; tmp = ascii_2_dec(barometric);
for(i = ; i < ; i++)
baro[i] = tmp >> ( - i) * ; tmp = ascii_2_dec(temp);
t = tmp; ack_buf[] = 0xFF;
ack_buf[] = 0xFF;
ack_buf[] = 0x00;
ack_buf[] = ACK_BAROMETRIC_LEN;
ack_buf[] = msg_buf[] | 0x0F;
ack_buf[] = msg_buf[];
ack_buf[] = msg_buf[];
ack_buf[] = rc;
ack_buf[] = baro[];
ack_buf[] = baro[];
ack_buf[] = baro[];
ack_buf[] = baro[];
ack_buf[] = t;
ack_buf[] = check_sum(&ack_buf[], ACK_BAROMETRIC_LEN + );
len += ACK_BAROMETRIC_LEN; return len;
} //上传回调函数
void upgrade_callback(void *arg)
{
struct upgrade_server_info *server = arg; if(server->upgrade_flag == true)
{
printf("upgrade success.\n");
system_upgrade_reboot();
}
else
printf("upgrade failed.\n"); free(server->url);
server->url = NULL;
} //解析服务器发送信息
et_int32 parse_msg_from_mqtt(et_uchar *msg_buf, et_int32 data_len)
{
et_int32 i, pos=, rc = -;
et_uchar cmd, type, bcc;
et_int32 len, seq;
et_uint16 gb_code=;
WORK_MODE_T mode; #ifdef USER_PRINT_DEBUG
print_hex("msg_buf", msg_buf, data_len);
#endif if(msg_buf[pos] != 0xFF ||msg_buf[pos + ] != 0xFF)
{
os_printf("parse packet head error\n");
return rc;
}
pos += ; len = (msg_buf[pos] << ) | msg_buf[pos + ];
if(len < || len != data_len - - )
{
os_printf("parse packet length error\n");
return rc;
} bcc = check_sum(&msg_buf[pos], len + - );
if(bcc != msg_buf[data_len - ])
{
msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_BCC_ERROR);
os_printf("bcc error\n");
rc = et_chat_to(g_cloud_handle,msg.buf, msg.len, g_user_id, SEND_TO_ALL);
return rc;
} pos += ; cmd = msg_buf[pos];
pos += ; seq += msg_buf[pos];
pos += ; type = msg_buf[pos];
pos += ; mode = user_get_run_mode(); //get board mode from adc
switch(cmd)
{
case CMD_VER_UPDATE_NOTE: //版本升级事件
{
et_uint version_len= len - ;
et_uchar version[]={}, user_bin[]={}, bin=;
struct upgrade_server_info server={}; strncpy(version, &msg_buf[pos], version_len);
if(strcmp(version, SOFTWARE_VERSION))
{
server.sockaddrin.sin_addr.s_addr = inet_addr("192.168.13.103");
server.sockaddrin.sin_port = htons();
server.sockaddrin.sin_family = AF_INET;
server.check_cb = upgrade_callback;
server.check_times = ;
strncpy(server.pre_version, SOFTWARE_VERSION, strlen(SOFTWARE_VERSION));
strncpy(server.upgrade_version, version, version_len);
if(server.url == NULL)
server.url = (et_uchar *)malloc();
memset(server.url, , ); bin = system_upgrade_userbin_check();
if(bin == UPGRADE_FW_BIN1)
{
memcpy(user_bin, "test/user2.bin", );
}
else if(bin == UPGRADE_FW_BIN2)
{
memcpy(user_bin, "test/user1.bin", );
} sprintf(server.url, "GET /%s HTTP/1.0\r\nHost: %s:%d\r\n"pheadbuffer"", user_bin, "192.168.13.103", ); if(system_upgrade_start(&server) == false)
{
printf("upgrade is already started\n");
} }
}
break; case CMD_CONTROL: //控制命令
{
switch(type)
{
case TYPE_RGB_LIGHT_DEV: //RGB_light
{
if(mode == WORK_MODE_RGB)
{ //code undefine
et_uchar red;
et_uchar gre;
et_uchar blu; red = msg_buf[pos];
pos += ;
gre = msg_buf[pos];
pos += ;
blu = msg_buf[pos]; RGB_light_set_color(red, gre, blu); //set rgb color
msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_SUCCESS);
rc = msg.len;
}
else
{
printf("mode error, mode = %u\n", mode);
msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_MODE_ERR);
rc = msg.len;
}
}
break; case TYPE_OLED_DEV: //OLED
{
et_uchar z_code, b_code;
et_uint offset;
et_uchar num,i=,j,line,colum[]={}; //OLED 128x64, character is 16x16, per line can show 128/16 =8 character,
//in total lines is 64/16 = 4, the OLED can display 32 charaters in total
if(mode == WORK_MODE_OLED)
{
num = (len - ) / ; //numbers of characters
if(num == )
break; if(num > )
num = ; line = (num - ) / + ; for(i = ; i < line - ; i++) //0 to line -1 is 8 characters
{
colum[i] = ;
} colum[i] = num % ; //the last line
if(colum[i] == )
colum[i] = ; OLED_clear(); //clear oled
for(i = ; i < line; i++)
{
for(j = ; j < colum[i] ; j++)
{
z_code = msg_buf[pos++];
b_code = msg_buf[pos++]; gb_code = (z_code << ) | b_code;
if(gb_code > 0x3759) //after 0xd7f9 ,five space
{
gb_code -= ;
if(b_code >= 0x01 && b_code <= 0x04)
gb_code -= 0xa2;
} z_code = (gb_code >> ) & 0xff;
b_code = gb_code & 0xff;
offset = ((et_uint32) * (z_code - 0x10) + b_code - 0x01)*( * );
spi_flash_read(GB_DZK_START_SECTOR * SPI_FLASH_SEC_SIZE + offset, (et_uint *)code , );
oled_show_gb_chn( * j, * i, code);
}
} msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_SUCCESS);
rc = msg.len;
}
else
{
os_printf("mode error, mode = %d\n", mode);
msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_MODE_ERR);
rc = msg.len;
}
}
break; default:
break;
}
}
break; case CMD_QUERY: //查询命令
{
switch(type & 0xF0)
{
case TYPE_TEMP_HUM_SENSOR: //温湿度传感器
{
et_uchar temp_hum[HUM_DATA_SIZE]={}; if(DHT11_read_temp_hum(temp_hum, HUM_DATA_SIZE) != RETURN_OK)
{
os_printf("DHT11_read_temp_hum error\n");
msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_DEV_FAILED);
rc = msg.len;
break;
} msg.len = ack_temp_hum_to_mqtt(msg_buf, temp_hum, msg.buf, ACK_SUCCESS);
rc = msg.len; if(mode == WORK_MODE_OLED)
{
et_uchar display_temp[]={};
et_uchar display_hum[]={};
sprintf(display_temp, ":%d.%d", temp_hum[], temp_hum[]);
sprintf(display_hum, ":%d.%d%%", temp_hum[], temp_hum[]);
OLED_clear(); //clear oled
switch(type & 0x0F)
{
case TEMP_AND_HUM: //温度和湿度
{
//display tempeature and hummity, such as:
//温度:20.08℃
//湿度:60.89%
OLED_show_chn(, , ); //show 小e:
OLED_show_str(, , "e:", );
OLED_show_chn(, , ); //温
OLED_show_chn(, , ); //度
OLED_show_str(, , display_temp, ); //such as :20.08
OLED_show_chn(, , ); //℃ OLED_show_chn(, , ); //湿
OLED_show_chn(, , ); //度
OLED_show_str(, , display_hum, );//such as :80.05% }
break; case TEMPERATUR: //温度
{
OLED_show_chn(, , ); //show 小e:
OLED_show_str(, , "e:", );
OLED_show_chn(, , ); //温
OLED_show_chn(, , ); //度
OLED_show_str(, , display_temp, ); //such as :20.08
OLED_show_chn(, , ); //℃
}
break; case HUMMITY: //湿度
{
OLED_show_chn(, , ); //show 小e:
OLED_show_str(, , "e:", );
OLED_show_chn(, , ); //湿
OLED_show_chn(, , ); //度
OLED_show_str(, , display_hum, );//such as :80.05%
}
break;
}
}
}
break; case TYPE_BAROMETRIC_SENSOR: //气压传感器
{
et_long32 barometric=, temperature=;
if(mode == WORK_MODE_BAROMETRIC)
{
barometric = barometric_collect(&temperature);
if(barometric == -)
{
os_printf("barometric_collect error\n");
msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_DEV_FAILED);
rc = msg.len;
break;
}
msg.len = ack_barometric_to_mqtt(msg_buf, (et_int32)barometric, (et_int32)temperature, msg.buf, ACK_SUCCESS);
rc = msg.len;
}
else
{
os_printf("mode error, mode = %d\n", mode);
msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_MODE_ERR);
rc = msg.len;
}
}
break; default:
break;
} }
break; default:
msg.len = ack_to_mqtt(msg_buf, msg.buf, ACK_CMD_ILLIGAL);
rc = msg.len;
break;
} //上传信息
rc = et_chat_to(g_cloud_handle,msg.buf, msg.len, g_user_id, SEND_TO_CLOUD_FIRST); return rc;
} et_int32 add_userid_to_clients(et_char *userid)
{
et_int32 i = ,j = ;
et_int32 ret = -;
et_char *str = "now device has max users";
//et_int32 add_flag = 0; for(i = ; i < MAX_ILINK_CONNECT;i++)
{
if(g_ilink_connect_clients[i].state == )
{
ret = strcmp(userid,g_ilink_connect_clients[i].user_id);
if(ret == )
{
return -;
}
} } for(j = ; j < MAX_ILINK_CONNECT;j ++)
{
if(g_ilink_connect_clients[j].state == -)
{
g_ilink_connect_clients[j].state = ;
strcpy(g_ilink_connect_clients[j].user_id,userid);
os_printf("now add userid is %s\n",g_ilink_connect_clients[j].user_id);
break; } } if(j >= MAX_ILINK_CONNECT)
{
et_chat_to(g_cloud_handle,str,strlen(str),userid,SEND_TO_CLOUD);
return -;
}
else
{
return ;
}
} et_int32 remove_userid_clients(et_char *userid)
{
et_int32 i = ;
et_int32 ret = -;
for(i = ; i < MAX_ILINK_CONNECT;i++)
{
if(g_ilink_connect_clients[i].state == )
{
ret = strcmp(userid,g_ilink_connect_clients[i].user_id);
if(ret == )
{
os_printf("now userid is %s\n",g_ilink_connect_clients[i].user_id);
g_ilink_connect_clients[i].state = -;
memset(g_ilink_connect_clients[i].user_id,,sizeof(g_ilink_connect_clients[i].user_id));
os_printf("now status is %d\n",g_ilink_connect_clients[i].state);
return ;
}
} } return -; } void read_uart_buf_task(void *pvParameters)
{
os_event_t e;
et_int32 rc = ;
et_int32 cmd,seq,len;
et_uchar *data; for (;;)
{
if (xQueueReceive(xQueueUart, (void *)&e, (portTickType)portMAX_DELAY))
{
switch (e.event)
{
case UART_EVENT_RX_CHAR:
{
read_uart_data_flag = ;
memset(uart_recv_buff,,sizeof(uart_recv_buff));
rc = recv_data_uart(uart_recv_buff, e.param, e.param * );
read_uart_data_flag = ;
printf("receive uart %d\n", rc);
}
break; default:
break;
}
}
} vTaskDelete(NULL);
} void init_clients(void)
{
et_int32 j = ; for(j = ; j < MAX_ILINK_CONNECT;j ++)
{
g_ilink_connect_clients[j].state = -;
memset(g_ilink_connect_clients[j].user_id,,sizeof(g_ilink_connect_clients[j].user_id)); } } //写Flash回调函数
et_int32 write_flash_callback (void *arg, const et_int64 file_size, const et_char *data, const et_int32 current_size)
{
et_int32 result=-; if (arg == NULL)
{
return EINVAL;
} if(sector > AUDIO_FLASH_STOP_SECTOR) //超过flash,flash重新覆盖初始地址
{
file_total_size += current_size;
if(file_total_size >= file_size)
{
sector = AUDIO_FLASH_START_SECTOR;
file_total_size = AUDIO_FLASH_LEN - ;
audio_voice_data = ; //to inform interrupt of voice data coming //越界不播放,仍然下载完,只是覆盖
write_flash_end = ; //to inform interrupt of being able to send voice data to i2s
printf("file size > flash size.just play length of flash size(the former 45 seconds).\n");
} return ;
} result = spi_flash_erase_sector(sector);
if(result != SPI_FLASH_RESULT_OK)
{
printf("spi_flash_erase_sector error\n");
return -;
} result = spi_flash_write(sector * SPI_FLASH_SEC_SIZE, (et_uint32 *)data, current_size); //write received voice data(4096 bytes) to flash
if(result != SPI_FLASH_RESULT_OK)
{
printf("spi_flash_write error\n");
return -;
} file_total_size += current_size;
sector++; if(file_total_size >= file_size) //下载完成
{
if(file_size > AUDIO_FLASH_LEN) //文件总长度打印flash长度,只播放音频的flash长度
file_total_size = AUDIO_FLASH_LEN; printf("down load file end.\n");
sector = AUDIO_FLASH_START_SECTOR;
audio_voice_data = ; //to inform interrupt of voice data coming
write_flash_end = ; //to inform interrupt of being able to send voice data to i2s
} return ;
} //消息处理任务
//其实对于消息和时间的分支定义,在 smart_e_taste_v1.4.x.x\et_app\include 的 et_types.h 的文件里。开发快官方写得非常详细。
void et_message_process(et_int32 type, et_char *send_userid, et_char *topic_name, et_int32 topic_len, et_context_mes_type *message)
{
int rc = -; switch(type)
{
case MES_CHAT_TO_CHAT: //点对点消息事件
{
os_printf("mes chat to chat: %s\n", send_userid);
memset(g_user_id, , sizeof(g_user_id));
snprintf(g_user_id, sizeof(g_user_id), "%s",send_userid);
parse_msg_from_mqtt(message->payload, message->payload_len);
}
break; case MES_FILE_TRANSFERS: //文件传输消息事件
{
if(user_get_run_mode() != WORK_MODE_AUDIO)
{
printf("run in mode %d ,error\n", user_get_run_mode());
break;
} os_printf("File trans mes from %s:%s\n", send_userid, topic_name);
memset(&i_file_info, , sizeof(et_dfs_file_info_type));
rc = et_file_info(g_cloud_handle,message->payload, &i_file_info);
if(rc == -)
{
os_printf("file info parse failed\n");
break;
} if(file_server_ip_addr == NULL)
{
file_server_ip_addr = gethostbyname(i_file_info.source_ip_addr);
if(file_server_ip_addr == NULL)
{
os_printf("failed, get ip from im server\n");
break;
}
} memset(i_file_info.source_ip_addr, , sizeof(i_file_info.source_ip_addr));
strcpy(i_file_info.source_ip_addr, inet_ntoa(*(file_server_ip_addr->h_addr))); while(write_flash_end)
{
os_delay_us();
} rc = et_down_file(g_cloud_handle,&i_file_info, write_flash_callback);
}
break; case MES_FROM_GROUP_SUBTOPIC: //群消息和主题消息事件
{
os_printf("Group mes from %s\n", topic_name); parse_msg_from_mqtt(message->payload, message->payload_len);
}
break; case MES_FROM_LOCAL: //内网消息事件
{
os_printf("Local mes from %s:%s\n", send_userid, topic_name);
memset(g_user_id, , sizeof(g_user_id));
snprintf(g_user_id, sizeof(g_user_id), "%s",send_userid);
parse_msg_from_mqtt(message->payload, message->payload_len);
}
break; case MES_NOTICE_ADD_BUDDY: //添加用户消息事件
os_printf("You are be add buddy by %s:%s\n", send_userid, topic_name);
break; case MES_NOTICE_REMOVE_BUDDY: //删除用户消息事件
os_printf("You are be remove buddy by %s:%s\n", send_userid, topic_name);
break; case MES_USER_OFFLINE: //用户下线消息事件
os_printf("%s Offline:%s\n", send_userid, topic_name);
break; case MES_USER_ONLINE: //用户上线消息事件
os_printf("%s Online:%s\n", send_userid, topic_name);
break; case MES_USER_STATUS: //用户状态消息事件
os_printf("%s Status:%s\n", send_userid, topic_name);
break; case MES_ONLINE_BUDDIES_LIST: //在线好友列表消息事件
os_printf("Get online buddies list%s:%s\n", send_userid, topic_name);
break;
}
} //事件处理任务
void et_event_process(et_event_type event)
{
et_int32 rc = -; switch(event.event_no)
{
case EVENT_CLOUD_CONNECT: //ilink连接事件
{
disarm_wifi_spark_timer();
wifi_led_on();
os_printf("You are connect:0x%x\n", event.event_no);
}
break;
case EVENT_CLOUD_DISCONNECT: //ilink断连事件
{
set_wifi_spark_timer();
os_printf("You are disconnect:0x%x\n", event.event_no);
//et_logout_cloud(g_cloud_handle);
//et_stop_srv(g_cloud_handle);
}
break;
case EVENT_LOGIN_KICK: //被踢下线事件
kick_out = ;
os_printf("Your account was login by others:0x%x\n", event.event_no);
//et_stop_srv(g_cloud_handle);
//et_logout_cloud(g_cloud_handle);
break;
case EVENT_CLOUD_SEND_FAILED: //外网消息发送失败事件
os_printf("Cloud send failed\n");
break;
case EVENT_CLOUD_SEND_SUCCESS: //外网消息发送成功事件
os_printf("Cloud send success\n");
break;
case EVENT_LOCAL_SEND_FAILED: //内网消息发送失败事件
os_printf("Local send failed\n");
break;
case EVENT_LOCAL_SEND_SUCCESS: //内网消息发送成功事件
os_printf("Local send success\n");
break;
}
} //外网处理任务
void et_ilink_task(void *pvParameters)
{
while()
{
if(!kick_out)
et_ilink_loop(g_cloud_handle);
taskYIELD();
}
vTaskDelete(NULL);
} //内网处理任务
void et_local_task(void *pvParameters)
{
while()
{
et_server_loop(g_cloud_handle);
taskYIELD();
} vTaskDelete(NULL);
} //用户主任务
void et_user_main(void *pvParameters)
{
et_int32 rc = -;
id_info_t id;
et_server_info_t server_info;
et_net_addr_type g_cloud_addr_para = {NULL, }; os_printf("ET U-SDK var%s\n",et_sdk_ver()); //输出et_SDK版本
to_stop_app = ; memset(&id, , sizeof(id_info_t)); //开辟id信息空间
if(get_uid(&id) != SPI_FLASH_RESULT_OK) //判断获取id状态
{
os_printf("et_user_main, get_uid error\n");
return ;
} id.uid[UID_LEN - ] = '\0'; //使用Printf,遇到'\0'停止->添加结尾数符
id.appkey[APPKEY_LEN - ] = '\0';
id.secretkey[SECRETKEY_LEN - ] = '\0'; memset(&server_info, , sizeof(et_server_info_t)); //开辟服务器信息空间
if(get_server(&server_info) != SPI_FLASH_RESULT_OK) //获取服务器信息
{
os_printf("et_user_main, get_server error\n");
return ;
} server_info.lb_addr[ET_LB_ADDR_MAX - ] = '\0';
server_info.lb_port[ET_LB_PORT_MAX - ] = '\0'; g_cloud_addr_para.name_ip = server_info.lb_addr; //绑定云平台地址
g_cloud_addr_para.port = atoi(server_info.lb_port); //绑定云平台端口 os_printf("uid : %s\n", id.uid);
os_printf("appkey : %s\n", id.appkey);
os_printf("secretkey : %s\n", id.secretkey);
os_printf("server information %s : %s\n", server_info.lb_addr, server_info.lb_port); //创建用户信息上下问,在et_client文件中有说明
g_cloud_handle = et_create_context(id.uid, id.appkey, id.secretkey, g_cloud_addr_para);
if(NULL == g_cloud_handle) //如果为Null表示没有用户
{
os_printf("Init et account failed\n");
goto error;
} //设置消息发送回调函数,事件回调函数
if(et_set_callback(g_cloud_handle,et_message_process, et_event_process) < )
{
os_printf("%s et_set_callback failed.\n");
et_destroy_context(g_cloud_handle); //设置失败销毁用户信息上下文
goto error;
} //内网连接,开始连接云
rc = et_start_svr(g_cloud_handle);
if(rc != ){
os_printf("%s et_start_svr fail.\n", __FUNCTION__);
et_destroy_context(g_cloud_handle);
return;
} //创建内网任务
if(pdPASS != xTaskCreate(et_local_task, "local_task", , NULL, , NULL))
{
os_printf("%s et_local_task failed.\n", __FUNCTION__);
et_stop_srv(g_cloud_handle);
et_destroy_context(g_cloud_handle);
return;
} //外网连接,注册用户信息
do
{
rc = et_login_cloud(g_cloud_handle, g_cloud_con_para);
if(rc != )
{
os_printf("login_cloud fail\n");
}
vTaskDelay( / portTICK_RATE_MS); //如果失败,每隔2s注册
}
while(rc != && to_stop_app == ); //创建一个连接任务
if(pdPASS != xTaskCreate(et_ilink_task, "ilink_task", , NULL, , NULL))
{
os_printf("%s et_ilink_task failed.\n", __FUNCTION__);
et_logout_cloud(g_cloud_handle);
et_destroy_context(g_cloud_handle);
goto error;
} error:
vTaskDelete(NULL);
return ;
} //函数 et_create_context ,et_destroy_context,et_set_callback的位置是在 smart_e_taste_v1.4.x.x\et_app\include 的 et_client.h 的文件里。
//函数 et_start_svr,et_stop_srv,et_login_cloud,et_logout_cloud的位置是在 smart_e_taste_v1.4.x.x\et_app\include 的 et_api_compatible.h 的文件里。

二. 开发块平台ESP8266模块Flash功能分区表

地址 固件名 功能
0x0 boot_v1.5.bin 启动引导,系统固件(原厂)
0x1000 user1.2048.new.3.bin 上节编译生成的固件,用户应用程序
0xfc000(4KB) fac.bin 进入工厂模式的bin,烧入该bin,用户可以重新烧入uid等信息到flash
0xfe000(4KB)>   Uid/appkey/securtkey存放地址
0xff000(4KB)   服务器ip、端口号存放地址
0x100000-0x1AE000   该分区用于存放当前体验语音留言功能时微信端下发的音频文件
0x1b0000 gb2312_only_characters.bin gb2312中文字库
0x1fc000 esp_init_data_default.bin 系统参数(原厂)
0x1fe000 blank.bin 系统固件(原厂)

开发快平台(M302I小e开发板系列教程)

三.   烧写固件方法如下:

1. ESP8266模块Flash擦除方法:

A.  ESP8266擦除工具路径:

http://down.liangchan.net/ESP8266%B2%C1%B3%FD%B9%A4%BE%DF%CD%EA%D5%FB%B0%B2%D7%B0.zip

http://www.liangchan.net/liangchan/9183.html

B 操作方法:

a、安装python27。

b、下载get-pip.py到python安装目录。

c、进入到pip安装包所在的目录,如“cd C:\Python27\Scripts”,运行python get-pip.py指令,等候一分钟。

d、把esptool-master文件夹放到python目录下。

e、安装esptool和pyserial。直接运行pip install esptool和pip install pyserial两条指令即可自动完成。

f、把ESP8266清除flash工具放入esptool-master目录,运行软件即可。(备注: ESP8266工作在升级模式,即:GPIO0接地 )

2. 配置烧录工具
    解压FLASH_DOWNLOAD_TOOLS_v2.4_150924.rar,并打开烧写软件:ESP_DOWNLOAD_TOOL_V2.4.exe,在Download Path Config选中文件并填写正确的地址,在前面的小框中打勾,表示选中该文件;按照下图配置SPI FLASH CONFIG参数;并在COM PORT选中开发板的串口PORT;
开发快平台(M302I小e开发板系列教程)
3. 烧录
    配置完成之后,点击START,出现下图所示表示等待烧录,此时按住airkiss按键不放,同时通过开关对开发板上电;当烧录进度条开始增长,表示开始烧写,此时释放airkiss按键,等待进度条变化直到显示烧录完成;
开发快平台(M302I小e开发板系列教程)
4.  固件烧写注意事项
(1)user1.2048.new.3.bin文件在bin/upgrade下面,其它文件在bin目录下面;
(2)M302I开发板出厂时已经烧入了表1所列的所有固件,用户在编译自己的用户程序时,可以仅仅烧入生成的用户固件(即user1.2048.new.3.bin),而不用烧入其他参数和固件;
(3)fac.bin文件是使开发板处于工厂生产模式的文件,如果烧入该文件,系统重启后将进入工厂模式,在该模式下可以重新烧入appkey/uid/securtkey以及服务器地址和端口号,如果在必要的情况下(比如appkey/uid/securtkey以及服务器地址和端口号分区不小心被烧入其他固件而使他们丢失了),可以重新烧入这些参数。

四. 操作步骤模式:

1.  获取ESP8266模块

a. 新的模块,内置已经下载好原厂固件,可以直接按照步骤2操作;

b. 如果是其它途径获取的模块,对下载的固件不了解,可以直接对Flash进行擦除操作,按照步骤2操作;

2.  使用开发快平台上的固件进行下载,固件可以到官网进行下载,或者找一个工厂文件进行下载,下载操作参考: “三.   烧写固件方法如下”

3.  通过单独或者下载全部文件(包含fac.bin文件),能够在串口工具中看到模块进入到工厂模式,在工厂模式下,能够通过: "设备标识码配置工具 - EtDevQuickTool.exe"来烧写相关信息 ,修改后,通过按恢复出厂设置,能够进入到正常工作模式;如下图:

开发快平台(M302I小e开发板系列教程)

4. 需要填写的相关信息如下:

APPKEY:  32d64ec4-9999-219200
 SECRETKEY: 1fc54501b999999999f42b6b9280237f
 U-SDK-UID:  Fc5wGsTuv9999999992rtasEjmj9QPfFZR
 ADDRESS:    lb.kaifakuai.com
 PORT:       8085 
 草料二维码生成器:https://cli.im/
   UID信息格式: {"appkey":"32d64ec4-9999-219200","uid":"Fc5wGsTuv9999999992rtasEjmj9QPfFZR"}

以上信息需要注册开发快,进入到云平台,在其中创建一个项目,ESP8266模块应该选择MCU平台,如下图:

开发快平台(M302I小e开发板系列教程)

5. 参考地址:

http://bbs.kaifakuai.com/forum.php?mod=viewthread&tid=1893&extra=page%3D1

6.  在正常工作模式下,通过按键操作,能够进入到Smart Config 模式下,用于通过微信平台连接,能够让ESP8266模块连接到Wifi;

7. 通过对源码进行修改,在Ubuntu环境下进行编译,生产新的user1.2048.new.3.bin文件,通过下载到ESP8266模块后能够运行新的应用;