I2C reading 4 bytes from 1 register.

Greetings!

I am controlling a capacitive touch panel using SSD2533 via I2C. The registers of SSD2533 are either 2 bytes or 4 bytes in length(i.e. 2 bytes or 4 bytes of data in 1 register address).

I have no trouble in writing the registers(two bytes to one register address). However, when I tried to read from a 4 bytes register, the Wire libraries seems to return and repeat only the 1st byte of the register.

I tried:

  Wire.beginTransmission(TPadd);
    Serial.print("Number of bytes sent:");
    a = Wire.write(byte(0x7C));
    Serial.println(a);
    Wire.endTransmission();
    b = Wire.requestFrom(TPadd, 4);
    Serial.print("Number of bytes return:");
    Serial.println(b);
    Serial.println("Trying to read..");
    while(4 <= Wire.available())    // slave may send less than requested
  { 
    c1 = Wire.read(); // receive a byte as character
    c2 = Wire.read();
    c3 = Wire.read();
    c4 = Wire.read();
    Serial.println(c1,HEX);         // print the character
    Serial.println(c2,HEX);
    Serial.println(c3,HEX);
    Serial.println(c4,HEX);
  }

Outputs :

Number of bytes sent:1
Number of bytes return:4
Trying to read..
D9
D9
D9
D9

where D9 is the reading of the x axis of touch panel. The rest bytes are eaten by the Wire lib.

I also tried:

Wire.beginTransmission(TPadd);
Serial.print("Number of bytes sent:");
a = Wire.write(byte(0x7C));
Serial.println(a);
Wire.endTransmission();
b = Wire.requestFrom(TPadd, 4);
Serial.print("Number of bytes return:");
Serial.println(b);
Serial.println("Trying to read..");
while(4 <= Wire.available()) // slave may send less than requested
{
c1 = Wire.read(); // receive a byte as character
c2 = Wire.read()<<8;
c3 = Wire.read()<<16;
c4 = Wire.read()<<24;
Serial.println(c1,HEX); // print the character
Serial.println(c2,HEX);
Serial.println(c3,HEX);
Serial.println(c4,HEX);
}

the outputs :

Number of bytes sent:1
Number of bytes return:4
Trying to read..
B6
0
0
0

where B6 is reading of x axis. The rest bytes are eaten by the Wire lib.

I am 100% sure that the I2C is returning the correct 1st byte data of the register. But how can I read the rest?

When I go to the wire lib, I found out that the buffer of I2C data register is 8bits. Anybody can help me out with this?

The following is the datasheet of the register:

The following is the recommended reading sequence:

Hi!

We are experiencing exactly the same problems as you. We have worked with this problem for a whole week no, so we begin to run out of ideas. We have confirmed that the device receives our commands, and returns the first byte multiple times.
Did you solve the problem? I'm very interesting to hear the solution if possible.

Regards,
Svein Arne

PLease post the whole code as this snippet gives too little information to analyse the cause.
I expect you have a wrong datatype for the c1, c2, c3, c4 but I cannot confirm

furthermore you should check the return value of Wire.endTransmission();
this should be 0 for success

Hi!

Here is the code:

#include <Wire.h>
#define slave0 0x48

//ssd2533 registers
#define event_stack byte(0x86)
#define device_id byte(0x2)
#define touch_status byte(0x79)
#define sleep_out byte(0x4)

void setup(){
Wire.begin();
Serial.begin(9600);
Serial.println("Welcome to this non-working shit");
Serial.println(" ");
Serial.println("commands: ");
Serial.println("w - Wake up "); //We know that the SSD2533 receives and accepts this command
Serial.println("s - Go to sleep "); //We know that the SSD2533 receives and accepts this command
Serial.println("2 - Get device id "); //Returns two bytes: 0x2525 Should be:0x2533
Serial.println("t - Get Touch status "); //Returns bytes from SD2533, but all bytes are the same(The first byte is most likely correct)
Serial.println("e - Get Event stack "); //Returns bytes from SD2533, but all bytes are the same(The first byte is most likely correct)
Serial.println(" ");

}
void loop(){

if (Serial.available() > 0)
{
char c = Serial.read();
if(c=='2'){
Serial.println("Testing GetDeviceID..");
runCommand(B0000010, 2);
}

if(c=='w'){
Serial.println("Waking up..");
wakeUp();
Serial.println("DONE..");
Serial.println(" ");
}

if(c=='s'){
Serial.println("Sleeping..");
sleep();
Serial.println("DONE..");
Serial.println(" ");
}
if(c=='t'){
Serial.println("Testing touch status..");
runCommand(0x79, 2);
}
if(c=='e'){
Serial.println("Event stack..");
runCommand(0x86, 5);
}
}

}

void wakeUp(){
runCommand(B0000100, 0);
delay(300);
runCommand(B0000000, 0);
}
void sleep(){
runCommand(B0000101, 0);
}

void runCommand(byte reg, int back_amount){

Wire.beginTransmission(slave00);
int num_sent = Wire.write(reg);

int test = Wire.endTransmission();

if(num_sent>0){
Serial.print(num_sent);Serial.print("B Sent ");Serial.print(" (HEX: ");Serial.print(reg,HEX);Serial.println(")");
}
else{
Serial.print("Could not send");Serial.print(" (HEX: ");Serial.print(reg,HEX);Serial.println(")");
}

Serial.print("Resp.code: ");
Serial.println(test);
int val;
//Do retreve if expecting data back
if(back_amount>0)
{
byte incomingBytes[back_amount];
delay(20);
Wire.requestFrom(slave0,back_amount);
if(Wire.available()>=back_amount){
//Get data
for(int i=0; i<back_amount; i++){
incomingBytes = (byte)Wire.read();

  • }*
  • //Print data*
  • for(int i=0; i<back_amount; i++){*
    _ Serial.println(incomingBytes*,HEX);_
    _
    }_
    _
    }_
    _
    }_
    _
    Serial.println(" ");_
    _
    }*_
incomingBytes[i] = (byte)Wire.read();

The same in the print statement that follows it.

Hi!

Thanks for looking into it!
This mistake will obviously result in the behaviour that we experience. Despite of this, I'm not convinced that this is the main issue.

I have my suspicions, because we used a real simple code earlier that just wrote to the device(0x2), and did two separate read operations with an Serial.println inbetween. Wire returned also then two exactly same bytes(0x2525) then as well.

Thank you so much! Correction of this error will save us alot of frustration, and hopefully a correct read from the device.

I will of course try it(monday morning) and come back with results.

Regards,

Svein Arne

Hi!

I had to go to my office today and try it. I corrected the code, but the result is still the same...any ideas?

Regards,
Svein Arne

Hi Svein and hexxx309

EDIT

Could you try changing your endTransmission calls (before you read the register) to:

Wire.endTransmission(false)

I noticed in the scan of the datasheet that the device requires a repeated start flag between writing the register address and reading the register contents. Adding false to endTransmission is meant to do this.

Any improvement?

Regards

Ray

Hi!

Thank you very much!
I will try it tomorrow morning and let you know.

Regards,
Svein Arne

Hi!

THANK YOU SO MUCH!

This simple parameter solved the problem.
We have earlier tried requestfrom(xx,x,false), but never tried endtransmission(False).
Now we recevies the correct bytes!

Again, Thank you!

Regards,
Svein Arne