- Labornetzteil AliExpress         
Ergebnis 1 bis 10 von 10

Thema: 2 PWM Signale gleichzeitig auswerten

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52

    2 PWM Signale gleichzeitig auswerten

    Anzeige

    E-Bike
    Hallo zusammen. Mein Roboter schreitet immer weiter seinem Ziel entgegen.
    Nun hab ich ein kleines Problem. Ich habe vor den Per Fernsteuerung zu steuern. Dazu hab ich ne alte Fernsteuerung von nem Flugzeug genommen und den dazu gehörigen Empfänger der im Flieger war und an dem die Servos angeschlossen waren.
    Ich überleg derzeit wie ich es schaffe meinem RP6 Control beizubringen 2 der PWM-Ausgänge des Empfängers mehr oder weniger gleichzeitig zu überwachen. Denn ich wollte die 2 Antriebsmotoren separat ansteuern.
    Wie isn das eigentlich, beim M32 steht ja dabei das er 4 PVM I/Os hat, sind die eigentlich noch frei? Oder hab ich da irgendwas übersehn und sind bereits alle 4 belegt.
    Der Empfänger ist nen 16 Kanal Superhet c16 von Graupner. Ich würde da zwar gern noch mehr Infos nennen, hab aber selber noch nciht viel dazu gefunden.
    Denn wenn da ja noch welche frei wären wär das überhaupt kein Problem.
    Ansonsten muss ich ja das PWM Signal erstmal in ne Gleichspannung wandeln un die dann auf nen ADC geben.

    Wär für Ideen dankbar. Ich stecke da grad in nem gedanklichen Dilemma *g*

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Ein Ansatz zur RC-Signalauswertung: Auf Basis eines Programms zur Servosansteuerung (RN-Wissen: Servos) schreibt man eine kleine Routine zur Messung der Impulslängen die der RC-Empfänger liefert. Der Code in der ISR für zwei Achsen:

    Code:
       if (PINC & 1) rc_temp_dir++; else 
          if (rc_temp_dir) { rc_input_dir=rc_temp_dir-1; rc_temp_dir=0; } 
       if (PINC & 2) rc_temp_pwr++; else 
          if (rc_temp_pwr) { rc_input_pwr=rc_temp_pwr-1; rc_temp_pwr=0; }
    Gemessen wird an den SCL- und SDA-Pins am XBUS-Stecker des RP6. rc_input_xxx sind die Messwerte der jeweiligen Kanäle. Verwendet hatte das mal hier:
    https://www.roboternetz.de/phpBB2/ze...=328824#328824

    Vielleicht hilft dir das weiter.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Hmm du machst das mit den Signalen des Empfängers nun über die Leitungen des I2C. Da ich das aber gern mit dem M32 machen wollte, müsste ich da ja genauso einen beliebigen anderen Input von dort nehmen können oder?
    Weil die Daten sollen ja bissl verarbeitet und dann an die Base geschickt werden. Bzw sollen damit über den M32 die base gesteuert werden.

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Das funktioniert natürlich an (nahezu) jedem Pin, also auch mit dem M32. Ich wollte nur zeigen wie man in der ISR durch Zählen der Aufrufe mit gesetztem Eingangspin die Impulszeit messen kann.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Hallo, ich schon wieder. Bin nun weiter was den Aufbau und das Programm selber angeht aber irgendwas klappt da nicht richtig.

    Erstmal der Code:

    Code:
    #include "RP6ControlLib.h"
    
    uint8_t rc_input_left, rc_input_right, rc_input_active;
    uint8_t rc_left, rc_right, rc_active;
    
    ISR(TIMER0_COMP_vect)
    {
        //ISR um Pegel der Pins für RC Steuerung abzufragen
        /*  Empfaenger liefert ein PWM-Signal entsprechend der Steuerung
            ISR fragt regelmaessig den Zustand der Pins ab. Ist der Pin
            auf 1 wird die Variable erhoeht.
            Je laenger das Signal waehrend einer Signalperiode auf 1 ist
            umso groesser wird die Zahl
        */
    
        static uint16_t rc_temp_left = 0;
        static uint16_t rc_temp_right = 0;
        static uint16_t rc_temp_active = 0;
    
        //RC-Steuerung aktivierung ermitteln
        if (PINC & 7)
        {
            rc_temp_active++;
        }
        else if (rc_temp_active)
        {
            rc_temp_active=rc_temp_active;
            rc_temp_active=0;
        }
    
        //Geschwindigkeit links ermitteln
        if (PINC & 6)
        {
            rc_temp_left++;
        }
        else if (rc_temp_left)
        {
            rc_input_left = rc_temp_left-1;
            rc_temp_left = 0;
        }
    
        //Geschwindigkeit rechts ermitteln
        if (PINC & 5)
        {
            rc_temp_right++;
        }
        else if (rc_temp_right)
        {
            rc_input_right=rc_temp_right;
            rc_temp_right=0;
        }
    
    
    }
    
    int main(void)
    {
        initRP6Control();
    
        setLEDs(0);
    
        while(1)
        {
            writeString_P("RC active :");
            writeInteger(rc_input_active, 10);
            writeString_P(" - ");
            writeString_P("RC links :");
            writeInteger(rc_input_left, 10);
            writeString_P(" - ");
            writeString_P("RC rechts :");
            writeInteger(rc_input_right, 10);
            writeString_P("\n\r");
        }
    
        if (rc_input_active > 500)
        {
            //blablabla
        }
    
        mSleep(500);
        return 0;
    }
    Da die ISR bereits in diesem Programm drinne ist hab ich die entsprechende ISR in der RP6ControlLib.h kurzerhand per /* und */ deaktiviert.

    Code:
    /*
    ISR (TIMER0_COMP_vect)
    {
    	// 16bit timer (100µs resolution)
    	timer++;
    
    	// Blocking delay (100µs):
    	delay_timer++;
    
    	// All 1ms based timing stuff
    	if(ms_timer++ >= 10) { // 10 * 100µs = 1ms
    		// 16bit Stopwatches:
    		if(stopwatches.watches & STOPWATCH1)
    			stopwatches.watch1++;
    		if(stopwatches.watches & STOPWATCH2)
    			stopwatches.watch2++;
    		if(stopwatches.watches & STOPWATCH3)
    			stopwatches.watch3++;
    		if(stopwatches.watches & STOPWATCH4)
    			stopwatches.watch4++;
    		if(stopwatches.watches & STOPWATCH5)
    			stopwatches.watch5++;
    		if(stopwatches.watches & STOPWATCH6)
    			stopwatches.watch6++;
    		if(stopwatches.watches & STOPWATCH7)
    			stopwatches.watch7++;
    		if(stopwatches.watches & STOPWATCH8)
    			stopwatches.watch8++;
    
    		// Sound generation timing:
    		if(controlStatus.beep) {
    			if(sound_timer < 1) { // sound_timer * 1ms
    				TCCR2 = 0;
    				controlStatus.beep = false;
    			}
    			else
    				sound_timer--;
    		}
    
    		ms_timer = 0;
    	}
    
    }
    */
    Die Eingänge habe ich auch gesetzt in der RP6Control.h

    Code:
    #define IO_PC7 	(1 << PINC7)	// I/O
    #define IO_PC6 	(1 << PINC6)	// I/O
    #define IO_PC5 	(1 << PINC5)	// I/O (Optional JTAG: TDI)
    #define IO_PC4 	(1 << PINC4)	// I/O (JTAG: TDO)
    #define IO_PC3 	(1 << PINC3)	// I/O (JTAG: TMS)
    #define IO_PC2 	(1 << PINC2)	// I/O (JTAG: TCK)
    #define SDA 	(1 << PINC1)	// I2C Data (I/O)
    #define SCL 	(1 << PINC0)	// I2C Clock (Output as Master, Input as Slave)
    
    // Initial value of port and direction registers.
    #define INIT_DDRC 0b00000000
    //#define INIT_PRTC 0b11111100
    //PC7 PC6 PC5 als Input ohne Pull-up
    #define INIT_PRTC 0b00011100
    Die Eingänge habe ich auch mal mit internem Pull-up probiert, aber das ergab keine Änderung.

    Verwendet habe ich an der I/O Buchse des M32 auch die Pins PC5, PC6 und PC7 anhand der Anschlussbelegung im entsprechenden Manual.

    Das ganze Programm soll vorerst nicht mehr machen als die Werte des Empfängers ermitteln und mit im Terminal ausgeben. Aber bisher gibt der mir nur 0er.

    Wenn irgendwer ne Idee hat woran das liegen könnte wär das super.
    Selbst wenn ich testweise mal die Pins direkt mit einer Drahtbrücke auf VDD lege ändert sich der Wert nicht.

    Und selbst wenn der Empfänger oder der Sender defekt wär und nichts mehr machen würde müsste doch spätestens hier sich was tun. Oder nicht?

    Ach und kompilieren lässt sich das ganze natürlich ohne Probleme.
    Bei bedarf kann ich auch mal das ganze Codeblocks Projekt packen und anhängen.

  6. #6
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    1:
    if (PINC & 7)

    Hier soll geprüft werden ob das 7te Bit gesetzt wird. Dieses hat die Wertigkeit 128, die Prüfung muss deshalb so aussehen:

    if (PINC & 128) oder alternativ
    if (PINC & (1 << PINC7))

    Das gilt auch für die anderen Pin-Abfragen!

    2:
    rc_temp_active=rc_temp_active;

    3:
    Variablen die in einer ISR verändert werden sollten als volatile definiert werden. Das zwingt den Compiler die Werte im RAM zwischenzuspeichern und nicht unerwarteterweise in einem flüchtigen Register:

    volatile uint8_t rc_input_left, rc_input_right, rc_input_active;

    Da die ISR bereits in diesem Programm drinne ist
    Anstatt die ISR in der Library auszukommentieren kannst du auch die Servo-ISR in die Lib einfügen ;)

    Ich hoffe, das du nun endlich zu einem Erfolg kommst.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Anstatt die ISR in der Library auszukommentieren kannst du auch die Servo-ISR in die Lib einfügen
    ... oder direkt den auf der M32 komplett freien Timer 1 im eigenen Programm verwenden

    MfG,
    SlyD

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    01.05.2008
    Beiträge
    52
    Oh man. Das waren ja keine Tomaten auf den Augen sondern eher schon Wassermelonen. Funktioniert nun genau so wie es soll.
    Hab den doofen Fehler bei den Variable behoben. Das Äpfel Äpfel sind hätt ich au so wissen müssen *g*.
    Das mit dem volatile hab ich au eingetragen. Muss ich die Variablen eigentlich dann in der Lib UND im Programm definieren? In der Lib setze ich die ja und im Programm frag ich die dann ab.

    Und das mit der Wertigkeit der Pins hab ich nu au endlich mal kapiert

    Dennoch *Kopf -> Tisch*

  9. #9
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Auf uint8_t lib_variable in einer Library kann man mit extern uint8_t lib_variable vom Programm aus zugreifen.

    Glückwunsch zum Erfolg *mitfreu*
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.01.2008
    Ort
    Zürich
    Beiträge
    604
    ^^

    also bei den rc-empfängern sollte auch eine art composite-stecker sein, da liegen dann alle signale an, also jeder kanal, d.h. bis zu 10 signale die man dann mit nur 1 port auswerten kann, das ist super!!


    MfG Pr0gm4n

    ps: *auch mitfreu*

Berechtigungen

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

12V Akku bauen