Finally got it working, combining Robin's Mk2 code, with eMonTx and an LCD display.
Still some problems with the current measurements, but so far so good.
Ignore the very messy wiring!!!
Video of the device in operation....
Nice work Stuart.
When you say 'finally', have you had problems? - I haven't been keeping up with the forum recently :(
I've had to re-write Robin's code to use interrupt handlers and thats been causing problems. I've also spent time minimising the phase difference between voltage + current samples in the circuit.
I've still got issues with the emonTX side of the code not measuring current properly, and at the moment I've no idea why!
I've published my working code for all this on github.
1. emonTx features monitoring of current and voltage
2. Solar PV power divert (as per Mk2 PV controller)
3. Output to LCD display
4. Interrupt driven reading of samples + PV power divert
I'll publish the circuit diagram once I've moved it over to stripboard.
In breif, I'm using an OpAmp gain on the CT readings to monitor current. Mascot AC adapter to measure voltage, which is also driven through an OpAmp comparitor circuit to detect positive zero cross detections which then fire hardware interrupt 1.
Once a zero cross has been detected, a second interrupt is setup to read samples from the wave form at set time intervals. I find reading 50-75 samples per full AC wave gives good readings.
On the next zero cross, the previous samples are used to drive the solar pv power divert logic. The eMonTx readings are taken every half second using the average of 25 wave form readings.
Because of the interrupt driven nature of the code/circuit, the main loop() of the code simply outputs things to serial or the LCD screen and doesn't need to worry about affecting the timing of the readings.
I'm going to attempt to put in the RFM12 module, and adjustable OpAmp gain with bilateral switches.
Great stuff !
Just what we are looking for?
Do you need an addition CT?
Look forward to your circuit details
At the moment, I'm not directly measuring PV power using a seperate CT.
Although I think theres time/room to add it into the code.
Might have problems with EMMA patent then though
Just started putting the circuit diagram together using CircuitLab, great site only just started using it today!
You can also run circuit simulation to see the waveforms - all from your web browser.
Circuit Lab does a great job!
Do you think your code will work using Robins MKII circuit? (unmodified)
I see you have more filtering and voltage stabilization on the 2.5v ref rail, and an opamp on the ac ref circuit
As you are using EmonTX are there any pin differences with Arduino Uno?
I'm not using emonTx or an Arduino board, simply the ATMEGA328P chip on breadboard!
I'm trying to use the newer features from emonTX-SMT but without the SMT parts !!
Additionally, running at 3.3v is not important to me as this is going to be run from the mains 24x7.
The code may work with Robin's MKII circuit, you'll just have to check the calibration values to get accurate readings, and you will need someway to do hardware phase calibration, otherwise the PHASECAL values will be large 2+ which makes for bad readings. Thats what the registor/capacitor combination are doing in the bottom right of my diagram.
Additionally, I'm using interrupts which need to be triggered from a zero crossing so some sort of detector is needed for this.
Amazingly I've now got RFM12B working with this circuit + code, transmitting the values over the air.
I made a stripboard version of this http://jeelabs.com/products/rfm12b-board
All working on a couple of prototype/breadboards - amazing !
I'm getting VERY short of spare digital pins now though, and need a couple for the OpAmp gain pins.
Looked at the Fritzing software last night and came up with this layout (needs a tidy up!) the software is clever in that it will turn this into a scematic and also a PCB layout - almost automatically.
The Fritzing layout file is on GITHUB if anyone ones it github.com/stuartpittaway/ArduinoSolarPowerController
Stuart, LM358 is not suitable for feeding the ADC as the output will not swing high enough. The datasheet is not very forthcoming on this, quoting results only for a 30V supply (28V max). An older datasheet I saw specified high level output voltage as Vcc – 1.5. This means that on a 5V supply the output will not go much above 3.5V, which will severely compromise the ADC measurements.
LM358 is good for generating the 2.5V rail and for feeding digital inputs, but not for feeding the ADC!
I carried out some measurements on several opamps to measure the minimum and maximum output voltage, as well as the ADC measurements from an Arduino. The circuit was a unity gain inverting amp, with the 2.5V reference coming from a 2.5V rail as per your circuit. All the resistors were 100kΩ. The supply voltage was measured as 5.04V.
As you can see, the maximum ADC reading from the LM358 was 764, obviously unacceptable.
First prize went to the OP295, with the full range of ADC outputs all the way from 0 to 1023. Unfortunately, OP295s seem to be becoming scarce and expensive. However, OP279 and TS912 both give very good results, and some are available on ebay.
It is worth noting that with the opamp in the inverting mode, the full range on the ADC will only be obtained if the 2.5V rail is precisely half way between the rails. If the resistor tolerance is 1%, you might expect to lose around 10 counts at one or other end of the scale. I had an old batch of 1% resistors that were very consistent, all the resistances were identical. With the 5V rail measuring 5.04V, the 2.5V measured 2.52V, which is very good. However, a new batch of 100kΩ resistors I bought recently on ebay are less consistent. The first two I picked gave 2.54V on the 2.5V rail – still within tolerance, but not as good.
Oh, and before I forget, many thanks to calypso_rae and stuart for publishing this excellent work. I intend to start building one soon.
Stuart the 2.5V reference in your circuit is shown as driving 100nF its only specified for 50pF so may have a tendency to oscillate. you can run without the op amp but only if you have a large cap ( 100uF ) across r2 and drop the values of r1 and r2 to 10k otherwise the adc inputs cross talk due to insufficient drive to charge the sample and hold in the time allowed.
Thanks for your comments folks:
Robin, I was simply using the LM358 as I had a bunch of them!
Just noticied the AVR reference notes are using the LMV358 (http://www.atmel.com/Images/doc2566.pdf) which seems to be a rail to rail opamp.
I could also run the ADC at a lower reference voltage - 1.1volt for instance and still retain the full scale output from the LM358 ?
pmcalli: Thanks for the feedback, you say run without the OpAmp - are you referring to a simple split resistor network instead ?
Given the above comments, I'm surprised its working as well as it does :-)
Stuart, if the purpose of the 100nF is to stablise the 2.5V rail, it might be better to connect it to the junction of R1 and R2. I have seen this arrangement used elsewhere.
Please can I ask a question about the zero crossing detector? I see that on the input R11 and R12 are 10k and 12k, so there is an offset from 2.5V. What is the thinking behind this please, and were any calculations involved?
Robin, if you look at the zero crossing detector on the breadboard, Im using a variable trimmer pot, and the OpAmp as a comparator, the trimmer then sets when the interrupt fires.
You don't actually want the interrupt firing at the exact time of zero cross, it needs to be slightly before this so the interrupt can then begin its reading and do some logic before the new sine wave starts. I configured this pot by watching the VZerocross value output in the serial window and trying to get as near to 512 as I could.
Thanks for the feedback, you say run without the OpAmp - are you referring to a simple split resistor network instead ?
Single resistor network of 2x10K and an FBC of 100uF across bottom one. It takes up same space and cost is about the same.
On the comments about selection of OpAmp, LM358 its mentioned that the output never goes above the top rail voltage-1.5v.
If I leave the OpAmp running at 5v, and then run the rest of the circuit from 3.3v (which also keeps the RFM12B happy) then I can get a much better range on the ADC, of 0.06v to 3.3v based on the numbers given above.
My DC bias circuit would then have to output about 1.6v to keep everything aligned.
I've got a box full of LM358's so I'd like to use them :-) but on a more realistic point, they are cheap to buy and easy to find.
I would like to suggest a method of measuring mains voltage that offers a different trade-off between the (conflicting) requirements.
This one offers the following advantages:
It is accurate.
It is safe if properly constructed.
It offers over-voltage protection up to 1000V.
It does not require a separate transformer.
It is reasonably cheap. The most expensive component is a TS912 opamp, available from RS in a DIL package at under £2. (LMV358 is also suitable.)
The circuit can still be connected to an LCD or a computer for monitoring.
The disadvantage is that it involves making direct connections to the mains, but we have to do that already if we are making a mains controller, so I don't see that as a disadvantage. When you look at the problem, you find that two small pieces of heatshrink sleeving are all that is required to make the system completely safe. However, all the usual precautions must be applied!
I have built this circuit and tested it on a breadboard, measuring the mains voltage waveform using the Arduino ADC. Full details are here. http://openenergymonitor.org/emon/node/1105
An LTSpice simulation was used to test the system and check that it is not damaged by high voltages. Further tests also checked that the circuit measures only mains voltage, and that any voltage between neutral and earth is filtered out. For this test there is 50V at 48z on the mains neutral line for this purpose. The circuit can be seen to measure only the 240V AC mains voltage – the voltage on neutral is filtered out. A screenshot of the simulation is shown on the attachment below.
One more thing: Stuart, your method of running the Arduino at 3.3V and an LM358 at 5V looks good, and may be an improvement over what I have done here.
Last night I finally got around the building the OpAmp circuit using a 3.3v regulator as the signal voltage.
So I have 3.3v going to the AREF on the ATMEL chip, 3.3v then runs to a voltage divider, giving 1.65v centre to the current and voltage sensor circuits.
Even when run through the op-amp, the signal is no longer clipped and the range on the arduino is very good.
Had to set analogReference(EXTERNAL) in the code to make it work.
How's the project going? Any more progress?
Have you sorted the problems you mentioned at the start moving to an interrupt driven code structure?
Really keen to see how this one goes!
Yes the interrupt code is working fine, I've not had much time to move from a breadboard working prototype to something more permanent - probably stripboard in my case.
I've added a 3.3v regulator to the circuit, and now looking at how to add a variable op-amp gain using similar circuit to the emontxSMT from this site.
Cool. I'm wondering at what stage I should jump in!
Do you think you're there yet? Are the Github/Fritzing locations up to date?
Sorry to be a pain!
The diagrams/Fritzing are old now, although they do work.
The Github is up-to-date, and works fine if you just want standard emontx+mk2 pv without the Opamp gain stuff.
Open-source tools for energy monitoring and analysis. Forum has moved to: https://community.openenergymonitor.org