/* Radio RFM69 Radio Manager for ESP8266 Based on sample code by Felix Rusu - http://LowPowerLab.com/contact Copyright (C) 2016 by Xose PĂ©rez This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Requires encapsulating any reference to SPCR and SPSR in SPIFlash.cpp in an #if clause like this: #if defined(SPCR) & defined(SPSR) ... #endif */ #include "RFM69Manager.h" bool RFM69Manager::initialize(uint8_t frequency, uint8_t nodeID, uint8_t networkID, const char* key, uint8_t gatewayID, int16_t targetRSSI) { bool ret = RFM69_ATC::initialize(frequency, nodeID, networkID); encrypt(key); _gatewayID = gatewayID; if (_gatewayID > 0) enableAutoPower(targetRSSI); if (_isRFM69HW) setHighPower(); #if RADIO_DEBUG char buff[50]; sprintf(buff, "[RADIO] Working at %d Mhz", frequency == RF69_433MHZ ? 433 : frequency == RF69_868MHZ ? 868 : 915); Serial.println(buff); Serial.print(F("[RADIO] Node: ")); Serial.println(nodeID); Serial.print(F("[RADIO] Network: ")); Serial.println(networkID); if (gatewayID == 0) { Serial.println("[RADIO] This node is a gateway"); } else { Serial.print(F("[RADIO] Gateway: ")); Serial.println(gatewayID); } Serial.println(F("[RADIO] Auto Transmission Control (ATC) enabled")); #endif return ret; } void RFM69Manager::promiscuous(bool promiscuous) { RFM69_ATC::promiscuous(promiscuous); #if RADIO_DEBUG if (_promiscuousMode) { Serial.println(F("[RADIO] Promiscuous mode ON")); } else { Serial.println(F("[RADIO] Promiscuous mode OFF")); } #endif } // overriding select the RFM69 transceiver (save SPI settings, set CS low) void RFM69Manager::select() { noInterrupts(); #if defined (SPCR) && defined (SPSR) // save current SPI settings _SPCR = SPCR; _SPSR = SPSR; #endif // set RFM69 SPI settings SPI.setDataMode(SPI_MODE0); SPI.setBitOrder(MSBFIRST); #if defined(ARDUINO_ARCH_ESP8266) SPI.setClockDivider(SPI_CLOCK_DIV2); // speeding it up for the ESP8266 #else SPI.setClockDivider(SPI_CLOCK_DIV4); #endif digitalWrite(_slaveSelectPin, LOW); } void RFM69Manager::onMessage(TMessageCallback fn) { _callback = fn; } void RFM69Manager::separator(char sep) { _separator = sep; } bool RFM69Manager::loop() { boolean ret = false; if (receiveDone()) { uint8_t senderID = SENDERID; uint8_t targetID = _promiscuousMode ? TARGETID : _address; int16_t rssi = RSSI; uint8_t length = DATALEN; char buffer[length + 1]; strncpy(buffer, (const char *) DATA, length); buffer[length] = 0; // Do not send ACKs in promiscuous mode, // we want to listen without being heard if (!_promiscuousMode) { if (ACKRequested()) sendACK(); } uint8_t parts = 1; for (uint8_t i=0; i 1) { char sep[2] = {_separator, 0}; uint8_t packetID = 0; char * name = strtok(buffer, sep); char * value = strtok(NULL, sep); if (parts > 2) { char * packet = strtok(NULL, sep); packetID = atoi(packet); } _message.messageID = ++_receiveCount; _message.packetID = packetID; _message.senderID = senderID; _message.targetID = targetID; _message.name = name; _message.value = value; _message.rssi = rssi; ret = true; if (_callback != NULL) { _callback(&_message); } } } return ret; } bool RFM69Manager::send(uint8_t destinationID, char * name, char * value, uint8_t retries, bool requestACK) { char message[RF69_MAX_DATA_LEN]; #if SEND_PACKET_ID if (++_sendCount == 0) _sendCount = 1; snprintf(message, RF69_MAX_DATA_LEN-1, "%s%c%s%c%d", name, _separator, value, _separator, _sendCount); #else snprintf(message, RF69_MAX_DATA_LEN-1, "%s%c%s", name, _separator, value); #endif #if RADIO_DEBUG Serial.print(F("[RADIO] Sending: ")); Serial.print(message); #endif bool ret = true; if (retries > 0) { ret = sendWithRetry(destinationID, message, strlen(message), retries); } else { RFM69_ATC::send(destinationID, message, strlen(message), requestACK); } #if RADIO_DEBUG if (ret) { Serial.println(" OK"); } else { Serial.println(" KO"); } #endif return ret; }