[gelöst] Einfache IR-Kommunikation für den RP6
Hallo
Da mich das Kabelgewurschtel nervt, suche ich nach einer einfachen Möglichkeit, vorerst nur Daten mit IR vom RP6 zum PC zu senden. Später auch zurück, aber immer schön einen Schritt nach dem anderen. Ziel ist dann eine Erweiterung für die Lib, aber das wird wohl noch etwas dauern. Hier mein erster kleiner Versuch in dieser Richtung:
Code:
// Sendet einzelne Zeichen mit 2400 Baud über die IR-Dioden.
// Das ist noch eine frühe Beta-Version zur allgemeinen Erheiterung ;)
// Leider funktioniert das so bei mir nur im Ultranahbereich.
// (Empfänger liegt auf der Diode!). Um die nervige Nabelschnur
// loszuwerden muss ich wohl noch ein bisschen tüfteln. mic 22.7.07
#include "RP6RobotBaseLib.h"
#define BAUD_2400 2400 //IR speed - 2400 Baud
//#define UBRR_BAUD_2400 ((F_CPU/(16*BAUD_2400))-1) // ergibt einen Fehler?
#define UBRR_BAUD_2400 (((F_CPU/16)/BAUD_2400)-1)
uint8_t i;
void IRwriteChar(uint8_t zeichen)
{
UBRRH = UBRR_BAUD_2400 >> 8; // Setup UART: Baudrate ist 2400
UBRRL = (uint8_t) UBRR_BAUD_2400;
cli(); // Bitte nicht stören!
PORTD &= ~IRCOMM; // IR-LEDs D3+D4 ausschalten
if (UCSRA & (1<<TXC)) UCSRA=1<<TXC; // Flag löschen falls gesetzt
while (!(UCSRA & (1<<UDRE))); // Warten bis Register leer (mit cli()!)
UDR = (uint8_t)zeichen; // Zeichen reinschreiben
while (!(UCSRA & (1<<TXC))) // Solange noch nicht alle Bits
{ // rausgeschoben sind, erkenntlich
statusLEDs.LED2=1; // an LED2, lauschen wir, was an
if ((PIND & (1<<PD1)) && 1) // TX rausgeht und steuern damit
{
statusLEDs.LED1=0; // die LED1 und
PORTD &= ~IRCOMM; // die IR-LEDs D3+D4 ;)
}
else
{
statusLEDs.LED1=1;
PORTD ^= IRCOMM;
}
updateStatusLEDs();
}
sei(); // Enable Global Interrupts // wir haben fertig
sleep(10);
// ACHTUNG! TXC-Flag schreiben bedeutet löschen!
// Und zwar mit = weil so ohne Wirkung auf andere Flags
// Normales Setzen mit | würde andere Flags mitlöschen!
UCSRA=1<<TXC;
statusLEDs.LED2=0; // und das zeigen wir auch
updateStatusLEDs();
UBRRH = UBRR_BAUD_LOW >> 8; // Loaderterminalbaudrate setzen
UBRRL = (uint8_t) UBRR_BAUD_LOW; // Setup UART: Baudrate is Low Speed
}
int main(void)
{
initRobotBase();
setLEDs(0b111111);
mSleep(100);
setLEDs(0);
powerON();
while(true)
{
for (i='a'; i<='z'; i++)
{
IRwriteChar(i);
}
IRwriteChar('\n');
IRwriteChar('\r');
mSleep(200);
}
return 0;
}
Das ist aber noch eine Vorbetaversion und soll nur zeigen, wie es im Ansatz funktionieren könnte.
Gruß
mic
[Edit]
Nun ist mir auch klar, warum das nicht richtig funktioniert: Es fehlt noch die 36kHz-Trägerfrequenz!
[Edit2]
Thread-Titel geändert
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo
Ich habe jetzt meine Library upgedatet (Stand 7.8.07) und seltsamerweise erhalte ich jetzt einen Fehler beim Kompilieren. Ursache ist folgender Hinweis in der Datei RP6RobotBase.h:
Code:
/*****************************************************************************/
// IRCOMM pin:
// ### WARNING!
//
// #define IRCOMM (1 << PIND7) // Output
//
// ### DO NOT USE THIS PIN BY YOURSELF!
// ONLY LET THE INTERRUPT ROUTINE OF THE LIBRARY
// CONTROL THIS PIN!
// The IR LEDs must be controlled by a modulated
// signal with minimal 5kHz or higher
// modulation frequency!
// Nominal modulation frequency is 36kHz!
// YOU MAY DAMAGE THE IRCOMM IF YOU USE IT
// IN ANY OTHER WAY!
// Only use this macro to make sure IRCOMM is
// turned off:
#define IRCOMM_OFF() PORTD &= ~(1 << PIND7);
// NEVER try to control IRCOMM by yourself if you
// do not know what you are doing!
// Always use Timer based modulation control!
/*****************************************************************************/
Hintergrund ist der Widerstand R6 vor den IR-Dioden D3/D4. Der hat nur 10 Ohm und wird im Dauerbetrieb extrem heis. Möglicherweise kann der RP6 durch falsche Ansteuerung des IRCOMM-Pins dauerhaft Schaden nehmen.
Das wusste ich bei den ersten Versionen meiner Funktionen noch nicht und habe deshalb ziemlich unvorsichtig den IR-Pin manipuliert. Die aktuelle Version moduliert die LEDs mit den geforderten 36kHz und schaltet nach dem Senden die LEDs auch aus. Trotzdem muss ich leider darauf hinweisen, dass die Verwendung meiner Funktionen auf euer eigenes Risiko geschied!
Ich werde das Projekt jetzt erstmal auf Eis legen und abwarten, ob irgendwelche negativen Berichte über die Verwendung gepostet werden. Da ich selbst die Funktionen seit Tagen ohne Schaden am RP6 verwende, biete ich euch auf euer eigenes Risiko noch den Quellcode meiner letzten Version an.
Mit den im Quellcode beschriebenen Änderungen in RP6uart.h und RP6uart.c sind nun noch die Funktionen void IRuartON(void) und void IRuartOFF(void) dazugekommen. Damit schaltet man die Baudraten und die writeChar()-Umleitung ein oder aus. (Ausführliche Doku für Interessierte im Quellcode)
Gruß
mic