关于在FreeRTOS下用C编程ESP8266的一些知识

应该有一个CAP,但是没有足够的预算。

Tarson对我对通过ESP8266通过WIFI与ARDUINO进行编程和数据交换的评论的回应的激励,我决定写有关FreeRTOS下用C编程ESP8266的基础知识。 细节剪下。

步骤0-装置

首先,您需要获得带有ESP8266的设备,希望在那里将USB到UART分开,这样您就不必关闭编程器。 我在NodeMCU上进行了非人为的实验。

因此,步骤1-收集工具链

首先,您需要安装一台装有Linux发行版的计算机(我有OpenSUSE Leap)。 我们转到tyts链接处的github,阅读汇编说明,安装必要的依赖项,克隆存储库并收集。 我在/ opt / ESP中克隆了,然后组装了Makefile规则,并设置了变量:

STANDALONE = n VENDOR_SDK = 2.1.0 

接下来,您可以在〜/ .bashrc中的PATH中添加到工具链二进制文件的路径:

 export PATH=/opt/ESP/esp-open-sdk/xtensa-lx106-elf/bin:$PATH 

第2步-获取SDK

我们转到github( tynk ),阅读说明,进行克隆(例如,在/ opt / ESP中)。 接下来,我们以自己喜欢的方式(例如,通过〜/ .bashrc)设置环境变量ESP8266_SDK_PATH:

 export ESP8266_SDK_PATH=/opt/ESP/esp-open-rtos 

第3步-创建一个项目

我们转到带有SDK的目录中的examples目录,然后复制您喜欢的任何示例。 我们在最喜欢的开发环境中导入/打开项目,受虐狂可以使用文本编辑器。 我更喜欢NetBeans-它对C / C ++项目(包括基于Makefile的项目)具有良好的支持。 该项目使用make进行组装,使用make flash进行刷新。 在local.mk文件中,您可以配置用于刷新设备的参数(例如,访问闪存的大小和模式)。

第4步-编程

我们会分析要求,主题领域,并按照GOST 34.602-89编制技术规范,然后您可以开始编写代码:)我不会闪烁LED,因为我没有它们,因此作为HelloWorld,我将从AM2302传感器读取数据( DHT22),然后通过MQTT协议将其发送到服务器。

为了使用其他模块,例如MQTT或DHT,必须将它们添加到Makefile中:

 PROGRAM=fffmeteo EXTRA_COMPONENTS = extras/paho_mqtt_c extras/dht include $(ESP8266_SDK_PATH)/common.mk 

主文件
 #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
 #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; } 


关于通过SNTP来获取您自己的时间同步代码的说法有些离题:在SDK的扩展中已经有这样的模块,但是由于某种原因我不喜欢它(很久以前,我不记得为什么),所以我无礼地复制了此代码并为自己修改了它。

一切都很简单:控制器启动后,初始化任务即启动,该任务连接到接入点,通过SNTP同步时间,启动湿度测量温度并将数据发送到服务器的任务,此后该任务会自行终止。 测量任务每59秒轮询一次传感器并将结果放入队列中,发送任务每2分钟启动一次,从队列中读取数据并将其发送到MQTT服务器。

从理论上讲,您可以用C ++编写。

步骤5-结论,没有他的地方

以这种简单的方法,使用C语言和曲率半径小的手,即可对ESP8266控制器进行编程。 与脚本解决方案(例如,LUA或MicroPython)相比,此方法的主要优点是可以完全控制固件的组成和资源,并且可以在有限的控制器资源中填充更多功能。 还有一个选项可以使用Espressif的RTOS SDK或NONOS SDK,但是我没有与第一个一起成长,也没有尝试使用第二个。 如果有人会感兴趣,以及我自己弄清楚时,我可以写以下有关OTA(空中固件更新)的教程。

这段代码的一些结果:

从MQTT服务器接收并上传到数据库的数据


在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我建议使用minicom(控制台)或cutecom(GUI)与PC上的UART一起使用。

有用的链接:

Source: https://habr.com/ru/post/zh-CN406813/


All Articles