// ********************************************************************************** // This sketch is an example of how wireless programming can be achieved with a Moteino // that was loaded with a custom 1k bootloader (DualOptiboot) that is capable of loading // a new sketch from an external SPI flash chip // This is the GATEWAY node, it does not need a custom Optiboot nor any external FLASH memory chip // (ONLY the target node will need those) // The sketch includes logic to receive the new sketch from the serial port (from a host computer) and // transmit it wirelessly to the target node // The handshake protocol that receives the sketch from the serial port // 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 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 //get it here: https://github.com/lowpowerlab/RFM69 #include //get it here: https://github.com/lowpowerlab/RFM69 #include //get it here: https://github.com/lowpowerlab/RFM69 #include //get it here: https://www.github.com/lowpowerlab/spiflash #include //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 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_HCW //uncomment only for RFM69HW/HCW! Leave out if you have RFM69W/CW! //********************************************************************************************* #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 // MoteinoMEGA has LED on D15 #else #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; 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_HCW radio.setHighPower(); //must include this only for RFM69HW/HCW! #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(){ byte inputLen = readSerialLine(input, 10, 64, 100); //readSerialLine(char* input, char endOfLineChar=10, byte maxLength=64, uint16_t timeout=1000); if (inputLen==4 && input[0]=='F' && input[1]=='L' && input[2]=='X' && input[3]=='?') { if (targetID==0) Serial.println("TO?"); else 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]==':') { byte newTarget=0; for (byte i = 3; i=48 && input[i]<=57) newTarget = newTarget*10+input[i]-48; else { newTarget=0; break; } if (newTarget>0) { targetID = newTarget; Serial.print("TO:"); Serial.print(newTarget); Serial.println(":OK"); } else { Serial.print(input); Serial.print(":INV"); } } else if (inputLen>0) { //just echo back Serial.print("SERIAL IN > ");Serial.println(input); } if (radio.receiveDone()) { for (byte i = 0; i < radio.DATALEN; i++) Serial.print((char)radio.DATA[i]); if (radio.ACK_REQUESTED) { radio.sendACK(); Serial.print(" - ACK sent"); } Serial.println(); } Blink(LED,5); //heartbeat } void Blink(byte PIN, int DELAY_MS) { pinMode(PIN, OUTPUT); digitalWrite(PIN,HIGH); delay(DELAY_MS); digitalWrite(PIN,LOW); }