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:
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;
}
MEGA:
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);
}
Lesezeichen