Arduinopower Source Code

So the other day I got a comment about my Ardunipower project. This encouraged me to dig out the source code and post it here. It’s a long way short of finished (and I’ve stopped working on the project.. since early 2010!), but hopefully this will provide at least some kind of insight into how I had commands going back and forth to the ADE7753 power measurement IC.

This code initialises all the various addresses within the ADE7753 from the data sheet. I then wrote (hardest part) a couple of routines to do multi-byte send/receive operations over SPI (Maybe it’s I2C.. I can’t remember anymore!) between the Arduino and the ADE7753. This particular version of the code is a demonstrator that polls some values and sends them back to a PC over serial (great if you have a bluetooth link going on!), slightly less good if you’re on a cable as my PCB design isn’t opto-isolated.

The next stage (that I didn’t do!) was calibration – actually turning the echoed values into something meaningful, and in particular adjusting to the measurement skew introduced between the voltage measures and the current transformer.

 

//registers on ADE7753  
#define WAVEFORM 0x01
#define AENERGY 0x02
#define RAENERGY 0x03
#define LAENERGY 0x04
#define VAENERGY 0x05
#define LVAENERGY 0x06
#define LVARENERGY 0x07
#define MODE 0x09
#define IRQEN 0x0A
#define STATUS 0x0B
#define RSTSTATUS 0x0C
#define CH1OS 0x0D
#define CH2OS 0x0E
#define GAIN 0x0F
#define PHCAL 0x10
#define APOS 0x11
#define WGAIN 0x12
#define WDIV 0x12
#define CFNUM 0x14
#define CFDEN 0x15
#define IRMS 0x16
#define VRMS 0x17
#define IRMSOS 0x18
#define VRMSOS 0x19
#define VAGAIN 0x1A
#define VADIV 0x1B
#define LINECYC 0x1C
#define ZXTOUT 0x1D
#define SAGCYC 0x1E
#define SAGLVL 0x1F
#define IPKLVL 0x20
#define VPKLVL 0x21
#define IPEAK 0x22
#define RSTIPEAK 0x23
#define VPEAK 0x24
#define RSTVPEAK 0x25
#define TEMP 0x26
#define PERIOD 0x27
#define TMODE 0x3D
#define CHKSUM 0x3E
#define DIEREV 0x3F

#define DATAOUT 11//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

//SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR1)|(1<<SPR0); //set clock rate to 1/16th system

byte eeprom_output_data;
byte multi_byte_data[3];
byte eeprom_input_data=0;
long long_eeprom_data = 0;
byte clr;
int address=0;
//data buffer
char buffer [128];

void fill_buffer()
{
  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  Serial.begin(115200);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<SPR1)|(1<<SPR0);
  SPSR = (0<<SPI2X);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  Serial.println("init complete");
  delay(1000);

  //testrun starts here

  //utils
  //read_eeprom(address value, how many bytes)
  //write_to_eeprom(target, values, bytes to write)

  //read what is there right now
  //address = LINECYC;
//  Serial.print(address,HEX);
 // eeprom_output_data = read_eeprom(STATUS,2);

  //long TestWrite;
  //TestWrite = 0xABCD;
  //write_to_eeprom(address, TestWrite, 2);
// Serial.println(eeprom_output_data, BIN);
  //eeprom_output_data = read_eeprom(address, 2);
  //Serial.println("Completed basic read write test");

}

void write_to_eeprom(int EEPROM_address, long write_buffer, int bytes_to_write)
{
  //Serial.print("Multiwrite ops to addr>");
  //Serial.println(EEPROM_address, HEX);
  //set write mode
  byte make_write_cmd = B10000000;
  byte this_write = B00000000;
  EEPROM_address = EEPROM_address|make_write_cmd;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer((char)(EEPROM_address));      //send address

  //here there should be a t7 delay, however long that is
  for (int i = 0; i<bytes_to_write; i++){
  //Serial.println(i);
  this_write = byte(write_buffer>>(8*((bytes_to_write-1)-i)));
  //Serial.println(this_write, HEX);
  spi_transfer((char)(this_write));      //send data byte
  }
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
}

long read_eeprom(int EEPROM_address, int bytes_to_read)
{
  //Serial.print("Multi-read to addr>");
  //Serial.print(EEPROM_address, HEX);
  Serial.println(" Data starts:");
  long data = 0;
  byte reader_buf = 0;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  for (int i = 1; i <= bytes_to_read; i++){
    reader_buf = spi_transfer(0xFF); //get data byte
    Serial.println(i);
    Serial.println(reader_buf, BIN);

    data = data|reader_buf;
    if (i< bytes_to_read) {
      data = data<<8;
    }
    }
  Serial.print("completed. data was>");
  Serial.println(data, BIN);
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
}

void loop()
{

    eeprom_output_data = read_eeprom(STATUS,2);
   Serial.println("STATUS CHECK");
   Serial.println(eeprom_output_data, BIN);
   Serial.println(eeprom_output_data, HEX);
   delay(1000);
   eeprom_output_data = read_eeprom(LINECYC,2);
   Serial.println("LINECYC CHECK");
   Serial.println(eeprom_output_data, BIN);
   Serial.println(eeprom_output_data, HEX);   

}
Tagged , , , , , , , , , , , , ,

2 thoughts on “Arduinopower Source Code

  1. […] This page is all about my attempt to build a desktop scale power meter, based on the arduino platform. It was a project I worked on for some time in 2009, before I decided to buy a house and lost all my free time to mortgage calculations. In the end I produced the first prototype, but the power readings were not as accurate as I’d hoped for, though all of the interfacing between the arduino and the ADE 7753 worked fine. None the less, I’m happy for anyone who is in need of a reference design to pick this up and use it as per the Creative Commons license. All of the information below has been rescued from the site arduinopower.pbworks.com which I originally set up for the project and have now mothballed. I will upload the schematics and libraries to github when I have time, the source code is already on this blog here. […]

Leave a comment