[SOLVED]Problem with I2c and multiple Wire.requestFrom()

In trying to read EDID data and getting erroneous results. Any pointers would be appreciated.

Proper Data should be

(000) 00 FF FF FF FF FF FF 00 4C AB
(010) 00 00 01 00 00 00 23 17 01 03
(020) 81 56 30 78 8A A5 8E A6 54 4A
(030) 9C 26 12 45 46 AD CE 00 81 40
(040) 01 01 01 01 01 01 01 01 01 01
(050) 01 01 01 01 04 74 00 30 F2 70
(060) 5A 80 B0 58 8A 00 56 E1 31 00
(070) 00 1E 9A 29 A0 D0 51 84 22 30
(080) 50 98 36 00 60 E1 31 00 00 1C
(090) 00 00 00 FD 00 32 4B 18 3C 0B
(100) 00 0A 20 20 20 20 20 20 00 00
(110) 00 FC 00 53 45 33 39 55 59 30
(120) 34 0A 20 20 20 20 01 65

Data return with 32 byte Wire.requestFrom() calls. One byte after every 32 is missed.

 (000) 00 FF FF FF FF FF FF 00 4C AB 
 (010) 00 00 01 00 00 00 23 17 01 03 
 (020) 81 56 30 78 8A A5 8E A6 54 4A 
 (030) 9C 26 45 46 AD CE 00 81 40 01   (should read - 9C 26 **12** 45 46 AD CE 00 81 40)
 (040) 01 01 01 01 01 01 01 01 01 01 
 (050) 01 01 01 04 74 00 30 F2 70 5A 
 (060) 80 B0 58 8A 56 E1 31 00 00 1E 
 (070) 9A 29 A0 D0 51 84 22 30 50 98 
 (080) 36 00 60 E1 31 00 00 1C 00 00 
 (090) 00 FD 00 32 4B 18 0B 00 0A 20 
 (100) 20 20 20 20 20 00 00 00 FC 00 
 (110) 53 45 33 39 55 59 30 34 0A 20 
 (120) 20 20 20 01 65 02 03 2A

Data return with 16 byte Wire.requestFrom() calls. One byte after every 16 is missed.

 (000) 00 FF FF FF FF FF FF 00 4C AB 
 (010) 00 00 01 00 00 00 17 01 03 81   (should read - 00 00 01 00 00 00 **23** 17 01 03)
 (020) 56 30 78 8A A5 8E A6 54 4A 9C 
 (030) 26 12 46 AD CE 00 81 40 01 01 
 (040) 01 01 01 01 01 01 01 01 01 01 
 (050) 01 04 74 00 30 F2 70 5A 80 B0 
 (060) 58 8A 00 56 31 00 00 1E 9A 29 
 (070) A0 D0 51 84 22 30 50 98 36 00 
 (080) E1 31 00 00 1C 00 00 00 FD 00 
 (090) 32 4B 18 3C 0B 00 20 20 20 20 
 (100) 20 20 00 00 00 FC 00 53 45 33 
 (110) 39 55 30 34 0A 20 20 20 20 01 
 (120) 65 02 03 2A 71 4F 06 07

Sample code below.

#include <Wire.h>

#define EDID_LENGTH 128

void setup() { 
  Serial.begin(115200);
  Wire.begin();
  delay(1000);
  ddcRead(32);
  ddcRead(16);
}

void loop() {
}

void ddcRead(byte req_size) {
  byte i = 0;
  byte edidbyte;
  Wire.beginTransmission(0x50);
  Wire.write(byte(0x00));
  Wire.endTransmission(); 
  delay(100);   
  Serial.print(req_size);
  Serial.println(" bytes at a time");
  for (int block = 0; block < (EDID_LENGTH / req_size ); block++) {
    Wire.requestFrom(0x50, req_size);
   
    while (Wire.available() && i < EDID_LENGTH) {
      edidbyte = Wire.read();
      if (i % 10 == 0) {
        Serial.println();
        Serial.print(" (");
   
        if (i < 10) Serial.print(0);
        if (i < 100) Serial.print(0);
        
        Serial.print(i);
        Serial.print(") ");
      }
      
      if (edidbyte < 16) Serial.print(0, HEX);
      
      Serial.print(edidbyte, HEX);
      Serial.print(" ");
      i++;
    }
  }
  Serial.println();
  Serial.println("********");
}

gamereaper:
In trying to read EDID data and getting erroneous results. Any pointers would be appreciated.

Which Arduino are you using?

Try adding the third parameter to the requestFrom(0x50,reqSize,false); It tells the Wire library not to Issue a stop command on the I2C bus. Your device may auto increment its internal register pointer when it sees STOP, START.

Or, just explicitly set the 'new' address before each request from:

void ddcRead(byte req_size) {
  byte i = 0;
  byte edidbyte;
  Serial.print(req_size);
  Serial.println(" bytes at a time");
  for (int block = 0; block < (EDID_LENGTH / req_size ); block++) {
    Wire.beginTransmission(0x50);
    Wire.write(byte(i));
    Wire.endTransmission(); // maybe you should use endTransmission(false); to use reStart protocol
    delay(100); // is the device really this slow?   

    Wire.requestFrom(0x50, req_size);
   
    while (Wire.available() && i < EDID_LENGTH) {
      edidbyte = Wire.read();
      if (i % 10 == 0) {
        Serial.println();
        Serial.print(" (");
   
        if (i < 10) Serial.print(0);
        if (i < 100) Serial.print(0);
       
        Serial.print(i);
        Serial.print(") ");
      }
     
      if (edidbyte < 16) Serial.print(0, HEX);
     
      Serial.print(edidbyte, HEX);
      Serial.print(" ");
      i++;
    }
  }
  Serial.println();
  Serial.println("********");
}

Chuck.

Chuck,

Thanks, the code as modified seems to have done the trick.

FYI, I am using the Mega.

From your comment the delay(100) is most likely too aggressive on my part, but this was just for testing.

Thanks again.