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[5];
byte Register=1;
byte block=0;
byte pos=0;
byte fertig=0;
long dg=0;
long timeout=0;
void setup() {
Wire.begin(4); // join I2C bus with address #8
Wire.onReceive(receiveEvent); // register event
Wire.onRequest(requestEvent); // register event
Serial.begin(57600); // start serial for output
Serial.println();
Serial.println("Starte I2C-Test");
}
byte chksum(byte arr[], byte anzahl)
{
byte i;
byte sum=0;
for(i = 0; i < anzahl; i++){
sum+=arr[i];
}
return sum;
}
void loop() {
byte i=0;
delay(100);
timeout++;
if (timeout==90){
timeout=0;
Wire.begin(4);
Serial.println("TimeOut!");
dg=0;
}
if (fertig !=0){
fertig=0;
timeout=0;
dg++;
Serial.println(dg);
for (i=0;i<REGSIZE;i++){
Serial.print(rspeicher[i]);
Serial.print (" ");
}
Serial.println();
}
}
void TWIRESET(){
Wire.begin(4);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
byte x[4];
byte i;
if(howMany == 4){
for (i=0;i<4;i++){
x[i]=Wire.read();
Serial.print (x[i]);
Serial.print (" ");
}
if (x[0]==137){
if (chksum(x,3)==x[3]){
if (x[1]<REGSIZE){
block=x[1];
rspeicher[block]=x[2];
wspeicher[block]=rspeicher[block];
}
if (x[1]==REGSIZE-1){
fertig=1;
}
Serial.println(" - Summe OK");
}else{
Serial.println(" - Summe fehlerhaft");
}
}
}else{
if (howMany==2){
for (i=0;i<2;i++){
x[i]=Wire.read();
if (x[0]==87 && x[1]==56){
TWIRESET();
}
}
}else{
Serial.print ("Anzahl Daten: ");
Serial.println(howMany);
while (0 < Wire.available()) { //überflüssiges lesen
x[4]=Wire.read();
}
}
}
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
byte i;
puffer[0]=block;
puffer[1]=wspeicher[block];
puffer[2]=chksum(puffer,2);
Wire.write(puffer,3);
for (i=0;i<3;i++){
Serial.print (puffer[i]);
Serial.print (" ");
}
Serial.println();
}
Raspi:
Code:
// GCC -Wall -pthread -o /var/scripte/bbi2cmaster1012 /var/scripte/bbi2cmaster1012.c -lpigpio -lrt
// /var/scripte/bbi2cmaster1012
//I2C mit pipgio
//peterfido
//V1.012
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pigpio.h>
#define SDA 2
#define SCL 3
#define TAKT 100000
#define PAUSEN 5000
#define ADDRESS 0x04
#define MSGSIZE 240
char empfdata[MSGSIZE]; //
char senddata[MSGSIZE];
char commando[20];
char puffer[12];
unsigned int ARDUPOS=0;
unsigned int laenge=0;
volatile sig_atomic_t done = 0;
void term(int signum)
{
done = 1;
}
int I2CResetBus(void)
{
char i;
int res=0;
if(gpioRead(SDA) && gpioRead(SCL)) {
return 0;
}
gpioSetMode(SCL, PI_INPUT);
gpioSetMode(SDA, PI_INPUT);
gpioSetPullUpDown(SDA, PI_PUD_UP); // Sets SDA pull-up.
gpioSetPullUpDown(SCL, PI_PUD_UP); // Sets SDA pull-up.
usleep(50);
if(!gpioRead(SCL)) {
return -1; /* SCL wird extern auf Low gehalten, nix zu machen */
}
for(i = 0; i<9; i++) {
gpioSetMode(SCL, PI_OUTPUT);
gpioWrite(SCL, 0);
usleep(50);
gpioSetMode(SCL, PI_INPUT);
gpioSetPullUpDown(SCL, PI_PUD_UP); // Sets SDA pull-up.
usleep(50);
if(gpioRead(SDA)) {
break; /* SDA ist high STOP */
}
} /* for */
if(!gpioRead(SDA)) {
return -1;
}
commando[0]= 3; //stop
commando[1]= 0; // Fertig
res=bbI2CZip(SDA,commando,2,NULL,0);
if (res!=0){
printf("Fehler beim Reset!\n");
}
if(gpioRead(SDA) && gpioRead(SCL)){
return 0;
}else{
return -1;
}
}
char chksum(char arr[], int anzahl)
{
int i;
char sum=0;
for(i = 0; i < anzahl; i++){
sum+=arr[i];
}
return sum;
}
int syncen() {
int erg=0;
int res=0;
int i=0;
commando[0]= 4; //'Adresse setzen ankündigen
commando[1]= 4; //'Adresse übergeben
commando[2]= 2; //start
commando[3]= 7; //'Bytes senden
commando[4]= 4; //'Anzahl
commando[5]= 137; //Position
commando[6]= ARDUPOS; //Position
commando[7]= senddata[ARDUPOS]; //Position
commando[8]= chksum(&commando[5],3); //Position
commando[9]= 3; //stop
commando[10]= 0; //keine weiteren Parameter
printf("Gesendet: ");
for(i=6;i<8;i++){
printf("%d ",commando[i]);
}
printf("\n");
res=I2CResetBus();
res=bbI2CZip(SDA,commando,20,puffer,12);
usleep(50000);
commando[0]= 4; //'Adresse setzen ankündigen
commando[1]= 4; //'Adresse übergeben
commando[2]= 2; //start
commando[3]= 6; //Bytes lesen
commando[4]= 3; //Anzahl
commando[5]= 3; //stop
commando[6]= 0; //keine weiteren Parameter
res=I2CResetBus();
res=bbI2CZip(SDA,commando,20,puffer,12);
printf("Empfangen:");
for(i=0;i<2;i++){
printf("%d ",puffer[i]);
}
if (puffer[2] == chksum(puffer,2)){
printf(" - Summe OK");
}else{
printf(" - Summe fehlerhaft %d",chksum(puffer,2));
}
if (res==3){
if (puffer[0]==ARDUPOS && puffer[2] == chksum(puffer,2)){
empfdata[ARDUPOS]=puffer[1];
erg=0;
}else{
printf(" - E Falsche Blocknummer. Erwartet: %d, bekommen: %d, Wert: %d\n",ARDUPOS,puffer[0],puffer[1]);
erg=1;
}
}else{
printf(" - E Fehler beim Blockeinlesen. Block: %d, Fehler: %d\n",ARDUPOS,res);
erg=1;
}
return erg;
}
void ARDURESET(){
commando[0]= 4; //'Adresse setzen ankündigen
commando[1]= 4; //'Adresse übergeben
commando[2]= 2; //start
commando[3]= 7; //'Bytes senden
commando[4]= 2; //'Anzahl
commando[5]= 87; //RESET-Sequenz
commando[6]= 56; //RESET-Sequenz
commando[7]= 3; //stop
commando[8]= 0; //keine weiteren Parameter
I2CResetBus();
bbI2CZip(SDA,commando,20,NULL,0);
usleep(50000);
}
int main(int argc, char **argv)
{
int res=0;
long dg=1;
long maxdg=0;
unsigned int Fehler=0;
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = term;
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
if (gpioInitialise() < 0)
{
printf("Fehler beim Initialisieren von gpio!");
gpioTerminate();
}else{
res=bbI2COpen(SDA,SCL,TAKT);
res=res+gpioSetMode(SDA, PI_INPUT); // Set SDA as input.
res=res+gpioSetMode(SCL, PI_INPUT); // Set SDA as input.
res=res+gpioSetPullUpDown(SDA, PI_PUD_UP); // Sets SDA pull-up.
res=res+gpioSetPullUpDown(SCL, PI_PUD_UP); // Sets SDA pull-up.
srand(time(NULL));
if(res==0){
printf("\n\n\nStarte I2C-Test\n\n");
while (!done)
{
senddata[ARDUPOS]=rand() % 255;
res=syncen();
if (senddata[ARDUPOS]==empfdata[ARDUPOS]){
printf(" - Daten OK %ld (%ld)\n",dg,maxdg);
Fehler=0;
dg++;
}else{
printf(" - Daten fehlerhaft ****************************************** %ld \n",dg);
// ARDURESET();
Fehler++;
dg=0;
if (dg>maxdg){
maxdg=dg;
}
if (Fehler==100){
break;
}
}
if (res==0){
ARDUPOS++;
if (ARDUPOS >= MSGSIZE){
ARDUPOS=0;
//usleep(500000);//Dem ARDUINO Zeit für die Anzeige geben
//sleep(2);//Dem ARDUINO Zeit für die Anzeige geben
}
}
usleep(5000);
}
}else{
printf("E Fehler beim Oeffnen\n");
}
}
res=bbI2CClose(SDA);
if (res!=0){
printf("E Fehler beim Schliessen: %d\n", res);
}else{
printf("E Schliessen OK\n");
}
gpioTerminate();
return 0;
}
Es läuft hier mit Pegelwandler.
Lesezeichen