- Akku Tests und Balkonkraftwerk Speicher         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Verbindung zwischen zwei uC

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2011
    Beiträge
    5

    Verbindung zwischen zwei uC

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Leute,

    ich möchte gerne Daten von einem Mikrocontroller zu einem anderen Mikrocontroller senden.
    Mikrocontroller2 wertet einen Ultraschallsensor SRF02 aus, und sendet die gemessene Entfernung zu Mikrocontroller1.

    Probiert habe ich das ganze über die Serielle Schnittstelle der beiden Mikrocontroller.
    Leider scheitert es immer wieder daran, dass die Zykluszeit des Mikrocontrollers der empfängt extrem in die Höhe schnellt.
    Dazu muss man noch sagen, dass auf dem Mikrocontroller der empfangen soll, die Mulwii-Software läuft welche einen Quadrocopter steuert.

    Sobald ich meinen Codeschnipsel in das Programm einfüge, geht die Zykluszeit in die höhe und der Quadrocopter reagiert nicht mehr.

    Mikrocontroller1: ArduinoProMini Atmega 328p (empfängt)
    Mikrocontroller2: Arduino Uno Atmega 328p (sendet)
    Ultraschallsensor: SRF02


    Diesen Code verwende ich auf dem zu empfangenden Mikrocontroller1:


    void srf02_serial()
    {

    char inString[21];
    int inCount;

    inCount = 0;

    do
    {
    while (Serial.available()==0);
    inString[inCount] = Serial.read();
    if(inString[inCount]==13) break;
    }

    while(++inCount < 20);

    inString[inCount] = 0;


    }

    die Übertragung funktioniert zwar, aber wie gesagt, die Zykluszeit geht extrem in die Höhe.

    kann ich an diesem Code etwas abändern damit er die Zykluszeit nicht so krass beeinflusst?

    lg tobias

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Herzlich willkommen im RN :-D

    Ich schätze, das dauert so lange, weil der andere µC so langsam sendet, bzw. UART nicht unbedingt sehr schnell ist, wenn man Übertragungsfehler vermeiden möchte.

    Ich würds z.B. so machen:
    Code:
    #define StringStatus_bereit        0
    #define StringStatus_empfange        1
    #define StringStatus_bitteabholen    2
    
    
    
    // Die drei Variablen global deklarieren
    char inString[21];
    int inCount;
    char StringStatus = StringStatus_bereit;    // Sagt dir, ob im Moment noch der String empfangen wird, oder ob er schon fertig ist
    
    
    
    
    void srf02_serial()
    {
        if ((StringStatus = StringStatus_bereit) && (Serial.available()==0))    // Falls bereit und Daten anliegen...
        {
            StringStatus = StringStatus_empfange;                // ...wird der Status auf "empfange" gesetzt
            inCount = 0;                            // Und der Zähler zurückgesetzt
        }
    
    
        while((StringStatus == StringStatus_empfange) && (Serial.available()==0))    // Falls mit Empfangen beschäftigt und Daten anliegen
        {
            inString[inCount] = Serial.read();                // Werden die Daten in den String geschrieben
            if((inString[inCount]==13) || (inCount >= 18))            // Falls dein Enter(?)-Zeichen kommt oder der String schon voll ist...
            {
                inString[19] = 0;                    // ...am Ende ein Stringende-Zeichen setzten...
                StringStatus = StringStatus_bitteabholen;        // ...und sagen dass die Übertragung fertig ist und die Daten abgeholt werden können
            }
            inCount++;
        }
    }
    (Aber ungetestet - sprich Tippfehler garantiert vorhanden^^)

    Allerdings muss dann die Sub bei jedem durchlauf der Hauptschleife aufgerufen werden. Sobald in StringStatus StringStatus_bitteabholen drinsteht, kannst du die Daten des Strings verarbeiten. Sobald du fertig bist musst du den StringStatus aber wieder auf StringStatus_bereit setzten, sonst wartet die Sub nur bis du endlich fertig bist.

    Viele Grüße
    -schumi-
    Geändert von -schumi- (05.11.2011 um 18:13 Uhr)

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Oder eine ISR-Lösung:

    Code:
    volatile uint8_t usart_puffer[25], usart_write=0, usart_read=0, eingabe=0;
    
    #define BAUD_LOW		38400  //Low speed - 38.4 kBaud
    #define UBRR_BAUD_LOW	((F_CPU/(16*BAUD_LOW))-1)
    
    UBRRH = UBRR_BAUD_LOW >> 8;	// Baudrate is Low Speed
    UBRRL = (uint8_t) UBRR_BAUD_LOW;
    UCSRA = 0x00;
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSRB = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE); // Senden, Empfangen und Empfang-ISR einschalten
    
    while(1)
    {
       if(eingabe)
       {
    		// empfangene Zeichen stehen jetzt in usart_puffer[]
    		// ...verarbeiten...
    
    		usart_read=0;
    		usart_write=0;
    		eingabe=0;
       }
       // Ab hier Hauptprogramm:
    }
    
    
    SIGNAL (SIG_UART_RECV)
    {
        usart_puffer[usart_write]=UDR;
        if(usart_puffer[usart_write++] == 13) eingabe=1; // CR empfangen
    	 if(usart_write > 24) {usart_write=24; eingabe=2;} // Pufferüberlauf!
    }
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2011
    Beiträge
    5
    @schumi
    seltsam, nachdem ich grade den Code hochgeladen habe, sind direkt die Motoren angelaufen!! das kapier ich jetzt mal überhaupt nicht!

    Im Prinzip gehts mir darum die Entfernung die der Ultraschallsensor ermittelt irgendwie in den Mikrocontroller rein zu bekommen.
    Ob es nun über einen zweiten uC geht oder direkt über den ersten per I2C ist mir egal.

    Ich möchte einfach nur die Entfernung einlesen, und mit diesem Wert weiter arbeiten, um den Copter auf einer höhe zu regeln,

    Vielleicht kannst du dir mal den Code hier anschauen und mir sagen wie ich den Sensor am besten in das Projekt implementieren kann. Ich steh irgendwie aufm Schlauch.
    http://multiwii.googlecode.com/files/MultiWiiV1_8.zip

    Grüße Tobias

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2011
    Beiträge
    5
    Zitat Zitat von radbruch Beitrag anzeigen
    Oder eine ISR-Lösung:

    Code:
    volatile uint8_t usart_puffer[25], usart_write=0, usart_read=0, eingabe=0;
    
    #define BAUD_LOW		38400  //Low speed - 38.4 kBaud
    #define UBRR_BAUD_LOW	((F_CPU/(16*BAUD_LOW))-1)
    
    UBRRH = UBRR_BAUD_LOW >> 8;	// Baudrate is Low Speed
    UBRRL = (uint8_t) UBRR_BAUD_LOW;
    UCSRA = 0x00;
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSRB = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE); // Senden, Empfangen und Empfang-ISR einschalten
    
    while(1)
    {
       if(eingabe)
       {
    		// empfangene Zeichen stehen jetzt in usart_puffer[]
    		// ...verarbeiten...
    
    		usart_read=0;
    		usart_write=0;
    		eingabe=0;
       }
       // Ab hier Hauptprogramm:
    }
    
    
    SIGNAL (SIG_UART_RECV)
    {
        usart_puffer[usart_write]=UDR;
        if(usart_puffer[usart_write++] == 13) eingabe=1; // CR empfangen
    	 if(usart_write > 24) {usart_write=24; eingabe=2;} // Pufferüberlauf!
    }

    also hier versteh ich mal garnix

  6. #6
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Die Interruptlösung ist natürlich eleganter, wenn auch komplizierter^^

    Allerdings glaub ich, wird das in diesen Fall nicht gehen, weil der Interrupt schon von der Mulwii-Software selbst benutzt wird (um dann weitere Unterfunktionen ala
    Serial.read() usw. bereitzustellen, denke ich)

    nachdem ich grade den Code hochgeladen habe, sind direkt die Motoren angelaufen!! das kapier ich jetzt mal überhaupt nicht!

    Ich noch weniger, hab die Software noch nie in den Finger gehabt und kann dementsprechend wenig damit anfangen...
    Könntest du mal kurz erläutern, wo überhaupt dein UART-Zeug steht? Wie das ganze gegliedert ist?

    Ich konnts nämlich nicht finden...

    Gruß
    -schumi-

    PS: Warum enden die Sourcen eigentlich auf .pde? Also wenn das ne IDE ist, dann ne doofe^^ Und was hat
    Java damit zu tun?

  7. #7
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Unabhängig vom Kompiler/IDE sind while-Schleifen tötlich, egal wie harmlos sie aussehen:

    while (Serial.available()==0);
    while((StringStatus = StringStatus_empfange) && (Serial.available()==0))

    (und 'ne Zuweisung statt des Vergleichs ist besonders fies ;)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2011
    Beiträge
    5
    Die Dateien kannst du mit dem Arduino Tool hier: http://arduino.googlecode.com/files/arduino-0022.zip öffnen.
    Das ganze untergliedert sich in verschiedene Bereiche:

    ich hab mal meinen Schaltplan + den Code als Bild angehängt


    Klicke auf die Grafik für eine größere Ansicht

Name:	Bild1.jpg
Hits:	5
Größe:	32,6 KB
ID:	20472Klicke auf die Grafik für eine größere Ansicht

Name:	Bild2.jpg
Hits:	5
Größe:	33,3 KB
ID:	20473Klicke auf die Grafik für eine größere Ansicht

Name:	Schaltplan.jpg
Hits:	17
Größe:	57,3 KB
ID:	20474

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Zitat Zitat von radbruch Beitrag anzeigen
    while((StringStatus = StringStatus_empfange) && (Serial.available()==0))
    (und 'ne Zuweisung statt des Vergleichs ist besonders fies
    Desshalb sagte ich ja, mit Sicherheit Tippfehler enthalten^^
    (Habs oben mal ausgebessert)

    Aber weist du was besseres? (Wenn man keine ISR benutzen darf)

    Das Problem ist ja, dass wenn man ein IF anstatt WHILE verwendet, der Controller pro 1x Hauptschleife durchlaufen auch nur 1 Zeichen entgegennehmen kann. Und da sowohl Geschwindigkeit des UART als auch die Zeit die die Hauptschleife um einmal durchzulaufen benötigt unbekannt sind, ist es nicht möglich abzuschätzen, ober der Buffer überläuft oder nicht.

    Mal abgesehen davon, dass ich damit warscheinlich sowiso überfordert währe, das auszurechnen^^

    Mit der While-Schleife entleert er bei jedem Durchlauf der Hauptschleife den Buffer, so dass ein Überlauf wohl recht unwarscheinlich ist...

    Hättest du ne bessere Lösung?

    Gruß

    [EDIT]: @nec-rot:
    Ich werds mal versuchen^^

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    23.03.2011
    Beiträge
    5
    danke Schumi

    mit dem I2C Bus hab ich das teil ja auch schon zum laufen bekommen, und zwar direkt über den Mikrocontroller 1.
    Vielleicht kann man den Code effizienter einsetzen um die Zykluszeit kaum zu beeinflussen.



    //Einlesen der Entferung über I2C mit SRF02 Ultraschallsensor.

    #include <Wire.h>

    #define srf02Address (0xE0 >> 1)
    #define cmdByte 0x00 //Startbefehl zum messen
    #define rangeByte 0x02
    #define startMessung 0x51

    byte MSB = 0x00;
    byte LSB = 0x00;


    void setup()
    {
    Serial.begin(115200);
    Wire.begin();
    }

    void loop()
    {
    int rangeData = getRange();

    Serial.println(rangeData); // Ausgabe der Entfernung

    delay(200);

    }

    int getRange()

    {
    int range = 0;

    Wire.beginTransmission(srf02Address); //Ultraschallmesser wird über seine Adresse angesprochen
    Wire.send(cmdByte); //Startbefehl zum messen
    Wire.send(startMessung); //Startet Messvorgang in cm
    Wire.endTransmission();

    delay(100);

    Wire.beginTransmission(srf02Address);
    Wire.send(rangeByte);
    Wire.endTransmission();

    Wire.requestFrom(srf02Address, 2);
    while(Wire.available() < 2);
    MSB = Wire.receive();
    LSB = Wire.receive();

    range = (MSB << + LSB;

    return(range);
    }

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Verbindung zwischen Bauteilen bei Experimentierplatine
    Von RobotMichi im Forum Robby RP6
    Antworten: 9
    Letzter Beitrag: 03.12.2009, 07:09
  2. Fehler bei Verbindung zwischen PC u. ATmega8 via LPT
    Von Foooob im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 14
    Letzter Beitrag: 15.05.2008, 01:01
  3. Verbindung zwischen Servo und Bein...
    Von TLink im Forum Mechanik
    Antworten: 4
    Letzter Beitrag: 23.04.2008, 08:04
  4. Ges.: Geschwindigkeit Verbindung zwischen Display und PC
    Von jahibo15 im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 1
    Letzter Beitrag: 27.08.2007, 22:03
  5. Diplomarbeit: Verbindung zwischen PDA und B&R SPS!
    Von doolitle15 im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 1
    Letzter Beitrag: 12.11.2005, 21:17

Berechtigungen

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

Labornetzteil AliExpress