After running the MCU for two weeks or so with a new transmitter I’m quite happy with the result. I think it was just once my lamp didn’t start as scheduled. This however, is almost certain due to poor reception or transmission because my terminal did log it as “Schedule 1 started”. To add some extra redundancy to the schedule function (well, actually the RF system) I’m invoking Blynk.syncVirtual(V0);
and not just the send command and a virtualWrite as before.
The code:
/******************************************************************************
Both NexaSelfLearningTransmitter.h and NexaSelfLearningReceiver.h uses
"transmitter" as a variable, so I had to change one in order to compile.
NexaSelfLearningReceiver.h now uses "transmitter2".
*******************************************************************************/
#define BLYNK_PRINT Serial
#include "NexaSelfLearningTransmitter.h"
#include "NexaSelfLearningReceiver.h"
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
#define W5100_CS 10 // SD-card
#define SDCARD_CS 4
#define RX_PIN 2
#define RX_LED 0 // Reduces the no of error msg when compiling (NULL is char 0?)
#define TX_PIN 8
#define TX_LED 0
#define TRANSMITTER_ID 1912830
NexaSelfLearningTransmitter transmitter = NexaSelfLearningTransmitter(TX_PIN, TX_LED);
NexaSelfLearningReceiver receiver = NexaSelfLearningReceiver(RX_PIN, RX_LED); // Actually, not used yet
bool on = false;
bool group = false;
short dim = 0;
uint8_t channel = 0;
uint64_t receivedSignal = 0;
//uint32_t transmitter = 0; // same as TRANSMITTER_ID
uint32_t transmitter2 = 0;
WidgetTerminal terminal(V4);
BlynkTimer timer;
WidgetRTC rtc;
char currentTime[9];
byte arduino_mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xCC };
IPAddress arduino_ip (192, 168, 0, 20);
IPAddress dns_ip (192, 168, 0, 1);
IPAddress gateway_ip (192, 168, 0, 1);
IPAddress subnet_mask(255, 255, 255, 0);
char auth[] = ""; // Token for Blynk
bool clockSync = false;
void setup() {
pinMode(SDCARD_CS, OUTPUT); // Deselect the SD card
digitalWrite(SDCARD_CS, HIGH);
Serial.begin(9600);
Serial.println();
Blynk.begin(auth, "cloud.blynk.cc", 8442, arduino_ip, dns_ip, gateway_ip, subnet_mask, arduino_mac);
while (Blynk.connect() == false) {
// Wait until connected
}
for (int i = 0; i <= 24; i++) {
terminal.println(""); // "clear screen" in app.
}
terminal.flush();
terminal.println(F("Blynk v" BLYNK_VERSION ": Device started"));
terminal.println(F("-------------"));
terminal.flush();
timer.setInterval(60000L, activetoday); // check every 60s if ON / OFF trigger time has been reached
timer.setInterval(30000L, reconnectBlynk); // check every 30s if still connected to server
timer.setInterval(1000L, clockDisplay); // check every second if time has been obtained from the server
}
BLYNK_CONNECTED() {
rtc.begin();
}
void activetoday(){ // check if schedule #1 or #2 should run today
if(year() != 1970){
Blynk.syncVirtual(V10); // sync scheduler #1
}
}
void clockDisplay(){ // only needs to be done once after time sync
if((year() != 1970) && (clockSync == false)){
sprintf(currentTime, "%02d:%02d:%02d", hour(), minute(), second());
Serial.println(currentTime);
terminal.println(currentTime);
terminal.flush();
clockSync = true;
}
}
BLYNK_WRITE(V10) { // Scheduler #1 Time Input widget
TimeInputParam t(param);
unsigned int nowseconds = ((hour() * 3600) + (minute() * 60) + second());
unsigned int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
unsigned int stopseconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
int dayadjustment = -1;
if(weekday() == 1){
dayadjustment = 6; // needed for Sunday Time library is day 1 and Blynk is day 7
}
if(t.isWeekdaySelected((weekday() + dayadjustment))){ //Time library starts week on Sunday, Blynk on Monday
//Schedule is ACTIVE today
if(nowseconds >= startseconds - 31 && nowseconds <= startseconds + 31 ){ // 62s on 60s timer ensures 1 trigger command is sent
transmitter.deviceOn(TRANSMITTER_ID, 15); // Doesnt always work for some reason
Blynk.virtualWrite(V0, 1); // This however always work as long as everything is online
Blynk.syncVirtual(V0);
Serial.println("Schedule 1 started");
terminal.println("Schedule 1 started");
terminal.flush();
}
if(nowseconds >= stopseconds - 31 && nowseconds <= stopseconds + 31 ){ // 62s on 60s timer ensures 1 trigger command is sent
transmitter.deviceOff(TRANSMITTER_ID, 15);
Blynk.virtualWrite(V0, 0);
Blynk.syncVirtual(V0);
Serial.println("Schedule 1 finished");
terminal.println("Schedule 1 finished");
terminal.flush();
}
}
}
BLYNK_WRITE(V0) { // Unit 1 (Remote Controller 1)
if ( param.asInt() == 1 ) {
transmitter.deviceOn(TRANSMITTER_ID, 15);
Serial.println("RC 1 ON");
terminal.println("RC 1 ON");
terminal.flush();
}
else {
transmitter.deviceOff(TRANSMITTER_ID, 15);
Serial.println("RC 1 OFF");
terminal.println("RC 1 OFF");
terminal.flush();
}
}
BLYNK_WRITE(V1) { // Unit 2
if ( param.asInt() == 1 ) {
transmitter.deviceOn(TRANSMITTER_ID, 14);
Serial.println("RC 2 ON");
terminal.println("RC 2 ON");
terminal.flush();
}
else {
transmitter.deviceOff(TRANSMITTER_ID, 14);
Serial.println("RC 2 OFF");
terminal.println("RC 2 OFF");
terminal.flush();
}
}
BLYNK_WRITE(V2) { // Unit 3
if ( param.asInt() == 1 ) {
transmitter.deviceOn(TRANSMITTER_ID, 13);
Serial.println("RC 3 ON");
terminal.println("RC 3 ON");
terminal.flush();
}
else {
transmitter.deviceOff(TRANSMITTER_ID, 13);
Serial.println("RC 3 OFF");
terminal.println("RC 3 OFF");
terminal.flush();
}
}
BLYNK_WRITE(V3) { // Group, all units
if ( param.asInt() == 1 ) {
transmitter.groupOn(TRANSMITTER_ID);
Blynk.virtualWrite(V0, 1);
Blynk.virtualWrite(V1, 1);
Blynk.virtualWrite(V2, 1);
Serial.println("ALL IS ON");
terminal.println("ALL IS ON");
terminal.flush();
}
else {
transmitter.groupOff(TRANSMITTER_ID);
Blynk.virtualWrite(V0, 0);
Blynk.virtualWrite(V1, 0);
Blynk.virtualWrite(V2, 0);
Serial.println("ALL IS OFF");
terminal.println("ALL IS OFF");
terminal.flush();
}
}
void reconnectBlynk() {
if (!Blynk.connected()) {
if(Blynk.connect()) {
BLYNK_LOG("Reconnected");
}
else {
BLYNK_LOG("Not reconnected");
}
}
}
void loop() {
if(Blynk.connected()) {
Blynk.run();
}
timer.run();
}
/***************************************************************************
void data_incoming() {
receivedSignal = receiver.receiveSignal(&transmitter2, &on, &group, &channel, &dim, 1000);
if(receivedSignal != 0) {
if (channel == 15) { // Unit 1
Blynk.virtualWrite(V0, on); // on == 1 || 0
Blynk.syncVirtual(V0);
}
else if (channel == 14) { // Unit 2
Blynk.virtualWrite(V1, on);
Blynk.syncVirtual(V1);
}
else if (channel == 13) { // Unit 3
Blynk.virtualWrite(V2, on);
Blynk.syncVirtual(V2);
}
else if (group == 1) {
if (on == 1 ) {
transmitter.groupOn(TRANSMITTER_ID);
Blynk.virtualWrite(V0, 1);
Blynk.virtualWrite(V1, 1);
Blynk.virtualWrite(V2, 1);
Blynk.syncVirtual(V0, V1, V2);
}
else {
transmitter.groupOff(TRANSMITTER_ID);
Blynk.virtualWrite(V0, 0);
Blynk.virtualWrite(V1, 0);
Blynk.virtualWrite(V2, 0);
Blynk.syncVirtual(V0, V1, V2);
}
}
else {
Serial.println("Not my remote controller?");
}
Serial.print("Recieved a signal: ");
Serial.print("transmitter_id="); Serial.print(transmitter2);
Serial.print(", group="); Serial.print(group);
Serial.print(", on="); Serial.print(on);
Serial.print(", channel="); Serial.print(channel);
Serial.print(", dim="); Serial.print(dim);
Serial.println("");
terminal.println("Recieved a signal!");
terminal.flush();
}
}
***************************************************************************/
My next challenge is to implement a receiver that updates the Blynk app (and perhaps retransmit) when wall mounted RF-switches or remote controllers are used. For this to work I think I need to get a LoRa transceiver. The cheap XY-MK-5V receivers that I’ve done some testing with is, by design, worthless!
Suggestion for a Blynk appropriate ESP board with matching LoRa module would be much appreciated!
@Costas thanks for the code and help! Guessing the category could be changed to “Solved” or “Awaiting new hardware”