John R McAlpine V Mac
Published © CC BY-NC-SA

Wind Wizard

IOT wind generator monitoring with real time logging and display on a Wink Nimbus gauge cluster.

BeginnerFull instructions provided6 hours1,438
Wind Wizard

Things used in this project

Hardware components

Photon
Particle Photon
×1
Control Everything 2x15A Particle Photon Shield
×1
Wink Nimbus
×1

Software apps and online services

Maker service
IFTTT Maker service
atomiot.com

Story

Read more

Schematics

Control Everything current measurement

Plug and play.. It couldn't get any easier.

Code

Dad's wind power meter

Arduino
// This #include statement was automatically added by the Particle IDE.
#include "elapsedMillis/elapsedMillis.h"

// This #include statement was automatically added by the Particle IDE.
#include "Current_Monitor/Current_Monitor.h"

CurrentMonitor current;

//cloud variables
double currentReading;
double kwh;
double dollars;
int firmware;
int maxCurrent;
int numberOfChannels;
int sensorType;
double ACVoltageD;

//local variables
float ACVoltage = 120.00;
unsigned long upTime = 0;
unsigned long lastReadTime;
int acVoltageStorageIndex = 0;
int kwhStorageStartIndex = 4;
int tripLimitIndex = 12;
double tripLimit = 100.00;
double lastReading = 0;
int rssival = 0;
double c = 0;
double wattage = 0;
double maxwattage = 0;

unsigned int interval = 50;
unsigned int particleinterval = 5000;
unsigned int particlefuncinterval = 10000;
unsigned long int telltaleinterval = 60000;


elapsedMillis timeElapsed; //declare global if you don't want it reset every time loop runs
elapsedMillis timeElapsed2; //declare global if you don't want it reset every time loop runs
elapsedMillis timeElapsed3;
elapsedMillis timeElapsed4;


//Cloud Functions
int setACVoltagte(String voltage);
int clearKWH(String channel);
int setTripLimit(String limit);
char publishString[40];

void setup() {
    pinMode(D7, OUTPUT);
    Serial.begin(230400);
    if(!current.initialize(0,0,0,0)){
        Serial.println("Initialize failed");
    }
    firmware = current.firmwareVersion;
    maxCurrent = current.maxCurrent;
    numberOfChannels = current.numberOfChannels;
    sensorType = current.sensorType;
    ACVoltageD = (double)ACVoltage;
    Serial.println(ACVoltageD);
    getInfoFromStorage();
    Particle.variable("Firmware", firmware);
    Particle.variable("Max_Current", maxCurrent);
    Particle.variable("Sensor_type", sensorType);
    Particle.variable("Channels", numberOfChannels);
    Particle.variable("Current", currentReading);
    Particle.variable("KWH_Readings", kwh);
    Particle.variable("ACVoltage", ACVoltageD);
    Particle.variable("Dollars", dollars);
    Particle.variable("Watts", wattage);
    Particle.variable("MaxWatts", maxwattage);
    Particle.function("SetACVoltage", setACVoltagte);
    Particle.function("ClearKWHs", clearKWH);
    Particle.function("Trip", setTripLimit);
    
    WiFi.selectAntenna(ANT_AUTO);
    //WiFi.selectAntenna(ANT_INTERNAL);
    //WiFi.selectAntenna(ANT_EXTERNAL);

}

void loop() {
    digitalWrite(D7,!digitalRead(D7));
    
    if(current.deviceStatusReady){
        //while(current.deviceStatusReady){
            //Read current on channel 1
            double c = current.readChannelCurrent(1);
            if(c != current.failedCommand){
                //Publish most recent current reading
                currentReading = c;
                if(currentReading > tripLimit && lastReading < currentReading){
                    Particle.publish("Tripped", "light_on", 60, PRIVATE);
                }
                lastReading = currentReading;
                // Calculate Kilowatt hours
                // Calculate Wattage
                wattage = currentReading*ACVoltage;
                maxwattage = max(wattage, maxwattage);
                Serial.println(wattage);
                //Calculate hours
                upTime = millis();
                double hours = (upTime - lastReadTime)/ (60.00 * 60.00 * 1000.00);
                lastReadTime = millis();
                //Calculate Kilowatt hours
                kwh = kwh + ((wattage * hours)/1000);
                //Store kwh in eeprom so we do not loose it on power loss.
                //EEPROM.put(kwhStorageStartIndex, kwh);
                Serial.println("Reading in while loop");
            }else{
                Serial.println("Reading of current failed");
            //}
            //We read current on the circuit once per second.
            //delay(1000);
        }
    }else{
        Serial.println("Device not ready");
        delay(1000);
    }

        delay(100);
        if (timeElapsed2> particleinterval) //Run code every x seconds
        {
            timeElapsed2 = 0; //reset interval timer
        
            sprintf(publishString, "%.2f", currentReading);
            Particle.publish("Current", publishString);
            sprintf(publishString, "%.1f", wattage);
            Particle.publish("Watts", publishString);
        }
        
        if (timeElapsed3> particlefuncinterval) //Run code every 10 seconds
            {
                rssival = WiFi.RSSI();
                sprintf(publishString,"%d",rssival);
                Particle.publish("RSSI",publishString);
                timeElapsed3 = 0; //reset interval timer
        }
        
        if (timeElapsed4> telltaleinterval) 
            {
                sprintf(publishString,"%.1f",maxwattage);
                Particle.publish("Maxwattage",publishString);
                maxwattage = 0;
                
                sprintf(publishString,"%3.3f",kwh);
                Particle.publish("Kwh",publishString);
                timeElapsed4 = 0; //reset interval timer
                
                dollars = kwh * .102;
                sprintf(publishString,"%3.3f",dollars);
                Particle.publish("Dollars",publishString);
                timeElapsed4 = 0; //reset interval timer
                EEPROM.put(kwhStorageStartIndex, kwh);

        }
}

int setACVoltagte(String voltage){
    ACVoltage = voltage.toFloat();
    ACVoltageD = (double)ACVoltage;
    EEPROM.put(acVoltageStorageIndex, ACVoltage);
    return 1;
}

int clearKWH(String channelNumber){
    kwh = 0.00;
    EEPROM.put(kwhStorageStartIndex, kwh);
    return 1;
    
}

int setTripLimit(String limit){
    float trip = limit.toFloat();
    tripLimit = (double)trip;
    EEPROM.put(tripLimitIndex, tripLimit);
    
}

void getInfoFromStorage(){
    float tACVoltage;
    EEPROM.get(acVoltageStorageIndex, tACVoltage);
    String emptyCheck = String(tACVoltage);
    if(emptyCheck.equalsIgnoreCase("0.000000")){
        Serial.println("No ACVoltage reading stored");
    }else{
        ACVoltage = tACVoltage;
        ACVoltageD = (double)ACVoltage;
    }

    double tKWHReading;
    EEPROM.get(kwhStorageStartIndex, tKWHReading);
    String eCheck = String(tKWHReading);
    if(eCheck.equalsIgnoreCase("0.000000")){
        Serial.println("No Stored kWH readings for channel 1 \n");
    }else{
        Serial.printf("%.4f stored for Channel %i \n", tKWHReading, 1);
        kwh = tKWHReading;
    }
    
    double tTripLimit;
    EEPROM.get(tripLimitIndex, tTripLimit);
    String eCheck1 = String(tTripLimit);
    if(eCheck1.equalsIgnoreCase("0.000000")){
        Serial.println("No Stored trip limit for channel 1 \n");
    }else{
        Serial.printf("%.4f stored for Channel %i trip limit \n", tTripLimit, 1);
        tripLimit = tTripLimit;
    }
}

Credits

John R McAlpine V Mac

John R McAlpine V Mac

17 projects • 87 followers
www.MACSBOOST.com Assistant Teaching Professor at UNC Charlotte MEGR3171 Instrumentation, Motorsports Research

Comments