Problem with arduino and cayenne button


#1

hi all,

so having an issue, my last part of the attached is to receive a button press in cayenne, and reset the months kwh counter…

the counter resets when the button is on, but when i turn the button off again, the counter never starts up again

any help would be amazing… pretty new to all this

#include <Wire.h>

#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon1;                   // Create an instance

#include <time.h>
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <OneWire.h>
#include <DallasTemperature.h>
#define CAYENNE_DEBUG
// If you're not using the Ethernet W5100 shield, change this to match your connection type. See Communications examples.
#include <CayenneEthernetW5500.h>

// Virtual Pin of the DS18B20 widget.
#define VIRTUAL_PIN V1
#define VIRTUAL_RESETPIN V15
// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "";


#include "DHT.h"

#define DHTPIN 39 

#define DHTTYPE DHT11   // DHT 11

DHT dht(DHTPIN, DHTTYPE);


// Kwh variables
int watts = 0;
int kwhCount = 0;
//int runningCount = 0;
//float runningTotal;
float dayKwh = 0.0;
float dayKwhAccrue = 0;
float cumulativeKwh = 0.0;
unsigned long kwhTime = 0;
float countKwhNow = true;
float cumulativeKwhTotal;

// time variables
//const int timezone = -5;  // hours
//const int dst = 0;
byte timeHour;
byte timeMin;


float humidity;
float airtemp;
//float heatindex;
float airtempoff = 3;

double Irms;
float Voltage = 238.0;

#include <DS3231.h>
Time  t;

#include <OneWire.h>

#include <DallasTemperature.h>

// Include the libraries we need

// include the library code:
#include <LiquidCrystal.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 22

DS3231  rtc(SDA, SCL);

// EEPRROM PUT STUFF

#include <EEPROM.h>
int MinAddress = 1;
int MaxAddress = 100;

const int eepromAddress = 200;
const int eepromAddress1 = 201;
const int eepromAddressLastMonth = 202;
float eeprommaxdisplay;
float eeprommindisplay;


long previousLCDMillis = 0;    // for LCD screen update
long lcdInterval = 5000;

// screen to show
int screen = 0;   
int screenMax = 4;
bool screenChanged = true;   // initially we have a new screen,  by definition
// defines of the screens to show
#define TEMPERATURE 0
#define MINMAXTEMP  1
#define TIME  2
#define POWER  3
#define POWERNOW  4



int ledState = LOW;

unsigned long previousMillis = 0; 
const long interval = 1000;

unsigned long currentMillis = 0;

const int switch1 = 31;
const int topupLED = 42;
//8const int switch2s = 21;
//int ResetState = LOW;
//const int ResetPin = 21;

float temp;

float temp2;

int topupval;

float tempoffset = 0;

float maxtemp = 0;
float mintemp = 100;
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 36, en = 37, d4 = 32, d5 = 33, d6 = 34, d7 = 35;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

/*
 * The setup function. We only start the sensors here
 */



//////////////////////////////////////
//
// display functions
//
void showWelcome()
{
  lcd.clear();
  lcd.setCursor(0, 0);           
  lcd.print("Tank Monitor V1.1");
  lcd.setCursor(0, 1);         
  lcd.print("initialising...");     
}

void showTemperature(int T)
{
lcd.clear();
  lcd.setCursor(0, 0);           
  lcd.print("W:");          
  lcd.print(temp,1);       
  lcd.print("c ");
  lcd.print("A:");
  lcd.print(airtemp,1);
  lcd.print("c");
    lcd.setCursor(0, 1);
     lcd.print("Humidity: ");          
  lcd.print(humidity,0);
    lcd.print("%");
}

void showMaxMinTemp(int MMT)
{

//  lcd.setCursor(0, 0);           
//  lcd.print("Min:");
//  lcd.print(mintemp,1);
//  lcd.print("Max:");
//  lcd.print(maxtemp,1);

lcd.clear();
  lcd.setCursor(0, 0);           
  lcd.print("Water Min:");
  EEPROM.get(MinAddress, eeprommindisplay);
  lcd.print(eeprommindisplay,1);
  lcd.print("c");

  lcd.setCursor(0, 1);  
  lcd.print("Water Max:");

    EEPROM.get(MaxAddress, eeprommaxdisplay);
  lcd.print(eeprommaxdisplay,1);
  lcd.print("c");
}

void showTime(int ST)
{


lcd.clear();
  lcd.setCursor(0, 0); 

   t = rtc.getTime();
lcd.print("      ");
  lcd.print(t.hour, DEC);
  lcd.print(":");
  lcd.print(t.min, DEC);
  lcd.print("  ");
  lcd.setCursor(0, 1); 
  lcd.print("   ");
  lcd.print(rtc.getDateStr());
            
//  lcd.print(rtc.getTimeStr());
//  lcd.print("-");
//  lcd.print(rtc.getDateStr());


}


void showPower(int SPP)
{


lcd.clear();
  lcd.setCursor(0, 0); 
  lcd.print("Month: ");
//EEPROM.get(eepromAddress, cumulativeKwhTotal);
  lcd.print(cumulativeKwhTotal);
 lcd.setCursor(0, 1); 

lcd.print("Dkwh: ");

lcd.print(dayKwh);



            
//  lcd.print(rtc.getTimeStr());
//  lcd.print("-");
//  lcd.print(rtc.getDateStr());


}

void showNowPower(int NP)
{


lcd.clear();
  lcd.setCursor(0, 0); 
  lcd.print("Watts:");
  lcd.print(Irms*Voltage);
 lcd.setCursor(0, 1); 

lcd.print("Amps:");

lcd.print(Irms);



            
//  lcd.print(rtc.getTimeStr());
//  lcd.print("-");
//  lcd.print(rtc.getDateStr());


}

 
void setup(void)
{
  // start serial port

    Serial.begin(9600);

// pinMode(ResetPin, INPUT);
 emon1.current(A15, 30.7);             // Current: input pin, calibration.


    
    lcd.begin(16, 2);
   lcd.clear();
  lcd.setCursor(0, 0);           
  lcd.print("Cayenne try to");
    lcd.setCursor(0, 1);           
  lcd.print("Connect");

Cayenne.begin(token);

  Serial.println("Dallas Temperature IC Control Library Demo");
  pinMode(switch1, INPUT_PULLUP);
  pinMode(topupLED, OUTPUT);
  // Start up the library
  sensors.begin();
  sensors.setResolution(11);
dht.begin();
  // Initialize the rtc object
  rtc.begin();
  
  // The following lines can be uncommented to set the date and time
//  rtc.setDOW(FRIDAY);     // Set Day-of-Week to SUNDAY
//  rtc.setTime(22, 07, 0);     // Set the time to 12:00:00 (24hr format)
//  rtc.setDate(9, 2, 2018);   // Set the date to January 1st, 2014
              
EEPROM.get(MaxAddress, eeprommaxdisplay);
EEPROM.get(MinAddress, eeprommindisplay);
if (eeprommindisplay == 0)
{
  eeprommindisplay = 100;
}

EEPROM.put(MaxAddress, eeprommaxdisplay);
  EEPROM.put(MinAddress, eeprommindisplay);
  // set up the LCD's number of columns and rows:

  cumulativeKwhTotal = EEPROM.read(eepromAddress);

getthetemp();
  showWelcome();
 
 // delay(2000);   


}

/*
 * Main function, get and show the temperature
 */

//CAYENNE_IN(VIRTUAL_RESETPIN)
//{
//  // get value sent from dashboard
//  int currentValue = getValue.asInt(); // 0 to 1
//
//  // assuming you wire your relay as normally open
//  if (currentValue == 0) {
//    Serial.println("HIGH");
//  } else {
//     Serial.println("LOW");
//       Cayenne.virtualWrite(21, 0);
//  }
//}

 
void loop()
{ 

 Cayenne.run();  
Irms = emon1.calcIrms(1480);
//
//if  (topupval == HIGH)
//{
// unsigned long currentMillis = millis();
//
//  if (currentMillis - previousMillis >= interval) {
//    // save the last time you blinked the LED
//    previousMillis = currentMillis;
//
//    // if the LED is off turn it on and vice-versa:
//    if (ledState == LOW) {
//      ledState = HIGH;
//    } else {
//      ledState = LOW;
//    }
//
//    // set the LED with the ledState of the variable:
//    digitalWrite(topupLED, ledState);
//
//  }
//
//else
//{
//ledState = LOW;
// digitalWrite(topupLED, ledState);
//
//}
//}

  if (millis() - kwhTime > 5000)
    {
      getKwh();
      kwhTime = millis();

      refreshTime();
    }
screenloop();
getthetemp();


//Serial.println("---------");
//Serial.println(Irms*Voltage);
//Serial.println("---------");
//Serial.println(Irms);
//Serial.println("---------");

//
//Serial.println("---------CUMALITVIE TOTAL --------");
//Serial.println(cumulativeKwhTotal);
//Serial.println("--------- cumulativeKwh");
//Serial.println(cumulativeKwh);
//Serial.println("--------- ");
//Serial.println("--------- kwhCount");
//Serial.println(kwhCount);
//Serial.println("--------- ");
//Serial.println("--------- dayKwhAccrue");
//Serial.println(dayKwhAccrue);
//Serial.println("--------- ");


//lcd.setCursor(0,0);
//lcd.print("Now:");
//lcd.print((temp)+(tempoffset),1);
//lcd.print(" ");
//lcd.print(" ");
//lcd.print((maxtemp + tempoffset),1);
//lcd.setCursor(0,1);
//topuploopsingle();



  
}

void getthetemp()
{

   // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
 // Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
 // Serial.println("DONE");
  // After we got the temperatures, we can print them here.
  // We use the function ByIndex, and as an example get the temperature from the first sensor only.
  //Serial.print("Temperature for the device 1 (index 0) is: ");
 // Serial.println(sensors.getTempCByIndex(0)); 
  temp =  (sensors.getTempCByIndex(0));
  temp2 = (sensors.getTempCByIndex(0) + tempoffset);


EEPROM.get(MaxAddress, eeprommaxdisplay);


  if (temp2 > eeprommaxdisplay)
  {
    eeprommaxdisplay = temp2;
  }



EEPROM.put(MaxAddress, eeprommaxdisplay);


EEPROM.get(MinAddress, eeprommindisplay);
  
if (temp2 < eeprommindisplay)
{
  eeprommindisplay = temp2;
}


EEPROM.put(MinAddress, eeprommindisplay);


    
  }




//void topuploop()
//
//{
//
//  if ((switch1 == 100) && (switch2 == 100))
//  {
//  lcd.setCursor(9,1);
//  lcd.print("ADD RO");
//  }
//    else if ((switch1 == 100) && (switch2 == 0))
//    {
//    lcd.setCursor(9,1);
//    lcd.print(" FAULT      ");
//    }
//          else if ((switch1 == 0) && (switch2 == 100))
//      {
//      lcd.setCursor(9,1);
//      lcd.print(" FAULT   ");
//    }
//              else 
//      
//      lcd.setCursor(9,1);
//      lcd.print(" ALL GOOD     ");
//    
//}

//
//void blinkled()
//{
//    unsigned long currentMillis = millis();
//
//  if (currentMillis - previousMillis >= interval) {
//    // save the last time you blinked the LED
//    previousMillis = currentMillis;
//
//    // if the LED is off turn it on and vice-versa:
//    if (ledState == LOW) {
//      ledState = HIGH;
//    } else {
//      ledState = LOW;
//    }
//
//    // set the LED with the ledState of the variable:
//    digitalWrite(topupLED, ledState);
//  }
//}






void screenloop()
{
  unsigned long currentLCDMillis = millis();

  // MUST WE SWITCH SCREEN?
  if(currentLCDMillis - previousLCDMillis > lcdInterval)              // save the last time you changed the display
  {
    previousLCDMillis = currentLCDMillis;
    screen++;
    if (screen > screenMax) screen = 0;  // all screens done? => start over
    screenChanged = true;
  }

  // debug Serial.println(screen);


  // DISPLAY CURRENT SCREEN
  if (screenChanged)   // only update the screen if the screen is changed.
  {
    screenChanged = false; // reset for next iteration
    switch(screen)
    {
    case TEMPERATURE:
      showTemperature(40);
      break;
    case MINMAXTEMP:
      showMaxMinTemp(50);
      break;
       case TIME:
      showTime(50);
      break;
 case POWER:
      showPower(50);
      break;

case POWERNOW:
      showNowPower(50);
      break;


    default:
      // cannot happen -> showError() ?
      break;
    }
  }
}

void dht11sample()
{

humidity = dht.readHumidity();
airtemp = dht.readTemperature();


   // Check if any reads failed and exit early (to try again).
  if (isnan(humidity) || isnan(airtemp) ) {
 //   Serial.println("Failed to read from DHT sensor!");
    return;
  }
//heatindex = dht.computeHeatIndex(airtemp, humidity, false);
    

}


// This function is called when the Cayenne widget requests data for the Virtual Pin.
CAYENNE_OUT(VIRTUAL_PIN)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(VIRTUAL_PIN, sensors.getTempCByIndex(0));
  // To send the temperature in Fahrenheit use the corresponding code below.
  //Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
}

//CAYENNE_OUT(VIRTUAL_PIN)
//{
//  // Send the command to get temperatures.
//  sensors.requestTemperatures();
//  // This command writes the temperature in Celsius to the Virtual Pin.
//  Cayenne.celsiusWrite(VIRTUAL_PIN, sensors.getTempCByIndex(0));
//  // To send the temperature in Fahrenheit use the corresponding code below.
//  //Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
//}

//
//void topuploopsingle()
//
//{
// topupval = digitalRead(switch1);
//
//  if (topupval == HIGH)
//  {
// // lcd.setCursor(0,1);
// // lcd.print(" !!! ADD RO !!! ");
// 
//// digitalWrite(topupLED, HIGH);    // sets the LED to the button's value
//
//}
//     else 
//      
//  //    lcd.setCursor(0,1);
//   //   lcd.print(" WATER LEVEL OK ");
//  // digitalWrite(topupLED, topupval);    // sets the LED to the button's value
//   ledState = LOW;
//   digitalWrite(topupLED, ledState);
//
//}


CAYENNE_OUT(V5)
{
  topupval = digitalRead(switch1);
  Cayenne.virtualWrite(V5, topupval);
}

CAYENNE_OUT(V2)
{
  
  humidity = dht.readHumidity();
//  Serial.print("Airtemp: ");
//   Serial.print(humidity); 
//   Serial.println("------");
  Cayenne.virtualWrite(V2, humidity); //virtual pin
}

CAYENNE_OUT(V3)
{
  
  airtemp = (dht.readTemperature() - airtempoff);
//  Serial.print("Airtemp: ");
//   Serial.print(airtemp); 
//   Serial.println("------");
  Cayenne.virtualWrite(V3, airtemp); //virtual pin
}



CAYENNE_OUT(V6)
{
  

  Cayenne.virtualWrite(V6, (Irms*Voltage)); //virtual pin   // . Apparant Power
}
CAYENNE_OUT(V7)
{

  Cayenne.virtualWrite(V7, Irms); //virtual pin   // Current Only
  
}




void getKwh()  // calculate kWh & month total
{
  watts = (Irms*Voltage);

  float kwhprice = 0.15;
 
  dayKwh = ( watts * 24 ) / 1000;

  kwhCount++;

  dayKwhAccrue += dayKwh;

  cumulativeKwh = dayKwhAccrue / kwhCount;

// cumulativeKwhTotal += cumulativeKwh;

  if (timeMin == 0 && countKwhNow == true)
    {
      cumulativeKwhTotal += cumulativeKwh;
      countKwhNow = false;
      EEPROM.put(eepromAddress, cumulativeKwhTotal);
  //    EEPROM.commit();

      kwhCount = 0;
      dayKwhAccrue = 0;
      cumulativeKwh = 0;
    }

  if (timeMin == 1)
    {
      countKwhNow = true;
    }

    Cayenne.virtualWrite(V25, dayKwh);
  Cayenne.virtualWrite(V24, cumulativeKwh);
 // Cayenne.virtualWrite(23, cumulativeKwh, "counter", "null");
  Cayenne.virtualWrite(V23, cumulativeKwhTotal);  

  Cayenne.virtualWrite(V18, (dayKwh * kwhprice));
    Cayenne.virtualWrite(V19, (cumulativeKwhTotal * kwhprice)); 

}

void refreshTime()  // updates time to dashboard & variables
{

 time_t now;
// struct tm * timeinfo;
//   time(&now);
//  timeinfo = localtime(&now);
//
  timeHour = ( t.hour, DEC );
  timeMin = ( t.min, DEC );

 //   timeHour = ( timeinfo->tm_hour );
 // timeMin = ( timeinfo->tm_min );
  
//  Cayenne.virtualWrite(10, timeHour);
//  Cayenne.virtualWrite(11, timeMin);

}

CAYENNE_IN(V15)
{
      //Cayenne.virtualWrite(V22, 0);
  int currentValue = 0;

  currentValue = getValue.asInt();
//  delay(1000);
  if (currentValue == 1)
  {
    Serial.println("MONTH RESET ON");

  //        EEPROM.write(eepromAddressLastMonth, cumulativeKwhTotal);
  //          delay(10);
          Cayenne.virtualWrite(V17, cumulativeKwhTotal);
    cumulativeKwhTotal = 0;
  //    kwhCount = 0;
  //    dayKwhAccrue = 0;
  //    cumulativeKwh = 0;
    
      EEPROM.write(eepromAddress, cumulativeKwhTotal);
   //    delay(10);
    Cayenne.virtualWrite(V22, 1);
  }
  if (currentValue == 0)
  {
    Serial.println("LOW");
    Cayenne.virtualWrite(V22, 0);
//    getKwh();
  
  }
}

#2

So you “cumulativeKwhTotal” variable stays 0 after the button toggle? A reset fixes it I assume?


#3

yes the cumulativeKwhTotal stays at 0 after the button toggle.

but i think there may be another problem as the cumulativeKwhTotal does not caculate properly either… will look deeper :slight_smile:


#4

Does it update on the dashboard ok after that or does everything stay at 0? I’m just wondering if it has something to do with writing a float value to eeprom… Maybe the value could be too big too? I think eeprom only does 0-255 if I’m correct… not 100% sure though.