I have a new board, nominally working using the ADE7953 IC. With the code from the Becky reference design I got off to a fast start but then hit a 4 hour brick wall trying to write to the 24 bit registers.
I am getting either no change to the register or else i get the wrong value written.
I simplified my code down a bit and tested it to make sure what I pasted below still works the same way. The main point is in this area:
//B100000000000000000000 - as startup
//B110000000000000000000 - I wanted this value of 180000h
//B 11000000110000 - is what I got. 12336 in the log - I assume it is decimal
This is the code that does not give the desired result
write (i2c,0x22C, "\\x180000");//IRQENA try to set the 19th bit
I tried to flip just one bit by writing the new/modified register value and this is my best result - I actually got the register value to change but not to the correct number
Some questions:
-
Where can I find some documentation on the format command. I cannot seem to find this in the squirrel docs or the imp api.
-
any help on what is going on with the register writing? The example code is a bit fancy compared to my skill; I do get the part where the number of bytes is auto-detected by the address number. I get a little bit turned around when it comes to strings and hex numbers - especially pertaining to squirrel code.
thanks in advance for any help. : )
`
//
/*
Code Derived from
electric imp [[becky]]
Trace: • becky
Electric Imp Developer Wiki
http://www.analog.com/en/analog-to-digital-converters/energy-measurement/ade7953/products/product.html
*/
local function read(i2c, addr) {
// registers 0-ff are 8 bit, 100-1ff are 16 bit, 200-2ff are 24 bit and
// 300-3ff are 32 bit
//local res = i2c.read(0x70, format("%c%c", addr>>8, addr&0xff), 1+(addr>>8));
local res = i2c.read(0x71, format("%c%c", addr>>8, addr&0xff), (1+(addr>>8))); //71 for read (70 for write)
local resv = 0;
if (res != null) {
foreach (b in res) resv = (resv<<8) + b;
return resv;
}
else
{
server.log("result is null");
}
return 0;
}
// Signed read
local function reads(i2c, addr) {
local r = read(i2c, addr);
local length = 1 + (addr>>8);
local mask = 1<<(length<<3);
if (r > (mask>>1)) return r-mask;
return r;
}
local function write(i2c, addr, data) {
// registers 0-ff are 8 bit, 100-1ff are 16 bit, 200-2ff are 24 bit and
// 300-3ff are 32 bit
local length = 1 + (addr>>8);
//server.log (typeof addr);
//server.log (typeof data);
i2c.write(0x70, format("%c%c", addr>>8, addr&0xff) + data);
}
// Pin1-2= I2C i2c12
// Pin5 = Pin CF2
// Pin7 = Pin CF1
// Pin8 = IRQ
// Pin9 = RESET
i2c <- hardware.i2c12;
i2c.configure(CLOCK_SPEED_100_KHZ);
write(i2c, 0xFE, “\xAD”);
write(i2c, 0x120, “\x30”);
server.log(read(i2c, 0xFE) + " required register unlock");//page 18
write(i2c, 0xFE, “\xAD”);
server.log(read(i2c, 0x120) + " required register setting");//page 18
// configure current gain to 1 (500mV swing max)
write(i2c, 0x008, “\x0”);
server.log(read(i2c, 0x008) + " register 8");
//server.log(read(i2c, 0x702) + " silicon number");
// configure voltage gain to 1 (500mV P-P swing max) but our nominal signal is 170mV, allowing for waveform errors
write(i2c, 0x007, “\x0”);
//server.log(read(i2c, 0x007) + " register 7");
// configure active energy line accumulation mode on current channel A, clear on read
write(i2c, 0x004, “\x41”);
//server.log(read(i2c, 0x004) + " register 4");
write (i2c,0x000,"\xFF");//set sag to 255ms as this is the max allowed
//server.log(read(i2c, 0x000) + " SAGCYC Register"); //this line WORKS - puts out 255The number of cycles for sensing this
server.log(read(i2c, 0x107) + " should be 768");
server.log(read(i2c, 0x102) + " is the CONFIG register"); //'1000000000000100
//===================================================================================================================
//IRQENA registers are 0x22C and 0x32C
server.log(read(i2c, 0x22C) + " IRQENA Register default is 1048576"); //bit-wise configuration, first read as 1048576, as mentioned in the datasheet
write (i2c,0x22C, “\x180000”);//IRQENA try to set the 19th bit
server.log(read(i2c, 0x22C) + " IRQENA Register after writing 0x180000"); //bit-wise configuration, first read as 1048576 Decimal
//100,000h change to 180000h
//1048576 change to 1572864
//B100000000000000000000 change to B110000000000000000000
//This code results in the DECIMAL result of 12336, hex of 3030 and BIN of
//B100000000000000000000 - as startup
//B110000000000000000000 - I wanted this value of 180000h
//B 11000000110000 - is what I got. 12336 in the log - I assume it is decimal
//the 19th bit enables the SAG interrupt, the 20th is always enables
//=================================================================================================================
//write (i2c,0x200, “\x2512D”);//SAGLVL register, set to 4V RMS
write (i2c, 0x200, “\x02\x51\x2D”);//SAGLVL register, set to 4V RMS
server.log(read(i2c, 0x200) + " SAGLVL Register"); //The number of cycles for sensing this
//========================================================================================
server.log(“about to write to 0x203 (515)”);
write (i2c, 0x203, “\xE434”);//AP_NOLOAD register
//writesag (i2c, 0x203, “\xFF”);//AP_NOLOAD register
server.log(read(i2c, 0x203) + " AP_NOLOAD Register default reads 58393"); //
server.log(read(i2c, 0x284) + " AVA GAIN: should read 4194304"); //
server.log(read(i2c, 0x2FF) + " value of the last good 24bit register write"); //
server.log(hardware.pin8.read() + " pin 8");
//==========================================================================================
function reporter() {
imp.wakeup(05, reporter);
local awatt = reads(i2c, 0x0212);
// Debug if we want more detail
local cyclecount = read(i2c, 0x010e);
local vrms = read(i2c, 0x21c);
local peak = read (i2c,0x227); //0x226 is voltage peak, 0x227 peak with reset
local Irms = read (i2c, 0x21a);//1773 counts with the power off 4773 counts with voltage applied (crosstalk?)
// No negative readings
if (awatt < 0.0) awatt = 0.0;
// Scaling
local watts = (286.0 * awatt) / 236000.0;
watts = math.floor(watts * 10 + 0.5) / 10.0;
server.log(1.0 * vrms + " , " + (223747.0/(cyclecount+1)) + " , " + 1.0 * peak + " " + awatt + " , " + Irms); //nominal counts scalar is 223000
//sendstate();
}
// Appear on planner
imp.configure("Fancy Power Meter-Proconn", [], []);
// Start reporting
reporter();
/*
These notes were in the original code that I started with
becky.txt · Last modified: 2013/02/06 18:34 by hugo
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
*/
`