hierin könnte die Lösung des Clock-Stretching-Problems bei den AVRs verborgen liegen:
http://abyz.co.uk/rpi/pigpio/cif.html#bbI2CZip
(nur verstehen tu ich's leider nicht, geschweige denn das Coding dann... säääähr schwäääre Kost.... :-/
Druckbare Version
hierin könnte die Lösung des Clock-Stretching-Problems bei den AVRs verborgen liegen:
http://abyz.co.uk/rpi/pigpio/cif.html#bbI2CZip
(nur verstehen tu ich's leider nicht, geschweige denn das Coding dann... säääähr schwäääre Kost.... :-/
Hallo,
ich habe mir zwischenzeitlich den SourceCode von i2cset und i2cget besorgt. Da wird SMBUS genutzt, um auf I2C zuzugreifen. Komme heute aber nicht zum proggen. Es gibt eine Begrenzung von 32 Byte pro Block. Da bist Du mit den 30 schon knapp dran.
Ich stelle mir ein Protokoll vor, wo entweder die Registeradresse mit übergeben wird oder diese auf 0 bleibt. Bei 0 soll der Arduino dann automatisch inkrementieren.
So braucht man auch nicht jedesmal die 30 (32) Bytes rüberschicken, wenn nur ein Byte geändert werden soll. Das spart Zeit, wenn der Arduino z.B. ein Display ansteuert. Darüber braucht man sich aber erst Gedanken zu machen, wenn die Kommunikation steht.
Wenn Du Dein verlinktes BitBang-Beispiel nutzen möchtest, dann kann jeder PIN genutzt werden. Die Pullups berücksichtigen.
Oben im Code
#include <pigpio.h>
und dann die Funktionen aufrufen. Klingt recht einfach. Damit fange ich morgen mal an.
die Arrays hin- und her schicken hat sowohl remote-control als auch Portexpander- (Telemetrie-) Zwecke. Zum einen sollen vom Raspi aus Encodermotoren gesteuert werden, zum anderen sollen möglichst schnell (auch zum Update der Fernsteuerung) alle möglichen Sensoren auf dem Slave ausgelesen werden.
32 Bytes sind dazu mehr als knapp, besser wären mindestens 64, gerade weil Encoderwerte 32 bit lang sind.
Auch Werte von i2c- oder UART-Sensoren auf dem Arduino sollen an den Raspi übermittelt werden können, die oft floats sind (also ebenfalls 32 bit).
Der Fall, dass nur 1 Byte im Array geändert wird, wird also fast nie vorkommen.
Wenn es keine Möglichkeit gibt, den i2c buffer vom Raspi auf 64 Bytes zu erhöhen, müssen sich 2 Arduino-Boards die Arbeit teilen. Allerdings scheidet dann der Mega komplett aus, da er ja bereits jetzt am Bus über 3mA per Pegelwandler gegen die 5V Pullups ziehen muss, und 3mA ist die Höchstgrenze für SDA/SCL laut I2C-specs. Und weitere i2c-Geräte kommen ja sowieso noch hinzu (zum Glück aber nicht mehr als hundert) ;)
Ich komme daher immer mehr zu der Überzeugung, dass die AVRs zur Zeit eine Sackgasse sind, wegen clock-stretching, und speziell auch der Mega wegen seiner zusätzlichen Pullups.
Das bedeutet allerdings dann: nur DUEs werden zur Zeit Sinn machen, da nichts anderes funktioniert.
Oder, wie Gordon Henderson (Autor der wiringPi libs) schrieb, nur eins macht Sinn für die AVRs: "... a newer version of the kernel driver.. So one day..."
Trotzdem bin ich natürlich auf deine pigpio-Versuche gespannt, insbesondere mit mehreren Geräten am selben Bus.
Da bleibt dann nur BitBang übrig. Da gibt es keine Einschränkungen, was die Puffergröße betrifft, da alles zu Fuss gemacht wird. DiePullups des Mega sollten sich mit etwas Geschick entfernen lassen. Wo hast Du die 3mA her? Die Pullups des Raspis scheinen 1k8 zu sein. Also knapp unter 2mA. Der MEGA hat bei 5V und 10k Pullups 0,5 mA. Den Strom des Pegelwandlers müsste dieser doch selbst verkraften. Nachgemessen habe ich es nicht.
Wenn der MEGA der einzige problematische Slave am Raspi ist, kann man auch ein eigenes Protokoll per BitBanging auf beiden Seiten verwenden. Bei Verwendung anderer PINs bleibt I2C für die anderen Slaves erhalten. Hätte den Vorteil, dass der MEGA nicht als Slave und Master arbeiten müsste. Oder halt im Multimaster-Betrieb. Oder SPI, da gibt es dann wieder Hardware-Puffer, welche von Vorteil sind, wenn der MEGA eh noch Einiges zu tun hat. Bei der Nutzung von Interrupts geht bei einer Zwei-Draht-Verbindung ohne Hardware-Puffer das ein oder andere Bit verloren.
Ich selbst brauche es nicht und sehe es nur als Herausforderung und kann es evtl. irgendwann doch mal brauchen. ;) Aktuell habe ich zwei Favoriten: Den SMBUS-Treiber und BitBang. Wobei BitBang auf dem ersten Blick wesentlich einfacher scheint.
Die Info samt Berechnung stammt aus dem Arduino-Forum:
Bitbang ist ja, was im Prinzip auch pigpio macht bzw. machen kann.Zitat:
The Arduino Mega 2560 is the only board with those 10k resistors on the board for I2C. Any other board would be no problem.
Connect 5V with 10k to 3.3V with 1k8. That makes 3.55V
I don't like that, often 3.6V is the limit for 3.3V chips, and this is very close.
Using a dirty trick with a resistor to GND to lower it might also cause trouble. The Arduino Mega board needs 3.5V to see a I2C level as high.
With a level shifter, the Arduino has to pull both sides of the level shifter down. A level shifter has often 10k on both sides.
Total current:
5V with 10k and 10k : 1mA
3.3V with 1k8 and 10k : 2.16mA
Together it is above 3mA, which is specified as the maximum current by the official I2C standard. But that 3mA is not very strict, it will work
SPI ist keine Option, weil SPI bereits auf dem Arduino voll ausgeschöpft ist (84MBit/s DMA für TFT).
Außerdem ist i2c Pflicht, weil ja zusätzlich MCPs und PCFs und auch der CMPS11 gemeinsam dran sollen.
SMBus ist aber nichts anderes als eine Raspi-I2C-Implementierung, oder irre ich mich?
ps,
leider ist joan nicht sehr hilfsbereit für die Implementierung ihrer pigpio API-libs. Es werden zwar Links zur Verfügung gestellt (s.o.), aber wie es jetzt genau funktioniert anstelle von read() und write().... Schweigen im Walde.
Selbst Gordon Henderson war es bisher nicht klar, dass pigpio überhaupt clock-stretching per bitbang zur Verfügung stellen könnte.
Hallo,
I2C wurde von Phlips Anfang der 80er entwickelt um Chips in Fernsehern einfach zu verbinden.
SMBus basiert auf dem I2C und wurde 1995 von Intel veröffentlicht ud war für PCs gedacht um Jumper zu ersetzen, Seriennummern und Parameter zu setzen und abzufragen. z.B. haben die Speichermodule ein Rom, in welchem Grösse, Timing-Parameter usw. abgelegt sind.
SMBus funktioniert zwischen 10kHz und 100kHz, i2C DC bis 400kHz und 2MHz.
SMBus kennt ein Timeout (35ms).
Die Pegel sind etwas unterschiedlich
MfG Peter(TOO)
Hallo,
die BitBang-Methode läuft bei mir überhaupt nicht. Es ist auch kein Beispiel vorhanden. Selbst, wenn ich als SDA und SCL alle GPIOs durchteste, zeigt mein LA keine Regung.
Die RawSend Methode läuft bis 32 Bytes am Stück. Gibt man mehr an, wird automatisch auf 32 Bytes reduziert.
Das lässt sich auch für mehr Bytes nutzen, indem man z.B. immer 31 Bytes verschickt, wo im ersten die Blocknummer angegeben ist und dann 30 Nutzbytes hinterher. Weiter kann man das erste Byte auch dazu nutzen, Kommandos zu versenden. Z.B. 'Sende mir Block x zurück', 'Starte Neu', 'Wiederhole dein Anliegen', usw.
Der Vorteil der pigpio ist, dass man mehrere Handles öffnen kann und so 'bequem' die einzelnen Slaves ansprechen kann.
Hin und wieder kam bei meinen Tests der nichtssagende Fehler -82. Dann hilft nur, den MEGA neu zu Starten.
Die BeispielCodes werden vom gcc angemeckert (inkompatible Pointer Typen). Das ist dann zu korrigieren.
Bei Deinem Projekt befürchte ich bald ein Timingproblem. Wenn der Raspi ständig Daten sendet und haben möchte, bleibt kaum Zeit für die anderen Dinge. Bei meinen Tests langweilt sich der MEGA.
Edit:
Bei Fehler -82 muss meist der MEGA zurückgesetzt werden.
Hallo,
ich sehe da ein Problem im ARDUINO-Code.
Der hängt sich weg, auch wenn man zwischen Senden und Empfangen eine Sekunde Pause einlegt.
Demnach läuft kein Puffer über, aber irgendetwas ist.
Meine aktuellen Codes:
MEGA:
Raspberry Pi:Code:// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
#define REGSIZE 240
byte rspeicher[REGSIZE];
byte wspeicher[REGSIZE];
byte puffer[32];
byte Register=1;
byte rdblock=0;
byte wrblock=0;
byte pos=0;
byte fertig=0;
void setup() {
Wire.begin(4); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
// Wire.onReceive(receiveEventRoh); // register event
Wire.onRequest(requestEvent); // register event
Serial.begin(57600); // start serial for output
/* for(byte i=0;i<REGSIZE;i++){
wspeicher[i]=i;
}*/
Serial.println();
Serial.println("Starte I2C-Test");
}
void loop() {
byte i=0;
delay(100);
if (fertig !=0){
fertig=0;
for (i=0;i<REGSIZE;i++){
wspeicher[i]=rspeicher[i];
Serial.print(rspeicher[i]);
Serial.print (" ");
}
Serial.println();
}
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
rdblock = Wire.read();
if (rdblock<=7){
pos=0;
while (0 < Wire.available()) {
if (pos<30){
rspeicher[rdblock*30+pos] = Wire.read();
pos++;
}
}
if (rdblock==7){
fertig=1;
}
}else{
if (rdblock >=10 && rdblock <=17){
wrblock=rdblock-10;
Serial.print("Leseblock: ");
Serial.println(wrblock);
}
}
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEventRoh(int howMany) {
while (0 < Wire.available()) {
byte x=Wire.read();
Serial.print (x);
Serial.print (" ");
}
Serial.println();
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
//Wire.write(speicher[Register],1);
memcpy( &puffer[1],&wspeicher[wrblock * 30],30);
puffer[0]=wrblock;
Wire.write(puffer,31);
}
Code:// gcc -Wall -pthread -o /var/scripte/i2cmaster01 /var/scripte/i2cmaster01.c -lpigpio -lrt
// /var/scripte/i2cmaster01
//I2C mit pipgio
//peterfido
//V0.0.1
#include <stdio.h>
#include <stdlib.h>
//#include <stdarg.h>
#include <string.h>
//#include <ctype.h>
#include <unistd.h>
#include <signal.h>
#include <pigpio.h>
//#define SDA 3
//#define SCL 5
#define BAUD 100
#define ADDRESS 0x04
#define MSGSIZE 240
#define LOOPS 30
char empfdata[MSGSIZE]; //
char senddata[MSGSIZE];
char commando[32];
int handle=0;
int handles=-1;
unsigned int laenge=0;
void handleSigInt( int parameter );
void handleSigInt( int parameter )
{
int res=0;
int dl=0;
if (handles >= 0){
for (dl=0;dl<handles;dl++){
res=i2cClose(dl);
printf("%d geschlossen: %d\n",dl, res);
}
}
gpioTerminate();
printf( "\nSIGINT wurde augeloest - Programm wird beendet\n" );
exit( 1 );
}
void senden() {
int res=0;
int i=0;
char wrblock=0;
for (wrblock=0;wrblock<=7;wrblock++){
handle=i2cOpen(1,ADDRESS,0);
handles ++;
if (handle>=0){
laenge=31;
printf("Oeffnen OK %d\n",handle);
res=0;
memcpy( &commando[1],&senddata[wrblock * 30],laenge);
commando[0]=wrblock;
res=res+i2cWriteDevice(handle,commando,laenge);
usleep(5000);
for(i=0;i<laenge;i++){
printf("%d ",commando[i]);
}
printf("\n");
if (res==0){
printf("Senden OK\n");
}else{
printf("I2C-Fehler: %d\n", res);
}
res=i2cClose(handle);
if (res!=0){
printf("Fehler beim schliessen: %d\n", res);
}else{
handles--;
}
}else{
printf("Fehler beim oeffnen: %d\n", res);
}
}
}
void empfangen() {
int res=0;
int i=0;
char rdblock=0;
for (rdblock=0;rdblock<=7;rdblock++){
handle=i2cOpen(1,ADDRESS,0);
handles ++;
if (handle>=0){
laenge=31;
printf("Oeffnen OK %d\n",handle);
commando[0]=rdblock+10;
res=i2cWriteDevice(handle,commando,1);
if (res==0){
usleep(30000);
res=i2cReadDevice(handle,commando,laenge);
if (res>0){
/* printf("Empfangen:\n");
for(i=0;i<laenge;i++){
printf("%d ",commando[i]);
}
printf("\n");*/
// memcpy( &commando[1],&empfdata[commando[0] * 30],laenge-1);
for (i=0;i<laenge-1;i++){
empfdata[commando[0]*30+i]=commando[i+1];
}
}else{
printf("Fehler beim Blockeinlesen: %d\n", res);
}
}else{
printf("Fehler beim Leseblock schreiben %d\n", rdblock);
}
res=i2cClose(handle);//+i2cClose(handle1);
if (res!=0){
printf("Fehler beim schliessen: %d\n", res);
}else{
handles--;
}
}else{
printf("Fehler beim oeffnen: %d\n", res);
}
}
printf("Empfangen:\n");
for(i=0;i<MSGSIZE;i++){
printf("%d ",empfdata[i]);
}
}
int vergleichen()
{
unsigned int i=0;
int ret=0;
for (i=0;i<MSGSIZE;i++){
if (empfdata[i]!=senddata[i]){
ret=-1;
break;
}
}
return ret;
}
int main(int argc, char **argv)
{
int i=0;
int dg=0;
/* for(i=0;i<MSGSIZE;i++){
senddata[i]=i;
}*/
signal( SIGINT, &handleSigInt );
signal( SIGTERM, &handleSigInt );
if (gpioInitialise() < 0)
{
printf("Fehler beim Initialisieren von gpio!");
gpioTerminate();
}else{
for(dg=0;dg<LOOPS;dg++)
{
srand(time(NULL));
for(i=0;i<MSGSIZE;i++){
senddata[i]=rand() % 255;
}
senden();
// usleep(100000);
sleep(1);
empfangen();
// usleep(100000);
sleep(1);
if (vergleichen()==0){
printf("Daten OK\n");
}else{
printf("Daten fehlerhaft\n");
}
}
}
gpioTerminate();
return 0;
}
wenn ich in meinen eigenen Code (siehe https://www.roboternetz.de/community...l=1#post623669) in der Loop statt delay(1) ein delay(2000) eingebe, habe ich kein Problem mit der Verbindung per Arduino DUE -
der Raspi sendet zwar lustig vor sich hin, aber der Arduino sendet und empfängt immer im 2-Sekundentakt die dann jeweils aktuellsten Daten:
Sendarr[4]= 36, [5]= 0, Recvarr[4]= 0, [5]= 93
Sendarr[4]= 37, [5]= 0, Recvarr[4]= 0, [5]= 168
Sendarr[4]= 38, [5]= 0, Recvarr[4]= 0, [5]= 243
Sendarr[4]= 39, [5]= 0, Recvarr[4]= 0, [5]= 61
Sendarr[4]= 40, [5]= 0, Recvarr[4]= 0, [5]= 133
Sendarr[4]= 41, [5]= 0, Recvarr[4]= 0, [5]= 209
Sendarr[4]= 42, [5]= 0, Recvarr[4]= 0, [5]= 29
Sendarr[4]= 43, [5]= 0, Recvarr[4]= 0, [5]= 104
Sendarr[4]= 44, [5]= 0, Recvarr[4]= 0, [5]= 179
Sendarr[4]= 45, [5]= 0, Recvarr[4]= 0, [5]= 255
Sendarr[4]= 46, [5]= 0, Recvarr[4]= 0, [5]= 75
Sendarr[4]= 47, [5]= 0, Recvarr[4]= 0, [5]= 151
- - - Aktualisiert - - -
ps,
auch bei mir funktioniert dann
#define MSGSIZE 32
einwandfrei.
Hallo,
auch möglich, dass der Raspi durch sein Multitasking I2C etwas aus dem Takt bringt und der Code für den MEGA das nicht mag.
Aktuell habe ich es soweit, dass beide Seiten Fehler erkennen und danach dann 'einfach' weitermachen. Läuft schon eine Weile durch.
Beschäftige ich den MEGA mit en paar UART-Ausgaben, dann steigt die Fehlerquote an. Somit ist da nicht wirklich viel Luft für Dein Vorhaben. Da der Raspi mit vielen Sensoren und Slaves umgehen kann, würde ich dem die meiste Arbeit aufbürden und den MEGA nur für 'kritische' Aufgaben nutzen, da meiner Erfahrung nach die AVRs zuverlässiger arbeiten. Im Zweifel den Watchdog aktivieren.
Raspi:
MEGA:Code:
// gcc -Wall -pthread -o /var/scripte/i2cmaster01 /var/scripte/i2cmaster01.c -lpigpio -lrt
// /var/scripte/i2cmaster01
//I2C mit pipgio
//peterfido
//V0.0.2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <pigpio.h>
#define ADDRESS 0x04
#define MSGSIZE 240
char empfdata[MSGSIZE]; //
char senddata[MSGSIZE];
char commando[32];
int handle=0;
int handles=-1;
unsigned int laenge=0;
void handleSigInt( int parameter );
void handleSigInt( int parameter )
{
int res=0;
int dl=0;
if (handles >= 0){
for (dl=0;dl<handles;dl++){
res=i2cClose(dl);
printf("%d geschlossen: %d\n",dl, res);
}
}
gpioTerminate();
printf( "\nSIGINT wurde augeloest - Programm wird beendet\n" );
exit( 1 );
}
void schreiben() {
int res=0;
int i=0;
char wrblock=0;
int Fehler=0;
for (wrblock=0;wrblock<=7;wrblock++){
laenge=31;
memcpy( &commando[1],&senddata[wrblock * 30],laenge);
commando[0]=wrblock;
res=i2cWriteDevice(handle,commando,laenge);
if (res!=0){
printf("S I2C-Fehler: %d, Block: %d\n", res,wrblock);
Fehler++;
wrblock--;
usleep(15000);
if (Fehler==10){
break;
}
}
usleep(15000);
}
printf("Gesendet:\n");
for(i=0;i<MSGSIZE;i++){
printf("%d ",senddata[i]);
}
printf("\n");
}
void lesen() {
int res=0;
int i=0;
char rdblock=0;
int Fehler=0;
for (rdblock=0;rdblock<=7;rdblock++){
laenge=31;
commando[0]=rdblock+10;
res=i2cWriteDevice(handle,commando,1);
if (res==0){
usleep(30000);
res=i2cReadDevice(handle,commando,laenge);
if (res==laenge){
printf("Empfangene Daten: %d, Block: %d\n",res,rdblock);
for (i=0;i<laenge-1;i++){
empfdata[commando[0]*30+i]=commando[i+1];
}
}else{
printf("E Fehler beim Blockeinlesen: %d, Block: %d\n", res,rdblock);
Fehler++;
rdblock--;
usleep(15000);
if (Fehler==10){
break;
}
}
}else{
printf("E Fehler beim Leseblock schreiben %d, Block: %d\n", res,rdblock);
break;
}
}
printf("Empfangen:\n");
for(i=0;i<MSGSIZE;i++){
printf("%d ",empfdata[i]);
}
printf("\n");
}
int vergleichen()
{
unsigned int i=0;
int ret=0;
for (i=0;i<MSGSIZE;i++){
if (empfdata[i]!=senddata[i]){
ret=-1;
break;
}
}
return ret;
}
int main(int argc, char **argv)
{
int res=0;
int i=0;
int dg=1;
unsigned int Fehler=0;
signal( SIGINT, &handleSigInt );
signal( SIGTERM, &handleSigInt );
if (gpioInitialise() < 0)
{
printf("Fehler beim Initialisieren von gpio!");
gpioTerminate();
}else{
handle=i2cOpen(1,ADDRESS,0);
if(handle>=0){
handles ++;
printf("\n\n\nStarte I2C-Test (%d)\n\n",handle);
while (1)
{
srand(time(NULL));
for(i=0;i<MSGSIZE;i++){
senddata[i]=rand() % 255;
}
schreiben();
usleep(100000);
lesen();
usleep(100000);
if (vergleichen()==0){
printf("Daten OK %d\n",dg);
Fehler=0;
}else{
printf("***************************** Daten fehlerhaft %d *****************************\n",dg);
Fehler++;
usleep(500000);
if (Fehler==10){
break;
}
}
}
}else{
printf("E Fehler beim Oeffnen: %d\n", handle);
}
}
res=i2cClose(handle);
if (res!=0){
printf("E Fehler beim Schliessen: %d\n", res);
}else{
handles--;
printf("E Schliessen OK %d\n",handle);
}
gpioTerminate();
return 0;
}
Code:// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
#define REGSIZE 240
byte rspeicher[REGSIZE];
byte wspeicher[REGSIZE];
byte puffer[32];
byte Register=1;
byte rdblock=0;
byte wrblock=0;
byte pos=0;
byte fertig=0;
long dg=0;
long timeout=0;
void setup() {
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
// Wire.onReceive(receiveEventRoh); // register event
Wire.onRequest(requestEvent); // register event
Serial.begin(57600); // start serial for output
/* for(byte i=0;i<REGSIZE;i++){
wspeicher[i]=i;
}*/
Serial.println();
Serial.println("Starte I2C-Test");
}
void loop() {
byte i=0;
delay(100);
timeout++;
if (timeout==30){
timeout=0;
Wire.begin(4);
Serial.println("Fehler!");
dg=0;
}
if (fertig !=0){
fertig=0;
timeout=0;
dg++;
Serial.println(dg);
for (i=0;i<REGSIZE;i++){
wspeicher[i]=rspeicher[i];
// Serial.print(rspeicher[i]);
// Serial.print (" ");
}
// Serial.println();
}
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
byte x=0;
if(howMany == 31){
rdblock = Wire.read();
if (rdblock<=7){
pos=0;
while (0 < Wire.available()) {
if (pos<30){
rspeicher[rdblock*30+pos] = Wire.read();
pos++;
}
}
if (rdblock==7){
fertig=1;
}
}
}
if (howMany==1){
x=Wire.read();
if (x >=10 && x <=17){
wrblock=x-10;
// Serial.print("Leseblock: ");
// Serial.println(wrblock);
}
}
while (0 < Wire.available()) {
x=Wire.read();
}
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEventRoh(int howMany) {
while (0 < Wire.available()) {
byte x=Wire.read();
// Serial.print (x);
// Serial.print (" ");
}
// Serial.println();
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
//Wire.write(speicher[Register],1);
memcpy( &puffer[1],&wspeicher[wrblock * 30],30);
puffer[0]=wrblock;
Wire.write(puffer,31);
}