- Labornetzteil AliExpress         
Ergebnis 1 bis 10 von 64

Thema: Raspi C/C++, Raspi als I2C-Master: byte arrays zu Arduino slave hin + her schicken?

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #34
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Hallo,

    es geht nur zuverlässig mit der BitBang-Methode.

    Folgende Codes laufen bei mir seit einiger Zeit fehlerfrei durch:

    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[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.

    Es wird in der Sub 'Sync' (Evtl. sollte diese noch einen anderen Namen bekommen. Der Name Sync ist bei HardwareI2C schon belegt...) bei jedem Aufruf nur ein DatenByte geschrieben und gelesen. Es gibt ein Startbyte und eine Prüfsumme um Kommunikationsfehler zu erkennen.

    Wie es sich mit Interrupts auf dem MEGA verträgt, habe ich nicht getestet. Ob die TWIRESET Sub auf dem Mega immer zuverlässig läuft, kann ich nicht sagen. Evtl. kann man die Pausen verkürzen, wenn der MEGA nix weiter zu tun hat oder sie müssen verlängert werden, wenn Fehler z.B. wegen vieler Interrupts auftreten.


    Hardware I2C verträgt sich mit dem (meinem) ARDUINO MEGA irgendwie nicht.
    Geändert von peterfido (15.02.2016 um 17:42 Uhr) Grund: Raspi Code mit falschem Kopf korrigiert, Sync umbenannt
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

Ähnliche Themen

  1. Raspi mit Arduino per USB verbinden
    Von HaWe im Forum Raspberry Pi
    Antworten: 4
    Letzter Beitrag: 11.11.2015, 16:26
  2. [ERLEDIGT] Raspi Club?
    Von pofoklempner im Forum Raspberry Pi
    Antworten: 16
    Letzter Beitrag: 09.07.2015, 06:20
  3. Antworten: 1
    Letzter Beitrag: 12.06.2015, 14:50
  4. Antworten: 5
    Letzter Beitrag: 24.08.2014, 16:36
  5. Schnelle(!) Objekterkennung mit Raspi+USB-Cam
    Von phantom111 im Forum Sensoren / Sensorik
    Antworten: 19
    Letzter Beitrag: 20.02.2014, 12:18

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen