Arduino, MPC3202 and power monitoring

Looking at the SPI bus and interfacing the MCP3202 DAC.  I’ve started to get my mains power monitor on to the breadboard and have the opto isolating working great. Couldn’t find a lot of information on interfacing the MCP3202 12bit DAC to the Arduino, so had to go from first principles. I thought I share the code here..

But before that, I should explain, I have CH0 of the DAC connected to 50Hz 5V peak to peak source with a 2.25V offset.  The code below is a quick test to see if can find the zero crossing points for the wave form.

#include "SPI.h"
const int cs=10;                         // chip select (pin 10)
unsigned int DAC_val = 0;                // DAC value
unsigned int last_val = 0;               // last value (for compare)
unsigned long time;                      // a variable for timing info

unsigned int DAC_read( byte channel ) {
  byte commandbits = B00001101;          //command bits - 0000, start, mode, chn, MSBF
  unsigned int b1 = 0;                   // get the return var's ready
  unsigned int b2 = 0;
  commandbits|=((channel-1)<<1);         // update the command bit to select either ch 1 or 2
  digitalWrite(cs, LOW);                 // select the MCP3202
  SPI.transfer(commandbits);             // send out the command bits
  const int hi = SPI.transfer(b1);       // read back the result high byte
  const int lo = SPI.transfer(b2);       // then the low byte
  digitalWrite(cs, HIGH);                // let the DAC go, we'done
  b1 = lo + (hi << 8);                   // assemble the two bytes into a word
  return (b1 >> 4);                      // We have got a 12bit answer but strip LSB's if
                                         // required >>4 ==10 bit (0->1024), >>2 ==12bit (0->4096)
}

void setup() {                           // basic setup stuff here
  pinMode(SS, OUTPUT);                   // make sure slave select is an output
  SPI.setClockDivider( SPI_CLOCK_DIV4 ); // slow the SPI bus down
  SPI.begin();                           // SPI at the ready
  Serial.begin(57600);                   // Serial at the ready
}

void loop() {                            // Loop time
  DAC_val = DAC_read( 1 );               // Read channel 0
                                         // look for a rising edge x-ing point
                                         // 0 == 512 from the DAC
  if (( last_val < 512 ) && ( DAC_val >= 512 )) {
                                         // found 0 xing point, show some timing info
    Serial.println( (micros() - time ) );
    time = micros();                     // store uS in time var
  }
  last_val = DAC_val;                    // save current DAC value for compare next time
}

Works a treat.. outputs about 19616uS.. Which when you take away the serial routine the timing is very close to the magic 20000uS for a 50Hz wave.

Carambola Core – interesting…

8devices Carambola Core is a tiny 35×45 mm, low cost, open-source and Linux friendly, easy embeddable module which allows adding extensive wireless and wired networking capabilities to any device around us in the upcoming era of the Internet things. Module can be supplied with an open source design development board which provides easy access to all Carambola Core functionality and can be a good starting point for quick time to market product development.

SPI and I2C bus, UART, USB, 802.11n and cabled Ethernet… for 22€. Very cool..

Carambola module

Isolated mains power monitoring (Arduino)

All about power today.. For a while now, I’ve been looking around for a mains (220-240VAC) power monitoring circuit that I might be able to interface with an Arduino.  There is of course the OpenEnergyMonitor solution, but they seem to use a transformer to isolate and measure the mains voltage.  The transformer doesn’t exactly couple to the mains nicely: so the voltage on the secondary side is not a scaled voltage of the input side, the transformer itself will distort the voltage sine wave.

Then over the weekend I came across Dave Berkeley’s Project Page, and he has a cool design for mains power usage monitor that does measure the line voltage directly. His Home Energy Monitor uses a dual channel ADC with opto-isolation, nice solution. There is loads of info over at his site, I’ve just changed a few little parts for my version.  He uses a 10bit ADC [MPC2003] which I couldn’t get from RS, they were showing back order on the part, so I had a dig around and came up with a 12bit version of the same chip [MPC3202] just have to watch the conversion time, it’s not 200ksps but 100ksps, but I don’t see it being a problem (famous last words!).

So started up KiCAD and got work, then on to RS to get the parts! If you like a PDF of the circuit diagram here you go: Mains Power Monitor Circuit Diagram (rev 1.0)

Initial circuit diagram for my power meter

On Dave’s circuit he has a voltage divider that I couldn’t make sense of, it looks like he has 100K current limiting resisters on the two input lines and a divider made up from one of these and a 270R.  The simulation on this only gave a 2.08 -> 2.92 volt swing on the ADC, given a 311V peek to peek AC input [which is 220VAC * sqt(2)]. I’ve used 1M0 on the current limiting and a divider of 1M0 and 10K, which give a little more input to the ADC.

Oregano Simulation on mains voltage divider

I’ve used an op-amp here to semi-simulate the ADC input just to check for any filtering that might be on the ADC front end.

Mains voltage divider – Transient Analysis plot

So there we have it, stay tuned.. Will post the prototyped version soon, parts due in a few days.. Scope at the ready!