merge new RFM69_OTA; upgrade wireless programming

This commit is contained in:
LowPowerLab 2016-11-17 21:13:22 -05:00
parent 7f140f04da
commit 18494fe085
27 changed files with 439319 additions and 402 deletions

View File

@ -10,9 +10,9 @@ cache:
env:
- PLATFORMIO_CI_SRC=Examples/DeepSleep
- PLATFORMIO_CI_SRC=Examples/DeepSleep_usingLowPowerLibrary
- PLATFORMIO_CI_SRC=Examples/DoorBellMote
- PLATFORMIO_CI_SRC=Examples/GarageMote
- PLATFORMIO_CI_SRC=Examples/GarageMote_base
- PLATFORMIO_CI_SRC=Examples/Gateway
- PLATFORMIO_CI_SRC=Examples/IOShield
- PLATFORMIO_CI_SRC=Examples/MailboxNotifier
@ -33,8 +33,8 @@ env:
- PLATFORMIO_CI_SRC=Examples/Struct_send
- PLATFORMIO_CI_SRC=Examples/TxRxBlinky
- PLATFORMIO_CI_SRC=Examples/WeatherNode
- PLATFORMIO_CI_SRC=Examples/WirelessProgramming_gateway
- PLATFORMIO_CI_SRC=Examples/WirelessProgramming_node
- PLATFORMIO_CI_SRC=Examples/WirelessProgramming_OTA\Node
- PLATFORMIO_CI_SRC=Examples/WirelessProgramming_OTA\Programmer
install:
- pip install -U platformio

View File

@ -1,12 +1,10 @@
// **********************************************************************************
// DoorBellMote sketch works with Moteinos equipped with RFM69W/RFM69HW
// Can be adapted to use Moteinos/Arduinos using RFM12B or other RFM69 variants (RFM69CW, RFM69HCW)
// http://www.LowPowerLab.com/
// 2015-07-22 (C) Felix Rusu of http://www.LowPowerLab.com/
// **********************************************************************************
// DoorBellMote sketch works with Moteinos equipped with RFM69W/RFM69HW/RFM69CW/RFM69HCW
// It detects current flow at the doorbell transformer and send a message each time to the gateway
// It can trigger doorbell through a relay powered from pins D6+D7
// Deploy and forget: wirelessly programmable via Moteino + WirelessHEX69 library
// Deploy and forget: wirelessly programmable via Moteino + RFM69_OTA library
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -22,24 +20,21 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h> //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <SPI.h> //comes with Arduino IDE (www.arduino.cc)
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/SITUATION!
//*****************************************************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define GATEWAYID 1
#define NODEID 133
#define NETWORKID 100
@ -48,7 +43,10 @@
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY "sampleEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//*****************************************************************************************************************************
#define CHIMEPIN 4 // active HIGH chime signal from detector H11AA1 circuit
#define RELAYPIN1 6 //for the bell ring relay we just need 2 digital pins together to activate the relay for a short pulse
#define RELAYPIN2 7 //for the bell ring relay we just need 2 digital pins together to activate the relay for a short pulse
@ -68,12 +66,16 @@
#define DEBUGln(input)
#endif
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
/////////////////////////////////////////////////////////////////////////////
#endif
//*****************************************************************************************************************************
// flash(SPI_CS, MANUFACTURER_ID)
// SPI_CS - CS pin attached to SPI flash chip (8 in case of Moteino)
// MANUFACTURER_ID - OPTIONAL, 0xEF30 for windbond 4mbit flash (Moteino OEM)
/////////////////////////////////////////////////////////////////////////////
//*****************************************************************************************************************************
SPIFlash flash(8, 0xEF30); //regular Moteinos have FLASH MEM on D8, MEGA has it on D4
char buff[50];
@ -92,6 +94,10 @@ void setup(void)
#endif
radio.encrypt(ENCRYPTKEY);
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
sprintf(buff, "DoorBellMote : %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
DEBUGln(buff);
@ -163,7 +169,7 @@ void loop()
}
// wireless programming token check
// DO NOT REMOVE, or GarageMote will not be wirelessly programmable any more!
// DO NOT REMOVE, or this Moteino will not be wirelessly programmable any more!
CheckForWirelessHEX(radio, flash, true);
//first send any ACK to request

View File

@ -1,17 +1,10 @@
// **********************************************************************************************************
// GarageMote garage door controller sketch that works with Moteinos equipped with RFM69W/RFM69HW
// Can be adapted to use Moteinos/Arduinos using RFM12B or other RFM69 variants (RFM69CW, RFM69HCW)
// GarageMote garage door controller sketch that works with Moteinos equipped with RFM69W/RFM69HW/RFM69CW/RFM69HCW
// Monitors door position (open, closed, closing, unknown)
// Can trigger door open/close
// http://www.LowPowerLab.com/GarageMote
// 2015-05-05 (C) Felix Rusu of http://www.LowPowerLab.com/
// **********************************************************************************************************
// It uses 2 hall effect sensors (and magnets mounted on the garage belt/chain) to detect the position of the
// door, and a small signal relay to be able to toggle the garage opener.
// Implementation details are posted at the LowPowerLab blog
// Door status is reported via RFM69 to a base Moteino, and visually on the onboard Moteino LED:
// - solid ON - door is in open position
// - solid OFF - door is in closed position
// - blinking - door is not in either open/close position
// - pulsing - door is in motion
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -27,32 +20,29 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// ***************************************************************************************************************************
// **********************************************************************************
//#define WEATHERSHIELD //uncomment if WeatherShield is present to report temp/humidity/pressure periodically
//#define WEATHERSENDDELAY 300000 // send WeatherShield data every so often (ms)
// ***************************************************************************************************************************
#include <RFM69.h> //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h> //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <SPI.h> //comes with Arduino IDE (www.arduino.cc)
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
#ifdef WEATHERSHIELD
#include <SFE_BMP180.h> //get it here: https://github.com/LowPowerLab/SFE_BMP180
#include <SI7021.h> //get it here: https://github.com/LowPowerLab/SI7021
#include <Wire.h>
#endif
//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/TRANSCEIVER SETTINGS/REQUIREMENTS
//*****************************************************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define GATEWAYID 1
#define NODEID 11
#define NETWORKID 250
@ -61,7 +51,10 @@
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY "sampleEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//*****************************************************************************************************************************
#define HALLSENSOR1 A0
#define HALLSENSOR1_EN 4
#define HALLSENSOR2 A1
@ -117,11 +110,16 @@ unsigned long ledPulseTimestamp=0;
unsigned long lastWeatherSent=0;
int ledPulseValue=0;
boolean ledPulseDirection=false; //false=down, true=up
RFM69 radio;
char Pstr[10];
char sendBuf[30];
SPIFlash flash(8, 0xEF30); //WINDBOND 4MBIT flash chip on CS pin D8 (default for Moteino)
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
void setup(void)
{
#ifdef SERIAL_EN
@ -141,6 +139,10 @@ void setup(void)
#endif
radio.encrypt(ENCRYPTKEY);
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
char buff[50];
sprintf(buff, "GarageMote : %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
DEBUGln(buff);

View File

@ -1,132 +0,0 @@
// **********************************************************************************************************
// GarageMote garage door controller base receiver sketch that works with Moteinos equipped with HopeRF RFM69W/RFM69HW
// Can be adapted to use Moteinos using RFM12B
// This is the sketch for the base, not the controller itself, and meant as another example on how to use a
// Moteino as a gateway/base/receiver
// 2013-09-13 (C) felix@lowpowerlab.com, http://www.LowPowerLab.com
// **********************************************************************************************************
// Creative Commons Attrib Share-Alike License
// You are free to use/extend this code/library but please abide with the CCSA license:
// http://creativecommons.org/licenses/by-sa/3.0/
// **********************************************************************************************************
#include <RFM69.h>
#include <SPI.h>
#include <SPIFlash.h>
//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/SITUATION!
//*****************************************************************************************************************************
#define NODEID 1
#define GARAGENODEID 99
#define NETWORKID 100
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define LED 9
#define SERIAL_BAUD 115200
#define ACK_TIME 30 // # of ms to wait for an ack
//*****************************************************************************************************************************
RFM69 radio;
SPIFlash flash(8, 0xEF30); //EF40 for 16mbit windbond chip
byte readSerialLine(char* input, char endOfLineChar=10, byte maxLength=64, uint16_t timeout=50);
void setup() {
Serial.begin(SERIAL_BAUD);
delay(10);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
radio.setHighPower(); //must include only for RFM69HW!
#endif
radio.encrypt(ENCRYPTKEY);
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
if (flash.initialize())
Serial.println("SPI Flash Init OK!");
else
Serial.println("SPI Flash Init FAIL! (is chip present?)");
}
byte ackCount=0;
byte inputLen=0;
char input[64];
void loop() {
//process any serial input
inputLen = readSerialLine(input);
if (inputLen >= 6)
{
if (input[0]=='G' && input[1]=='R' && input[2]=='G' && input[3]=='O' && input[4]=='P' && input[5]=='N')
{
Serial.print("OPN ... ");
if (radio.sendWithRetry(GARAGENODEID, "OPN", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='G' && input[1]=='R' && input[2]=='G' && input[3]=='C' && input[4]=='L' && input[5]=='S')
{
Serial.print("CLS ... ");
if (radio.sendWithRetry(GARAGENODEID, "CLS", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='G' && input[1]=='R' && input[2]=='G' && input[3]=='S' && input[4]=='T' && input[5]=='S')
{
Serial.print("STS ... ");
if (radio.sendWithRetry(GARAGENODEID, "STS", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
//if (input == 'i')
//{
// Serial.print("DeviceID: ");
// word jedecid = flash.readDeviceId();
// Serial.println(jedecid, HEX);
//}
}
if (radio.receiveDone())
{
Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
for (byte i = 0; i < radio.DATALEN; i++)
Serial.print((char)radio.DATA[i]);
Serial.print(" [RSSI:");Serial.print(radio.RSSI);Serial.print("]");
if (radio.ACKRequested())
{
byte theNodeID = radio.SENDERID;
radio.sendACK();
Serial.print("[ACK-sent]");
}
Serial.println();
Blink(LED,3);
}
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
// reads a line feed (\n) terminated line from the serial stream
// returns # of bytes read, up to 255
// timeout in ms, will timeout and return after so long
byte readSerialLine(char* input, char endOfLineChar, byte maxLength, uint16_t timeout)
{
byte inputLen = 0;
Serial.setTimeout(timeout);
inputLen = Serial.readBytesUntil(endOfLineChar, input, maxLength);
input[inputLen]=0;//null-terminate it
Serial.setTimeout(0);
//Serial.println();
return inputLen;
}

View File

@ -1,13 +1,33 @@
// Sample RFM69 receiver/gateway sketch, with ACK and optional encryption, and Automatic Transmission Control
// Passes through any wireless received messages to the serial port & responds to ACKs
// It also looks for an onboard FLASH chip, if present
// RFM69 library and sample code by Felix Rusu - http://LowPowerLab.com/contact
// Copyright Felix Rusu (2015)
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
// 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.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h> //comes with Arduino IDE (www.arduino.cc)
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE install (www.arduino.cc)
//*********************************************************************************************
//************ IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE *************
@ -20,9 +40,14 @@
//#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*********************************************************************************************
//Auto Transmission Control - dials down transmit power to save battery
//Usually you do not need to always transmit at max output power
//By reducing TX power even a little you save a significant amount of battery power
//This setting enables this gateway to work with remote nodes that have ATC enabled to
//dial their power down to only the required level
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
//*********************************************************************************************
#define SERIAL_BAUD 115200
#ifdef __AVR_ATmega1284P__

View File

@ -1,9 +1,6 @@
// **********************************************************************************
// IOShield sample sketch works with Moteinos equipped with RFM69W/RFM69HW
// Can be adapted to use Moteinos/Arduinos using other RFM69 variants (RFM69CW, RFM69HCW) or even RFM12b
// http://moteino.com
// IOShield sample sketch works with Moteinos equipped with RFM69W/RFM69HW/RFM69CW/RFM69HCW
// http://www.LowPowerLab.com/IOShield
// 2015-03-13 (C) Felix Rusu of Low Power Lab LLC
// **********************************************************************************
// It works with IOShield(s) that have 2 shift registers (74HC595)
// You can daisy chain up to 16 IOShields for a total of 256 outputs/stations/zones
@ -15,6 +12,10 @@
// - 'OFF' turns off all outputs
// - 'PRG A:n ... Z:m' - runs a program in sequence, first token is station/zone/output number, second is the number of seconds to turn it ON for
// WARNING: there is no delay between switching zones, so beware of the frequency you switch the valves on/off
// Example use: control your sprinkler controller wirelessly, more at lowpowerlab.com/gateway
// Deploy and forget: wirelessly programmable via Moteino + RFM69_OTA library
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -30,30 +31,31 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h> //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <SPI.h> //comes with Arduino IDE (www.arduino.cc)
//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/SITUATION!
//*****************************************************************************************************************************
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define GATEWAYID 1
#define NODEID 121
#define NETWORKID 250
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY "sampleEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//*****************************************************************************************************************************
#define LATCHPIN 5
#define CLOCKPIN 6
#define DATAPIN 7
@ -71,12 +73,17 @@
#define DEBUGln(input)
#endif
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
/////////////////////////////////////////////////////////////////////////////
#endif
//*****************************************************************************************************************************
// flash(SPI_CS, MANUFACTURER_ID)
// SPI_CS - CS pin attached to SPI flash chip (8 in case of Moteino)
// MANUFACTURER_ID - OPTIONAL, 0xEF30 for windbond 4mbit flash (Moteino OEM)
/////////////////////////////////////////////////////////////////////////////
//*****************************************************************************************************************************
SPIFlash flash(8, 0xEF30); //regular Moteinos have FLASH MEM on D8, MEGA has it on D4
char buff[30]; //max radio DATA length = 61
String str;
@ -96,6 +103,10 @@ void setup(void)
#endif
radio.encrypt(ENCRYPTKEY);
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
//sprintf(buff, "IOShield : %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
//DEBUGln(buff);
DEBUGln(F("START"));

View File

@ -1,10 +1,11 @@
// **********************************************************************************************************
// MightyHat gateway base unit sketch that works with MightyHat with onboard RFM69W/RFM69HW
// MightyHat gateway base unit sketch that works with MightyHat equipped with RFM69W/RFM69HW/RFM69CW/RFM69HCW
// This will relay all RF data over serial to the host computer (RaspberryPi, PC etc) and vice versa
// http://LowPowerLab.com/MightyHat
// Copyright http://www.LowPowerLab.com (2015)
// Also see http://LowPowerLab.com/gateway
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
// This program is free software; you can redistribute it
@ -19,10 +20,6 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
@ -31,18 +28,17 @@
// **********************************************************************************
#define MHAT_VERSION 3 //latest version is R3, change to "2" if you have a MightyHat R2
// ****************************************************************************************
#include <RFM69.h> //get it here: http://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPIFlash.h> //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <SPI.h> //comes with Arduino IDE (www.arduino.cc)
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
#include "U8glib.h" //https://bintray.com/olikraus/u8glib/Arduino
//u8g compared to adafruit lib: https://www.youtube.com/watch?v=lkWZuAnHa2Y
//draing bitmaps: https://www.coconauts.net/blog/2015/01/19/easy-draw-bitmaps-arduino/
//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/SCENARIO !
//*****************************************************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NODEID 1 //the gateway has ID=1
#define NETWORKID 100 //all nodes on the same network can talk to each other
//#define FREQUENCY RF69_433MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)

File diff suppressed because it is too large Load Diff

View File

@ -23,10 +23,6 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
@ -42,9 +38,9 @@
#include <SparkFunBME280.h> //get it here: https://github.com/sparkfun/SparkFun_BME280_Breakout_Board/tree/master/Libraries/Arduino/src
#include <Wire.h> //comes with Arduino
//*********************************************************************************************
//************ IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NODEID 88 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
#define GATEWAYID 1

View File

@ -1,16 +1,36 @@
// Sample RFM69 sender/node sketch, with ACK and optional encryption, and Automatic Transmission Control
// Sends periodic messages of increasing length to gateway (id=1)
// It also looks for an onboard FLASH chip, if present
// RFM69 library and sample code by Felix Rusu - http://LowPowerLab.com/contact
// Copyright Felix Rusu (2015)
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
// 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.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE install (www.arduino.cc)
//*********************************************************************************************
//************ IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE *************
//************ IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE ************
//*********************************************************************************************
#define NODEID 2 //must be unique for each node on same network (range up to 254, 255 is used for broadcast)
#define NETWORKID 100 //the same on all nodes that talk to each other (range up to 255)
@ -21,7 +41,14 @@
//#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*********************************************************************************************
//Auto Transmission Control - dials down transmit power to save battery
//Usually you do not need to always transmit at max output power
//By reducing TX power even a little you save a significant amount of battery power
//This setting enables this gateway to work with remote nodes that have ATC enabled to
//dial their power down to only the required level (ATC_RSSI)
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -80
//*********************************************************************************************
#ifdef __AVR_ATmega1284P__
@ -34,7 +61,7 @@
#define SERIAL_BAUD 115200
int TRANSMITPERIOD = 150; //transmit a packet to gateway so often (in ms)
int TRANSMITPERIOD = 200; //transmit a packet to gateway so often (in ms)
char payload[] = "123 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buff[20];
byte sendSize=0;
@ -61,7 +88,7 @@ void setup() {
//For more variable nodes that can expect to move or experience larger temp drifts a lower margin like -70 to -80 would probably be better
//Always test your ATC mote in the edge cases in your own environment to ensure ATC will perform as you expect
#ifdef ENABLE_ATC
radio.enableAutoPower(-70);
radio.enableAutoPower(ATC_RSSI);
#endif
char buff[50];

View File

@ -23,10 +23,6 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
@ -39,9 +35,9 @@
#include <LowPower.h> //get library from: https://github.com/lowpowerlab/lowpower
#include "U8glib.h" //get library from: https://code.google.com/p/u8glib/
//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NODEID 122 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):

View File

@ -1,35 +1,52 @@
// **********************************************************************************************************
// Moteino gateway/base sketch that works with Moteinos equipped with HopeRF RFM69 transceivers (W/CW/HW/HCW)
// Moteino gateway/base sketch that works with Moteinos equipped with RFM69W/RFM69HW/RFM69CW/RFM69HCW
// This is a basic gateway sketch that receives packets from end node Moteinos, formats them as ASCII strings
// with the end node [ID] and passes them to Pi/host computer via serial port
// (ex: "messageFromNode" from node 123 gets passed to serial as "[123] messageFromNode")
// It also listens to serial messages that should be sent to listening end nodes
// (ex: "123:messageToNode" sends "messageToNode" to node 123)
// Make sure to adjust the settings to match your transceiver settings (frequency, HW etc).
// 2016 (C) Felix Rusu, http://www.LowPowerLab.com
// **********************************************************************************************************
// License: GPL 3.0, please see the License.txt file in library for details
// https://www.gnu.org/licenses/gpl-3.0.en.html
// **********************************************************************************************************
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
// 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.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <SPI.h> //already included in ArduinoIDE (www.arduino.cc)
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/SITUATION!
//*****************************************************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NODEID 1 //the ID of this node
#define NETWORKID 200 //the network ID of all nodes this node listens/talks to
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY "sampleEncryptKey" //identical 16 characters/bytes on all nodes, not more not less!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ACK_TIME 30 // # of ms to wait for an ack packet
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75 //target RSSI for RFM69_ATC (recommended > -80)
#define ACK_TIME 30 // # of ms to wait for an ack packet
//*****************************************************************************************************************************
// Serial baud rate must match your Pi/host computer serial port baud rate!
#define SERIAL_EN //comment out if you don't want any serial verbose output

View File

@ -1,37 +1,57 @@
// **********************************************************************************************************
// Moteino gateway/base sketch that works with Moteinos equipped with HopeRF RFM69 transceivers (W/CW/HW/HCW)
// This sketch uses a 2x20 newhaven RGB backlight LCD to display incoming messages from end nodes
// Moteino gateway/base sketch that works with Moteinos equipped with RFM69W/RFM69HW/RFM69CW/RFM69HCW
// This sketch uses a 2x20 Newhaven RGB backlight LCD to display incoming messages from end nodes
// http://www.digikey.com/product-search/en?keywords=NHD-C0220BIZ-FS(RGB)-FBW-3VM
// This is a basic gateway sketch that receives packets from end node Moteinos, formats them as ASCII strings
// with the end node [ID] and passes them to Pi/host computer via serial port
// (ex: "messageFromNode" from node 123 gets passed to serial as "[123] messageFromNode")
// It also listens to serial messages that should be sent to listening end nodes
// (ex: "123:messageToNode" sends "messageToNode" to node 123)
// Make sure to adjust the settings to match your transceiver settings (frequency, HW etc).
// 2014 (C) Felix Rusu, http://www.LowPowerLab.com
// **********************************************************************************************************
// License: GPL 3.0, please see the License.txt file in library for details
// https://www.gnu.org/licenses/gpl-3.0.en.html
// **********************************************************************************************************
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
// 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.
#include <RFM69.h> //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h> //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <SPI.h> //comes with Arduino IDE (www.arduino.cc)
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
#include <Wire.h> //included with Arduino IDE (www.arduino.cc)
#include "ST7036.h" //get it from here: https://bitbucket.org/fmalpartida/st7036-display-driver/src/
#include "LCD_C0220BiZ.h" //get it from here: https://bitbucket.org/fmalpartida/st7036-display-driver/src/
#include <Wire.h> //comes with Arduino
//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/SITUATION!
//*****************************************************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NODEID 1 //the ID of this node
#define NETWORKID 200 //the network ID of all nodes this node listens/talks to
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY "sampleEncryptKey" //identical 16 characters/bytes on all nodes, not more not less!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ACK_TIME 30 // # of ms to wait for an ack
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75 //target RSSI for RFM69_ATC (recommended > -80)
//*****************************************************************************************************************************
// Serial baud rate must match your Pi/host computer serial port baud rate!
#define SERIAL_EN //comment out if you don't want any serial verbose output
@ -56,7 +76,12 @@
#define DEBUGln(input);
#endif
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
SPIFlash flash(FLASH_SS, 0xEF30); //EF40 for 16mbit windbond chip
//initialize LCD
@ -74,6 +99,10 @@ void setup() {
#endif
radio.encrypt(ENCRYPTKEY);
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
char buff[50];
sprintf(buff, "\nTransmitting at %d Mhz...", radio.getFrequency()/1000000);

View File

@ -1,6 +1,11 @@
// Sample RFM69 sketch for PulseMote - reading an EE-SY310 based water/pulse meter
// Sample RFM69 sketch for PulseMote sketch works with Moteinos equipped with RFM69W/RFM69HW/RFM69CW/RFM69HCW
// Reads an EE-SY310 based water/pulse meter and reports readings like:
// - GPM - gallons per minute (when actively flowing)
// - GLM - gallons last minute (gallons used in the last minute)
// - GAL - total gallons used
// Example: https://lowpowerlab.com/blog/2013/02/02/meet-the-watermote-moteino-based-water-meter-reader-ee-sy310/
// Copyright (c) 2015 Felix Rusu (felix@lowpowerlab.com). All rights reserved.
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -16,31 +21,33 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// ***************************************************************************************************************************
#include <RFM69.h> //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h> //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <EEPROM.h>
#include <SPI.h>
// **********************************************************************************
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
#include <EEPROM.h> //included with Arduino IDE (www.arduino.cc)
#include <TimerOne.h>
//*********************************************************************************************
//************ IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NODEID 5
#define GATEWAYID 1
#define NETWORKID 250
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY "sampleEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//*****************************************************************************************************************************
#define PULSESPERGALLON 45 //how many pulses from sensor equal 1 gallon
#define GPMTHRESHOLD 8000 // GPM will reset after this many MS if no pulses are registered
#define XMITPERIOD 5000 // GPMthreshold should be less than 2*XMITPERIOD
@ -63,7 +70,16 @@
#define DEBUGln(input);
#endif
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
//*****************************************************************************************************************************
// flash(SPI_CS, MANUFACTURER_ID)
// SPI_CS - CS pin attached to SPI flash chip (8 in case of Moteino)
// MANUFACTURER_ID - OPTIONAL, 0xEF30 for windbond 4mbit flash (Moteino OEM)
//*****************************************************************************************************************************
SPIFlash flash(8, 0xEF30); //WINDBOND 4MBIT flash chip on CS pin D8 (default for Moteino)
volatile byte ledState = LOW;
@ -102,6 +118,10 @@ void setup() {
radio.encrypt(ENCRYPTKEY);
pinMode(LED, OUTPUT);
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
//initialize counter from EEPROM
unsigned long savedCounter = EEPROM_Read_Counter();
if (savedCounter <=0) savedCounter = 1; //avoid division by 0

View File

@ -1,5 +1,9 @@
// ***************************************************************************************
// Sample RFM69 sketch for Moteino to illustrate sending and receiving, button interrupts
// Sample RFM69 sketch for Moteino to illustrate:
// - sending
// - receiving
// - automatic transmission control
// - button reading/interrupts
// ***************************************************************************************
// When you press the button on the SENDER Moteino, it will send a short message to the
// RECEIVER Moteino and wait for an ACK (acknowledgement that message was received) from
@ -19,8 +23,7 @@
// Get libraries at: https://github.com/LowPowerLab/
// Make sure you adjust the settings in the configuration section below !!!
// **********************************************************************************
// Copyright Felix Rusu, LowPowerLab.com
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -36,24 +39,20 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
#include <LowPower.h> //get library from: https://github.com/lowpowerlab/lowpower
//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NETWORKID 100 //the same on all nodes that talk to each other
#define RECEIVER 1 //unique ID of the gateway/receiver
#define SENDER 2
@ -64,6 +63,9 @@
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW //uncomment only for RFM69HW! Remove/comment if you have RFM69W!
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//*********************************************************************************************
#define SERIAL_BAUD 115200
#ifdef __AVR_ATmega1284P__
@ -80,7 +82,11 @@
#define LED_RED 5 //RED LED on the SENDER
#define RX_TOGGLE_PIN 7 //GPIO to toggle on the RECEIVER
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
void setup() {
Serial.begin(SERIAL_BAUD);
@ -89,6 +95,11 @@ void setup() {
radio.setHighPower(); //only for RFM69HW!
#endif
radio.encrypt(ENCRYPTKEY);
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);

View File

@ -1,15 +1,15 @@
// **********************************************************************************************************
// WeatherShield sketch that works with Moteinos equipped with RFM69W/RFM69HW and WeatherShield
// WeatherShield sketch that works with Moteinos equipped with RFM69W/RFM69HW/RFM69CW/RFM69HCW and WeatherShield R1 (Si7021+BMP180 sensors)
// It sends periodic highly accurate weather readings (temp, hum, atm pressure) from the
// WeatherShield to the base node/gateway Moteino
// Can be adapted to use Moteinos/Arduinos using RFM12B or other RFM69 variants (RFM69CW, RFM69HCW)
// For use with MoteinoMEGA you will have to revisit the pin definitions defined below
// http://www.LowPowerLab.com/WeatherShield
// Used in this project: http://lowpowerlab.com/blog/2015/07/24/attic-fan-cooling-tests/
// 2015-07-23 (C) Felix Rusu of http://www.LowPowerLab.com/
// **********************************************************************************************************
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************************************
// **********************************************************************************
// 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
@ -22,31 +22,27 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// ***************************************************************************************************************************
#include <RFM69.h> //get it here: http://github.com/lowpowerlab/rfm69
#include <SPIFlash.h> //get it here: http://github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming
#include <SPI.h> //comes with Arduino
// **********************************************************************************
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
#include <Wire.h> //included with Arduino IDE (www.arduino.cc)
#include <SFE_BMP180.h> //get it here: https://github.com/LowPowerLab/SFE_BMP180
#include <SI7021.h> //get it here: https://github.com/LowPowerLab/SI7021
#include <Wire.h> //comes with Arduino
#include <LowPower.h> //get library from: https://github.com/lowpowerlab/lowpower
//writeup here: http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/
//*****************************************************************************************************************************
// ADJUST THE SETTINGS BELOW DEPENDING ON YOUR HARDWARE/TRANSCEIVER SETTINGS/REQUIREMENTS
//*****************************************************************************************************************************
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define GATEWAYID 1
#define NODEID 164
#define NETWORKID 100
@ -55,6 +51,10 @@
#define FREQUENCY RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY "sampleEncryptKey" //has to be same 16 characters/bytes on all nodes, not more not less!
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//*****************************************************************************************************************************
#define SEND_LOOPS 15 //send data this many sleep loops (15 loops of 8sec cycles = 120sec ~ 2 minutes)
//*********************************************************************************************
#define SLEEP_FASTEST SLEEP_15MS
@ -91,9 +91,19 @@ period_t sleepTime = SLEEP_LONGEST; //period_t is an enum type defined in the Lo
//global program variables
SI7021 weatherShield_SI7021;
SFE_BMP180 weatherShield_BMP180;
RFM69 radio;
char Pstr[10];
char buffer[50];
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
//*****************************************************************************************************************************
// flash(SPI_CS, MANUFACTURER_ID)
// SPI_CS - CS pin attached to SPI flash chip (8 in case of Moteino)
// MANUFACTURER_ID - OPTIONAL, 0xEF30 for windbond 4mbit flash (Moteino OEM)
//*****************************************************************************************************************************
SPIFlash flash(8, 0xEF30); //WINDBOND 4MBIT flash chip on CS pin D8 (default for Moteino)
void setup(void)
@ -109,6 +119,10 @@ void setup(void)
#endif
radio.encrypt(ENCRYPTKEY);
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
sprintf(buffer, "WeatherMote - transmitting at: %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
DEBUGln(buffer);

View File

@ -10,8 +10,7 @@
// is handled by the SPIFLash/WirelessHEX69 library, which also relies on the RFM69 library
// These libraries and custom 1k Optiboot bootloader for the target node are at: http://github.com/lowpowerlab
// **********************************************************************************
// Copyright Felix Rusu, LowPowerLab.com
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -27,41 +26,53 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming/tree/master/WirelessHEX69
#include <SPI.h> //included with Arduino IDE (www.arduino.cc)
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NODEID 254 //this node's ID, should be unique among nodes on this NETWORKID
#define NETWORKID 250 //what network this node is on
#define NETWORKID 100 //what network this node is on
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define FREQUENCY_EXACT 916000000
#define ENCRYPTKEY "sampleEncryptKey" //(16 bytes of your choice - keep the same on all encrypted nodes)
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*********************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
//*********************************************************************************************
//#define BR_300KBPS //run radio at max rate of 300kbps!
//*********************************************************************************************
#define DEBUG_MODE false //set 'true' to see verbose output from programming sequence
#define SERIAL_BAUD 115200
#define ACK_TIME 50 // # of ms to wait for an ack
#define TIMEOUT 3000
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#define LED 15 // MoteinoMEGA has LED on D15
#else
#define LED 9 // Moteinos hsave LEDs on D9
#define LED 9 // Moteino has LED on D9
#endif
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
char c = 0;
char input[64]; //serial input buffer
byte targetID=0;
@ -70,10 +81,25 @@ void setup(){
Serial.begin(SERIAL_BAUD);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
radio.encrypt(ENCRYPTKEY); //OPTIONAL
#ifdef FREQUENCY_EXACT
radio.setFrequency(FREQUENCY_EXACT); //set frequency to some custom frequency
#endif
#ifdef IS_RFM69HW
radio.setHighPower(); //only for RFM69HW!
#endif
Serial.println("Start wireless gateway...");
#ifdef BR_300KBPS
radio.writeReg(0x03, 0x00); //REG_BITRATEMSB: 300kbps (0x006B, see DS p20)
radio.writeReg(0x04, 0x6B); //REG_BITRATELSB: 300kbps (0x006B, see DS p20)
radio.writeReg(0x19, 0x40); //REG_RXBW: 500kHz
radio.writeReg(0x1A, 0x80); //REG_AFCBW: 500kHz
radio.writeReg(0x05, 0x13); //REG_FDEVMSB: 300khz (0x1333)
radio.writeReg(0x06, 0x33); //REG_FDEVLSB: 300khz (0x1333)
radio.writeReg(0x29, 240); //set REG_RSSITHRESH to -120dBm
#endif
}
void loop(){
@ -83,7 +109,7 @@ void loop(){
if (targetID==0)
Serial.println("TO?");
else
CheckForSerialHEX((byte*)input, inputLen, radio, targetID, TIMEOUT, ACK_TIME, false);
CheckForSerialHEX((byte*)input, inputLen, radio, targetID, TIMEOUT, ACK_TIME, DEBUG_MODE);
}
else if (inputLen>3 && inputLen<=6 && input[0]=='T' && input[1]=='O' && input[2]==':')
{

View File

@ -6,11 +6,10 @@
// the FLASH chip, then restart the Moteino so the bootloader can continue the job of
// actually reflashing the internal flash memory from the external FLASH memory chip flash image
// The handshake protocol that receives the sketch wirelessly by means of the RFM69 radio
// is handled by the SPIFLash/WirelessHEX69 library, which also relies on the RFM69 library
// is handled by the SPIFLash/RFM69_OTA library, which also relies on the RFM69 library
// These libraries and custom 1k Optiboot bootloader are at: http://github.com/lowpowerlab
// **********************************************************************************
// Copyright Felix Rusu, LowPowerLab.com
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -26,29 +25,34 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69.h> //get it here: https://www.github.com/lowpowerlab/rfm69
#include <SPI.h>
#include <SPIFlash.h> //get it here: https://www.github.com/lowpowerlab/spiflash
#include <avr/wdt.h>
#include <WirelessHEX69.h> //get it here: https://github.com/LowPowerLab/WirelessProgramming/tree/master/WirelessHEX69
#include <RFM69.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_ATC.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h> //get it here: https://github.com/lowpowerlab/RFM69
#include <SPIFlash.h> //get it here: https://github.com/lowpowerlab/spiflash
#include <SPI.h> //included with Arduino IDE install (www.arduino.cc)
//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define NODEID 123 // node ID used for this unit
#define NETWORKID 250
#define NETWORKID 100
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*****************************************************************************************************************************
#define ENABLE_ATC //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75
//*****************************************************************************************************************************
//#define BR_300KBPS //run radio at max rate of 300kbps!
//*****************************************************************************************************************************
#define SERIAL_BAUD 115200
#define ACK_TIME 30 // # of ms to wait for an ack
#define ENCRYPTKEY "sampleEncryptKey" //(16 bytes of your choice - keep the same on all encrypted nodes)
@ -62,17 +66,22 @@
#define FLASH_SS 8 // and FLASH SS on D8
#endif
#ifdef ENABLE_ATC
RFM69_ATC radio;
#else
RFM69 radio;
#endif
char input = 0;
long lastPeriod = -1;
/////////////////////////////////////////////////////////////////////////////
//*****************************************************************************************************************************
// flash(SPI_CS, MANUFACTURER_ID)
// SPI_CS - CS pin attached to SPI flash chip (8 in case of Moteino)
// MANUFACTURER_ID - OPTIONAL, 0x1F44 for adesto(ex atmel) 4mbit flash
// 0xEF30 for windbond 4mbit flash
// 0xEF40 for windbond 16/64mbit flash
/////////////////////////////////////////////////////////////////////////////
//*****************************************************************************************************************************
SPIFlash flash(FLASH_SS, 0xEF30); //EF30 for windbond 4mbit flash
void setup(){
@ -80,15 +89,36 @@ void setup(){
Serial.begin(SERIAL_BAUD);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
radio.encrypt(ENCRYPTKEY); //OPTIONAL
#ifdef FREQUENCY_EXACT
radio.setFrequency(FREQUENCY_EXACT); //set frequency to some custom frequency
#endif
#ifdef ENABLE_ATC
radio.enableAutoPower(ATC_RSSI);
#endif
#ifdef IS_RFM69HW
radio.setHighPower(); //only for RFM69HW!
#endif
Serial.print("Start node...");
Serial.print("Node ID = ");
Serial.println(NODEID);
if (flash.initialize())
Serial.println("SPI Flash Init OK!");
else
Serial.println("SPI Flash Init FAIL!");
#ifdef BR_300KBPS
radio.writeReg(0x03, 0x00); //REG_BITRATEMSB: 300kbps (0x006B, see DS p20)
radio.writeReg(0x04, 0x6B); //REG_BITRATELSB: 300kbps (0x006B, see DS p20)
radio.writeReg(0x19, 0x40); //REG_RXBW: 500kHz
radio.writeReg(0x1A, 0x80); //REG_AFCBW: 500kHz
radio.writeReg(0x05, 0x13); //REG_FDEVMSB: 300khz (0x1333)
radio.writeReg(0x06, 0x33); //REG_FDEVLSB: 300khz (0x1333)
radio.writeReg(0x29, 240); //set REG_RSSITHRESH to -120dBm
#endif
}
void loop(){
@ -156,12 +186,12 @@ void loop(){
}
//else Serial.print('.');
////////////////////////////////////////////////////////////////////////////////////////////
//*****************************************************************************************************************************
// Real sketch code here, let's blink the onboard LED
if ((int)(millis()/BLINKPERIOD) > lastPeriod)
{
lastPeriod++;
digitalWrite(LED, lastPeriod%2);
}
////////////////////////////////////////////////////////////////////////////////////////////
//*****************************************************************************************************************************
}

View File

@ -1,8 +1,7 @@
// **********************************************************************************
// Driver definition for HopeRF RFM69W/RFM69HW/RFM69CW/RFM69HCW, Semtech SX1231/1231H
// **********************************************************************************
// Copyright Felix Rusu (2014), felix@lowpowerlab.com
// http://lowpowerlab.com/
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -18,10 +17,6 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//

View File

@ -1,8 +1,7 @@
// **********************************************************************************
// Driver definition for HopeRF RFM69W/RFM69HW/RFM69CW/RFM69HCW, Semtech SX1231/1231H
// **********************************************************************************
// Copyright Felix Rusu (2014), felix@lowpowerlab.com
// http://lowpowerlab.com/
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
@ -18,10 +17,6 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//

View File

@ -19,10 +19,6 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//

View File

@ -19,10 +19,6 @@
// 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 <http://www.gnu.org/licenses/>.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//

525
RFM69_OTA.cpp Normal file
View File

@ -0,0 +1,525 @@
// **********************************************************************************
// Library for OTA wireless programming of Moteinos using an RFM69 transceiver
// **********************************************************************************
// Hardware requirements:
// - DualOptiboot bootloader - ships with all Moteinos
// - SPI "Flash MEM" chip on Moteino (optional)
// Library requirements:
// - RFM69 - get library at: https://github.com/LowPowerLab/RFM69
// - SPIFLash.h - get it here: http://github.com/LowPowerLab/SPIFlash
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
// 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.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#include <RFM69_OTA.h>
#include <RFM69registers.h>
#include <avr/wdt.h>
//===================================================================================================================
// CheckForWirelessHEX() - Checks whether the last message received was a wireless programming request handshake
// If so it will start the handshake protocol, receive the new HEX image and
// store it on the external flash chip, then reboot
// Assumes radio has been initialized and has just received a message (is not in SLEEP mode, and you called CRCPass())
// Assumes flash is an external SPI flash memory chip that has been initialized
//===================================================================================================================
void CheckForWirelessHEX(RFM69 radio, SPIFlash flash, uint8_t DEBUG, uint8_t LEDpin)
{
//special FLASH command, enter a FLASH image exchange sequence
if (radio.DATALEN >= 4 && radio.DATA[0]=='F' && radio.DATA[1]=='L' && radio.DATA[2]=='X' && radio.DATA[3]=='?')
{
uint8_t remoteID = radio.SENDERID;
if (radio.DATALEN == 7 && radio.DATA[4]=='E' && radio.DATA[5]=='O' && radio.DATA[6]=='F')
{ //sender must have not received EOF ACK so just resend
radio.send(remoteID, "FLX?OK",6);
}
#ifdef SHIFTCHANNEL
else if (HandleWirelessHEXDataWrapper(radio, remoteID, flash, DEBUG, LEDpin))
#else
else if (HandleWirelessHEXData(radio, remoteID, flash, DEBUG, LEDpin))
#endif
{
if (DEBUG) Serial.print(F("FLASH IMG TRANSMISSION SUCCESS!\n"));
resetUsingWatchdog(DEBUG);
}
else
{
if (DEBUG) Serial.print("Timeout/Error, erasing written data ... ");
//flash.blockErase32K(0); //clear any written data in first 32K block
if (DEBUG) Serial.println(F("DONE"));
}
}
}
//===================================================================================================================
// HandleHandshakeACK() - checks there is a FLASH chip and sends an ACK for the OTA request handshake
//===================================================================================================================
void HandleHandshakeACK(RFM69 radio, SPIFlash flash, uint8_t flashCheck) {
if (flashCheck)
{
if (!flash.initialize())
{
radio.sendACK("FLX?NOK:NOFLASH",15); //NO FLASH CHIP FOUND, ABORTING
Serial.println(F("FAIL:NO FLASH MEM"));
return;
}
}
radio.sendACK("FLX?OK",6); //ACK the HANDSHAKE
}
//===================================================================================================================
// HandleWirelessHEXDataWrapper() - wrapper function for HandleWirelessHEXData()
// that also shifts channel when SHIFTCHANNEL is defined
//===================================================================================================================
#ifdef SHIFTCHANNEL
uint8_t HandleWirelessHEXDataWrapper(RFM69 radio, uint8_t remoteID, SPIFlash flash, uint8_t DEBUG, uint8_t LEDpin) {
HandleHandshakeACK(radio, flash);
if (DEBUG) { Serial.println(F("FLX?OK (ACK sent)")); Serial.print(F("Shifting channel to ")); Serial.println(radio.getFrequency() + SHIFTCHANNEL);}
radio.setFrequency(radio.getFrequency() + SHIFTCHANNEL); //shift center freq by SHIFTCHANNEL amount
uint8_t result = HandleWirelessHEXData(radio, remoteID, flash, DEBUG, LEDpin);
if (DEBUG) { Serial.print(F("UNShifting channel to ")); Serial.println(radio.getFrequency() - SHIFTCHANNEL);}
radio.setFrequency(radio.getFrequency() - SHIFTCHANNEL); //restore center freq
return result;
}
#endif
//===================================================================================================================
// HandleWirelessHEXData() - ACKs the wireless programming handshake and handles
// the complete transmission of the HEX image at the OTA programmed node side
//===================================================================================================================
uint8_t HandleWirelessHEXData(RFM69 radio, uint8_t remoteID, SPIFlash flash, uint8_t DEBUG, uint8_t LEDpin) {
uint32_t now=0;
uint16_t tmp,seq=0;
char buffer[16];
uint16_t timeout = 3000; //3s for flash data
uint16_t bytesFlashed=10;
#ifndef SHIFTCHANNEL
HandleHandshakeACK(radio, flash);
if (DEBUG) Serial.println(F("FLX?OK (ACK sent)"));
#endif
//first clear the fist 32k block (dedicated to a new FLASH image)
flash.blockErase32K(0);
flash.writeBytes(0,"FLXIMG:", 7);
flash.writeByte(9,':');
now=millis();
while(1)
{
if (radio.receiveDone() && radio.SENDERID == remoteID)
{
uint8_t dataLen = radio.DATALEN;
if (dataLen >= 4 && radio.DATA[0]=='F' && radio.DATA[1]=='L' && radio.DATA[2]=='X')
{
if (radio.DATA[3]==':' && dataLen >= 7) //FLX:_:_
{
uint8_t index=3;
tmp = 0;
//read packet SEQ
for (uint8_t i = 4; i<8; i++) //up to 4 characters for seq number
{
if (radio.DATA[i] >=48 && radio.DATA[i]<=57)
tmp = tmp*10+radio.DATA[i]-48;
else if (radio.DATA[i]==':')
{
if (i==4)
return false;
else break;
}
index++;
}
if (DEBUG) {
Serial.print(F("radio ["));
Serial.print(dataLen);
Serial.print(F("] > "));
PrintHex83((uint8_t*)radio.DATA, dataLen);
}
if (radio.DATA[++index] != ':') return false;
now = millis(); //got "good" packet
index++;
if (tmp==seq || tmp==seq-1) // if {temp==seq : new packet}, {temp==seq-1 : ACK was lost, host resending previously saved packet so must only resend the ACK}
{
if (tmp==seq)
{
seq++;
for(uint8_t i=index;i<dataLen;i++)
{
flash.writeByte(bytesFlashed++, radio.DATA[i]);
if (bytesFlashed%32768==0) flash.blockErase32K(bytesFlashed);//erase subsequent 32K blocks (possible in case of atmega1284p)
}
}
//send ACK
tmp = sprintf(buffer, "FLX:%u:OK", tmp);
if (DEBUG) Serial.println((char*)buffer);
radio.sendACK(buffer, tmp);
}
}
if (radio.DATA[3]=='?')
{
if (dataLen==4) //ACK for handshake was lost, resend
{
HandleHandshakeACK(radio, flash);
if (DEBUG) Serial.println(F("FLX?OK resend"));
}
if (dataLen==7 && radio.DATA[4]=='E' && radio.DATA[5]=='O' && radio.DATA[6]=='F') //Expected EOF
{
#ifdef __AVR_ATmega1284P__
if ((bytesFlashed-10)>65526) { //max 65536 - 10 bytes (signature)
if (DEBUG) Serial.println(F("IMG > 64k, too big"));
radio.sendACK("FLX?NOK:HEX>64k",15);
return false; //just return, let MAIN timeout
}
#else //assuming atmega328p
if ((bytesFlashed-10)>31744) {
if (DEBUG) Serial.println(F("IMG > 31k, too big"));
radio.sendACK("FLX?NOK:HEX>31k",15);
return false; //just return, let MAIN timeout
}
#endif
HandleHandshakeACK(radio, flash, false);
if (DEBUG) Serial.println(F("FLX?OK"));
//save # of bytes written
flash.writeByte(7,(bytesFlashed-10)>>8);
flash.writeByte(8,(bytesFlashed-10));
flash.writeByte(9,':');
return true;
}
}
}
#ifdef LED //blink!
pinMode(LEDpin,OUTPUT); digitalWrite(LEDpin,HIGH); delay(1); digitalWrite(LEDpin,LOW);
#endif
}
//abort FLASH sequence if no valid packet received for a long time
if (millis()-now > timeout)
{
return false;
}
}
}
//===================================================================================================================
// readSerialLine() - reads a line feed (\n) terminated line from the serial stream
// returns # of bytes read, up to 255
// timeout in ms, will timeout and return after so long
// this is called at the OTA programmer side
//===================================================================================================================
uint8_t readSerialLine(char* input, char endOfLineChar, uint8_t maxLength, uint16_t timeout)
{
uint8_t inputLen = 0;
Serial.setTimeout(timeout);
inputLen = Serial.readBytesUntil(endOfLineChar, input, maxLength);
input[inputLen]=0;//null-terminate it
Serial.setTimeout(0);
return inputLen;
}
//===================================================================================================================
// CheckForSerialHEX() - returns TRUE if a HEX file transmission was detected and it was actually transmitted successfully
// this is called at the OTA programmer side
//===================================================================================================================
uint8_t CheckForSerialHEX(uint8_t* input, uint8_t inputLen, RFM69 radio, uint8_t targetID, uint16_t TIMEOUT, uint16_t ACKTIMEOUT, uint8_t DEBUG)
{
if (inputLen == 4 && input[0]=='F' && input[1]=='L' && input[2]=='X' && input[3]=='?') {
if (HandleSerialHandshake(radio, targetID, false, TIMEOUT, ACKTIMEOUT, DEBUG))
{
if (radio.DATALEN >= 7 && radio.DATA[4] == 'N')
{
Serial.println((char*)radio.DATA); //signal serial handshake fail/error and return
return false;
}
Serial.println(F("\nFLX?OK")); //signal serial handshake back to host script
#ifdef SHIFTCHANNEL
if (HandleSerialHEXDataWrapper(radio, targetID, TIMEOUT, ACKTIMEOUT, DEBUG))
#else
if (HandleSerialHEXData(radio, targetID, TIMEOUT, ACKTIMEOUT, DEBUG))
#endif
{
Serial.println(F("FLX?OK")); //signal EOF serial handshake back to host script
if (DEBUG) Serial.println(F("FLASH IMG TRANSMISSION SUCCESS"));
return true;
}
if (DEBUG) Serial.println(F("FLASH IMG TRANSMISSION FAIL"));
return false;
}
else Serial.println(F("FLX?NOK"));
}
return false;
}
//===================================================================================================================
// HandleSerialHandshake() - handles the handshake with the serial port
//===================================================================================================================
uint8_t HandleSerialHandshake(RFM69 radio, uint8_t targetID, uint8_t isEOF, uint16_t TIMEOUT, uint16_t ACKTIMEOUT, uint8_t DEBUG)
{
long now = millis();
while (millis()-now<TIMEOUT)
{
if (radio.sendWithRetry(targetID, isEOF ? "FLX?EOF" : "FLX?", isEOF?7:4, 2,ACKTIMEOUT))
if (radio.DATALEN >= 6 && radio.DATA[0]=='F' && radio.DATA[1]=='L' && radio.DATA[2]=='X' && radio.DATA[3]=='?')
return true;
}
if (DEBUG) Serial.println(F("Handshake fail"));
return false;
}
//===================================================================================================================
// HandleSerialHEXDataWrapper() - wrapper for HandleSerialHEXData(), also shifts the channel if SHIFTCHANNEL is defined
//===================================================================================================================
#ifdef SHIFTCHANNEL
uint8_t HandleSerialHEXDataWrapper(RFM69 radio, uint8_t targetID, uint16_t TIMEOUT, uint16_t ACKTIMEOUT, uint8_t DEBUG) {
radio.setFrequency(radio.getFrequency() + SHIFTCHANNEL); //shift center freq by SHIFTCHANNEL amount
uint8_t result = HandleSerialHEXData(radio, targetID, TIMEOUT, ACKTIMEOUT, DEBUG);
radio.setFrequency(radio.getFrequency() - SHIFTCHANNEL); //shift center freq by SHIFTCHANNEL amount
return result;
}
#endif
//===================================================================================================================
// HandleSerialHEXData() - handles the transmission of the HEX image from the serial port to the node being OTA programmed
// this is called at the OTA programmer side
//===================================================================================================================
uint8_t HandleSerialHEXData(RFM69 radio, uint8_t targetID, uint16_t TIMEOUT, uint16_t ACKTIMEOUT, uint8_t DEBUG) {
long now=millis();
uint16_t seq=0, tmp=0, inputLen;
uint8_t remoteID = radio.SENDERID; //save the remoteID as soon as possible
uint8_t sendBuf[57];
char input[115];
//a FLASH record should not be more than 64 bytes: FLX:9999:10042000FF4FA591B4912FB7F894662321F48C91D6
while(1) {
inputLen = readSerialLine(input);
if (inputLen == 0) goto timeoutcheck;
tmp = 0;
if (inputLen >= 6) { //FLX:9:
if (input[0]=='F' && input[1]=='L' && input[2]=='X')
{
if (input[3]==':')
{
uint8_t index = 3;
for (uint8_t i = 4; i<8; i++) //up to 4 characters for seq number
{
if (input[i] >=48 && input[i]<=57)
tmp = tmp*10+input[i]-48;
else if (input[i]==':')
{
if (i==4)
return false;
else break;
}
index++;
}
//Serial.print(F("input[index] = "));Serial.print(F("["));Serial.print(index);Serial.print(F("]="));Serial.println(input[index]);
if (input[++index] != ':') return false;
now = millis(); //got good packet
index++;
uint8_t hexDataLen = validateHEXData(input+index, inputLen-index);
if (hexDataLen>0)
{
if (tmp==seq) //only read data when packet number is the next expected SEQ number
{
uint8_t sendBufLen = prepareSendBuffer(input+index+8, sendBuf, hexDataLen, seq); //extract HEX data from input to BYTE data into sendBuf (go from 2 HEX bytes to 1 byte), +8 jumps over the header to the HEX raw data
//Serial.print(F("PREP "));Serial.print(sendBufLen); Serial.print(F(" > ")); PrintHex83(sendBuf, sendBufLen);
//SEND RADIO DATA
if (sendHEXPacket(radio, remoteID, sendBuf, sendBufLen, seq, TIMEOUT, ACKTIMEOUT, DEBUG))
{
sprintf((char*)sendBuf, "FLX:%u:OK",seq);
Serial.println((char*)sendBuf); //response to host
seq++;
}
else return false;
}
}
else Serial.println(F("FLX:INV"));
}
if (inputLen==7 && input[3]=='?' && input[4]=='E' && input[5]=='O' && input[6]=='F')
{
//SEND RADIO EOF
return HandleSerialHandshake(radio, targetID, true, TIMEOUT, ACKTIMEOUT, DEBUG);
}
}
}
//abort FLASH sequence if no valid packet received for a long time
timeoutcheck:
if (millis()-now > TIMEOUT)
{
Serial.print(F("Timeout getting FLASH image from SERIAL, aborting.."));
//send abort msg or just let node timeout as well?
return false;
}
}
return true;
}
//===================================================================================================================
// validateHEXData() - returns length of HEX data bytes if everything is valid
//returns 0 if any validation failed
//===================================================================================================================
uint8_t validateHEXData(void* data, uint8_t length)
{
//assuming 1 byte record length, 2 bytes address, 1 byte record type, N data bytes, 1 CRC byte
char* input = (char*)data;
if (length <12 || length%2!=0) return 0; //shortest possible intel data HEX record is 12 bytes
//Serial.print(F("VAL > ")); Serial.println((char*)input);
uint8_t checksum=0;
//check valid HEX data and CRC
for (uint8_t i=0; i<length;i++)
{
if (!((input[i] >=48 && input[i]<=57) || (input[i] >=65 && input[i]<=70))) //0-9,A-F
return 0;
if (i%2 && i<length-2) checksum+=BYTEfromHEX(input[i-1], input[i]);
}
checksum=(checksum^0xFF)+1;
//TODO : CHECK for address continuity (intel HEX addresses are big endian)
//Serial.print(F("final CRC:"));Serial.println((uint8_t)checksum, HEX);
//Serial.print(F("CRC byte:"));Serial.println(BYTEfromHEX(input[length-2], input[length-1]), HEX);
//check CHECKSUM byte
if (((uint8_t)checksum) != BYTEfromHEX(input[length-2], input[length-1]))
return 0;
uint8_t dataLength = BYTEfromHEX(input[0], input[1]); //length of actual HEX flash data (usually 16bytes)
//calculate record length
if (length != dataLength*2 + 10) //add headers and checksum bytes (a total of 10 combined)
return 0;
return dataLength; //all validation OK!
}
//===================================================================================================================
// prepareSendBuffer() - returns the final size of the buf
//===================================================================================================================
uint8_t prepareSendBuffer(char* hexdata, uint8_t*buf, uint8_t length, uint16_t seq)
{
uint8_t seqLen = sprintf(((char*)buf), "FLX:%u:", seq);
for (uint8_t i=0; i<length;i++)
buf[seqLen+i] = BYTEfromHEX(hexdata[i*2], hexdata[i*2+1]);
return seqLen+length;
}
//===================================================================================================================
// BYTEfromHEX() - converts from ASCII HEX to byte, assume A and B are valid HEX chars [0-9A-F]
//===================================================================================================================
uint8_t BYTEfromHEX(char MSB, char LSB)
{
return (MSB>=65?MSB-55:MSB-48)*16 + (LSB>=65?LSB-55:LSB-48);
}
//===================================================================================================================
// sendHEXPacket() - return the SEQ of the ACK received, or -1 if invalid
//===================================================================================================================
uint8_t sendHEXPacket(RFM69 radio, uint8_t targetID, uint8_t* sendBuf, uint8_t hexDataLen, uint16_t seq, uint16_t TIMEOUT, uint16_t ACKTIMEOUT, uint8_t DEBUG)
{
long now = millis();
while(1) {
if (DEBUG) { Serial.print(F("RFTX > ")); PrintHex83(sendBuf, hexDataLen); }
if (radio.sendWithRetry(targetID, sendBuf, hexDataLen, 2, ACKTIMEOUT))
{
uint8_t ackLen = radio.DATALEN;
if (DEBUG) { Serial.print(F("RFACK > ")); Serial.print(ackLen); Serial.print(F(" > ")); PrintHex83((uint8_t*)radio.DATA, ackLen); }
if (ackLen >= 8 && radio.DATA[0]=='F' && radio.DATA[1]=='L' && radio.DATA[2]=='X' &&
radio.DATA[3]==':' && radio.DATA[ackLen-3]==':' &&
radio.DATA[ackLen-2]=='O' && radio.DATA[ackLen-1]=='K')
{
uint16_t tmp=0;
sscanf((const char*)radio.DATA, "FLX:%u:OK", &tmp);
return tmp == seq;
}
}
if (millis()-now > TIMEOUT)
{
Serial.println(F("Timeout waiting for packet ACK, aborting FLASH operation ..."));
break; //abort FLASH sequence if no valid ACK was received for a long time
}
}
return false;
}
//===================================================================================================================
// PrintHex83() - prints 8-bit data in HEX format
//===================================================================================================================
void PrintHex83(uint8_t *data, uint8_t length)
{
char tmp[length*2+1];
uint8_t first ;
int j=0;
for (uint8_t i=0; i<length; i++)
{
first = (data[i] >> 4) | 48;
if (first > 57) tmp[j] = first + (uint8_t)39;
else tmp[j] = first ;
j++;
first = (data[i] & 0x0F) | 48;
if (first > 57) tmp[j] = first + (uint8_t)39;
else tmp[j] = first;
j++;
}
tmp[length*2] = 0;
Serial.println(tmp);
}
//===================================================================================================================
// resetUsingWatchdog() - Use watchdog to reset the MCU
//===================================================================================================================
void resetUsingWatchdog(uint8_t DEBUG)
{
//wdt_disable();
if (DEBUG) Serial.print(F("REBOOTING"));
wdt_enable(WDTO_15MS);
while(1) if (DEBUG) Serial.print(F("."));
}

79
RFM69_OTA.h Normal file
View File

@ -0,0 +1,79 @@
// **********************************************************************************
// Library for OTA wireless programming of Moteinos using an RFM69 transceiver
// **********************************************************************************
// Hardware requirements:
// - DualOptiboot bootloader - ships with all Moteinos
// - SPI "Flash MEM" chip on Moteino (optional)
// Library requirements:
// - RFM69 - get library at: https://github.com/LowPowerLab/RFM69
// - SPIFLash.h - get it here: http://github.com/LowPowerLab/SPIFlash
// **********************************************************************************
// Copyright Felix Rusu 2016, http://www.LowPowerLab.com/contact
// **********************************************************************************
// License
// **********************************************************************************
// 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.
//
// Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
// **********************************************************************************
#ifndef RFM69_OTA_H
#define RFM69_OTA_H
#ifdef __AVR_ATmega1284P__
#define LED 15 // Moteino MEGAs have LEDs on D15
#else
#define LED 9 // Moteinos have LEDs on D9
#endif
#define SHIFTCHANNEL 1000000 //amount to shift frequency of HEX transmission to keep original channel free of the HEX transmission traffic
#ifndef DEFAULT_TIMEOUT
#define DEFAULT_TIMEOUT 3000
#endif
#ifndef ACK_TIMEOUT
#define ACK_TIMEOUT 20
#endif
#include <RFM69.h>
#include <SPIFlash.h>
//functions used in the REMOTE node
void CheckForWirelessHEX(RFM69 radio, SPIFlash flash, uint8_t DEBUG=false, uint8_t LEDpin=LED);
void HandleHandshakeACK(RFM69 radio, SPIFlash flash, uint8_t flashCheck=true);
void resetUsingWatchdog(uint8_t DEBUG=false);
uint8_t HandleWirelessHEXData(RFM69 radio, uint8_t remoteID, SPIFlash flash, uint8_t DEBUG=false, uint8_t LEDpin=LED);
#ifdef SHIFTCHANNEL
uint8_t HandleWirelessHEXDataWrapper(RFM69 radio, uint8_t remoteID, SPIFlash flash, uint8_t DEBUG=false, uint8_t LEDpin=LED);
#endif
//functions used in the MAIN node
uint8_t CheckForSerialHEX(uint8_t* input, uint8_t inputLen, RFM69 radio, uint8_t targetID, uint16_t TIMEOUT=DEFAULT_TIMEOUT, uint16_t ACKTIMEOUT=ACK_TIMEOUT, uint8_t DEBUG=false);
uint8_t HandleSerialHandshake(RFM69 radio, uint8_t targetID, uint8_t isEOF, uint16_t TIMEOUT=DEFAULT_TIMEOUT, uint16_t ACKTIMEOUT=ACK_TIMEOUT, uint8_t DEBUG=false);
uint8_t HandleSerialHEXData(RFM69 radio, uint8_t targetID, uint16_t TIMEOUT=DEFAULT_TIMEOUT, uint16_t ACKTIMEOUT=ACK_TIMEOUT, uint8_t DEBUG=false);
#ifdef SHIFTCHANNEL
uint8_t HandleSerialHEXDataWrapper(RFM69 radio, uint8_t targetID, uint16_t TIMEOUT=DEFAULT_TIMEOUT, uint16_t ACKTIMEOUT=ACK_TIMEOUT, uint8_t DEBUG=false);
#endif
uint8_t waitForAck(RFM69 radio, uint8_t fromNodeID, uint16_t ACKTIMEOUT=ACK_TIMEOUT);
uint8_t validateHEXData(void* data, uint8_t length);
uint8_t prepareSendBuffer(char* hexdata, uint8_t*buf, uint8_t length, uint16_t seq);
uint8_t sendHEXPacket(RFM69 radio, uint8_t remoteID, uint8_t* sendBuf, uint8_t hexDataLen, uint16_t seq, uint16_t TIMEOUT=DEFAULT_TIMEOUT, uint16_t ACKTIMEOUT=ACK_TIMEOUT, uint8_t DEBUG=false);
uint8_t BYTEfromHEX(char MSB, char LSB);
uint8_t readSerialLine(char* input, char endOfLineChar=10, uint8_t maxLength=115, uint16_t timeout=1000);
void PrintHex83(uint8_t* data, uint8_t length);
#endif

View File

@ -11,6 +11,7 @@
#######################################
RFM69 KEYWORD2
RFM69_ATC KEYWORD2
RFM69_OTA KEYWORD2
#######################################
# Methods and Functions (KEYWORD2)
@ -41,6 +42,16 @@ rcCalibration KEYWORD2
readAllRegs KEYWORD2
enableAutoPower KEYWORD2
CheckForSerialHEX KEYWORD2
CheckForWirelessHEX KEYWORD2
HandleHandshakeACK KEYWORD2
HandleWirelessHEXData KEYWORD2
readSerialLine KEYWORD2
BYTEfromHEX KEYWORD2
waitForAck KEYWORD2
PrintHex83 KEYWORD2
resetUsingWatchdog KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################