Deveria haver uma PAC, mas não havia orçamento suficiente para isso.Motivado pela resposta de
Tarson ao meu comentário sobre
Programação e troca de dados com ARDUINO via WIFI via ESP8266 , decidi escrever sobre o básico da programação ESP8266 em C no FreeRTOS. Detalhes sob o corte.
Etapa 0 - dispositivoPrimeiro, você precisa adquirir um dispositivo com o ESP8266; é desejável que o USB para o UART seja separado lá, para que você não precise desligar o programador. Passo minhas experiências desumanas no
NodeMCU .
Então, passo 1 - colete a cadeia de ferramentasPrimeiro você precisa ter um computador com a distribuição Linux instalada (eu tenho o OpenSUSE Leap). Vamos ao github no link
tyts , lemos as instruções de montagem, instalamos as dependências necessárias, clonamos o repositório e coletamos. Eu clonei em / opt / ESP e antes de montar as regras do Makefile, definindo as variáveis:
STANDALONE = n VENDOR_SDK = 2.1.0
Em seguida, você pode adicionar o caminho aos binários da cadeia de ferramentas no PATH em ~ / .bashrc:
export PATH=/opt/ESP/esp-open-sdk/xtensa-lx106-elf/bin:$PATH
Etapa 2 - obtenha o SDKVamos ao github (
tynk ), lemos as instruções, clonamos (por exemplo, em / opt / ESP). Em seguida, definimos a variável de ambiente ESP8266_SDK_PATH da nossa maneira favorita (por exemplo, através de ~ / .bashrc):
export ESP8266_SDK_PATH=/opt/ESP/esp-open-rtos
Etapa 3 - criar um projetoVamos para o diretório de exemplos no diretório com o SDK e copiamos qualquer exemplo que você desejar. Importamos / abrimos o projeto em nosso ambiente de desenvolvimento favorito. Os masoquistas podem usar um editor de texto. Eu prefiro o NetBeans - ele tem um bom suporte para projetos C / C ++, incluindo aqueles baseados no Makefile. O projeto é montado usando make, é costurado usando make flash. No arquivo local.mk, você pode configurar os parâmetros para a atualização do dispositivo (tamanho e modo de acesso à memória flash, por exemplo).
Etapa 4 - ProgramaçãoAnalisamos os requisitos, a área de assunto, compilamos as especificações técnicas de acordo com GOST 34.602-89, após o qual você pode começar a escrever o código :) Eu não pisquei os LEDs, porque não os tenho, então, como um HelloWorld, lerei dados do sensor AM2302 (é DHT22) e enviá-los pelo protocolo MQTT para o servidor.
Para usar módulos adicionais, por exemplo, MQTT ou DHT, eles devem ser adicionados ao Makefile:
PROGRAM=fffmeteo EXTRA_COMPONENTS = extras/paho_mqtt_c extras/dht include $(ESP8266_SDK_PATH)/common.mk
main.h #ifndef MAIN_H #define MAIN_H #include <stdio.h> #include <stdint.h> #include <limits.h> #include <FreeRTOS.h> #include <task.h> #include <queue.h> #include <semphr.h> #define DEBUG #ifdef DEBUG #define debug(args...) printf("--- "); printf(args) #define SNTP_DEBUG_ENABLED true #else #define debug(args...) #define SNTP_DEBUG_ENABLED false #endif #define WIFI_SSID "kosmonaFFFt" #define WIFI_PASS "mysupermegapassword" #define MQTT_HOST "m11.cloudmqtt.com" #define MQTT_PORT 16464 #define MQTT_USER "kosmonaFFFt" #define MQTT_PASS "mysupermegapassword" #define MQTT_TOPIC "/meteo" #define NTP_SERVER "pool.ntp.org" #define UART0_BAUD 9600 #define STACK_SIZE 512 #define INIT_TASK_PRIORITY (configTIMER_TASK_PRIORITY + 1) #define MEASUREMENT_TASK_PRIORITY (INIT_TASK_PRIORITY + 1) #define SENDING_DATA_TASK_PRIORITY (MEASUREMENT_TASK_PRIORITY + 1) #define MEASUREMENTS_PERIOD_S 59 #define MAX_MEASUREMENTS_COUNT 16 #define SEND_PERIOD_S 120 #define RUN_SNTP_SYNC_PERIOD 5 #define MS(x) (x / portTICK_PERIOD_MS) #define AM2302_PIN 5 #ifdef __cplusplus extern "C" { #endif #ifdef __cplusplus } #endif #endif /* MAIN_H */
main.c #include "main.h" #include "sntp.h" #include <esp/uart.h> #include <espressif/esp_common.h> #include <paho_mqtt_c/MQTTESP8266.h> #include <paho_mqtt_c/MQTTClient.h> #include <dht/dht.h> //-----------------------------------------------------------------------------+ // Measurements task section. | //-----------------------------------------------------------------------------+ struct measurement_results { time_t timestamp; int am2302_humidity; int am2302_temperature; }; static QueueHandle_t measurements_queue; void measurement_task(void *arg) { int16_t humidity; int16_t temperature; struct measurement_results measurements; while (true) { debug("MEASUREMENTS: Start measurements...\n"); measurements.timestamp = time(NULL); bool success = dht_read_data(DHT_TYPE_DHT22, AM2302_PIN, &humidity, &temperature); if (success && temperature >= -500 && temperature <= 1500 && humidity >= 0 && humidity <= 1000) { measurements.am2302_humidity = humidity; measurements.am2302_temperature = temperature; } else { debug("MEASUREMENT: Error! Cannot read data from AM2302!!!\n"); measurements.am2302_humidity = INT_MIN; measurements.am2302_temperature = INT_MIN; } debug("MEASUREMENTS: Measurements finished...\n"); xQueueSendToBack(measurements_queue, &measurements, MS(250)); vTaskDelay(MS(MEASUREMENTS_PERIOD_S * 1000)); } vTaskDelete(NULL); } //-----------------------------------------------------------------------------+ // Sending data task section. | //-----------------------------------------------------------------------------+ static uint8_t mqtt_buf[512]; static uint8_t mqtt_readbuf[128]; void sending_data_task(void *arg) { mqtt_network_t network; mqtt_network_new(&network); mqtt_client_t client = mqtt_client_default; mqtt_packet_connect_data_t data = mqtt_packet_connect_data_initializer; uint8_t sntp_sync_counter = 0; while (true) { debug("MQTT: ConnectNetwork...\n"); int err = mqtt_network_connect(&network, MQTT_HOST, MQTT_PORT); if (err) { debug("MQTT: Error!!! ConnectNetwork ERROR!\n"); vTaskDelay(MS(5 * 1000)); continue; } else { debug("MQTT: ConnectNetwork success...\n"); } // TODO: add check for errors!!! // TODO: replace magic constants!!! mqtt_client_new(&client, &network, 5000, mqtt_buf, 100, mqtt_readbuf, 100); data.willFlag = 0; data.MQTTVersion = 3; data.clientID.cstring = "fff"; data.username.cstring = MQTT_USER; data.password.cstring = MQTT_PASS; data.keepAliveInterval = 10; data.cleansession = 0; err = mqtt_connect(&client, &data); if (err) { debug("MQTT: Error!!! MQTTConnect ERROR!\n"); vTaskDelay(MS(5 * 1000)); continue; } else { debug("MQTT: MQTTConnect success...\n"); } struct measurement_results msg; while (xQueueReceive(measurements_queue, &msg, 0) == pdTRUE) { if (msg.am2302_humidity == INT_MIN || msg.am2302_temperature == INT_MIN) { debug("MQTT: Got invalid message, no publishing!!!\n"); continue; } debug("MQTT: Got message to publish...\n"); debug(" timestamp: %ld\n", msg.timestamp); debug(" am2302_humidity: %.1f\n", msg.am2302_humidity / 10.0); debug(" am2302_temperature: %.1f\n", msg.am2302_temperature / 10.0); msg.timestamp = htonl(msg.timestamp); msg.am2302_humidity = htonl(msg.am2302_humidity); msg.am2302_temperature = htonl(msg.am2302_temperature); mqtt_message_t message; message.payload = &msg; message.payloadlen = sizeof (msg); message.dup = 0; message.qos = MQTT_QOS1; message.retained = 0; err = mqtt_publish(&client, MQTT_TOPIC, &message); if (err) { debug("MQTT: Error!!! Error while publishing message!\n"); } else { debug("MQTT: Successfully publish message...\n"); } } mqtt_disconnect(&client); mqtt_network_disconnect(&network); ++sntp_sync_counter; if (sntp_sync_counter == RUN_SNTP_SYNC_PERIOD) { sntp_sync(NTP_SERVER, NULL, arg); sntp_sync_counter = 0; } vTaskDelay(MS(SEND_PERIOD_S * 1000)); } vTaskDelete(NULL); } //-----------------------------------------------------------------------------+ // Init task section. | //-----------------------------------------------------------------------------+ /** * This semaphore is taken during sntp sync and released after it finished. */ static SemaphoreHandle_t init_task_sem; /** * Set time and free init task semaphore. * @param error unused * @param arg unused */ void init_sntp_callback(int8_t error, void* arg) { time_t ts = time(NULL); debug("TIME: %s", ctime(&ts)); xSemaphoreGive(init_task_sem); } /** * Connection parameters. */ static struct sdk_station_config STATION_CONFIG = { .ssid = WIFI_SSID, .password = WIFI_PASS, }; void init_task(void* arg) { debug("INIT: setting pins...\n"); gpio_set_pullup(AM2302_PIN, false, false); debug("INIT: Set station parameters...\n"); sdk_wifi_station_set_auto_connect(false); sdk_wifi_station_set_config(&STATION_CONFIG); debug("Station parameters has been set.\n"); debug("INIT: Connecting to AP...\n"); sdk_wifi_station_connect(); while (sdk_wifi_station_get_connect_status() != STATION_GOT_IP) { vTaskDelay(MS(1000)); } debug("INIT: Connection to AP has been estabilished...\n"); debug("INIT: Start SNTP synchronization...\n"); init_task_sem = xSemaphoreCreateMutex(); if (!init_task_sem) { debug("INIT: Cannot create init task semaphore!!!"); return; } xSemaphoreTake(init_task_sem, 0); sntp_init(); sntp_sync(NTP_SERVER, init_sntp_callback, arg); BaseType_t result = pdFALSE; while (true) { debug("INIT: Trying to take init task semaphore...\n"); result = xSemaphoreTake(init_task_sem, MS(5 * 1000)); if (result == pdTRUE) { debug("INIT: Init task semaphore is taken...\n"); break; } } measurements_queue = xQueueCreate(MAX_MEASUREMENTS_COUNT, sizeof (struct measurement_results)); if (!measurements_queue) { debug("INIT: ERROR!!! Cannot create queue for measurements!\n"); goto fail; } result = xTaskCreate(measurement_task, "measurement_task", STACK_SIZE, NULL, MEASUREMENT_TASK_PRIORITY, NULL); if (result == pdFAIL) { debug("INIT: Measurement task creation failed!!!\n"); goto fail; } debug("INIT: Measurement task created...\n"); result = xTaskCreate(sending_data_task, "send_data_task", STACK_SIZE, NULL, SENDING_DATA_TASK_PRIORITY, NULL); if (result == pdFAIL) { debug("INIT: Send task creation failed!!!\n"); goto fail; } debug("INIT: Send data task created...\n"); fail: vSemaphoreDelete(init_task_sem); vTaskDelete(NULL); } //-----------------------------------------------------------------------------+ // Application entry point. | //-----------------------------------------------------------------------------+ void user_init(void) { debug("USER_INIT: SDK version: %s\n", sdk_system_get_sdk_version()); debug("USER_INIT: sizeof (int): %d\n", sizeof (int)); debug("USER_INIT: sizeof (float): %d\n", sizeof (float)); debug("USER_INIT: sizeof (time_t): %d\n", sizeof (time_t)); uart_set_baud(0, UART0_BAUD); BaseType_t result = xTaskCreate(init_task, (const char * const) "init_task", STACK_SIZE, NULL, INIT_TASK_PRIORITY, NULL); if (!result) { debug("USER_INIT: Cannot create init task!!!"); return; } }
sntp.h #ifndef SNTP_H #define SNTP_H #include <time.h> #include <stdint.h> #ifdef __cplusplus extern "C" { #endif #define SNTP_ERR_OK 0 #define SNTP_ERR_CONTEXT -1 #define SNTP_ERR_DNS -2 #define SNTP_ERR_UDP_PCB_ALLOC -3 #define SNTP_ERR_PBUF_ALLOC -4 #define SNTP_ERR_SEND -5 #define SNTP_ERR_RECV_ADDR_PORT -6; #define SNTP_ERR_RECV_SIZE -7 #define SNTP_ERR_RECV_MODE -8 #define SNTP_ERR_RECV_STRATUM -9 typedef void (*sntp_sync_callback)(int8_t error, void *arg); void sntp_init(); void sntp_sync(char *server, sntp_sync_callback callback, void *callback_arg); time_t sntp_get_rtc_time(int32_t *us); void sntp_update_rtc(time_t t, uint32_t us); #ifdef __cplusplus } #endif #endif /* SNTP_H */
sntp.c #include "main.h" #include "sntp.h" #include <time.h> #include <string.h> #include <lwip/ip_addr.h> #include <lwip/err.h> #include <lwip/dns.h> #include <lwip/udp.h> #include <esp/rtc_regs.h> #include <espressif/esp_common.h> #define TIMER_COUNT RTC.COUNTER /** * Daylight settings. * Base calculated with value obtained from NTP server (64 bits). */ #define SNTP_BASE (*((uint64_t*) RTC.SCRATCH)) /** * Timer value when base was obtained. */ #define SNTP_TIME_REF (RTC.SCRATCH[2]) /** * Calibration value. */ #define SNTP_CALIBRATION (RTC.SCRATCH[3]) /** * SNTP modes. */ #define SNTP_MODE_CLIENT 0x03 #define SNTP_MODE_SERVER 0x04 #define SNTP_MODE_BROADCAST 0x05 /** * Kiss-of-death code. */ #define SNTP_STRATUM_KOD 0x00 #define SNTP_OFFSET_LI_VN_MODE 0 #define SNTP_OFFSET_STRATUM 1 #define SNTP_OFFSET_RECEIVE_TIME 32 #define DIFF_SEC_1900_1970 (2208988800UL) struct sntp_message { uint8_t li_vn_mode; uint8_t stratum; uint8_t poll; uint8_t precision; uint32_t root_delay; uint32_t root_dispersion; uint32_t reference_identifier; uint32_t reference_timestamp[2]; uint32_t originate_timestamp[2]; uint32_t receive_timestamp[2]; uint32_t transmit_timestamp[2]; } __attribute__ ((packed)); struct sntp_sync_context { ip_addr_t ip_address; sntp_sync_callback callback; void* callback_arg; }; void sntp_init() { SNTP_BASE = 0; SNTP_CALIBRATION = 1; SNTP_TIME_REF = TIMER_COUNT; } void on_dns_found(const char* name, ip_addr_t* ipaddr, void* arg); void on_udp_recv(void* arg, struct udp_pcb* pcb, struct pbuf* p, ip_addr_t* addr, u16_t port); void sntp_sync(char* server, sntp_sync_callback callback, void* callback_arg) { int result = ERR_OK; debug("SNTP: Start SNTP synchronization, allocating memory for context...\n"); struct sntp_sync_context* context = malloc(sizeof (struct sntp_sync_context)); if (!context) { debug("SNTP: Error!!! Cannot allocate memory for context!\n"); result = SNTP_ERR_CONTEXT; goto fail; } context->callback = callback; context->callback_arg = callback_arg; debug("SNTP: Context successfully allocated...\n"); debug("SNTP: Start DNS lookup...\n"); err_t err = dns_gethostbyname(server, &(context->ip_address), on_dns_found, context); if (!(err == ERR_OK || err == ERR_INPROGRESS)) { debug("SNTP: Error!!! DNS lookup error!\n"); result = SNTP_ERR_DNS; goto fail; } return; fail: if (context) { free(context); } if (callback) { callback(result, callback_arg); } } // //============================================================================================================================================================== // void on_dns_found(const char* name, ip_addr_t* ipaddr, void* arg) { debug("SNTP: Start DNS lookup successfully finished...\n"); int result = ERR_OK; struct sntp_sync_context* context = arg; sntp_sync_callback callback = context->callback; void* callback_arg = context->callback_arg; debug("SNTP: Creating upd_pcb...\n"); struct udp_pcb* sntp_pcb = udp_new(); if (!sntp_pcb) { debug("SNTP: Error!!! Cannot allocate udp_pcb!\n"); result = SNTP_ERR_UDP_PCB_ALLOC; goto fail; } debug("SNTP: Successfully created upd_pcb...\n"); debug("SNTP: Allocating pbuf...\n"); struct pbuf* p = pbuf_alloc(PBUF_TRANSPORT, sizeof (struct sntp_message), PBUF_RAM); if (!p) { debug("SNTP: Error!!! DNS lookup error!\n"); result = SNTP_ERR_PBUF_ALLOC; goto fail; } struct sntp_message* message = p->payload; memset(message, 0, sizeof (struct sntp_message)); message->li_vn_mode = 0b00100011; // li = 00, vn = 4, mode = 3 debug("SNTP: Pbuf allocated successfully...\n"); debug("SNTP: Sending data to server...\n"); udp_recv(sntp_pcb, on_udp_recv, context); err_t err = udp_sendto(sntp_pcb, p, ipaddr, 123); pbuf_free(p); if (err != ERR_OK) { debug("SNTP: Error!!! data sending error!\n"); result = SNTP_ERR_SEND; goto fail; } debug("SNTP: Data sent...\n"); return; fail: if (context) { free(context); } if (sntp_pcb) { udp_remove(sntp_pcb); } if (callback) { callback(result, callback_arg); } } void on_udp_recv(void* arg, struct udp_pcb* pcb, struct pbuf* p, ip_addr_t* addr, u16_t port) { debug("SNTP: Response has successfully received...\n"); int result = ERR_OK; struct sntp_sync_context* context = arg; sntp_sync_callback callback = context->callback; void* callback_arg = context->callback_arg; debug("SNTP: Checking response size...\n"); if (p->tot_len < sizeof (struct sntp_message)) { debug("SNTP: Error!!! Invalid response size!\n"); result = SNTP_ERR_RECV_SIZE; goto fail; } debug("SNTP: Response size is OK...\n"); debug("SNTP: Checking mode...\n"); u8_t mode = 0x0; pbuf_copy_partial(p, &mode, sizeof (mode), SNTP_OFFSET_LI_VN_MODE); mode &= 0b00000111; if (mode != SNTP_MODE_SERVER && mode != SNTP_MODE_BROADCAST) { debug("SNTP: Error!!! Invalid mode!\n"); result = SNTP_ERR_RECV_MODE; goto fail; } debug("SNTP: Mode is OK...\n"); debug("SNTP: Checking stratum...\n"); u8_t stratum = 0x0; pbuf_copy_partial(p, &stratum, sizeof (stratum), SNTP_OFFSET_STRATUM); if (stratum == SNTP_STRATUM_KOD) { debug("SNTP: Error!!! Kiss of death!\n"); result = SNTP_ERR_RECV_STRATUM; goto fail; } debug("SNTP: Stratum is OK...\n"); debug("SNTP: Updating system timer...\n"); uint32_t receive_time[2]; pbuf_copy_partial(p, &receive_time, 2 * sizeof (uint32_t), SNTP_OFFSET_RECEIVE_TIME); time_t t = ntohl(receive_time[0]) - DIFF_SEC_1900_1970; uint32_t us = ntohl(receive_time[1]) / 4295; sntp_update_rtc(t, us); debug("SNTP: System timer updated...\n"); fail: if (context) { free(context); } if (pcb) { udp_remove(pcb); } if (callback) { callback(result, callback_arg); } } /** * Check if a timer wrap has occurred. Compensate sntp_base reference * if affirmative. * TODO: think about multitasking and race conditions. */ inline void sntp_check_timer_wrap(uint32_t current_value) { if (current_value < SNTP_TIME_REF) { // Timer wrap has occurred, compensate by subtracting 2^32 to ref. SNTP_BASE -= 1LLU << 32; } } /** * Return secs. If us is not a null pointer, fill it with usecs */ time_t sntp_get_rtc_time(int32_t *us) { time_t secs; uint32_t tim; uint64_t base; tim = TIMER_COUNT; // Check for timer wrap. sntp_check_timer_wrap(tim); base = SNTP_BASE + tim - SNTP_TIME_REF; secs = base * SNTP_CALIBRATION / (1000000U << 12); if (us) { *us = base * SNTP_CALIBRATION % (1000000U << 12); } return secs; } /** * Update RTC timer. Called by SNTP module each time it receives an update. */ void sntp_update_rtc(time_t t, uint32_t us) { // Apply daylight and timezone correction // DEBUG: Compute and print drift int64_t sntp_current = SNTP_BASE + TIMER_COUNT - SNTP_TIME_REF; int64_t sntp_correct = (((uint64_t) us + (uint64_t) t * 1000000U) << 12) / SNTP_CALIBRATION; debug("RTC Adjust: drift = %ld ticks, cal = %d\n", (time_t) (sntp_correct - sntp_current), SNTP_CALIBRATION); SNTP_TIME_REF = TIMER_COUNT; SNTP_CALIBRATION = sdk_system_rtc_clock_cali_proc(); SNTP_BASE = (((uint64_t) us + (uint64_t) t * 1000000U) << 12) / SNTP_CALIBRATION; } /** * Syscall implementation. doesn't seem to use tzp. */ int _gettimeofday_r(struct _reent* r, struct timeval* tp, void* tzp) { // Syscall defined by xtensa newlib defines tzp as void* // So it looks like it is not used. Also check tp is not NULL if (tzp || !tp) { return EINVAL; } tp->tv_sec = sntp_get_rtc_time((int32_t*) & tp->tv_usec); return 0; }
Digressão lírica sobre a disponibilidade do seu próprio código de sincronização de horário via SNTP: nas extensões do SDK já existe esse módulo, mas por alguma razão eu não gostei (há muito tempo, não me lembro por quê), copiei esse código de maneira imprudente e o modifiquei por mim mesmo.
Tudo funciona de maneira simples: quando o controlador é iniciado, a tarefa de inicialização é iniciada, que se conecta ao ponto de acesso, sincroniza o tempo via SNTP, inicia a tarefa de medir temperatura com umidade e enviar dados para o servidor, após o que se mata. A tarefa de medição pesquisa o sensor uma vez a cada 59 segundos e coloca os resultados em uma fila, a tarefa de envio é iniciada a cada 2 minutos, lê os dados da fila e os envia ao servidor MQTT.
Teoricamente, você pode escrever em C ++.
Etapa 5 - conclusão, onde sem eleDe uma maneira tão simples, usando a linguagem C e as mãos com um pequeno raio de curvatura, você pode programar o controlador ESP8266. A principal vantagem dessa abordagem em relação às soluções de script (por exemplo, LUA ou MicroPython) é o controle total sobre a composição e os recursos do firmware e a capacidade de aumentar a funcionalidade com recursos limitados do controlador. Há também uma opção para usar o RTOS SDK ou NONOS SDK da Espressif, mas não cresci junto com o primeiro e não tentei usar o segundo. Se alguém estiver interessado, assim como quando eu descobrir, posso escrever o seguinte tutorial sobre OTA (atualização de firmware por via aérea).
Alguns resultados deste código:
Dados recebidos do servidor MQTT e carregados no banco de dados Exaustão do controlador de depuração no UART SDK version: 0.9.9 --- USER_INIT: sizeof (int): 4 --- USER_INIT: sizeof (float): 4 --- USER_INIT: sizeof (time_t): 4 mode : sta(18:fe:34:d2:c5:a7) add if0 --- INIT: setting pins... --- INIT: Set station parameters... --- Station parameters has been set. --- INIT: Connecting to AP... scandone add 0 aid 2 cnt connected with kosmonaFFFt, channel 1 dhcp client start... ip:192.168.1.21,mask:255.255.255.0,gw:192.168.1.1 --- INIT: Connection to AP has been estabilished... --- INIT: Start SNTP synchronization... --- SNTP: Start SNTP synchronization, allocating memory for context... --- SNTP: Context successfully allocated... --- SNTP: Start DNS lookup... --- INIT: Trying to take init task semaphore... --- SNTP: Start DNS lookup successfully finished... --- SNTP: Creating upd_pcb... --- SNTP: Successfully created upd_pcb... --- SNTP: Allocating pbuf... --- SNTP: Pbuf allocated successfully... --- SNTP: Sending data to server... --- SNTP: Data sent... --- SNTP: Response has successfully received... --- SNTP: Checking response size... --- SNTP: Response size is OK... --- SNTP: Checking mode... --- SNTP: Mode is OK... --- SNTP: Checking stratum... --- SNTP: Stratum is OK... --- SNTP: Updating system timer... --- RTC Adjust: drift = 1220897578 ticks, cal = 1 --- SNTP: System timer updated... --- TIME: Thu Sep 21 19:20:36 2017 --- INIT: Init task semaphore is taken... --- MEASUREMENTS: Start measurements... --- MEASUREMENTS: Measurements finished... --- INIT: Measurement task created... --- MQTT: ConnectNetwork... --- INIT: Send data task created... --- MQTT: ConnectNetwork success... --- MQTT: MQTTConnect success... --- MQTT: Got message to publish... --- timestamp: 1506021636 --- am2302_humidity: 55.8 --- am2302_temperature: 23.4 --- MQTT: Successfully publish message... --- MEASUREMENTS: Start measurements... --- MEASUREMENTS: Measurements finished... --- MEASUREMENTS: Start measurements... --- MEASUREMENTS: Measurements finished... --- MQTT: ConnectNetwork... --- MQTT: ConnectNetwork success... --- MQTT: MQTTConnect success... --- MQTT: Got message to publish... --- timestamp: 1506021694 --- am2302_humidity: 55.2 --- am2302_temperature: 23.8 --- MQTT: Successfully publish message... --- MQTT: Got message to publish... --- timestamp: 1506021751 --- am2302_humidity: 56.5 --- am2302_temperature: 24.4 --- MQTT: Successfully publish message... --- MEASUREMENTS: Start measurements... --- MEASUREMENTS: Measurements finished... --- MEASUREMENTS: Start measurements... --- MEASUREMENTS: Measurements finished... --- MQTT: ConnectNetwork... --- MQTT: ConnectNetwork success... --- MQTT: MQTTConnect success... --- MQTT: Got message to publish... --- timestamp: 1506021807 --- am2302_humidity: 53.0 --- am2302_temperature: 24.7 --- MQTT: Successfully publish message... --- MQTT: Got message to publish... --- timestamp: 1506021863 --- am2302_humidity: 52.3 --- am2302_temperature: 24.8 --- MQTT: Successfully publish message... --- MEASUREMENTS: Start measurements... --- MEASUREMENTS: Measurements finished... --- MEASUREMENTS: Start measurements... --- MEASUREMENTS: Measurements finished... --- MQTT: ConnectNetwork... --- MQTT: ConnectNetwork success... --- MQTT: MQTTConnect success... --- MQTT: Got message to publish... --- timestamp: 1506021919 --- am2302_humidity: 52.0 --- am2302_temperature: 24.9 --- MQTT: Successfully publish message... --- MQTT: Got message to publish... --- timestamp: 1506021975 --- am2302_humidity: 53.3 --- am2302_temperature: 25.2 --- MQTT: Successfully publish message...
PS Eu recomendo usar minicom (console) ou cutecom (GUI) para trabalhar com o UART no PC.
Links úteis: