ESP32 Dev, reading a register of an I2C-Device

Hello!

I have this Code and it works fine at an UNO ( but now i want to use it on an ESP32.
The "Original" is using the SoftI2CMaster.h which does not work on the ESP.

/************************************************************************************

PackProbe

by Erik Speckman

*************************************************************************************/

//  Arduino Dpin6 = Atmega PD7
#define SDA_PORT PORTC
#define SDA_PIN 4

// Arduino DPin8 = Atmega PB4
#define SCL_PORT PORTC
#define SCL_PIN 5

#define I2C_SLOWMODE 1
#include <SoftI2CMaster.h>


// standard I2C address for Smart Battery packs
byte deviceAddress = 11;


#define BATTERY_MODE             0x03
#define TEMPERATURE              0x08
#define VOLTAGE                  0x09
#define CURRENT                  0x0A
#define RELATIVE_SOC             0x0D
#define ABSOLUTE_SOC             0x0E
#define REMAINING_CAPACITY       0x0F
#define FULL_CHARGE_CAPACITY     0x10
#define TIME_TO_FULL             0x13
#define CHARGING_CURRENT         0x14
#define CHARGING_VOLTAGE         0x15
#define BATTERY_STATUS           0x16
#define CYCLE_COUNT              0x17
#define DESIGN_CAPACITY          0x18
#define DESIGN_VOLTAGE           0x19
#define SPEC_INFO                0x1A
#define MFG_DATE                 0x1B
#define SERIAL_NUM               0x1C
#define MFG_NAME                 0x20   // String
#define DEV_NAME                 0x21   // String
#define CELL_CHEM                0x22   // String
#define MFG_DATA                 0x23   // String
#define CELL4_VOLTAGE            0x3C   // Indidual cell voltages don't work on Lenovo and Dell Packs
#define CELL3_VOLTAGE            0x3D
#define CELL2_VOLTAGE            0x3E
#define CELL1_VOLTAGE            0x3F
#define STATE_OF_HEALTH          0x4F

#define bufferLen 32
uint8_t i2cBuffer[bufferLen];

void setup()
{
  

  Serial.begin(9600);  // start serial for output
  Serial.println(i2c_init());


  while (!Serial) {    
    ; // wait for Serial port to connect.
  }

  Serial.println("Serial Initialized");
  
  i2c_init();
  Serial.println("I2C Inialized");
  scan();
}

int fetchWord(byte func)
{
  i2c_start(deviceAddress<<1 | I2C_WRITE);
  i2c_write(func);
  i2c_rep_start(deviceAddress<<1 | I2C_READ);
  byte b1 = i2c_read(false);
  byte b2 = i2c_read(true);
  i2c_stop();
  return (int)b1|((( int)b2)<<8);
}

uint8_t i2c_smbus_read_block ( uint8_t command, uint8_t* blockBuffer, uint8_t blockBufferLen ) 
{
  uint8_t x, num_bytes;
  i2c_start((deviceAddress<<1) + I2C_WRITE);
  i2c_write(command);
  i2c_rep_start((deviceAddress<<1) + I2C_READ);
  num_bytes = i2c_read(false); // num of bytes; 1 byte will be index 0
  num_bytes = constrain(num_bytes,0,blockBufferLen-2); // room for null at the end
  for (x=0; x<num_bytes-1; x++) { // -1 because x=num_bytes-1 if x<y; last byte needs to be "nack"'d, x<y-1
    blockBuffer[x] = i2c_read(false);
  }
  blockBuffer[x++] = i2c_read(true); // this will nack the last byte and store it in x's num_bytes-1 address.
  blockBuffer[x] = 0; // and null it at last_byte+1
  i2c_stop();
  return num_bytes;
}

void scan()
{
  Serial.println("Starte Scan");
  byte i = 0;
  for ( i= 0; i < 127; i++  )
  {
    Serial.print("Address: 0x");
    Serial.print(i,HEX);
   
    bool ack = i2c_start(i<<1 | I2C_WRITE); 
    
    if ( ack ) {
      Serial.println(": OK");
      Serial.flush();
    }
    else {
      Serial.println(": -");
      Serial.flush();      
    }
    i2c_stop();
  }
  Serial.println("Scan beendet");
}

void loop()
{
  uint8_t length_read = 0;

  Serial.print("Manufacturer Name: ");
  length_read = i2c_smbus_read_block(MFG_NAME, i2cBuffer, bufferLen);
  Serial.write(i2cBuffer, length_read);
  Serial.println("");

  Serial.print("Device Name: ");
  length_read = i2c_smbus_read_block(DEV_NAME, i2cBuffer, bufferLen);
  Serial.write(i2cBuffer, length_read);
  Serial.println("");

  Serial.print("Chemistry ");
  length_read = i2c_smbus_read_block(CELL_CHEM, i2cBuffer, bufferLen);
  Serial.write(i2cBuffer, length_read);
  Serial.println("");

  // Serial.print("Manufacturer Data ");
  // length_read = i2c_smbus_read_block(MFG_DATA, i2cBuffer, bufferLen);
  // Serial.write(i2cBuffer, length_read);
  // Serial.println("");
  
  Serial.print("Design Capacity: " );
  Serial.println(fetchWord(DESIGN_CAPACITY));
  
  Serial.print("Design Voltage: " );
  Serial.println(fetchWord(DESIGN_VOLTAGE));
  
  String formatted_date = "Manufacture Date (Y-M-D): ";
  int mdate = fetchWord(MFG_DATE);
  int mday = B00011111 & mdate;
  int mmonth = mdate>>5 & B00001111;
  int myear = 1980 + (mdate>>9 & B01111111);
  formatted_date += myear;
  formatted_date += "-";
  formatted_date += mmonth;
  formatted_date += "-";
  formatted_date += mday;
  Serial.println(formatted_date);

  Serial.print("Serial Number: ");
  Serial.println(fetchWord(SERIAL_NUM));

  Serial.print("Specification Info: ");
  Serial.println(fetchWord(SPEC_INFO));
 
  Serial.print("Cycle Count: " );
  Serial.println(fetchWord(CYCLE_COUNT));
  
  Serial.print("Voltage: ");
  Serial.println((float)fetchWord(VOLTAGE)/1000);

  Serial.print("Full Charge Capacity: " );
  Serial.println(fetchWord(FULL_CHARGE_CAPACITY));
  
  Serial.print("Remaining Capacity: " );
  Serial.println(fetchWord(REMAINING_CAPACITY));

  Serial.print("Relative Charge(%): ");
  Serial.println(fetchWord(RELATIVE_SOC));
  
  Serial.print("Absolute Charge(%): ");
  Serial.println(fetchWord(ABSOLUTE_SOC));
  
  Serial.print("Minutes remaining for full charge: ");
  Serial.println(fetchWord(TIME_TO_FULL));

  // These aren't part of the standard, but work with some packs.
  // They don't work with the Lenovo and Dell packs we've tested
  Serial.print("Cell 1 Voltage: ");
  Serial.println(fetchWord(CELL1_VOLTAGE));
  Serial.print("Cell 2 Voltage: ");
  Serial.println(fetchWord(CELL2_VOLTAGE));
  Serial.print("Cell 3 Voltage: ");
  Serial.println(fetchWord(CELL3_VOLTAGE));
  Serial.print("Cell 4 Voltage: ");
  Serial.println(fetchWord(CELL4_VOLTAGE));
  
  Serial.print("State of Health: ");
  Serial.println(fetchWord(STATE_OF_HEALTH));

  Serial.print("Battery Mode (BIN): 0b");
  Serial.println(fetchWord(BATTERY_MODE),BIN);

  Serial.print("Battery Status (BIN): 0b");
  Serial.println(fetchWord(BATTERY_STATUS),BIN);
  
  Serial.print("Charging Current: ");
  Serial.println(fetchWord(CHARGING_CURRENT));
  
  Serial.print("Charging Voltage: ");
  Serial.println(fetchWord(CHARGING_VOLTAGE));

  Serial.print("Temp: ");
  unsigned int tempk = fetchWord(TEMPERATURE);
  Serial.println((float)tempk/10.0-273.15);

  Serial.print("Current (mA): " );
  Serial.println(fetchWord(CURRENT));
  
  Serial.println(".");
  delay(1000);

But its recomendet to use the SlowSoftI2CMaster.h but I am not getting it. So I tried the SlowSoftWire.h but its similar to the SlowSoftI2CMaster.h.
I know about the procedur:

int fetchWord(byte func)
{
  i2c_start(deviceAddress<<1 | I2C_WRITE);
  i2c_write(func);
  i2c_rep_start(deviceAddress<<1 | I2C_READ);
  byte b1 = i2c_read(false);
  byte b2 = i2c_read(true);
  i2c_stop();
  return (int)b1|((( int)b2)<<8);
}

I tried the Examples of the libaries, but they doesn´t work for me.
So if you have any ideas how to use it with the SlowSoftWire/I2CMaster i would be happy.
My tries looked like:

#define I2C_SLOWMODE 1
#include <SlowSoftWire.h>

SlowSoftWire Wire = SlowSoftWire(21, 22);
// standard I2C address for Smart Battery packs
byte deviceAddress = 11;

int fetchWord(byte func)
{
  unsigned int b1,b2;
  
  Wire.beginTransmission(deviceAddress);
  Wire.write(func);
  Wire.endTransmission();
  Wire.requestFrom(deviceAddress, 2 , false);
  
    b1 = Wire.read();
    b2 = Wire.read();
  Wire.endTransmission();
  return (int)b1|((( int)b2)<<8);
}

void setup() {
Serial.begin(9600);  // start serial for output
 // pinMode(22,INPUT_PULLUP);
//  pinMode(21,INPUT_PULLUP);
Wire.begin();

}

void loop() {
  Serial.print("Temperatur [°C]:     ");
  unsigned int tempk = fetchWord(0x08);
  Serial.println((float)tempk/10.0-273.15);
  delay(1000);

}

Thx Krogs

Have you got a particular reason to use software I2C on the ESP ?

Use the normal Arduino-compatile Wire library.
If you want to change to something else in the future, then you can easily change to a software I2C library that behaves just like the Arduino library.

There is a big list here: https://github.com/Testato/SoftwareWire/wiki/Arduino-I2C-libraries.

init -> begin : alright.
start-write-repeatedstart-read-stop : not okay

The repeated start should be use like this:

  Wire.beginTransmission(deviceAddress);
  Wire.write(func);
  Wire.endTransmission(false);     // false for a repeated start !

  Wire.requestFrom(deviceAddress, 2);   // no third parameter !
  b1 = Wire.read();
  b2 = Wire.read();

  // no endTransmission after a requestFrom !

  return word( b2, b1);   // the 'word()' is a handy function by Arduino

Can you update your sketch and show us the new sketch ?

The code looks now like

#include <Wire.h>
byte deviceAddress = 11;    //0x0B

int fetchWord(byte func)
{
  unsigned int b1,b2;
  Wire.beginTransmission(deviceAddress);
  Wire.write(func);
  Wire.endTransmission(false);

  Wire.requestFrom(deviceAddress, 2 );
    b1 = Wire.read();
    b2 = Wire.read();
  Wire.endTransmission();
  return word(b2,b1);
}

void setup() {
Serial.begin(9600);  // start serial for output
 // pinMode(22,INPUT_PULLUP);
//  pinMode(21,INPUT_PULLUP);
Wire.begin();
}

void loop() {
  Serial.print("Temperatur [°C]:     ");
  unsigned int tempk = fetchWord(0x08);
  Serial.println(tempk);            //Just the pure Value   6280.35
  Serial.println((float)tempk/10.0-273.15);     // 65535
  delay(1000);
}

I didnt used the <Wire.h> because the example i2csanner didnt found the battery which adress ist (0x0B). With the Software stuff it works, but it was found 0x0D too, maybe from the Wifi-modul? SDA is at 21, and SCL at 22
I am using external 10k Pullup resistors, should i remove them?

@krogs
Please follow the advice given in the link below when posting code. Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

Using it for a battery does ring a bell. A software I2C is sometimes slower and has more distance between the signal edges. However, I prefer that you first try to make the normal Wire library work.
Try to find an example of someone who did the same with the ESP32.

You need pullup resistors. 10k is okay.
Do you use wires ? I hope you don't use a flat ribbon cable.
The Arduino Uno has extra strong signals with input and output filters, the ESP32 has "normal" signals.

Remove the Wire.endTransmission() after the Wire.requestFrom()
nonono

You could try with 50kHz instead of the default 100kHz.

Wire.begin();
Wire.setClock( 50000L);

It´s working now with the standard Wire.h. The battery was damaged :roll_eyes: That´s the function now, like

Koepel

said. Ty

int fetchWord(byte func)
{
  unsigned int b1, b2;
  Wire.beginTransmission(deviceAddress);
  Wire.write(func);
  Wire.endTransmission(false);

  Wire.requestFrom(deviceAddress, 2 );
  b1 = Wire.read();
  b2 = Wire.read();
  return word(b2, b1);
}

My only Problem is now this function:

uint8_t i2c_smbus_read_block ( uint8_t command, uint8_t* blockBuffer, uint8_t blockBufferLen ) 
{
  uint8_t x, num_bytes;
  i2c_start((deviceAddress<<1) + I2C_WRITE);
  i2c_write(command);
  i2c_rep_start((deviceAddress<<1) + I2C_READ);
  num_bytes = i2c_read(false); // num of bytes; 1 byte will be index 0
  num_bytes = constrain(num_bytes,0,blockBufferLen-2); // room for null at the end
  for (x=0; x<num_bytes-1; x++) { // -1 because x=num_bytes-1 if x<y; last byte needs to be "nack"'d, x<y-1
    blockBuffer[x] = i2c_read(false);
  }
  blockBuffer[x++] = i2c_read(true); // this will nack the last byte and store it in x's num_bytes-1 address.
  blockBuffer[x] = 0; // and null it at last_byte+1
  i2c_stop();
  return num_bytes;
}

I tried it like this:

uint8_t i2c_smbus_read_block ( uint8_t command, uint8_t* blockBuffer, uint8_t blockBufferLen ){
  uint8_t x, num_bytes;
  Wire.beginTransmission(deviceAddress);
  Wire.write(command);
 Wire.endTransmission(false);
num_bytes =Wire.requestFrom(deviceAddress,1,false);
//  num_bytes = Wire.read(); // num of bytes; 1 byte will be index 0
  
  num_bytes = constrain(num_bytes, 0, blockBufferLen - 2); // room for null at the end
  for (x = 0; x < num_bytes - 1; x++) { // -1 because x=num_bytes-1 if x<y; last byte needs to be "nack"'d, x<y-1
  blockBuffer[x]= Wire.requestFrom(deviceAddress,1,false);
//   blockBuffer[x] = Wire.read();
  }
 blockBuffer[x++]= Wire.requestFrom(deviceAddress,1);
//  blockBuffer[x++] = Wire.read(); // this will nack the last byte and store it in x's num_bytes-1 address.
  blockBuffer[x] = 0; // and null it at last_byte+1
  return num_bytes;
}

Any ideas pls?

My alternative explanation of the Wire library is here: https://github.com/Koepel/How-to-use-the-Arduino-Wire-library/wiki/Explanation-of-the-functions-of-the-Wire-library

Notice what I write about the third parameter of the 'Wire.requestFrom()' function. No one uses it, because with a normal I2C bus there is no use for it.

After writing the command, request the number of bytes that you want, then followed by all the reads. There is a function 'Wire.readBytes()' that can read a whole block.

num_bytes = Wire.requestFrom(deviceAddress, blockBufferLen);
if( num_bytes == blockBufferLen)  // received the same amount as requested ?
{
  Wire.readBytes( blockBuffer, blockBufferLen);
}

The "Wire.readBytes()" is from the Stream class and is safe to use this way, but it was not written with the Wire library in mind.
If you want a normal for-loop, then you can use a normal for-loop of course:

num_bytes = Wire.requestFrom(deviceAddress, blockBufferLen);
if( num_bytes == blockBufferLen)  // received the same amount as requested ?
{
  for( int i=0; i<blockBufferLen; i++)
  {
    blockBuffer[i] = (uint8_t) Wire.read();
  }
}

I think that the ESP32 has buffers in the Wire library of 256 bytes. That is the maximum that can be read with a single Wire.requestFrom(). The Arduino Uno has only 32 bytes.

Something like that?

uint8_t i2c_smbus_read_block ( uint8_t command, uint8_t* blockBuffer, uint8_t blockBufferLen ) {
  uint8_t x, num_bytes;
  Wire.beginTransmission(deviceAddress);
  Wire.write(command);
  Wire.endTransmission(false);
  num_bytes = Wire.requestFrom(deviceAddress, blockBufferLen);
  if ( num_bytes == blockBufferLen) // received the same amount as requested ?
  {
    Wire.readBytes( blockBuffer, blockBufferLen);
  }
   num_bytes = constrain(num_bytes, 0, blockBufferLen - 2); // room for null at the end
  if ( num_bytes == blockBufferLen) // received the same amount as requested ?
  {
    for ( int i = 0; i < blockBufferLen; i++)
    {
      blockBuffer[i] = (uint8_t) Wire.read();
    }
  }
  return num_bytes;
}

I am geting now the Names (one String or just chars) but with ????? after. So it looks like MELTON??????. I raised the Buffer to 256, but that returned no Chars. Coulde i use **Wire.available ** instead of the for-loop?
The

is that false okay?

Suppose that 12 bytes are requested, then the data is in a buffer in the Wire library.
Use either Wire.readBytes( buffer, 12) or a for-loop that reads 12 times.
You do both.

I don't understand the constrain. If you request 12 bytes, then you should get 12 bytes and your sketch has to process those 12 bytes. You should not add bytes or remove bytes.

The 'false' is okay. It tells the Wire.endTransmission() to not send a STOP condition. The Wire.requestFrom() will do a START and since there was no STOP, the START becomes a REPEATED START. Does that make sense ?

You can always use the Wire.available(). You can use it once after the Wire.requestFrom() or continuously in a while- or for-loop. But if you check the return value of Wire.requestFrom() then you have enough information. It is the exact same value as Wire.available() at that moment.

#define bufferLen 128
uint8_t i2cBuffer[bufferLen];

uint8_t i2c_smbus_read_block ( uint8_t command, uint8_t* blockBuffer, uint8_t blockBufferLen ) {
  uint8_t x, num_bytes;
  Wire.beginTransmission(deviceAddress);
  Wire.write(command);
  Wire.endTransmission(false);
  num_bytes = Wire.requestFrom(deviceAddress, blockBufferLen);
  if ( num_bytes == blockBufferLen) // received the same amount as requested ?
  {
    Wire.readBytes( blockBuffer, blockBufferLen);
  }
   return num_bytes;
}

I think that the constrain cuts off not needed bytes. Because if i raise the bufferLen, I get more MELTONr⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

Should I send the endTransmission(false) at the end, before the return?

I don't know how much valid data there is from the chip.
If the chip stops sending data, then you will receive 0xFF.

A Wire.requestFrom() should not be followed by a Wire.endTransmission().

So it looks like MELTON??????.
Because if i raise the bufferLen, I get more MELTONr⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

Your original posting was about how to read bytes over i2c into a buffer. Now your questions appear to be about the Serial output of that buffer, but you are providing no code about how you do that.

Is the buffer null terminated? Have you tried printing the individual chars of what you requested byte by byte?

Yes, that is my second question. For the Output i am using

length_read = i2c_smbus_read_block(MFG_NAME, i2cBuffer, bufferLen);
  Serial.write(i2cBuffer, length_read);

I don´t know, if the buffer is null terminated. My try looks like:

 for (int i=0;i<32;i++){
    Serial.print(i2cBuffer[i]);
  }

returns: 67769768479781142552552552551404646300000464630000232300
But i don´t know what to do :frowning:

for (int i=0;i<32;i++){
    Serial.print(i2cBuffer[i]);
  }
returns: 67769768479781142552552552551404646300000464630000232300

This should be decimal ascii, but it doesn't look like MELTON.

You can certainly convert to chars with

for (int i=0;i<32;i++){
    Serial.print((char)i2cBuffer[i]);
  }

I don't like the idea of requesting a large buffer of data from the device. Typically you request what you know is present in the registers you want to read.

Do you have any documentation on the battery charger?

Yes, this returned Melton??????????????????. I also tried

while (Wire.available()) {    //Read while somthing is in the buffer
    int wert;
    wert=Wire.read();
    Serial.print(wert);Serial.print("                     ");
      if(wert>65&&wert<90){     //Show only capital letters
        Serial.print((char)Wire.read());
      }
   }

This returned the same Result.
I have no documentation about the charger.

Why do you request 32 bytes?

If you are going to request more bytes than there is actual data, then I think this is what you will get.

If the MELTON is terminated with a '\n' or '\0' or 255 perhaps you can read the unknown buffer until you see the terminator. If you print the numerical value of the bytes of instead of the chars, what do see following the MELTON for the first ?

Querying registers when you don't know what data is there, how many bytes, and the format of the return is going to give results like you see.

Going back to the last post. Is this really what gives MELTON????...
returns: 67769768479781142552552552551404646300000464630000232300

The 77 69 76 84 79 78 is MELTON but the leading 6 is strange.
My ascii table says its an 'ack'. The 114 is the little 'r' you previously saw.

I don´t know. I want to read th hole word and not a part, mayby. I changed th code now to this:

uint8_t i2c_smbus_read_block ( uint8_t command, uint8_t* blockBuffer, uint8_t blockBufferLen ) {
  uint8_t x, num_bytes;
  Wire.beginTransmission(deviceAddress);
  Wire.write(command);
  Wire.endTransmission(false);
  num_bytes = Wire.requestFrom(deviceAddress, blockBufferLen);
     if ( num_bytes == blockBufferLen) // received the same amount as requested ?
  {
   blockBuffer[x] = 0; // and null it at last_byte+1  //I think this is trash
  

  while (Wire.available()) {
    blockBuffer[x] = (uint8_t) Wire.read(); 
    if (blockBuffer[x] >= 65 && blockBuffer[x] <= 90) {     //if x=upercase Letter, print it
      Serial.print((char)blockBuffer[x]); Serial.print("  ");
     
    }
    else if (blockBuffer[x] >= 97 && blockBuffer[x] <= 122) { //if x=lowercase Letter
      if (blockBuffer[x-1] >= 65 && blockBuffer[x-1] <= 90){  //if the last was upper,leave
        return num_bytes;
      }
      Serial.print((char)blockBuffer[x]); Serial.print("  "); //else print it
    }
    else if (blockBuffer[x] == 255) {       //stop

        return num_bytes;
      } 
    x++;
  }}
}

This returns
Manufacture Name: M E L T O N MELTONr
Typ: b a t t e r y abattery⸮⸮
Typ: L I O N LION1⸮y⸮⸮

6 is an ACK, but i dont understand the r, too. Now i can print the name. To store it i should use a char? And i dont really understand what does the num_bytes do.

I wonder if the little r indicates the name is a registered trademark?

blockBuffer[x] = 0; // and null it at last_byte+1 //I think this is trash
I agee. It makes no sense in the context of this code. It can be used to null terminate a character array when the x value is a count of bytes received.

To store it

You should be able to copy the received block buffer into a character array.

And i dont really understand what does the num_bytes do.

It's not really useful as a return value. It will actually give the number of bytes requested, not received. See this discussion and some github links.

http://www.gammon.com.au/forum/?id=10896&reply=10#reply10

https://github.com/arduino/ArduinoCore-avr/issues/171

https://github.com/arduino/ArduinoCore-avr/issues/384

Okay thank you very much. My result is:

uint8_t i2c_smbus_read_block ( uint8_t command, uint8_t* blockBuffer, uint8_t blockBufferLen ) {
  uint8_t x, num_bytes;
  Wire.beginTransmission(deviceAddress);
  Wire.write(command);
  Wire.endTransmission(false);
  num_bytes = Wire.requestFrom(deviceAddress, blockBufferLen);
  if ( num_bytes == blockBufferLen) // received the same amount as requested ?
  {
    while (Wire.available()) {
      blockBuffer[x] = (uint8_t) Wire.read();
      if (blockBuffer[x] >= 65 && blockBuffer[x] <= 90) {     //if x=upercase Letter, print it
        Serial.print((char)blockBuffer[x]); 
        words[x] = (char)blockBuffer[x];
        words[x+1]='\0';//Mamby not nessacary
      }
      else if (blockBuffer[x] >= 97 && blockBuffer[x] <= 122) { //if x=lowercase Letter
        if (blockBuffer[x - 1] >= 65 && blockBuffer[x - 1] <= 90) { //if the last was upper,leave
          return num_bytes;
        }
        Serial.print((char)blockBuffer[x]);  //else print it
        words[x] = (char)blockBuffer[x];
        words[x+1]='\0';//Mamby not nessacary
      }
      else if (blockBuffer[x] == 255) {       //stop
        words[x+1]='\0';    //Mamby not nessacary
        return num_bytes;
      }
      x++;
    }
  }
}

I can println(words) and see the word. So it´s working fine.
My last question is to put this into a String. I tried:

String test=String(words);       // or

String test;
test=words;