summary; I think the limiting factor in speed of this code is the entering of bytes into the blob.
I am using the ADE7953 energy measuring chip from Analog Devices. This ic includes a feature that you can read the data of the instantaneous waveform (plot the sine curve of voltage, waveform of the current). the fastest I have been able to read this is to get 60 readings in 37 milliseconds which is about 1600 Hz.
The read is done by sending a 2-byte address and 3rd byte indicating I want to read rather than write to the register. The ADE chip responds by sending 3 bytes, a 24 bit number. I tried getting the communication to go full duplex but the chip does not seem to work this way.
I have run the spi clock as high as 3750 kHz and it does not get appreciably faster than much slower speeds, though of course there is a speed gain due to the shorter communication time.
3750 kHz - time to build data points is 37.2ms
486 kHz - time to build data points is 48.1 ms
have I done all I can?
btw, I am sending a table with blobs in it from device to agent. The agent is decoding the blobs and making arrays, then converting to JSON for the browser. this is an optimization I added recently and I feel it made the software more responsive.
I only ask for this waveform data infrequently. The primary function of the device is to do the mundane ; log watts.
`
cswriter <- CSpin.write.bindenv(CSpin);
myspi <- hardware.spi189;
myspireader <- myspi.writeread.bindenv(myspi);
function getawavespi(){
//pre-compute the register address string
local Vaddr = format("%c%c", (V>>8), V&0xff);
local IAaddr = format("%c%c", (IA>>8), IA&0xff);
//add the read byte and blank bytes to keep the clock going
//strings are 6 bytes long
local readVolts= Vaddr + format("%c",128) + format("%c%c%c",0xaa,0xaa,0xaa);
local readCurrent= IAaddr + format("%c",128)+ format("%c%c%c",0xaa,0xaa,0xaa);
//blobs to hold the data, 3 bytes each, 60 data points
local IAblob = blob(180); //current
local Vblob = blob(180); //volts
local tblob = blob(240); //time
//results of spi read
local resultV = “”;
local resultA = “”;
local start = hardware.micros();
//60 data points, taking roughly 37 to 50 milliseconds
for(local a=0;a<60;a+=1){
cswriter(0);
resultV = myspireader(readVolts);
cswriter(1);
tblob.writen(hardware.micros(), 'i');
try {
Vblob.writen(resultV[5],'b');
Vblob.writen(resultV[4],'b');
Vblob.writen(resultV[3],'b');
}
catch (e)
{
Vblob.writen(0,'b');
Vblob.writen(0,'b');
Vblob.writen(0,'b');
}
cswriter(0);
resultA = myspireader(readCurrent);
cswriter(1);
try {
IAblob.writen(resultA[5],'b');
IAblob.writen(resultA[4],'b');
IAblob.writen(resultA[3],'b');
}
catch (e)
{
IAblob.writen(0,'b');
IAblob.writen(0,'b');
IAblob.writen(0,'b');
}
}
server.log(hardware.micros()-start);//37.26 milliseconds
cswriter(1);
//built a table up with tables and values to send to the agent
local sendtable = {};
sendtable[“IAblob”] <- IAblob;
sendtable[“Vblob”] <- Vblob;
sendtable[“tblob”] <- tblob;
sendtable[“start”] <- start;
//Get RMS values so we can normalize the vertical scale
local ICOUNTA = readbus(IRMSA)
local VCOUNT = readbus( VRMS);
//add RMS values to the table so that the agent will get them
sendtable[“ICOUNTA”] <- ICOUNTA;
sendtable[“VCOUNT”] <- VCOUNT;
//Send the raw blobs to the agent where they can be decoded and
//turned into waveforms
agent.send(“wave”,sendtable);
}`