Syndicate content
Open-source tools for energy monitoring and visualisation
Updated: 7 hours 59 min ago

Testing KiCad PCB

Sat, 25/10/2014 - 19:54
We are always a fan of using open-source software wherever possible. A few years ago I briefly attempted to use open-source KiCad and gEDA PCB CAD software but found them very limiting, clumsy and buggy.

Recently there have been a raft of shiny looking browser based PCB design tools such as Circuit Maker and Upverter, these look very interesting; the online collaborative development opportunities are obvious and linking into the OctoPart's live component pricing, standard part library and BOM management tools could be a big time saver at the manufacturing stage. Maybe online tools will be the future, however I am a little reserved about having designs locked into a closed online platform.

In particular I have been keeping a close eye on KiCad developments after I heard CERN had got involved in the development. I was very impressed watching this video showing the newly developed KiCad intelligent semi-auto router in action:

I think it's time I gave KiCad another try! Today I managed to install KiCad and put together the RFM12Pi schematic and layout the board. Here's my experience:

I wanted the latest build to get the shiny new features, so I installed the development branch by adding the PPA to Ubuntu:

I installed KiCad build dated 16th July on 32-bit Ubuntu 14.04

I found I needed to add the line "export KIGITHUB="";" to my ~/.profile file to get rid of cannot find github footprint errors when running CvPCB (the program in KiCad which links the schematic parts to PCB footprints)

I followed the fantastic video tutorials from Contextual Electronics to help me get started.

1. KiCad Schematic Editor, net list must be manually exported to move to the next setp
2. Linking schematic parts to PCB footprints
3. Board layout the new interactive router was great (see video above)New router options
Obviously we have considerable lock-in to EAGLE PCB with our historic designs and learning a new software tool is always going to be a slow and slightly frustrating process, however I'm quite impressed that after about 5hrs I think I'm got the hang of basic KiCad functions. I will seriously consider using KiCad for new designs in the future. I think the increased effort will be worthwhile to enable us to be using a fully open-source bit of design software to design open-hardware, what do you think?
Thinks I liked about KiCad:
  • Interactive router, very impressed with this. Big time saver
  • More intuitive setup of default track widths and net classes 
  • How net and pin names are displayed in the layout editor 
  • How schematic symbols and PCB footprints are handled as separate entities, more intuitive than Eagle IMHO  
Thinks I miss moving from Eagle:
  • Have a live link between schematic and PCB, KiCad requires exporting and re-importing a new netlist each time there is a change in schematic
  • There are more ready made parts in Eagle libraries then there are KiCad part libraries, but I'm sure this will change. 
  • Being able to highlight all tracks on a particular net by selecting a wire on the schematic (maybe I've just not found this feature yet in KiCad?)
Categories: Blog

Emonhub installation/update, replacing the PHP raspberrypi emoncms module

Fri, 24/10/2014 - 11:58
From Paul Reed's post on the forums here:

Emonhub is now the recommended method of interfacing a rfm12pi to a local or remote emoncms install, and replaces the PHP and Python scripts which we have previously used.

Update: This blog post refers to installing emonHub on existing system, if setting up a new system downloading the ready-to-go pre-built RaspberryPi image is the easiest way to get started.

Thanks to Paul Burnell, the author of emonhub, installation of emonhub can be achieved via a command line, which clones an installation script to automate the installation process.

To install emonhub:

$ git clone ~/dev-emonhub && ~/dev-emonhub/install

If you have the raspberry pi module already installed, it's important that it is removed prior to installing emonhub, as only one software can use the serial UART the RFM2Pi is connected to at any one time.

To remove the existing module, and then install emonhub, enter the following command line;

$ git clone ~/dev-emonhub && ~/dev-emonhub/upgrade

You will notice that after running this command, that emoncms will stop updating, this is expected until the configuration file is updated as follows;

$ nano /etc/emonhub/emonhub.conf

Enter your emoncms read/write api key in [[[runtimesettings]]] and also enter your rfm2pi frequency, group & base id under [[[runtimesettings]]]
Save your settings, and; $ sudo service emonhub restart

View the error log; $ tail -f /var/log/emonhub/emonhub.log

By default this is set to record 'WARNING', however this can be changed to either - DEBUG, INFO, WARNING, ERROR, and CRITICAL by editing the configuration file.


NOTE - This update will not orphan or alter your input processes, feeds, visualizations or feed data, as it only changes the way in which data is fed to emoncms.
Categories: Blog

From the Forum: Using Modbus RS485 to read a SDM630M 3-phase meter

Thu, 11/09/2014 - 12:20

JBecker writes :
I am using a modified OpenEnergyMonitor energy monitoring hardware since more than a year now, with one voltage sensor and three CTs for the current measurement of the three mains phases. This system logs via the RFM12 and a Jeelink USB dongle to Emoncms on a Windows Home Server. This setup is running very reliably with an accuracy of better than ~4% compared to my power meter. I think it would be possible to get better accuracy by using individual voltage sensors on all phases.
In Germany the majority of household have three phase supply. To be able to use three voltage sensors it would be necessary to have three outlets within the distribution (for non-invasive mounting). I have never seen that. This means that you have to ask a friendly electrician to install these outlets. But then the whole thing is not really 'non-invasive' any more (and the OEM solutions becomes quite complex with a lot of cabling). This is a dilemma which is hard to solve.
So I came to another solution which is quite simple and uses mostly ready-made components:
I am using Chinese 3-phase energy monitors since some time for professional purposes (PV-Systems with battery storage). A very nice unit of this type is the Eastron SDM630M. This device has integrated shunts for current measurement, a nice little display and an RS485 interface for data readout with Modbus protocol. A lot of measuring values can be read, including imported and exported energy, phase voltages, currents, frequency, reactive power and so on. Parameters for the RS485 can also be set via four small keys and the display.

For data storage and visualization I decided use the new Emoncms 'low-write' version on a Raspberry Pi. This was installed according to the installation instructions and worked 'out-of-the-box'. The only thing missing on the RasbPi for direct connection to the SDM630 is an RS485 interface.

To be able to use the already existing software for data collection on the RasPi (Emonhub), I simply made a 'clone' of the RFM12Pi module. This now has an RS485 driver onboard instead of the RFM12 RF transceiver. Software on the RS485Pi board is the Opti-bootloader (same as on RFM12Pi) for Arduino compatibility and a small sketch for data readout via modbus. As the only available hardware UART is already used for communication with the RasbPi I had to use a software serial for the RS485 interface. (The 'ModbusMasterSoft' library I use is a dirty hack of the existing ModbusMaster library and the AltSoftSerial library. I found no decent way to make these two work together, so I had to modify them)
So the whole installation now consists of:
- a Raspberry Pi with power supply and the RS485Pi interface board
- the SDM630 energy meter
(- and a cable in between :-))
See forum thread for schematic and code:

Written by Joerg Becker uses code from: - ModbusMaster library - AltSoftSerial library - pezibaer (SDM630M-DC thread in hardware 'cloned' from: - RFM12Pi (OpenEnergyMonitor, mharazinov) - 3V3 RS485 driver added - bootloader compatible to RFM12Pi ModbusMasterSoft is a dirty hack I made by combining the ModbusMaster library and the AltSoftSerial library. I was unable to combine these two in a decent way. The software serial is used for the RS485, hardware serial for Raspberry Pi connection */ #include <AltSoftSerial.h> #include <ModbusMasterSoft.h> // settings for RS485 bus (SDM630M can be configured to different values!) #define _SDM630M_MODBUS_ID 4 // Modbus address of SD630M energy monitor #define _MODBUS_BAUD 9600 // Modbus (RS485) baud rate // settings for communication with Raspberry Pi #define _INTERVAL 10 // send interval (s) to Raspberry Pi (running EmonCMS) #define _RASPI_BAUD 9600 // UART baud rate // some hardware definitions #define LED1_PIN A0 // RS485 activity LED #define LED2_PIN A1 // UART activity LED //AltSoftSerial AltSerial; // not needed here, done in ModbusMasterSoft // instantiate ModbusMaster object ModbusMasterSoft node(_SDM630M_MODBUS_ID); // float calculations are slow, but here we have enough processing time float v1,v2,v3; float i1,i2,i3; float p1,p2,p3,pa; float v1_sum,v2_sum,v3_sum; float v1_avg,v2_avg,v3_avg; float i1_sum,i2_sum,i3_sum; float i1_avg,i2_avg,i3_avg; float p1_sum,p2_sum,p3_sum,pa_sum; float p1_avg,p2_avg,p3_avg,pa_avg; uint32_t timeout; void setup() { pinMode(LED1_PIN, OUTPUT); pinMode(LED2_PIN, OUTPUT); digitalWrite(LED1_PIN, 0); digitalWrite(LED2_PIN, 0); Serial.begin(_RASPI_BAUD); Serial.println("SDM630M Test Program"); delay(1000); // initialize Modbus communication baud rate node.begin(_MODBUS_BAUD); timeout = millis(); } void loop() { static uint8_t interval = 0; uint8_t result; uint32_t tmpL; tmpL = millis(); if( (tmpL-timeout)>=1000 ) // do this every second { timeout = tmpL; digitalWrite(LED1_PIN, 1); digitalWrite(LED2_PIN, 0); ReadVoltages(); v1_sum += v1; v2_sum += v2; v3_sum += v3; ReadCurrents(); i1_sum += i1; i2_sum += i2; i3_sum += i3; ReadPowers(); p1_sum += p1; p2_sum += p2; p3_sum += p3; pa_sum += pa; if( ++interval>=_INTERVAL ) { interval = 0; v1_avg = v1_sum*10/_INTERVAL; // preserve one (of two) decimal digit(s) v2_avg = v2_sum*10/_INTERVAL; v3_avg = v3_sum*10/_INTERVAL; v1_sum = v2_sum = v3_sum = 0; i1_avg = i1_sum/_INTERVAL; i2_avg = i2_sum/_INTERVAL; i3_avg = i3_sum/_INTERVAL; i1_sum = i2_sum = i3_sum = 0; p1_avg = p1_sum/_INTERVAL; p2_avg = p2_sum/_INTERVAL; p3_avg = p3_sum/_INTERVAL; pa_avg = pa_sum/_INTERVAL; p1_sum = p2_sum = p3_sum = pa_sum = 0; digitalWrite(LED2_PIN, 1); PrintJeelink(); } digitalWrite(LED1_PIN, 0); } } void PrintJeelink(void) { unsigned char i; union DATA { unsigned char item[]; struct { int P1; int P2; int P3; int V1; int V2; int V3; } val; } data; data.val.P1 = (int)(p1_avg+0.5); data.val.P2 = (int)(p2_avg+0.5); data.val.P3 = (int)(p3_avg+0.5); data.val.V1 = (int)(v1_avg+0.5); data.val.V2 = (int)(v2_avg+0.5); data.val.V3 = (int)(v3_avg+0.5); Serial.print(" 10"); // this is data from 'node' number 10 for(i=0;i<sizeof(data.val);i++) { Serial.print(" "); Serial.print(data.item[i]); } Serial.println(); } uint8_t ReadVoltages( void ) { uint8_t result; uint32_t val; result = node.readInputRegisters(0x0000, 6); // read Modbus registers 0 to 5 if (result == node.ku8MBSuccess) { val = ((uint32_t)node.getResponseBuffer(0))<<16 |((uint32_t)node.getResponseBuffer(1)); memcpy(&v1, &val, 4); val = ((uint32_t)node.getResponseBuffer(2))<<16 |((uint32_t)node.getResponseBuffer(3)); memcpy(&v2, &val, 4); val = ((uint32_t)node.getResponseBuffer(4))<<16 |((uint32_t)node.getResponseBuffer(5)); memcpy(&v3, &val, 4); } return result; } uint8_t ReadCurrents( void ) { uint8_t result; uint32_t val; result = node.readInputRegisters(0x0006, 6); // read Modbus registers 6 to 11 if (result == node.ku8MBSuccess) { val = ((uint32_t)node.getResponseBuffer(0))<<16 |((uint32_t)node.getResponseBuffer(1)); memcpy(&i1, &val, 4); val = ((uint32_t)node.getResponseBuffer(2))<<16 |((uint32_t)node.getResponseBuffer(3)); memcpy(&i2, &val, 4); val = ((uint32_t)node.getResponseBuffer(4))<<16 |((uint32_t)node.getResponseBuffer(5)); memcpy(&i3, &val, 4); } return result; } uint8_t ReadPowers( void ) { uint8_t result; uint32_t val; result = node.readInputRegisters(0x000C, 6); // read Modbus registers 12 to 17 if (result == node.ku8MBSuccess) { val = ((uint32_t)node.getResponseBuffer(0))<<16 |((uint32_t)node.getResponseBuffer(1)); memcpy(&p1, &val, 4); val = ((uint32_t)node.getResponseBuffer(2))<<16 |((uint32_t)node.getResponseBuffer(3)); memcpy(&p2, &val, 4); val = ((uint32_t)node.getResponseBuffer(4))<<16 |((uint32_t)node.getResponseBuffer(5)); memcpy(&p3, &val, 4); } return result; } ]]>
Categories: Blog