Stap 7: Arduino IDE broncode voor het Project
Broncode voor de SolarPowerESP8266 Project
Hieronder vindt u de broncode voor de Arduino IDE ESP8266 pack. De Arduino IDE ESP8266 pack installeren Controleer deze post.
Vereiste bibliotheken:
aREST.h - https://github.com/marcoschwartz/aREST
SunAirPlus INA3221 Libraries - https://github.com/switchdoclabs/SDL_Arduino_INA3221
Zorg ervoor dat u in uw eigen waarden voor SSID en wachtwoord voor uw lokale toegangspunt:
SolarPowerESP8266.ino
/* SwitchDoc Labs Code for SolarPower ESP8266 Uses ESP8266 and SunAirPlus Dedember 2015 */ #pragma GCC diagnostic ignored "-Wwrite-strings" extern "C" { #include "user_interface.h" } #include #define DEBUG_MODE 1 #include #include // SunAirPlus Data Structures // Note: SunAirPlus uses a 3 channel current/voltage I2C chip - INA3221 to read all values - see github.com/switchdoclabs/SDL_Arduino_INA3221 // #include "SDL_Arduino_INA3221.h" // SAP INA3221 SDL_Arduino_INA3221 ina3221_SAP; // structure for one SAP ina3221 struct SAPData { float busVoltage[3]; float current[3]; float loadVoltage[3]; }; SAPData currentSAPData; // the three channels of the INA3221 named for SunAirPlus Solar Power Controller channels (www.switchdoc.com) #define SAP_LIPO_BATTERY_CHANNEL 0 #define SAP_SOLAR_CELL_CHANNEL 1 #define SAP_OUTPUT_CHANNEL 2 // SAP Buffer for sending readings to RaspberryPi struct SAPBufferStruct { unsigned long timeStamp; SAPData SAPEntry; }; #define SAPBUFFERSIZE 200 SAPBufferStruct SAPBuffer[SAPBUFFERSIZE]; int CurrentSAPBuffer; int lastReadSAPBuffer; #include "SAPData.h" //---------------------------------------------------------------------- //Local WiFi SunAirPlus const char* ssid = "YOURSSID"; const char* password = "YOURPASSWORD"; #define SOLARPOWERESP8266VERSION 004 //---------------------------------------------------------------------- int blinkPin = 0; // pin to blink led at each reading // The port to listen for incoming TCP connections #define LISTEN_PORT 80 // Create an instance of the server WiFiServer server(LISTEN_PORT); unsigned long oldReadSunAirPlusTime; unsigned long newReadSunAirPlusDeltaTime; int RestTimeStamp; String RestDataString; // Create aREST instance aREST rest = aREST(); // Custom function accessible by the API int ledControl(String command) { // Get state from command int state = command.toInt(); digitalWrite(0, state); return 1; } void setup() { pinMode(blinkPin, OUTPUT); // pin that will blink every reading digitalWrite(blinkPin, HIGH); // High of this pin is LED OFF // SAP initialization startSAPINA3221(); Serial.begin(115200); // we agree to talk fast! Serial.println("----------------"); Serial.println("SolarPower ESP8266"); Serial.println("----------------"); RestTimeStamp = 0; RestDataString = ""; rest.variable("RestTimeStamp", &RestTimeStamp); rest.variable("RestDataString", &RestDataString); // Function to be exposed rest.function("led", ledControl); // Give name and ID to device rest.set_id("1"); rest.set_name("SolarPowerESP8266"); Serial.print("Connecting to "); Serial.print(ssid); if (strcmp (WiFi.SSID().c_str(), ssid) != 0) { WiFi.begin(ssid, password); } while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Local WiFi connected, IP address: "); Serial.println(WiFi.localIP()); // Start the server server.begin(); Serial.println("Server started"); oldReadSunAirPlusTime = micros(); initSAPBuffer(); } int sampleCount = 0; // Loop through reading current and solar performance void loop() { // Handle REST calls WiFiClient client = server.available(); if (client) { while (!client.available()) { delay(1); } if (client.available()) { Serial.print("Buffer Count="); Serial.println(returnCountSAPBuffer()); RestTimeStamp = millis(); //printDebugFullSAPBuffer(); RestDataString = assembleSAPBuffer(); rest.handle(client); } } newReadSunAirPlusDeltaTime = micros() - oldReadSunAirPlusTime; // doing this handles the 71 second rollover because of unsighned arithmetic if (newReadSunAirPlusDeltaTime > 1000000) // check for 1 second work to be done { Serial.print("Free heap on ESP8266:"); Serial.println(ESP.getFreeHeap(), DEC); digitalWrite(blinkPin, LOW); // High of this pin is LED ON Serial.println(); readSAP(); writeSAPBuffer(); digitalWrite(blinkPin, HIGH); // High of this pin is LED OFF oldReadSunAirPlusTime = micros(); //printDebugFullSAPBuffer(); } yield(); // take a break - you must do this for the ESP8266 to work correctly in all cases! }
Het bestand SAPData.h
// SAP Buffer Routines void initSAPBuffer() { CurrentSAPBuffer = -1; lastReadSAPBuffer = -1; int i; for (i = 0; i < SAPBUFFERSIZE; i++) { SAPBuffer[i].timeStamp = 0; } } void writeSAPBuffer() { //Serial.print("Entry WriteSAPBuffer C / R "); //Serial.print(CurrentSAPBuffer); //Serial.print(" / "); //Serial.println(lastReadSAPBuffer); CurrentSAPBuffer++; if (CurrentSAPBuffer >= SAPBUFFERSIZE) // wrap around { CurrentSAPBuffer = 0; } SAPBuffer[CurrentSAPBuffer].timeStamp = millis(); SAPBuffer[CurrentSAPBuffer].SAPEntry = currentSAPData; //Serial.print("Exit WriteSAPBuffer C / R "); //Serial.print(CurrentSAPBuffer); //Serial.print(" / "); //Serial.println(lastReadSAPBuffer); } int returnCountSAPBuffer() { int i; int count = 0; for (i = 0; i < SAPBUFFERSIZE; i++) { if (SAPBuffer[i].timeStamp > 0) count++; } return count; } int readSAPBuffer(SAPBufferStruct *mySAPBuffer) { //Serial.print("inReadSAPBuffer C / R "); //Serial.print(CurrentSAPBuffer); //Serial.print(" / "); //Serial.println(lastReadSAPBuffer); // read out all data, doesn't matter the order. The SQL Databoase on the Pi will figure it out... if (lastReadSAPBuffer == -1 ) // deal with first read no matter how long ago { // scan Buffer for smallest > 0 timeStamp - set to lastReadSAPBuffer int i; int smallestTimeStamp = 4294967295; // 2^32-1 int smallestIndex = 0; for (i = 0; i < SAPBUFFERSIZE; i++) { if (SAPBuffer[i].timeStamp != 0) { if (SAPBuffer[i].timeStamp < smallestTimeStamp) { smallestTimeStamp = SAPBuffer[i].timeStamp; smallestIndex = i; } } } lastReadSAPBuffer = smallestIndex; } if (SAPBuffer[lastReadSAPBuffer].timeStamp == 0) { return -1; } *mySAPBuffer = SAPBuffer[lastReadSAPBuffer]; SAPBuffer[lastReadSAPBuffer].timeStamp = 0; lastReadSAPBuffer++; if (lastReadSAPBuffer >= SAPBUFFERSIZE) { lastReadSAPBuffer = 0; } } String assembleSAPBuffer() { int status; SAPBufferStruct mySAPBuffer; String returnString; returnString = ""; returnString = String(ESP.getFreeHeap()); status = readSAPBuffer(&mySAPBuffer); while (status != -1) { if (returnString.length() != 0) { returnString += " | "; } String sensorBuild; sensorBuild = String(mySAPBuffer.timeStamp) + ","; int i; for (i = 0; i < 3; i++) { sensorBuild += String(mySAPBuffer.SAPEntry.busVoltage[i], 2) + ","; sensorBuild += String(mySAPBuffer.SAPEntry.loadVoltage[i], 2) + ","; if (i < 2) sensorBuild += String(mySAPBuffer.SAPEntry.current[i], 2) + ","; else sensorBuild += String(mySAPBuffer.SAPEntry.current[i], 2) ; //Serial.print("sensorBuild="); //Serial.println(sensorBuild); } returnString += sensorBuild; status = readSAPBuffer(&mySAPBuffer); } return returnString; } void printDebugFullSAPBuffer() { Serial.print("DebugFullSAPBuffer State C / R "); Serial.print(CurrentSAPBuffer); Serial.print(" / "); Serial.println(lastReadSAPBuffer); int i; for (i = 0; i < SAPBUFFERSIZE; i++) { Serial.print("index:"); Serial.print(i); Serial.print(" timeStamp = "); Serial.print(SAPBuffer[i].timeStamp); if (SAPBuffer[i].timeStamp == 0) { Serial.println(" SAPEntry = null"); } else { Serial.println(" SAPEntry = Full"); /* SAPData currentSAPData; currentSAPData = SAPBuffer[i].SAPEntry; Serial.println("--------SAP ENTRY-------"); Serial.print("LIPO_Battery Current: "); Serial.print(currentSAPData.current[0]); Serial.println(" mA"); Serial.print("Solar Cell Bus Voltage: "); Serial.print(currentSAPData.busVoltage[1]); Serial.println(" V"); Serial.print("Output Bus Current: "); Serial.print(currentSAPData.current[2]); Serial.println(" mA"); */ } } } // Read data from specific SunAirPlus unit (SAP0 - SAP2) void startSAPINA3221() { ina3221_SAP.begin(); // SAP } void readSAP() { int i; for (i = 0; i < 3; i++) { currentSAPData.busVoltage[i] = 0.0f; currentSAPData.current[i] = 0.0f; currentSAPData.loadVoltage[i] = 0.0f; } currentSAPData.busVoltage[0] = ina3221_SAP.getBusVoltage_V(SAP_LIPO_BATTERY_CHANNEL + 1); currentSAPData.current[0] = ina3221_SAP.getCurrent_mA(SAP_LIPO_BATTERY_CHANNEL + 1); // minus is to get the "sense" right. - means the battery is charging, + that it is discharging currentSAPData.loadVoltage[0] = currentSAPData.busVoltage[0] + (ina3221_SAP.getShuntVoltage_mV(SAP_LIPO_BATTERY_CHANNEL + 1) / 1000); currentSAPData.busVoltage[1] = ina3221_SAP.getBusVoltage_V(SAP_SOLAR_CELL_CHANNEL + 1); currentSAPData.current[1] = - ina3221_SAP.getCurrent_mA(SAP_SOLAR_CELL_CHANNEL + 1); // minus is to get the "sense" right. - means the battery is charging, + that it is discharging currentSAPData.loadVoltage[1] = currentSAPData.busVoltage[1] + (ina3221_SAP.getShuntVoltage_mV(SAP_SOLAR_CELL_CHANNEL + 1) / 1000); currentSAPData.busVoltage[2] = ina3221_SAP.getBusVoltage_V(SAP_OUTPUT_CHANNEL + 1); currentSAPData.current[2] = ina3221_SAP.getCurrent_mA(SAP_OUTPUT_CHANNEL + 1); // minus is to get the "sense" right. - means the battery is charging, + that it is discharging currentSAPData.loadVoltage[2] = currentSAPData.busVoltage[2] + (ina3221_SAP.getShuntVoltage_mV(SAP_OUTPUT_CHANNEL + 1) / 1000); Serial.println("--------SAP Data-------"); Serial.print("LIPO_Battery Bus Voltage: "); Serial.print(currentSAPData.busVoltage[0]); Serial.println(" V"); Serial.print("LIPO_Battery Load Voltage: "); Serial.print(currentSAPData.loadVoltage[0]); Serial.println(" V"); Serial.print("LIPO_Battery Current: "); Serial.print(currentSAPData.current[0]); Serial.println(" mA"); Serial.println(""); Serial.print("Solar Cell Bus Voltage: "); Serial.print(currentSAPData.busVoltage[1]); Serial.println(" V"); Serial.print("Solar Cell Load Voltage: "); Serial.print(currentSAPData.loadVoltage[1]); Serial.println(" V"); Serial.print("Solar Cell Current: "); Serial.print(currentSAPData.current[1]); Serial.println(" mA"); Serial.println(""); Serial.print("Output Bus Bus Voltage: "); Serial.print(currentSAPData.busVoltage[2]); Serial.println(" V"); Serial.print("Output Bus Load Voltage: "); Serial.print(currentSAPData.loadVoltage[2]); Serial.println(" V"); Serial.print("Output Bus Current: "); Serial.print(currentSAPData.current[2]); Serial.println(" mA"); Serial.println(""); Serial.println("--------"); return; }