Confirm IR signal was received

Hello,

I have a created a aquarium dosing and motoring program using a Wemos D1 mini. The main light is only controllable via I.R. It all works using I.R.; however, I would like a way to be able to tell in my Blynk app that the signal was received and/or whether the light is currently on. Any ideas?

/*  Wemos D1 mini R1
  D0 heater relay
  D1 empty (mosfet)
  D2 IR
  D4 water temp sensor
  D5 aux light
  D6 pump relay
  D7 CO2 relay

  BLYNK VIRTUAL PINS
  MISC V0-V9
  V0 water Temp
  V1 time
  V2 activeLED
  V3 CO2LED
  V4 heaterLED
  V5 blynkLCD
  Lights V10-V29
  Pumps/Sliders V30-V39
  V40 Dose Counter Reset
*/


//#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266.h>
#include <EEPROM.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
#define heaterPin D0
#define lightPin D1
#define IR_LED D2
#define ONE_WIRE_BUS D4
#define motorPin D6
#define CO2Pin D7
#define lightButton V20
#define pumpButton  V30

char auth[] = "XXXXXXXXXXXXX";
const char* ssid = "XXXXX";
const char* pass = "XXXXXX";

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
BlynkTimer timer;
WidgetRTC rtc;
WidgetLED activeLED(V2);
WidgetLED CO2LED(V3);
WidgetLED heaterLED (V4);
WidgetLCD blynkLCD(V5);
IRsend irsend(IR_LED);  // Set the GPIO to be used to sending the message.

////variables
float waterTemp = 0;
int pumpCount = 0;
float mlsGiven = 0;
float pumpml;
float correctionFactor = 1; //correction factor for pump
String lastRunDate = ""; //for LCD to Print the Date Pump ran
String lastRunTime = ""; //for LCD to Print the Time Pump ran

/////////////////////CLOCK/////////////////////////////
String getTime() {
  String currentTime = String(hour()) + ":" + minute() + ":" + second();
  return currentTime;
}
String getDate() {
  String currentDate = String(month()) + "/" + day() ;
  return currentDate;
}
BLYNK_CONNECTED() {// Synchronize time, widgets on connection
  rtc.begin();
  Blynk.syncVirtual(V20); //rear light button
  Blynk.syncVirtual(V31); //fertilizer slide
  Blynk.syncVirtual(V30); //pump
}

//////////////////////PUMPS///////////////////////////
BLYNK_WRITE(V31) {//  Pump 1 slider
  pumpml = param.asFloat();
  Serial.println(String("Pump 1 slider value = ") + pumpml );
}
void primePump() {
  digitalWrite(motorPin, HIGH);
  blynkLCD.clear();
  Serial.println("PRIMING PUMP");
  blynkLCD.print(0, 0, " PRIMING PUMP");
  Blynk.virtualWrite(V30, 1);
  timer.setTimeout(2000, LCDWriteCounts);
}
BLYNK_WRITE(pumpButton) {//  Prime button
  int motorButtonValue = param.asInt();
  if (motorButtonValue == 1) {
    primePump();
  }
  else {
    pumpOff();
  }
}
void pumpOff() {
  digitalWrite(motorPin, LOW);
  Blynk.virtualWrite(pumpButton, LOW);
}
void runPump() {
  Serial.println(String("Dosing ThriveS") + pumpml + (" mls"));
  Blynk.virtualWrite(V30, 1);
  blynkLCD.clear();
  blynkLCD.print(0, 0, "Dosing ThriveS");
  blynkLCD.print(4, 1, pumpml);
  blynkLCD.print(10, 1, "ml");
  Blynk.virtualWrite(pumpButton, HIGH);
  Blynk.setProperty(pumpButton, "onLabel", "DOSING");
  digitalWrite(motorPin, HIGH);
  delay(pumpml * (1000 * correctionFactor)); // set how long you want the motor to run... 1000 = aprox 1ml
  pumpOff();
  delay(1000);// for doses <  one second long
  pumpCount ++;
  lastRunTime = getTime();
  lastRunDate = getDate();
  mlsGiven = (mlsGiven + pumpml);
  EEPROM.write(0, pumpCount);
  EEPROM.write(1, hour());
  EEPROM.write(2, minute());
  EEPROM.write(3, second());
  EEPROM.write(4, month());
  EEPROM.write(5, day());
  EEPROM.put(6, mlsGiven);
  EEPROM.commit();
  timer.setTimeout(2000, LCDWriteCounts);
}
void LCDWriteCounts() {
  blynkLCD.clear();
  blynkLCD.print(0, 0, "#");
  blynkLCD.print(1, 0, pumpCount);
  blynkLCD.print(4, 0, "t.ml: ");
  blynkLCD.print(10, 0, mlsGiven);
  //Line 2
  blynkLCD.print(0, 1, lastRunDate);
  blynkLCD.print(8, 1, lastRunTime);
}
void resetCounts() {
  for (int a = 0; a < 1; a++) {
    pumpCount = 0;
    mlsGiven = 0;
    lastRunDate = "";
    lastRunTime = "";
  }
  for (int i = 0 ; i < 30 ; i++) {
    EEPROM.write(i, 0);
  }
  EEPROM.commit();
  blynkLCD.clear();
  Serial.println("EEPROM ERASED");
  Serial.println("counts reset");
  blynkLCD.print(0, 0, "  EEPROM ERASED");
  blynkLCD.print(0, 1, "  COUNTS RESET");
  timer.setTimeout(2000, LCDWriteCounts);
}
BLYNK_WRITE(V40) {// Count reset
  int resetButton = param.asInt();
  if (resetButton == 1) {
    resetCounts();
  }
}
void getPumpData() { // Read pump EEPROM data and write to variables
  pumpCount = EEPROM.read(0);
  lastRunTime =  String(EEPROM.read(1)) + ":" + EEPROM.read(2) + ":" + EEPROM.read(3);
  lastRunDate =  String(EEPROM.read(4)) + "/" + EEPROM.read(5);
  float f = 0.00f;
  mlsGiven = EEPROM.get(6, f);
}

//////////////////////CO2//////////////////////////
void CO2ON() {
  digitalWrite(CO2Pin, HIGH);
  Serial.println("CO2 ON");
  CO2LED.on();
}
void CO2OFF() {
  digitalWrite(CO2Pin, LOW);
  Serial.println("CO2 OFF");
  CO2LED.off();
}

//////////////////////LIGHTS//////////////////////////
void rearLightOn() {
  Blynk.virtualWrite(lightButton, HIGH);
  digitalWrite(lightPin, HIGH);
  Serial.println(String("light on"));
}
void rearLightOff() {
  Blynk.virtualWrite(lightButton, LOW);
  digitalWrite(lightPin, LOW);
  Serial.println(String("light off"));
}
void powerWhite() {
  irsend.sendNEC(0xF7C03F, 32);
}
void maxWhite() {
  for (int i = 0; i < 10; i++) {
    irsend.sendNEC(0xF7E01F, 32);
  }
}
void minWhite() {
  for (int i = 0; i < 10; i++) {
    irsend.sendNEC(0xF7D02F, 32);
  }
}
void upWhite(int p) {
  for (int i = 0; i < p; i++) {
    irsend.sendNEC(0xF7E01F, 32);
  }
}
void downWhite(int p) {
  for (int i = 0; i < p; i++) {
    irsend.sendNEC(0xF7D02F, 32);
  }
}
void maxRGB() {
  for (int i = 0; i < 10; i++) {
    irsend.sendNEC(0xF700FF, 32);
  }
}
void minRGB() {
  for (int i = 0; i < 10; i++) {
    irsend.sendNEC(0xF7807F, 32);
  }
}
void upRGB(int p) {
  for (int i = 0; i < p; i++) {
    irsend.sendNEC(0xF700FF, 32);
  }
}
void downRGB(int p) {
  for (int i = 0; i < p; i++) {
    irsend.sendNEC(0xF7807F, 32);
  }
}
void red() {
  irsend.sendNEC(0xF720DF, 32);
}
void red1() {
  irsend.sendNEC(0xF710EF, 32);
}
void red2() {
  irsend.sendNEC(0xF730CF, 32);
}
void red3() {
  irsend.sendNEC(0xF708F7, 32);
}
void red4() {
  irsend.sendNEC(0xF728D7, 32);
}
void green1() {
  irsend.sendNEC(0xF710EF, 32);
}
void green2() {
  irsend.sendNEC(0xF730CF, 32);
}
void green3() {
  irsend.sendNEC(0xF708F7, 32);
}
void green4() {
  irsend.sendNEC(0xF728D7, 32);
}
void blue() {
  irsend.sendNEC(0xF7609F, 32);
}
void blue1() {
  irsend.sendNEC(0xF750AF, 32);
}
void blue2() {
  irsend.sendNEC(0xF7708F, 32);
}
void blue3() {
  irsend.sendNEC(0xF748B7, 32);
}
void blue4() {
  irsend.sendNEC(0xF76897, 32);
}
BLYNK_WRITE(lightButton) { // Rear Light
  int ltButton = param.asInt();
  if (ltButton == HIGH) {
    rearLightOn();
  }
  else {
    rearLightOff();
  }
}
BLYNK_WRITE(V10) { // White Power
  int pinData = param.asInt();
  if (pinData == HIGH) {
    irsend.sendNEC(0xF7C03F, 32);
  }
}
BLYNK_WRITE(V11) { // White Max
  int pinData = param.asInt();
  if (pinData == HIGH) {
    maxWhite();
  }
}
BLYNK_WRITE(V12) { // White Min
  int pinData = param.asInt();
  if (pinData == HIGH) {
    minWhite();
  }
}
BLYNK_WRITE(V13) { // RGB Power
  int pinData = param.asInt();
  if (pinData == HIGH) {
    irsend.sendNEC(0xF740BF, 32);
  }
}
BLYNK_WRITE(V14) { // RGB Max
  int pinData = param.asInt();
  if (pinData == HIGH) {
    maxRGB();
  }
}
BLYNK_WRITE(V15) { // RGB Min
  int pinData = param.asInt();
  if (pinData == HIGH) {
    minRGB();
  }
}
BLYNK_WRITE(V17) { // Moonlight
  int pinData = param.asInt();
  if (pinData == HIGH) {
    irsend.sendNEC(0xF7F00F, 32);
  }
}
BLYNK_WRITE(V18) { // Thunderstorm
  int pinData = param.asInt();
  if (pinData == HIGH) {
    irsend.sendNEC(0xF7C837, 32);
  }
}
BLYNK_WRITE(V19) { // RGB cycle
  int pinData = param.asInt();
  if (pinData == HIGH) {
    irsend.sendNEC(0xF7E817, 32);
  }
}

void blinkactiveLED() {
  //LED
  if (activeLED.getValue()) {
    activeLED.off();
    Serial.println("Status LED on V2: off");
  } else {
    activeLED.on();
    Serial.println("Status LED on V2: on");
  }
  //CLOCK
  Blynk.virtualWrite(V1, getTime());
}
void checkTemperature() {
  DS18B20.requestTemperatures();
  waterTemp = DS18B20.toFahrenheit(DS18B20.getTempCByIndex(0));
  if (isnan(waterTemp)) {
    Serial.println("Failed to read from DS18B20 sensor!");
    return;
  }
  Blynk.virtualWrite(V0, waterTemp); //water
  Serial.print(" DS18B20 F:  "),
               Serial.println(waterTemp);
}
void checkHeater() {
  DS18B20.requestTemperatures();
  waterTemp = DS18B20.toFahrenheit(DS18B20.getTempCByIndex(0));
  if (isnan(waterTemp)) {
    digitalWrite(heaterPin, LOW);
    Blynk.setProperty(V4, "color", "#D3435C");
    heaterLED.on();
    Serial.println("temp sensor not working, heater OFF");
    blynkLCD.clear();
    blynkLCD.print(0, 0, "Temp Error");
    return;
  }
  else if (waterTemp < 78) {
    digitalWrite(heaterPin, HIGH);
    Serial.println("Heater ON");
    Blynk.setProperty(V4, "color", "#23C48E");
    heaterLED.on();
  }
  else if (waterTemp >=  79) {
    digitalWrite(heaterPin, LOW);
    Serial.println("Heater OFF");
    heaterLED.off();
  }
}
void checkSchedules() {
  if (hour() == 00 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue();
    downRGB(1);
    rearLightOff();
  }
  if (hour() == 01 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue();
    downRGB(1);
    rearLightOff();
  }
  if (hour() == 02 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue();
    downRGB(1);
    rearLightOff();
  }
  if (hour() == 03 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue();
    minRGB();
    rearLightOff();
  }
  if (hour() == 04 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue1();
    minRGB();
    upRGB(2);
    rearLightOff();
  }
  if (hour() == 05 && minute() == 00 && second() == 00) {
    CO2OFF();
    green2();
    minRGB();
    upRGB(7);
    rearLightOn();
  }
  if (hour() == 06 && minute() == 00 && second() == 00) {
    CO2OFF();
    red4();
    minRGB();
    upRGB(4);
    powerWhite();
    Blynk.virtualWrite(V13, "ON: 1");
    minWhite();
    rearLightOn();
  }
  if (hour() == 07 && minute() == 00 && second() == 00) {
    CO2OFF();
    red4();
    maxRGB();
    upWhite(1);
    Blynk.virtualWrite(V13, "ON: 3");
    rearLightOn();
  }
  if (hour() == 8 && minute() == 00 && second() == 00) {
    CO2ON();
    red3();
    maxRGB();
    upWhite(1);
    Blynk.virtualWrite(V13, "ON: 5");
    rearLightOn();
  }
  if (hour() == 9 && minute() == 00 && second() == 00) {
    runPump();//////daily fertilizer
    CO2ON();
    red2();
    maxRGB();
    upWhite(2);
    Blynk.virtualWrite(V13, "ON: 8");
    rearLightOn();
  }
  if (hour() == 10 && minute() == 00 && second() == 00) {
    CO2ON();
    red1();
    maxRGB();
    maxWhite();
    Blynk.virtualWrite(V13, "ON: 10");
    rearLightOn();
  }
  if (hour() == 11 && minute() == 00 && second() == 00) {
    CO2ON();
    red();
    maxRGB();
    maxWhite();
    Blynk.virtualWrite(V13, "ON: 10");
    rearLightOn();
  }
  if (hour() == 12 && minute() == 00 && second() == 00) {
    CO2ON();
    red();
    maxRGB();
    maxWhite();
    Blynk.virtualWrite(V13, "ON: 10");
    rearLightOn();
  }
  if (hour() == 13 && minute() == 00 && second() == 00) {
    CO2ON();
    red();
    maxRGB();
    maxWhite();
    Blynk.virtualWrite(V13, "ON: 10");
    rearLightOn();
  }
  if (hour() == 14 && minute() == 22 && second() == 00) {
    CO2ON();
    red();
    maxRGB();
    maxWhite();
    Blynk.virtualWrite(V13, "ON: 10");
    rearLightOn();
  }
  if (hour() == 15 && minute() == 00 && second() == 00) {
    CO2ON();
    red();
    maxRGB();
    downWhite(1);
    Blynk.virtualWrite(V13, "ON: 8");
    rearLightOn();
  }
  if (hour() == 16 && minute() == 00 && second() == 00) {
    CO2ON();
    red();
    maxRGB();
    downWhite(2);
    Blynk.virtualWrite(V13, "ON: 5");
    rearLightOn();
  }
  if (hour() == 17 && minute() == 00 && second() == 00) {
    CO2OFF();
    red1();
    maxRGB();
    downWhite(1);
    Blynk.virtualWrite(V13, "ON: 3");
    rearLightOn();
  }
  if (hour() == 18 && minute() == 00 && second() == 00) {
    red1();
    maxRGB();
    minWhite();
    Blynk.virtualWrite(V13, "ON: 1");
    rearLightOn();
  }
  if (hour() == 19 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue1();
    maxRGB();
    minWhite();
    Blynk.virtualWrite(V13, "ON: 1");
    rearLightOn();
  }
  if (hour() == 20 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue1();
    maxRGB();
    powerWhite();
    Blynk.virtualWrite(V13, "OFF");
    rearLightOn();
  }
  if (hour() == 21 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue();
    maxRGB();
    rearLightOn();
  }
  if (hour() == 22 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue();
    maxRGB();
    downRGB(8);
    rearLightOff();
  }
  if (hour() == 23 && minute() == 00 && second() == 00) {
    CO2OFF();
    blue();
    downRGB(2);
    rearLightOff();
  }
}

void OTASetup() {
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }
  ArduinoOTA.setHostname("15 Gallon Tank");
  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: % u % % \r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[ % u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}
void setup() {
  Serial.begin(9600);
  Blynk.config(auth, IPAddress(192, 168, 1, 70), 8080);
  OTASetup();
  blynkLCD.clear();
  irsend.begin();
  DS18B20.begin();
  pinMode(lightPin, OUTPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(CO2Pin, OUTPUT);
  pinMode(heaterPin, OUTPUT);
  EEPROM.begin(512);
  getPumpData();//  reads pump data from EEPROM and writes to variables
  timeStatus(), setSyncInterval(10 * 60);// every
  timer.setInterval(1000L, blinkactiveLED);// every 1 second
  timer.setInterval(1000 * 60, checkTemperature); // every 1 minute
  timer.setInterval(1000 * 60, LCDWriteCounts);// every 1 minute
  timer.setInterval(10000 * 60, checkHeater);// every 10 minutes
}
void loop() {
  ArduinoOTA.handle();
  Blynk.run();
  timer.run();
  checkSchedules();
  yield();
}

Add a LDR to your setup and use it to determine the light levels coming from the lamp. An alternative would be a current sensor on the power line to the lamp.

2 Likes