Merge branch 'master' of github.com:openenergymonitor/emonth2

This commit is contained in:
Glyn Hudson 2016-11-29 13:05:03 +00:00
commit 89e6f34986
9 changed files with 4624 additions and 60 deletions

View File

@ -9,8 +9,11 @@ install:
- pip install -U platformio
script:
- platformio run -d firmware -e emonth2_deploy
deploy:
provider: releases
skip_cleanup: true
overwrite: true
api_key:
secure: nSzsNZeeR5wKud3CHP1MD3r9Uc9vy0hE4ZBLz0U3ATpcpUfh/WB15axs6wU1rOot8mxCo8+FLAhXt0RGfw3kZmEdId/VyBxmunOFDX4hGmXPzCi7ov9RXFsYWKuKOo9owodir+Iu0xF+UrzBKmPKATuRcc5JyW36IdHjFgG1ru41eNMWPk/A4Nre1yWpPh6gK/Fadl261/uuh2hfZbce48yRpzvAjdKWPXPZREjONZi8vwLBLjpS+s9YMaIWvZh+zYjM+jYpPB5MB+R8bjRi9kFkFwTjj0UcI1k/XJ+drdcNKuBfGiHlKu0ACt7HsO5uQWj/PTzy1LQnB45Rf4Dw6qEOIoxPBvlq5gt972LaAuLP5lldAlTcd+pvEntqbe2ziXSaWwTy2/wRx5Bx6xxgB7TSQ7J3JoPNSR9EGY4/3NIosK+4BTl77L7jVhLLxRopxge0PSs7/qej0ZhPJ5JdGWmVlATNZ006PEKdqwiUe+lyEsuuBqBqSlXgBwW1g2jZdkV+dwgpsF9w4MZW7ePFg0xvUEDIYFEs1Jv1ydrVkiRohXzwxZUbK+2xWIAEEiGXg3YR57fzDCCPjfGUHAMCLHeKWJd2SAFgOOXV6Hb2ztlCpLLy9wdL2KXTvDe5Vx1cKxADkW2ixRF0KR9rlCMdmTMmYsJfiUprTpUOQhhXXqs=
file: firmware/.pioenvs/emonth2_deploy/firmware.hex

View File

@ -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

123
firmware/src/config.ino Normal file
View File

@ -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);
}
}

View File

@ -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

4381
hardware/emonTH V2.0.2.fab Normal file

File diff suppressed because it is too large Load Diff

BIN
hardware/emonth2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 824 KiB

View File

@ -6,7 +6,14 @@
V2.0 hardware revision adds support for SI7021 temperature and humidity. This sensor brings performance and power savings over the DHT22, see `sensor_test` folder of this repo for sensor evaluation and comparison.
<<<<<<< HEAD
![emonTH V2](hardware/emonth2.png)
=======
### Open-Hardware
- Hardware schematic & CAD files are in the `hardware` folder of thisw repo
- See [emonTH V1 Technical Wiki](https://wiki.openenergymonitor.org/index.php/EmonTH_V1.5) for more hardware design notes.
>>>>>>> b956573eccf6fa67f0026f2d06bd417c4f487087
### Related Blog Posts

View File

@ -13,17 +13,25 @@
| Sleep Current | 0.02uA | 0.06uA | 15uA | 750 times less power | 0.1uA - 0.3uA |
| Measurement Current | 0.045mA | 0.09 mA | 0.5mA | 11 times less power | 0.714mA - 0.350mA |
| Measurement time | 0.01s - 0.0026s | 0.01s - 0.0026s | 2s | 200 times faster | 0.013s |
| Energy consumed per sample | 0.00045mW || 1mW | 2222 times less power | |
| Energy consumed per sample | 1.5uJ | 2.97uJ | 3300uJ | 2000 times less power | |
| Time sampling per day* | 14.4s || 2800s | | |
| Time sleeping per day* | 86386s || 83600s | | |
| Energy consumed per day* | 2.36mW [1] || 2836mW [2] | 1201 times less energy per day! | |
| Energy consumed per day* | 7.8mJ [1] || 8700mJ [2] | 1115 times less energy per day! | |
```
energy consumed (joule, J) = potential difference (volt, V) × charge (coulomb, C)
charge (coulomb, C) = current (ampere, A) × time (second, s)
energy consumed (joule, J) = potential difference (volt, V) × current (ampere, A) × time (second, s)
```
## Energy consumed per day*
- **HTU21D:** (14.4s * 0.045mA) + (86386 * 0.00002mA) = 0.63mW + 1.73mW = **2.36mW** [1]
- **DHT22:** (2800s * 0.55mA) + (86386 * 0.015mA) = 1540mW + 1295.8mW = **2836mW** [2]
Energy consumed per day = energy consumed per sample + energy consumed while sleeping.
\*Assuming 1 sample per min and sleeping in between samples, 1440 min per day = 86400s per day
- **HTU21D:** (1400 * 0.0015mJ) + (3.3V * 0.00002mA * 86386 ) = 2.1mJ + 5.7mJ = 7.8mJ [1]
- **DHT22:** (1400 * 3.3mJ) + (3.3V * 0.015mA * 83600) = 4.6mJ + 4.1J = 8.7J = 8700mJ [2]
\*Assuming 1 sample per min and sleeping in between samples: 1400 samples per day
[Adafruit HTU21D Library](https://github.com/adafruit/Adafruit_HTU21DF_Library)