
{"id":7178,"date":"2018-05-02T18:31:42","date_gmt":"2018-05-02T09:31:42","guid":{"rendered":"https:\/\/okiraku-camera.tokyo\/blog\/?page_id=7178"},"modified":"2018-05-07T18:23:48","modified_gmt":"2018-05-07T09:23:48","slug":"esp-now%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e6%b8%a9%e5%ba%a6%e6%b8%ac%e5%ae%9a%e7%94%a8%e3%82%b9%e3%82%b1%e3%83%83%e3%83%81%e3%81%a8%e3%82%b9%e3%82%af%e3%83%aa%e3%83%97%e3%83%881","status":"publish","type":"page","link":"https:\/\/okiraku-camera.tokyo\/blog\/?page_id=7178","title":{"rendered":"ESP-NOW\u3092\u4f7f\u3063\u305f\u6e29\u5ea6\u6e2c\u5b9a\u7528\u30b9\u30b1\u30c3\u30c1\u3068\u30b9\u30af\u30ea\u30d7\u30c81"},"content":{"rendered":"<h1>ESP-NOW\u3092\u4f7f\u3063\u305f\u6e29\u5ea6\u6e2c\u5b9a\u7528\u30b9\u30b1\u30c3\u30c1\u3068\u30b9\u30af\u30ea\u30d7\u30c8<\/h1>\n<p>\u30b9\u30b1\u30c3\u30c1\u3084\u30b5\u30fc\u30d0\u30fc\u5074\u30b9\u30af\u30ea\u30d7\u30c8\u3002\u30c7<a href=\"https:\/\/okiraku-camera.tokyo\/blog\/?page_id=7007#3\" target=\"_blank\" rel=\"noopener\">\u30fc\u30bf\u30d9\u30fc\u30b9\u5b9a\u7fa9\u306b\u3064\u3044\u3066\u306f\u4ee5\u524d\u8f09\u305b\u305f\u3082\u306e\u3068\u540c\u69d8\u306a\u306e\u3067\u3053\u3061\u3089<\/a>\u3092\u53c2\u7167\u306e\u3053\u3068\u3002\u3053\u306e\u30da\u30fc\u30b8\u306e<a href=\"\/blog\/?p=7167\">\u672c\u6587\u306f\u3053\u3061\u3089<\/a>\u3002<\/p>\n<ul>\n<li><a href=\"#1\">ESP32\u7528\u30b9\u30ec\u30fc\u30d6\u5074\u30b9\u30b1\u30c3\u30c1 (ESP32_espnow_slave3.ino)<\/a><\/li>\n<li><a href=\"#2\">ESP8266\u7528\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u5074\u30b9\u30b1\u30c3\u30c1 (ESP_espnow_ctrl5.ino)<\/a><\/li>\n<li><a href=\"#3\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u683c\u7d0d\u7528\u30b9\u30af\u30ea\u30d7\u30c8 (store_data.php)<\/a><\/li>\n<\/ul>\n<h2 id=\"1\">ESP32_espnow_slave3.ino<\/h2>\n<p>Arduino core for ESP32\u3067\u30d3\u30eb\u30c9\u3057\u305f\u3002\u30d0\u30fc\u30b8\u30e7\u30f3\u756a\u53f7\u304c\u3088\u304f\u5206\u304b\u3089\u306a\u3044\u306e\u3060\u304c\u30012018\u5e744\u670815\u65e5\u306bgithub\u304b\u3089\u305d\u3063\u304f\u308azip\u3067\u843d\u3068\u3057\u3066\u3001<em>&#8230;\\[aruino-src]\\hardware\\espressif\\esp32<\/em> \u306b\u5c55\u958b\u3057\u3066\u4f7f\u3063\u3066\u3044\u308b\u3002esp_now.h\u306f\u3001<em>&#8230;\\tools\\sdk\\include\\esp32<\/em> \u5185\u306b\u3042\u308b\u3002<\/p>\n<pre class=\"lang:c++ decode:true \">#include &lt;esp_now.h&gt;\r\n#include &lt;WiFi.h&gt;\r\n\/**\r\n * ESP32\u3067\u52d5\u304b\u3059\u30b9\u30ec\u30fc\u30d6\u5074\r\n *\/\r\n\r\n#define SERIAL_MONITOR  1\r\n\r\n#if SERIAL_MONITOR\r\n#define START_MSG \"\\n\" + String(__FILE__) + \" start.\\n\"\r\n#define SERIAL_OUT(a) Serial.print(a)\r\n#define SERIAL_F(...) Serial.printf(__VA_ARGS__)\r\n#define SERIAL_INIT(a) Serial.begin(a)\r\n#else\r\n#define SERIAL_INIT(a)\r\n#define SERIAL_OUT(a)\r\n#define SERIAL_F(...) \r\n#endif\r\n\r\n#define LED 13\r\n#define WIFI_CHANNEL  0\r\nconst char* slave_ssid  = \"ESP_SLAVE_SSID\";\r\nconst char* slave_password = \"SLAVE_PASSWORD\";\r\n\r\n\/\/ wifi\r\nconst char* ssid = \"ssid\";\r\nconst char* password = \"password\";\r\nconst char* remote_host = \"host_ipaddress\";\r\n\/\/ static ip info\r\nconst IPAddress myip(192,168,1,123);\r\nconst IPAddress gwip(192,168,1,1);\r\nconst IPAddress mask(255,255,255,0);\r\n\r\n#pragma pack(push, 1)\r\ntypedef struct RX_LOG {\r\n  char mac[32];\r\n  unsigned long rx_millis;\r\n  long last_seq_no;\r\n} rx_log_t;\r\n\r\ntypedef struct {\r\n  uint16_t seq_no;\r\n  uint16_t elapsed;\r\n  uint16_t extra;    \/\/ \r\n  uint8_t retry;\r\n  float T;\r\n  float H;\r\n  float P;\r\n  float V;\r\n  uint8_t checksum;\r\n} sensor_data_t;\r\n#pragma pack(pop)\r\n\r\nbool data_recieved = false;\r\nString sender_mac;\r\nsensor_data_t rx_data;\r\n\r\n#define MAX_CLIENT  20\r\nrx_log_t rx_log[MAX_CLIENT];\r\nvoid init_rx_log() {\r\n  for(int i = 0; i &lt; MAX_CLIENT; i++)\r\n    memset((void*)&amp;rx_log[i], 0, sizeof(rx_log_t));\r\n}\r\n\r\nrx_log_t* findlog() {\r\n  int i;\r\n  for(i = 0; i &lt; MAX_CLIENT; i++) {\r\n    rx_log_t* p = &amp;rx_log[i];\r\n    if (!*p-&gt;mac || !strcmp(p-&gt;mac, sender_mac.c_str()))\r\n      return p;\r\n  }\r\n  return NULL;\r\n}\r\n\r\nstatic uint8_t calc_check_sum(uint8_t* p) {\r\n  uint8_t sum = 0;\r\n  for(int i = 0; i &lt; sizeof(sensor_data_t) - 1; i++)\r\n    sum += p[i];\r\n  return sum;\r\n}\r\n\r\nvoid die(const char* cp) {\r\n  if (cp)\r\n    SERIAL_OUT(String(cp) + \"\\n\");\r\n  digitalWrite(LED, 1);\r\n  delay(500);\r\n  digitalWrite(LED, 0);\r\n  delay(500);\r\n}\r\n\r\n#define WAIT_MS 50\r\n#define WAIT_LIMIT  (int)(15000 \/ WAIT_MS)\r\nbool ap_connect() {\r\n  int n;\r\n  int count = 0;\r\n  int retry = 0;\r\n  SERIAL_OUT(\"\\nstart ap_connect()\\n\");\r\n  WiFi.config(myip, gwip, mask, gwip);\r\n  WiFi.mode(WIFI_STA);\r\n  WiFi.disconnect();\r\n  delay(10);\r\n  WiFi.begin(ssid, password); \r\n  while ((n = WiFi.status()) != WL_CONNECTED) {\r\n    SERIAL_OUT(n);\r\n    delay(WAIT_MS);\r\n    if (n == WL_NO_SSID_AVAIL || n == WL_CONNECT_FAILED) {\r\n      WiFi.reconnect();\r\n      SERIAL_OUT(\"+\");\r\n      count = 0;\r\n      retry++;\r\n    }\r\n    if (count++ &gt; WAIT_LIMIT || retry &gt; 3) {\r\n      SERIAL_OUT(\"\\nap_connect() failed\\n\");\r\n      return false;\r\n    }\r\n  }\r\n  SERIAL_OUT(\"\\nap_connect() done.\\n\");\r\n  return true;\r\n}\r\n\r\nbool send_to_server() {\r\n  int count = 0;\r\n  SERIAL_OUT(\"start send_to_server()\");\r\n  WiFiClient client;\r\n  if (!client.connect(remote_host, 80))\r\n    return false;\r\n  String request = \"\/store_data.php?point_id=\" + sender_mac + \"&amp;T=\" + String(rx_data.T) + \"&amp;H=\" + String(rx_data.H) + \r\n      \"&amp;P=\" + String(rx_data.P) + \"&amp;V=\" + String(rx_data.V) + \"&amp;X1=\" + String(rx_data.elapsed) + \"&amp;X2=\" + rx_data.retry;\r\n  String req_line = \"GET \" + request + \" HTTP\/1.1\\r\\nHost: \" + String(remote_host) + \"\\r\\nConnection: close\\r\\n\\r\\n\";\r\n  client.print(req_line);\r\n  count = 0;\r\n  while(!client.available()) {  \/\/ waif for response.\r\n    delay(1);\r\n    if (count++ &gt; 5000)\r\n        return false;\r\n  }\r\n  while(client.available()) { \/\/ read response.\r\n    String line = client.readStringUntil('\\n');\r\n    SERIAL_F(\"%s\\n\", line.c_str());\r\n    delay(1);\r\n  }\r\n  return true;\r\n}\r\n\r\nvoid onReceive(const uint8_t *mac, const uint8_t *data, int data_len) {\r\n  char tmp[20];\r\n  sprintf(tmp, \"%02X:%02X:%02X:%02X:%02X:%02X\", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);\r\n  sender_mac = String(tmp);\r\n  esp_now_unregister_recv_cb();\r\n  if (data_len == sizeof(sensor_data_t)) {\r\n    memcpy((uint8_t*)&amp;rx_data, data, data_len);\r\n    if (calc_check_sum((uint8_t*)&amp;rx_data) == rx_data.checksum)\r\n      data_recieved = true;\r\n    else\r\n      SERIAL_OUT(\"onReceive() : checksum not match.\\n\");\r\n  } else\r\n      SERIAL_OUT(\"onReceive() : data length dose not match\\n\");\r\n}\r\n\r\nvoid start_espnow() {\r\n  SERIAL_F(\"\\nstart_espnow()\\n\");\r\n  WiFi.mode(WIFI_AP);\r\n  if (WiFi.softAP(slave_ssid, slave_password, WIFI_CHANNEL, 1))\r\n    SERIAL_F(\"SoftAP Start. my MAC : %s\\n\" , WiFi.softAPmacAddress().c_str());\r\n  else\r\n    die(\"softAP start failed\");  \r\n  if (esp_now_init() != ESP_OK)\r\n    die(\"ESPNow Init Failed\"); \r\n  esp_now_register_recv_cb(onReceive);\r\n}\r\n\r\nvoid setup() {\r\n  delay(1);\r\n  SERIAL_INIT(115200);\r\n  SERIAL_OUT(\"\\nESP32_espnow_slave2 start\\n\");\r\n  pinMode(LED, OUTPUT);\r\n  digitalWrite(LED, 0);\r\n  init_rx_log();\r\n  start_espnow();\r\n}\r\n\r\nvoid loop() {\r\n  delay(1);\r\n  if (data_recieved) {\r\n    esp_now_deinit();\r\n    data_recieved = false;\r\n    rx_log_t* p = findlog();\r\n    unsigned long tm = millis();\r\n    bool skip = false;\r\n    if (p != NULL) {\r\n      if (*p-&gt;mac) {\r\n        SERIAL_F(\"find %s in rx_log\\n\", p-&gt;mac);\r\n        SERIAL_F(\"rx interval = %d last_seq = %d\\n\", tm - p-&gt;rx_millis, p-&gt;last_seq_no);\r\n        if (p-&gt;last_seq_no == rx_data.seq_no) \/\/ \u524d\u56de\u3068\u540c\u3058\u30b7\u30fc\u30b1\u30f3\u30b9\u756a\u53f7\u3002\u30de\u30b9\u30bf\u306f\u5931\u6557\u3057\u305f\u3068\u601d\u3063\u3066\u518d\u9001\u3057\u3066\u3044\u308b\u304c\u53d7\u4fe1\u6e08\u3002\r\n          skip = true;\r\n      } else {\r\n        strncpy(p-&gt;mac, sender_mac.c_str(), sizeof(p-&gt;mac));\r\n        SERIAL_F(\"new client %s\\n\", p-&gt;mac);\r\n      }\r\n      p-&gt;last_seq_no = rx_data.seq_no;\r\n      p-&gt;rx_millis = tm;\r\n      if (!skip) {\r\n        digitalWrite(LED, 1);\r\n        if (ap_connect()) {\r\n          send_to_server();\r\n          WiFi.disconnect();\r\n        }\r\n        digitalWrite(LED, 0);\r\n        SERIAL_F(\"send_data takes %d msec.\\n\", (millis() - tm));\r\n      }\r\n      start_espnow();\r\n    } else {\r\n      init_rx_log();\r\n      ESP.restart();\r\n    }\r\n  }\r\n}<\/pre>\n<h3>\u8ffd\u8a18<\/h3>\n<h6>WiFi\u30a2\u30af\u30bb\u30b9\u30dd\u30a4\u30f3\u30c8\u306b\u63a5\u7d9a\u3067\u304d\u306a\u304f\u306a\u3063\u305f<\/h6>\n<p>\u6700\u521d\u306e\u30b9\u30b1\u30c3\u30c1\u3067\u52d5\u304b\u3057\u59cb\u3081\u3066\u304b\u30894.5\u65e5\u9593\u307b\u3069\u7d4c\u904e\u3057\u305f\u6642\u70b9\u3067\u3001\u30b9\u30ec\u30fc\u30d6\u5074\u304b\u3089WiFi\u30eb\u30fc\u30bf\u30fc\u3078\u306e\u63a5\u7d9a\u304c\u5931\u6557\u3059\u308b\u3088\u3046\u306b\u306a\u3063\u305f\u3002\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u304b\u3089\u306eESP-NOW\u306b\u3088\u308b\u63a5\u7d9a\u306f\u6b63\u5e38\u306b\u884c\u308f\u308c\u3066\u3044\u308b\u3088\u3046\u3067\u3001\u30b9\u30ec\u30fc\u30d6\u304b\u3089WiFi\u30eb\u30fc\u30bf\u30fc\u3078\u306e\u63a5\u7d9a\u4e2d\uff08\u5b9f\u969b\u306f\u8a66\u884c\u4e2d\uff09\u3092\u793a\u3059LED\u3082\u5b9a\u671f\u7684\u306b\u70b9\u706f\u3057\u3066\u304a\u308aESP-NOW\u306e\u53d7\u4fe1\u52d5\u4f5c\u81ea\u4f53\u306f\u6301\u7d9a\u3057\u3066\u3044\u305f\u6a21\u69d8\u3002<br \/>\n\u63a5\u7d9a\u4e0d\u80fd\u306b\u306a\u308b\u307e\u3067\u306e\u30c7\u30fc\u30bf\u306f\u30b5\u30fc\u30d0\u30fc\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c6\u30fc\u30d6\u30eb\u306b\u683c\u7d0d\u3055\u308c\u3066\u304a\u308a\u3001\u7d0427600\u884c\u304c\u683c\u7d0d\u3055\u308c\u3066\u3044\u305f\u304b\u3089\u3001\u540c\u3058\u3060\u3051\u306e\u56de\u6570WiFi.begin() \u306b\u3088\u308b\u63a5\u7d9a\u304c\u6210\u529f\u3057\u3066\u3044\u305f\u3053\u3068\u306b\u306a\u308b\u3002<\/p>\n<p>\u30b9\u30ec\u30fc\u30d6\u5074\u3092\u30ea\u30bb\u30c3\u30c8\u3057\u305f\u308a\u96fb\u6e90\u3092\u30aa\u30d5\u306b\u3057\u3066\u3082\u6cbb\u3089\u306a\u3044\u306e\u3067\u3001\u5225\u306eESP32\u30e2\u30b8\u30e5\u30fc\u30eb\u306b\u5207\u308a\u66ff\u3048\u3001MAC\u30a2\u30c9\u30ec\u30b9\u3092\u5909\u66f4\u3059\u308b\u90fd\u5408\u3067\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u306e\u30b9\u30b1\u30c3\u30c1\u3082\u5165\u308c\u66ff\u3048\u3066ESP-NOW\u306e\u5b9f\u9a13\u306f\u7d99\u7d9a\u3059\u308b\u3053\u3068\u306b\u3057\u305f\u3002<\/p>\n<p>\u554f\u984c\u306eESP32\u30e2\u30b8\u30e5\u30fc\u30eb\u306bWiFi\u63a5\u7d9a\u306e\u305f\u3081\u306e\u5358\u7d14\u306a\u30b9\u30b1\u30c3\u30c1\u3092\u5165\u308c\u3066\u8a66\u3057\u3066\u307f\u3066\u3082\u30eb\u30fc\u30bf\u30fc\u306b\u63a5\u7d9a\u3067\u304d\u306a\u304b\u3063\u305f\u3002\u8abf\u3079\u3066\u307f\u308b\u3068WiFi.begin() \u306b\u3088\u308b\u63a5\u7d9a\u304c\u5931\u6557\u3057\u3066\u3044\u305f\u3002<\/p>\n<pre class=\"lang:default decode:true\">WiFi.begin(ssid, password); \r\nwhile ((n = WiFi.status()) != WL_CONNECTED) {\r\n  ...<\/pre>\n<p><em>WiFi.status()<\/em> \u306e\u623b\u308a\u5024\u304c\u3057\u3070\u3089\u304f\u306e\u9593\u306f <em>WL_DISCONNECTED<\/em> ( == 6) \u3092\u8fd4\u3059\u304c\u3001\u305d\u306e\u5f8c <em>WL_NO_SSID_AVAIL<\/em> ( == 1) \u3068\u306a\u3063\u3066\u56de\u5fa9\u305b\u305a\u3001\u30b9\u30b1\u30c3\u30c1\u304c\u63a5\u7d9a\u3092\u3042\u304d\u3089\u3081\u3066\u3044\u308b\u3053\u3068\u304c\u5206\u304b\u3063\u305f\u3002\u767a\u751f\u3057\u305f\u72b6\u6cc1\u306f\u9055\u3046\u304c\u3001<a href=\"https:\/\/okiraku-camera.tokyo\/blog\/?p=3686\" target=\"_blank\" rel=\"noopener\">\u4ee5\u524dESP-WROOM-02\u76f8\u4e92\u9593\u3067\u306e\u63a5\u7d9a\u304c\u3046\u307e\u304f\u3044\u304b\u306a\u304b\u3063\u305f<\/a>\u3068\u304d\u306b\u4f3c\u3066\u3044\u308b\u3002<\/p>\n<p>\u5bfe\u7b56\u3068\u3057\u3001\u73fe\u5728\u306e\u30b9\u30b1\u30c3\u30c1\u306e\u3088\u3046\u306b\u3001WiFi.begin(); \u306e\u524d\u306b\u3001WiFi.disconnect(); \u3092\u5165\u308c\u308b\u3053\u3068\u306b\u3057\u305f\u3002<\/p>\n<pre class=\"lang:default decode:true \">WiFi.mode(WIFI_STA);\r\nWiFi.disconnect();\r\ndelay(10);\r\nWiFi.begin(ssid, password);<\/pre>\n<p>\u305d\u3057\u3066\u3001\u30a2\u30af\u30bb\u30b9\u30dd\u30a4\u30f3\u30c8\u3078\u306e\u63a5\u7d9a\u304c\u6210\u529f\u3057\u305f\u5834\u5408\u306f\u5e38\u306bWiFi.disconnect(); \u3057\u3066\u304b\u3089ESP-NOW\u306e\u521d\u671f\u5316\u3092\u884c\u3046\u3088\u3046\u306b\u3057\u305f\u3002\u63a5\u7d9a\u4e0d\u80fd\u306b\u306a\u3063\u305f\u7406\u7531\u306f\u4e0d\u660e\u3060\u304c\u3001WiFi\u63a5\u7d9a\u306b\u95a2\u3059\u308b\u5185\u90e8\u72b6\u614b\u304c\u5999\u306a\u5177\u5408\u306b\u306a\u3063\u3066\u3057\u307e\u3046\u3053\u3068\u304c\u3042\u308b\u3093\u3060\u308d\u3046\u3002\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u5909\u66f4\u3068\u30b9\u30b1\u30c3\u30c1\u306e\u66f8\u304d\u76f4\u3057\u5f8c\u3001\u7d048\u6642\u9593\u307b\u3069\u3067\u52d5\u4f5c\u3092\u518d\u958b\u3057\u305f\u3002<\/p>\n<h2 id=\"2\">ESP_espnow_ctrl5.ino<\/h2>\n<p>ESP8266 Core for Arduino 2.4.1\u3067\u30d3\u30eb\u30c9\u3002I2C\u3092\u4f7f\u3063\u305f\u6e29\u5ea6\u30bb\u30f3\u30b5\u30fc\u30a4\u30f3\u30bf\u30d5\u30a7\u30fc\u30b9\u7528\u306e<a href=\"\/blog\/?page_id=7007#2\" target=\"_blank\" rel=\"noopener\">&#8220;hdc1000_bme280.h&#8221;\u306b\u3064\u3044\u3066\u306f\u3001\u3053\u3061\u3089\u306e\u30da\u30fc\u30b8<\/a>\u3092\u53c2\u7167\u306e\u3053\u3068\u3002<\/p>\n<pre class=\"lang:c++ decode:true \">#include &lt;espnow.h&gt;\r\n#include &lt;ESP8266WiFi.h&gt;\r\nextern \"C\" {\r\n  #include \"user_interface.h\"\r\n}\r\n#include \"hdc1000_bme280.h\"\r\n\r\n#define LED 15\r\n#define MEASURE_INTERVAL_MS 60000       \/\/ 60\u79d2\r\n#define RESEND_INTERVAL_MS 10000   \/\/ 10\u79d2\r\n\r\n#define WIFI_CHANNEL  0\r\n#ifndef ESP_OK\r\n  #define ESP_OK  0\r\n#endif\r\n\r\n#define SERIAL_MONITOR  0\r\n#if SERIAL_MONITOR\r\n#define START_MSG \"\\n\" + String(__FILE__) + \" start.\\n\"\r\n#define SERIAL_INIT(a) Serial.begin(a)\r\n#define SERIAL_OUT(a) Serial.print(a)\r\n#define SERIAL_F(...) Serial.printf(__VA_ARGS__)\r\n#else\r\n#define START_MSG\r\n#define SERIAL_INIT(a) \r\n#define SERIAL_OUT(a) \r\n#define SERIAL_F(...) \r\n#endif\r\n\r\n#pragma pack(push, 1)\r\ntypedef struct {\r\nuint16_t seq_no; \r\n\tuint16_t elapsed;\r\n\tuint16_t extra;\r\n\tuint8_t retry;\r\n\tfloat T;\r\n\tfloat H;\r\n\tfloat P;\r\n\tfloat V;\r\n\tuint8_t checksum;\r\n} sensor_data_t;\r\n#pragma pack(pop)\r\n\r\nuint8_t slave_mac[] = {0x24, 0x0a, 0xc4, 0xXX, 0xXX, 0xXX}; \/\/ \u9001\u4fe1\u5148 (ESP-32)\r\nbme280 bme280(0x76);\r\nunsigned long start_time = millis();\r\n\r\nvoid die(const char* cp) {\r\n\tif (cp)\r\n\t\tSERIAL_F(\"\\n%s\\n\", cp);\r\n\tfor(;;) {\r\n\t\tdigitalWrite(LED, 1);\r\n\t\tdelay(500);\r\n\t\tdigitalWrite(LED, 0);\r\n\t\tdelay(500);\r\n\t}\r\n}\r\n\r\n#if SERIAL_MONITOR\r\nstatic void DUMP_RTC(sensor_data_t* p) {\r\n\tString s;\r\n\tchar tmp[120];\r\n\ts = \"RTC: \";\r\n\tfor(int i = 0; i &lt; sizeof(sensor_data_t); i++) {\r\n\t\tSERIAL_F(\"%02X \", ((uint8_t*)p)[i]);\r\n\t\ts += String(tmp) + String(\" \");\r\n\t}\r\n\tSERIAL_F(\"\\nDUMP RTC\\nseq_no=%d, elapsed=%d, extra=%d, retry=%d, T=%.2f, checksum = %02x\\n\",\r\n\t\tp-&gt;seq_no, p-&gt;elapsed, p-&gt;extra, p-&gt;retry, p-&gt;T, p-&gt;checksum);\r\n}\r\n#else\r\n  #define DUMP_RTC(a)\r\n#endif\r\n\r\nuint8_t calc_check_sum(uint8_t* p) {\r\n\tuint8_t sum = 0;\r\n\tfor(int i = 0; i &lt; sizeof(sensor_data_t) - 1; i++)\r\n\t\tsum += p[i];\r\n\treturn sum;\r\n}\r\n\r\nenum { S_WAIT = 0, S_SUCCESS , S_RETRY, S_TIMEOUT, S_FAILED } state = S_WAIT;\r\nvoid onSent(u8* mac, u8 result) {\r\n\tstate = result == ESP_OK ? S_SUCCESS : S_RETRY;\r\n}\r\n\r\nint send_data(sensor_data_t* p) {\r\n\tfloat vbat = 570.0 * system_adc_read() \/ 1024.0;  \/\/ 100\u500d\u3057\u305f\u96fb\u5727\u3002470K + 100K\u3067\u306e\u5206\u5727\u6642 570 \/ 100 = 5.7\r\n\tbme280.measure();\r\n\tp-&gt;T = bme280.temp;\r\n\tp-&gt;H = bme280.humi;\r\n\tp-&gt;P = bme280.press;\r\n\tp-&gt;V = vbat;\r\n\tp-&gt;checksum = calc_check_sum((uint8_t*)p);\r\n\tesp_now_register_send_cb(onSent);\r\n\tif (esp_now_send(slave_mac, (u8*)p, sizeof(sensor_data_t)) != ESP_OK) {\r\n\t\tesp_now_unregister_send_cb();\r\n\t\treturn S_FAILED;\r\n\t}\r\n\tunsigned long start = millis();    \r\n\twhile(state == S_WAIT) {\r\n\t\tif (millis() - start &gt; 1000) {  \/\/ \u6700\u59271\u79d2\u5f85\u3064\u3002\r\n\t\t\tstate = S_TIMEOUT;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tdelay(1);\r\n\t}\r\n\tesp_now_unregister_send_cb();\r\n\treturn state;     \r\n}\r\n\r\nvoid setup() {\r\n\tuint8_t sta_mac[6];  \/\/ \u81ea\u5206\r\n\tsensor_data_t data;\r\n\r\n\tSERIAL_INIT(115200);\r\n\tSERIAL_OUT(START_MSG);\r\n\tif (!bme280.init())\r\n\t\tdie(\"FATAL: BME280 init failed.\");\r\n\tpinMode(LED, OUTPUT);\r\n\tdigitalWrite(LED, 1);\r\n\r\n\trst_info *prst = ESP.getResetInfoPtr();\r\n\tif (prst-&gt;reason != REASON_DEEP_SLEEP_AWAKE) {\r\n\t\tmemset(&amp;data, 0, sizeof(sensor_data_t));\r\n\t\tdelay(10);\r\n\t} else {\r\n\t\tESP.rtcUserMemoryRead(0, (uint32_t*)&amp;data, sizeof(sensor_data_t));\r\n\t\tif (data.checksum != calc_check_sum((u8*)&amp;data)) {\r\n\t\t  SERIAL_F(\"\\nrtc data corrupted.\\n\");\r\n\t\t  memset(&amp;data, 0, sizeof(sensor_data_t));\r\n\t\t}\r\n\t}\r\n\tDUMP_RTC(&amp;data);\r\n  \r\n\tWiFi.macAddress(sta_mac);\r\n\tunsigned long random_seed = (unsigned long)sta_mac[5] &lt;&lt; 24 &amp; 0xff000000 \r\n\t\t| (unsigned long)sta_mac[4] &lt;&lt; 16 &amp; 0xff0000 | (unsigned long)sta_mac[3] &lt;&lt; 8 &amp; 0xff00 \r\n\t\t| (unsigned long)sta_mac[2] &amp; 0xff;\r\n\tSERIAL_F(\"random_seed = %d\\n\", random_seed);      \r\n\trandomSeed(random_seed);\r\n\tWiFi.mode(WIFI_STA);\r\n\tSERIAL_F(\"STA MAC: %s\\n\", WiFi.macAddress().c_str());\r\n\tif (esp_now_init() != ESP_OK)\r\n\t\tdie(\"ESPNow Init Failed\"); \r\n\tesp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);\r\n\tif ( esp_now_add_peer(slave_mac, ESP_NOW_ROLE_SLAVE, WIFI_CHANNEL, NULL, 0) != ESP_OK)\r\n\t\tdie(\"esp_now_add_peer() failed.\");\r\n\tunsigned long sleep_ms = 0;\r\n\tint state = send_data(&amp;data);\r\n\tswitch(state) {\r\n\tcase S_FAILED:\r\n\t\tdie(\"esp_now_send() failed.\");\r\n\t\tbreak;\r\n\tcase S_SUCCESS:\r\n\t\tSERIAL_OUT(\"Data is sent.\\n\");\r\n\t\tsleep_ms = MEASURE_INTERVAL_MS;\r\n\t\tif (data.retry &gt; 0)\r\n\t\t\tsleep_ms += random(2000, 4000); \r\n\t\tdata.seq_no++;\r\n\t\tdata.retry = 0;\r\n\t\tbreak;\r\n\tcase S_RETRY:\r\n\t\tdata.retry++;\r\n\t\tif (data.retry &lt; 10) {\r\n\t\t\tsleep_ms = random(1000, 2000);  \r\n\t\t\tSERIAL_F(\"Data send failed. retry count = %d. wait %d msec.\\n\", data.retry, sleep_ms);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tESP.restart();\r\n\t\tdelay(10);\r\n\t\tbreak;\r\n\tcase S_TIMEOUT:\r\n\t\tSERIAL_OUT(\"send_data timeout.\");\r\n\t\tdata.retry = 0;\r\n\t\tdata.seq_no = 0;\r\n\t\tsleep_ms = RESEND_INTERVAL_MS;\r\n\t\tbreak;\r\n\t}\r\n\tunsigned long tm = millis() - start_time;\r\n\tif (state != S_SUCCESS)\r\n\t\tdata.extra += tm;\r\n\telse {      \r\n\t\tdata.elapsed = tm + data.extra; \r\n\t\tdata.extra = 0;\r\n\t}\r\n\tdata.checksum = calc_check_sum((u8*)&amp;data);\r\n\tESP.rtcUserMemoryWrite(0, (uint32_t*)&amp;data, sizeof(sensor_data_t));\r\n#if SERIAL_MONITOR        \r\n\tdelay(10);\r\n#endif        \r\n\tESP.deepSleep(sleep_ms * 1000, WAKE_RF_DEFAULT);\r\n}\r\n\r\nvoid loop() { }\r\n<\/pre>\n<h2 id=\"3\">store_data.php<\/h2>\n<p>\u3059\u3079\u3066\u306e\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u304b\u3089\u306e\u30c7\u30fc\u30bf\u306f\u5358\u4e00\u306e\u30c6\u30fc\u30d6\u30eb(envdata10) \u3068\u3001MAC\u30a2\u30c9\u30ec\u30b9\u3054\u3068\u306e\u30c6\u30fc\u30d6\u30eb\u306b\u683c\u7d0d\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u5404\u30c6\u30fc\u30d6\u30eb\u306f\u3001<br \/>\n<span class=\"lang:default decode:true crayon-inline \">mysql&gt; create table envdata10 like envdata;<\/span><br \/>\n\u3068\u3044\u3063\u305f\u65b9\u6cd5\u3067\u4f5c\u6210\u3057\u305f\u3002\u3053\u306e\u30b9\u30af\u30ea\u30d7\u30c8\u304c\u5229\u7528\u3057\u3066\u3044\u308b <a href=\"\/blog\/?page_id=7007#4\">envdata_db.php \u306f\u3053\u3061\u3089\u3092\u53c2\u7167<\/a>\u3002insert_array() \u5185\u3067 $_GET[] \u304b\u3089\u5024\u3092\u53d6\u5f97\u3059\u308b\u90e8\u5206\u306f\u30e0\u30c0\u3060\u304c\u554f\u984c\u306f\u306a\u3044\u3002<\/p>\n<pre class=\"lang:php decode:true\">&lt;?PHP\r\nrequire_once('envdata_db.php');\r\nheader('cotent-type: text\/html');\r\n$ar = array('T' =&gt; 0.0, 'P' =&gt; 0.0, 'H' =&gt; 0.0, 'V' =&gt; 0.0, 'X1' =&gt; 0.0, 'X2' =&gt; 0.0, 'point_id' =&gt; 'unknown');\r\nforeach($ar as $k =&gt; $v) {\r\n$s = isset($_GET[$k]) ? $_GET[$k] : \"\";\r\n\tif (strlen($s) &gt; 0)\r\n\t\t$ar[$k] = $s;\r\n}\r\n\r\n$db = new envdata_db();\r\n$db-&gt;insert_array(\"envdata10\", $ar);\r\n\r\n$table = \"\";\r\nif ($ar['point_id'] == '18:FE:34:XX:XX:XX')\r\n\t$table = \"envdata5\";\r\nelse if ($ar['point_id'] == 'BC:DD:C2:XX:XX:XX')\r\n\t$table = \"envdata\";\r\nelse if ($ar['point_id'] == '5C:CF:7F:XX:XX:XX')\r\n\t$table = \"envdata7\";\r\nelse if ($ar['point_id'] == '84:F3:EB:XX:XX:XX')\r\n\t$table = \"envdata8\";\r\nelse\r\n\techo \"table name is empty\";\r\n\r\nif ($table != \"\") {\r\n\tif (!$db-&gt;insert_array($table, $ar)) {\r\n\t\techo \"NG SQL ERROR: \" . $envdata-&gt;getLast_error() . '&lt;br\/&gt;';\r\n\t\techo $envdata-&gt;getLast_sql() . '&lt;br\/&gt;';\r\n\t} else\r\n\t\techo \"OK\";\r\n}\r\n?&gt;<\/pre>\n<p>MAC\u30a2\u30c9\u30ec\u30b9\u5148\u982d3\u30d0\u30a4\u30c8(Espressif\u793e\u3092\u8868\u3059)\u306e\u7a2e\u985e\u3082\u5897\u3048\u3066\u304d\u305f\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>ESP-NOW\u3092\u4f7f\u3063\u305f\u6e29\u5ea6\u6e2c\u5b9a\u7528\u30b9\u30b1\u30c3\u30c1\u3068\u30b9\u30af\u30ea\u30d7\u30c8 \u30b9\u30b1\u30c3\u30c1\u3084\u30b5\u30fc\u30d0\u30fc\u5074\u30b9\u30af\u30ea\u30d7\u30c8\u3002\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5b9a\u7fa9\u306b\u3064\u3044\u3066\u306f\u4ee5\u524d\u8f09\u305b\u305f\u3082\u306e\u3068\u540c\u69d8\u306a\u306e\u3067\u3053\u3061\u3089\u3092\u53c2\u7167\u306e\u3053\u3068\u3002\u3053\u306e\u30da\u30fc\u30b8\u306e\u672c\u6587\u306f\u3053\u3061\u3089\u3002 ESP32\u7528\u30b9\u30ec\u30fc\u30d6\u5074\u30b9\u30b1\u30c3\u30c1 ( &hellip; <a href=\"https:\/\/okiraku-camera.tokyo\/blog\/?page_id=7178\" class=\"more-link\">\u7d9a\u304d\u3092\u8aad\u3080 <span class=\"screen-reader-text\">ESP-NOW\u3092\u4f7f\u3063\u305f\u6e29\u5ea6\u6e2c\u5b9a\u7528\u30b9\u30b1\u30c3\u30c1\u3068\u30b9\u30af\u30ea\u30d7\u30c81<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-7178","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/okiraku-camera.tokyo\/blog\/index.php?rest_route=\/wp\/v2\/pages\/7178","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/okiraku-camera.tokyo\/blog\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/okiraku-camera.tokyo\/blog\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/okiraku-camera.tokyo\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/okiraku-camera.tokyo\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7178"}],"version-history":[{"count":0,"href":"https:\/\/okiraku-camera.tokyo\/blog\/index.php?rest_route=\/wp\/v2\/pages\/7178\/revisions"}],"wp:attachment":[{"href":"https:\/\/okiraku-camera.tokyo\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}