I2C write more than one byte of data


#5

I have put 10k pullup registors on SDA and clock lines

i2c <- “i2cAB” in hardware ? hardware.i2cAB : hardware.i2c89;
i2c.configure(CLOCK_SPEED_400_KHZ);
ex_en <- “i2cAB” in hardware ? hardware.pinC : hardware.pinE;

ENABLE <- “i2cAB” in hardware ? 0 : 1;
DISABLE <- “i2cAB” in hardware? 1 : 0;
ex_en.configure(DIGITAL_OUT, ENABLE);

to start and truncate I2C comunication


#6

Reading from EEPROM is working fine.
But reading and writing to RAM is not woking


#7

What is the i2c enable?


#8

I am using Pin-C of electric imp to start I2C communication by writing 0, creating the start of the I2C communication and pulling it high again to stop the communication.

There is an EEPROM and RAM in the sensor both are on I2C. I am ableto read data from EEPROM but writing to the RAM gives error. I think the pullups are working fine as I am able to read from EEPROM

The working code is

function readEEPROM(){
server.log(“read EEPROM data::::::::::::::::::::::::::::::::::::::::::::::”);
local cmd = blob();
cmd.writen(0x00, ‘b’);
ex_en.configure(DIGITAL_OUT, ENABLE);
imp.sleep(0.05);
server.log(“Sending:”);
server.log( cmd.tostring());
local resp = i2c.write(0x50 << 1, cmd.tostring());
server.log("Sending response------------------------------ "+resp);
//imp.sleep(REINSTATE_TIME);
if(resp==0){
server.log(“Successfully send command”);
eepromData = i2c.read(0x50 << 1, “”, 256);
server.log(“length of RAM data---------------------”+(eepromData.len()));
}
ex_en.configure(DIGITAL_OUT, DISABLE);
server.log(eepromData[OSC_TRIM_VALUE])
}


#9

Yeah, I’m asking what circuitry is connected to that pin?


#10

…regardless, scope traces of the i2c bus are likely needed to progress further. I’d also check the power supply to the device is ok (does it have local bypass caps, etc?)


#11

Hi Hugo sorry for delay I was occupied with something else.

I have removed all the external circuit. I have connected the sensor with imp004 on bread board.I have connected to i2CQP to the sensor directly.

I have not used any external pullup in the SDA or Clock line.
The sensor also donot have any pullup.

But still I am able to read data from EEPROM. I am sending code snipet with results

eepromData <- array(256);
i2c <- “i2cQP” in hardware ? hardware.i2cQP : hardware.i2cNM;
i2c.configure(CLOCK_SPEED_400_KHZ);
ex_en <- hardware.pinP;
ex_en1 <- hardware.pinQ;
ENABLE <- “i2cQP” in hardware ? 0 : 1;
DISABLE <- “i2cQP” in hardware? 1 : 0;

function readEEPROM(){
server.log(“read EEPROM data::::::::::::::::::::::::::::::::::::::::::::::”);
local cmd = blob();
cmd.writen(0x00, ‘b’);
server.log(“Pin P state”+ex_en.read());
server.log(“Pin Q state”+ex_en1.read());
imp.sleep(0.05);
server.log(“Sending:”);
server.log( cmd.tostring());
local resp = i2c.write(0x50 << 1, cmd.tostring());
server.log("Sending response------------------------------ "+resp);
if(resp==0){
server.log(“Successfully send command”);
eepromData = i2c.read(0x50 << 1, “”, 256);
server.log(“length of data---------------------”+(eepromData.len()));
}
server.log(“Pin P state”+ex_en.read());
server.log(“Pin Q state”+ex_en1.read());
}

readEEPROM();

Result:

2018-07-08 00:28:03 +05:30 [Device] Pin P state0
2018-07-08 00:28:03 +05:30 [Device] Pin Q state0
2018-07-08 00:28:03 +05:30 [Device] Sending:
2018-07-08 00:28:03 +05:30 [Device] binary: 00
2018-07-08 00:28:03 +05:30 [Device] Sending response------------------------------ 0
2018-07-08 00:28:03 +05:30 [Device] Successfully send command
2018-07-08 00:28:03 +05:30 [Device] length of data---------------------256
2018-07-08 00:28:03 +05:30 [Device] Pin P state0
2018-07-08 00:28:03 +05:30 [Device] Pin Q state0

When I2C comunication starts?

Please explain when there is no pull on the sensor, like the “SA56004X temperature sensor” given in I2C documentation, How we should put pullup resistor? Please sight any example, I searched but i could not get one.

Also please explain the result I am getting
Any clue will be a great help.

Oscilloscope reading will take some while. I have to order one.


#12

I2C is an open drain bus. It requires pull up resistors. Please add these and retest - it’s rather a miracle it’s working at all without them. 4k7 to 3.3v should be fine.

Datasheets for slave devices may not always show pull-ups, but these are always required - you have one set of pullups per bus not one set per device.


#13

Thanks Hugo, I will try and get back


#14

Hi Hugo,
Thanks a lot
I tried with the pullup resistors on the data, and clock line, Now I can write data it is giving ack(0).
so one problem solved.
But
This sensor works like charm with Arduino. In that also external pullup was required. now same pullups I have given here.
Now I got the read error MASTER_RECEIVE_SELECT_ERROR (-10)
I was also surprised why it was giving EEPROM data. In manufacturer’s manual it says no internal pullup, external pull up is required. No matter what I do EEPROM data is reading.
Now I am able to write comands but after writing a command, the value to be read, there it is giving error.


#15

I think seeing the current state of the code would be useful?

Please use the “</>” button in the editor when you paste it, so it formats correctly.


#16
eepromData <- array(256);
 ptatData<-array(64);
 const OSC_TRIM_VALUE    =    0xF7
 i2c <- "i2cQP" in hardware ? hardware.i2cQP : hardware.i2cNM;
 i2c.configure(CLOCK_SPEED_400_KHZ);
 ex_en <- hardware.pinP;
 ex_en1 <- hardware.pinQ;
 ENABLE <- "i2cQP" in hardware ? 0 : 1;
 DISABLE <- "i2cQP" in hardware? 1 : 0;

function readEEPROM(){
server.log("read EEPROM data::::::::::::::::::::::::::::::::::::::::::::::");
local cmd = blob();
cmd.writen(0x00, 'b');
server.log("Pin P state"+ex_en.read());
server.log("Pin Q state"+ex_en1.read());
imp.sleep(0.05);
server.log("Sending:");
server.log( cmd.tostring());
server.log("Pin P state"+ex_en.read());
server.log("Pin Q state"+ex_en1.read());
local resp = i2c.write(0x50 << 1, cmd.tostring());
server.log("Pin P state"+ex_en.read());
server.log("Pin Q state"+ex_en1.read());
server.log("Sending response------------------------------  "+resp);   
if(resp==0){
    server.log("Successfully send command");
    eepromData = i2c.read(0x50 << 1, "", 256);
    server.log("length of data---------------------"+(eepromData.len()));
}
 server.log("Pin P state"+ex_en.read());
 server.log("Pin Q state"+ex_en1.read()+eepromData[0xf7]);
}

function start(){
server.log("start:::::::::::::::::::::::::::::::::::::::");
local resp = i2c.write(0x60 << 1, "\x01"+"\x08");
server.log("Sending response------------------------------  "+resp);   
if(resp==0){
    server.log("Successfully send command for measurement");
    local resp1 = i2c.write(0x60 << 1, "\x02"+"\x00"+"\x01"+"\x40");
if(resp1==0){
    server.log("Successfully send command for temp measurement"+resp1);
    ptatData=i2c.read(0x60 << 1, "\x00",64);
    if(null == ptatData){
   server.error("i2c_recv: Not working. "+ i2c.readerror());
}
    }
    
//server.log("length of data---------------------"+ptatData.len());
}
 server.log(ptatData);
}

function writeTrimmingValue(){
server.log("osc trimming value::::::::::::::::::::::::::::::::::::::::::");
local cmd = blob();
cmd.writen(0x04, 'b');
cmd.writen(eepromData[OSC_TRIM_VALUE] - 0xAA, 'b');
cmd.writen(eepromData[OSC_TRIM_VALUE], 'b');
cmd.writen(0x56, 'b');
cmd.writen(0x00, 'b');
server.log("Sending:");   
server.log(cmd.tostring());
local resp3 = i2c.write(0x60 << 1, cmd.tostring());  
server.log("Sending response------------------------------  "+resp3);
}

function readConfig(){
server.log("Read Configuration:::::::::::::::::::::::::::::::::::::::");
local resp5 = i2c.write(0x60 << 1, "\x02"+"\x00"+"\x01"+"\x40");
local conf=array(64);
server.log("Sending response------------------------------  "+resp5);   
if(resp5==0){
    server.log("Successfully send command for Read Configuration");
    conf = i2c.read(0x60 << 1, "\x00",3);
    if(null == conf){
   server.error("i2c_recv: Not working. Reason: "+ i2c.readerror());
}
}
 server.log(conf);
}

 function setConf(){
server.log("Set Configuration:::::::::::::::::::::::::::::::::::::::");
local resp6 = i2c.write(0x60 << 1, "\x03"+"\xE9"+"\x3E"+"\xF1"+"\x46");
server.log("Sending response------------------------------  "+resp6);   
if(resp6==0){
    server.log("Successfully send command for Set Configuration");
}
}




readEEPROM();
writeTrimmingValue();
//setConf();
start();
//readConfig();

Th result is:

2018-07-11 08:16:05 +05:30 [Status] Downloading new code; 1.99% program storage used
2018-07-11 08:16:05 +05:30 [Device] read EEPROM data::::::::::::::::::::::::::::::::::::::::::::::
2018-07-11 08:16:05 +05:30 [Device] Pin P state0
2018-07-11 08:16:05 +05:30 [Device] Pin Q state0
2018-07-11 08:16:05 +05:30 [Device] Sending:
2018-07-11 08:16:05 +05:30 [Device] binary: 00
2018-07-11 08:16:05 +05:30 [Device] Pin P state0
2018-07-11 08:16:05 +05:30 [Device] Pin Q state0
2018-07-11 08:16:05 +05:30 [Device] Pin P state0
2018-07-11 08:16:05 +05:30 [Device] Pin Q state0
2018-07-11 08:16:05 +05:30 [Device] Sending response------------------------------ 0
2018-07-11 08:16:05 +05:30 [Device] Successfully send command
2018-07-11 08:16:05 +05:30 [Device] length of data---------------------256
2018-07-11 08:16:05 +05:30 [Device] Pin P state0
2018-07-11 08:16:05 +05:30 [Device] Pin Q state083
2018-07-11 08:16:05 +05:30 [Device] osc trimming value::::::::::::::::::::::::::::::::::::::::::
2018-07-11 08:16:05 +05:30 [Device] Sending:
2018-07-11 08:16:05 +05:30 [Device] binary: 04 a9 53 56 00
2018-07-11 08:16:06 +05:30 [Device] Sending response------------------------------ 0
2018-07-11 08:16:06 +05:30 [Device] start:::::::::::::::::::::::::::::::::::::::
2018-07-11 08:16:06 +05:30 [Device] Sending response------------------------------ 0
2018-07-11 08:16:06 +05:30 [Device] Successfully send command for measurement
2018-07-11 08:16:06 +05:30 [Device] Successfully send command for temp measurement0
2018-07-11 08:16:06 +05:30 [Device] ERROR: i2c_recv: Not working. -10
2018-07-11 08:16:06 +05:30 [Device] (null : 0x0)

I am using imp004 breakout board I have also provided the pullup resiortors. I have put nothing else.


#17

Thanks for helping…


#18

One issue here is that your read command is sending “\x00” when nothing is expected. Also, you are issuing the read IR data command, telling it that you’re about to read 64 bytes, then reading 3 of them after this spurious write.

To read IR data, this should work:

// Issue IR data read command, step 1, 0x40 bytes, and read them
local irdata = i2c.read(0x60 << 1, "\x02\x00\x01\x40", 64);
if (irdata == null) server.log("i2c error "+i2c.readerror());
else {
  server.log("read "+irdata.len()+" bytes");
}

#19

Thank you very much, It is working, thanks a lot. It was really a pain.
Could you please explain
i2c.read(0x60 << 1, “\x02\x00\x01\x40”, 64);
“\x02\x00\x01\x40” This is register address?
For reading any data, I need to send the string sequence in place of register address?
Any ways thanks a lot it is working.


#20

Hi Hugo,
can you please tell, what I am doing wrong in this command?
I have to write this command
image
Reading irData is working fine.

 function setConf(){
    server.log("Set Configuration:::::::::::::::::::::::::::::::::::::::");
    local resp6 = i2c.write(0x60 << 1, "\x03"+"\xE9"+"\x3E"+"\xF1"+"\x46");
    server.log("Sending response------------------------------  "+resp6);   
    if(resp6==0){
        server.log("Successfully send command for Set Configuration");
    }
}

setConf();

Result I am getting is:

018-07-12 07:02:43 +05:30 [Device] Set Configuration:::::::::::::::::::::::::::::::::::::::
2018-07-12 07:02:43 +05:30 [Device] Sending response------------------------------ -3

#21

Sorry for leaping in, but Hugo is travelling today. The sequence "\x02\x00\x01\x40" is 0x02 for read, 0x00 for the start address, 0x01 for the address increment, and 0x40 for the number of reads (64). See p31 of the datasheet.

Yes, you send as a string the data the component (whatever it is) expects. In this case that’s the command plus three bytes of data, but it might just be a register address, a different comment, or an address plus further data. The crucial thing is that you just provide a string of the bytes and impOS does all the work sending in in the correct way.


#22

Thanks smittytone,
If you can take a quick look at the code i sent in previous post and tell where I am doing wrong, It will be very big help.


#23

That command looks correct (per the datasheet), however, looking at the configuration register docs (section 8.2.2.1) it seems like 0x3e46 is not a valid value to write to this register (ie, the example is wrong)

In particular, bit 13 is “1” here. The docs say it must be “0”.

If the value sent is instead 0x1e46 you will set 400kHz I2C (correct), step mode (?), 15 bit ADC and 256Hz refresh.

That’d be a write of

i2c.write(0x60 << 1, "\x03\xc9\x1e\xf1\x46")

#24

…any update? Seems like, from my reading, there was a doc issue here.