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);   

}
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.