Last active
February 1, 2016 08:14
-
-
Save chaeplin/71a41d0f6702fb55159e to your computer and use it in GitHub Desktop.
lowreal.net_rtc_mem.ino
This file contains hidden or 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
// from 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 <class T> | |
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); | |
Serial.begin(9600); | |
Serial.println("Initializing..."); | |
// データ読みこみ | |
bool ok; | |
ok = system_rtc_mem_read(USER_DATA_ADDR, &retain_data, sizeof(retain_data)); | |
if (!ok) { | |
Serial.println("system_rtc_mem_read failed"); | |
} | |
Serial.print("retain_data.count = "); | |
Serial.println(retain_data.count); | |
// ハッシュが一致していない場合、初期化されていないとみなし、初期化処理を行う | |
uint32_t hash = calc_hash(retain_data); | |
if (retain_data.hash != hash) { | |
Serial.println("retain_data may be uninitialized"); | |
retain_data.count = 0; | |
retain_data.send = 0; | |
} | |
// データの変更処理(任意) | |
retain_data.count++; | |
if (!retain_data.send) { | |
// 4回に1度送信する | |
retain_data.send = retain_data.count % 4 == 0; | |
} else { | |
Serial.println("send data"); | |
retain_data.send = 0; | |
// なんか定期的に書きこみたい処理 | |
post_sensor_data(); | |
} | |
// 書きこみ処理。hash を計算していれておく | |
retain_data.hash = hash = calc_hash(retain_data); | |
ok = system_rtc_mem_write(USER_DATA_ADDR, &retain_data, sizeof(retain_data)); | |
if (!ok) { | |
Serial.println("system_rtc_mem_write failed"); | |
} | |
// 動作確認用のダミー | |
digitalWrite(13, HIGH); | |
delay(1000); | |
digitalWrite(13, LOW); | |
if (retain_data.send) { | |
ESP.deepSleep(1e6, WAKE_RF_DEFAULT); | |
} else { | |
// sendしない場合は WIFI をオフで起動させる | |
ESP.deepSleep(1e6, WAKE_RF_DISABLED); | |
} | |
} | |
void loop() { | |
} | |
// dummy | |
void post_sensor_data() { | |
for (uint i = 0; i < 5; i++) { | |
digitalWrite(13, HIGH); | |
delay(300); | |
digitalWrite(13, LOW); | |
delay(300); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment