- 3D-Druck Einstieg und Tipps         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 23

Thema: RP6 und RC

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    25.10.2007
    Ort
    Solingen
    Alter
    31
    Beiträge
    177

    RP6 und RC

    Anzeige

    Praxistest und DIY Projekte
    Hi,
    ich habe auf meinen Robby einen RCEmpfänger draufgebaut und die PWM Stecker an die ADCs gesteckt.
    Ich habe ein Programm geschrieben ,dass 200ms lang zählt wie oft der Strom an geht.
    Hmm,jetzt habe ich beim Steuern des RP6 immer eine Verzögerung bis er reagiert.

    Gibt es eine bessere Methode die Frequenz des PWM zu ermitteln?

    DIV

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi,

    wenn du so ein Programm schreiben kannst, könntest du sicher auch darauf kommen, dass man so ohne alle weiteren Infos (Hardware: Was ist wo dran? Was soll das bewirken? Software: Stell dein Prog ein!) eine Glaskugel brauchen würde, um deine Frage zu beantworten.

    Gruß Dirk

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    25.10.2007
    Ort
    Solingen
    Alter
    31
    Beiträge
    177
    Hi, okay kann ich verstehen.

    Ich finde keine Datenblätter zu dem Empfänder und der Fernsteuerung ( acoms AP-202/40 und AR-2/40 ), war auch keine Anleitung dabei .
    Der Empfänder hat zwei Kanäle. Ich habe die PWM-Stecker, der beiden Kanäle, an ADC2 und ADC3 auf dem M32 gesteckt und die GNDs an die GNDs.

    Wenn ich die ADCs auslese erhalte ich entweder 0 oder 655.
    Jetzt möchte ich herausfinden wie die Frequenz der PWMs ist, um den RP6 mit der Fernsteuerung steuern zu können
    Angehängte Dateien Angehängte Dateien
    • Dateityp: c rc.c (3,6 KB, 16x aufgerufen)

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2007
    Beiträge
    386
    ....Jetzt möchte ich herausfinden wie die Frequenz der PWMs .......


    kannste doch selber festlegen.

    http://www.mikrocontroller.net/topic/87282#new

  5. #5
    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 blenderkid

    Mit einfachen Bordmitteln des RP6:
    Code:
    // Auswerten eines 2-Kanal RC-Empfängers an PortC0 und PortC1     31.12.2007 mic
    
    // Mit der RP6-Library, blockierend ähnlich wie sleep(), noch ohne timeout!!!
    // Durch die Verwendung von SCL/SDA kann das Programm nicht angehalten werden,
    // Nach einem Reset startet der ATMega32 sofort erneut.
    // Besser ist ein Anschluß an ADC0/ADC1 (PortA0 und PortA1)
    
    #include "RP6RobotBaseLib.h"        // Library einbinden
    #include "RP6uart.h"        			// Zum Debuggen, wir wollen ja was sehen,
    #include "RP6uart.c"        			// auch wenn wir kein LCD besitzen
    
    uint8_t read_rc(uint8_t kanal)
    {
    	extern uint8_t delay_timer; 		// der sleep()-Timer aus RP6RobotBaseLib.c
    
    	if (kanal == 1)  // Eingang Kanal 1 der RC-Fernbedienung (SCL xBus Pin10)
    	{
    	   while (!(PINC & 1));          // Warten auf aufsteigende Flanke
    	   sleep(1);                     // setzt den delay_timer auf 0
    	   while (PINC & 1);          	// Warten auf absteigende Flanke
    	   return (delay_timer);         // Fertig, Rückgabewert in 0.1ms
    	}
    	if (kanal == 2)  // Eingang Kanal 2 der RC-Fernbedienung (SDA xBus Pin12)
    	{
    	   while (!(PINC & 2));          // Warten auf aufsteigende Flanke
    	   sleep(1);                     // setzt den delay_timer auf 0
    	   while (PINC & 2);          	// Warten auf absteigende Flanke
    	   return (delay_timer);         // Fertig, Rückgabewert in 0.1ms
    	}
    	return(0);                       // ungültiger Parameter übergeben
    }
    
    
    int main(void)
    {
    	initRobotBase();
    	DDRC &= ~3;					// Ports auf Eingang
    	PORTC &= ~3;            // und PullUps aus
    	setLEDs(1);             // Anzeige Programm gestartet
    	
    	writeString_P("\n\n\r2-Kanal RC-Empfänger einlesen                   31.12.07 mic\n\r");
    	
    	while(1)
    	{
    	   writeString_P("\n\r");
    	   writeString_P("Kanal 1: ");
    	   writeInteger(read_rc(1), 10);
    	   writeString_P("  Kanal 2: ");
    	   writeInteger(read_rc(2), 10);
    	   mSleep(300);
    	}
    	return 0;
    }
    Die Ausgabe dazu:
    Code:
    [RP6BOOT]
    
    [READY]
    
    
    
    2-Kanal RC-Empfãnger einlesen                   31.12.07 mic
    
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 13  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 13  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 15  Kanal 2: 13
    
    Kanal 1: 15  Kanal 2: 13
    
    Kanal 1: 15  Kanal 2: 13
    
    Kanal 1: 16  Kanal 2: 13
    
    Kanal 1: 16  Kanal 2: 14
    
    Kanal 1: 17  Kanal 2: 14
    
    Kanal 1: 18  Kanal 2: 14
    
    Kanal 1: 18  Kanal 2: 14
    
    Kanal 1: 18  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 12  Kanal 2: 14
    
    Kanal 1: 9  Kanal 2: 14
    
    Kanal 1: 10  Kanal 2: 14
    
    Kanal 1: 10  Kanal 2: 14
    
    Kanal 1: 10  Kanal 2: 13
    
    Kanal 1: 10  Kanal 2: 13
    
    Kanal 1: 12  Kanal 2: 13
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 11
    
    Kanal 1: 14  Kanal 2: 10
    
    Kanal 1: 14  Kanal 2: 10
    
    Kanal 1: 14  Kanal 2: 10
    
    Kanal 1: 14  Kanal 2: 10
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 15
    
    Kanal 1: 14  Kanal 2: 18
    
    Kanal 1: 14  Kanal 2: 18
    
    Kanal 1: 14  Kanal 2: 18
    
    Kanal 1: 14  Kanal 2: 18
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    
    Kanal 1: 14  Kanal 2: 14
    Da das Signal nur 0 oder 1 ist, benötigt man natürlich keinen ADC. Der Empfänger wird an Vcc und GND angeschlossen. Die Kanäle in dieser Version an SDA und SCL (PortC0/PortC1). Alle Anschlüsse sind am xBUS verfügbar.

    Gruß

    mic

    [Edit]
    Ich Depp, ich weiß doch, welche Ports verwendet werden sollten. Hier die Version für ADC2/3 (ungeprüft):
    Code:
    // Auswerten eines 2-Kanal RC-Empfängers an PortA2 und PortA3     31.12.2007 mic
    
    // Version für blenderkid (nicht geprüft)
    
    #include "RP6RobotBaseLib.h"        // Library einbinden
    #include "RP6uart.h"        			// Zum Debuggen, wir wollen ja was sehen,
    #include "RP6uart.c"        			// auch wenn wir kein LCD besitzen
    
    uint8_t read_rc(uint8_t kanal)
    {
    	extern uint8_t delay_timer; 		// der sleep()-Timer aus RP6RobotBaseLib.c
    
    	if (kanal == 1)  // Eingang Kanal 1 der RC-Fernbedienung (ADC2 PortA2)
    	{
    	   while (!(PINA & 4));          // Warten auf aufsteigende Flanke
    	   sleep(1);                     // setzt den delay_timer auf 0
    	   while (PINA & 4);          	// Warten auf absteigende Flanke
    	   return (delay_timer);         // Fertig, Rückgabewert in 0.1ms
    	}
    	if (kanal == 2)  // Eingang Kanal 2 der RC-Fernbedienung (ADC3 PortA3)
    	{
    	   while (!(PINA & 8));          // Warten auf aufsteigende Flanke
    	   sleep(1);                     // setzt den delay_timer auf 0
    	   while (PINA & 8);          	// Warten auf absteigende Flanke
    	   return (delay_timer);         // Fertig, Rückgabewert in 0.1ms
    	}
    	return(0);                       // ungültiger Parameter übergeben
    }
    
    
    int main(void)
    {
    	initRobotBase();
    	DDRA &= ~12;				// Ports auf Eingang   ADC2+3
    	PORTA &= ~12;            // und PullUps aus
    	setLEDs(1);             // Anzeige Programm gestartet
    	
    	writeString_P("\n\n\r2-Kanal RC-Empfänger einlesen                   31.12.07 mic\n\r");
    	
    	while(1)
    	{
    	   writeString_P("\n\r");
    	   writeString_P("Kanal 1: ");
    	   writeInteger(read_rc(1), 10);
    	   writeString_P("  Kanal 2: ");
    	   writeInteger(read_rc(2), 10);
    	   mSleep(300);
    	}
    	return 0;
    }
    Noch ein [Edit]: Hab' doch glatt überlesen, dass es für ein M32 sein soll. Damit kann ich leider nicht dienen, weil mir das keiner schenken mag. *traurigkuck*
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Hallo,

    @mic:
    Kleiner Hinweis dazu:
    Seit Version 1.3 der RP6Lib vom 25.9 gibt es auch die 16Bit Variable "timer" die alle 100µs hochgezählt wird. Sowohl für die RP6BaseLib als auch die RP6ControlLib.

    Damit könnte man es so schreiben:
    // Hier wird der E_INT1 Pin an PORTA als Eingang verwendet...
    while (!(PINA & E_INT1)); // Warten auf aufsteigende Flanke
    timer=0;
    while (PINA & E_INT1); // Warten auf absteigende Flanke
    return (timer); // Fertig, Rückgabewert in 0.1ms
    Auf delay_timer sollte man eigentlich gar keinen Zugriff haben (der Compiler sollte meckern ) - hast Du an den Headern was verändert?


    Den Bootloader interessiert zum Starten des Programms übrigens nur SDA.

    ACHTUNG: Auf jeden Fall zur Sicherheit 1K Widerstände in Serie dazwischen schalten wenn man SDA oder SCL als Sensoreingänge verwenden möchte! Der Bootloader generiert beim Starten nämlich einen General Call auf dem I2C Bus, schaltet SDA und SCL also als Ausgänge und ganz kurz nach GND!

    --> Für E_INT1 und die beiden freien ADC Anschlüsse braucht man natürlich keinen Widerstand.
    An den freien I/Os vom RP6-M32 Modul sowieso nicht wenn man die Portrichtung auf Eingang schaltet.


    --------------------------------------------------------------------

    @blenderkid:
    Für das RP6-M32 Erweiterungsmodul funktioniert es prinzipiell natürlich ganz ähnlich. Hier hast Du auch jede Menge freie I/O Pins.

    Um nochmal auf die Ausgangsfrage einzugehen:
    Gibt es eine bessere Methode die Frequenz des PWM zu ermitteln?
    Ja - man misst statt der Anzahl der Pulse einfach die Dauer eines einzelnen Pulses! Wie in dem Programmbeispiel von mic.

    MfG,
    SlyD

  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
    Hallo SlyD

    Ich verwende die orginale Version 1.3 vom 25.9.07 Die Variable delay_timer habe so eingebunden:

    extern uint8_t delay_timer;

    Eine Fehlermeldung erhalte ich nicht beim Compilieren, ich lese die Variable auch nur aus.

    Ich verwende delay_timer mit Absicht, weil weiterhin timer für eigene Anwendungen frei bleiben sollte. Weil meine Funktion blockierend ist, kann delay_timer von sleep() in dieser Zeit nicht verwendet/verändert werden. Ein weiterer Vorteil ist, dass ich mit sleep(0) (war noch ein Bug in der ersten Version) bequem schreibend auf delay_timer zugreifen kann, auch wenn der Aufruf theoretisch einen kleinen Messfehler verursacht.

    Der Tipp mit dem SDA-Reset funktioniert wunderbar, ich habe nun den zweiten Kanal auf E-INT1 gelegt und kann das Programm deshalb auch wieder stoppen.

    Das aktuelle Programm sieht nun so aus:
    Code:
    // Auswerten eines 2-Kanal RC-Empfängers an PortC0 und PortA4    31.12.2007 mic
    
    // Mit der RP6-Library, blockierend wie sleep(), ohne timeout!!!
    // Besser ist ein Anschluß an ADC0/ADC1 (PortA0 und PortA1)
    
    #include "RP6RobotBaseLib.h"        // Library einbinden
    #include "RP6uart.h"        			// Zum Debuggen, wir wollen ja was sehen,
    #include "RP6uart.c"        			// auch wenn wir kein LCD besitzen
    
    uint8_t read_rc(uint8_t kanal)
    {
    	extern uint8_t delay_timer; 		// der sleep()-Timer aus RP6RobotBaseLib.c
    
    	if (kanal == 1)  // Eingang Kanal 1 der RC-Fernbedienung (SCL xBus Pin10)
    	{
    	   while (!(PINC & 1));          // Warten auf aufsteigende Flanke
    	   sleep(0);                     // setzt den delay_timer auf 0
    	   while (PINC & 1);          	// Warten auf absteigende Flanke
    	   return (delay_timer);         // Fertig, Rückgabewert in 0.1ms
    	}
    	if (kanal == 2)  // Eingang Kanal 2 der RC-Fernbedienung (E_INT1 xBus Pin8)
    	{
    	   while (!(PINA & E_INT1));     // Warten auf aufsteigende Flanke
    	   sleep(0);                     // setzt den delay_timer auf 0
    	   while (PINA & E_INT1);        // Warten auf absteigende Flanke
    	   return (delay_timer);         // Fertig, Rückgabewert in 0.1ms
    	}
    	return(0);                       // ungültiger Parameter übergeben
    }
    
    
    int main(void)
    {
    	initRobotBase();
    	DDRC &= ~1;					// Ports auf Eingang (SCL)
    	PORTC &= ~1;            // und PullUps aus
    	extIntOFF();            // E_INT1 auf Eingang
    	setLEDs(1);             // Anzeige Programm gestartet
    	
    	writeString_P("\n\n\r2-Kanal RC-Empfänger einlesen                   31.12.07 mic\n\r");
    	
    	while(1)
    	{
    	   writeString_P("\n\r");
    	   writeString_P("Kanal 1: ");
    	   writeInteger(read_rc(1), 10);
    	   writeString_P("  Kanal 2: ");
    	   writeInteger(read_rc(2), 10);
    	   mSleep(300);
    	}
    	return 0;
    }
    Leider sind meine ADC0/1-Anschlüsse vorerst dauerhaft belegt, weil ich sie zur Servoansteuerung verwende um meinen RP6 mit einem 4-Radantrieb zu betreiben. Ich habe immer noch keine Alternative zu den orginalen Antriebseinheiten gefunden, deshalb muss ich wohl abwarten, bis mir die passenden Teile eines Schrott-RP6 in die Hände fallen oder arexx ein Getriebekit zum Nachrüsten anbietet.

    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!

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    25.10.2007
    Ort
    Solingen
    Alter
    31
    Beiträge
    177
    Hi, muss man irgendetwas besonderes machen um den timer zu verwenden?
    Bei mir sagt der immer 0.
    ich habe mal probiert:
    writeInteger(timer,10);
    mSpleep(200);
    writeInteger(timer,10);

    und auch da sagt er zwei mal 0.

  9. #9
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    39
    Beiträge
    1.516
    Die timer Variable gibt es wie gesagt erst seit der Version vom 25.9.2007 bzw. 28.9 der RP6Lib.
    Hier die aktuelle Version:
    http://www.arexx.com/rp6/downloads/R...s_20071016.zip

    Da muss man eigentlich nichts machen und kann die Variable direkt in allen eigenen Programmen verwenden.

    Beispiel:
    Code:
    		uint16_t t_end = 0;
    		uint16_t t_start = timer;
    
    		mSleep(100);
    		t_end = timer;
    
                   // Es ist besser die Ausgaben getrennt von den Messungen zu machen 
                   // da die Ausgaben selbst auch Zeit benötigen.
    
    		writeString_P("# Start: ");
    		writeInteger(t_start,DEC);
    		writeString_P(" -> End: ");
    		writeInteger(t_end,DEC);
                    writeString_P(" -> Diff: ");
    		writeInteger(t_end - t_start,DEC);
    		writeChar('\n');
    MfG,
    SlyD

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    25.10.2007
    Ort
    Solingen
    Alter
    31
    Beiträge
    177
    ich habe das hier geschrieben:

    uint8_t RC(uint8_t kanal)
    {
    if (kanal == 1)
    {
    while((PINA&);

    timer=0;


    while(!(PINA&);

    return (timer);
    }
    if (kanal == 2)
    {
    while(!(PINA&4));

    timer=0;

    while(PINA&4);

    return (timer);
    }
    return(0);
    }

    und da sagt er immer 0.

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress