├── .gitattributes ├── .gitignore ├── ESPSensorHourlyEnhanced ├── ESPSensorHourlyEnhanced.ino ├── Mail.ino ├── Sparkfun.ino └── ubidots.ino ├── README.md └── RTCmemTest └── RTCmemTest.ino /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /ESPSensorHourlyEnhanced/ESPSensorHourlyEnhanced.ino: -------------------------------------------------------------------------------- 1 | 2 | ADC_MODE(ADC_VCC); //vcc read-mode 3 | 4 | #include 5 | #include ; 6 | extern "C" { 7 | #include "user_interface.h" // this is for the RTC memory read/write functions 8 | } 9 | #define RTCMEMORYSTART 66 10 | #define RTCMEMORYLEN 125 11 | #define VCC_ADJ 1.0 // measure with your voltmeter and calculate that the number mesured from ESP is correct 12 | 13 | #define COLLECT 17 14 | #define SEND 66 15 | #define SLEEPTIME 1000000 16 | 17 | #define SPARKFUN_BATTERY 1 18 | 19 | 20 | 21 | typedef struct { 22 | int magicNumber; 23 | int valueCounter; 24 | } rtcManagementStruc; 25 | 26 | rtcManagementStruc rtcManagement; 27 | 28 | typedef struct { 29 | float battery; 30 | int other; 31 | } rtcStore; 32 | 33 | rtcStore rtcValues; 34 | 35 | int i; 36 | int buckets; 37 | unsigned long startTime; 38 | 39 | WiFiClient client; 40 | 41 | 42 | void setup() { 43 | Serial.begin(115200); 44 | Serial.println(); 45 | Serial.println(); 46 | Serial.print("Booted "); 47 | 48 | 49 | rst_info *rsti; 50 | rsti = ESP.getResetInfoPtr(); 51 | 52 | switch (rsti->reason) { 53 | 54 | case 5: 55 | Serial.println(" from RTC-RESET (ResetInfo.reason = 5)"); 56 | break; 57 | case 6: 58 | Serial.println(" from POWER-UP (ResetInfo.reason = 6)"); 59 | rtcManagement.magicNumber = COLLECT; 60 | rtcManagement.valueCounter = 0; 61 | break; 62 | } 63 | 64 | system_get_rst_info(); 65 | 66 | buckets = (sizeof(rtcValues) / 4); 67 | if (buckets == 0) buckets = 1; 68 | // Serial.print("Buckets "); 69 | // Serial.println(buckets); 70 | system_rtc_mem_read(64, &rtcManagement, 8); 71 | // Serial.print("Magic Number "); 72 | // Serial.println(rtcManagement.magicNumber); 73 | 74 | // initialize System after first start 75 | if (rtcManagement.magicNumber != COLLECT && rtcManagement.magicNumber != SEND ) { 76 | rtcManagement.magicNumber = COLLECT; 77 | rtcManagement.valueCounter = 0; 78 | system_rtc_mem_write(64, &rtcManagement, 8); 79 | Serial.println("Initial values set"); 80 | ESP.deepSleep(10, WAKE_RF_DISABLED); 81 | } 82 | if (rtcManagement.magicNumber == COLLECT) { // Read sensor and store 83 | if (rtcManagement.valueCounter <= RTCMEMORYLEN / buckets) { 84 | Serial.println("Sensor reads"); 85 | 86 | rtcValues.battery = ESP.getVcc() * VCC_ADJ ; 87 | rtcValues.other = rtcManagement.valueCounter; 88 | 89 | int rtcPos = RTCMEMORYSTART + rtcManagement.valueCounter * buckets; 90 | system_rtc_mem_write(rtcPos, &rtcValues, buckets * 4); 91 | system_rtc_mem_write(rtcPos, &rtcValues, 4); 92 | system_rtc_mem_write(64, &rtcManagement, 4); 93 | 94 | Serial.print("Counter : "); 95 | Serial.print(rtcManagement.valueCounter); 96 | Serial.print(" Position: "); 97 | Serial.print(rtcPos); 98 | Serial.print(", battery: "); 99 | Serial.print(rtcValues.battery); 100 | rtcManagement.valueCounter++; 101 | system_rtc_mem_write(64, &rtcManagement, 8); 102 | Serial.println("before sleep W/O RF"); 103 | ESP.deepSleep(SLEEPTIME, WAKE_NO_RFCAL); 104 | } 105 | else { // set initial values 106 | rtcManagement.magicNumber = SEND; 107 | rtcManagement.valueCounter = 0; 108 | system_rtc_mem_write(64, &rtcManagement, 8); 109 | Serial.println("before sleep w RF"); 110 | ESP.deepSleep(10, WAKE_RFCAL); 111 | } 112 | } 113 | else { // Send to Cloud 114 | startTime = millis(); 115 | Serial.println(); 116 | Serial.println(); 117 | WiFi.mode(WIFI_STA); 118 | Serial.print("Start Sending values. Connecting to "); 119 | Serial.println(ASP_ssid); 120 | WiFi.begin(ASP_ssid, ASP_password); 121 | 122 | while (WiFi.status() != WL_CONNECTED) { 123 | delay(500); 124 | Serial.print("."); 125 | } 126 | Serial.println("Sending "); 127 | 128 | for (i = 0; i <= RTCMEMORYLEN / buckets; i++) { 129 | int rtcPos = RTCMEMORYSTART + i * buckets; 130 | system_rtc_mem_read(rtcPos, &rtcValues, sizeof(rtcValues)); 131 | Serial.print("i: "); 132 | Serial.print(i); 133 | Serial.print(" Position "); 134 | Serial.print(rtcPos); 135 | Serial.print(", battery: "); 136 | Serial.print(rtcValues.battery); 137 | Serial.print(", other: "); 138 | Serial.println(rtcValues.other); 139 | sendSparkfun(SPARKFUN_BATTERY, rtcValues.other, rtcValues.battery); 140 | yield(); 141 | } 142 | rtcManagement.magicNumber = COLLECT; 143 | rtcManagement.valueCounter = 0; 144 | system_rtc_mem_write(64, &rtcManagement, 8); 145 | Serial.print("Writing to Cloud done. It took "); 146 | Serial.print(millis() - startTime) / 1000.0; 147 | Serial.println(" Seconds "); 148 | ESP.deepSleep(SLEEPTIME, WAKE_NO_RFCAL); 149 | } 150 | } 151 | 152 | 153 | void loop() {} 154 | 155 | -------------------------------------------------------------------------------- /ESPSensorHourlyEnhanced/Mail.ino: -------------------------------------------------------------------------------- 1 | 2 | char server[] = "mail.smtpcorp.com"; 3 | 4 | #define HEADER_WELCOME "ESP8266 System powered on" 5 | #define HEADER_ALARM "ESP8266 ALARM!" 6 | #define HEADER_LIVE "ESP8266 System is working ok" 7 | #define HEADER_LOW_BAT "ESP8266 System has low battery" 8 | 9 | #define MAIL_FROM "sensorsiot@gmail.com" 10 | #define MAIL_TO "andreas.spiess@arumba.com" 11 | 12 | 13 | // mail Types 14 | #define MAIL_NO_MAIL 0 15 | #define MAIL_WELCOME 1 // mail at startup 16 | #define MAIL_LIVE_SIGNAL 2 17 | #define MAIL_ALARM 3 18 | #define MAIL_LOW_BAT 4 19 | 20 | 21 | // my Chip IDs to give it a cleartype name 22 | #define WA1 14117293 23 | #define WA2 12612352 24 | 25 | 26 | bool sendEmail(byte MailType) 27 | { 28 | byte thisByte = 0; 29 | byte respCode; 30 | 31 | #ifdef DEBUG_NO_SEND 32 | if (MailType == MAIL_WELCOME) 33 | Serial.println(F(HEADER_WELCOME)); 34 | if (MailType == MAIL_ALARM) 35 | Serial.println(F(HEADER_ALARM)); 36 | if (MailType == MAIL_LIVE_SIGNAL) 37 | Serial.println(F(HEADER_LIVE)); 38 | if (MailType == MAIL_LOW_BAT) 39 | Serial.println(F(HEADER_LOW_BAT)); 40 | 41 | return true; 42 | #endif 43 | 44 | if (client.connect(server, 2525) == 1) { 45 | Serial.println(F("connected")); 46 | } else { 47 | Serial.println(F("connection failed")); 48 | return false; 49 | } 50 | if (!eRcv()) return false; 51 | 52 | Serial.println(F("Sending EHLO")); 53 | client.println("EHLO www.example.com"); 54 | if (!eRcv()) return false; 55 | Serial.println(F("Sending auth login")); 56 | client.println("auth login"); 57 | if (!eRcv()) return false; 58 | Serial.println(F("Sending User")); 59 | // Change to your base64, ASCII encoded user 60 | // client.println(MAIL_USER); 61 | client.println(SMTP2goUSER); //<---------User in base64 62 | if (!eRcv()) return false; 63 | Serial.println(F("Sending Password")); 64 | // change to your base64, ASCII encoded password 65 | // client.println(MAIL_PASS); 66 | client.println(SMTP2goPW);//<---------Password in base64 67 | if (!eRcv()) return false; 68 | Serial.println(F("Sending From")); 69 | // change to your email address (sender) 70 | client.print(F("MAIL From: ")); 71 | client.println(F(MAIL_FROM)); 72 | if (!eRcv()) return false; 73 | // change to recipient address 74 | Serial.println(F("Sending To")); 75 | client.print(F("RCPT To: ")); 76 | client.println(F(MAIL_TO)); 77 | if (!eRcv()) return false; 78 | Serial.println(F("Sending DATA")); 79 | client.println(F("DATA")); 80 | if (!eRcv()) return false; 81 | Serial.println(F("Sending email")); 82 | // change to recipient address 83 | client.print(F("To: ")); 84 | client.println(F(MAIL_TO)); 85 | // change to your address 86 | client.print(F("From: ")); 87 | client.println(F(MAIL_FROM)); 88 | client.print(F("Subject: ")); 89 | if (MailType == MAIL_WELCOME) 90 | client.println(F(HEADER_WELCOME)); 91 | if (MailType == MAIL_ALARM) 92 | client.println(F(HEADER_ALARM)); 93 | if (MailType == MAIL_LIVE_SIGNAL) 94 | client.println(F(HEADER_LIVE)); 95 | if (MailType == MAIL_LOW_BAT) 96 | client.println(F(HEADER_LOW_BAT)); 97 | 98 | client.println(F("This is from my ESP8266\n")); 99 | client.print(F("Power is: ")); 100 | client.print(float(ESP.getVcc() * VCC_ADJ)); 101 | client.println(F("mV")); 102 | int32 ChipID = ESP.getChipId(); 103 | if (ChipID == WA1) 104 | client.println("Device: Water-Alarm 1"); 105 | else if (ChipID == WA2) 106 | client.println("Device: Water-Alarm 2"); 107 | else 108 | { client.print(F("Device Chip ID: ")); 109 | client.println(ChipID); 110 | } 111 | 112 | 113 | client.println(F(".")); 114 | if (!eRcv()) return false; 115 | Serial.println(F("Sending QUIT")); 116 | client.println(F("QUIT")); 117 | if (!eRcv()) return false; 118 | client.stop(); 119 | Serial.println(F("disconnected")); 120 | return true; 121 | } 122 | 123 | byte eRcv() 124 | { 125 | byte respCode; 126 | byte thisByte; 127 | int loopCount = 0; 128 | 129 | while (!client.available()) { 130 | delay(1); 131 | loopCount++; 132 | // if nothing received for 10 seconds, timeout 133 | if (loopCount > 10000) { 134 | client.stop(); 135 | Serial.println(F("\r\nTimeout")); 136 | return false; 137 | } 138 | } 139 | 140 | respCode = client.peek(); 141 | while (client.available()) 142 | { 143 | thisByte = client.read(); 144 | Serial.write(thisByte); 145 | } 146 | 147 | if (respCode >= '4') 148 | { 149 | // efail(); 150 | return false; 151 | } 152 | return true; 153 | } 154 | -------------------------------------------------------------------------------- /ESPSensorHourlyEnhanced/Sparkfun.ino: -------------------------------------------------------------------------------- 1 | 2 | // my Chip IDs to give it a cleartype name 3 | #define WA1 14117293 4 | #define WA2 12612352 5 | 6 | 7 | bool sendSparkfun(byte sparkfunType, int value1, float value2) { 8 | 9 | // Use Sparkfun testing stream 10 | const char* host = "data.sparkfun.com"; 11 | const char* streamId = "q5Jpbl9jmpFYgLMr8zQv"; 12 | const char* privateKey = "BVBnz5ywgnSJpz68ek7r"; 13 | 14 | Serial.print("Connecting to "); Serial.print(host); 15 | 16 | int retries = 5; 17 | while (!client.connect(host, 80) && (retries-- > 0)) { 18 | Serial.print("."); 19 | } 20 | Serial.println(); 21 | if (!client.connected()) { 22 | Serial.println("Failed to connect, going back to sleep"); 23 | return false; 24 | } 25 | 26 | String url = "/input/"; 27 | url += streamId; 28 | url += "?private_key="; 29 | url += privateKey; 30 | url += "&counter="; 31 | url += value1; 32 | url += "&battery="; 33 | url += value2; // Could be any string 34 | 35 | Serial.println(); 36 | Serial.print("sparkfun: "); 37 | 38 | 39 | Serial.print("Request URL: "); Serial.println(url); 40 | 41 | client.print(String("GET ") + url + 42 | " HTTP/1.1\r\n" + 43 | "Host: " + host + "\r\n" + 44 | "Connection: close\r\n\r\n"); 45 | 46 | int timeout = 5 * 10; // 5 seconds 47 | while (!client.available() && (timeout-- > 0)) { 48 | delay(100); 49 | } 50 | 51 | if (!client.available()) { 52 | Serial.println("No response, going back to sleep"); 53 | return false; 54 | } 55 | Serial.println(F("disconnected")); 56 | return true; 57 | } 58 | -------------------------------------------------------------------------------- /ESPSensorHourlyEnhanced/ubidots.ino: -------------------------------------------------------------------------------- 1 | 2 | // Use Sparkfun testing stream 3 | 4 | 5 | 6 | // my Chip IDs to give it a cleartype name 7 | #define WA1 14117293 8 | #define WA2 12612352 9 | 10 | 11 | bool sendubidots(byte ubidotsType) { 12 | const char* host = "things.ubidots.com"; 13 | const char* streamId = ubidotsStreamId; 14 | const char* token = ubidotsToken; 15 | Serial.print("Connecting to "); Serial.print(host); 16 | 17 | WiFiClient client; 18 | int retries = 5; 19 | while (!client.connect(host, 80) && (retries-- > 0)) { 20 | Serial.print("."); 21 | } 22 | Serial.println(); 23 | if (!client.connected()) { 24 | Serial.println("Failed to connect, going back to sleep"); 25 | return false; 26 | } 27 | 28 | String url = "/api/v1.6/variables/"; 29 | url += streamId; 30 | 31 | 32 | Serial.println(); 33 | Serial.println("UBIDOTS: "); 34 | Serial.println(); 35 | 36 | String value = String(float(ESP.getVcc() * VCC_ADJ)); 37 | String valueStr = "{\"value\":" + value + '}'; 38 | 39 | String urlLoad = String("POST ") + url + 40 | "/values HTTP/1.1\r\n" + 41 | "X-Auth-Token: " + token + "\r\n" + 42 | "Host: " + host + "\r\n" + 43 | "Connection: close\r\n" + 44 | "Content-Type: application/json\r\n" + 45 | "Content-Length: " + valueStr.length() + "\r\n\r\n" + 46 | valueStr + "\r\n\r\n"; 47 | 48 | Serial.print(urlLoad); 49 | client.print(urlLoad); 50 | 51 | int timeout = 5 * 10; // 5 seconds 52 | while (!client.available() && (timeout-- > 0)) { 53 | delay(100); 54 | } 55 | 56 | if (!client.available()) { 57 | Serial.println("No response, going back to sleep"); 58 | return false; 59 | } 60 | Serial.println(F("disconnected")); 61 | return true; 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP8266-RTC-Memory 2 | How to use RTC memory. How to test it first, and then, use it to reduce power consumption by temporary storing sensor data in RTC memory 3 | Corresponding YouTube video https://youtu.be/r-hEOL007nw 4 | -------------------------------------------------------------------------------- /RTCmemTest/RTCmemTest.ino: -------------------------------------------------------------------------------- 1 | 2 | #define RTCMEMORYSTART 65 3 | #define RTCMEMORYLEN 127 4 | 5 | 6 | extern "C" { 7 | #include "user_interface.h" // this is for the RTC memory read/write functions 8 | } 9 | 10 | typedef struct { 11 | int battery; 12 | int other; 13 | } rtcStore; 14 | 15 | rtcStore rtcMem; 16 | 17 | int i; 18 | int buckets; 19 | bool toggleFlag; 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | Serial.println(); 24 | Serial.println("Start"); 25 | buckets = (sizeof(rtcMem) + 3) / 4; 26 | Serial.print("Buckets "); 27 | Serial.println(buckets); 28 | system_rtc_mem_read(64, &toggleFlag, 4); 29 | Serial.print("toggle Flag "); 30 | Serial.println(toggleFlag); 31 | if (toggleFlag) { 32 | Serial.println("Start Writing"); 33 | for (i = 0; i < RTCMEMORYLEN / buckets; i++) { 34 | rtcMem.battery = i; 35 | rtcMem.other = i * 11; 36 | int rtcPos = RTCMEMORYSTART + i * buckets; 37 | system_rtc_mem_write(rtcPos, &rtcMem, buckets * 4); 38 | toggleFlag = false; 39 | system_rtc_mem_write(64, &toggleFlag, 4); 40 | 41 | Serial.print("i: "); 42 | Serial.print(i); 43 | Serial.print(" Position: "); 44 | Serial.print(rtcPos); 45 | Serial.print(", battery: "); 46 | Serial.print(rtcMem.battery); 47 | Serial.print(", other: "); 48 | Serial.println(rtcMem.other); 49 | yield(); 50 | } 51 | Serial.println("Writing done"); 52 | } 53 | else { 54 | Serial.println("Start reading"); 55 | for (i = 0; i < RTCMEMORYLEN / buckets; i++) { 56 | int rtcPos = RTCMEMORYSTART + i * buckets; 57 | system_rtc_mem_read(rtcPos, &rtcMem, sizeof(rtcMem)); 58 | toggleFlag = true; 59 | system_rtc_mem_write(64, &toggleFlag, 4); 60 | 61 | Serial.print("i: "); 62 | Serial.print(i); 63 | Serial.print(" Position "); 64 | Serial.print(rtcPos); 65 | Serial.print(", battery: "); 66 | Serial.print(rtcMem.battery); 67 | Serial.print(", other: "); 68 | Serial.println(rtcMem.other); 69 | yield(); 70 | } 71 | Serial.println("reading done"); 72 | for (i = 0; i < RTCMEMORYLEN / buckets; i++) { 73 | rtcMem.battery = 0; 74 | rtcMem.other = 0; 75 | int rtcPos = RTCMEMORYSTART + i * buckets; 76 | system_rtc_mem_write(rtcPos, &rtcMem, buckets * 4); 77 | } 78 | } 79 | Serial.println("before sleep"); 80 | 81 | ESP.deepSleep(5000000, WAKE_RFCAL); 82 | } 83 | void loop() {} 84 | 85 | --------------------------------------------------------------------------------