Forum: Mikrocontroller und Digitale Elektronik IRMP Atmega168 Signal wird falsch übergeben?


von Julian T. (Firma: Stuttgart) (livingevil)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich bin neu hier, einigermaßen fachfremd und minimal ausgestattet, 
sprich Atmega168, IR Empfängermodul und China Fernbedienung (NEC).

Wenn ich das Signal direkt mit dem IR Empfänger über die Soundkarte 
auslese sieht es vernünftig aus (Orignial_Signal.png, rechtes Bild). 
Wenn ich das gleiche mit dem Signal mache, welches die CallBack LED 
bekommt, sieht es verfälscht aus, siehe Bild "Call_Back_Signal.png", was 
vermutlich der Grund ist, warum ich keine Reaktion auf einprogrammierte 
Befehle erhalte.

Frage 1: Ist es korrekt, dass die CallBack LED, programmiert nach dem 
Beispiel aus dem Hauptthread, dauerhaft leuchtet, solange kein IR Signal 
empfangen wird?

Frage 2: Woran kann es liegen, dass die Pulsweiten so verfälscht werden? 
Kann das an F_Cpu liegen oder ist das ein Hardware-Problem?


sorry das erste Bild ist falsch

: Verschoben durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Julian Tauscher schrieb:

> Wenn ich das gleiche mit dem Signal mache, welches die CallBack LED
> bekommt, sieht es verfälscht aus,

Da das Signal mit 15kHz gescannt wird, ist das Ergebnis, welches Du über 
die Callback-Funktion erhältst, naturgemäß etwas verfälscht. Bei Dir ist 
das aber schon erheblich - vermuteter Grund: Siehe unten.

Trotzdem würde ich auf den Output keinen großen Wert legen. Die 
Callback-Funktion ist eher dafür gedacht, zu signalisieren, ob überhaupt 
ein Signal detektiert wird.

> Frage 2: Woran kann es liegen, dass die Pulsweiten so verfälscht werden?
> Kann das an F_Cpu liegen oder ist das ein Hardware-Problem?

Ich tippe darauf, dass Dein ATmega nur mit 1 MHz statt 8 MHz läuft. 
Prüfe mal bitte die CKDIV8-Fuse, welche den Takt nochmal durch 8 teilt. 
Bei einem Takt von 1MHz ist die Abtastrate auch nur noch ein Achtel, 
also 1875 Hz. Das würde auch das schlechte Muster der Callback-LED 
erklären.

Wenn es daran nicht liegt, zeige bitte mal irmpconfig.h.

von Julian T. (Firma: Stuttgart) (livingevil)



Lesenswert?

Sorry für die Verspätung, habe an den Fuses rumprobiert und den int. 
128kHz Osc. aktiviert...hat ne ganze Weile gedauert bis ich wieder bei 
8MHz angekommen bin (Klassiker) ;)

Dein Tipp mit der CKDIV8-Fuse war Gold wert: Was ich nun erreicht habe, 
ist im Grunde das Input Signal 1:1 über die CallBack Funktion wieder 
auszugeben (hab hier einige IR Dioden rumliegen). Dafür habe ich dein 
CallBack Beispiel invertiert, sprich die Callback-IR Diode geht bei 
jedem High-Pegel am Input 'an', statt wie bisher 'aus'.

Was ich jedoch nicht schaffe, eine simple Funktion (LED an, wenn IR 
Befehl erkannt) zu starten. Ich habe wie folgt versucht, meine Funktion 
in die main.c einzubauen:
1
if (irmp_data.protocol == IRMP_NEC_PROTOCOL &&  irmp_data.address == 0xFF)
2
3
switch (irmp_data.command)
4
     {
5
       case 0xFD02: key1_pressed(); break;  
6
     }
7
void key1_pressed() 
8
     {
9
    DDRD=0xFF;
10
    PORTD=0b10000000;
11
     _delay_ms(1000);
12
    PORTD=0b00000000;
13
     _delay_ms(1000);
14
     }

Wie viel kann man dabei falsch machen? Hast du vielleicht ein simples 
Bsp., das gewiss funktioniert und auf das ich dann Schritt für Schritt 
aufbauen kann?

Vielen Dank für deine Mühen!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Wie kommst Du auf die Adresse 0xFF?
Wie kommst Du auf das Kommando 0xFD02?
Wo hast Du die Werte her?

Dein Beispielcode sieht - soweit es der Auszug erlaubt - okay aus. Du 
solltest Dich dem Ziel schrittweise nähern.

Erstmal:
1
if (irmp_data.protocol == IRMP_NEC_PROTOCOL)
2
{
3
    key1_pressed();
4
}

Wenn das klappt, weiter einengen:
1
if (irmp_data.protocol == IRMP_NEC_PROTOCOL && irmp_data.address == 0xFF)
2
{
3
    key1_pressed();
4
}

Als letztes dann:
1
if (irmp_data.protocol == IRMP_NEC_PROTOCOL && irmp_data.address == 0xFF)
2
{
3
    if (irmp_data.command == 0xFD02)
4
    {
5
        key1_pressed();
6
    }
7
}

> Wie viel kann man dabei falsch machen?

In C kann man eine Menge falsch machen ;-)

> Hast du vielleicht ein simples
> Bsp., das gewiss funktioniert und auf das ich dann Schritt für Schritt
> aufbauen kann?

Hast Du Dir das Beispiel-main.c mal angeschaut?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ich bin mir ziemlich sicher, dass diese FB als Adresse nicht 0x00FF, 
sondern 0xFF00 verwendet. Hast Du die Werte vielleicht aus irgendwelchen 
Lirc-Tabellen? Lirc beachtet nicht, dass beim NEC-Protokoll die Werte 
als LSB gesendet werden, Lirc berechnet die Codes immwer mittels MSB, 
was hier aber falsch ist.

Besser ist es, Du gibst die empfangenen Codes auf UART oder LCD aus. 
Dann kannst Du sie auch wieder im C-Code verwenden. Die nächste Stufe 
wäre dann, die FB anzulernen und die Codes im EEPROM zu speichern. Dann 
brauchst Du die konkreten Werte überhaupt nicht zu wissen.

von Julian T. (Firma: Stuttgart) (livingevil)


Lesenswert?

> Wie kommst Du auf die Adresse 0xFF?
> Wie kommst Du auf das Kommando 0xFD02?
> Wo hast Du die Werte her?

Ich habe beides manuell "analog" mit Hilfe der Soundkarte ausgelesen, da 
ich über kein UART etc verfüge. Ich hatte im ersten Post Bilder 
angehängt, davon zeigt das Bild ganz rechts beispielsweise die Adresse 
00000000 11111111 und ergibt doch mit der Beachtung NEC und LSB -> FF00 
und auf diese Weise auch das Kommando. Keine Sorge, ich habe 
sicherheitshalber alle Kombinationen (byteweise) durchprobiert.


> Hast Du Dir das Beispiel-main.c mal angeschaut?

Ich kenne nur eine main.c, keine Beispiel-main.c oder meinst du das 
Beispiel IN main.c? Ich werde heute Abend nochmal probieren, mich mit 
deiner Schritt-für-Schritt Methode ranzutasten.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Julian Tauscher schrieb:
> Keine Sorge, ich habe
> sicherheitshalber alle Kombinationen (byteweise) durchprobiert.

Der oben angegebene Kommando-Code FD02 ist definitiv falsch.

NEC kennt nur 8 Bit als Kommando. Die zweiten 8 Bit sind nur ein 
Komplementärwert zu den ersten. Folglich gibt IRMP auch nur einen 
8-Bit-Wert zurück - nach Prüfung, ob die zweiten 8 Bit komplementär zu 
den ersten 8-Bit sind.

> Ich kenne nur eine main.c, keine Beispiel-main.c oder meinst du das
> Beispiel IN main.c?

Ja, ich meinte das Beispiel in main.c. Das einfachste ist nämlich, den 
von IRMP ermittelten Code (Protokoll, Adresse, Kommando) auf dem UART 
auszugeben. Genau das macht das beispielhafte main.c, sprich 
Beispiel-main.c. Du brauchst also nur einen UART_zu_USB-Adapter an den 
ATmega anzuschließen und Dir werden sämtliche Werte direkt in einer 
Terminal-Emulation bei 9600/8/N ausgegeben, fertig.

> Ich werde heute Abend nochmal probieren, mich mit
> deiner Schritt-für-Schritt Methode ranzutasten.

Warum so umständlich mit einer LED? Okay, Du kannst Adresse und 
Kommando-Code auch morsen ;-)

von Julian T. (Firma: Stuttgart) (livingevil)


Lesenswert?

Im Moment schaffe ich es nicht einmal, dass das Protokoll
1
if (irmp_data.protocol == IRMP_NEC_PROTOCOL)

erkannt wird. Die Callbackfunktion sagt mir aber, dass das Signal 
richtig ankommt, da es ja 1:1 wieder ausgegeben wird. Ich habe das 
Gefühl, dass ich in der main.c noch etwas verbockt habe, aber ich komm 
nicht drauf wie. Dein Beispiel war nicht explizit in dem Code-Bereich, 
der für die AVRs gedacht ist deklariert, sondern weiter unten...von dort 
habe ich mir den kopiert. Aber daran kanns eigentlich nicht liegen - ist 
ja der gleiche code, wie du mir oben als Bsp. gegeben hast. Hast du 
vielleicht noch eine Idee woran es liegen kann?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Das main.c im IRMP-Paket ist auch hier zu sehen:

   http://www.mikrocontroller.net/svnbrowser/irmp/main.c?view=markup

Lass Dich nicht verwirren, dass da auch Code für PIC & STM32 drin ist, 
der wird von Deinem Compiler ignoriert.

Schließe einen USB->UART-Wandler an RX/TX vom ATmega an, z.B. diesen:

  http://shop.myavr.de/systemboards%20and%20programmer/myUSBtoUART.htm?sp=article.sp.php&artID=200024

Beachte: RX -> TX und TX -> RX

Dann sollten die empfangenen Codes direkt ausgegeben werden.

Ansonsten: Zeige mal Deine main.c.

von Julian T. (Firma: Stuttgart) (livingevil)


Lesenswert?

Servus, ich habe das Gefühl, das etwas grundliegends falsch ist. Denn 
unabh. von den Kommandos, sollte das Programm wenigstens die Codierung 
(NEC etc.) erkennen. Daher mal die main.c wie folgt, mit der Bitte an 
Dich, ob dir etwas auffällt:
1
#include "irmp.h"
2
 #define F_CPU 8000000UL
3
#ifndef F_CPU
4
#error F_CPU unkown
5
#endif
6
7
/*---------------------------------------------------------------------------------------------------------------------------------------------------
8
 * ATMEL AVR part:
9
 *---------------------------------------------------------------------------------------------------------------------------------------------------
10
 */
11
#if defined (ATMEL_AVR)
12
13
  #define LED_PORT PORTD                                  // LED at PD6
14
  #define LED_DDR  DDRD
15
  #define LED_PIN  6
16
17
18
#include "irmp.h"
19
#define BAUD  9600L
20
#include <util/setbaud.h>
21
22
#ifdef UBRR0H
23
24
#define UART0_UBRRH                             UBRR0H
25
#define UART0_UBRRL                             UBRR0L
26
#define UART0_UCSRA                             UCSR0A
27
#define UART0_UCSRB                             UCSR0B
28
#define UART0_UCSRC                             UCSR0C
29
#define UART0_UDRE_BIT_VALUE                    (1<<UDRE0)
30
#define UART0_UCSZ1_BIT_VALUE                   (1<<UCSZ01)
31
#define UART0_UCSZ0_BIT_VALUE                   (1<<UCSZ00)
32
#ifdef URSEL0
33
#define UART0_URSEL_BIT_VALUE                   (1<<URSEL0)
34
#else
35
#define UART0_URSEL_BIT_VALUE                   (0)
36
#endif
37
#define UART0_TXEN_BIT_VALUE                    (1<<TXEN0)
38
#define UART0_UDR                               UDR0
39
#define UART0_U2X                               U2X0
40
        
41
#else
42
43
#define UART0_UBRRH                             UBRRH
44
#define UART0_UBRRL                             UBRRL
45
#define UART0_UCSRA                             UCSRA
46
#define UART0_UCSRB                             UCSRB
47
#define UART0_UCSRC                             UCSRC
48
#define UART0_UDRE_BIT_VALUE                    (1<<UDRE)
49
#define UART0_UCSZ1_BIT_VALUE                   (1<<UCSZ1)
50
#define UART0_UCSZ0_BIT_VALUE                   (1<<UCSZ0)
51
#ifdef URSEL
52
#define UART0_URSEL_BIT_VALUE                   (1<<URSEL)
53
#else
54
#define UART0_URSEL_BIT_VALUE                   (0)
55
#endif
56
#define UART0_TXEN_BIT_VALUE                    (1<<TXEN)
57
#define UART0_UDR                               UDR
58
#define UART0_U2X                               U2X
59
60
#endif //UBRR0H
61
62
static void
63
uart_init (void)
64
{
65
    UART0_UBRRH = UBRRH_VALUE;                                                                      // set baud rate
66
    UART0_UBRRL = UBRRL_VALUE;
67
68
#if USE_2X
69
    UART0_UCSRA |= (1<<UART0_U2X);
70
#else
71
    UART0_UCSRA &= ~(1<<UART0_U2X);
72
#endif
73
74
    UART0_UCSRC = UART0_UCSZ1_BIT_VALUE | UART0_UCSZ0_BIT_VALUE | UART0_URSEL_BIT_VALUE;
75
    UART0_UCSRB |= UART0_TXEN_BIT_VALUE;                                                            // enable UART TX
76
}
77
78
static void
79
uart_putc (unsigned char ch)
80
{
81
    while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE))
82
    {
83
        ;
84
    }
85
86
    UART0_UDR = ch;
87
}
88
89
static void
90
uart_puts (char * s)
91
{
92
    while (*s)
93
    {
94
        uart_putc (*s);
95
        s++;
96
    }
97
}
98
99
static void
100
uart_puts_P (PGM_P s)
101
{
102
    uint8_t ch;
103
104
    while ((ch = pgm_read_byte(s)) != '\0')
105
    {
106
        uart_putc (ch);
107
        s++;
108
    }
109
}
110
111
static uint8_t
112
itox (uint8_t val)
113
{
114
    uint8_t rtc;
115
116
    val &= 0x0F;
117
118
    if (val <= 9)
119
    {
120
        rtc = val + '0';
121
    }
122
    else
123
    {
124
        rtc = val - 10 + 'A';
125
    }
126
    return (rtc);
127
}
128
129
static void
130
itoxx (char * xx, unsigned char i)
131
{
132
    *xx++ = itox (i >> 4);
133
    *xx++ = itox (i & 0x0F);
134
    *xx = '\0';
135
}
136
137
static void
138
timer1_init (void)
139
{
140
#if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__)                // ATtiny45 / ATtiny85:
141
142
#if F_CPU >= 16000000L
143
    OCR1C   =  (F_CPU / F_INTERRUPTS / 8) - 1;                              // compare value: 1/15000 of CPU frequency, presc = 8
144
    TCCR1   = (1 << CTC1) | (1 << CS12);                                    // switch CTC Mode on, set prescaler to 8
145
#else
146
    OCR1C   =  (F_CPU / F_INTERRUPTS / 4) - 1;                              // compare value: 1/15000 of CPU frequency, presc = 4
147
    TCCR1   = (1 << CTC1) | (1 << CS11) | (1 << CS10);                      // switch CTC Mode on, set prescaler to 4
148
#endif
149
150
#else                                                                       // ATmegaXX:
151
    OCR1A   =  (F_CPU / F_INTERRUPTS) - 1;                                  // compare value: 1/15000 of CPU frequency
152
    TCCR1B  = (1 << WGM12) | (1 << CS10);                                   // switch CTC Mode on, set prescaler to 1
153
#endif
154
155
#ifdef TIMSK1
156
    TIMSK1  = 1 << OCIE1A;                                                  // OCIE1A: Interrupt by timer compare
157
#else
158
    TIMSK   = 1 << OCIE1A;                                                  // OCIE1A: Interrupt by timer compare
159
#endif
160
}
161
162
#ifdef TIM1_COMPA_vect                                                      // ATtiny84
163
#define COMPA_VECT  TIM1_COMPA_vect
164
#else
165
#define COMPA_VECT  TIMER1_COMPA_vect                                       // ATmega
166
#endif
167
168
ISR(COMPA_VECT)                                                             // Timer1 output compare A interrupt service routine, called every 1/15000 sec
169
{
170
  (void) irmp_ISR();                                                        // call irmp ISR
171
  // call other timer interrupt routines...
172
}
173
174
 
175
/*-----------------------------------------------------------------------------------------------------------------------
176
 * Called (back) from IRMP module
177
 * This example switches a LED (which is connected to Vcc)
178
 *-----------------------------------------------------------------------------------------------------------------------
179
 */
180
void
181
led_callback (uint8_t on)
182
{
183
    if (on)
184
    {
185
         LED_PORT &= ~ (1 << LED_PIN);
186
       }
187
       else
188
       {
189
   
190
     LED_PORT |=(1 << LED_PIN);
191
    }
192
}
193
/*-----------------------------------------------------------------------------------------------------------------------*/
194
195
int main (void)
196
{  
197
198
  
199
    IRMP_DATA   irmp_data;
200
    char        buf[3];
201
  
202
   if (irmp_get_data (&irmp_data))
203
   {
204
     if (irmp_data.protocol == IRMP_NEC_PROTOCOL ||IRMP_NEC42_PROTOCOL || IRMP_NEC16_PROTOCOL)   // NEC-Protokoll && Adresse 0x1234                
205
     {
206
       
207
      DDRD=0xFF;
208
      
209
       PORTD=0b10000000;  //Blinke, wenn du was erkennst...
210
       _delay_ms(1000);
211
       PORTD=0b00000000;
212
       _delay_ms(1000);
213
       
214
       
215
//        switch (irmp_data.command)
216
//        {
217
//          case 0x0001: key1_pressed(); break;          // Taste 1
218
//          case 0x0002: key2_pressed(); break;          // Taste 2
219
//          ...
220
//          case 0x0009: key9_pressed(); break;          // Taste 9
221
//        }
222
     }
223
   }
224
225
    irmp_init();                                                            // initialize irmp
226
    
227
  LED_DDR |= (1 << LED_PIN);                // LED pin to output
228
  LED_PORT |= (1 << LED_PIN);                // switch LED off (active low)
229
  irmp_set_callback_ptr (led_callback);
230
  
231
  timer1_init();                                                          // initialize timer1
232
    uart_init();                                                            // initialize uart
233
234
    sei ();                                                                 // enable interrupts
235
236
    for (;;)
237
    {
238
        if (irmp_get_data (&irmp_data))
239
        {
240
            uart_puts_P (PSTR("protocol: 0x"));
241
            itoxx (buf, irmp_data.protocol);
242
            uart_puts (buf);
243
244
#if IRMP_PROTOCOL_NAMES == 1
245
            uart_puts_P (PSTR("   "));
246
            uart_puts_P (pgm_read_word (&(irmp_protocol_names[irmp_data.protocol])));
247
#endif
248
249
            uart_puts_P (PSTR("   address: 0x"));
250
            itoxx (buf, irmp_data.address >> 8);
251
            uart_puts (buf);
252
            itoxx (buf, irmp_data.address & 0xFF);
253
            uart_puts (buf);
254
255
            uart_puts_P (PSTR("   command: 0x"));
256
            itoxx (buf, irmp_data.command >> 8);
257
            uart_puts (buf);
258
            itoxx (buf, irmp_data.command & 0xFF);
259
            uart_puts (buf);
260
261
            uart_puts_P (PSTR("   flags: 0x"));
262
            itoxx (buf, irmp_data.flags);
263
            uart_puts (buf);
264
265
            uart_puts_P (PSTR("\r\n"));
266
        }
267
    }
268
}
269
270
/*---------------------------------------------------------------------------------------------------------------------------------------------------
271
 * LM4F120 Launchpad (ARM Cortex M4):
272
 *---------------------------------------------------------------------------------------------------------------------------------------------------
273
 */
274
#elif defined(STELLARIS_ARM_CORTEX_M4)
275
276
void
277
timer1_init (void)
278
{
279
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
280
    TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER);
281
282
    TimerLoadSet(TIMER1_BASE, TIMER_A, (F_CPU / F_INTERRUPTS) -1);
283
    IntEnable(INT_TIMER1A);
284
    TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
285
    TimerEnable(TIMER1_BASE, TIMER_A);
286
    // Important: Timer1IntHandler has to be configured in startup_ccs.c !
287
}
288
289
void
290
Timer1IntHandler(void)                                                      // Timer1 Interrupt Handler
291
{
292
  (void) irmp_ISR();                                                        // call irmp ISR
293
  // call other timer interrupt routines...
294
}
295
296
int
297
main (void)
298
{
299
    IRMP_DATA irmp_data;
300
301
    ROM_FPUEnable();
302
    ROM_FPUStackingEnable();
303
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
304
305
    irmp_init();                                                            // initialize irmp
306
    timer1_init();                                                          // initialize timer1
307
    sei ();                                                                 // enable interrupts
308
309
    for (;;)
310
    {
311
        if (irmp_get_data (&irmp_data))
312
        {
313
            // ir signal decoded, do something here...
314
            // irmp_data.protocol is the protocol, see irmp.h
315
            // irmp_data.address is the address/manufacturer code of ir sender
316
            // irmp_data.command is the command code
317
            // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h)
318
        }
319
    }
320
}
321
322
/*---------------------------------------------------------------------------------------------------------------------------------------------------
323
 * PIC18F4520 with XC8 compiler:
324
 *---------------------------------------------------------------------------------------------------------------------------------------------------
325
 */
326
#elif defined (__XC8)
327
328
#define _XTAL_FREQ  32000000UL                                              // 32MHz clock
329
#define FOSC        _XTAL_FREQ
330
#define FCY         FOSC / 4UL                                              // --> 8MHz
331
332
#define BAUDRATE 19200UL
333
#define BRG (( FCY  16  BAUDRATE ) -1UL)
334
335
#include <stdio.h>
336
#include <stdlib.h>
337
338
int
339
main (void)
340
{
341
    IRMP_DATA irmp_data;
342
343
    irmp_init();                                                            // initialize irmp
344
345
    // infinite loop, interrupts will blink PORTD pins and handle UART communications.
346
    while (1)
347
    {
348
        LATBbits.LATB0 = ~LATBbits.LATB0;
349
350
        if (irmp_get_data (&irmp_data))
351
        {
352
            // ir signal decoded, do something here...
353
            // irmp_data.protocol is the protocol, see irmp.h
354
            // irmp_data.address is the address/manufacturer code of ir sender
355
            // irmp_data.command is the command code
356
            // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h)
357
            printf("proto %d addr %d cmd %d\n", irmp_data.protocol, irmp_data.address, irmp_data.command );
358
        }
359
    }
360
}
361
362
void interrupt high_priority high_isr(void)
363
{
364
    if (TMR2IF)
365
    {
366
        TMR2IF = 0;                                                         // clear Timer 0 interrupt flag
367
        irmp_ISR();
368
    }
369
}
370
371
/*---------------------------------------------------------------------------------------------------------------------------------------------------
372
 * STM32:
373
 *---------------------------------------------------------------------------------------------------------------------------------------------------
374
 */
375
#elif defined(ARM_STM32)
376
377
uint32_t
378
SysCtlClockGet(void)
379
{
380
    RCC_ClocksTypeDef RCC_ClocksStatus;
381
    RCC_GetClocksFreq(&RCC_ClocksStatus);
382
    return RCC_ClocksStatus.SYSCLK_Frequency;
383
}
384
385
void
386
timer2_init (void)
387
{
388
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
389
    NVIC_InitTypeDef NVIC_InitStructure;
390
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
391
392
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
393
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
394
    TIM_TimeBaseStructure.TIM_Period = 7;
395
    TIM_TimeBaseStructure.TIM_Prescaler = ((F_CPU / F_INTERRUPTS)/8) - 1;
396
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
397
398
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
399
400
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
401
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
402
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
403
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
404
    NVIC_Init(&NVIC_InitStructure);
405
406
    TIM_Cmd(TIM2, ENABLE);
407
}
408
409
void
410
TIM2_IRQHandler(void)                                                  // Timer2 Interrupt Handler
411
{
412
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
413
  (void) irmp_ISR();                                                        // call irmp ISR
414
  // call other timer interrupt routines...
415
}
416
417
int
418
main (void)
419
{
420
    IRMP_DATA irmp_data;
421
        
422
    irmp_init();                                                            // initialize irmp
423
    timer2_init();                                                          // initialize timer2
424
425
    for (;;)
426
    {
427
        if (irmp_get_data (&irmp_data))
428
        {
429
            // ir signal decoded, do something here...
430
            // irmp_data.protocol is the protocol, see irmp.h
431
            // irmp_data.address is the address/manufacturer code of ir sender
432
            // irmp_data.command is the command code
433
            // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h)
434
        }
435
    }
436
}
437
#endif

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Julian Tauscher schrieb:
> Servus, ich habe das Gefühl, das etwas grundliegends falsch ist. Denn
> unabh. von den Kommandos, sollte das Programm wenigstens die Codierung
> (NEC etc.) erkennen. Daher mal die main.c wie folgt, mit der Bitte an
> Dich, ob dir etwas auffällt:

Da fällt mir eigentlich nichts besonderes auf, da es mehr oder weniger 
die originale main.c (Beispielcode) aus dem IRMP-Paket ist. Das, was Du 
da vor der Endlossschleife eingefügt hast, wird nur einmal beim 
Programmstart durchlaufen. Ich bezweifle, dass Du mit der Fernbedienung 
so schnell bist.

Und dann hast Du es noch vor irmp_init() eingefügt. Das kann nicht 
klappen.

Ersetze bitte die Funktion main() durch folgenden Code, wenn Du wirklich 
nur eine LED hast und partout nicht bereit bist, am UART einen 
USB-Adapter anzuschließen:
1
int main (void)
2
{  
3
    IRMP_DATA   irmp_data;
4
  
5
    irmp_init();                        // initialize irmp
6
    
7
    LED_DDR |= (1 << LED_PIN);          // LED pin to output
8
    LED_PORT |= (1 << LED_PIN);         // switch LED off (active low)
9
    irmp_set_callback_ptr (led_callback);
10
  
11
    timer1_init();
12
    sei();                              // enable interrupts
13
    DDRD=0xFF;                          // Port D auf Ausgang
14
15
    for (;;)
16
    {
17
        if (irmp_get_data (&irmp_data))
18
        {
19
            if (irmp_data.protocol == IRMP_NEC_PROTOCOL) 
20
            {
21
                PORTD=0b10000000;  //Blinke, wenn du was erkennst...
22
                _delay_ms(1000);
23
                PORTD=0b00000000;
24
                _delay_ms(1000);
25
            }
26
        }
27
    }
28
}

Das hier:
1
if (irmp_data.protocol == IRMP_NEC_PROTOCOL ||IRMP_NEC42_PROTOCOL || IRMP_NEC16_PROTOCOL)

ist übrigens Käse. Das schreibt man so:
1
if (irmp_data.protocol == IRMP_NEC_PROTOCOL || irmp_data.protocol == IRMP_NEC42_PROTOCOL || irmp_data.protocol == IRMP_NEC16_PROTOCOL)

Ich hoffe, dass die LED, die da blinken soll, nicht die Callback-LED 
ist. Sonst schaltet Dir die Callback-Funktion Deine LED sofort wieder 
aus. Sicherheitshalber solltest Du erstmal den Aufruf von

   irmp_set_callback_ptr (led_callback);

auskommentieren.

: Bearbeitet durch Moderator
von Julian T. (Firma: Stuttgart) (livingevil)


Lesenswert?

Servus Frank,

vielen Dank, mit deiner Hilfe habe ich es jetzt hinbekommen (hat etwas 
gedauert hust). Worauf ich stolz bin: ohne UART..also mit einfachsten 
Mitteln (das ist mein Anspruch an mich selbst ;) )

Woran es also lag:

-die main war falsch, mit deinem Vorschlag tut es
-ich wusste nicht, dass als Kommando nur die nicht invertierte Version 
interessiert
-die Reihenfole LSB MSB war genau umgekehrt wie auf der Tabelle, von der 
ich die Codes für meine FB habe. FF00 war btw. die von dir richtig 
vermutete Adresse.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Gratuliere! Viel Spaß noch mit IRMP :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.