Replies: 4 comments 19 replies
-
Hello Håkan! There's another way to use loadFDRS() where you tell it what ID you want to use, could that be of help? ( I am still planning to fix that float issue soon! |
Beta Was this translation helpful? Give feedback.
-
Hi! Code: /*
MCP23017 uses inverted logic. Output from 0 to 15
To set relay ON or OFF convert short integer to 'binary' and set each output according
To set relay 1,3 and 4 to ON (=0) and the rest to OFF (=1)
convert 'binary representation 1111111111110100 = 65524
SEND:
[{"id":31,"type":0,"data":65524}]
compile with DOIT ESP32 DEVKIT V1
*/
#define FDRS_DEBUG
#define READING_ID 31
#define GTWY_MAC 0x01
#define USE_ESPNOW
#define status_PIN 2
#include <fdrs_node.h>
#include <Adafruit_MCP23X17.h>
Adafruit_MCP23X17 mcp;
// for debug only
String str_binary = "";
/*### incoming data variable ###
make sure all relays are set to OFF if node restarts for safety
1111111111111111 = 65535
*/
int tmpdata = 65535;
//########## Non blocking delay var's #################
unsigned long previousMillis = 0;
const long interval = 2000;
//only send if value have changed not to stress system, causes TIMEOUT !!!!
//int previousValue = 0;
//int currentValue = 0;
//##############################
void fdrs_recv_cb(DataReading theData) {
digitalWrite(status_PIN,LOW);//for visual debug in field
tmpdata = (unsigned short)theData.d;
str_binary = "";
String tmpbit;
//#### write new values to MCP23017 #####
// read bitvalue at each position and write value to MCP23017
for(int i = 15; i >= 0; i--) {
// check bits, LSB first
int bitValue = bitRead(tmpdata, i); // read the bit at position i
tmpbit = String(bitValue);//save result for debug
mcp.digitalWrite(i, bitValue);//write value to MCP23017
str_binary = str_binary + tmpbit;//add in debugstring
//****************** If possible set topic to fdrs/data/relay(i) with value bitvalue ************
}
}
void setup() {
pinMode(status_PIN, OUTPUT);//visualizing node ok
beginFDRS();
if (addFDRS(1000, fdrs_recv_cb))
subscribeFDRS(READING_ID);
Wire.begin(); // I/O expander
mcp.begin_I2C();
//set all pins to output
for (int i = 0; i <= 15; i++) {
mcp.pinMode(i, OUTPUT);
}
}
void loop() {
unsigned long currentMillis = millis();
//currentValue = tmpdata;
loopFDRS();
//avoid stressing system, only send when new value arrives
//if (currentValue != previousValue) {
if (currentMillis - previousMillis >= interval) {
// save the last time when code was running
previousMillis = currentMillis;
//****************** If possible set topic to fdrs/data/relayx with payload bitvalue (0/1)************
//send data
loadFDRS(tmpdata,STATUS_T);
// DBG(sendFDRS());
if(sendFDRS()){
//LED blinking: alive,sending OK
digitalWrite(status_PIN,HIGH);
Serial.println(str_binary);
DBG("TMPDATA ");
DBG(tmpdata);
} else {
//LED NOT blinking: ERROR of some kind
digitalWrite(status_PIN,LOW);
DBG("ERROR SENDING DATA");
}
}//end if currentmillis...
//}//end if current value
//previousValue = currentValue;
//sleepFDRS(10); //Sleep time in seconds
}//end void loop ================================================================` I'm not sure what "There's another way to use loadFDRS() where you tell it what ID you want to use, could that be of help? (void loadFDRS(float d, uint8_t t, uint16_t id)" will do ? Still the float value to be sent,right? Best Regards Håkan |
Beta Was this translation helpful? Give feedback.
-
Hi again! One 'dirty' way is to send 'Type' as o to 15 indicating what pin numer is actual and as data either 0 or 1. This I can catch in Home assistant. I have two lora nodes and my relay node running and data comes in just fine in Home assistant via mqtt. I have tested to send from mqtt explorer and data changes in Home assistant bur I realize that data is not recieved in relay node! Is it correct to senda data TO node in json like [{"id":31,"type":0,"data":65524}] or is it another format when publishing to node ?? I tried to see from code but I can't really find out. So in summary have I understood you right with extra argument ? |
Beta Was this translation helpful? Give feedback.
-
I have got a'lot of help from the developer Timm struggling with ESPnow relay nodes and just wanted to do a follow up and share if other people have had the same experience and like me are not proffesional programmers. Code below is an example similar to irrigation node example but a little bit easier to change number of relay's needed and with a status LED to easier trobleshoot eventual problems and check when connection got's bad in the field . I also have an example using MCP23017 only using 2 pin's (I2C) to get 16 outputs if one needs a'lot of outputs. /* Inspired from Timm's work and all credit to him! Sharing this in case someone else beside me can have use for it (as it is) ESP-NOW Sensor Example with various number of relay's just changing a few lines of code When setting a relay from Front end, the nodes send back and update relay status. Relay's are set a dirty way using type as relay number but works ok, and you only need to define one READING_ID regardless of number of relays. id = node id(READING_ID), type = relay no (0-3), data = on(0) off(1) inverted mode Topic: fdrs/command (imortant! (fdrs/data won't work ) compile with DOIT ESP32 DEVKIT V1 Or whatever mcu used but check pin's! */
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#include <FastLED.h> // for visual status of node
// programmable status LED
#define NUM_LEDS 1
#define status_PIN 23
CRGB leds[NUM_LEDS];
int tmpdata; // holds status 0 or 1
int tmp_pinnumber; // holds relay number
bool isData = false; // check if data received
bool firsttime = true; // set all relays to OFF when reboot and update variable's in Frontend
bool connected = false; // conn status to GW
const int relay_no = 4; //number of relays to use, add in struct Relay to match pin number and no of relays. 1 to number of avaliable pins
struct Relay {
int pin; // Pin number connected to the relay
//uncomment if relay is set by HIGH or LOW
bool status; // Current status of the relay (0: on, 1: off) inverted mode
//bool status; // Current status of the relay (0: off, 1: on) non inverted mode
};
//change to number of relays to use and define pin number
Relay relays[relay_no] = {
{ 4, 1 }, // Relay 0 connected to pin 4, initially off if inverted mode
{ 0, 1 }, // Relay 1 connected to pin 0, initially off if inverted mode
{ 2, 1 }, // Relay 2 connected to pin 2, initially off if inverted mode
{ 15, 1 } // Relay 3 connected to pin 15, initially off if inverted mode
};
//##########################################
void fdrs_recv_cb(DataReading theData) {
isData = true;
DBG("Indata");
tmp_pinnumber = theData.t;
tmpdata = static_cast<int>(theData.d); //convert to integer from float
loadFDRS(tmpdata, tmp_pinnumber);
//#########################################
}
void setup() {
// Set relay pins as outputs
for (int i = 0; i < relay_no; i++) {
pinMode(relays[i].pin, OUTPUT);
}
// initialize status LED
FastLED.addLeds<WS2811, status_PIN, RGB>(leds, NUM_LEDS); //change to right type
FastLED.setBrightness(32); //0 - 255
beginFDRS();
if (addFDRS(1000, fdrs_recv_cb)) {
subscribeFDRS(READING_ID);
DBG("Connected to Gateway" + GTWY_MAC);
leds[0] = CRGB::Green;
FastLED.show();
connected = true;
} else {
DBG("Not Connected to Gateway");
leds[0] = CRGB::Red;
FastLED.show();
connected = false;
}
// for debug, prints out a string like: 'off off off off off' to check in monitor that all works as expecte
String binaryString = "";
for (int i = 0; i < relay_no; i++) {
binaryString += (relays[i].status) ? " Off " : " On ";
}
DBG("Relaystatus 0-3 :");
DBG(binaryString);
// ##############################################################################
}
void loop() {
loopFDRS();
if (!connected) { //blink status LED to show that we are not connected
leds[0] = CRGB::Red;
FastLED.show();
delay(1000);
leds[0] = CRGB::White;
FastLED.show();
//delay(500);
pingFDRS(1000);
}
if (firsttime && connected) { //if connected, send all relay's to off to Front end
firsttime = false;
for (int i = 0; i < relay_no; i++) {
loadFDRS(1, i, READING_ID);
if (sendFDRS()) {
DBG("OK");
}
} //end loadFDRS loop
} //end firsttime
if (isData) {
isData = false;
if (sendFDRS()) {
leds[0] = CRGB::Blue; //blink LED to show that command has been sent OK
FastLED.show();
delay(300);
leds[0] = CRGB::Black;
FastLED.show();
delay(300);
leds[0] = CRGB::Green;
FastLED.show();
//set relay
// ########## Set relay to new status #######################
relays[tmp_pinnumber].status = tmpdata;
digitalWrite(relays[tmp_pinnumber].pin, relays[tmp_pinnumber].status);
// ####################################################
// for debug
String binaryString = "";
for (int i = 0; i < relay_no; i++) {
binaryString += (relays[i].status) ? " Off " : " On ";
}
DBG("Relaystatus 0-3 :");
DBG(binaryString);
} else {
//ERROR of some kind, /blink LED to show that command has not been sent
leds[0] = CRGB::Red;
FastLED.show();
delay(300);
leds[0] = CRGB::Black;
FastLED.show();
delay(300);
leds[0] = CRGB::Yellow;
FastLED.show();
DBG("ERROR SENDING DATA");
}
}
} //end void loop Regards Håkan |
Beta Was this translation helpful? Give feedback.
-
Hi!
I have a Node sending relaystatus as a float value. My problem is that I collect data in Home Assistant and it seems more or less impossible to create a sensor for every inudividual bit in value. In Node sketch I have split the value to bit true/false. So my question is, can topic be changed from dfrs/data to dfrs/data/relay1, dfrs/data/relay2 etc. So I can send a specific topic for every relay.
I know
loadFDRS(data,STATUS_T);
don't include the option to select topic,but is there a workaround ?Best Regards Håkan
Beta Was this translation helpful? Give feedback.
All reactions