- Labornetzteil AliExpress         
Seite 4 von 7 ErsteErste ... 23456 ... LetzteLetzte
Ergebnis 31 bis 40 von 64

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

  1. #31
    HaWe
    Gast
    Anzeige

    Praxistest und DIY Projekte
    update:
    nicht nur mit dem Mega scheint es Probleme zu geben sondern auch mit anderen AVRs.
    Uno habe ich keinen, aber ich habe jetzt einen Nano getestet:

    Auch mit dem Nano (keine Pullups eingebaut, daher braucht er keine Levelshifter) dasselbe Phänomen wie beim Mega MIT Levelshiftern:

    er überträgt eine Handvoll Zyklen lang (mal 2, mal 10, mal bis zu 30) und dann blockiert die Übertragung. Der Raspi erkennt dann auch hier den Arduino nicht mehr als Slave, Adresse 0x04 ist leer.

    Nach resetten des Nanos geht es erst wieder kurz, dann wieder Schicht.

    Jetzt bräuchte man wen, der ein Oszi hat (wenn man das überhaupt nachmessen kann). Es scheint vllt doch am Clock-Stretching zu liegen, was evtl besonders die AVRs betrifft, scheinbar weniger die ARMs.


    hab jetzt die Datenausgabe auf dem Pi ein wenig geändert, um es besser verfolgen zu können:
    Beim Lesen bleibt der Pi beim AVR (Nano und Mega) recht schnell hängen, beim Schreiben zählt er weiter - aber beim AVR kommt nichts mehr an.

    Code:
    //  Raspberry Pi Master code to send/receive byte arrays
    //  to an Arduino as an I2C slave
    // 
    //  ver. 0.002a
    
    
    #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 (;;)
      {
        memset(data, 0, sizeof(data) );
        data[0]=  0xff;    // init for transmission error check
        read (fd, data, MSGSIZE) ;
        if( data[1] != calcchecksum( data )  ) {
             // handle transmission error !
        }   
        else {
           printf ("  read:  ");
           for (i = 0 ; i < 7 ; ++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 < 7; ++i)
             printf ("  %3d", data [i]) ;
           printf ("\n\n") ;
           delay(10) ;     
        }
      }
    
      return 0 ;
    }
    Code:
    //  Arduino code to send/receive byte arrays
    //  Arduino as an I2C slave
    //
    //  ver. 0.002
    
    
    #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..
    }
    Nach kurzem Lauf wieder kein AVR-slave mehr dann an I2C detektiert
    Code:
    pi@raspberrypi ~ $ i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --
    erst nach Resetten ist 0x04 wieder da - beim nächsten Programmstart aber schnell wieder rausgekickt.

    Wie gesagt, wie bisher aber kein Problem mit dem Due.

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

    die Pegelwandler sind da. Damit funktioniert der letzte Code. Da auch mein Raspi nach einiger Zeit den Slave nicht mehr finden konnte, habe ich doch noch ein USB-Kabel geopfert und die 5V-Ader durchtrennt, sodass der ARDUINO mit 3V3 läuft. Flashen und Seriell funktioniert alles. Bei der I2C-Verbindung nach einiger Zeit das gleiche Problem.

    Solange die beiden miteinander 'reden' bleibt die Verbindung stabil. Beende ich das Master-Programm auf dem Raspi, erlischt nach einiger Zeit die LED auf dem ARDUINO und dann ist der Slave nicht mehr zu finden. Resete ich den ARDUINO, ohne das Masterprogramm am Raspi zu starten, erlischt oft, aber nicht immer, die LED auch wieder nach einiger Zeit und der Slave ist wech. Scheint, als ob der Slave-Code es nicht mag, wenn der Master nicht da ist.

    Ich musste die BAUD-Rate auf dem ARDUINO auf 57600 runtersetzen. Bei 115200 BAUD kommt sowohl bei 3V3 als auch bei 5V nur Müll im Terminal an.

    Beschäftigt man den ARDUINO zusätzlich noch etwas, gehen Daten verloren. Viel Luft ist also nicht. Wenn dieser als Gateway / 'Relaisstation' dienen soll, muss da ein gutes Protokoll her.


    Das wars für Heute. Morgen Abend geht es weiter.

    Gruß
    Peterfido
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  3. #33
    HaWe
    Gast
    Danke für die Rückmeldung!
    Bei mir erlischt ja schon die i2c-Verbindung ohne dass einer von beiden per Kabel abgetrennt wurde: die Daten-Verbindung hält höchstens 1 Sekunde!

    Der Due dagegen bleibt ständig sicher verbunden und verkraftet sogar auch das zwischenzeitliche ab- und wieder anstöpseln und resynced sich automatisch.

    Hast du auch einen normalen AVR (Uno oder Nano) ?

  4. #34
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Hallo Peterfido,
    Zitat Zitat von peterfido Beitrag anzeigen
    Ich musste die BAUD-Rate auf dem ARDUINO auf 57600 runtersetzen. Bei 115200 BAUD kommt sowohl bei 3V3 als auch bei 5V nur Müll im Terminal an.
    Das sieht jetzt aber langsam nach Störungen aus!

    z.B. eine schlechte Masseverbindung.
    Oder der Oszillator ist instabil.

    Lege mal eine zusätzlich Masseverbindung zwischen PC und den beiden kleinen, darf schon 1.5mm2 sein.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  5. #35
    HaWe
    Gast
    Die Masseleitungen sind in beiden Fällen exakt gleich lang - es sind sogar dieselben Kabel, sie wurden nur umgesteckt. Die Masseleitungen der beiden Boards sind direkt miteinander verbunden, genau wie die i2c-Leitungen.
    Und der Fehler tritt bei 2 verschiedenen AVRs auf, nicht aber bei einem ARM - mehrfach hin- und hergesteckt. Und er tritt auch auf, wenn die AVRs stand-allone laufen.
    Auch andere User haben i.Ü, diesen AVR-spezifischen Fehler reproduziert - nicht nur in diesem Forum.

    Im übrigen bitte ich dich, zuerst den Aufbau zu nachzubauen, das jetzige Verhalten zu überprüfen und dann deine Theorie zu testen. Teste es also erst selber und DANN poste!

    Denn wie schon mehrfach gesagt: Tipps aus dem Blauen wieder ins Blaue bingen nichts.........:
    Für alle Tipps bin ich natürlich offen, aber der, der sie vorschlägt, müsste schon in der Lage sein, die Verbindung ebenfalls herzustellen und bei sich selber vor Ort zu testen (d.h. er müsste auch einen Raspi und einen Arduino besitzen und sie entsprechend verbinden und seinen eigenen - bzw. unseren gemeinsamen, auf einander abgestimmten - Code testen können).
    Geändert von HaWe (11.02.2016 um 16:33 Uhr)

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

    so wie es aussieht, liegt es am MEGA, wenn die Kommunikation zusammenbricht. Mal hält dieser dann SCL auf Low und mal reagiert er einfach nicht mehr. Allerdings immer nach unterschiedlicher Zeit. Mal läuft es minutenlang durch und mal klemmt es nach wenigen Sekunden. Egal ob mit Pegelwandler oder direkt verbunden und 3V3 Versorgung des MEGA. Der MEGA hängt sich allerdings nicht weg. Die Hauptschleife läuft weiter.


    Die Pegelwandler sind 1A. Selbst bei 24MHZ erkennt mein LA keine Verzögerung.

    An einem Protokoll brauchen wir noch nicht zu arbeiten, solange die Verbindung unzuverlässig ist.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  7. #37
    HaWe
    Gast
    hallo,
    wie gesagt: mit dem NANO passiert genau dasselbe, in diesem Falle 5V ohne Pegelwandler.
    Könnte ein Clock-Stretching Ding sein, das alle AVRs betrifft (nicht aber ARMs).

    Hast du auch einen "normalen" Arduino (Uno, Nano, Micro) ?



    ps,

    guck mal hier:
    https://www.raspberrypi.org/forums/v...870098#p769282
    https://www.raspberrypi.org/forums/v...870098#p870098

  8. #38
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.686
    Hi!
    Zitat Zitat von peterfido Beitrag anzeigen
    .. so wie es aussieht, liegt es am MEGA, wenn die Kommunikation zusammenbricht. Mal hält dieser dann SCL auf Low und mal reagiert er einfach nicht mehr ..
    Ich musste mal hier reinschaun. Über 30 Postings zu I²C - erinnerte mich an ein paar Probleme die ich vor Monaten mit diesem Bus/Protokoll hatte. Bei MIR war der Beginn der Lösung ein Oskarbildchen. Als ich die Flanken sah, überhaupt die Peaks . . . au weia. Busterminierung geändert - Bildchen - Taktrate geändert - Bildchen - aaahhhhh. Seit der Zeit habe ich soweit ich es in der aktuellen Testphase (Thema ist NICHT mehr I²C) sehe, bei Laufzeiten teils über eine Stunde (ok, das klingt nicht nach Wochen) keine Probleme. Übrigens hatte ich mal vor vielen Monaten in einem anderen Projekt erfolgreiche Versuche damit gemacht, dass ich das Clockstreching dynamisch begrenzt hatte.
    Ciao sagt der JoeamBerg

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

    nein, ich habe nur den einen Arduino. Ein Oszi habe ich nicht. 'Nur' ein LA. Die Beispielcodes der Arduino IDE 'bleiben am Leben.' So dass ich darauf aufbauen nochmal was Neues erstelle. Allerdings nicht mehr heute.

    Folgendes läuft schon einige Zeit 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>
    
    void setup() {
      Wire.begin(4);                // join I2C bus with address #8
      Wire.onReceive(receiveEvent); // register event
      Serial.begin(57600);           // start serial for output
    }
    
    void loop() {
      delay(100);
    }
    
    // function that executes whenever data is received from master
    // this function is registered as an event, see setup()
    void receiveEvent(int howMany) {
      while (1 < Wire.available()) { // loop through all but the last
        char c = Wire.read(); // receive byte as a character
        Serial.print(c);         // print the character
      }
      int x = Wire.read();    // receive byte as an integer
      Serial.println(x);         // print the integer
    }
    Raspi: (Bash-Script)
    Code:
    #!/bin/bash
    #
    #
    
    d=0;
    while [ true ];do
     i2cset -y 1 0x04 3 $d
     d=$(($d+1))
    if [ $d -gt 255 ]; then
       d=0
    fi
    sleep 0.005
    done
    Wobei gelegentlich 'write Failed' ausgegeben wird. Bei 10 ms Pausen war das nicht so.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  10. #40
    HaWe
    Gast
    @oberallgeier:
    dann probier es doch mal bitte aus: Raspi plus AVR-Arduino!
    Du hast das Problem mit dem Clockstretching, das der Raspi nicht verträgt, doch verstanden, oder?
    Verbinde beide Boards (3 Kabel), lade die Sourcecodes, guck was dein Vorschlag bringt!

    Wie schon so oft gesagt:
    Für alle Tipps bin ich natürlich offen, aber der, der sie vorschlägt, müsste schon in der Lage sein, die Verbindung ebenfalls herzustellen und bei sich selber vor Ort zu testen (d.h. er müsste auch einen Raspi und einen Arduino besitzen und sie entsprechend verbinden und seinen eigenen - bzw. unseren gemeinsamen, auf einander abgestimmten - Code testen können).
    @peterfido:
    bin sehr gespannt!

    angeblich soll ja pigpio Clock-Stretching unterstützen, im Gegensatz zu wiringPi.... :-/

    ... nur wie und was muss man da machen?



    ps,
    Zambetti's i2c-Code war auch die Grundlage für meinen Arduino-Slave-Teil.
    Grundfunktionen sind i.P. 100% identisch!
    (Nur mein Code stellt sicher, dass keine inkompletten Arrays gesendet, empfangen oder verarbeitet werden, sondern erst, wenn alle Bytes komplett im i2c-Buffer drin sind ...und dann getestet sind auf Transmission Errors !)

Seite 4 von 7 ErsteErste ... 23456 ... LetzteLetzte

Ähnliche Themen

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

Berechtigungen

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

LiFePO4 Speicher Test