A solar-powered ESP8266 WiFi module joins the IoT
Source Code
Source code for the Arduino IDE version of the SolarPowerESP8266 system is shown in Listing 7 and is available on the SwitchDoc Labs GitHub page [10]. Make sure you put in your own SSID and PASSWORD values for your local access point. Additionally, you will need aREST, the REST library for the ESP8266 [11], and the SunAirPlus INA3221 libraries, which are the C libraries for reading current/voltage on the SunAirPlus [12].
Listing 7
SolarPowerESP8266.ino
001 /* 002 SwitchDoc Labs Code for SolarPower ESP8266 003 004 Uses ESP8266 and SunAirPlus 005 006 Dedember 2015 007 008 */ 009 010 #pragma GCC diagnostic ignored "-Wwrite-strings" 011 012 extern "C" { 013 #include "user_interface.h" 014 } 015 #include <ESP8266WiFi.h> 016 017 #define DEBUG_MODE 1 018 019 #include <aREST.h> 020 021 #include <String.h> 022 023 024 // SunAirPlus Data Structures 025 // Note: SunAirPlus uses a 3 channel current/voltage I2C chip - INA3221 to read all values - see github.com/switchdoclabs/SDL_Arduino_INA3221 026 // 027 028 #include "SDL_Arduino_INA3221.h" 029 030 // SAP INA3221 031 SDL_Arduino_INA3221 ina3221_SAP; 032 033 034 // structure for one SAP ina3221 035 struct SAPData 036 { 037 038 float busVoltage[3]; 039 float current[3]; 040 float loadVoltage[3]; 041 042 }; 043 044 045 SAPData currentSAPData; 046 047 // the three channels of the INA3221 named for SunAirPlus Solar Power Controller channels (www.switchdoc.com) 048 #define SAP_LIPO_BATTERY_CHANNEL 0 049 #define SAP_SOLAR_CELL_CHANNEL 1 050 #define SAP_OUTPUT_CHANNEL 2 051 052 // SAP Buffer for sending readings to RaspberryPi 053 054 struct SAPBufferStruct 055 { 056 057 unsigned long timeStamp; 058 SAPData SAPEntry; 059 060 061 }; 062 063 #define SAPBUFFERSIZE 20 064 065 SAPBufferStruct SAPBuffer[SAPBUFFERSIZE]; 066 067 int CurrentSAPBuffer; 068 069 int lastReadSAPBuffer; 070 071 #include "SAPData.h" 072 073 074 //------------------------------------------------------- 075 //Local WiFi SunAirPlus 076 077 const char* ssid = "gracie"; 078 const char* password = "faraday01"; 079 080 #define SOLARPOWERESP8266VERSION "005" 081 082 083 //------------------------------------------------------- 084 085 086 int blinkPin = 0; // pin to blink led at each reading 087 088 089 090 // The port to listen for incoming TCP connections 091 #define LISTEN_PORT 80 092 093 // Create an instance of the server 094 WiFiServer server(LISTEN_PORT); 095 096 unsigned long oldReadSunAirPlusTime; 097 unsigned long newReadSunAirPlusDeltaTime; 098 099 int RestTimeStamp; 100 String RestDataString; 101 String Version; 102 103 104 // Create aREST instance 105 aREST rest = aREST(); 106 107 // Custom function accessible by the API 108 int ledControl(String command) { 109 110 // Get state from command 111 int state = command.toInt(); 112 113 digitalWrite(0, state); 114 return 1; 115 } 116 117 void setup() { 118 119 120 pinMode(blinkPin, OUTPUT); // pin that will blink every reading 121 digitalWrite(blinkPin, HIGH); // High of this pin is LED OFF 122 123 // SAP initialization 124 125 startSAPINA3221(); 126 127 Serial.begin(115200); // we agree to talk fast! 128 129 130 Serial.println("----------------"); 131 Serial.println("SolarPower ESP8266"); 132 Serial.println("----------------"); 133 134 135 136 RestTimeStamp = 0; 137 RestDataString = ""; 138 Version = SOLARPOWERESP8266VERSION; 139 140 141 rest.variable("RestTimeStamp", &RestTimeStamp); 142 rest.variable("RestDataString", &RestDataString); 143 rest.variable("FirmwareVersion", &Version); 144 145 146 // Function to be exposed 147 rest.function("led", ledControl); 148 149 // Give name and ID to device 150 rest.set_id("1"); 151 rest.set_name("SolarPowerESP8266"); 152 153 154 Serial.print("Connecting to "); 155 Serial.print(ssid); 156 if (strcmp (WiFi.SSID().c_str(), ssid) != 0) { 157 WiFi.begin(ssid, password); 158 } 159 while (WiFi.status() != WL_CONNECTED) { 160 delay(500); 161 Serial.print("."); 162 } 163 Serial.println(""); 164 165 Serial.print("Local WiFi connected, IP address: "); 166 Serial.println(WiFi.localIP()); 167 168 // Start the server 169 server.begin(); 170 Serial.println("Server started"); 171 172 oldReadSunAirPlusTime = micros(); 173 174 initSAPBuffer(); 175 176 177 } 178 179 int sampleCount = 0; 180 181 // Loop through reading current and solar performance 182 183 void loop() { 184 185 186 // Handle REST calls 187 WiFiClient client = server.available(); 188 if (client) 189 { 190 191 while (!client.available()) { 192 delay(1); 193 } 194 if (client.available()) 195 { 196 Serial.print("Buffer Count="); 197 Serial.println(returnCountSAPBuffer()); 198 RestTimeStamp = millis(); 199 //printDebugFullSAPBuffer(); 200 RestDataString = assembleSAPBuffer(); 201 rest.handle(client); 202 203 } 204 } 205 206 newReadSunAirPlusDeltaTime = micros() - oldReadSunAirPlusTime; // doing this handles the 71 second rollover because of unsighned arithmetic 207 208 209 if (newReadSunAirPlusDeltaTime > 30000000) // check for 30 second work to be done 210 { 211 212 Serial.print("Free heap on ESP8266:"); 213 Serial.println(ESP.getFreeHeap(), DEC); 214 215 digitalWrite(blinkPin, LOW); // High of this pin is LED ON 216 Serial.println(); 217 readSAP(); 218 writeSAPBuffer(); 219 220 digitalWrite(blinkPin, HIGH); // High of this pin is LED OFF 221 222 oldReadSunAirPlusTime = micros(); 223 224 225 //printDebugFullSAPBuffer(); 226 } 227 228 229 yield(); // take a break 230 }
Conclusion
The ESP8266 would be effective in many applications, and now that you can power it with the sun, you can explore many more possibilities (e.g., building a weather station). On the SwitchDoc Labs blog [13], the software reads data from the ESP8266 via a REST interface and then writes it into a MySQL database. I am also using MatPlotLib to visualize the data. Check out the previous SwitchDoc Labs column on using MatPlotLib to build graphs on the Raspberry Pi [14].
« Previous 1 2 3 4 Next »
Buy this article as PDF
Pages: 8
(incl. VAT)