Hi Pete,
- I have 2 devices, but they’re both individual apps with own Auth Token.
- I used Virtual PINs
- How do i get out which ESP32 core i’m using … not sure about that
- See the code below (let me know if you need the other includes a well)
- Is very hard to get the HW output for me but i can try … but i don’t write a a lot to serial at all.
main.cpp
// Fill-in information from your Blynk Template here
#define BLYNK_TEMPLATE_ID "xxxxxxxx"
#define BLYNK_TEMPLATE_NAME "xxxxxxx"
#define BLYNK_FIRMWARE_VERSION "1.2"
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG
#include <Arduino.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#define APP_DEBUG
#define USE_ESP32S2_DEV_KIT
#define PIN_UPTIME V29
#define BLYNK_GREEN "#23C48E"
#define BLYNK_BLUE "#04C0F8"
#define BLYNK_YELLOW "#ED9D00"
#define BLYNK_RED "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"
#define led 26
#define onboardLed 13
#define ventilator 14
#define luefterLow 33
#define luefterHigh 25
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#include "BlynkEdgent.h"
#include <ezTime.h>
BlynkTimer timer;
#include "AVariablen.h"
#include "ASystemFunc.h"
#include "AGrowFunc.h"
void setup()
{
Serial.begin(115200);
dht.begin();
digitalWrite(resetPin, HIGH);
pinMode(resetPin, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
pinMode(onboardLed, OUTPUT);
digitalWrite(onboardLed, LOW);
pinMode(ventilatorPin, OUTPUT);
digitalWrite(ventilatorPin, HIGH);
pinMode(luefterLowPin, OUTPUT);
digitalWrite(luefterLowPin, HIGH);
pinMode(luefterHighPin, OUTPUT);
digitalWrite(luefterHigh, HIGH);
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
for (int thisReading = 0; thisReading < numReadings1; thisReading++) {
readings[thisReading] = 0;
}
// Timer setzten
timer.setInterval(10000, WifiSgn);
timer.setInterval(60000, Uptime);
timer.setInterval(120000, alarm_notify);
timer.setInterval(60000, licht_anaus);
timer.setInterval(60000, timestamp);
timer.setInterval(55000, sendSensorDTHaussen);
timer.setInterval(10000, sendSensorSoil);
timer.setInterval(30000, abluft_auto);
BlynkEdgent.begin();
}
BLYNK_WRITE(V4) {
licht = param.asInt();
if (debug == 1) {
Blynk.virtualWrite(V1, timestamp_debug + "-Licht:" + String(licht) +"\n");
}
}
BLYNK_WRITE(V5) {
h_i = param.asInt();
}
BLYNK_WRITE(V11) {
co2_ppm = param.asInt();
}
BLYNK_WRITE(V12) {
TVOC = param.asInt();
}
BLYNK_WRITE(V19) {
debug = param.asInt();
}
BLYNK_WRITE(V6) {
t_i = param.asInt();
}
BLYNK_WRITE(V15)
{
maxTemp = param.asInt();
}
BLYNK_WRITE(V16)
{
maxH = param.asInt();
}
BLYNK_WRITE(V20)
{
targetRLF = param.asInt();
}
BLYNK_WRITE(V9)
{
intervalcount_max = param.asInt();
}
BLYNK_WRITE(V18) {
switch (param.asInt())
{
case 0: // Item 1
alarm_not = 1;
Blynk.virtualWrite(V1, timestamp_log + " Alarm: An\n");
break;
case 1: // Item 2
alarm_not = 0;
Blynk.virtualWrite(V1, timestamp_log + " Alarm: Aus\n");
break;
default:
alarm_not = 1;
Blynk.virtualWrite(V1, timestamp_log + " Alarm: An\n");
}
}
BLYNK_WRITE(V33) {
switch (param.asInt())
{
case 0: // Item 1
alldays = 1;
Blynk.virtualWrite(V1, timestamp_log + " Automatik Beleuchtung: Auto\n");
Blynk.logEvent("status_led-belechtung", String("Automatik Beleuchtung eingeschalten"));
break;
case 1: // Item 2
alldays = 0;
digitalWrite(ledPin, HIGH);
licht = 0;
ledLicht.setColor(BLYNK_RED);
Blynk.virtualWrite(V1, timestamp_log + " Automatik Beleuchtung: Manuell Aus\n");
Blynk.logEvent("status_led-belechtung", String("Automatik Beleuchtung: Manuell Aus"));
break;
case 2:
alldays = 0;
licht = 1;
digitalWrite(ledPin, LOW);
ledLicht.setColor(BLYNK_GREEN);
Blynk.virtualWrite(V1, timestamp_log + " Automatik Beleuchtung: Manuell An\n");
Blynk.logEvent("status_led-belechtung", String("Automatik Beleuchtung: Manuell An"));
break;
default:
Blynk.virtualWrite(V1, timestamp_log + " Automatik Beleuchtung: Auto\n");
Blynk.logEvent("status_led-belechtung", String("Automatik Beleuchtung eingeschalten"));
alldays = 1;
}
// Serial.println("DEBUG: V33 OK");
}
BLYNK_WRITE(V35) {
switch (param.asInt())
{
case 0:
Blynk.virtualWrite(V1, timestamp_log + " Umluftventilator Aus\n");
Blynk.logEvent("status_umluft-ventilation", String(" Umluftventilator Aus"));
digitalWrite(ventilatorPin, HIGH);
ledVentilator.setColor(BLYNK_RED);
break;
case 1:
Blynk.virtualWrite(V1, timestamp_log + " Umluftventilator An\n");
Blynk.logEvent("status_umluft-ventilation", String(" Umluftventilator An"));
digitalWrite(ventilatorPin, LOW);
ledVentilator.setColor(BLYNK_GREEN);
break;
default:
digitalWrite(ventilatorPin, HIGH);
ledVentilator.setColor(BLYNK_RED);
}
}
BLYNK_WRITE(V30) {
switch (param.asInt())
{
case 0:
Blynk.virtualWrite(V1, timestamp_log + " Abluft: Auto - Intervall Lüften an\n");
Blynk.logEvent("status_abluft", String(" Abluft: Auto - Intervall Lüften an"));
intervalenable = 1;
break;
case 1:
Blynk.virtualWrite(V1, timestamp_log + " Abluft: Auto - Intervall Lüften aus\n");
Blynk.logEvent("status_abluft", String(" Abluft: Auto - Intervall Lüften aus"));
intervalenable = 0;
break;
default:
intervalenable = 1;
}
}
BLYNK_WRITE(V37) {
WaterValue1 = param.asInt();
}
BLYNK_WRITE(V38) {
AirValue1 = param.asInt();
}
BLYNK_WRITE(V39) {
WaterValue2 = param.asInt();
}
BLYNK_WRITE(V40) {
AirValue2 = param.asInt();
}
BLYNK_WRITE(V36) {
switch (param.asInt())
{
case 0:
luefter_auto = 0;
Blynk.virtualWrite(V1, timestamp_log + " Abluftventilator Aus\n");
Blynk.logEvent("status_abluft", String("Abluftventilator Aus\n"));
digitalWrite(luefterHighPin, HIGH);
digitalWrite(luefterLowPin, HIGH);
ledLuefter.setColor(BLYNK_RED);
break;
case 1:
luefter_auto = 0;
Blynk.virtualWrite(V1, timestamp_log + " Abluftventilator 100%\n");
Blynk.logEvent("status_abluft", String(" Abluftventilator 100%\n"));
digitalWrite(luefterHighPin, HIGH);
digitalWrite(luefterLowPin, LOW);
ledLuefter.setColor(BLYNK_BLUE);
break;
case 2:
luefter_auto = 0;
Blynk.virtualWrite(V1, timestamp_log + " Abluftventilator 80%\n");
Blynk.logEvent("status_abluft", String(" Abluftventilator 80%\n"));
digitalWrite(luefterHighPin, LOW);
digitalWrite(luefterLowPin, HIGH);
ledLuefter.setColor(BLYNK_DARK_BLUE);
break;
case 3:
Blynk.virtualWrite(V1, timestamp_log + " Abluft: Auto\n");
Blynk.logEvent("status_abluft", String(" Abluft: Auto\n"));
luefter_auto = 1;
// if (luefter_auto >= 1) {
// digitalWrite(luefterHighPin, LOW);
// digitalWrite(luefterLowPin, HIGH);
// ledLuefter.setColor(BLYNK_DARK_BLUE);
// }
break;
default:
luefter_auto = 0;
digitalWrite(luefterHighPin, HIGH);
digitalWrite(luefterLowPin, HIGH);
ledLuefter.setColor(BLYNK_RED);
}
}
void loop() {
timer.run(); // Initiates BlynkTimer
BlynkEdgent.run();
}
AGrowFuction.h
void resetNotifiedT()
{
notifiedT = 0;
}
void resetLufter__auto_T()
{
lufter__auto_T = 0;
}
void resetNotifiedH()
{
notifiedH = 0;
}
void licht_anaus()
{
if (alldays == 1)
{
if (licht >= 1)
{
digitalWrite(ledPin, LOW);
ledLicht.setColor(BLYNK_GREEN);
if (licht == 1)
{
Blynk.logEvent("status_led-belechtung", String("Beleuchtung An"));
Blynk.virtualWrite(V1, timestamp_log + " Beleuchtung An \n");
}
licht = licht + 1;
}
else if (licht <= 0)
{
digitalWrite(ledPin, HIGH);
ledLicht.setColor(BLYNK_RED);
if (licht == 0)
{
Blynk.logEvent("status_led-belechtung", String("Beleuchtung Aus"));
Blynk.virtualWrite(V1, timestamp_log + " Beleuchtung Aus \n");
}
licht = -1;
}
}
}
void sendSensorSoil()
{
Blynk.syncVirtual(V5, V6);
topf1 = topf1 - readings[readIndex];
topf2 = topf2 - readings1[readIndex1];
// read from the sensor:
readings[readIndex] = analogRead(soil_sensor1);
readings1[readIndex1] = analogRead(soil_sensor2);
// add the reading to the topf1:
topf1 = topf1 + readings[readIndex];
topf2 = topf2 + readings1[readIndex1];
// advance to the next position in the array:
readIndex = readIndex + 1;
readIndex1 = readIndex1 + 1;
// if we're at the end of the array...
if (readIndex >= numReadings)
{
// ...wrap around to the beginning:
readIndex = 0;
}
// if we're at the end of the array...
if (readIndex1 >= numReadings1)
{
// ...wrap around to the beginning:
readIndex1 = 0;
}
// calculate the average:
topf1_average = topf1 / numReadings;
topf2_average = topf2 / numReadings1;
output_value1 = topf1_average;
moisturelevel1 = constrain(map(output_value1, AirValue1, WaterValue1, 0, 100), 0, 100);
output_value2 = topf2_average;
moisturelevel2 = constrain(map(output_value2, AirValue2, WaterValue2, 0, 100), 0, 100);
Blynk.virtualWrite(V7, moisturelevel1);
Blynk.virtualWrite(V8, moisturelevel2);
if (debug == 1)
{
Blynk.virtualWrite(V1, timestamp_debug + "-T1-M:" + String(moisturelevel1) + " Out:" + String(output_value1) + " wet:" + String(WaterValue1) + " sry:" + String(AirValue1) + "\n");
Blynk.virtualWrite(V1, timestamp_debug + "-T2-M:" + String(moisturelevel2) + " Out:" + String(output_value2) + " wet:" + String(WaterValue2) + " dry:" + String(AirValue2) + "\n");
}
Blynk.virtualWrite(V21, output_value1);
Blynk.virtualWrite(V22, output_value2);
}
void sendSensorDTHaussen()
{
float h_a_raw = dht.readHumidity();
float t_a_raw = dht.readTemperature();
// h_a = dht.readHumidity();
// t_a = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
if (h_a_raw <= 100)
{
h_a = h_a_raw;
}
else
{
if (debug == 1)
{
Blynk.virtualWrite(V1, timestamp_debug + "-DHT22-Lesesefehler RLF:" + String(h_a_raw) + "\n");
}
}
if (t_a_raw <= 45)
{
t_a = t_a_raw;
}
else
{
if (debug == 1)
{
Blynk.virtualWrite(V1, timestamp_debug + "-DHT22-Lesesefehler Temp:" + String(t_a_raw) + "\n");
}
}
Blynk.virtualWrite(V51, h_a);
Blynk.virtualWrite(V50, t_a);
if (debug == 1)
{
Blynk.virtualWrite(V1, "DEBUG - DTH22 - Aussen - Temp:" + String(t_a) + " RLF:" + String(h_a) + " \n");
}
}
void alarm_notify()
{
String notifyStringT;
String notifyStringH;
// h_i = bme.readHumidity();
// t_i = bme.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
if (alarm_not == 1)
{
Blynk.syncVirtual(V5, V6);
// Blynk.virtualWrite(V1, timestamp_log + "- Test 1 "+ t_i +" "+ maxTemp+" "+notifiedT +"\n");
if (t_i >= maxTemp && !notifiedT)
{
notifiedT = true;
notifyStringT = "Temperatur IST:" + String(t_i) + " SOLL MAX:" + String(maxTemp) + "\n";
// Serial.println(notifyStringT);
Blynk.virtualWrite(V1, timestamp_log + "-" + notifyStringT);
Blynk.logEvent("alarm_innenraum_temperatur", notifyStringT);
timer.setTimeout(1200000, resetNotifiedT);
}
if (h_i >= maxH && !notifiedH)
{
notifiedH = true;
notifyStringH = "Luftfeuchtigkeit IST:" + String(h_i) + " SOLL MAX:" + String(maxH) + "\n";
// Serial.println(notifyStringH);
Blynk.virtualWrite(V1, timestamp_log + "-" + notifyStringH);
Blynk.logEvent("alarm_rlf", notifyStringH);
}
}
if (debug == 1)
{
Blynk.virtualWrite(V1, timestamp_debug + " - BM280 - Innen - Temp:" + String(t_i) + " RLF:" + String(h_i) + "\n");
}
}
void abluft_auto()
{
if (luefter_auto == 1)
{
// if (intervalenable == 1)
// {
// intervalcount = intervalcount + 1;
// if (debug == 1)
// {
// Blynk.virtualWrite(V1, timestamp_log + " - Interval Zähler:" + String(intervalcount) + "/" + String(intervalcount_max) + "\n");
// Blynk.virtualWrite(V1, timestamp_log + " - RLF:" + String(h_i) + "/" + String(targetRLF) + "\n");
// }
// }
// if (h_i >= targetRLF || (intervalenable == 1) || (intervalcount >= intervalcount_max) ) {
// if (h_i >= targetRLF)
// {
if (h_i > (targetRLF + 5))
{
digitalWrite(luefterHighPin, HIGH);
digitalWrite(luefterLowPin, LOW);
Blynk.virtualWrite(V1, timestamp_log + " Abluft:Auto-Lüfter 100%-RLF ist:" + h_i + "% Ziel:" + targetRLF + "% \n");
Blynk.logEvent("status_abluft", String(" Abluft: Auto - Lüfter auf 100%") + "\n");
}
else if (h_i >= (targetRLF + 2) && h_i <= (targetRLF + 5))
{
digitalWrite(luefterHighPin, LOW);
digitalWrite(luefterLowPin, HIGH);
Blynk.virtualWrite(V1, timestamp_log + " Abluft:Auto-Lüfter 80%-RLF ist:-" + h_i + "% Ziel:" + targetRLF + "% \n");
Blynk.logEvent("status_abluft", String(" Abluft: Auto - Lüfter auf 80%") + "\n");
}
else if (h_i <= targetRLF)
{
digitalWrite(luefterHighPin, HIGH);
digitalWrite(luefterLowPin, HIGH);
ledLuefter.setColor(BLYNK_RED);
Blynk.virtualWrite(V1, timestamp_log + " Abluft:Auto-Lüfter Aus-RLF ist:" + h_i + "% Ziel:" + targetRLF + "% \n");
Blynk.logEvent("status_abluft", String(" Abluft: Auto - Lüfter Aus") + "\n");
}
}
// intervalcount = 0;
ledLuefter.setColor(BLYNK_YELLOW);
}
ASystemFunction.h
BLYNK_CONNECTED() {
// Request the latest state from the server
// Synchronize time on connection
Blynk.sendInternal("rtc", "sync");
Blynk.virtualWrite(V1, "\n Growbox v"+ v + "\n");
waitForSync();
Timezone myTZ;
myTZ.setLocation(F("Europe/Berlin"));
Blynk.virtualWrite(V1, "\n----------------------------\n");
Blynk.virtualWrite(V1, myTZ.dateTime("l, d-M-y H:i")+ "\n");
Blynk.virtualWrite(V1, "----------------------------\n");
Blynk.virtualWrite(V1, "ready \n");
Blynk.virtualWrite(V0, v);
ledLicht.on();
ledVentilator.on();
ledLuefter.on();
ledTest.on();
}
void timestamp()
{
Timezone myTZ;
myTZ.setLocation(F("Europe/Berlin"));
timestamp_debug = (String("**D-") + myTZ.dateTime("d-M H:i") + String(" :"));
timestamp_log = (myTZ.dateTime("d-M H:i") + String(" :"));
timestamp_short = (myTZ.dateTime("l, d-M H:i"));
}
void Uptime() {
uptime = uptime + 1;
Blynk.sendInternal("rtc", "sync");
Blynk.virtualWrite(V29, uptime ); // labeled value settings
if (firststart == 1){
Blynk.syncVirtual(V4,V5,V6,V9,V15,V16,V18,V20,V33,V35,V36,V19,V37, V38,V39,V40);
// Blynk.syncVirtual();
// Blynk.syncAll();
firststart = 0;
}
}
void WifiSgn() {
Signal = (WiFi.RSSI());
if (Signal >= -30) {
SGN = S5;
}
else if (Signal <= -31 && Signal > -67) {
SGN = S4;
}
else if (Signal <= -67 && Signal > -70) {
SGN = S3;
}
else if (Signal <= -70 && Signal > -80) {
SGN = S2;
}
else if (Signal <= -80 && Signal > -90) {
SGN = S1;
}
else {
SGN = S0;
}
Blynk.virtualWrite(V2, SGN ); // labeled value settings
Blynk.virtualWrite(V3, Signal);// label value
}
AVariablen.h
WidgetLED ledLicht(V46);
WidgetLED ledVentilator(V47);
WidgetLED ledLuefter(V48);
WidgetLED ledTest(V2);
bool ledStatus = false;
/*************** signal init ***************/
String S0 = "no signal";
String S1 = "\u2581" ; //▁
String S2 = "\u2581 \u2583"; //▁ ▃
String S3 = "\u2581 \u2583 \u2585" ; //▁ ▃ ▆
String S4 = "\u2581 \u2583 \u2585 \u2587" ; //▁ ▃ ▆ ▇
String S5 = "\u2581 \u2583 \u2585 \u2587 \u2588" ; //▁ ▃ ▆ ▇ █
int Signal = 0;
String SGN ;
String v = BLYNK_FIRMWARE_VERSION;
int uptime = 0;
String timestamp_debug;
String timestamp_log;
String timestamp_short;
char Date[16];
char Time[16];
int t;
int h;
int t_a;
int h_a;
int t_i;
int h_i;
int maxTemp = 30;
int maxH = 65;
int targetRLF = 50;
int intervalcount = 0;
int intervalcount_max = 10;
int intervalenable = 1;
int resetPin = 12;
int firststart = 1;
char currentTime[9];
bool clockSync = false;
bool notifiedT = false;
bool notifiedH = false;
bool lufter__auto_T = false;
int alldays ;
int alarm_not = 1;
int manual = 0;
long startsecondswd; // weekday start time in seconds
long stopsecondswd; // weekday stop time in seconds
long nowseconds; // time now in seconds
bool isFirstConnect = true;
// Calibration for Soil Sensors
int AirValue1 ;
int WaterValue1 ;
int AirValue2 ;
int WaterValue2 ;
int soil_sensor1 = A6;
int output_value1 ;
int moisturelevel1;
int soil_sensor2 = A4;
int output_value2 ;
int moisturelevel2 ;
int co2_ppm ;
int TVOC;
int licht;
int debug;
int luefter_auto = 0;
int luefer_auto_timer = 30000;
int ledPin = 26;
int ventilatorPin = 14;
int luefterLowPin = 33;
int luefterHighPin = 25;
const int numReadings = 20;
const int numReadings1 = 20;
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int readings1[numReadings]; // the readings from the analog input
int readIndex1 = 0; // the index of the current reading
int topf1 = 0; // the running total
int topf1_average = 0; // the average
int topf2 = 0; // the running total
int topf2_average = 0; // the average
``