How to directly write to one value in a two-dimensional array

I am trying to directly write to individual values of a two-dimensional array. The following code runs without displaying an error but the results are not what I want or expect.

Is it possible to do this in squirrel? how?

code and output:

Device
`
TwoDimArrayTest <- array(6,[7,8]);

agent.send(“test”,TwoDimArrayTest);

TwoDimArrayTest[3] = [3, 4];//works

agent.send(“test”,TwoDimArrayTest);

TwoDimArrayTest[5][0] = 9;//does not work?
TwoDimArrayTest[5][1] = 12;//does not work?

server.log(TwoDimArrayTest[0][0]);
server.log(TwoDimArrayTest[0][1]);

agent.send(“test”,TwoDimArrayTest);`

Agent
`
function test (iv){

server.log(http.jsonencode(iv));

}

device.on(“test”,test);`

result is this:

The values 9 and 12 are being assigned to all elements of the array instead of only the sixth one (index 5)

[Agent] [ [ 7, 8 ], [ 7, 8 ], [ 7, 8 ], [ 7, 8 ], [ 7, 8 ], [ 7, 8 ] ]
[Device] 9
[Agent] [ [ 7, 8 ], [ 7, 8 ], [ 7, 8 ], [ 3, 4 ], [ 7, 8 ], [ 7, 8 ] ]
[Device] 12
[Agent] [ [ 9, 12 ], [ 9, 12 ], [ 9, 12 ], [ 3, 4 ], [ 9, 12 ], [ 9, 12 ] ]

You have run into a really sneaky problem!

The line of code you’re using to initialize the array is the problem:

TwoDimArrayTest <- array(6,[7,8]);

This line of code is not creating a new two-dimensional array. It’s creating a new 1-dimensional array, with each slot in the array filled with a pointer to another array.

It’s a subtle, but important, difference.

What this means is that each slot in the array is pointing to the same array.

That first line of code is equivalent to this:

baseArray <- [6,7] TestTwoDimArray <- array(6, baseArray);

I think what you want to do is this:

TestTwoDimArray = array(6); foreach(t in TestTwoDimArray) { t = array(2); t[0] = 6; t[1] = 7 }

Arrays are making my eyes bleed. I’m creating an iOS math flashcard app for work. Objective-C makes reminding you that you are using pointers a little more visually obvious.

thanks for the snappy reply, but that code didn’t seem to work.

Here is the actual code in my Device; i left in the part that didn’t work but commented it out.

This stuff is really hard to understand.

The reason I am doing this is that I want to read values into this array as fast as possible. I could be wrong but I have the impression this will be the fastest if the array already contains all if its elements and only needs the values to be modified.

I am reading the waveform data from the ADE7953 chip - same as the Becky board.

Currently I can get datapoints about 950 microseconds apart. This is good enough for now for this 60Hz wave.

`

local Iwave = array(60);

local Vwave = array(60);

//Commented this out because it did not work
//foreach(t in Vwave){
// t = array(2);
//}

//This seems to be a necessary part of creating a new array with zeros
for(local a=0;a<60;a+=1){
Vwave[a] = [0,0];//
}

//Capture a rough waveform by reading the Voltage and Current channels
//as fast as possible

for(local a=0;a<60;a+=1){

Vwave[a][1] = reads(i2c, V);//
Iwave[a][1] = reads(i2c, IA);//
Iwave[a][0] = hardware.micros();//

}

`

Oh - if you’re trying to capture a wave form, you want to be using the Sampler Class!

ya, except the ADE7953 chip is doing the analog work and the waveform that I am getting is just by reading the registers as fast as possible over I2c. It works well enough for now.

I think it might run faster if I used a blob but I have not found good documentation on that. Maybe using SPI would also be faster but to change to that I would have to do another board.

This table and array stuff is a bit hard to understand. I have been able to make my way through trial and error and by looking at examples but I have yet to reach the threadshold of true understanding.

I do appreciate the help… a lot!

Ahh, I see.

If you can use a blob, it would be a lot faster. What’s the range of values you get back from the I2C registers? Are they all 1 byte long?

The numbers are 24 bit signed. by the way, I started this code by using Hugo’s code for the Becky board. I have changed it a lot since then but I still use the code he wrote for the I2c read.

Heh, I still use this code too (I have two beckys at home, one on a floor lamp and one on the christmas tree lights)

Energy measuring is such a hot topic in certain circles these days. I found it useful in diagnosing and fixing my gas hot water heater. It did not fire reliably and the power draw history showed the success or failure due to the electric fan and igniter. I have also put a meter on computers to track the power-reduction modes.

I have a start at reading from I2c to blobs and it does speed things but only a small amount. I think the big gain would be to change from I2C to SPI in a later spin of the board.

@Hugo, I found one odd thing in the ADE7953 ic. The first thing I tried to calibrate it on was a floor lamp with a two-position dimmer switch. The low position cuts half the cycle from the power. The ADE chip has a high-pass filter in the signal path to remove DC offsets from the signal. Normally this is a good thing but on that particular load it causes the chip to give the wrong result as it offsets the current waveform from the correct level.

In other words, the waveform is assumed to be symmetric +/-.

I’ll share back the web/device/agent code when I get it to a slightly better state.

just tested the improved code for grabbing a short bit of the waveform.

it reads from I2C to blobs, then creates 2D arrays, then adds it to a JSON table that will go to Highcharts.

It is my first code using blobs so I am definitely interested to hear if I have done something bad - and other should copy snippets with caution.

`
function getawave(){

local IAblob = blob(180); //current
local Vblob = blob(180); //volts
local tblob = blob(240); //time

//pre-compute the I2C address
local Vaddr = format("%c%c", (V>>8), V&0xff)
local IAaddr = format("%c%c", (IA>>8), IA&0xff)

//establish the variable by reading once. required?
local res = i2c.read(0x71, Vaddr, 3);
local resIA = i2c.read(0x71, IAaddr, 3);

local start = hardware.micros();

//TRY to read as FAST as possible.
//loop is 845 microseconds on average
for(local a=0;a<60;a+=1){

res = i2c.read(0x71, Vaddr, 3);

resIA = i2c.read(0x71, IAaddr, 3);

tblob.writen(hardware.micros(), 'i');

IAblob.writen(resIA[2],'b');
IAblob.writen(resIA[1],'b');
IAblob.writen(resIA[0],'b');

Vblob.writen(res[2],'b');
Vblob.writen(res[1],'b');
Vblob.writen(res[0],'b');

}

// now get the data ready for output
//extract from blob, scaled and inserted to ARRAY for JSON for Highcharts

local Iwave = array(60);

local Vwave = array(60);

//This seems to be a necessary part of creating a new array with zeros
for(local a=0;a<60;a+=1){
Vwave[a] = [0,0];//
}

for(local a=0;a<60;a+=1){
Iwave[a] = [0,0];//
}

//Get value of RMS current
local ICOUNTA = readi2c (i2c, 0x21a)

//Get value of RMS potential
local VCOUNT = readi2c(i2c, VRMS);

//scale the waveform to volts
local _VRMS = (1.0* VCOUNT/CAL._VOLTSCALE);

//scale the waveform to amps
local _IRMS = (1.0* ICOUNTA/CAL.CURRENTSCALARA);

//scale the waveform so 100 is the peak of a pure sine wave
//with waveforms different than ‘sine’ the peak will be other than +100/-100

_VRMS = (141.42/CAL._VOLTSCALE)/_VRMS;

//for power factor other than 1.0, the current waveform will grow
_IRMS = (141.42/_IRMS) /(CAL.CURRENTSCALARA*previousjson.meterdata.PF);

//set the blob points to the beginning
Vblob.seek(0,‘b’);
tblob.seek(0,‘b’);
IAblob.seek(0,‘b’);

local mask = (1<<24);//for converting to signed numbers

for(local a=0;a<60;a+=1){

//build the blob back into signed integers
local _V= Vblob.readn('b');
 _V = _V | (Vblob.readn('b')<<8);
_V = _V | (Vblob.readn('b')<<16);

if (_V > (mask>>1)) {
  _V=_V - mask;
}

local IA= IAblob.readn('b');
IA = IA | (IAblob.readn('b')<<8);
IA = IA| (IAblob.readn('b')<<16);

if (IA > (mask>>1)) {
  IA=IA-mask;
}

local tm= tblob.readn('b');
tm = tm | (tblob.readn('b')<<8);
tm = tm| (tblob.readn('b')<<16);
tm = tm| (tblob.readn('b')<<24);

//Format the data so that Highcharts will get the JSON Array it needs
//and apply the scaling

Vwave[a][1] = (_VRMS * _V);
Iwave[a][1] = (_IRMS * IA);
Vwave[a][0] = 0.001*  (tm-start);
Iwave[a][0] = 0.001*  (tm-start+423);

//server.log(a + " , " + b + " , " + tm + " , " + IA);

}

responsejson[“waveIA”] <- Iwave;
responsejson[“waveV”] <- Vwave;

server.log(“waveform added to output JSON”);

}

`

In general there are not necessary “to read ad fast as possible” because that have no sense for energy metering.
Especially if ADE use delta-sigma modulation for calculations. And there is a reason for that.
I have do that (conventional method - sum of instant volt-ams values multiplication) with about 1200 samples per 50Hz period. Results are fare from acceptable due to noise etc. in all available circuits.
By the way - my current headache is 125Mps voltage and current sampling in power convertors - it is very difficult to split real voltage-current values and inducted noise. It is possible easy get efficiency more than 1.
In overall - sampling rate is about 3-4KHz in practice. Theoretically: SMPS must have defined harmonics levels up to ~40 harmonic - 2 KHz for 50Hz. That mean that sampling rate must be 4 KHz.
Attempt to increase speed as discussed here is important for fast fuzzy logic bit the best fuzzy logic is analog:)

oh, I read as fast as possible only to display the shape of the waveform on the web app. This snapshot of the waveform helps to show what kind of load there is, whether there is noise, etc. This is just a sanity check. For the energy or watts I read the accumulated energy register.

There is also a peak register I can read and this can give a little more of a clue what the load is like.

Thanks for the notes about switching power supplies. This is good information.

Can any one help me with a C code for initial configuration of ADE7953 IC.I have been trying very hard on it.