Created
August 26, 2013 09:51
-
-
Save mattiarossi/6339834 to your computer and use it in GitHub Desktop.
emonTx firmware, three CT sensors, one temperature, retrieves data from I2C and forwards it to emonBase
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <DallasTemperature.h> | |
#include <OneWire.h> | |
#include <JeeLib.h> | |
#include <Ports.h> | |
#include <PortsBMP085.h> | |
#include <PortsLCD.h> | |
#include <PortsSHT11.h> | |
#include <RF12.h> | |
#include <RF12sio.h> | |
#include <EmonLib.h> | |
/* | |
EmonTx CT123 + Voltage example | |
An example sketch for the emontx module for | |
CT and AC voltage sample electricity monitoring. Enables real power and Vrms calculations. | |
Part of the openenergymonitor.org project | |
Licence: GNU GPL V3 | |
Authors: Glyn Hudson, Trystan Lea | |
Builds upon JeeLabs RF12 library and Arduino | |
emonTx documentation: http://openenergymonitor.org/emon/modules/emontxshield/ | |
emonTx firmware code explination: http://openenergymonitor.org/emon/modules/emontx/firmware | |
emonTx calibration instructions: http://openenergymonitor.org/emon/modules/emontx/firmware/calibration | |
THIS SKE228/TCH REQUIRES: | |
Libraries in the standard arduino libraries folder: | |
- JeeLib https://github.com/jcw/jeelib | |
- EmonLib https://github.com/openenergymonitor/EmonLib.git | |
Other files in project directory (should appear in the arduino tabs above) | |
- emontx_lib.ino | |
*/ | |
/*Recommended node ID allocation | |
------------------------------------------------------------------------------------------------------------ | |
-ID- -Node Type- | |
0 - Special allocation in JeeLib RFM12 driver - reserved for OOK use | |
1-4 - Control nodes | |
5-10 - Energy monitoring nodes | |
11-14 --Un-assigned -- | |
15-16 - Base Station & logging nodes | |
17-30 - Environmental sensing nodes (temperature humidity etc.) | |
31 - Special allocation in JeeLib RFM12 driver - Node31 can communicate with nodes on any network group | |
------------------------------------------------------------------------------------------------------------- | |
*/ | |
#define FILTERSETTLETIME 5000 // Time (ms) to allow the filters to settle before sending data | |
//CT 1 is always enabled | |
const int CT2 = 1; // Set to 1 to enable CT channel 2 | |
const int CT3 = 1; // Set to 1 to enable CT channel 3 | |
#define freq RF12_868MHZ // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have. | |
const int nodeID = 11; // emonTx RFM12B node ID | |
const int networkGroup = 210; // emonTx RFM12B wireless network group - needs to be same as emonBase and emonGLCD needs to be same as emonBase and emonGLCD | |
const int UNO = 1; // Set to 0 if your not using the UNO bootloader (i.e using Duemilanove) - All Atmega's shipped from OpenEnergyMonitor come with Arduino Uno bootloader | |
#include <avr/wdt.h> // the UNO bootloader | |
#include <I2C.h> | |
const uint8_t SlaveDeviceId = 1; | |
#include <JeeLib.h> // Download JeeLib: http://github.com/jcw/jeelib | |
ISR(WDT_vect) { Sleepy::watchdogEvent(); } | |
#include "EmonLib.h" | |
EnergyMonitor ct1,ct2,ct3; // Create instances for each CT channel | |
#define ONE_WIRE_BUS 4 // Data wire is plugged into port 2 on the Arduino | |
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) | |
DallasTemperature sensors(&oneWire); | |
DeviceAddress address_T1 = { 0x28, 0x4F, 0xC3, 0xA2, 0x04, 0x00, 0x00, 0x13 }; | |
DeviceAddress address_T2 ={ 0x28, 0xAD, 0x0B, 0xA3, 0x04, 0x00, 0x00, 0xC7 }; | |
int sw1State = -1 ; | |
int sw2State = -1; | |
int sw3State = -1; | |
int pump1Active = -1; | |
int pump2Active = -1; | |
int anomaly = -1; | |
typedef struct { int power1, power2, power3, Vrms, T1, sw1State, sw2State, sw3State, pump1Active, pump2Active, anomaly, anomalyRelay1, anomalyRelay2; } PayloadTX; // neat way of packaging data for RF comms | |
PayloadTX emontx; | |
const int LEDpin = 9; // On-board emonTx LED | |
boolean settled = false; | |
void setup() | |
{ | |
I2c.begin(); | |
I2c.pullup(true); | |
I2c.timeOut(2000); | |
Serial.begin(9600); | |
Serial.println("emonTX CT123 Voltage example"); | |
Serial.println("OpenEnergyMonitor.org"); | |
Serial.print("Node: "); | |
Serial.print(nodeID); | |
Serial.print(" Freq: "); | |
if (freq == RF12_433MHZ) Serial.print("433Mhz"); | |
if (freq == RF12_868MHZ) Serial.print("868Mhz"); | |
if (freq == RF12_915MHZ) Serial.print("915Mhz"); | |
Serial.print(" Network: "); | |
Serial.println(networkGroup); | |
ct1.voltageTX(222.365, 1.7); // ct.voltageTX(calibration, phase_shift) - make sure to select correct calibration for AC-AC adapter http://openenergymonitor.org/emon/modules/emontx/firmware/calibration. Default is set for Ideal Power voltage adapter. | |
ct1.currentTX(1, 111.1); // Setup emonTX CT channel (channel (1,2 or 3), calibration) | |
// CT Calibration factor = CT ratio / burden resistance | |
ct2.voltageTX(222.365, 1.7); // CT Calibration factor = (100A / 0.05A) x 18 Ohms | |
ct2.currentTX(2, 111.1); | |
ct3.voltageTX(222.365, 1.7); | |
ct3.currentTX(3, 111.1); | |
sensors.begin(); | |
rf12_initialize(nodeID, freq, networkGroup); // initialize RF | |
rf12_sleep(RF12_SLEEP); | |
pinMode(LEDpin, OUTPUT); // Setup indicator LED | |
digitalWrite(LEDpin, HIGH); | |
if (UNO) wdt_enable(WDTO_8S); // Enable anti crash (restart) watchdog if UNO bootloader is selected. Watchdog does not work with duemilanove bootloader // Restarts emonTx if sketch hangs for more than 8s | |
} | |
void loop() | |
{ | |
sensors.requestTemperatures(); // Send the command to get temperatures | |
emontx.T1 = sensors.getTempC(address_T2) * 100; | |
Serial.print(emontx.T1);Serial.print(" "); | |
ct1.calcVI(20,2000); // Calculate all. No.of crossings, time-out | |
emontx.power1 = ct1.realPower; | |
Serial.print(emontx.power1); | |
emontx.Vrms = ct1.Vrms*100; // AC Mains rms voltage | |
if (CT2) { | |
ct2.calcVI(20,2000); //ct.calcVI(number of crossings to sample, time out (ms) if no waveform is detected) | |
emontx.power2 = ct2.realPower; | |
Serial.print(" "); Serial.print(emontx.power2); | |
} | |
if (CT3) { | |
ct3.calcVI(20,2000); | |
emontx.power3 = ct3.realPower; | |
Serial.print(" "); Serial.print(emontx.power3); | |
} | |
Serial.print(" "); Serial.print(ct1.Vrms); | |
Serial.println(); delay(100); | |
// Request data from slave. | |
uint8_t r = I2c.read(SlaveDeviceId,(uint8_t)6); | |
if (r==0){ | |
if(I2c.available() ==6){ | |
emontx.sw1State = I2c.receive() ; | |
emontx.sw2State = I2c.receive(); | |
emontx.sw3State = I2c.receive(); | |
emontx.pump1Active = I2c.receive(); | |
emontx.pump2Active = I2c.receive(); | |
emontx.anomaly = I2c.receive(); | |
if (emontx.pump1Active && emontx.power1 < 100){ | |
emontx.anomalyRelay1 = 1; | |
}else{ | |
emontx.anomalyRelay1 = 0; | |
} | |
if (emontx.pump2Active && emontx.power2 < 100){ | |
emontx.anomalyRelay2 = 1; | |
}else{ | |
emontx.anomalyRelay2 = 0; | |
} | |
digitalWrite(LEDpin, HIGH); delay(20); digitalWrite(LEDpin, LOW); // flash LED | |
delay(200); | |
digitalWrite(LEDpin, HIGH); delay(20); digitalWrite(LEDpin, LOW); // flash LED | |
Serial.print("Switch 1: "); | |
Serial.println(emontx.sw1State); delay(100); | |
Serial.print("Switch 2: "); | |
Serial.println(emontx.sw2State); delay(100); | |
Serial.print("Switch 3: "); | |
Serial.println(emontx.sw3State); delay(100); | |
Serial.print("Pump1: "); | |
Serial.println(emontx.pump1Active); delay(100); | |
Serial.print("Pump2: "); | |
Serial.println(emontx.pump2Active); delay(100); | |
Serial.print("Pump1 Anomaly : "); | |
Serial.println(emontx.anomalyRelay1); delay(100); | |
Serial.print("Pump2 Anomaly : "); | |
Serial.println(emontx.anomalyRelay2); delay(100); | |
} | |
else | |
{ | |
Serial.print("Unexpected number of bytes received: "); | |
Serial.println(I2c.available()); | |
emontx.sw1State = -1 ; | |
emontx.sw2State = -1; | |
emontx.sw3State = -1; | |
emontx.pump1Active = -1; | |
emontx.pump2Active = -1; | |
emontx.anomaly = -1; | |
emontx.anomalyRelay1 = -1; | |
emontx.anomalyRelay2 = -1; | |
} | |
}else{ | |
Serial.println("Slave not connected!!!"); | |
emontx.sw1State = -1 ; | |
emontx.sw2State = -1; | |
emontx.sw3State = -1; | |
emontx.pump1Active = -1; | |
emontx.pump2Active = -1; | |
emontx.anomaly = -1; | |
emontx.anomalyRelay1 = -1; | |
emontx.anomalyRelay2 = -1; | |
} | |
// because millis() returns to zero after 50 days ! | |
if (!settled && millis() > FILTERSETTLETIME) settled = true; | |
if (settled) // send data only after filters have settled | |
{ | |
send_rf_data(); // *SEND RF DATA* - see emontx_lib | |
digitalWrite(LEDpin, HIGH); delay(2); digitalWrite(LEDpin, LOW); // flash LED | |
emontx_sleep(5); // sleep or delay in seconds - see emontx_lib | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment