Last active
March 17, 2017 22:51
-
-
Save chaeplin/e78ecaa11ee05c62865c to your computer and use it in GitHub Desktop.
esp8266_rtc_mem_test.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
system_rtc_mem_write | |
Function: | |
During deep sleep, only RTC still working, so maybe we need to save some user data in RTC memory. | |
Only user data area can be used by user. | |
|<--------system data--------->|<-----------------user data--------------->| | |
| 256 bytes | 512 bytes | | |
Note: | |
RTC memory is 4 bytes aligned for read and write operations. Parameter des_addr means block number(4 bytes per block). | |
So, if we want to save some data at the beginning of user data area, des_addr will be 256/4 = 64, save_size will be data length. | |
Prototype: | |
bool system_rtc_mem_write ( | |
uint32 des_addr, | |
void * src_addr, | |
uint32 save_size | |
) | |
Parameter: | |
uint32 des_addr : destination address (block number) in RTC memory, des_addr >=64 | |
void * src_addr : data pointer. | |
uint32 save_size : data length ( byte) | |
Return: | |
true: succeed | |
false: fail | |
system_rtc_mem_read | |
Function: | |
Read user data from RTC memory. Only user data area should be accessed by the user. | |
|<--------system data--------->|<-----------------user data--------------->| | |
| 256 bytes | 512 bytes | | |
Note: | |
RTC memory is 4 bytes aligned for read and write operations. | |
Parameter src_addr means block number(4 bytes per block). | |
So, to read data from the beginning of user data area, src_addr will be 256/4=64, save_size will be data length. | |
Prototype: | |
bool system_rtc_mem_read ( | |
uint32 src_addr, | |
void * des_addr, | |
uint32 save_size | |
) | |
Parameter: | |
uint32 src_addr : source address (block number) in rtc memory, src_addr >= 64 | |
void * des_addr : data pointer | |
uint32 save_size : data length, byte | |
Return: | |
true: succeed | |
false: fail | |
*/ | |
#include <ESP8266WiFi.h> | |
#include <PubSubClient.h> | |
#include "/usr/local/src/ap_setting.h" | |
extern "C" { | |
#include "user_interface.h" | |
} | |
//-- | |
#define RTC_MAGIC 12345678 | |
typedef struct _tagPoint { | |
uint32 magic ; | |
uint32 salt; | |
uint32 nemo; | |
} RTC_TEST; | |
RTC_TEST rtc_mem_test; | |
#define IPSET_STATIC { 192, 168, 10, 7 } | |
#define IPSET_GATEWAY { 192, 168, 10, 1 } | |
#define IPSET_SUBNET { 255, 255, 255, 0 } | |
#define IPSET_DNS { 192, 168, 10, 10 } | |
IPAddress ip_static = IPSET_STATIC; | |
IPAddress ip_gateway = IPSET_GATEWAY; | |
IPAddress ip_subnet = IPSET_SUBNET; | |
IPAddress ip_dns = IPSET_DNS; | |
//--- | |
String macToStr(const uint8_t* mac); | |
void sendmqttMsg(char* topictosend, String payload); | |
//--- | |
const char* ssid = WIFI_SSID; | |
const char* password = WIFI_PASSWORD; | |
IPAddress mqtt_server = MQTT_SERVER; | |
char* topic = "pubtest"; | |
String clientName; | |
long lastReconnectAttempt = 0; | |
long lastMsg = 0; | |
int test_para = 1; | |
unsigned long startMills; | |
WiFiClient wifiClient; | |
PubSubClient client(mqtt_server, 1883, wifiClient); | |
void goingToSleepNoRF() | |
{ | |
// 3 sec | |
Serial.println("going to sleep with no rf"); | |
//system_deep_sleep_set_option(4); | |
//system_deep_sleep(10000000); | |
ESP.deepSleep(3000000, WAKE_RF_DISABLED); | |
} | |
void goingToSleepWithRF() | |
{ | |
// 3 sec | |
Serial.println("going to sleep with rf"); | |
//system_deep_sleep_set_option(0); | |
//system_deep_sleep(10000000); | |
ESP.deepSleep(1, WAKE_RF_DEFAULT); | |
} | |
void rtc_count() | |
{ | |
// system_rtc_mem_read(64... not work, use > 64 | |
system_rtc_mem_read(100, &rtc_mem_test, sizeof(rtc_mem_test)); | |
Serial.print("=================> rtc mem mgic / salt / nemo : "); | |
Serial.print(rtc_mem_test.magic); | |
Serial.print(" / "); | |
Serial.print(rtc_mem_test.salt); | |
Serial.print(" / "); | |
Serial.println(rtc_mem_test.nemo); | |
if (rtc_mem_test.magic != RTC_MAGIC) { | |
Serial.println("===============> rtc mem init..."); | |
rtc_mem_test.magic = RTC_MAGIC; | |
rtc_mem_test.salt = 0; | |
rtc_mem_test.nemo = 0; | |
} | |
rtc_mem_test.salt++; | |
rtc_mem_test.nemo++; | |
boolean reportnow = false; | |
if ( rtc_mem_test.nemo > 10 || rtc_mem_test.nemo == 1) { | |
reportnow = true; | |
rtc_mem_test.nemo = 1; | |
} | |
if (system_rtc_mem_write(100, &rtc_mem_test, sizeof(rtc_mem_test))) { | |
Serial.println("rtc mem write is ok"); | |
} else { | |
Serial.println("rtc mem write is fail"); | |
} | |
if (reportnow == false) { | |
if ( rtc_mem_test.nemo == 10 ) { | |
goingToSleepWithRF(); | |
} else { | |
goingToSleepNoRF(); | |
} | |
} | |
} | |
boolean reconnect() | |
{ | |
if (!client.connected()) { | |
if (client.connect((char*) clientName.c_str())) { | |
Serial.println("===> mqtt connected"); | |
} else { | |
Serial.print("---> mqtt failed, rc="); | |
Serial.println(client.state()); | |
} | |
} | |
return client.connected(); | |
} | |
void wifi_connect() | |
{ | |
if (WiFi.status() != WL_CONNECTED) { | |
// WIFI | |
Serial.println(); | |
Serial.print("===> WIFI ---> Connecting to "); | |
Serial.println(ssid); | |
delay(10); | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(ssid, password); | |
WiFi.config(IPAddress(ip_static), IPAddress(ip_gateway), IPAddress(ip_subnet), IPAddress(ip_dns)); | |
int Attempt = 0; | |
while (WiFi.status() != WL_CONNECTED) { | |
Serial.print(". "); | |
Serial.print(Attempt); | |
delay(100); | |
Attempt++; | |
if (Attempt == 250) | |
{ | |
Serial.println(); | |
Serial.println("-----> Could not connect to WIFI"); | |
ESP.restart(); | |
delay(200); | |
} | |
} | |
Serial.println(); | |
Serial.print("===> WiFi connected"); | |
Serial.print(" ------> IP address: "); | |
Serial.println(WiFi.localIP()); | |
} | |
} | |
void setup() | |
{ | |
startMills = millis(); | |
Serial.begin(74880); | |
Serial.println(""); | |
Serial.println("rtc mem test"); | |
Serial.println(wifi_station_get_auto_connect()); | |
WiFi.setAutoConnect(true); | |
rtc_count(); | |
wifi_connect(); | |
clientName += "esp8266-"; | |
uint8_t mac[6]; | |
WiFi.macAddress(mac); | |
clientName += macToStr(mac); | |
clientName += "-"; | |
clientName += String(micros() & 0xff, 16); | |
} | |
void loop() | |
{ | |
if (WiFi.status() == WL_CONNECTED) { | |
if (!client.connected()) { | |
long now = millis(); | |
if (now - lastReconnectAttempt > 200) { | |
lastReconnectAttempt = now; | |
if (reconnect()) { | |
lastReconnectAttempt = 0; | |
} | |
} | |
} else { | |
long now = millis(); | |
if (now - lastMsg > test_para) { | |
lastMsg = now; | |
String payload = "{\"startMills\":"; | |
payload += (millis() - startMills); | |
payload += ",\"salt\":"; | |
payload += rtc_mem_test.salt; | |
payload += ",\"FreeHeap\":"; | |
payload += ESP.getFreeHeap(); | |
payload += ",\"RSSI\":"; | |
payload += WiFi.RSSI(); | |
payload += "}"; | |
sendmqttMsg(topic, payload); | |
} | |
client.loop(); | |
goingToSleepNoRF(); | |
} | |
} else { | |
wifi_connect(); | |
} | |
} | |
void sendmqttMsg(char* topictosend, String payload) | |
{ | |
if (client.connected()) { | |
Serial.print("Sending payload: "); | |
Serial.print(payload); | |
unsigned int msg_length = payload.length(); | |
Serial.print(" length: "); | |
Serial.println(msg_length); | |
byte* p = (byte*)malloc(msg_length); | |
memcpy(p, (char*) payload.c_str(), msg_length); | |
if ( client.publish(topictosend, p, msg_length)) { | |
Serial.println("Publish ok"); | |
free(p); | |
//return 1; | |
} else { | |
Serial.println("Publish failed"); | |
free(p); | |
//return 0; | |
} | |
} | |
} | |
String macToStr(const uint8_t* mac) | |
{ | |
String result; | |
for (int i = 0; i < 6; ++i) { | |
result += String(mac[i], 16); | |
if (i < 5) | |
result += ':'; | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://lowreal.net/2016/01/10/1 --->
'''
include <Arduino.h>
extern "C" {
include <user_interface.h>
};
// system_rtc_mem_write() 先のブロックアドレス。
// 4 bytes で align されており、先頭256bytes はシステム予約領域
// 64 から書けるはずだが、65 以降でないとうまくいかなかった。。
static const uint32_t USER_DATA_ADDR = 66;
// ハッシュ関数 (FNV) CRC でいいけどコード的に短いのでFNV
static uint32_t fnv_1_hash_32(uint8_t *bytes, size_t length) {
static const uint32_t FNV_OFFSET_BASIS_32 = 2166136261U;
static const uint32_t FNV_PRIME_32 = 16777619U;
uint32_t hash = FNV_OFFSET_BASIS_32;;
for(size_t i = 0 ; i < length ; ++i) hash = (FNV_PRIME_32 * hash) ^ (bytes[i]);
return hash;
}
// struct の hash (先頭にあることを想定) を除くデータ部分のハッシュを計算する
template
uint32_t calc_hash(T& data) {
return fnv_1_hash_32(((uint8_t*)&data) + sizeof(data.hash), sizeof(T) - sizeof(data.hash));
}
struct {
// retain data
uint32_t hash;
uint16_t count;
uint8_t send;
uint16_t etc2;
} retain_data;
void post_sensor_data();
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
}
// dummy
void post_sensor_data() {
for (uint i = 0; i < 5; i++) {
digitalWrite(13, HIGH);
delay(300);
digitalWrite(13, LOW);
delay(300);
}
}
'''