Arduino I2C mehrere Bytes vom Slave abholen

Hallo,

ich versuche 100bytes mit einem Arduino Master von einem Arduino Slave zu holen, soviel ich jetzt gelesen habe können nur 32bytes mit einer abfrage gelesen werden.
Mein Master würde so aussehen:

Wire.beginTransmission(42);   // Start Übertragung zum M328P Wire
  Wire.write(0);                 // "move your register pointer back to 00h"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen 
  Readbyte[1] = Wire.read();
  Readbyte[2] = Wire.read();
  Readbyte[3] = Wire.read();
  Readbyte[4] = Wire.read();
  Readbyte[5] = Wire.read();
  Readbyte[6] = Wire.read();
  Readbyte[7] = Wire.read();
  Readbyte[8] = Wire.read();
  Readbyte[9] = Wire.read();
  Readbyte[10] = Wire.read(); 
  Readbyte[11] = Wire.read();
  Readbyte[12] = Wire.read();
  Readbyte[13] = Wire.read();
  Readbyte[14] = Wire.read();
  Readbyte[15] = Wire.read();
  Readbyte[16] = Wire.read();
  Readbyte[17] = Wire.read();
  Readbyte[18] = Wire.read();
  Readbyte[19] = Wire.read(); 
  Readbyte[20] = Wire.read();  
  Readbyte[21] = Wire.read();
  Readbyte[22] = Wire.read();
  Readbyte[23] = Wire.read();
  Readbyte[24] = Wire.read();
  Readbyte[25] = Wire.read();
  
   Wire.beginTransmission(42);   // Start Übertragung zum M328P Wire
  Wire.write(25);                 // "move your register pointer to 25"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen  
  
  Readbyte[26] = Wire.read();
  Readbyte[27] = Wire.read();
  Readbyte[28] = Wire.read();
  Readbyte[29] = Wire.read(); 
  Readbyte[30] = Wire.read();
  
  Readbyte[31] = Wire.read();
  Readbyte[32] = Wire.read();
  Readbyte[33] = Wire.read();
  Readbyte[34] = Wire.read();
  Readbyte[35] = Wire.read();
  Readbyte[36] = Wire.read();
  Readbyte[37] = Wire.read();
  Readbyte[38] = Wire.read(); 
  Readbyte[39] = Wire.read();
  Readbyte[40] = Wire.read();
 
  Readbyte[41] = Wire.read();
  Readbyte[42] = Wire.read();
  Readbyte[43] = Wire.read();
  Readbyte[44] = Wire.read();
  Readbyte[45] = Wire.read();
  Readbyte[46] = Wire.read();
  Readbyte[47] = Wire.read();
  Readbyte[48] = Wire.read();
  Readbyte[49] = Wire.read(); 
  Readbyte[50] = Wire.read(); 

--> bis Readyte[100]

Aber wie muss ich jetzt beim Slave die Daten bereitstellen das der Master diese richtig übertragen bekommt?

void setup()
{
  Wire.begin(42); 
  Wire.onRequest(requestEvent); 

}

void requestEvent(void) {
  Wire.write(Byte_send,25); // so vermutlich nicht :-)
}

Leider sind auch alle Beispiele die ich bisher gefunden habe mit nur 1-3 Bytes

void requestEvent(void) {
 Wire.write(Byte_send,25); // so vermutlich nicht :-)
}

Warum nicht?
Wenn geklärt wird, was Byte_send bedeuten mag, dann sehe ich keine Gegenanzeigen.

Aber die 100 zeilige Zuweisungswurst, die baust du noch auf Schleife um, oder?

mhh das sind dann die ersten 25bytes, wie werden dann die zweiten 25bytes angesprochen?

hätte das byte_send als array mit 100bytes gefüllt, aber wie wird das vom Master/Slave adressiert das z.B. Byte 26-50 übertragen wird?

Master dann so mit for-Schleife:

  Wire.beginTransmission(42);   // Start Übertragung zum M328P 1-Wire
  Wire.write(0);                 // "move your register pointer back to 00h"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen 
  for (int i=1; i <= 25; i++){
  Readbyte[i] = Wire.read();
  }
  
   Wire.beginTransmission(42);   // Start Übertragung zum M328P 1-Wire
  Wire.write(25);                 // "move your register pointer back to 00h"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen  
   for (int i=26; i <= 50; i++){
  Readbyte[i] = Wire.read();
  } 
  
  Wire.beginTransmission(42);   // Start Übertragung zum M328P 1-Wire
  Wire.write(50);                 // "move your register pointer back to 00h"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen 
   for (int i=51; i <= 75; i++){
  Readbyte[i] = Wire.read();
  } 
  
  Wire.beginTransmission(42);   // Start Übertragung zum M328P 1-Wire
  Wire.write(75);                 // "move your register pointer back to 00h"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen 
    for (int i=76; i <= 100; i++){
  Readbyte[i] = Wire.read();
  }

Du hast 2 grundlegende Möglichkeiten.

  1. Du merkst Dir den Index des zuletzt gesendeten Bytes auf dem Slafe und machst bei der nächsten Anforderung wieder dort weiter.

  2. Du übergibst vorm Lesen die neue Anfangsadresse vom Master an den Slave, speicherst sie dort und benutzt diese zum Senden. Ist in meinen Augen flexibler.

Gruß Tommy

mhh das sind dann die ersten 25bytes, wie werden dann die zweiten 25bytes angesprochen?

Wie gesagt....
Das Geheimnis liegt in Byte_send......

So kann ich nur sagen, den Pointer ins Datenfeld um 25 Byte weiter setzen.

würde es dann so klappen?
MASTER

void takeReading()
{
  Wire.beginTransmission(42);   // Start Übertragung zum M328P 
  Wire.write(0);                 // "move your register pointer back to 0"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen 
  for (int i=1; i <= 25; i++){
  Readbyte[i] = Wire.read();
  }
  
   Wire.beginTransmission(42);   // Start Übertragung zum M328P
  Wire.write(25);                 // "move your register pointer back to 25"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen  
   for (int i=26; i <= 50; i++){
  Readbyte[i] = Wire.read();
  } 
  
  Wire.beginTransmission(42);   // Start Übertragung zum M328P
  Wire.write(50);                 // "move your register pointer back to 50"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen 
   for (int i=51; i <= 75; i++){
  Readbyte[i] = Wire.read();
  } 
  
  Wire.beginTransmission(42);   // Start Übertragung zum M328P
  Wire.write(75);                 // "move your register pointer back to 75"
  Wire.endTransmission();       // Ende
  // Daten vom M328P abholen
  Wire.requestFrom(42, 25); // 25 Bytes lesen 
    for (int i=76; i <= 100; i++){
  Readbyte[i] = Wire.read();
  }

SLAVE:

byte Byte_send1[25];
byte Byte_send2[25];
byte Byte_send3[25];
byte Byte_send4[25];

void requestEvent(void) {

switch (A) {
    case 0:
      Wire.write(Byte_send1,25);
      break;
    case 25:
      Wire.write(Byte_send2,25);
      break;
    case 50:
      Wire.write(Byte_send3,25);
      break;
    case 75:
      Wire.write(Byte_send3,25);
      break;
    default: 
    break;
  }

}

void receiveEvent(int anzahl)
{
  while (Wire.available()){
    A = Wire.read();

  }  
}

Umständlich!
Sehr umständlich.

Sieht aber fast richtig aus.

So kleine Details, sind noch falsch!

 for (int i=1; i <= 25; i++){

Readbyte[i] = Wire.read();
  }

Möchte gerne so aussehen:

 for (int i=0; i < 25; i++){
  Readbyte[i] = Wire.read();
  }

Wobei immer noch geheim ist, was Readbyte ist.
Tipp:
Ich sehe nicht was du siehst!

Danke,
Funktioniert wunderbar.
@combie
Du sagst sehr Umständlich....
Wie wäre es den einfacher?

Readbyte ist als byte deklariert und wird über Modbus TCP weitergeleitet.

Du könntest z.B. nur ein einziges Array nehmen und dann mit Zeiger-Arithmetik arbeiten um auf den korrekten Index zu kommen

byte data[100];

...

Wire.write(data + A, 25);

Danke funktioniert einwandfrei.

wie könnte man so was in ne Schleife packen?

  Byte_send[0] = highByte(regs[0]);
  Byte_send[1] = lowByte(regs[0]);
  Byte_send[2] = highByte(regs[1]);
  Byte_send[3] = lowByte(regs[1]);
  Byte_send[4] = highByte(regs[2]);
  Byte_send[5] = lowByte(regs[2]);
  Byte_send[6] = highByte(regs[3]);
  Byte_send[7] = lowByte(regs[3]);
  Byte_send[8] = highByte(regs[4]);
  Byte_send[9] = lowByte(regs[4]);

wie könnte man so was in ne Schleife packen?

Vielleicht ist das gar nicht nötig, wenn man denn die richtigen Strukturen nutzt.

ja dann

Nunja...

Du wirfst einen kleinen Brocken in die Runde, und möchtest daraufhin die Welt erklärt haben...
Das muss nicht immer gelingen!

Eine andere passende Antwort wäre:

Danke funktioniert einwandfrei.

Nein! Ich bekomme

'regs' was not declared in this scope

Das führt dich, genauso wie

Vielleicht ist das gar nicht nötig, wenn man denn die richtigen Strukturen nutzt.

in die richtige Richtung, wenn du folgen willst.

Die regs kann ich ned ändern, die kommen aus der modbus Bibliothek .....

simon24j:
Die regs kann ich ned ändern, die kommen aus der modbus Bibliothek .....

Sicher? oder tust du die da rein, weil dei Modbus Bibliothek die so braucht?
Zum Glück kenn ich sie nicht, so lass ich es dir oder sonst jemand, dir passende Datenstrukturen zu basteln.
Oder du machst in einer for Schleife je reg zwei Zuweisungen:

Byte_send[i/2] = highByte(regs[i]);
Byte_send[i/2+1] = lowByte(reg[i]);

oder du sparst die die Umkopiererei und sendest es gleich

Wire.write((byte*)regs,20); // sendet regs[0] .. regs[9]