- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 10 von 64

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

Hybrid-Darstellung

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

    ich habe mal kurz Zeit gefunden. Das Setup steht soweit. Der Raspi findet den ARDUINO. Von Vorteil wären Deine aktuellen Testprogramme für beide Plattformen. Das, welches Du weiter oben als Basis verlinkt hast, macht von Haus aus schon 120ms Pause jeden Loop. Warum der State auf dem ARDUINO zwischengespeichert wird, habe ich noch nicht verstanden. Das Testprogramm für den Raspi möchte ja die zu sendenden Daten mit übergeben haben. Wird also nicht das sein, womit Du testest.

    Meine Pegelwandler sind alle. Habe mir eben welche geordert. Wenn die da sind, teste ich weiter. Der ARDUINO läuft zwar mit 3V3 aber den muss ich sonst vor und nach dem Flashen umstecken. Wenn ich das vergesse, kann es das für den Raspi gewesen sein.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  2. #2
    HaWe
    Gast
    120ms Pause ?
    wo?
    hast du diesen Code hier von diesem Link?

    http://www.mindstormsforum.de/viewto...tart=15#p67908

    der Raspi-Teil stammt von Gordon Henderson -
    Frage:
    was macht sleep(1)? 1 ms ? oder etwa 1sec ?


    ps
    (edit: )
    Ja, du hast Recht!

    Der Raspi hat eingebaute Pullups, die auf 3.3V hochziehen, aber beim Mega verbleiben 10k Board-Pullups, die machen es grenzwertig, auch wenn man die internen disabled. Tatsächlich sind beim mega Levelshifter sicherer!



    - - - Aktualisiert - - -

    hahaha, das war's!

    Gordon hatte 1 sek Wartezeit drin, nicht 1 ms!

    ich hab jetzt auf delay(10) geändert - das rauscht nur so durch, dass man gar nicht hinterher kommt !!

    das muss ich mir jetzt erstmal genauer angucken!

    - - - Aktualisiert - - -

    update:

    schaut absolut grandios aus. Kein Transmission-Fehler erkennbar. Mal gucken, wie lang die I2C Verbindung hält oder ob sie abbricht:

    Raspi Master Code:
    Code:
    //  Raspberry Pi Master code to send/receive byte arrays
    //  to an Arduino as an I2C slave
    // 
    //  ver. 0.001b
    //  protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
    //  http://creativecommons.org/licenses/by-nc-sa/3.0/   //
    
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <wiringPi.h>
    #include <wiringPiI2C.h>
    
    #include <errno.h>
    #include <string.h>
    
    #define MSGSIZE 30
    
    
    unsigned char  calcchecksum( unsigned char array[]) {   
      int32_t  sum=0;
      for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
      return (sum & 0x00ff);
    }
    
    
    
    int main (void)
    {
       
      int fd, i ;
      unsigned char test=0;
      unsigned char data [MSGSIZE] ;
    
      if ((fd = wiringPiI2CSetup (0x04) ) < 0)
      {
        fprintf (stderr, "Can't open RTC: %s\n", strerror (errno)) ;
        exit (EXIT_FAILURE) ;
      }
    
    
      for (;;)
      {
        read (fd, data, MSGSIZE) ;
        if( data[1] != calcchecksum( data ) ) {
             // handle transmission error !
        }    
        printf ("read:  ");
        for (i = 0 ; i < MSGSIZE ; ++i)
          printf ("  %3d", data [i]) ;
        printf ("\n") ;
        delay(10);
       
        memset(data, 0, sizeof(data) );
        data[5]=  test++;
        data[0]=  0xff;
        data[MSGSIZE-1]= 0x04;
        data[1] = calcchecksum( data );
       
        write(fd, data, MSGSIZE) ;
        printf ("write: ");
        for (i = 0 ; i < MSGSIZE ; ++i)
          printf ("  %3d", data [i]) ;
        printf ("\n\n") ;
        delay(10);
      }
    
      return 0 ;
    }
    Arduino slave code
    Code:
    //  Arduino code to send/receive byte arrays
    //  Arduino as an I2C slave
    //  compiles for MEGA and DUE, IDE 1.6.5
    //  ver. 0.001b
    //  (c) HaWe 2016
    //
    //  protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
    //  http://creativecommons.org/licenses/by-nc-sa/3.0/   //
    
    
    #include  <Wire.h>
    
    #define  SLAVE_ADDRESS 0x04
    #define  MSGSIZE  30
    byte     recvarray[MSGSIZE];  // 0=0xff; 1=chksum; ...data...; MSGSIZE-1=SLAVE_ADDRESS
    byte     sendarray[MSGSIZE];
    
    volatile int8_t  flag=0;
    
    
    //=====================================================================================
    //=====================================================================================
    void setup() {
       int32_t  i=0;
    
       // Serial terminal window
       i=115200;
       Serial.begin(i);
       Serial.print("Serial started, baud=");
       Serial.println(i);
    
       // Wire (i2c)
       Wire.begin(SLAVE_ADDRESS);     // start Arduino as a I2C slave, addr=0x04 (7-bit coded)
       
       Wire.onReceive(receiveData );  // event when master array is sent
       Wire.onRequest(sendData );     // event when master requests array to read
       
       memset(sendarray, 0, sizeof(sendarray) );  // init send- and recv arrays
       memset(recvarray, 0, sizeof(recvarray) );   
       
       Serial.print("I2C init: my slave address= ");
       Serial.println(SLAVE_ADDRESS);
       Serial.println("I2C init: done.");
       Serial.println();
       
       Serial.println("setup(): done.");   
    
    }
    
    
    //=====================================================================================
    
    
    uint8_t  calcchecksum(uint8_t array[]) {   
      int32_t  sum=0;
      for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
      return (sum & 0x00ff);
    }
    
    //=====================================================================================
    
    void loop()
    {
       char sbuf[128];
    
       Serial.println(); Serial.println();
    
       // do something with the received data
       // and then do something to build the sendarray [3]...[MSG_SIZE-2]
       
       if (flag==1) {
           //debug
           sendarray[4] +=1;   
       }
    
       sendarray[0] = 0xff;                        // 0 = start: 0xff == msg start flag
       sendarray[2] = flag;                        // 2 = send back msg error flag   
       sendarray[MSGSIZE-1] = SLAVE_ADDRESS;       // end of array: ID check     
       
       sendarray[1] = calcchecksum(sendarray);     // 1 = calc new chksum
       flag=0;   
       
       // debug output
       sprintf(sbuf, "Sendarr[4]=%4d,   [5]=%4d,   Recvarr[4]=%4d,  [5]=%4d",
                      sendarray[4], sendarray[5],  recvarray[4],    recvarray[5]) ;
       Serial.println(sbuf);
    
       delay(1);                                     // short break for the cpu and the bus
    }
    
    
    //=====================================================================================
    
    void receiveData(int byteCount) {
        int32_t i;
        byte val;
    
        while(Wire.available()<MSGSIZE) ;           // wait for all bytes to complete
        i=0;                                        // init counter var
        while(Wire.available()&& (i<MSGSIZE) )      // read all recv array bytes
        {
          val=Wire.read();
          recvarray[i++]=val;
        }
       
        // check for transmission error
        if(  (recvarray[0]  == 0xff)
          && (recvarray[1]  == calcchecksum(recvarray))
          && (recvarray[MSGSIZE-1] == SLAVE_ADDRESS  ) ) 
             flag=1;        // data ok
        else
             flag=127;      // data faulty => handle rcv-error => flag =127
    }
    
    //=====================================================================================
    
    void sendData(){
      // Wire.write writes data from a slave device in response to a request from a master
      Wire.write(sendarray, MSGSIZE);    // send own byte array back to master..
    }
    - - - Aktualisiert - - -

    also, es läuft jetzt störungsfrei seit etwa ner halben Stunde - da gibt's momentan nichts mehr zu meckern!

    (y)
    Geändert von HaWe (09.02.2016 um 09:09 Uhr)

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Hallo,

    prima, dann brauch ich nicht weiter testen. Mache es am WE trotzdem mal

    Edit:
    SDA ist bei meinem ARDUINO auf High, wenn ich Deinen Code compiliere. Daher die Pegelandler oder den Mega2560 mit 3V3 betreiben.
    Geändert von peterfido (08.02.2016 um 15:31 Uhr)
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  4. #4
    HaWe
    Gast
    Beim Mega muss man zwingend die dort vorhandenen internen Pullups auf 5V disablen; dazu 2 Zeilen in twi.c auskommentieren:

    file: twi.c ( path: Arduino\hardware\arduino\avr\libraries\Wire\utilit y )
    // activate internal pullups for twi.
    // digitalWrite(SDA, 1);
    // digitalWrite(SCL, 1);

    ps
    (edit: )
    Ja, du hast Recht!

    Der Raspi hat eingebaute Pullups, die auf 3.3V hochziehen, aber beim Mega verbleiben 10k Board-Pullups, die machen es grenzwertig, auch wenn man die internen disabled. Tatsächlich sind beim mega Levelshifter sicherer!
    Geändert von HaWe (09.02.2016 um 09:10 Uhr)

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Hallo,

    ich habe es auskommentiert. Die Pullups sind aber immer noch aktiviert. Evtl. was auf dem Board.?. Meiner ist von Sainsmart, MEGA2560. Suche ich morgen weiter, jetzt kommt Wheelers Dealers

    Dein Programm läuft soweit, bis man kurz mal die Verbindung trennt. Dann syncen die nicht mehr auf Beginn des Telegramms. Auch das werde ich mir mal näher ansehen.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  6. #6
    HaWe
    Gast
    Hm - bisher habe ich nur den Due beutzt - aber ja, tatsächlich, er hat 2 im Prozessor und 2 auf dem Board. Die einen lassen sich disablen, die anderen nicht.
    Angeblich sollen aber die verbleibenden wegen Ihres höheren Widerstandes dann nicht mehr ins Gewicht fallen :
    http://www.varesano.net/blog/fabio/h...nd-scl-i2c-bus
    internal pullups
    Submitted by as3.1415rin (not verified) on Thu, 2012-07-19 21:39.

    as far as I understand, the 5V/3.3V is the only reason to switch them off. if that's not the point, internal + external pullups should be fine, then the activated internal ones are not doing any damage
    ps
    (edit: )
    Ja, du hast Recht!

    Der Raspi hat eingebaute Pullups, die auf 3.3V hochziehen, aber beim Mega verbleiben 10k Board-Pullups, die machen es grenzwertig, auch wenn man die internen disabled. Tatsächlich sind beim mega Levelshifter sicherer!



    ps,
    das mit dem re-syncen stimmt und ist noch nicht gelöst. Ich war jetzt nach dem sleep-Bug erstmal froh, dass es überhaupt schon sehr schnell lief. Ich weiß auch nicht, wie es sonst auf dem Raspi läuft, wenn mal eine i2c-line zu einem Device wie z.B. einem MCP oder PCF zwischenzeitlich ausfällt und dann wieder hergestellt wird. Ein stabiles Protokoll mit re-sync wäre schon wünschenswert. Eventuell könnte man einen Timer mitlaufen lassen, der z.B. nach 100ms time-out sowohl auf dem Master als auch dem Slave I2C resettet und dann neu startet?
    Geändert von HaWe (09.02.2016 um 09:10 Uhr)

  7. #7
    HaWe
    Gast
    habe jetzt genauere Infos aus dem Arduino-Forum:
    On the Arduino Mega 2560 board are pullup resistors of 10k for SDA and SCL. The internal pullup resistors of the ATmega2560 chip are about 50k.

    The internal pullup resistors can be disabled in the library, or in the sketch.
    It can be done in the sketch, because SDA and SCL are still digital inputs, even if I2C is enabled for those pins. So writing a zero disables the pullup.
    Code: [Select]


    Wire.begin();
    digitalWrite( SDA, LOW);
    digitalWrite( SCL, LOW);
    ...

    It is the other way around.
    The 50k are internal in the ATmega2560 chip and can be disabled.
    The 10k are on the Arduino Mega 2560 board and can not be disabled. Perhaps you can try to scratch a pcb trace and work around that 10k.

    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
    http://gammon.com.au/forum/?id=10896&reply=5#reply5

    My conclusion : Use a level shifter or an other Arduino board.
    Also, ich muss mich berichtigen: gerade die blöden 10k lassen sich nicht disablen, und damlt wird es tatsächlich kritisch.

Ä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
  •  

fchao-Sinus-Wechselrichter AliExpress