Hallo
Zur besseren Übersicht habe ich eine Library erstellt und ein kleines Demo dazu geschrieben. Ohne Verwendung der asuro-Lib kann das kleine Programm z.B. die Tasterwerte einlesen und in binärer Darstellung an das Terminal senden:
Code:
#include "fernbedienunglib.c"
int main(void)
{
Init();
FrontLED(ON);
while(1)
{
StatusLED(RED);
SerWrite("Hallo\r\n", 7);
PrintChar(12345);
SerWrite("\n\r", 2);
PrintBin(PollSwitch());
SerWrite("\n\n\r", 3);
StatusLED(YELLOW);
Msleep(500);
}
return(0);
}
/* uses timer2 (36kHz for IR communication */
/* counts falling and rising edge => 36kHz*2 = 72kHz */
SIGNAL (SIG_OUTPUT_COMPARE2)
{
count72kHz ++;
}
Dazu passt dann diese Library die man als "fernbedienlib.c" speichern sollte:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#define OFF 0
#define ON 1
volatile unsigned char count72kHz;
/* uses 72kHz timer => Sleep(x) = x/72kHz [sec] */
void Sleep(unsigned char time72kHz)
{
count72kHz = 0;
while (count72kHz < time72kHz);
}
/* function to read out switches */
unsigned char PollSwitch (void)
{
unsigned int i;
DDRD |= (1 << PD3); // Switches as Output
PORTD |= (1 << PD3); // Output HIGH for measurement
ADMUX = (1 << REFS0) | (1 << MUX2); // AVCC reference with external capacitor
Sleep(10);
ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF)));// wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
i = ADCL + (ADCH << 8);
PORTD &= (1 << PD3);
//return ((unsigned char) ((( 1024.0/(float)i - 1.0)) * 63.0 + 0.5));
return ((10240000L/(long)i-10000L)*63L+5000L)/10000;
}
/* function for serial communication */
void SerWrite(unsigned char *data,unsigned char length)
{
unsigned char i = 0;
UCSRB = 0x08; // enable transmitter
while (length > 0) {
if (UCSRA & 0x20) { // wait for empty transmit buffer
UDR = data[i++];
length --;
}
}
while (!(UCSRA & 0x40));
for (i = 0; i < 0xFE; i++)
for(length = 0; length < 0xFE; length++);
}
// aus: https://www.roboternetz.de/phpBB2/ze...=328394#328394
void PrintChar(unsigned int x)
{
char ergebnis[5] = {'0','0','0','0','0'};
while (x >=10000) { ergebnis[0]++; x -=10000; }
while (x >= 1000) { ergebnis[1]++; x -= 1000; }
while (x >= 100) { ergebnis[2]++; x -= 100; }
while (x >= 10) { ergebnis[3]++; x -= 10; }
ergebnis[4] +=x;
SerWrite(ergebnis,5);
}
void PrintBin(unsigned int x)
{
char bit=16;
char ergebnis[16];;
while(bit--)
{
ergebnis[15-bit]=0;
while (x >= (1<<bit)) { ergebnis[15-bit]++; x -= (1<<bit); }
ergebnis[15-bit] +='0';
}
SerWrite(ergebnis, 16);
}
/* Front LED */
inline void FrontLED(unsigned char status)
{
PORTD = (PORTD &~(1 << PD6)) | (status << PD6);
}
/* Status LED (OFF,GREEN,YELLOW,RED)*/
inline void StatusLED(unsigned char color)
{
#define GREEN 1
#define RED 2
#define YELLOW 3
#define GREEN_LED (1 << PB0)
#define RED_LED (1 << PD2)
#define GREEN_LED_ON PORTB |= GREEN_LED
#define GREEN_LED_OFF PORTB &= ~GREEN_LED
#define RED_LED_ON PORTD |= RED_LED
#define RED_LED_OFF PORTD &= ~RED_LED
if (color == OFF) {GREEN_LED_OFF; RED_LED_OFF;}
if (color == GREEN) {GREEN_LED_ON; RED_LED_OFF;}
if (color == YELLOW) {GREEN_LED_ON; RED_LED_ON;}
if (color == RED) {GREEN_LED_OFF; RED_LED_ON;}
}
void Msleep(int dauer)
{
int z;
for(z=0;z<dauer;z++) Sleep(72);
}
void Init(void)
{
//-------- seriell interface programmed in boot routine and already running -------
// prepare 36kHz for IR - Communication
TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);
OCR2 = 0x6E; // 36kHz @8MHz
TIMSK |= (1 << OCIE2); // 36kHz counter for sleep
// prepare RS232
UCSRA = 0x00;
UCSRB = 0x00;
UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
UBRRL = 0xCF; // 2400bps @ 8.00MHz
// I/O Ports
DDRB = (1<<PB3) | (1<<PB0); // OC2 und GreenLED auf Ausgang
DDRD = (1<<PD6) | (1<<PD2) | (1<<PD1); // FrontLED, RedLED und TXD auf Ausgang
sei();
StatusLED(GREEN);
}
Nun wieder zum eigentlichen RC5-Senden. Es tut sich die erste echte Hürde auf: Wie erkenne ich ob RC5 gesendet wird? Ohne einen RC5-Detektor kommt man erstmal nicht weiter. Deshalb hier ein kleines Programm mit dem der asuro RC5-Signale erkennen kann:
Code:
#include "fernbedienunglib.c"
unsigned int count, temp; // Zaehler, IR-Kommando
unsigned char daten[14], ir_status; // IR-datenspeicher, IR-Eingangsegel
int main(void)
{
Init();
FrontLED(ON);
while(1)
{
StatusLED(YELLOW);
temp=0;
count=0;
while (PIND & (1 << PD0)) //warten auf die Flanke des Startbits
StatusLED(RED); // Alarmstufe ROT: ein Zeichen ist im Anflug
for (count=0; count<13; count++) { // im Gesamten warten wir auf 14 bits
Sleep(96); // Information einlesen nach 3/4 der Bitlaenge
ir_status=(PIND & (1 << PD0)); // Pegel Speichern
if (ir_status) daten[count]='1'; else daten[count]='0'; // und merken
if (ir_status) temp |= (1 << (13-count)); // das MSB(=mostsuefikantbit) zuerst
while (ir_status == (PIND & (1 << PD0))); // Bit gelesen, warten auf naechste Flanke
}
temp=temp/2; // Die Info steht in den Bits 1-4
StatusLED(YELLOW); // Daten gelesen
Msleep(1000); // Zeit um der IR-Transceifer ueber den asuro zu bringen
SerWrite("\n\r",2);
//SerWrite(daten,14); // Bitmuster zum PC senden
//SerWrite("-",1);
PrintBin(temp); // erkannte Daten zum PC senden
SerWrite("\n\r",2);
StatusLED(GREEN);
Msleep(1000);
}
return(0);
}
/* uses timer2 (36kHz for IR communication */
/* counts falling and rising edge => 36kHz*2 = 72kHz */
SIGNAL (SIG_OUTPUT_COMPARE2)
{
count72kHz ++;
}
(Aus https://www.roboternetz.de/phpBB2/vi...=287750#287750 btw. kann auch die aktuelle Lib RC5 empfangen)
Nach dem Programmstart startet man das Terminal und hält man den Transceiver über den asuro. Wenn man den IR-Empfänger auf dem asuro nun mit RC5-Signalen anblitzt erhält man in etwa so eine Ausgabe im Terminal:
01000000010
cæãæcÆãÆcÆãÆcÆãæÆœ˜Æ˜
0001101000111100
þþþ
0001001000000001
3ø3ø3øÆxÌf3ø
0001101000000010
cÆãÆcÆãÆcÆãÆ
0001001000000011
ó˜ó˜˜
0001101000000100
þþþ
0001001000000101
†ó†ó†
0001101000000110
cÆÆcÆÆ
0001001000000111
ÆÆxÌfÆ
0001101000001000
cÆ8þcÆþ
0001001000001001
3Æ3Æ
0001101000000000
(Das sind die Tasten 1-0 als IR-Code :)
Immer im Wechsel eine Zeile RC5 per serielle Schnittstelle und die Daten vom asuro. Das Programm reagiert übrigends auf viele IR-Signale, man kann den asuro z.b. auch mit dem Tranceiver anblinken. Viel Spass beim Testen.
Gruß
mic
Lesezeichen