完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
不久前,我研究了 ESP8266 的电池供电选项。发现了一些有趣的文章,并设法用一个每 5 分钟更新一次 Thingspeak 的温度传感器对 ESP8266 进行编程。它在 3.7V 锂离子 200mAh 电池上运行约 20 天。
我不会详细介绍,但涉及的“技巧”之一是将 deepsleep 置于 RF 禁用模式,这样当它从 deepsleep 返回时,RF 最初是不启用的。 ESP.deepSleep(睡眠时间,WAKE_RF_DISABLED); 此外,我使用静态 IP 和 rtcMemory 来存储 MAC 地址和 WIFI 通道,以调用快速 WIFI 连接。(这可以节省大量时间!) WiFi.config( ip,dns, gateway, subnet ); WiFi.begin( WLAN_SSID, WLAN_PASSWD, rtcData.channel, rtcData.ap_mac, true ); 我的设置每 5 分钟读取一次温度传感器(以及电池电压和 ESP 唤醒时间)并将其发送到 Thingspeak。每次测量仅“开启”约 1.3 秒。但是,还有更多收获。如果我在 rtcMemory 中存储 -say- 12 个测量值(方便 1 小时的数据)并且每小时只上传一次怎么办?每次测量的“开启”时间会急剧下降(我测得大约 250 毫秒),耗电的 RF 无线电每小时只能开启 1.3 秒。 所以我熬了一夜并编写了一个新的设置。为方便起见,使用 NodeMCU。它似乎有效。 然而,这就是问题所在,- 抱歉,介绍太长了 - 快速连接“技巧”不再起作用。它需要再次获取已知的信息,这大约需要 10 秒才能完成。 我尝试了几件事,在一些 RF 命令后延迟,尝试了 WIFI_off 和其他 goto sleep 命令,但到目前为止没有任何效果。 奇怪的是,当我每次测量打开 WIFI 时,它都会快速连接。一旦我在不打开 WIFI 的情况下循环通过代码,它就不会再快速连接了。 所以我回到了一个简单的设置。这个“错误”再次出现!因此,当每次从深度睡眠中恢复并启动 WIFI 时,都会建立快速连接。但是,当我从深度睡眠中醒来并循环一次或多次而不打开 WIFI 时,它会失去快速连接的能力。 也许有人可以阐明这个问题.... (代码可能有一些多余的行,我从我的主程序中复制了它们) 我把箭头放在哪里 <---------------- ------在代码中尝试先输入 0,然后输入 2。在打开 WIFI 之前,它会在深度睡眠中循环的次数。 代码:全选 //What happens if radio is switched on every xx times? // No reading of sensors, only radio on/off long SLEEPTIME=30e6; // 30secs #include #include "secrets.h" float tempSensor1, V_adjust=0.97, VBat; unsigned long myChannelNumber = SECRET_CH_ID; const char * myWriteAPIKey = SECRET_WRITE_APIKEY; char* WLAN_SSID = SECRET_SSID; // your network SSID (name) char* WLAN_PASSWD = SECRET_PASS; // your network password int httpCode=0; unsigned long previousTime = millis(); const unsigned long interval = 1000; int OTA_Timeout = 60; WiFiClient clientWiFi; // Temperature wire is plugged into port D5 on the ESP8266 (GPIO 14) // We make a structure to store connection information // The ESP8266 RTC memory is arranged into blocks of 4 bytes. The access methods read and write 4 bytes at a time, // so the RTC data structure should be padded to a 4-byte multiple. struct { uint32_t crc32; // 4 bytes uint8_t channel; // 1 byte, 5 in total uint8_t ap_mac[6];// 6 bytes, 11 in total uint8_t index_count; // 1 byte, 12 in total } rtcData; //We will use static ip IPAddress ip( 192, 168, 1, 12 );// pick your own suitable static IP address IPAddress gateway( 192, 168, 1, 254 ); // may be different for your network IPAddress subnet( 255, 255, 255, 0 ); // may be different for your network (but this one is pretty standard) IPAddress dns(192,168,1,254); void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); //That means LED off.. Serial.begin(115200); // we disable WiFi, coming from DeepSleep, as we do not need it right away WiFi.mode( WIFI_OFF ); //required? we start with rf disabled ??? WiFi.forceSleepBegin(); delay( 1 ); // Try to read WiFi settings from RTC memory bool rtcValid = false; if( ESP.rtcUserMemoryRead( 0, (uint32_t*)&rtcData, sizeof( rtcData ) ) ) { // Calculate the CRC of what we just read from RTC memory, but skip the first 4 bytes as that's the checksum itself. uint32_t crc = calculateCRC32( ((uint8_t*)&rtcData) + 4, sizeof( rtcData ) - 4 ); if( crc == rtcData.crc32 ) { rtcValid = true; } else { rtcData.index_count = 0; } } //----------------- // Now is the time to do stuff like reading sensors while the radio is still off // Start the sensors but to give it time the actual reading is done later //----------------- Serial.println(); Serial.println(); Serial.printf("millis: %i, msecs\n\r", millis()); //Read the voltage int vdd = analogRead(A0); Serial.printf("Vdd = %d -> %.2fV\n\r",vdd, vdd*5.02/1024*V_adjust); //Switch Radio back On Serial.printf("millis: %i, msecs\n\r", millis()); Serial.printf("index count: %i\n\r", rtcData.index_count); if (rtcData.index_count >= 2) { // set to 0 for every cycle, set to eg 4 for every 4 cycles. <---------------------- Serial.println(" Starting Radio"); WiFi.forceSleepWake(); delay(1); // Disable the WiFi persistence. The ESP8266 will not load and save WiFi settings unnecessarily in the flash memory. WiFi.persistent( false ); // Bring up the WiFi connection WiFi.mode( WIFI_STA ); WiFi.config( ip,dns, gateway, subnet ); //-----------Now we replace the normally used "WiFi.begin();" with a procedure using connection data stored by us if( rtcValid ) { // The RTC data was good, make a quick connection Serial.println("RTC OK, Quick connection!"); WiFi.begin( WLAN_SSID, WLAN_PASSWD, rtcData.channel, rtcData.ap_mac, true ); } else { // The RTC data was not valid, so make a regular connection Serial.println("RTC BAD, Regular connection!"); WiFi.begin( WLAN_SSID, WLAN_PASSWD ); } //------now wait for connection int retries = 0; int wifiStatus = WiFi.status(); while( wifiStatus != WL_CONNECTED ) { retries++; if( retries == 100 ) { Serial.println("Retries WIFI = 100"); // Quick connect is not working, reset WiFi and try regular connection WiFi.disconnect(); delay(10); WiFi.forceSleepBegin(); delay(10); WiFi.forceSleepWake(); delay(10); WiFi.begin( WLAN_SSID, WLAN_PASSWD ); } if( retries == 600 ) { Serial.println("Retries WIFI = 600"); // Giving up after 30 seconds and going back to sleep WiFi.disconnect( true ); delay(1); WiFi.mode( WIFI_OFF ); Serial.printf("millis: %i, msecs\n\r", millis()); ESP.deepSleep( SLEEPTIME, WAKE_RF_DISABLED ); } delay(50); wifiStatus = WiFi.status(); } //--------- Serial.println(" WiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // Write current connection info back to RTC rtcData.channel = WiFi.channel(); memcpy( rtcData.ap_mac, WiFi.BSSID(), 6 ); // Copy 6 bytes of BSSID (AP's MAC address) rtcData.index_count = 0; // reset count rtcData.crc32 = calculateCRC32( ((uint8_t*)&rtcData) + 4, sizeof( rtcData ) - 4 ); ESP.rtcUserMemoryWrite( 0, (uint32_t*)&rtcData, sizeof( rtcData ) ); //-------Now it's time to use your connection, e.g. by sending data // Do nothing just test deepsleep cycles.... WiFi.disconnect( true ); delay( 1 ); } rtcData.index_count++; rtcData.crc32 = calculateCRC32( ((uint8_t*)&rtcData) + 4, sizeof( rtcData ) - 4 ); ESP.rtcUserMemoryWrite( 0, (uint32_t*)&rtcData, sizeof( rtcData ) ); // WAKE_RF_DISABLED to keep the WiFi radio disabled when we wake up Serial.printf("millis: %i, msecs\n\r", millis()); Serial.println(" Going to Deepsleep zzzzz"); ESP.deepSleep( SLEEPTIME, WAKE_RF_DISABLED ); } void loop() { } // the CRC routine uint32_t calculateCRC32( const uint8_t *data, size_t length ) { uint32_t crc = 0xffffffff; while( length-- ) { uint8_t c = *data++; for( uint32_t i = 0x80; i > 0; i >>= 1 ) { bool bit = crc & 0x80000000; if( c & i ) { bit = !bit; } crc <<= 1; if( bit ) { crc ^= 0x04c11db7; } } } return crc; } |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
1142 浏览 1 评论
578浏览 6评论
479浏览 5评论
有没有办法在不使用混杂模式的情况下实现Wifi驱动程序接收缓冲区访问中断呢?
463浏览 5评论
464浏览 4评论
440浏览 4评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 02:34 , Processed in 0.827696 second(s), Total 43, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号