Skip to content

Instantly share code, notes, and snippets.

@mattiarossi
Created August 26, 2013 09:51
Show Gist options
  • Save mattiarossi/6339834 to your computer and use it in GitHub Desktop.
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
#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