Hallo
Erstaunlicherweise habe ich alle Teile auf Anhieb wiedergefunden, sogar die Batterien meines RC-Senders funktionieren noch (die waren natürlich separat gelagert). Zusammengestöpselt, das oben erwähnte, schon kompilierte Programm geflash, läuft.
Beim Anschluß muss selbstverständlich auch die Minus-Leitung des RC-Empfängers mit dem GND des RP6 verbunden sein!
"Die RC-Kanäle kommen an den XBUS-Stecker, links/rechts an Pin10 (SCL), vor/zurück an Pin12 (SDA). RC-Empfänger + und - an VCC und GND des RP6."
Ich hatte zusätzlich noch Angstwiderstände (820 Ohm) in die Signalleitungen eingebaut. Als Alternative zum XBUS kann man übrigends auch den I2C-Anschluß auf der RP6-Platine neben XBUS2 verwenden. Auf den 5 Pins liegen Vdd (5V), GND, SDA, SCL und INT1 (E_INT). Das hatte ich damals auch noch nicht gecheckt ;)
Wichtig ist vielleicht noch, dass die RC-Fernbedienung positive Servosignale sendet.
Aus heutiger Sicht betrachtet war das damals echter Murks, aber ich war Anfänger und es hat (leidlich) funktioniert. Inzwischen kann ich die Servos auch libverträglich ansteuern und der ganze rblib-Mist ist somit Geschichte:
Code:
// Servoansteuerung mit Timer1 31.1.2010 mic
// Einfach und elegant, warum finde ich das erst jetzt? Timer1 (RP6-Motoransteuerung)
// läuft ja sowieso im Hintergrund. Deshalb kann man die "klassische" Servoansteuerung
// in die Overflow-ISR einbauen und mit ca. 19kHz aufrufen lassen. Timersetup der Lib:
// Mode 10, Phase Correct mit ICR1 als Top ergibt bei ICR1=210 ca. 8MHz/420=19047,6Hz ;)
// Drehbereich meiner RS-2-Servos ist von ca. 14 bis ca. 38
#include "RP6RobotBaseLib.h"
volatile uint8_t servo1, servo2, servo3, p; // Servopositionen und Impulszähler
uint8_t c; // ein Char zur freien Verfügung
int main(void)
{
initRobotBase();
servo1=servo2=servo3=26; // Servomitte?
TIMSK |= (1 << TOIE1); // Die Timer1 Overflow-ISR zur Servoansteuerung
DDRA |= (E_INT1); // Servopins auf Ausgang setzen
DDRC |= (SCL | SDA);
setLEDs(1); // und los!
startStopwatch1();
startStopwatch2();
startStopwatch3();
while(1)
{
for(c=0;c<6;c++) // 6 mal ein einfaches Demo....
{
setLEDs(1<<c);
servo1=servo2=servo3=26; // mitte
p=50; while(p); // warten bis 50 Impulse gesendet (ca. 1 Sek.)
servo1=servo2=servo3=14; // links
p=50; while(p);
servo1=servo2=servo3=38; // rechts
p=50; while(p);
}
setStopwatch1(0);
setStopwatch2(0);
setStopwatch3(0);
while(c) // und 6 mal ein etwas anspruchsvolleres Demo
{
setLEDs(1<<c);
if(getStopwatch1()>1000)
{
setStopwatch1(0);
switch(servo1)
{
case 38: servo1=30; break;
case 30: servo1=20; break;
case 20: servo1=14; break;
case 14: servo1=21; break;
case 21: servo1=31; break;
case 31: servo1=38; break;
}
}
if(getStopwatch2()>100)
{
setStopwatch2(0);
servo2++;
if (servo2 > 38) { servo2=14; c--; }
}
if(getStopwatch3()>300)
{
setStopwatch3(0);
if (servo3 == 10) servo3=50; else servo3=10;
}
task_RP6System(); // Verträglichkeitstest ;)
}
}
return 0;
}
ISR (TIMER1_OVF_vect)
{
static uint16_t servocount=1;
if(servocount > servo1) PORTA &= ~E_INT1; else PORTA |= E_INT1; // PA4 XBUS 8
if(servocount > servo2) PORTC &= ~SCL; else PORTC |= SCL; // PC0 XBUS 10
if(servocount > servo3) PORTC &= ~SDA; else PORTC |= SDA; // PC1 XBUS 12
if(servocount < 400) servocount++; else {servocount=1; if(p) p--;} // p = 1/50 Sek
}
(Code aus https://www.roboternetz.de/phpBB2/ze...=483757#483757)
Allerdings ist die Auflösung viel geringer (100kHz zu knapp 20kHz), aber dafür ist der zusätzliche Code minimal:
TIMSK |= (1 << TOIE1);
schaltet den Overflow-Interrupt ein und bindet so die zusätzlich Timer1-OverFlow-ISR ein. Für das Einlesen der RC-Signale müsste die ISR dann etwa so aussehen:
Code:
// Globale Variablen
volatile uint8_t rc_input_pwr, rc_input_dir;
ISR (TIMER1_OVF_vect)
{
static uint16_t rc_temp_pwr=0;
static uint16_t rc_temp_dir=0;
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; }
}
Vorsichtshalber sollte man volatile verwenden.
Die eingelesenen Werte sind so zwar deulich kleiner (ca. 1/5), aber zur Ansteuerung sollte es reichen. Die Formel zur Verteilung der Werte auf beide Antriebe passt dann natürlich auch nicht mehr, aber die war auch nicht besonders gut ;)
Der linke Antrieb meines RP6 lief damals nur, wenn ich den Motortreiberbaustein angewärmt (anhauchen oder ohne Motorüberwachung warmfahren) hatte. Den Fehler, der da dahintersteckt, hatte ich nie gefunden. Zur Zeit funktioniert das aber auch ohne vorwärmen problemlos.
Gruß
mic
Lesezeichen