摘要:本文介绍如何在ubuntu下的idf编写模拟-数字转换(ADC)程序,然后把数据传输到阿里云上。
硬件连接使用的是ESP32的ADC引脚,
下图是示意图
我们要用到的是33引脚,对应的是ADC1的第5通道ADC1_CH5
编程也相对简单,不会编写的话有例程可以借鉴。其中核心功能是:
#define EXAMPLE_ADC1_CHAN1 ADC_CHANNEL_5
然后初始化
//-------------ADC1 Init---------------//
adc_oneshot_unit_handle_t adc1_handle;
adc_oneshot_unit_init_cfg_t init_config1 = {
.unit_id = ADC_UNIT_1,
};
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle));
//-------------ADC1 Config---------------//
adc_oneshot_chan_cfg_t config = {
.bitwidth = ADC_BITWIDTH_DEFAULT,
.atten = EXAMPLE_ADC_ATTEN,
};
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN0, &config));
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config));
//-------------ADC1 Calibration Init---------------//
adc_cali_handle_t adc1_cali_chan0_handle = NULL;
adc_cali_handle_t adc1_cali_chan1_handle = NULL;
bool do_calibration1_chan0 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC1_CHAN0, EXAMPLE_ADC_ATTEN, &adc1_cali_chan0_handle);
bool do_calibration1_chan1 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC1_CHAN1, EXAMPLE_ADC_ATTEN, &adc1_cali_chan1_handle);
在while主循环中,循环采集电压然后LOG出来。
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0]));
ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw[0][0]);
if (do_calibration1_chan0) {
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, adc_raw[0][0], &voltage[0][0]));
ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage[0][0]);
}
最后是通过mqtt指令,将数据上报到阿里云。由于要发送的是json字符串,那么将下面这个字符串中的指定数据替换成最新的数据,需要一个json解析算法。
char mqtt_publish_data2[] = "{\"method\":\"thing.event.property.post\",\"params\":{\"OF\":1,\"waterml\":1036}}";
// 解析JSON字符串
cJSON *root = cJSON_Parse(mqtt_publish_data2);
if (root == NULL) {
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL) {
fprintf(stderr, "Error before: %s\n", error_ptr);
}
//return 1;
}
// 查找"waterml"字段
cJSON *waterml = cJSON_GetObjectItemCaseSensitive(cJSON_GetObjectItemCaseSensitive(root, "params"), "waterml");
if (waterml == NULL) {
fprintf(stderr, "Failed to find 'waterml' field.\n");
cJSON_Delete(root);
//return 1;
}
// 假设newData是三位数
int newData = voltage[0][0];
// 替换"waterml"字段的值
cJSON_SetNumberValue(waterml, newData); // 注意:这里我们直接设置数字值,而不是字符串
cJSON *OF = cJSON_GetObjectItemCaseSensitive(cJSON_GetObjectItemCaseSensitive(root, "params"), "OF");
if (OF == NULL) {
fprintf(stderr, "Failed to find 'waterml' field.\n");
cJSON_Delete(root);
//return 1;
}
cJSON_SetNumberValue(OF, ofValue); // 注意:这里我们直接设置数字值,而不是字符串
// 如果你需要设置为字符串,则使用cJSON_SetString()
// 生成修改后的JSON字符串
char *output = cJSON_Print(root);
if (output == NULL) {
fprintf(stderr, "Failed to print JSON\n");
cJSON_Delete(root);
// return 1;
}
ESP_LOGI(TAG, "mqtt_publish_data2 is %s", output);
//花生,要发布哪个消息呢?data1是OF置1,data2是OF置0,data3是发布一个字符串。
esp_mqtt_client_publish(client, AliyunPublishTopic_user_update, output, strlen(output), 1, 0);
vTaskDelay(2000 / portTICK_PERIOD_MS);
最终成功运行,定时上报消息。日志如下:
lulu@lulu-HP-Notebook:~/esp/app-MqttToAliyun$ idf.py monitor
Executing action: monitor
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
Running idf_monitor in directory /home/lulu/esp/app-MqttToAliyun
Executing "/home/lulu/.espressif/python_env/idf5.4_py3.8_env/bin/python /home/lulu/esp/esp-idf/tools/idf_monitor.py -p /dev/ttyUSB0 -b 115200 --toolchain-prefix xtensa-esp32-elf- --target esp32 --revision 0 /home/lulu/esp/app-MqttToAliyun/build/app-MqttToAliyun.elf -m '/home/lulu/.espressif/python_env/idf5.4_py3.8_env/bin/python' '/home/lulu/esp/esp-idf/tools/idf.py'"...
--- esp-idf-monitor 1.4.0 on /dev/ttyUSB0 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jul 29 2019 12:21:46rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7176
load:0x40078000,len:15564
ho 0 tail 12 room 4
load:0x40080400,len:4
0x40080400: _init at ??:?load:0x40080404,len:3904
entry 0x40080640
I (31) boot: ESP-IDF v5.4-dev-12-g3d813afa01 2nd stage bootloader
I (31) boot: compile time Apr 25 2024 07:37:54
I (33) boot: Multicore bootloader
I (37) boot: chip revision: v3.0
I (41) boot.esp32: SPI Speed : 40MHz
I (45) boot.esp32: SPI Mode : DIO
I (50) boot.esp32: SPI Flash Size : 2MB
I (54) boot: Enabling RNG early entropy source...
I (60) boot: Partition Table:
I (63) boot: ## Label Usage Type ST Offset Length
I (71) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (86) boot: 2 factory factory app 00 00 00010000 00100000
I (93) boot: End of partition table
I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=285d8h (165336) map
I (162) esp_image: segment 1: paddr=00038600 vaddr=3ff80000 size=00004h ( 4) load
I (163) esp_image: segment 2: paddr=0003860c vaddr=3ffb0000 size=03df4h ( 15860) load
I (174) esp_image: segment 3: paddr=0003c408 vaddr=40080000 size=03c10h ( 15376) load
I (183) esp_image: segment 4: paddr=00040020 vaddr=400d0020 size=a44b0h (672944) map
I (416) esp_image: segment 5: paddr=000e44d8 vaddr=40083c10 size=12bf8h ( 76792) load
I (457) boot: Loaded app from partition at offset 0x10000
I (457) boot: Disabling RNG early entropy source...
I (469) cpu_start: Multicore app
I (478) cpu_start: Pro cpu start user code
I (478) cpu_start: cpu freq: 160000000 Hz
I (478) app_init: Application information:
I (481) app_init: Project name: app-MqttToAliyun
I (486) app_init: App version: 1
I (491) app_init: Compile time: Apr 25 2024 07:46:58
I (497) app_init: ELF file SHA256: d0411feec...
I (502) app_init: ESP-IDF: v5.4-dev-12-g3d813afa01
I (508) efuse_init: Min chip rev: v0.0
I (513) efuse_init: Max chip rev: v3.99
I (518) efuse_init: Chip rev: v3.0
I (523) heap_init: Initializing. RAM available for dynamic allocation:
I (530) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (536) heap_init: At 3FFB86F8 len 00027908 (158 KiB): DRAM
I (542) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (549) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (555) heap_init: At 40096808 len 000097F8 (37 KiB): IRAM
I (563) spi_flash: detected chip: generic
I (566) spi_flash: flash io: dio
W (570) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (585) main_task: Started on CPU0
I (595) main_task: Calling app_main()
I (615) wifi station: ESP_WIFI_MODE_STA
I (625) wifi:wifi driver task: 3ffc06b8, prio:23, stack:6656, core=0
I (635) wifi:wifi firmware version: 34d9141e9
I (635) wifi:wifi certification version: v7.0
I (635) wifi:config NVS flash: enabled
I (635) wifi:config nano formating: disabled
I (635) wifi:Init data frame dynamic rx buffer num: 32
I (645) wifi:Init static rx mgmt buffer num: 5
I (645) wifi:Init management short buffer num: 32
I (655) wifi:Init dynamic tx buffer num: 32
I (655) wifi:Init static rx buffer size: 1600
I (655) wifi:Init static rx buffer num: 10
I (665) wifi:Init dynamic rx buffer num: 32
I (665) wifi_init: rx ba win: 6
I (675) wifi_init: accept mbox: 6
I (675) wifi_init: tcpip mbox: 32
I (675) wifi_init: udp mbox: 6
I (685) wifi_init: tcp mbox: 6
I (685) wifi_init: tcp tx win: 5760
I (695) wifi_init: tcp rx win: 5760
I (695) wifi_init: tcp mss: 1440
I (695) wifi_init: WiFi IRAM OP enabled
I (705) wifi_init: WiFi RX IRAM OP enabled
I (715) phy_init: phy_version 4791,2c4672b,Dec 20 2023,16:06:06
I (795) wifi:mode : sta (c0:49:ef:f1:8a:00)
I (795) wifi:enable tsf
I (805) wifi station: wifi_init_sta finished.
I (825) wifi:new:<1,1>, old:<1,0>, ap:<255,255>, sta:<1,1>, prof:1, snd_ch_cfg:0x0
I (825) wifi:state: init -> auth (0xb0)
I (825) wifi:state: auth -> assoc (0x0)
I (835) wifi:state: assoc -> run (0x10)
I (1035) wifi:[ADDBA]RX DELBA, reason:39, delete tid:0, initiator:1(originator)
I (1035) wifi:[ADDBA]RX DELBA, reason:39, delete tid:0, initiator:0(recipient)
I (1035) wifi:[ADDBA]RX DELBA, reason:39, delete tid:1, initiator:1(originator)
I (1055) wifi:connected with Z4309, aid = 3, channel 1, 40U, bssid = 6c:b1:58:2a:35:1e
I (1055) wifi:security: WPA2-PSK, phy: bgn, rssi: -49
I (1055) wifi:pm start, type: 1I (1065) wifi:dp: 1, bi: 102400, li: 3, scale listen interval from 307200 us to 307200 us
I (1095) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (1105) wifi:<ba-add>idx:0 (ifx:0, 6c:b1:58:2a:35:1e), tid:0, ssn:673, winSize:64
I (2075) esp_netif_handlers: sta ip: 192.168.1.102, mask: 255.255.255.0, gw: 192.168.1.1
I (2075) wifi station: got ip:192.168.1.102
I (2075) wifi station: connected to ap SSID:Z4309 password:62262466
I (2085) MQTT_EXAMPLE: Other event id:7
I (2095) MQTT_EXAMPLE: calibration scheme version is Line Fitting
I (2095) MQTT_EXAMPLE: Calibration Success
I (2095) MQTT_EXAMPLE: calibration scheme version is Line Fitting
I (2105) MQTT_EXAMPLE: Calibration Success
I (2105) main_task: Returned from app_main()
I (2115) MQTT_EXAMPLE: calibration scheme version is Line Fitting
I (2125) MQTT_EXAMPLE: Calibration Success
I (2125) MQTT_EXAMPLE: ADC1 Channel[4] Raw Data: 1630
I (2135) MQTT_EXAMPLE: ADC1 Channel[4] Cali Voltage: 1489 mV
I (2145) wifi:<ba-add>idx:1 (ifx:0, 6c:b1:58:2a:35:1e), tid:1, ssn:14, winSize:64
I (2195) MQTT_EXAMPLE: MQTT_EVENT_CONNECTED
I (2205) MQTT_EXAMPLE: sent publish successful, msg_id=60130
I (2205) MQTT_EXAMPLE: sent subscribe successful, msg_id=32048
I (2245) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=60130
I (2285) MQTT_EXAMPLE: MQTT_EVENT_SUBSCRIBED, msg_id=32048
I (2295) MQTT_EXAMPLE: sent publish successful, msg_id=0
I (3135) MQTT_EXAMPLE: voltage[0][0] is 1489
I (3135) MQTT_EXAMPLE: mqtt_publish_data2 is {
"method": "thing.event.property.post",
"params": {
"OF": 0,
"waterml": 1489
}
}
I (3175) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=63520
I (5145) MQTT_EXAMPLE: ADC1 Channel[4] Raw Data: 1631
I (5145) MQTT_EXAMPLE: ADC1 Channel[4] Cali Voltage: 1489 mV
I (6145) MQTT_EXAMPLE: voltage[0][0] is 1489
I (6145) MQTT_EXAMPLE: mqtt_publish_data2 is {
"method": "thing.event.property.post",
"params": {
"OF": 0,
"waterml": 1489
}
}
I (6185) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=55202
I (8155) MQTT_EXAMPLE: ADC1 Channel[4] Raw Data: 1626
I (8155) MQTT_EXAMPLE: ADC1 Channel[4] Cali Voltage: 1485 mV
I (9155) MQTT_EXAMPLE: voltage[0][0] is 1485
I (9155) MQTT_EXAMPLE: mqtt_publish_data2 is {
"method": "thing.event.property.post",
"params": {
"OF": 0,
"waterml": 1485
}
}
I (9195) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=2336
I (11165) MQTT_EXAMPLE: ADC1 Channel[4] Raw Data: 4095
I (11165) MQTT_EXAMPLE: ADC1 Channel[4] Cali Voltage: 3155 mV
I (12165) MQTT_EXAMPLE: voltage[0][0] is 3155
I (12165) MQTT_EXAMPLE: mqtt_publish_data2 is {
"method": "thing.event.property.post",
"params": {
"OF": 1,
"waterml": 3155
}
}
I (12215) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=9345
I (14175) MQTT_EXAMPLE: ADC1 Channel[4] Raw Data: 4095
I (14175) MQTT_EXAMPLE: ADC1 Channel[4] Cali Voltage: 3155 mV
I (15175) MQTT_EXAMPLE: voltage[0][0] is 3155
I (15175) MQTT_EXAMPLE: mqtt_publish_data2 is {
"method": "thing.event.property.post",
"params": {
"OF": 1,
"waterml": 3155
}
}