0

multiple switches problem with Adafruit IO and ESP8266 huzza
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

multiple switches problem with Adafruit IO and ESP8266 huzza

by wmichielsen on Wed May 22, 2019 4:37 pm

The following code renders unstable back reading of the state of multiple switches implemented in Adafruit IO:
* 2019/05/07
* ESP8266 pinout definitions
* IO14 = NTC sensors -> digital one-wire communication enabled
* IO12 = DHT22 sensor on PCB -> digital one-wire communication enabled
*
* IO13 = DIO_3
* IO15 = DIO_1
* IO2 = DIO_4 (blue LED)
* IO0 = not assigned (red LED)
* IO16 = DIO_2
*
* I2C communication: SDA and SCL is shared between external screen, DHT22 and energy monitoring
* pinout: T1 = IO2 (blue led) or IO14
* NOTE: a 220uF capacitor is needed between 3.3V and 0V to stabalize power supply for the OLED screen
*/
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <AdafruitIO_WiFi.h> // important: this library includes ref to ESP8266WiFi.h, WiFicliensecure.h
//The example for time synchronization is from: https://www.geekstips.com/arduino-time- ... p8266-udp/
//The WiFiUdp.h is still needed as reference
//The order of listing the WiFi inclusions is therefore important !!!
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>


/*Print to external screen difinitions
*************************************/
#define SCL 5
#define SDA 4
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display

/*Definition of DHT22 pin
*************************/
#define DHTPIN 12 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302)
uint32_t delayMS;
float temp, humid;
DHT_Unified dht(DHTPIN, DHTTYPE);

/* IoT ADAFRUIT DEFINITIONS
**************************/
#define WIFI_SSID "donut"
#define WIFI_PASS "passwd"
#define IO_USERNAME "blabla"
#define IO_KEY "secretkey"
const long utcOffsetInSeconds = 3600;
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
unsigned long comparetimeA, comparetimeB;
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

/*define switches T1,T2,T3,T4
****************************/
const int T1Pin = 14; // the physical pinnumber of T1
const int T2Pin = 16; // the physical pinnumber of T2
const int T3Pin = 13; // the physical pinnumber of T3
const int T4Pin = 15; // the physical pinnumber of T4
unsigned long timezeroA, timezeroB;

/* Define NTP Client to get time
********************************/
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

/*defines for LTC2945 from Analog Devices
****************************************/
char LTCADDR[4] = {B1101111, B1101111, B1101111, B1101111 };
//#define LTCADDR[0] B1101111 //Table 1 both LOW (7bit address)
//#define LTCADDR[1] B1101111 //Table 1 both LOW (7bit address) !!!!!!!
//#define LTCADDR[2] B1101111 //Table 1 both LOW (7bit address) !!!!!!!
//#define LTCADDR[3] B1101111 //Table 1 both LOW (7bit address) !!!!!!

byte ADCvinMSB, ADCvinLSB, curSenseMSB, curSenseLSB, AinVMSB, AinVLSB;
unsigned int ADCvin, ADCcur, AinV;
float inputVoltage, ADCvoltage, current, watt;


/********************** Configuration IOT *****************************/
// time between sending data to adafruit io, in minutes
#define MESSAGE_WAIT_SEC (1 * 16)
// set up the 'temperature' feed
AdafruitIO_Feed *huzzah_temperature = io.feed("temperature");
AdafruitIO_Feed *huzzah_humidity = io.feed("humidity");
AdafruitIO_Feed *huzzah_voltageT1 = io.feed("group1.voltage-t1"); //T1
AdafruitIO_Feed *huzzah_currentT1 = io.feed("group1.current-t1");
AdafruitIO_Feed *huzzah_wattT1 = io.feed("group1.watts-t1");
AdafruitIO_Feed *huzzah_switchT1 = io.feed("group1.switch-t1");
AdafruitIO_Feed *huzzah_voltageT2 = io.feed("group2.voltage-t2"); //T2
AdafruitIO_Feed *huzzah_currentT2 = io.feed("group2.current-t2");
AdafruitIO_Feed *huzzah_wattT2 = io.feed("group2.watts-t2");
AdafruitIO_Feed *huzzah_switchT2 = io.feed("group2.switch-t2");
AdafruitIO_Feed *huzzah_voltageT3 = io.feed("group3.voltage-t3"); //T3
AdafruitIO_Feed *huzzah_currentT3 = io.feed("group3.current-t3");
AdafruitIO_Feed *huzzah_wattT3 = io.feed("group3.watts-t3");
AdafruitIO_Feed *huzzah_switchT3 = io.feed("group3.switch-t3");
AdafruitIO_Feed *huzzah_voltageT4 = io.feed("group4.voltage-t4"); //T4
AdafruitIO_Feed *huzzah_currentT4 = io.feed("group4.current-t4");
AdafruitIO_Feed *huzzah_wattT4 = io.feed("group4.watts-t4");
AdafruitIO_Feed *huzzah_switchT4 = io.feed("group4.switch-t4");
/**********************************************************************/

void setup(void)
/*********************************************************************/
{
Serial.begin(115200); // init the PC screen output TX,RX
pinMode(T1Pin, OUTPUT); //definition for T1Pin as output
pinMode(T2Pin, OUTPUT); //definition for T2Pin as output
pinMode(T3Pin, OUTPUT); //definition for T3Pin as output
pinMode(T4Pin, OUTPUT); //definition for T4Pin as output

u8g2.setI2CAddress(0x78);
u8g2.begin(); //init the external screen
u8g2.clearDisplay();

// connect to io.adafruit.com
Serial.print("Connecting to Adafruit IO");
io.connect();

// set up a message handler for the 'digital' feed.
// the handleMessage function (defined below)
// will be called whenever a message is
// received from adafruit io.
huzzah_switchT1->onMessage(handleMessageT1);
huzzah_switchT2->onMessage(handleMessageT2);
huzzah_switchT3->onMessage(handleMessageT3);
huzzah_switchT4->onMessage(handleMessageT4);

// wait for a connection
while (io.status() < AIO_CONNECTED)
{
Serial.print(".");
delay(500);
}
// we are connected
Serial.println();
Serial.println(io.statusText());

huzzah_switchT1->get();
huzzah_switchT2->get();
huzzah_switchT3->get();
huzzah_switchT4->get();

dht.begin(); //init DHT22 sensor
sensor_t sensor;
delayMS = sensor.min_delay / 1000; // Set delay between sensor readings based on sensor details.

Wire.begin(); // init the I2C output from the LTC2945

timeClient.begin();
timeClient.update();
timezeroA = timeClient.getEpochTime();
timezeroB = timeClient.getEpochTime();
}


void loop(void) {
/*************************************************************************/
// io.run(); is required for all sketches.
// it should always be present at the top of your loop
// function. it keeps the client connected to
// io.adafruit.com, and processes any incoming data.
io.run();
timeClient.update();

comparetimeB = timeClient.getEpochTime(); //get current time
if (comparetimeB - timezeroB >= MESSAGE_WAIT_SEC) {
for (int i = 0; i < 4; i++ )
{
// output V,I,P for T1..T4
get_energy_values(LTCADDR[i]);

// DHT22 sensor reading
// Get temperature event and print its value.
get_temp_hum_dht();

//send all data to adafruit io

Serial.print("Sending to Adafruit IO, i = ");
Serial.println(i);
switch (i) {
case 0:
huzzah_temperature->save(temp, 0, 0, 0, 1); //last digit = accuracy
delay(100);
huzzah_humidity->save(humid, 0, 0, 0, 1); //last digit = accuracy
delay(100);
huzzah_voltageT1->save(inputVoltage, 0, 0, 0, 1); //last digit = accuracy
delay(100);
huzzah_currentT1->save(current, 0, 0, 0, 2); //last digit = accuracy
delay(100);
huzzah_wattT1->save(watt, 0, 0, 0, 1); //last digit = accuracy
delay(100);
break;

case 1:
huzzah_voltageT2->save(inputVoltage, 0, 0, 0, 1); //last digit = accuracy
delay(100);
huzzah_currentT2->save(current, 0, 0, 0, 2); //last digit = accuracy
delay(100);
huzzah_wattT2->save(watt, 0, 0, 0, 1); //last digit = accuracy
delay(100);
break;

case 2:
huzzah_voltageT3->save(inputVoltage, 0, 0, 0, 1); //last digit = accuracy
delay(100);
huzzah_currentT3->save(current, 0, 0, 0, 2); //last digit = accuracy
delay(100);
huzzah_wattT3->save(watt, 0, 0, 0, 1); //last digit = accuracy
delay(100);
break;

case 3:
huzzah_voltageT4->save(inputVoltage, 0, 0, 0, 1); //last digit = accuracy
delay(100);
huzzah_currentT4->save(current, 0, 0, 0, 2); //last digit = accuracy
delay(100);
huzzah_wattT4->save(watt, 0, 0, 0, 1); //last digit = accuracy
delay(100);
break;
}
}

// Print all results to external screen as well
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_mozart_nbp_tf);
u8g2.setCursor(5, 15);
u8g2.print(daysOfTheWeek[timeClient.getDay()]);
u8g2.print(" ");
u8g2.print(timeClient.getHours()+1);
u8g2.print(":");
u8g2.print(timeClient.getMinutes());
u8g2.print(":");
u8g2.print(timeClient.getSeconds());
u8g2.setCursor(5, 30);
u8g2.print(comparetimeB - timezeroB);
u8g2.print(",Temp="); u8g2.print(int(temp)); u8g2.print("C");
u8g2.print(",Hum="); u8g2.print(int(humid)); u8g2.print("%");
u8g2.setCursor(5, 45);
u8g2.print("T1:");
u8g2.print(inputVoltage); u8g2.print("V,");
u8g2.print(current); u8g2.print("A,");
u8g2.setCursor(45, 60);
u8g2.print(watt); u8g2.print("W");
} while ( u8g2.nextPage() );
// Serial.print("switchstate= ");
// Serial.println(TState);

timezeroB = comparetimeB;
}
Serial.println("Sending...Done!");
delay(20000);
}

/* this function is called whenever an 'digital' feed message
is received from Adafruit IO. it was attached to
the 'digital' feed in the setup() function above.*/
void handleMessageT1(AdafruitIO_Data *data)
{
Serial.print("received <- ");
if(data->toPinLevel() == HIGH)
Serial.println("HIGH");
else
Serial.println("LOW");
digitalWrite(T1Pin, data->toPinLevel());
}

void handleMessageT2(AdafruitIO_Data *data)
{
Serial.print("received <- ");
if(data->toPinLevel() == HIGH)
Serial.println("HIGH");
else
Serial.println("LOW");
digitalWrite(T2Pin, data->toPinLevel());
}

void handleMessageT3(AdafruitIO_Data *data)
{
Serial.print("received <- ");
if(data->toPinLevel() == HIGH)
Serial.println("HIGH");
else
Serial.println("LOW");
digitalWrite(T3Pin, data->toPinLevel());
}

void handleMessageT4(AdafruitIO_Data *data)
{
Serial.print("received <- ");
if(data->toPinLevel() == HIGH)
Serial.println("HIGH");
else
Serial.println("LOW");
digitalWrite(T4Pin, data->toPinLevel());
}


void get_energy_values(char LTCADDRESS)
{
Wire.beginTransmission(LTCADDRESS);//first get Input Voltage - 80V max
Wire.write(0x1E);
Wire.endTransmission(false);
Wire.requestFrom(LTCADDRESS, 2, true);
delay(1);
ADCvinMSB = Wire.read();
ADCvinLSB = Wire.read();
ADCvin = ((unsigned int)(ADCvinMSB) << 4) + ((ADCvinLSB >> 4) & 0x0F);//formats into 12bit integer
inputVoltage = ADCvin * 0.025; //25mV resolution

Wire.beginTransmission(LTCADDRESS);//get ADC Input 2V max
Wire.write(0x28);
Wire.endTransmission(false);
Wire.requestFrom(LTCADDRESS, 2, true);
delay(1);
AinVMSB = Wire.read();
AinVLSB = Wire.read();
AinV = ((unsigned int)(AinVMSB) << 4) + ((AinVLSB >> 4) & 0x0F);//12 bit format
ADCvoltage = AinV * 0.5E-3; //500uV resolution

Wire.beginTransmission(LTCADDRESS);//get sense current
Wire.write(0x14);
Wire.endTransmission(false);
Wire.requestFrom(LTCADDRESS, 2, true);
delay(1);
curSenseMSB = Wire.read();
curSenseLSB = Wire.read();
ADCcur = ((unsigned int)(curSenseMSB) << 4) + ((curSenseLSB >> 4) & 0x0F);//12 bit format
//gets voltage across, 25uV resolution, then this converts to voltage for each sense resistor
current = ADCcur * (25E-6) / 0.0025; //20A max, unit is A
watt = inputVoltage*current;
}

void get_temp_hum_dht()
{
sensors_event_t event;
dht.temperature().getEvent(&event);
if (isnan(event.temperature)) {
Serial.println(F("Error reading temperature!"));
}
else {
Serial.print(F("Temperature: "));
temp=(event.temperature);
Serial.print(temp);
Serial.println(F("°C"));
}
// Get humidity event and print its value.
dht.humidity().getEvent(&event);
if (isnan(event.relative_humidity)) {
Serial.println(F("Error reading humidity!"));
}
else {
Serial.print(F("Humidity: "));
humid = event.relative_humidity;
Serial.print(humid);
Serial.println(F("%"));
}
}

wmichielsen
 
Posts: 1
Joined: Fri May 10, 2019 3:18 am

Please be positive and constructive with your questions and comments.