#include #include using namespace ace_crc::crc16ccitt_nibble; #define RF_PACKET_SIZE 16 // RF69 ESP8266 connections: // CS/NSS pin: D8 // DIO0 pin: D1 // RESET pin: D3 // SCK D5 // MOSI D7 // MISO D6 RF69 radio1 = new Module(D8, D1, D3); volatile bool receivedFlag = false; // we make a structure for all settings (in the full project we set this with MQTT-topic and JSON-stream from Host-Web-Server) struct setvals { int ontime =300; // holdtime for each relais (millisecs), its possible for a defined pulstime on the external gate control (you can change to longer) String sync ="21A4"; // the syncword in a RF-stream for kinetic switches... String c1[2] = {"C46A01", "EF3B04"}; // three hex values for a indentifier kinetic-button ('C46A' is kinetic switch ID (from the swicht backside label), next hex value is the button-id ) String c2[2] = {"C46A02", "EF3B02"}; // three hex values for a indentifier kinetic-button ('C46A' is kinetic switch ID (from the swicht backside label), next hex value is the button-id ) // '01 - left button // '02' - right button // '04' - middle button } settings; // outputs #define ch1 16 // D0 3,3 V Relais on pnp-transistor (low active) #define ch2 4 // D2 3,3 V Relais on pnp-transistor (low active) unsigned long t1; // member holdtime chanel 1 unsigned long t2; // member holdtime chanel 2 uint8_t* getkeyarray(String keyid, int hex ){ unsigned int str_len = keyid.length() + 1; uint8_t* payload = new byte[str_len]; // Allocate memory on the heap char charArray[str_len]; keyid.toCharArray(charArray, str_len); unsigned long number = strtoul( charArray, nullptr, 16); for(int i= keyid.length()/2; i>=1; i--) // start with lowest byte of number { if (hex==1){ payload[i] = number & 0xFF; } else { payload[i] = byte( number); } number >>= 8; // get next byte into position } uint8_t* pl= new byte[(keyid.length()/2)-1]; return payload; } bool radioPacketValid(const uint8_t* buf) { byte messageArr[] = { buf[1], buf[2], buf[3] }; unsigned long messageCRC = (buf[4] << 8) | buf[5]; crc_t crc = crc_init(); crc = crc_update(crc, messageArr, 3); crc = crc_finalize(crc); return ((unsigned long)crc) == messageCRC; } void printHex(uint8_t num) { char hexCar[2]; sprintf(hexCar, "%02X ", num); Serial.print(hexCar); } void setup() { Serial.begin(115200); pinMode(ch1, OUTPUT); pinMode(ch2, OUTPUT); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(ch1, HIGH); digitalWrite(ch2, HIGH); digitalWrite(LED_BUILTIN, HIGH); Serial.print(F("[RF69] Initializing ... ")); // carrier frequency: 433.3 MHz // bit rate: 96kbps // frequency deviation: 50kHz // Rx bandwidth: 100kHz // output power: 13 dBm // preamble length: 32 bits int rstate = radio1.begin(433.3, 96, 50, 100.0, 13, 32); radio1.setCrcFiltering(false); radio1.fixedPacketLengthMode(RF_PACKET_SIZE); if (rstate == RADIOLIB_ERR_NONE) { Serial.println(F("success!")); } else { Serial.print(F("failed, code ")); Serial.println(rstate); while (true); } uint8_t* buf = getkeyarray(settings.sync,1); uint8_t sd[] = {buf[1], buf[2]}; if (radio1.setSyncWord(sd, sizeof(sd)) == RADIOLIB_ERR_INVALID_SYNC_WORD) { Serial.println(F("[RF69] Selected sync word is invalid for this module!")); while (true); } radio1.enableSyncWordFiltering(0); radio1.setPreambleLength(32); // RF-Stream length (bytes) radio1.setDio0Action(handleRfPacket); radio1.startReceive(); } // This will be registered as an ISR for receiving packets from the // 433 MHz radio. #if defined(ESP8266) || defined(ESP32) ICACHE_RAM_ATTR #endif void handleRfPacket() { receivedFlag = true; uint8_t buf[RF_PACKET_SIZE]; float rssi; int rstate = radio1.readData(buf, sizeof(buf)); // output all bytes as hex, for check or modify RF-stream (bytes) // for (int i = 0; i < sizeof(buf); i++) { // printHex(buf[i]); // } // Serial.println(); if (rstate == RADIOLIB_ERR_NONE) { rssi = radio1.getRSSI(); if (rssi < -120) { return; } } else if (rstate == RADIOLIB_ERR_RX_TIMEOUT) { Serial.println("[RF69] Receive timeout!"); return; } else { // some other error occurred Serial.printf("[RF69] Unknown error: %d\n", rstate); return; } if (radioPacketValid(buf)) { // create a new array from first three RF-data bytes byte m1[] = {buf[1], buf[2], buf[3] }; //read data // create a new array from first thre keyident-bytes (chanel1) from both settings c1-array items uint8_t* buf = getkeyarray(settings.c1[0],0); uint8_t l1[] = {buf[1], buf[2], buf[3]}; buf = getkeyarray(settings.c1[1],0); uint8_t l2[] = {buf[1], buf[2], buf[3]}; //check RF-data with keyident (chanel 1) and set output 1 if (memcmp (m1, l1, 3) == 0 || memcmp (m1, l2, 3) ==0) { Serial.println("left"); digitalWrite(ch1, LOW); t1 = millis(); } // create a new array from first thre keyident-bytes (chanel2) from both settings c2-array items buf = getkeyarray(settings.c2[0],0); uint8_t r1[] = {buf[1], buf[2], buf[3]}; buf = getkeyarray(settings.c2[1],0); uint8_t r2[] = {buf[1], buf[2], buf[3]}; //check RF-data with keyident (chanel 1) and set output 2 if (memcmp (m1, r1, 3) == 0 || memcmp (m1, r2, 3) == 0) { Serial.println("right"); digitalWrite(ch2, LOW); t2 = millis(); } return; } } void loop() { if (receivedFlag) { receivedFlag = false; radio1.startReceive(); } unsigned long currentMillis = millis(); if (currentMillis > t1 + settings.ontime ) { digitalWrite(ch1, HIGH); // reset output chanel1 after ontime- settings (ms) } if (currentMillis > t2 + settings.ontime ) { digitalWrite(ch2, HIGH); // reset output chanel2 after ontime- settings (ms) } }