PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 2 PWM Signale gleichzeitig auswerten



vogel0815
30.08.2008, 11:31
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*

radbruch
30.08.2008, 11:52
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:


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/zeigebeitrag.php?p=328824#328824

Vielleicht hilft dir das weiter.

Gruß

mic

vogel0815
30.08.2008, 13:42
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.

radbruch
30.08.2008, 13:57
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

vogel0815
02.09.2008, 16:36
Hallo, ich schon wieder. Bin nun weiter was den Aufbau und das Programm selber angeht aber irgendwas klappt da nicht richtig.

Erstmal der 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.


/*
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


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

radbruch
02.09.2008, 17:25
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

SlyD
02.09.2008, 17:42
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

vogel0815
02.09.2008, 18:01
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*

radbruch
02.09.2008, 18:07
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*

Pr0gm4n
04.09.2008, 13:17
^^

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*