RF Serial Config Feature/serialconfig (#1)
Configure RF config via serial. Ported from recent emonTx V3 update https://community.openenergymonitor.org/t/emontx-v3-configure-rf-settings-via-serial-released-fw-v2-6-0/2064
This commit is contained in:
parent
dae1853ad5
commit
8f8f679a49
|
|
@ -27,7 +27,7 @@ lib_deps_external =
|
|||
JeeLib @c057b5f4c0
|
||||
Si7021 @c5ce0922ef
|
||||
|
||||
build_flags = -D BUILD_TAG=3.1.0
|
||||
build_flags = -D BUILD_TAG=3.2.0
|
||||
|
||||
[env:emonth2]
|
||||
platform = atmelavr
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
|
||||
|
||||
#include <EEPROM.h>
|
||||
|
||||
byte value;
|
||||
|
||||
static void load_config(){
|
||||
|
||||
byte flag=0;
|
||||
// Read nodeID
|
||||
if (EEPROM.read(0) != 255){ // 255 = EEPROM default (blank) value
|
||||
nodeID = EEPROM.read(0);
|
||||
flag++;
|
||||
}
|
||||
if (EEPROM.read(1) != 255){
|
||||
RF_freq = EEPROM.read(1);
|
||||
flag++;
|
||||
}
|
||||
if (EEPROM.read(2) != 255){
|
||||
networkGroup = EEPROM.read(2);
|
||||
flag++;
|
||||
}
|
||||
|
||||
if (flag > 0){
|
||||
Serial.println("Loaded EEPROM RF config >");
|
||||
}
|
||||
else {
|
||||
Serial.println("No EEPROM config");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void config (char c) {
|
||||
|
||||
if ('0' <= c && c <= '9') {
|
||||
value = 10 * value + c - '0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (c > ' ') {
|
||||
|
||||
switch (c) {
|
||||
|
||||
case 'i': //set node ID
|
||||
if (value){
|
||||
nodeID = value;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'b': // set band: 4 = 433, 8 = 868, 9 = 915
|
||||
value = bandToFreq(value);
|
||||
if (value){
|
||||
RF_freq = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g': // set network group
|
||||
if (value>=0){
|
||||
networkGroup = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's': // Save to EEPROM. Atemga328p has 1kb EEPROM
|
||||
save_config();
|
||||
break;
|
||||
|
||||
case 'v': // print firmware version
|
||||
Serial.print(F("[emonTx FW: V")); Serial.print(version*0.1); Serial.print(F("]"));
|
||||
break;
|
||||
|
||||
default:
|
||||
showString(helpText1);
|
||||
} //end case
|
||||
|
||||
//Print Current RF config
|
||||
if (RF_STATUS==1) {
|
||||
Serial.print(F(" "));
|
||||
// Serial.print((char) ('@' + (nodeID & RF12_HDR_MASK)));
|
||||
Serial.print(F(" i"));
|
||||
Serial.print(nodeID & RF12_HDR_MASK);
|
||||
Serial.print(F(" g"));
|
||||
Serial.print(networkGroup);
|
||||
Serial.print(F(" @ "));
|
||||
Serial.print(RF_freq == RF12_433MHZ ? 433 :
|
||||
RF_freq == RF12_868MHZ ? 868 :
|
||||
RF_freq == RF12_915MHZ ? 915 : 0);
|
||||
Serial.print(F(" MHz"));
|
||||
}
|
||||
|
||||
Serial.println(F(" "));
|
||||
|
||||
} // end c > ' '
|
||||
value = 0;
|
||||
|
||||
}
|
||||
|
||||
static void save_config(){
|
||||
Serial.println("Saving...");
|
||||
// Clear any old EEPROM settings
|
||||
for (int i = 0 ; i < EEPROM.length() ; i++) {
|
||||
EEPROM.write(i, 0);
|
||||
}
|
||||
//Save new settings
|
||||
EEPROM.write(0, nodeID);
|
||||
EEPROM.write(1, RF_freq);
|
||||
EEPROM.write(2, networkGroup);
|
||||
Serial.println("Done. New config saved to EEPROM");
|
||||
}
|
||||
|
||||
static byte bandToFreq (byte band) {
|
||||
return band == 4 ? RF12_433MHZ : band == 8 ? RF12_868MHZ : band == 9 ? RF12_915MHZ : 0;
|
||||
}
|
||||
|
||||
static void showString (PGM_P s) {
|
||||
for (;;) {
|
||||
char c = pgm_read_byte(s++);
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c == '\n')
|
||||
Serial.print('\r');
|
||||
Serial.print(c);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
emonTH Low Power SI7021 Humidity & Temperature, DS18B20 Temperature & Pulse counting Node Example
|
||||
emonTH V2 Low Power SI7021 Humidity & Temperature, DS18B20 Temperature & Pulse counting Node Example
|
||||
|
||||
Si7201 = internal temperature & Humidity
|
||||
DS18B20 = External temperature
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
Libraries required:
|
||||
- see platformio.ini
|
||||
- recommend compiling with platformIO for auto library download
|
||||
- recommend compiling with platformIO for auto library download https://guide.openenergymonitor.org/technical/compiling
|
||||
- Arduino IDE can be used to compile but libs will need to be manually downloaded
|
||||
|
||||
Recommended node ID allocation
|
||||
|
|
@ -30,8 +30,9 @@
|
|||
31 - Special allocation in JeeLib RFM12 driver - Node31 can communicate with nodes on any network group
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
Change log:
|
||||
V3.1.0 - 18Oct16 test for RFM69CW and SI7201 at startup, allow serial use without RF prescent
|
||||
V3.0.0 - Oct16 Add support for SI7021 sensor instead of DHT22 (emonTH V2.0 hardware)
|
||||
V3.2.0 - (13/11/16) run-time serial nodeID config
|
||||
V3.1.0 - (19/10/16) Test for RFM69CW and SI7201 at startup, allow serial use without RF prescent
|
||||
V3.0.0 - (xx/10/16) Add support for SI7021 sensor instead of DHT22 (emonTH V2.0 hardware)
|
||||
^^^ emonTH V2.0 hardware ^^^
|
||||
V2.7 - (15/09/16) Serial print serial pairs for emonesp compatiable e.g. temp:210,humidity:56
|
||||
V2.6 - (24/10/15) Tweek RF transmission timmng to help reduce RF packet loss
|
||||
|
|
@ -60,7 +61,7 @@
|
|||
boolean debug=1; // Set to 1 to few debug serial output
|
||||
boolean flash_led=0; // Flash LED after each sample (battery drain) default=0
|
||||
|
||||
const byte version = 30; // firmware version divided by 10 e,g 16 = V1.6
|
||||
const byte version = 32; // firmware version divided by 10 e,g 16 = V1.6
|
||||
// These variables control the transmit timing of the emonTH
|
||||
const unsigned long WDT_PERIOD = 80; // mseconds.
|
||||
const unsigned long WDT_MAX_NUMBER = 690; // Data sent after WDT_MAX_NUMBER periods of WDT_PERIOD ms without pulses:
|
||||
|
|
@ -73,12 +74,12 @@ const unsigned long PULSE_MAX_DURATION = 50;
|
|||
#include <JeeLib.h> // https://github.com/jcw/jeelib
|
||||
#include <RF69_avr.h>
|
||||
#define REG_SYNCVALUE1 0x2F
|
||||
boolean rfm69cw_status;
|
||||
boolean RF_STATUS;
|
||||
|
||||
|
||||
#define RF_freq RF12_433MHZ // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.
|
||||
int nodeID = 23; // EmonTH temperature RFM12B node ID - should be unique on network
|
||||
const int networkGroup = 210; // EmonTH RFM12B wireless network group - needs to be same as emonBase and emonGLCD
|
||||
byte RF_freq=RF12_433MHZ; // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.
|
||||
byte nodeID = 23; // EmonTH temperature RFM12B node ID - should be unique on network
|
||||
int networkGroup = 210; // EmonTH RFM12B wireless network group - needs to be same as emonBase and emonGLCD
|
||||
// DS18B20 resolution 9,10,11 or 12bit corresponding to (0.5, 0.25, 0.125, 0.0625 degrees C LSB),
|
||||
// lower resolution means lower power
|
||||
|
||||
|
|
@ -103,9 +104,9 @@ const byte LED= 9;
|
|||
const byte BATT_ADC= 1;
|
||||
const byte DIP_switch1= 7;
|
||||
const byte DIP_switch2= 8;
|
||||
const byte pulse_countINT= 1; // INT 1 / Dig 3 Screw Terminal Block Number 4 on emonTH V1.5 - Change to INT0 DIG2 on emonTH V1.4
|
||||
const byte pulse_count_pin=3; // INT 1 / Dig 3 Screw Terminal Block Number 4 on emonTH V1.5 - Change to INT0 DIG2 on emonTH V1.4
|
||||
#define ONE_WIRE_BUS 17 // D19 emonTH V1.5
|
||||
const byte pulse_countINT= 1; // INT 1 / Dig 3 Screw Terminal Block Number 4
|
||||
const byte pulse_count_pin=3; // INT 1 / Dig 3 Screw Terminal Block Number 4
|
||||
#define ONE_WIRE_BUS 17
|
||||
const byte DHT22_PWR= 6; // Not used in emonTH V2.0, 10K resistor R1 connects DHT22 pins
|
||||
const byte DHT22_DATA= 16; // Not used in emonTH V2.0, 10K resistor R1 connects DHT22 pins.
|
||||
|
||||
|
|
@ -115,7 +116,7 @@ boolean DS18B20; // create
|
|||
|
||||
// Note: Please update emonhub configuration guide on OEM wide packet structure change:
|
||||
// https://github.com/openenergymonitor/emonhub/blob/emon-pi/configuration.md
|
||||
typedef struct { // RFM12B RF payload datastructure
|
||||
typedef struct { // RFM RF payload datastructure
|
||||
int temp;
|
||||
int temp_external;
|
||||
int humidity;
|
||||
|
|
@ -132,8 +133,18 @@ volatile unsigned long pulseCount;
|
|||
unsigned long WDT_number;
|
||||
boolean p;
|
||||
|
||||
unsigned long now = 0;
|
||||
unsigned long now, start;
|
||||
const byte SLAVE_ADDRESS = 42;
|
||||
|
||||
const char helpText1[] PROGMEM = // Available Serial Commands
|
||||
"\n"
|
||||
"Available commands:\n"
|
||||
" <nn> i - set node IDs (standard node ids are 1..30)\n"
|
||||
" <n> b - set MHz band (4 = 433, 8 = 868, 9 = 915)\n"
|
||||
" <nnn> g - set network group (RFM12 only allows 212, 0 = any)\n"
|
||||
" s - save config to EEPROM\n"
|
||||
" v - Show firmware version\n"
|
||||
;
|
||||
//################################################################################################################################
|
||||
//################################################################################################################################
|
||||
#ifndef UNIT_TEST // IMPORTANT LINE! // http://docs.platformio.org/en/stable/plus/unit-testing.html
|
||||
|
|
@ -168,48 +179,53 @@ void setup() {
|
|||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("OpenEnergyMonitor.org");
|
||||
Serial.print("emonTH - Firmware V"); Serial.println(version*0.1);
|
||||
#if (RF69_COMPAT)
|
||||
Serial.println("RFM69CW: ");
|
||||
#else
|
||||
Serial.println("RFM12B: ");
|
||||
#endif
|
||||
Serial.print("Node: ");
|
||||
Serial.print(nodeID);
|
||||
Serial.print(" Freq: ");
|
||||
if (RF_freq == RF12_433MHZ) Serial.print("433Mhz");
|
||||
if (RF_freq == RF12_868MHZ) Serial.print("868Mhz");
|
||||
if (RF_freq == RF12_915MHZ) Serial.print("915Mhz");
|
||||
Serial.print(" Network: ");
|
||||
Serial.println(networkGroup);
|
||||
Serial.print("emonTH FW: V"); Serial.println(version*0.1);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// Test for RFM69CW and int with test sequence if found
|
||||
spiInit();
|
||||
writeReg(REG_SYNCVALUE1, 0xAA);
|
||||
int result = readReg(REG_SYNCVALUE1);
|
||||
writeReg(REG_SYNCVALUE1, 0x55);
|
||||
result = result + readReg(REG_SYNCVALUE1);
|
||||
if (result!=0){ // result will be > 0 if RFM69CW is found
|
||||
rfm69cw_status = 1;
|
||||
rf12_initialize(nodeID, RF_freq, networkGroup); // Initialize RFM
|
||||
if (debug==1) Serial.println("RFM Started");
|
||||
// Send RFM69CW test sequence (for factory testing)
|
||||
for (int i=10; i>-1; i--)
|
||||
{
|
||||
emonth.temp=i;
|
||||
rf12_sendNow(0, &emonth, sizeof emonth);
|
||||
delay(100);
|
||||
}
|
||||
rf12_sendWait(2);
|
||||
emonth.temp=0;
|
||||
// end of factory test sequence
|
||||
rf12_sleep(RF12_SLEEP);
|
||||
} else {
|
||||
if (debug) Serial.println("RFM69CW NOT Detected");
|
||||
rfm69cw_status =0;
|
||||
// Test for RFM69CW and int with test sequence if found
|
||||
// spiInit();
|
||||
//writeReg(REG_SYNCVALUE1, 0xAA);
|
||||
// int result = readReg(REG_SYNCVALUE1); //CAUSED RFM TO HANG
|
||||
// writeReg(REG_SYNCVALUE1, 0x55);
|
||||
//result = result + readReg(REG_SYNCVALUE1);
|
||||
// readReg(REG_SYNCVALUE1);
|
||||
// if (result!=0){ // result will be > 0 if RFM69CW is found
|
||||
// RF_STATUS = 1;
|
||||
// } else {
|
||||
// if (debug) Serial.println("RFM NOT Detected");
|
||||
// RF_STATUS =0;
|
||||
// }
|
||||
RF_STATUS=1;
|
||||
|
||||
if (RF_STATUS==1){
|
||||
load_config(); // Load RF config from EEPROM (if any exist
|
||||
if (debug) Serial.println("Int RFM...");
|
||||
rf12_initialize(nodeID, RF_freq, networkGroup); // Initialize RFM
|
||||
|
||||
if (debug){
|
||||
Serial.println("RFM Started");
|
||||
Serial.print("Node: ");
|
||||
Serial.print(nodeID);
|
||||
Serial.print(" Freq: ");
|
||||
if (RF_freq == RF12_433MHZ) Serial.print("433Mhz");
|
||||
if (RF_freq == RF12_868MHZ) Serial.print("868Mhz");
|
||||
if (RF_freq == RF12_915MHZ) Serial.print("915Mhz");
|
||||
Serial.print(" Network: ");
|
||||
Serial.println(networkGroup);
|
||||
}
|
||||
// Send RFM69CW test sequence (for factory testing)
|
||||
for (int i=10; i>-1; i--)
|
||||
{
|
||||
emonth.temp=i;
|
||||
rf12_sendNow(0, &emonth, sizeof emonth);
|
||||
delay(100);
|
||||
}
|
||||
rf12_sendWait(2);
|
||||
emonth.temp=0;
|
||||
// end of factory test sequence
|
||||
rf12_sleep(RF12_SLEEP);
|
||||
}
|
||||
|
||||
pinMode(DS18B20_PWR,OUTPUT);
|
||||
pinMode(BATT_ADC, INPUT);
|
||||
|
|
@ -279,6 +295,32 @@ void setup() {
|
|||
WDT_number=720;
|
||||
p = 0;
|
||||
attachInterrupt(pulse_countINT, onPulse, RISING);
|
||||
|
||||
//################################################################################################################################
|
||||
// RF Config mode
|
||||
//################################################################################################################################
|
||||
if (RF_STATUS==1){
|
||||
Serial.println("");
|
||||
Serial.println("'+++' then [Enter] for RF config mode");
|
||||
Serial.println("waiting 5s...");
|
||||
start = millis();
|
||||
while (millis() < (start + 5000)){
|
||||
// If serial input of keyword string '+++' is entered during 5s power-up then enter config mode
|
||||
if (Serial.available()){
|
||||
if ( Serial.readString() == "+++\r\n"){
|
||||
Serial.println("Entering config mode...");
|
||||
showString(helpText1);
|
||||
// char c[]="v"
|
||||
config(char('v'));
|
||||
while(1){
|
||||
if (Serial.available()){
|
||||
config(Serial.read());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//################################################################################################################################
|
||||
// Power Save - turn off what we don't need - http://www.nongnu.org/avr-libc/user-manual/group__avr__power.html
|
||||
|
|
@ -291,7 +333,7 @@ void setup() {
|
|||
// power_timer0_disable(); //don't disable necessary for the DS18B20 library
|
||||
|
||||
// Only turn off LED if both sensor and RF69CW are working
|
||||
if ((rfm69cw_status) && (SI7021_status)){
|
||||
if ((RF_STATUS) && (SI7021_status)){
|
||||
digitalWrite(LED,LOW); // turn off LED to indciate end setup
|
||||
}
|
||||
} // end of setup
|
||||
|
|
@ -358,7 +400,7 @@ void loop()
|
|||
|
||||
|
||||
// Send data via RF
|
||||
if (rfm69cw_status){
|
||||
if (RF_STATUS){
|
||||
power_spi_enable();
|
||||
rf12_sleep(RF12_WAKEUP);
|
||||
dodelay(30); // wait for module to wakup
|
||||
|
|
|
|||
Loading…
Reference in New Issue