Forum: Projekte & Code IRMP - Infrared Multi Protocol Decoder


von eku (Gast)


Lesenswert?

Hallo Frank,

ich inkludiere die IRMP Sourcen in ein Hauptprogramm, damit der Compiler 
besser optieren kann. Seit der Implementierung des ROOMBA Protokolls 
erhalte ich folgende Warnungen:

irsnd.c:366:0: warning: "ROOMBA_1_PAUSE_LEN" redefined [enabled by 
default]
 #define ROOMBA_1_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS 
* ROOMBA_1_PAUSE_TIME + 0.5)
 ^
irmp.c:412:0: note: this is the location of the previous definition
 #define ROOMBA_1_PAUSE_LEN                      ((uint8_t)(F_INTERRUPTS 
* ROOMBA_1_PAUSE_TIME))
 ^
irsnd.c:367:0: warning: "ROOMBA_0_PAUSE_LEN" redefined [enabled by 
default]
 #define ROOMBA_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS 
* ROOMBA_0_PAUSE_TIME + 0.5)
 ^
irmp.c:417:0: note: this is the location of the previous definition
 #define ROOMBA_0_PAUSE_LEN                      ((uint8_t)(F_INTERRUPTS 
* ROOMBA_0_PAUSE_TIME))
 ^

Diese Redefinitions treten nur beim ROOMBA Protokoll auf. Warum befinden 
sich diese nicht in irmpprotocols.h? Kannst Du die 
Namensüberschneidungen bitte lösen.


Gruß, eku

von Moritz Kerner (Gast)


Lesenswert?

Danke vorerst Frank,

>Kannst Du mal Deine irmpconfig.h, irsndconfig.h und Deine ISR
>zeigen? Vielleicht auch noch die main-Funktion...

werde ich dann gerne machen, vorher ändere ich mein Programm aber 
nochmal auf die Ausgabe mittels simpler Toggle-LED, damit ich Störungen 
in der Senderoutine ausschließen kann! Wird aber inkl. der Test's etwas 
dauern, läuft ja nichts davon...

Melde mich wieder & besten Dank, Moritz K.

von Conny G. (conny_g)


Lesenswert?

Hallo Frank,

ich habe folgende Frage zum SIRCS Protokoll - Sony arbeitet doch damit, 
richtig?

Es geht da um einen Sony Home Theater Receiver, den DAV-DZ260. Der hat 
wie viele Geräte keine absolute Lautstärkeneinstellung (wenn's das doch 
gibt als Discretes -her damit!) und so muss ich zum klarstellen des 
Lautstärkelevels auf Null fahren und wieder hoch auf X.
Dazu muss ich also die "Vol Down" Sequenz ca. 35x senden und dann zB 12x 
"Vol Up".

Das habe ich über die IRSND Flags versucht, also data.flags = 4 für 4 
Wiederholungen.
Und seitens des Receivers wird das aber als 1x oder maximal 2x Drücken 
verstanden, ich vermute da ist noch eine Entprell-Logik am Werk.
Mit der Fernbedienung funktioniert das aber wunderbar.

Ohne es noch weiter mit Oszi etc. untersucht zu haben, hast Du da einen 
Tipp wie es geht oder an was es liegt oder ob die einzelnen Geräte sich 
hier verschieden verhalten?

Da gibt's doch die Sache mit dem Toggle-Bit und im Code fand ich 
Hinweise, dass bei SIRCS Repeat erst ab 4 Wiederholungen erkannt wird. 
Muss ich dann für x Wiederholungen ein Repeat von 3+x einstellen? (Hab 
ich auch ausprobiert, hat auch nicht funktioniert). Oder 4 * x?
Aber eigentlich dürfte ich mich ausserhalb von IRSND nicht um das 
kümmern müssen, das sollte gekapselt sein, damit ich ausserhalb das 
Protokoll nicht verstehen muss.

Ich habe mir einstweilen damit beholfen, dass mein uC-basierter Sender 
halt dann eine Schleife mit Wartezeit 200ms durchläuft, das geht ok, ist 
m.E. aber ein Hack.
Einerseits dauert es etwas länger als mit der Fernbedienung die Taste 
gehalten, andererseits riecht es danach, dass andere Geräte sich hier 
anders verhalten könnten.
Deshalb würde ich schon gerne die richtige Lösung finden.

Danke & Grüße,
Konrad

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Konrad,

Konrad G. schrieb:

> ich habe folgende Frage zum SIRCS Protokoll - Sony arbeitet doch damit,
> richtig?

Ja.

> Es geht da um einen Sony Home Theater Receiver, den DAV-DZ260. Der hat
> wie viele Geräte keine absolute Lautstärkeneinstellung (wenn's das doch
> gibt als Discretes -her damit!) und so muss ich zum klarstellen des
> Lautstärkelevels auf Null fahren und wieder hoch auf X.
> Dazu muss ich also die "Vol Down" Sequenz ca. 35x senden und dann zB 12x
> "Vol Up".

Beachte bitte, dass beim Senden nur die unteren 4 Bits von flags für den 
Wiederholungsfaktor genutzt werden. Der maximale Wiederholungsfaktor ist 
also 15. Damit können maximal lediglich 1 + 15 = 16 gleiche Befehle mit 
einem irsnd_send() gesendet werden.

Bei SIRCS speziell ist, dass mindestens 3 Frames gesandt werden, d.h. 
der erste Frame (und nur der erste!) wird automatisch 2x wiederholt - 
eben deshalb, weil SIRCS nichts kürzeres als 3 Frames kennt.

Damit sind es also 1 + 2 + 15 = 19 Frames, die tatsächlich rausgehen, 
wenn Du flags auf 15 setzt.

flags = 0:   3 Frames -> 1 Lautstärkestufe
flags = 1:   4 Frames -> 2 Lautstärkestufen
...
flags = 15: 19 Frames -> 16 Lautstärkestufen

Bei Flags = 15 sollte also die Lautstärke 16 mal höher/niedriger sein 
als vorher. IRSND bildet das damit transparent ab. Die Tatsache, dass 
auch bei kürzestem Tastendruck auf der FB 3 Frames rausgesandt werden, 
was lediglich eine Lautstärkenänderung von 1 Stufe bewirken sollte, ist 
rein intern und muss den Anwender eigentlich nicht kümmern.

> Das habe ich über die IRSND Flags versucht, also data.flags = 4 für 4
> Wiederholungen.

Damit hast Du lediglich eine Änderung von 1 + 4 = 5 Lautstärkestufen.

> Und seitens des Receivers wird das aber als 1x oder maximal 2x Drücken
> verstanden, ich vermute da ist noch eine Entprell-Logik am Werk.
> Mit der Fernbedienung funktioniert das aber wunderbar.

Ich kann mir das nur erklären, dass die Pausen zwischen den Frames beim 
Senden zu kurz sind. Ich habe da mangels SIRCS-FB keine genauen Daten.

Hilfreich wäre daher ein Scan mit IRMP Deiner Fernbedienung:

  - Vol+: Einmal kurz gedrückt (so kurz wie möglich!)
  - Vol+: Einmal lang gedrückt
  - Vol-: Einmal kurz gedrückt (so kurz wie möglich!)
  - Vol-: Einmal lang gedrückt

> Da gibt's doch die Sache mit dem Toggle-Bit und im Code fand ich
> Hinweise, dass bei SIRCS Repeat erst ab 4 Wiederholungen erkannt wird.

SIRCS kennt kein Toggle-Bit. Die Anzahl der Wiederhoungen bei kurz 
gedrückter Taste wurden aus diversen Scans empirisch ermittelt, da die 
Internet-Quellen hier widersprüchlich sind.

> Muss ich dann für x Wiederholungen ein Repeat von 3+x einstellen? (Hab
> ich auch ausprobiert, hat auch nicht funktioniert).

Nein, IRSND sollte den Frame bei flags = 0 insgesamt 3 mal rausschicken, 
wobei die Pause zwischen den Frames ca. 25ms betragen. Bei flags = N 
sollten 3 + N Frames rausgeschickt werden.

Ich habe das unter Linux gerade mal getestet und festgestellt, dass das 
Senden für flags > 1 bei SIRCS fehlerhaft ist. IRSND vergisst dann ab 
dem 3+Nten Frame, eine Pause einzulegen. Die Daten "überstürzen" sich 
also. Das würde auch erklären, warum Dein Gerät nur 1 bis max. 2 
Wiederholungen erkennt.

Ich schaue, dass ich den Fehler kurzfristig behebe und melde mich dann 
nochmal.

Trotzdem wäre ein Scan von Deiner Seite aus ganz hilfreich für mich.

Viele Grüße,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Konrad G. schrieb:

> Ohne es noch weiter mit Oszi etc. untersucht zu haben, hast Du da einen
> Tipp wie es geht oder an was es liegt oder ob die einzelnen Geräte sich
> hier verschieden verhalten?

Hier ein kurzer Bugfix:

Ersetze bitte in irsnd.c
1
   else if (packet_repeat_pause_counter < repeat_frame_pause_len)

durch
1
   if (auto_repetition_counter == 0 && packet_repeat_pause_counter < repeat_frame_pause_len)  // NOT else!

und berichte dann, ob bei Setzen von flags = N genau N+1 
Lautstärkestufen durchlaufen werden.

Gruß,

Frank

von Conny G. (conny_g)


Lesenswert?

Frank,
vielen Dank! Probier ich gg. Ende der Woche!
Vg,
Konrad

von Uwe B. (derexponent)


Lesenswert?

Hi Frank,

erstmal großes LOB von meiner Seite für IRMP und IRSND
...funktioniert super

ich habe beide am STM32F4 Discovery Board am laufen
und da ist mir aufgefallen das im File "irsndconfig.h"
(wenn der Define auf ARM_STM32 gesetzt ist)

der Timer-10 Channel-1 benutzt wird
und als Port-Pin der PA6

beim STM32F4 liegt aber der Timer-10 CH-1 an PB8
somit funktioniert das ganze also nicht
(nach abändern der Defines auf PB8 geht alles wunderbar)

allerdings bin ich nicht sicher ob das jetzt nur beim F4 so ist
und beim F3 (oder F2) event. der PA6 stimmt

nur als "Hinweis" falls da jemand Fehler sucht

Gruss Uwe

von Michael K. (Gast)


Lesenswert?

@ Uwe B.
Ich hatte den Code für einen STM32L1xx angepasst und bei dieser 
Gelegenheit gleich für STM32F1xx und STM32F4xx vorbereitet, allerdings 
ohne ihn auf diesen beiden zu testen. Beim STM32L1xx liegt Timer 10 Ch. 
1 eben an PA6.

Musstest du sonst noch etwas anpassen, oder lief es dann auf Anhieb?

von Uwe B. (derexponent)


Lesenswert?

>Musstest du sonst noch etwas anpassen, oder lief es dann auf Anhieb?

bei IRMP habe ich die UART-Ausgabe für den STM32F4 noch aktiviert
falls "IRMP_LOGGING" enabled wird

ich habe allerdings nicht das File "irmpextlog" dazu benutzt
sondern die UART-Funktionen direkt in "irmp.c" geschrieben

da gibt es ja schon "irmp_uart_init" und "irmp_uart_putc"

ich hab dazu einfach einen Define
dazugeschrieben, das war für mich am einfachsten
1
#if defined(ARM_STM32F4XX)



ansonsten läuft alles wunderbar

Gruss

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Uwe,

Uwe B. schrieb:

> erstmal großes LOB von meiner Seite für IRMP und IRSND
> ...funktioniert super

Danke, freut mich.

> ich habe beide am STM32F4 Discovery Board am laufen
> und da ist mir aufgefallen das im File "irsndconfig.h"
> (wenn der Define auf ARM_STM32 gesetzt ist)
>
> der Timer-10 Channel-1 benutzt wird
> und als Port-Pin der PA6
>
> beim STM32F4 liegt aber der Timer-10 CH-1 an PB8
> somit funktioniert das ganze also nicht
> (nach abändern der Defines auf PB8 geht alles wunderbar)

Okay, dann muss man das für den F4 wohl ändern, wenn ich da jetzt 
Michaels Antwort richtig verstanden habe. Gibt es da eine 
Preprocessor-Konstante, um den F4 vom L1 zu unterscheiden, die man 
abfragen könnte?

Die UART-Anpassung wäre natürlich auch noch interessant für andere 
Anwender. Könntest Du mir Deine Änderungen zuschicken? Meine 
eMail-Adresse findest Du jeweils im Header der Source-Files.

Viele Grüße,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Uwe B. schrieb:

> ich hab dazu einfach einen Define
> dazugeschrieben, das war für mich am einfachsten
>
1
> #if defined(ARM_STM32F4XX)
2
>

D.h. ARM_STM32F4XX ist bei Dir bereits automatisch gesetzt? Und beim F2 
wäre das dann ARM_STM32F2XX und beim L1 dann ARM_STM32L1XX?

Wenn ja, wäre das ja optimal, um die Varianten zu unterscheiden.

Gruß,

Frank

von Uwe B. (derexponent)


Lesenswert?

Hi Frank,

>D.h. ARM_STM32F4XX ist bei Dir bereits automatisch gesetzt?

Ja, die ist gesetzt

die anderen für F1, F2, L1 kann ich nicht verifizieren
(ich vermute aber die funktionieren auch)

den Quellcode für die UART kann ich dir
heut abend zusenden der wäre dann aber auch nur für den F4
weil ich nicht genau weis ob die anderen STM32 an den
gleichen Pins hängen

von Michael K. (Gast)


Lesenswert?

Frank M. schrieb:
> Gibt es da eine Preprocessor-Konstante, um den F4 vom L1 zu
> unterscheiden, die man abfragen könnte?

Siehe irmpsystem.h Zeile 29, 36 und 40.

Ist ein bisschen mit der Kirche ums Dorf: erst auf die zig anderen 
Symbole zu überprüfen (z.B. Zeile 30-33) und dann auch noch ein weiteres 
zu generieren (z.B. ARM_STM32F10X), aber sonst müsste man im Code selber 
immer auf die ganzen Derivate hin überprüfen.

Falls das nicht gefällt, kann es ja entsprechend geändert werden, dann 
fallen die zusätzlichen Symbole weg.

Lässt sich sicher drüber streiten was aus welchen Gründen besser ist.

von m-joy (Gast)


Lesenswert?

Guten Tag,

ich würde den IRMP gerne mit einem PIC32MX795 @ 80Mhz benutzen. Ist dies 
möglich? Welchen Pin sollte ich dafür vorsehen?

Viele Grüße

von m-joy (Gast)


Lesenswert?

Kein PIC experte unterwegs? xD

von Moritz Kerner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Frank,

jetzt sind zwar schon ~4 Monate vergangen, ich hoffe du erinnerst dich 
noch. Es ging um die Umwandlung der B&O-Befehle auf andere Formate 
(Samsung32, RC5).

>Kannst Du mal Deine irmpconfig.h, irsndconfig.h und Deine ISR
>zeigen? Vielleicht auch noch die main-Funktion...

Ich hab mal in der MAIN unnötige Zeilen entfernt (im Prinzip nur einen 
Sendebefehl stehen lassen) und alles als ZIP angehängt.

Ich habe inzwischen durch Versuche rausgefunden, es liegt NICHT am 
Empfang der B&O-Befehle, sondern mit dem Senden hakt es so jedes ~20. 
mal :-/.

Sollte dir im Code etwas auffallen, dann wäre dies genial! Wiederum: 
eilt nicht...

Besten Dank, Moritz K.

von Jing J. (jingjok)


Lesenswert?

IRMP auf PIC und MikroC Pro

Hallo und erstmal vielen Dank an Frank fuer diese grossartige Library.

Ich habe IRMP 2.3.8 (nur den Empfaenger) auf einem PIC 16F1825 zum 
laufen gebracht und habe einige Kommentare / Fragen...

Zuerst zum PIC - ein anderer Forumsbesucher fragte danach – IRMP 
funktioniert bei mir gut mit dem oben genannten PIC, dieser ist wohl der 
kleinte (i.e billigste) PIC auf dem man IRMP zum laufen bekommen kann 
(wenn man weniger Protokolle braucht kann man sogar den 4K PIC 16F1824 
benutzen). Ich habe verschiedene Taktraten ausprobiert und 
herausgefunden, das der PIC mit 32 Mhz betrieben werden muss, sonst 
kommt der neue Interrupt bevor die ISR fertig abgearbeitet ist. Man 
sollte den PIC Timer2 benutzen, da dieser nicht jedes Mal in der ISR neu 
geladen werden muss. Damit ist das Timing einfacher in den Griff zu 
bekommen.

Ich benutzte Mikroe MikroC Pro for PIC Compiler, falls jemand 
interessiert ist hier die notwendigen Aenderungen im IRMP Code fuer 
MikroC :

- Am Anfang von irmp.h habe ich die folgende Zeile zugefuegt, dies setzt 
den Compiler auf CCS, welcher zu MikroC am aehnlichsten ist.
#define _PCH_  // force the CCS compiler

- MikroC kommt mit der folgenden Zeile nicht zurecht :
IRMP_PARAMETER *irmp_param_p = (IRMP_PARAMETER *) 0;
Nach dem Aufsplitten in 2 Zeilen funktioniert es :
IRMP_PARAMETER *irmp_param_p;
irmp_param_p = (IRMP_PARAMETER *) 0;

- MikroC versucht eine Variable heraus zu optimieren, welche 
offensichtlich benoetigt wird, ich habe den Optimisation Level auf 0 
gesetzt, um dies zu vermeiden.

- Die Port definition unter der Zeile
#elif defined (PIC_CCS)
in irmpconfig.h muss auf
#define IRMP_PIN PORTA.B0
(oder irgendeienen anderen Port) geaendert warden

- Die Zeile #include <string.h> in irmpsystem.h muss auskommentiert 
werden, weil string Funktionen automatisch eingebunden werden, dazu 
muessen die Library C_String (und C_Stdlib, C_Type) im Library Manager 
angewaehlt sein.

- Im gleichen File muss die 3. Zeile in dem Block
#if defined(PIC_CCS) || defined(PIC_C18) || defined(ARM_STM32) || 
defined(STELLARIS_ARM_CORTEX_M4)
typedef unsigned char                   uint8_t;
typedef unsigned short                  uint16_t;
#endif
Geandert werden auf :
...
typedef unsigned int                  uint16_t;
...

Frank, wenn Interesse besteht kann ich auch den neuen Code in den 
Original Code mit einer neuen Konstante fuer den MikroC Compiler 
einbauen.

Ich habe noch ein Paar Fragen...
- Wofuer ist die Konstante F_CPU da ? Sie scheint nirgends benutzt zu 
werden.

- Wenn irmp_get_data das allererste Mal aufgerufen wird nach einem 
Reset, gibt es bei mir TRUE zurueck und die Parameter enthalten Garbage. 
Wo koennte das Problem liegen ?

- Ich habe alle meine Fernbedienungen ausprobiert und die meisten 
funtionieren einwandfrei, bis auf meine Samsung Set-Top Box HD-5200C. 
IRMP reagiert ueberhaupt nicht darauf. Kann mir jemand bestaetigen, das 
diese nicht unterstuetzt wird oder ob diese funtionieren sollte und 
meine Codeaenderungen fuer MikroC noch Probleme haben ?

    Vielen Dank !

von jar (Gast)


Lesenswert?

Jing Jok schrieb:
> Ich habe noch ein Paar Fragen...
> - Wofuer ist die Konstante F_CPU da ? Sie scheint nirgends benutzt zu
> werden.

überall im Timer init in Uart usw.

Frank rechnet ja alles auf die Interrupts

in IR_send
#define IRSND_FREQ_32_KHZ                       (uint8_t) ((F_CPU / 
32000 / 2) - 1)
#define IRSND_FREQ_36_KHZ                       (uint8_t) ((F_CPU / 
36000 / 2) - 1)
#define IRSND_FREQ_38_KHZ                       (uint8_t) ((F_CPU / 
38000 / 2) - 1)
#define IRSND_FREQ_40_KHZ                       (uint8_t) ((F_CPU / 
40000 / 2) - 1)
#define IRSND_FREQ_56_KHZ                       (uint8_t) ((F_CPU / 
56000 / 2) - 1)
#define IRSND_FREQ_455_KHZ                      (uint8_t) ((F_CPU / 
455000 / 2) - 1)

in irmpsystem.h
#elif defined(TARGET_IS_BLIZZARD_RA2) 
// TI Stellaris (tested on Stellaris Launchpad with Code Composer 
Studio)
#  define STELLARIS_ARM_CORTEX_M4
#  define F_CPU (SysCtlClockGet())

in irsndmaim.c
#if defined (_AVR_ATtiny45_) || defined (_AVR_ATtiny85_) 
// ATtiny45 / ATtiny85:
    OCR1C   =  (F_CPU  F_INTERRUPTS  4) - 1; 
// compare value: 1/15000 of CPU frequency, presc = 4
    TCCR1   = (1 << CTC1) | (1 << CS11) | (1 << CS10); 
// switch CTC Mode on, set prescaler to 4

von Achill (Gast)


Angehängte Dateien:

Lesenswert?

Ich verwende diese lib mit Atmel Software Framework auf dem evalbord 
xmega-a1 Xplained. Mit Atmel Studio 6.1

Empfang funktioniert gut, mit dem Senden hatte ich aber Probleme.
Wenn jemand das im svn einbauen will, nur zu.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Moritz,

Moritz Kerner schrieb:

> jetzt sind zwar schon ~4 Monate vergangen, ich hoffe du erinnerst dich
> noch. Es ging um die Umwandlung der B&O-Befehle auf andere Formate
> (Samsung32, RC5).

Ja, ich erinnere mich dunkel :-)

> Ich habe inzwischen durch Versuche rausgefunden, es liegt NICHT am
> Empfang der B&O-Befehle, sondern mit dem Senden hakt es so jedes ~20.
> mal :-/.

Jedes 20. Mal? Das ist blöd, denn dann auch schwer nachvollziehbar.

> Sollte dir im Code etwas auffallen, dann wäre dies genial! Wiederum:
> eilt nicht...

Ich schaue es mir mal an und melde mich, sollte ich etwas finden.

Gruß,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Jing Jok schrieb:

> Hallo und erstmal vielen Dank an Frank fuer diese grossartige Library.

Danke fürs Danke :-)

> Frank, wenn Interesse besteht kann ich auch den neuen Code in den
> Original Code mit einer neuen Konstante fuer den MikroC Compiler
> einbauen.

Sehr gerne, denn das wäre optimal. Ich werde dann Deine Änderungen 
wieder zur Verfügung stellen.

> Ich habe noch ein Paar Fragen...
> - Wofuer ist die Konstante F_CPU da ? Sie scheint nirgends benutzt zu
> werden.

Das ist die Taktfrequenz der CPU. Wird (zumindest bei den AVRs) dazu 
benutzt, alle notwendigen Zeitkonstanten (z.B. für den Timer) vom 
Preprocessor ausrechnen zu lassen.

> - Wenn irmp_get_data das allererste Mal aufgerufen wird nach einem
> Reset, gibt es bei mir TRUE zurueck und die Parameter enthalten Garbage.
> Wo koennte das Problem liegen ?

Das hört sich nach nicht initialisierten globalen Variablen an. Ein 
Standard-C-Compiler initialisiert sie alle mit 0. Aber offenbar gibt es 
da einige C-Compiler für µCs, die sich nicht an den Standard halten. 
Daher initialisiere ich sie alle selber.... Habe ich da vielleicht eine 
vergessen?

> - Ich habe alle meine Fernbedienungen ausprobiert und die meisten
> funtionieren einwandfrei, bis auf meine Samsung Set-Top Box HD-5200C.
> IRMP reagiert ueberhaupt nicht darauf. Kann mir jemand bestaetigen, das
> diese nicht unterstuetzt wird oder ob diese funtionieren sollte und
> meine Codeaenderungen fuer MikroC noch Probleme haben ?

Kann ich Dir nicht sagen. Ich bräuchte dafür eine Logging-Datei, schau 
Dir bitte das entsprechende Kapitel im IRMP-Artikel an.

Gruß,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Achill schrieb:
> Ich verwende diese lib mit Atmel Software Framework auf dem evalbord
> xmega-a1 Xplained. Mit Atmel Studio 6.1
>
> Empfang funktioniert gut, mit dem Senden hatte ich aber Probleme.

Hast Du die Probleme lösen können?

> Wenn jemand das im svn einbauen will, nur zu.

Ich schaue es mir gerne an und baue es dann in den IRMP-Source ein. 
Danke sehr!

Gruß,

Frank

von Achill (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Frank,
die Probleme mit dem Senden haben aufgehört als ich wider mit
IRMP_LOGGING                          0
getestet habe.

Auch habe ich hier noch deine lib noch um irthru.h/.c erweitert. Damit 
kann mann ohne Protokollerkennung auf die Sendediode umleiten. Dabei 
wird vor allem Code aus deinen Sourcen verwendet. Auch wird die gleiche 
irmp und irsnd configuration verwendet.
Der Vorteil dabei man spart Code und übertägt auch alle repeats 
automatisch richtig. Die verzögerung des signals wird auch verkleinert.

Bei irmp -> irsnd werden immer die repeats geschluckt, da nach dem 
empfang des ersten telegramm der Empfänger abstellt bis der Sender das 
telegramm ausgegeben hat. (könnte man vieleicht mit zwei alternierenden 
IRMP_DATA verbessern, die verzögerung bleibt aber weiterhin eine 
telegramm länge.)

Wäre schön, wenn noch andere atmel bord Bestizer mit AtmelStudio und der 
kleinen Sende und Empfangs schaltung von meiner ersten Post es mal 
versuchen. Die Versorgungsspannung kann man über USB beziehen der 
Ausgang des tsop modul wird mit einem widerstand auf 3.3V gebracht.

Die neuen Sourcen basiern auf dem letzten svn stand mit meinen 
änderungen,
schau dir die an. (src_with_irthru.zip ist ein update des vorangegagenen 
irmp.zip, auspacken im irmp/src Verzeichniss)

in der datei teminal_output.txt werden zwei FB getestet.

ciao Achill

von Günter X. (kolle)


Lesenswert?

Ich möchte auch meinen Dank für dieses coole Projekt aussprechen.

Als Betreiber eines T+A Verstärker mit Fernbedienung (F2000, ~1995) kam 
der Wunsch auf einen Linux-PC als Tape auch über die RemoteControl 
steuern zu können. (Plan A)

Das Projekt IRMP hat dieses einwandfrei und letzt endlich 'auf Anhieb' 
mit einem ATmega164 gelöst, der LinuxPC hängt seriell am Atmel und als 
Zusatz wird jetzt (Plan B) auch der Kenwood Tuner KT 6050 (~1995) per 
Kabel und XS Systembus gesteuert. (auch hier Danke an für die Infos ;)

Der LinuxPC nimmt die seriellen Codes mit CMD und Counter entgegen und 
steuert damit ein simples script mit einem switch case.
Jedem sinnvollen Befehlsbyte wird ein Programmaufruf zur Steuerung von 
audacious mit Hilfe der audtool gegeben und so läßt sich die 
digitalisierte LP-Sammlung locker vom Sofa steuern :)

Plan C, einen BluRay-Player sammt 8-fach Volumenregler, ist als nächste 
Ausbaustufe in der Mache wobei ich den Player wohl mit echten IR 
versorgen muß, was aber auch kein Thema sein dürfte. (Volumenregler muß, 
IR für BRP kann)

Der ATMega bekommt vom T+A über 3 Klinkenstrippen die IR-Signale für 
TAPE, TUNER oder AUX und steuert abhängig vom Input die serielle, den 
Kenwood XS Bus oder die IRDiode für den Bluray Player und wird die 
notwendigen PGA4311 per SPI bedienen.

Nochmals besten Dank für IRMP

:)


PS:
Ein wichtiger Tip kam aus einer T+A Doku welche darauf verwies das es 
Konflikte mit Grundig-Fernbedienungen geben kann.
IRMP mit GRUNDIG-Protokoll ist T+A

: Bearbeitet durch User
von Stefan V. (vollmars)


Lesenswert?

Hallo,

hat sich hier schon jemand mit der Unterstützung von 
Funksteckdosensender, etc. beschäftigt? Die verwenden ja meistens On-off 
keying, müsste also ohne alzuviel Aufwand unterstützt werden können. Ein 
passender Empfänger wäre der SYN470R, gibts bei ebay als Modul.

Gruß
Stefan

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Stefan V. schrieb:
> hat sich hier schon jemand mit der Unterstützung von
> Funksteckdosensender, etc. beschäftigt?

Nein, ich bisher jedenfalls nicht. Ich benutze selbst keine 
Funktsteckdosen.

> Die verwenden ja meistens On-off keying, müsste also ohne alzuviel
> Aufwand unterstützt werden können.

Ja, was ich bisher hier an Scope-Hardcopies an Funksteckdosensignalen 
gesehen habe, hat mich auch immer an 
Pulse-Distance-Fernbedienungsprotokolle erinnert.

> Ein passender Empfänger wäre der SYN470R, gibts bei ebay als Modul.

Hab mir gerade eins bestellt.

Viele Grüße,

Frank

von Stefan V. (vollmars)


Lesenswert?

Frank M. schrieb:
> Stefan V. schrieb:
>> hat sich hier schon jemand mit der Unterstützung von
>> Funksteckdosensender, etc. beschäftigt?
>
> Nein, ich bisher jedenfalls nicht. Ich benutze selbst keine
> Funktsteckdosen.

Es geht mir auch nicht um die Funksteckdosen, ich denke eher an 
Fernbedienanwendungen in denen IR nicht benutzbar ist.

>> Die verwenden ja meistens On-off keying, müsste also ohne alzuviel
>> Aufwand unterstützt werden können.
>
> Ja, was ich bisher hier an Scope-Hardcopies an Funksteckdosensignalen
> gesehen habe, hat mich auch immer an
> Pulse-Distance-Fernbedienungsprotokolle erinnert.
>
>> Ein passender Empfänger wäre der SYN470R, gibts bei ebay als Modul.
>
> Hab mir gerade eins bestellt.

Super, macht es Sinn wenn ich da auch aktiv werde, ich bin besonders an 
dem Intertechno Protokol interessiert, das ist weit verbreitet und die 
verwenden CR2032 Batterien im Sender, viele andere, z.B. mit 2262 Chip, 
haben so eine exotische 12V Batterie und sind dadurch auch globiger.

Vielen Dank und Grüße
Stefan

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Stefan V. schrieb:
> Super, macht es Sinn wenn ich da auch aktiv werde, ich bin besonders an
> dem Intertechno Protokol interessiert, das ist weit verbreitet und die
> verwenden CR2032 Batterien im Sender, viele andere, z.B. mit 2262 Chip,
> haben so eine exotische 12V Batterie und sind dadurch auch globiger.

Kannst Du das Intertechno-Protokoll mit IRMP-Logging aufzeichnen und mir 
ein paar Scans schicken? Dann kann ich das einbauen.

Ich habe mir bei eBay folgendes bestellt:

  http://www.ebay.com/itm/Wireless-Radio-Superhet-Receiver-Module-433HZ-107dBm-France-IC-SYNOXO-SYN470R-/280909375160

Da ist also auch ein kleiner Sender dabei. Könnte ich dann mit diesem 
per IRSND das Intertechno-Protokoll wieder senden? Sorry für die 
vielleicht dumme Frage, kenne mich mit diesen Funksendern und deren 
Protokollen bisher sehr wenig bis gar nicht aus.

Viele Grüße,

Frank

von Stefan V. (vollmars)


Lesenswert?

Frank M. schrieb:
> Stefan V. schrieb:
>> Super, macht es Sinn wenn ich da auch aktiv werde, ich bin besonders an
>> dem Intertechno Protokol interessiert, das ist weit verbreitet und die
>> verwenden CR2032 Batterien im Sender, viele andere, z.B. mit 2262 Chip,
>> haben so eine exotische 12V Batterie und sind dadurch auch globiger.
>
> Kannst Du das Intertechno-Protokoll mit IRMP-Logging aufzeichnen und mir
> ein paar Scans schicken? Dann kann ich das einbauen.
>
> Ich habe mir bei eBay folgendes bestellt:
>
> 
http://www.ebay.com/itm/Wireless-Radio-Superhet-Receiver-Module-433HZ-107dBm-France-IC-SYNOXO-SYN470R-/280909375160
>
> Da ist also auch ein kleiner Sender dabei. Könnte ich dann mit diesem
> per IRSND das Intertechno-Protokoll wieder senden? Sorry für die
> vielleicht dumme Frage, kenne mich mit diesen Funksendern und deren
> Protokollen bisher sehr wenig bis gar nicht aus.
>
> Viele Grüße,
>
> Frank

Ich bin jetzt auch nicht so bewandert in der Thematik, ich habe eben 
Bedarf an einer Funk Lösung. Das SYN470R Modul habe ich schon hier. Mit 
IRMP habe ich noch keine Erfahrung. Ich mach mich am Wochenende mal 
daran, einen Log zu generieren. Es gibt schon eine Protokollbeschreibung 
hier im Forum:
Beitrag "Re: Intertechno Funksteckdosen per AVR steuern"

Gruß
Stefan

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Stefan V. schrieb:
> Ich mach mich am Wochenende mal daran, einen Log zu generieren.

das wäre prima, siehe dazu auch:

  http://www.mikrocontroller.net/articles/IRMP#Scannen_von_unbekannten_IR-Protokollen

> Es gibt schon eine Protokollbeschreibung hier im Forum:
> Beitrag "Re: Intertechno Funksteckdosen per AVR steuern"

Danke, sehr hilfreich! Neuartig daran ist die Nutzung von Doppelpulsen 
für lediglich 1 Bit gegenüber den Pulse-Distance-Protokollen, die bei 
IR-FBs meist verwendet werden. Aber das ist kein Hindernis, eher eine 
Herausforderung :-)

Ich werde das Protokoll mal parallel zu Deinem Logging in den IRMP 
integrieren. Dann kann ich den Decoder direkt mit Deinen Log-Dateien 
testen. Zusammen bekommen wir das schon hin :-)

von xv (Gast)


Lesenswert?

Hallo,
erstmal vielen Dank für die Entwicklung von IRMP! Ich habe es mal 
ausprobiert und dabei folgendes festgestellt:
Wenn ich Ruwido ausgeschaltet hab, wird meine eine Fernbedienung 
(Technotrend) sauber als RC5 erkannt, eine weitere als NEC (Sherwood) 
und die von meinem Fernseher (Metz) gar nicht.
Wenn ich nun Ruwido einschalte, geht RC5 immer noch problemlos, NEC wird 
in ca. 1/3 der Fälle als Siemens oder Ruwido erkannt, die Metz 
Fernbedienung meistens als Ruwido, aber mit willkürlicher 
Adresse/Kommando.
Da ich auch die Merlin-Tastatur benutzen möchte, brauche ich Ruwido 
(konnte die Tastatur noch nicht testen, da ich kein 56kHz Empfänger 
rumliegen hab).
Der AVR läuft mit Quarz (18,432MHz), ich habe die Intervalle 15000, 
18432 und 20000 ausprobiert, immer das gleiche. Woran liegt das? Ist das 
Ruwido/Siemens Protokoll einfach so beliebig, das Fehlinterpretationen 
nicht zu vermeiden sind, ist die Implementierung in IRMP noch nicht 
ausgereift oder kann ich irgendwas falsch gemacht haben?
Vielen Dank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

xv schrieb:
> Wenn ich nun Ruwido einschalte, geht RC5 immer noch problemlos, NEC wird
> in ca. 1/3 der Fälle als Siemens oder Ruwido erkannt, die Metz
> Fernbedienung meistens als Ruwido, aber mit willkürlicher
> Adresse/Kommando.

Schicke mir bitte Scans von Deinen nicht sauber erkannten FBs. 1-3 
Tasten pro FB sollten reichen. Dann bitte noch Deine irmpconfig.h.

> Woran liegt das? Ist das
> Ruwido/Siemens Protokoll einfach so beliebig, das Fehlinterpretationen
> nicht zu vermeiden sind, ist die Implementierung in IRMP noch nicht
> ausgereift oder kann ich irgendwas falsch gemacht haben?

Es gibt immer da Probleme, wo sich Protokolle bzgl. des Timings ähneln. 
Da die FBs selber Timing-Abweichungen von bis zu 40% haben, ist IRMP 
ziemlich tolerabel - aber mit dem erkauften Nachteil, dass es die 
Wahrscheinlichkeit von Konflikten bei der Erkennung von Protokollen 
erhöht.

Das Ruwido-Protokoll wird nicht oft verwendet. So habe ich da nur wenige 
empirische Daten. Scans von Deinen FBs würden daher helfen, die 
Toleranzgrenzen von IRMP zu optimieren und damit auch das 
Konfliktpotential zwischen den Protokollen.

Viele Grüße,

Frank

von Klaus L. (Gast)


Lesenswert?

Frank M. schrieb: (Funkprotokoll)
> Danke, sehr hilfreich! Neuartig daran ist die Nutzung von Doppelpulsen
> für lediglich 1 Bit gegenüber den Pulse-Distance-Protokollen, die bei
> IR-FBs meist verwendet werden. Aber das ist kein Hindernis, eher eine
> Herausforderung :-)
>
> Ich werde das Protokoll mal parallel zu Deinem Logging in den IRMP
> integrieren. Dann kann ich den Decoder direkt mit Deinen Log-Dateien
> testen. Zusammen bekommen wir das schon hin :-)

Hallo Frank,

oh, wenn ich geahnt hätte das Du auch Funkprotokolle zulässt ;-)
Ein weiterer Kandidat wäre noch FS20, ist ja gut dokumentiert und auch 
z.B. schon in Ethersex implementiert.

Im Gegensatz zu den IR Protokollen, bei denen Störungen, bzw. die 
Trägerfrequenz ja schon beim TSOP rausgefiltert wird, empfangen die 
Funkreceiver ja dauernd Störimpulse, nur die eigentlichen Signale sind 
einigermassen sauber. Wie sieht es denn bei so was mit der Erkennung 
aus? Könnte das klappen?

LG,
Klaus

von Oliver R. (superberti)


Lesenswert?

Hi,

ich wollte Frank nur mal eben meinen herzlichen Dank für die super 
Arbeit an dem IRMP aussprechen!
Ich habe für die Hardware+Software auf meinem Dev-Board gerade mal eine 
Stunde benötigt und dann lief die Sache (Ausgabe auf dem UART) auf 
anhieb!
Toll, jetzt kann die Wandschrank-LED-Beleuchtung mit der 
Fernseher-Fernbedienung geschaltet und gedimmt werden.

Wenn's doch immer so laufen würde ;-)

Also, noch mal besten Dank und viele Grüße.

Oliver

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Oliver R. schrieb:
> ich wollte Frank nur mal eben meinen herzlichen Dank für die super
> Arbeit an dem IRMP aussprechen!

Danke fürs Danke und viel Spaß!

Frank

von Ulli (Gast)


Lesenswert?

Hallo zusammen,

ich nuzte schon begeistert seit längerer Zeit IRMP. Klasse Sache!

Zusätzlich habe ich meine Funkprotokolle wie die Baumarktfunksteckdosen 
(Intertechno) oder FS20 anderweitig integriert.
Ich bin gerade sehr überrascht das sich dies auch in IRMP einbinden 
lässt und wäre auch daran interessiert und könnte euch helfen dies 
umzusetzen, da es bei mir schon läuft, nur eben nicht über IRMP.
(Hier ein kleiner Beitrag über meinen AVR bzw JeeNode inkl. Sourcen
http://forum.fhem.de/index.php/topic,17697.0.html)

Mir stellt sich aber die Frage ob sich IRMP gleichzeitig an zwei Pins 
betreiben lässt? (Für IR und OOK Funksignale)..

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ulli schrieb:

> Zusätzlich habe ich meine Funkprotokolle wie die Baumarktfunksteckdosen
> (Intertechno) oder FS20 anderweitig integriert.
> Ich bin gerade sehr überrascht das sich dies auch in IRMP einbinden
> lässt und wäre auch daran interessiert und könnte euch helfen dies
> umzusetzen, da es bei mir schon läuft, nur eben nicht über IRMP.
> (Hier ein kleiner Beitrag über meinen AVR bzw JeeNode inkl. Sourcen
> http://forum.fhem.de/index.php/topic,17697.0.html)

2 Fragen dazu:

Gibt der Funkempfänger ein Active-Low-Signal aus?

Wenn ja, könntest Du einfach das Funkprotokoll mit IRMP scannen (s. 
Artikel: IRMP_LOGGING) und mir die Scan-Dateien schicken (Beispiele 
siehe IR_Data/*.txt).

Wenn nein, müsstest Du das Macro:

define input(x)                              ((x) & (1 << IRMP_BIT))

ändern in:

define input(x)                              !((x) & (1 << IRMP_BIT))

> Mir stellt sich aber die Frage ob sich IRMP gleichzeitig an zwei Pins
> betreiben lässt? (Für IR und OOK Funksignale)..

Ja, das ginge. Solange nicht zur selben Zeit ein IR-Sender und ein 
Funksender senden. Dann wirds komplizierter. Aber ich glaube, den Fall 
einer Signalkollision können wir vernachlässigen....

Gruß,

Frank

von Karol B. (johnpatcher)


Lesenswert?

Hi,

ich will dir natürlich nicht in "deinem" Wiki-Artikel herum editieren, 
Frank, aber so wie es scheint hast du mittlerweile Version 2.3.10 
veröffentlicht. Das ist im Artikel aber noch nicht aktualisiert. Hat das 
einen Grund?

Mit freundlichen Grüßen,
Karol Babioch

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hi Karol,

Karol Babioch schrieb:
> ich will dir natürlich nicht in "deinem" Wiki-Artikel herum editieren,
> Frank, aber so wie es scheint hast du mittlerweile Version 2.3.10
> veröffentlicht. Das ist im Artikel aber noch nicht aktualisiert. Hat das
> einen Grund?


Ich werde in den nächsten Tagen sowieso ein Update von IRMP rausgeben. 
Dann werde ich den Artikel auch aktualisieren.

Ich hoffe, dass bis dahin Andreas die Kaputt-Formatierung des Artikels 
durch sein neues Website-Layout wieder in Ordnung gebracht hat.

Vielen Dank für den Hinweis,

Frank

von Karol B. (johnpatcher)


Lesenswert?

Hi,

Frank M. schrieb:
> Ich werde in den nächsten Tagen sowieso ein Update von IRMP rausgeben.
> Dann werde ich den Artikel auch aktualisieren.

Ok, vielen Dank für die Antwort.

Darf man dich denn in der Zwischenzeit darauf hinweisen, dass sich die 
jetzige Version mit einer avr-gcc Toolchain nicht ohne Warnung 
kompilieren lässt. Schuld daran ist die Funktion "dummy" in 
"irmpextlog.c", die folgende Warnung auslöst:

> avr-gcc -Wall -Werror -Os -fpack-struct -fshort-enums -ffunction-sections
> -fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields
> -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"src/IRMP/irmpextlog.d"
> -MT"src/IRMP/irmpextlog.d" -c -o "src/IRMP/irmpextlog.o" "../src>
> /IRMP/irmpextlog.c"
> ../src/IRMP/irmpextlog.c:104:1: error: 'dummy' defined but not used
>[-Werror=unused-function]

Damit ist es mir nicht möglich mein Projekt mit -Werror zu kompilieren 
;).

Basierend auf dem Kommentar und der Konditionen aus den anderen Dateien 
schlage ich folgenden Fix vor:
1
#if defined(PIC_C18)
2
static void
3
dummy (void)
4
{
5
  // Only to avoid C18 compiler error
6
}
7
#endif

Das lässt die Warnung bei mir verschwinden, Ob es den gewünschten Effekt 
bei einer C18 Toolchain hat, weiß ich natürlich nicht. Wäre aber schön, 
wenn das in den nächsten Versionen von offizieller Seite aus gefixt 
wird.

Mit freundlichen Grüßen,
Karol Babioch

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


Lesenswert?

Hi Karol,

Karol Babioch schrieb:
> Basierend auf dem Kommentar und der Konditionen aus den anderen Dateien
> schlage ich folgenden Fix vor:
> [...]

Danke, habe ich übernommen. Alternativ dazu hättest Du irmpextlog.c gar 
nicht erst ins AVR-Projekt mit aufnehmen sollen. Bei AVRs ist diese 
Datei nämlich hyperfluid ;-)

Viele Grüße,

Frank

: Bearbeitet durch Moderator
von Dominic A. (neo123)


Lesenswert?

Hallo zusammen,

Ich habe derzeit ein kleines Problem mit der Library. Auf einem dsPIC 
mit dem XC16 Compiler funktioniert alles wunderbar. Grosses Dankeschön 
dafür.

Nun jedoch versuche ich es auf dem XC8 zum laufen zu bringen. Aber ich 
scheitere an den folgenden Makros aus irmp.c Zeile 397:
1
#else
2
#  define ANALYZE_PUTCHAR(a)
3
#  define ANALYZE_ONLY_NORMAL_PUTCHAR(a) 
4
#  define ANALYZE_PRINTF(...) 
5
#  define ANALYZE_ONLY_NORMAL_PRINTF(...) 
6
#  define ANALYZE_NEWLINE()
7
#endif

Ich bekomme immer folgende Fehler Meldung:
1
IRMP/irmp.c:399: error: #define syntax error
2
IRMP/irmp.c:400: error: #define syntax error
3
IRMP/irmp.c:1490: warning: wrong number of preprocessor macro arguments for "ANALYZE_PRINTF" (1 instead of 0)
4
IRMP/irmp.c:1888: warning: wrong number of preprocessor macro arguments for "ANALYZE_PRINTF" (2 instead of 0)
5
...
Das mit den wrong number of preprocessor macro arguments kommt für jede 
Zeile in welcher das Makro gebraucht wird.
Scheinbar funktioniert eine variable Anzahl von Argumenten mit dem XC8 
Compiler nicht.
Hatte dieses Problem auch schon mal jemand?
Ich habe keine andere Methode für den XC8 gefunden um variable Argumente 
zu definieren.

Grüsse

von Karol B. (johnpatcher)


Lesenswert?

Um dir die Suche zu erleichtern: Diese Art von Macros sind als Variadic 
macros bekannt, siehe [1], und fanden erst mit C99 Einzug in den C 
Standard. Der XC8 Compiler, den ich zugegebenermaßen nicht kenne, 
unterstützt dies wohl nicht. Insofern wirst du die Makros in ihrer 
jetzigen Form nicht verwenden können.

Aber, vermutlich willst du das auch gar nicht. Denn die entsprechenden 
Makros werden nur gebraucht, wenn auch das das Makro ANALYZE definiert 
ist. Dieses wiederum wird in "irmpsystem.h" gesetzt - und zwar nur im 
Falle, dass UNIX_OR_WINDOWS gesetzt ist.

Auf deutsch gesagt: Dein Compiler wird von IRMP nicht erkannt und es 
wird davon ausgegangen, dass du die Desktopversion kompilieren möchtest, 
die die entsprechende Analysefunktionalität mitbringt. An dieser bist du 
aber vermutlich nicht interessiert.

Wenn du das Problem "richtig" lösen willst, dann musst du den Compiler 
in der Datei "irmpsystem.h" entsprechend eintragen. Wie sich dieser zu 
erkennen gibt, weiß ich leider nicht, das lässt sich aber i.d.R. im 
Manual finden. Frank würde das sicherlich auch mit Freude übernehmen.

Ansonsten könntest du das natürlich auch noch "Quick-and-dirty" lösen, 
in dem du die Erkennung entfernst bzw. so anpasst, dass keine 
Desktopversion erkannt wird.

Mit freundlichen Grüßen,
Karol Babioch

[1]: https://en.wikipedia.org/wiki/Variadic_macro

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


Lesenswert?

Karol Babioch schrieb:

> Aber, vermutlich willst du das auch gar nicht. Denn die entsprechenden
> Makros werden nur gebraucht, wenn auch das das Makro ANALYZE definiert
> ist. [...]

Deine Vermutung ist leider falsch. Sein Zitat bezieht sich auf den 
#else-Zweig, also wenn kein ANALYZE gesetzt ist. Hier sollen die 
Makros dafür sorgen, dass die entsprechenden ANALYZE_PRINTF-Anweisungen 
im kompletten Code durch "Nichts" ersetzt werden. Der XC8 scheint keine 
Variadic-Macros zu verstehen.

Da gibt es nur zwei Möglichkeiten:

 - Sämtliche ANALYZE-Macros im Source auskommentieren bzw. entfernen
 - Sämtliche ANALYZE-Macros im Source mit #ifdef ANALYZE ... #endif
   "umhüllen".

Blöd, aber ich sehe keine andere Möglichkeit.

Der einfachste Weg ist wohl, mit dem Editor sämtliche Vorkommnisse von

  ANALYZE

durch

  // ANALYZE

zu ersetzen.

: Bearbeitet durch Moderator
von gera (Gast)


Lesenswert?

Hallo,

der XC8 kann im Moment keine Variadic macros.
Den Compiler kann man mit "__XC8" erkennen.
Dann könnte man mit #ifdef um die Analyze Zeilen die dann weglassen.

#ifndef __XC8
...
#endif

Gruß

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

gera schrieb:
> #ifndef __XC8
> ...
> #endif

Dann besser, weil allgemeiner:

#ifdef ANALYZE
...
#endif

Das macht den Source aber leider nicht übersichtlicher, weil das für 
alle Vorkommnisse der ANALYZE-Macros gemacht werden müsste. Deshalb 
werde ich das auch nicht in den Standard-Source übernehmen.

Die einfachste Möglichkeit für Dominic ist es, einfach die Textersetzung

  ANALYZE -> // ANALYZE

im Editor durchzuführen.

von gera (Gast)


Lesenswert?

Hast recht.
Man kann ja noch hoffen, dass der XC8 mal diese Macros kann :-)

von Dominic A. (neo123)


Lesenswert?

Alles klar,
Ich habe nun alle ANALYZE Makros auskommentiert.
Jedoch musst ich doch alle von Hand kommentieren da die meisten 
Mehrzeilig sind und somit nur eine Zeile auskommentiert wird.
Nun funktioniert es jedoch ohne Probleme.

Vielen Dank für eure Hilfe.

Grüsse

von Vilex (Gast)


Lesenswert?

Hallo,

kennt jemand eventuell eine bezugsquelle für eine fernbedienung + 
empfänger und im optimalsten fall noch mit angepassten sourcecode :D

hätte 
http://www.ebay.com/itm/Arduino-Infrared-IR-wireless-remote-control-kit-for-Arduino-PIC-AVR-/130939662157?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item1e7c9caf4d 
gefunden allerdings kein plan ob und wie ich da anfangen sollte!!!


mfg

von Karol B. (johnpatcher)


Lesenswert?

Hi,

Vilex schrieb:
> kennt jemand eventuell eine bezugsquelle für eine fernbedienung +
> empfänger und im optimalsten fall noch mit angepassten sourcecode :D

Und was soll "angepasster" Sourcecode heißen? Überhaupt erschließt sich 
mir der Sinn eines solchen Aufbaus nicht so ganz, weil ein IR-Empfänger 
ja nur dort Sinn macht, wo etwas gesteuert werden soll. Und da gibt es 
i.d.R. doch schon einen Mikrocontroller. Mehr als einen IR-Empfänger für 
einige Cent und einen freien Pin (einschließlich ein bisschen 
Rechenzeit) braucht man doch nicht.

Mit freundlichen Grüßen,
Karol Babioch

von Vilex (Gast)


Lesenswert?

ok ich habe glaub ich meine frage etwas schlecht gestellt.

also ich würde gerne zu  meiner steuerung diese IRMP auch einbauen damit 
ich mit fernbedinung steuern kann.
allerdings besitze ich keine fernbedienung und keinen IRMP empfänger, 
also wo am besten kaufen?  und noch besser wärs wenns keine allzu 
exotische ferndbedienuung wär slndern was bewährtes was gleich auf 
anhieb funktioniert!

von Karol B. (johnpatcher)


Lesenswert?

Hi,

Vilex schrieb:
> allerdings besitze ich keine fernbedienung und keinen IRMP empfänger,
> also wo am besten kaufen?

Naja, dann solltest du dich zunächst einmal damit auseinander setzen was 
genau IRMP eigentlich ist. Dabei handelt es sich nämlich um eine 
Bibliothek, welche im Prinzip fast alle verbreiteten IR-Protokolle 
dekodieren kann. Und du benötigst keinen "IRMP"-Empfänger, sondern einen 
typischen IR-Empfänger von der Stange, z.B. einen TSOP 31238 [1].

Alle weiteren Details findest du hier [2].

Mit freundlichen Grüßen,
Karol Babioch

[1]: 
https://secure.reichelt.de/Fotodioden-etc-/TSOP-31238/3//index.html?ACTION=3&GROUPID=3045&ARTICLE=107210
[2]: https://www.mikrocontroller.net/articles/IRMP

von jar (Gast)


Lesenswert?

Vilex schrieb:
> allerdings besitze ich keine fernbedienung

wie geht das, ich habe mindestes 15 Fernbedienungen und alle kennt IRMP.

Ich dachte jeder hat mehr als eine Fernbedienung und evt. auch von 
ausgemusterten Geräten, die wären doch ideal.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Es gibt eine neue Version von IRMP & IRSND im SVN bzw. zum Download im 
IRMP-Artikel.

Die wichtigsten Änderungen:

IRMP:

  - Fehlerhafte Decodierung des SIEMENS-Protokolls korrigiert
  - Neue Protokolle: RCMM32, RCMM24 und RCMM12
  - Timing für ROOMBA verbessert

IRSND:

  - Neues Protokoll: RUWIDO

Viel Spaß mit IRMP!

Gruß,

Frank

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Es gibt eine neue Version von IRMP & IRSND im SVN

Klasse und Danke !

eine (zwei) doofe Frage(n) habe ich noch, ich habe schon gesucht finde 
es aber nicht,

gibt es max und min Grenzen für F_CPU ? ich möchte einen festen IR 
Tester bauen, aber möglichst stromsparen, also F_CPU so gering wie 
möglich.

Aber trotzdem sollen alle Protokolle erkennbar sein, ist es jetzt 
möglich ohne "Fehlinterpretationen" alle Protokolle zu enabeln ? (ich 
erinnere mich an Anfangsschwierigkeiten wo du bemerktest nur die 
einzuschalten die wirklich gebraucht werden)

vielen Dank
LG jar

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:

> gibt es max und min Grenzen für F_CPU ?

Ab 8MHz bist Du auf der sicheren Seite. Nach oben hin gibt es erstmal 
keine Einschränkung.

Wenn es ein Tester werden soll, kannst Du die CPU ja mit einem Taster 
aufwecken. Anschließend schaltet der µC dann den TSOP ein - der 
verbraucht nämlich am meisten Strom.

Siehe dazu auch:

http://www.mikrocontroller.net/articles/DIY_Lernf%C3%A4hige_Fernbedienung_mit_IRMP

Gruß,

Frank

: Bearbeitet durch Moderator
von jar (Gast)


Lesenswert?

Frank M. schrieb:
> Ab 8MHz bist Du auf der sicheren Seite. Nach oben hin gibt es erstmal
> keine Einschränkung.

OK dachte ich mir, reicht der interne Clock oder besser Quarz ?

> Wenn es ein Tester werden soll, kannst Du die CPU ja mit einem Taster
> aufwecken. Anschließend schaltet der µC dann den TSOP ein - der
> verbraucht nämlich am meisten Strom.

da bin ich platt, der braucht doch nur µA, aber den direkt aus einem 
Port speisen und Abschalten ist ja keine Hürde :-)

danke

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

jar schrieb:
> OK dachte ich mir, reicht der interne Clock oder besser Quarz ?

Für IRMP reicht die interne Clock, bei IRSND wäre ein Quarz ratsam, weil 
einige Hersteller ziemlich "untolerant" beim Timing sind.

> da bin ich platt, der braucht doch nur µA, aber den direkt aus einem
> Port speisen und Abschalten ist ja keine Hürde :-)

Ich hab das auf die alte TSOP17xx-Reihe bezogen, denn da bist Du im 
mA-Bereich. Kann aber durchaus sein, dass neuere TSOPs da genügsamer 
sind.

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Ich hab das auf die alte TSOP17xx-Reihe bezogen, denn da bist Du im
> mA-Bereich. Kann aber durchaus sein, dass neuere TSOPs da genügsamer
> sind.

OK sind 3 mA ich meine irgendwo mal was anderes gelesen zu haben oder 
das der bei Ineffektivität in den standby geht. Aber man weiss ja nie ob 
er nicht immer von IR aufgeweckt wird oder von Netz-, Funkstörungen.

von Frank M. (ukw) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ich habe in den letzten Wochen ein neues Projekt begonnen:

Anlernbare IR-Fernsteuerung mit einem netzwerkfähigen Android-Handy über 
WLAN.

Dabei wird ein ATmega328, der mit einem W51000 Ethernet-Contoller 
ausgestattet wird, angesteuert. Mittels TSOP-Empfänger am ATmega können 
Codes angelernt werden und direkt einer Taste in der Android-App 
zugewiesen werden. Sendet die App den IRMP-Code wieder an den ATmega, 
kann dieser per IRSND den Code als Infrarot-Signal wieder aussenden.

Die dafür nötigen Tasten sind in der App frei gestaltbar. Dafür bietet 
die App die Möglichkeit, mehrere Bedienerseiten (für mehrere Geräte) 
anzulegen, um dann dort die nötigen Tasten zu definieren.

Man kann die nötigsten Tasten für mehrere Geräte auch auf eine Seite 
legen, sodass man alles Wichtige "auf einen Blick" hat. Ausserdem können 
mehrere ATmega-Satelliten im Netzwerk angesprochen werden. Einer könnte 
zum Beispiel im Wohnzimmer stehen, ein anderer im Kinderzimmer oder 
Hobbyraum.

Geplant ist noch eine Erweiterung im IRMP/IRSND, dass auch 
Funksteckdosen-Signale angelernt und wiedergegeben werden. Somit lässt 
sich dann alles Erdenkliche im Haushalt per Handy steuern.

Wenn Ihr interessiert seid, kann ich das Projekt gerne in einem neuen 
Artikel vorstellen.

Auf Feedback bin ich mal gespannt :-)

Gruß,

Frank

von Konrad S. (maybee)


Lesenswert?

Frank M. schrieb:
> Wenn Ihr interessiert seid

Aber sicher doch!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Konrad S. schrieb:
> Aber sicher doch!

Jut, ich hab mal mit dem Artikel angefangen: Remote IRMP

Es wird aber noch einige Tage dauern, bis dieser einigermaßen 
vollständig ist ;-)

von Konrad S. (maybee)


Lesenswert?

Frank M. schrieb:
> Jut, ich hab mal mit dem Artikel angefangen: Remote IRMP

Super, danke!

von Michael H. (michael_h45)


Lesenswert?

Frank M. schrieb:
> Wenn Ihr interessiert seid, kann ich das Projekt gerne in einem neuen
> Artikel vorstellen.
>
> Auf Feedback bin ich mal gespannt :-)

Find ich eine super Idee!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

So, der Artikel Remote IRMP ist nun soweit, dass man schon mal damit 
arbeiten kann.

Ich werde in Zukunft die Seite weiter vervollständigen und pflegen.

Viel Spaß!

von Joachim B. (jar)


Lesenswert?

supi ! danke (ich hoffe das hat nix mit dem heutigen Datum zu tun)

PS ob es auch mal möglich wäre den Code in gcc auf den raspberry PI zu 
bringen ?

eigenen Code hatte ich schon mal portiert, aber da blicke ich ja auch 
durch, bei fremden Code ist mir das aber ein wenig zu hoch

: Bearbeitet durch User
von Conny G. (conny_g)


Lesenswert?

Joachim B. schrieb:
> PS ob es auch mal möglich wäre den Code in gcc auf den raspberry PI zu
> bringen ?

Das ist nicht realistisch, aber nicht, weil es vom Code her nicht geht, 
sondern weil man beim Raspberry Pi keine Kontrolle über das Timing hat.
D.h. Timer wie bei den uCs um die es hier geht gibt es nicht und Linux 
ist kein Realtime-Betriebssystem.
Man kann also niemals sicherstellen, dass man eine genaue Abtast- oder 
Sendefrequenz von 38 oder 40 kHz einhält und damit wird das Ganze ein 
sehr mühsames und zufälliges Geschäft.

von Joachim B. (jar)


Lesenswert?

Conny G. schrieb:
> Das ist nicht realistisch, aber nicht, weil es vom Code her nicht geht,
> sondern weil man beim Raspberry Pi keine Kontrolle über das Timing hat.

ich habe ja nur wenig Ahnung, aber was wird denn bei IRMP gemacht mit 
der Konstante Interrupt ?
#  define F_INTERRUPTS                          15000
ein polling mit oversample und dann werden die Zeiten zwischen high und 
low ermittelt

irmp_pulse_time++;

if (((irmp_pulse_time < NIKON_START_BIT_PULSE_LEN_MIN || irmp_pulse_time 
> NIKON_START_BIT_PULSE_LEN_MAX) && irmp_pause_time > IRMP_TIMEOUT_LEN) 
||


einen interrupt kann ich auch am PI auswerten, ok evtl. nicht so stabil, 
aber ich könnte höhere Interrupt wählen, dann wird es evtl. hinreichend 
genau

oder ich polle eben nicht sondern frage wirklich gezielt high und low 
Flanke interrupt getriggert ab....

so denke ich mir das

aber wie gesagt so die Ahnung habe ich nicht

PS lirc auf dem PI funktioniert, warum sollte IRMP nicht ?

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Frank M. schrieb:
> So, der Artikel Remote IRMP ist nun soweit, dass man schon mal damit
> arbeiten kann.

Finde ich sehr spannend.

Macht es Sinn das ganze mit netio von davideickhoff zu kombinieren?

Weil sich im Consumer-Bereich immer die Lösungen duchsetzen, die (bei 
ansonsten vergleichbaren Eigenschaften) um ein paar Cent billiger sind, 
würde ich mein Remote-IRMP gern mit mehreren NRF24L01+ umsetzen.

Aber ich befürchte, dass man dabei wenig aus dem 
Internet-Prtokoll-orientierten Remote IRMP übernehmen kann. Oder wie 
seht Ihr das?

Natürlich wird´s ein Gateway aus dem LAN zu den Mesh-vernetzen NRF24L01+ 
geben. Das kann dan evt. zur o.g. Lösung kompatibel sein.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> PS ob es auch mal möglich wäre den Code in gcc auf den raspberry PI zu
> bringen ?

Sorry, ich vergaß zu erwähnen, dass ich für Remote IRMP einen neuen 
Thread aufgemacht habe.

Ich antworte Dir mal dort: 
Beitrag "Remote IRMP - IR übers Netzwerk"

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Torsten C. schrieb:

> Macht es Sinn das ganze mit netio von davideickhoff zu kombinieren?

Auch auf Deine Fragen antworte ich Dir gern im Nachbar-Thread:

Beitrag "Remote IRMP - IR übers Netzwerk"

von Klaus2 (Gast)


Lesenswert?

Hallo UKW,

vielen Dank für den IRMP - damit bin ich bei meinem eigentlichen Ziel, 
ein altes Radio IR fernbedienbar zu machen innerhalb von nur 20min 
(Downlaod, Config, Breadboardaufbau) ein großes Stück weiter gekommen. 
TOP!

Sieht man auch irgednwo, ob das CMD mehrfach gesendet wurde 
(Dauertastendruck), oder hört da die Bequemlichkeit auf? :)

Danke, Klaus.

von Konrad S. (maybee)


Lesenswert?

Klaus2 schrieb:
> Sieht man auch irgednwo, ob das CMD mehrfach gesendet wurde
> (Dauertastendruck), oder hört da die Bequemlichkeit auf? :)

Alles da:
http://www.mikrocontroller.net/articles/IRMP#.22Entprellen.22_von_Tasten

von Klaus2 (Gast)


Lesenswert?

Hallo zusammen,

das repetition flag bereitet mir Kopfschmerzen.

Also, es wird bereits bei sehr kurzen Tastendrücken ab 100ms (JVC) 
gesetzt, wie soll ich denn "so kurz" die Taste drücken?

Ich muss in shortpress und longpress unterscheiden:

WENN eine Taste gedrückt wurde, warte kurz und entscheide, ob Sie nur 
kurz (dann Operation A) oder länger (dann Operation B) gedrückt wurde.

Operation A darf nicht direkt ausgeführt werden, erst wenn klar ist, was 
vorlag.

Wer kann mir mit Erfahrungswerten helfen?

Klaus.

von Konrad S. (maybee)


Lesenswert?

Das Flag besagt, dass die Fernbedienung den entsprechenden Code als 
Wiederholung gesendet hat, da kann IRMP nichts dafür. Ich habe auch 
mindestens eine Fernbedienung, die sehr schnell mit Wiederholungscodes 
zur Stelle ist.

von Klaus2 (Gast)


Lesenswert?

...ich weiß, das IRMP nichts dafür kann, daher habe ich es selbst 
versucht, aber bis dato noch erfolglos, weil zum Beispiel der Wert in 
command nicht zurückgesetzt wird, obwohl gar keine Taste mehr gedrückt 
ist. Mit meiner üblichen Denke für "echte Tastewn" komme ich grade nicht 
weiter, weil das output struct sich nicht so verhält, wie ich dachte. 
Gut, muss ich noch etwas grübeln - außer mir gibt jmd einen TIP.

Gruß, Klaus.

von Konrad S. (maybee)


Lesenswert?

Klaus2 schrieb:
> command nicht zurückgesetzt

Wovon sprichst du? Im Beispiel
http://www.mikrocontroller.net/articles/IRMP#Anwendung_von_IRMP
wird bei erfolgreichem Aufruf von irmp_get_data() einmalig die 
irmp_data-Struktur ausgewertet. Und das eben in einer Schleife.
1
int main( void )
2
{
3
  IRMP_DATA irmp_data;
4
  ...
5
  while ( 1 ) {
6
    if ( irmp_get_data( &irmp_data ) ) {
7
      if ( irmp_data.protocol == IRMP_NEC_PROTOCOL &&    // NEC-Protokoll
8
          irmp_data.address == 0x1234 )                  // Adresse 0x1234
9
      {
10
         switch ( irmp_data.command ) {
11
            case 0x0001: key1_pressed(); break;          // Taste 1
12
            case 0x0002: key2_pressed(); break;          // Taste 2
13
            ...
14
            case 0x0009: key9_pressed(); break;          // Taste 9
15
         }
16
      }
17
    }
18
  }
19
}

von Klaus2 (Gast)


Lesenswert?

Hallo Konrad,

nicht trivial zu erklären, daher die ganz simple Frage:

Wie würdest du mit der IRMP "API" rasfinden, ob eine Taste kurz (bis 
500ms) oder lang (>500ms) gedrückt wurde.

Kein Code, bitte nur den Gedankenanstoss...

Danke, Klaus.

von Konrad S. (maybee)


Lesenswert?

Ein Timer liefert einen Zeittakt, der etwas langsamer ist als die 
Wiederholrate der Fernbedienung. Am Anfang eines Tastendrucks merkst du 
dir den Zählerstand. Solange der gleiche Tastendruck ankommt, wird 
"Tastendauer"-Zähler hochgezählt. Kommt kein oder ein anderer 
Tastendruck, dann wertest du den "Tastendauer"-Zähler aus, wobei im Fall 
"anderer Tastendruck" dafür die Zeit zu laufen beginnt.

von Conny G. (conny_g)


Lesenswert?

Klaus2 schrieb:
> Wie würdest du mit der IRMP "API" rasfinden, ob eine Taste kurz (bis
> 500ms) oder lang (>500ms) gedrückt wurde.
>
> Kein Code, bitte nur den Gedankenanstoss...

Ungefähr so:

Du merkst Dir immer den letzten erkannten Code in einer Variablen.
Und Du incremetierst in der Interrupt-Routine des Timers einen 
Zeitzähler.

Jedesmal, wenn ein Code erkannt wird:
  Wenn er ungleich dem vorherigen ist:
     Tastegedrückt = 1
     Zeitzähler    = 0
  Wenn er gleich dem vorherigen ist:
     Zeitzähler > 500ms?
        Ja:
           Tastegedrückt = 1
           Zeitzähler = 0
        Nein:
           nichts tun

Einen Fall muss man noch unterbringen:
keine Taste gedrückt setzt ebenfalls den Zeitzähler zurück, der zählt ja 
nur solange ein Code laufend wiederholt erkannt wird.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Klaus2 schrieb:

> das repetition flag bereitet mir Kopfschmerzen.
>
> Also, es wird bereits bei sehr kurzen Tastendrücken ab 100ms (JVC)
> gesetzt, wie soll ich denn "so kurz" die Taste drücken?

Viele der von IRMP unterstützten Protokolle habe ich nicht selber testen 
können, sondern es wurden mir Scan-Dateien zugeschickt, welche ich dann 
benutzt habe, um das entsprechende Protokoll einzubauen.

Leider ist es so, dass die Leute sich dabei keine bis wenig Gedanken 
über kurze/lange Tastendrücke machen. Deshalb habe ich nicht in allen 
Fällen eine Information darüber, ob die gescannte Taste kurz oder lang 
gedrückt wurde.

Bei einigen Protokollen wird ein Telegramm auch bei kurzem Tastendruck 
aus Sicherheitsgründen mehrfach ausgesendet. Das könnte IRMP dann falsch 
verstehen... als langen Tastendruck.

Daher meine Frage: wie oft liefert IRMP einen Code zurück bei kürzester 
Tastenabfrage? In welchen Schritten geht es weiter? Ist es nur ein 
weiterer Code? Dann wäre die Schrittzahl z.B.

2 Frames = kurze Taste
3 Frames = etwas länger gedrückt
4 Frames = noch etwas länger gedrückt

Es könnte aber auch so sein:

2 Frames = kurze Taste
4 Frames = etwas länger gedrückt
6 Frames = noch etwas länger gedrückt

D.h. es würde immer nur eine gerade Zahl von Frames geschickt.

Wenn ich diese Info habe, kann ich den Decoder darauf abstimmen und Du 
bekommst dann nur noch einen Code statt mehrere zurück.

Aber nochmal kurz zu Deinem Problem: Wenn Du wirklich messen willst, ob 
eine Taste "sehr lange" gedrückt wurde, würde ich an Deiner Stelle 
einfach einen Zähler einbauen, der misst, wie oft ein und derselbe Code 
mit Repetition-Flag zurückkam. Ist die Anzahl z.B. größer als 5, handelt 
es sich um einen langen Tastendruck.

Denn bedenke: Die meisten FBs schicken kontinuierlich Frames weg, sobald 
Du eine Taste drückst. IRMP bekommt keine Info darüber, wann eine 
Taste wirklich losgelassen wurde.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Conny G. schrieb:
> Du merkst Dir immer den letzten erkannten Code in einer Variablen.
> Und Du incremetierst in der Interrupt-Routine des Timers einen
> Zeitzähler.

Es geht einfacher: Einfach die Anzahl der hintereinander vorkommenden 
Repetition-Flags mitzählen. Ist sie zum Beispiel größer als 5, handelt 
es sich um einen sehr langen Tastenduck.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Klaus2 schrieb:

> WENN eine Taste gedrückt wurde, warte kurz und entscheide, ob Sie nur
> kurz (dann Operation A) oder länger (dann Operation B) gedrückt wurde.

Sorry, meine Antwort war zu kurz gedacht. Da IRMP keine Infos darüber 
hat, wann die Taste losgelassen wurde, kannst Du Long- und Short-Press 
wirklich nur unterscheiden, indem Du selbst mit einem Timeout arbeitest. 
Mit meiner "Lösung" oben (zählen der Repetition-Flags) kannst Du zwar 
lange Tastendrücke erkennen, aber keine kurzen! ;-)

Deshalb brauchst Du für die kurzen Tastendrücke noch zusätzlich die 
Regel:

Bekommst Du innerhalb einer bestimmten Zeit keinen Frame mehr, handelt 
es sich um einen kurzen Tastendruck. Den Timeout handelst Du Du am 
besten über den Timer ab. Meine Vorredner haben da schon den richtigen 
Weg aufgezeigt.

von Klaus R. (klaus2)


Lesenswert?

Hallo alle zusammen,

GENAU so hatte ich es vor, aber mein Problem - vermutlich habe ich ein 
Brett vor dem Kopf - ist, wie Frage ich ab, ob nichts mehr kommt?

- In command steht ja IMMER etwas, auch wenn NICHTS empfangen wird? 
(Wollte last_command mit command vergleichen, geht aber nicht, da 
gelatcht)
- Flags ist auch IMMER gesetzt, wenn es einmal gesetzt wurde? (Wollte 
testen, ob wenn das RF einmal gesetzt ist, es nach loslassen (500ms 
später) nicht mehr gesetzt ist)
- if ( irmp_get_data( &irmp_data)) wird gelatched, also ist das auch 
immer wahr? (Ist nach 500ms auch wahr, da ja immer mehr als eine Sequenz 
übertragen wird).

Klar ist mir, wie ich erkenne, DASS eine Taste gedrückt wurde, aber 
nicht, wie ich dann nach zB 200ms und 500ms prüfen kann, ob sie JETZT 
nicht mehr gedrückt ist und darauf entscheide, ob short- oder longpress. 
Und das lässt mir einfach keine Ruhe :)

EDIT: Ich schaue mir eure Vorschläge morgen Abend nochmal an, vll. habe 
ich einfach etwas übersehen...vermtulich habe ich die Möglichkeit "if 
(!irmp_get_data( &irmp_data)) -> Taste ist nicht gedrückt" einfach nicht 
ordentlich genutzt...

Klaus.

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


Lesenswert?

Klaus R. schrieb:

> - if ( irmp_get_data( &irmp_data)) wird gelatched, also ist das auch
> immer wahr? (Ist nach 500ms auch wahr, da ja immer mehr als eine Sequenz
> übertragen wird).

Ja, da ist was dran. Aber: Solange Du die Daten per irmp_get_data() 
nicht abholst, kommt da auch nichts neues mehr rein.

Also mal ins unreine geschrieben:

Zeitpunkt 0: irmp_get_data(...) // check, ob Taste gedrückt
Zeitpunkt 1: while (irmp_get_data(..)) { ; }  // IRMP-Buffer leeren
Zeitpunkt 2: if (irmp_get_data(...) AND repetition) lang(); else kurz()

Wären noch die Zeitpunkte zu wählen... ich schlage da als erste 
Versuchswerte vor:

Zeitpunkt 1: 0 + 100ms
Zeitpunkt 2: 0 + 200ms

Dann weisst Du nach 0,2 sec, ob es ein langer oder kurzer Tastendruck 
ist. Das ist meines Erachtens ein Wert, den ein Mensch als Reaktionszeit 
noch tolerieren wird.

Sonst musst Du mit den Werten ein wenig spielen. Die meisten FBs senden 
ca. 10 Frames pro Sekunde.

von Klaus R. (klaus2)


Lesenswert?

Puh, ich bin schonmal froh, dass ich nicht völlig falsch lag mit meinen 
Vermutungen :)

Ich habe gestern ca 200ms gewartet und bei 180ms einmal "geleert" [Btw: 
Leert "irmp_get_data(..)" denn dann auch 100%ig zB den command-wert, 
also setzt diesen auf 0?], aber 100% hat das nicht funktioniert - mag 
aber daran gelegen haben, dass ich über die api zu sehr verunsichert 
war, als ich festgestellt habe, dass da viel gelatched wird. Ganz normal 
ist mein Anwendungsfall aber auch nicht, gebe ich zu - ich wollte per 
kurzem "Power" ein Gerät ausschalten, per langem dann einen Sleeptimer 
hochsetzen (jeweils 30min+). Aber ich hatte dann die Schnauze voll und 
hab eine extra Taste dafür spendiert, klappt nun - natürlich - genau so, 
wie es soll...aber mich lässt das nicht ganz in Ruhe, rein aus 
akademischem Interesse.

Klaus.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Klaus R. schrieb:
> Ich habe gestern ca 200ms gewartet und bei 180ms einmal "geleert" [Btw:
> Leert "irmp_get_data(..)" denn dann auch 100%ig zB den command-wert,
> also setzt diesen auf 0?],

Wenn irmp_get_data mit FALSE zurückkommt, ist die übergebene Struct 
unberührt.... also unverändert. Halte Dich also allein an den 
Return-Wert.

Es wäre auch Quatsch, command auf 0 zu setzen. Es gibt durchaus gültige 
FB-Befehle, bei denen command == 0 ist.

> aber 100% hat das nicht funktioniert - mag
> aber daran gelegen haben, dass ich über die api zu sehr verunsichert
> war, als ich festgestellt habe, dass da viel gelatched wird.

Ja, aber es wird max. nur ein Frame gelatched - nicht mehr.

> Ganz normal
> ist mein Anwendungsfall aber auch nicht, gebe ich zu - ich wollte per
> kurzem "Power" ein Gerät ausschalten, per langem dann einen Sleeptimer
> hochsetzen (jeweils 30min+). Aber ich hatte dann die Schnauze voll und
> hab eine extra Taste dafür spendiert, klappt nun - natürlich - genau so,
> wie es soll...aber mich lässt das nicht ganz in Ruhe, rein aus
> akademischem Interesse.

Das "Entprellen" von Tasten (mit Absicht in Gänsefüßchen) soll nur 
verhindern, dass bei einer Zahleneingabe eine Taste mehrfach 
interpretiert wird. Deshalb das Beispiel im Artikel, wo Frames mit 
gesetztem Flag einfach ignoriert werden - im Gegensatz zu Volume-Tasten 
beim Fernseher.

Dein Anwendungsfall ist da schon etwas komplexer... und untypisch für 
IR-Fernbedienungen. Aber mit dem oben aufgezeigtem Weg Einlesen, Leeren, 
nochmal Einlesen sollte es gehen.

Gruß,

Frank

von Joachim B. (jar)


Lesenswert?

Klaus R. schrieb:
> Ich habe gestern ca 200ms gewartet und bei 180ms einmal "geleert" [Btw:
> Leert "irmp_get_data(..)" denn dann auch 100%ig zB den command-wert,
> also setzt diesen auf 0?], aber 100% hat das nicht funktioniert

die Probleme habe ich ja auch und noch immer keine Lösung, aber kann ja 
noch kommen

> ....dass da viel gelatched wird. Ganz normal
> ist mein Anwendungsfall aber auch nicht, gebe ich zu

bei mir auch, aber der "Erfinder" meint mein Fall ist ungewöhnlich und 
die Lösung nah

> ...aber mich lässt das nicht ganz in Ruhe, rein aus
> akademischem Interesse.
> Klaus.

na mal sehen vielleicht findet sich auch für mich irgendwann ne Lösung

Es war aber einfacher mit dem RC5 toogle Bit (scnr)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> die Probleme habe ich ja auch und noch immer keine Lösung, aber kann ja
> noch kommen

Auf Deinen Kommentar habe ich schon gewartet ;-)

> na mal sehen vielleicht findet sich auch für mich irgendwann ne Lösung

Genau so machen wie oben aufgezeigt.

> Es war aber einfacher mit dem RC5 toogle Bit (scnr)

Das Toggle-Bit gibt es nicht bei seiner FB. Vergiss das doch mal 
endlich.

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Das Toggle-Bit gibt es nicht bei seiner FB. Vergiss das doch mal
> endlich.

war doch nicht böse gemeint, ich sagte ja schon mehrfach, dein Code ist 
genial und ich setze ihn gerne ein und danke dafür nochmal.

> Genau so machen wie oben aufgezeigt.

du kannst ja nix dafür das ich so unfähig bin

- nur für meine alte Steuerung hatte ich da halt Probleme, aber die ist 
tot, von daher alles im grünen Bereich ;-) -

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


Lesenswert?

Joachim B. schrieb:
> - nur für meine alte Steuerung hatte ich da halt Probleme, aber die ist
> tot, von daher alles im grünen Bereich ;-) -

Wieder ein Problem ausgesessen ;-)

von Klaus R. (klaus2)


Lesenswert?

...und ich freue mich, dass mein Problem etwas ungewöhnlicher ist und 
nicht so einfach zu lösen. jetzt muss ich mich nur noch selbst davon 
überzuegen, dass das mit einer Taste mehr auch iO ist und ich mich 
lieber auf die letzten 3 Projektschritte stürze, als meine Selbstachtung 
zu retten :)

Klaus.

von Ulli (Gast)


Lesenswert?

Ich baue gerade eine IR TX & RX Schaltung auf die auf 3.3Volt 
Versorgungsspannung basiert.

Was denkt Ihr, kann ich die identische Schaltung für TX und RX einfach 
bei 3.3 Volt betreiben?
Der Basiswiderstand für die IR Diode würde ich mit 1k dimensionieren.
Laut Datenblatt des TSOP1736 sollte dies ebenso kein Problem 
darstellen...

Was denkt ihr?

von Klaus R. (klaus2)


Lesenswert?

Ich denke, schnapp dirn Bollerwagen und feier mal sauber den 1. Mai.

Klaus.

von Michael K. (Gast)


Lesenswert?

Ulli schrieb:
> Was denkt ihr?
Tx ist kein Problem: einfach den Vorwiderstand anpassen. Aber der 
TSOP1736 wird mit 3.3V Versorgungsspannung nicht funktionieren, sondern 
erst ab 4.5V. Aber es gibt andere die das tun, z.B. TSOP34836.

von Ulli (Gast)


Lesenswert?

Mir ist gestern noch aufgefallen das der BC337 ja nur mit einer 
Basisspannug von 5 Volt durchschaltet? Welchen nehm ich da dann am 
besten?
Als Vorwiderstand meinst du die 33 Ohm, Was nehm ich dann da am besten?
Sind 22 Ohm passend?

von Michael K. (Gast)


Lesenswert?

Ulli schrieb:
> Mir ist gestern noch aufgefallen das der BC337 ja nur mit einer
> Basisspannug von 5 Volt durchschaltet?
Nein, das ist ein normaler Transistor - da brauchst du keine 5V. Die 
Schaltung aus dem Artikel kannst du 1:1 verwenden und mit R1 kannst du 
den Strom durch die Diode einstellen (siehe deren Datenblatt). Bau es 
erstmal auf wie im Artikel, vielleicht funktioniert es ja schon 
ausreichend gut. Und wenn die Reichweite zu gering ist, kannst du es 
vielleicht mit R1 hinzudrehen.

von Michael K. (Gast)


Lesenswert?

Bei zu geringer Reichweite kannst du auch R2 noch auf 3.3k verringern.

von eku (Gast)


Lesenswert?

Hallo ukw,

in SVN Rev 121 hast Du zwei Themen vermischt. Würdest Du bitte die 
Commits in Zukunft nach Themen aufteilen. Dadurch erleichterst Du die 
Übernahme der Änderungen in andere Projekte. Im konkreten Fall hätten 
wir nur die Korrektur des Siemens-Protokolls gebraucht. Ein svn diff 
-r120:121 enthält leider auch das RCMM-Protokoll. Schade.

Grüße, eku

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

eku schrieb:
> in SVN Rev 121 hast Du zwei Themen vermischt.

Sorry, werde es versuchen, kann es aber nicht immer versprechen.

von kaihs (Gast)


Lesenswert?

Ich habe in einem Projekt (culfw) das eine ältere Version von IRMP 
nutzte einen Update auf die Version 2.4 gemacht, da das Senden von 
RC6/Philips nicht funktionierte.

Das funktioniert jetzt in der 2.4, dafür funktionierte das Senden von 
Samsung nicht mehr, Samsung32 dagegen immer noch.

Ich habe dann die letzten Änderungen die am Samsung-Timing vorgenommen 
worden sind wieder rückgängig gemacht, d.h.
1
#define SAMSUNG_1_PAUSE_TIME                    1650.0e-6                       // 1650 usec pause
2
#define SAMSUNG_0_PAUSE_TIME                     550.0e-6                       //  550 usec pause

wieder in
1
#define SAMSUNG_1_PAUSE_TIME                    1450.0e-6                       // 1450 usec pause
2
#define SAMSUNG_0_PAUSE_TIME                     450.0e-6                       //  450 usec pause

geändert.
Dann funktioniert das Senden von Samsung wieder, aber das Senden von 
Samsung32 ist unzuverlässiger geworden.

Kann es sein, dass die beiden Samsung Protokolle unterschiedliches 
Timing haben, 1650/550 für Samsung32 und 1450/450 für Samsung?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

kaihs schrieb:
> Kann es sein, dass die beiden Samsung Protokolle unterschiedliches
> Timing haben, 1650/550 für Samsung32 und 1450/450 für Samsung?

Nein, eigentlich ist das Timing identisch. Leider ist es so, dass das 
Timing je nach Hersteller durchaus mal etwas abweichen kann.

Kannst Du mal die Mittelwerte ausprobieren, um festzustellen, ob dann 
wieder beide Protokolle zuverlässig funktionieren?

Also:
1
#define SAMSUNG_1_PAUSE_TIME                    1550.0e-6 // 1550 usec pause
2
#define SAMSUNG_0_PAUSE_TIME                     500.0e-6 //  500 usec pause

Wenn das so klappt, werde ich das übernehmen.

von kaihs (Gast)


Lesenswert?

In der Annahme, dass auch Samsung Ingenieure 'glatte' Zahlen bevorzugen 
habe ich die Werte mal auf
1
#define SAMSUNG_1_PAUSE_TIME                    1500.0e-6 // 1500 usec pause
2
#define SAMSUNG_0_PAUSE_TIME                     500.0e-6 //  500 usec pause

geändert.

Dann funktionieren beide Codes bei mir.

Wäre schön, wenn du das übernehmen würdest.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

kaihs schrieb:
> In der Annahme, dass auch Samsung Ingenieure 'glatte' Zahlen bevorzugen
> habe ich die Werte mal auf
>
>
1
> #define SAMSUNG_1_PAUSE_TIME                    1500.0e-6 // 1500 usec 
2
> pause
3
> #define SAMSUNG_0_PAUSE_TIME                     500.0e-6 //  500 usec 
4
> pause
5
>
>
> geändert.
>
> Dann funktionieren beide Codes bei mir.

Freut mich! Übernehme ich gern. Kommt mit dem nächsten Update.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Es sind neue Updates im SVN verfügbar:

IRMP: Version 2.5.3:

    05.06.2014: Neues Protokoll: LGAIR
    30.05.2014: Neues Protokoll: SPEAKER
    30.05.2014: Timings für SAMSUNG-Protokolle optimiert

IRSND: Version 2.5.2:

    03.06.2014: Neues Protokoll: TELEFUNKEN
    30.05.2014: Neues Protokoll: SPEAKER
    30.05.2014: Timings für SAMSUNG-Protokolle optimiert

LGAIR ist ein von LG verwendetes Protokoll für Klimaanlagen. Das habe 
ich anhand von Scans von einem IRMP-User aus Ungarn erfolgreich 
entschlüsseln können. Das Senden über IRSND steht noch aus, kommt aber 
in Kürze. Damit kann man seine Klimaanlage nun auch programmgesteuert 
(oder mit Remote IRMP auch übers INTERNET oder Handy) fernsteuern.

SPEAKER ist ein Protokoll zur Fernsteuerung von Lautsprechersystemen 
(ähnlich NUBERT).

: Bearbeitet durch Moderator
von Jörg R. (jrie)


Lesenswert?

IRSND auf STM32F10x

Ich habe IRMP und IRSND auf einen STM32F105 angepasst.
Ich hätte ein paar Verbesserungsvorschläge.
Timer10 gibt es oft nicht, daher schlage ich als Default Timer4 vor. Der 
liegt per Default an B6.
Der Kommentar in Zeile 610 in irsnd.c („TODO: remapping required“) 
klingt für mich so, als ob remapping nötig wäre. Falls man den Default 
Pin benutzt, ist das aber nicht der Fall.
Falls man tatsächlich remappen muss, ist zusätzlich noch die Aktivierung 
von AFIO nötig, sonst geht es nicht.
Man sollte sich unbedingt Kapitel 9.3.7 im Referenzhandbuch (RM0008) und 
im Datenblatt die Tabelle "Pin definitions" ansehen und in 
stm32f10._gpio.c die diversen GPIO_Remap Argumente.

--- IRMP1/irsnd.c       2014-06-23 08:58:42.000000000 +0200
+++ IRMP2/irsnd.c       2014-07-04 16:18:27.891586612 +0200
@@ -590,6 +590,7 @@
         RCC_AHBPeriphClockCmd(IRSND_PORT_RCC, ENABLE);
 #    elif defined (ARM_STM32F10X)
         RCC_APB2PeriphClockCmd(IRSND_PORT_RCC, ENABLE);
+//        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // only 
in case of remapping, not necessary for default port-timer mapping
 #    elif defined (ARM_STM32F4XX)
         RCC_AHB1PeriphClockCmd(IRSND_PORT_RCC, ENABLE);
 #    endif
@@ -607,7 +608,7 @@
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
         GPIO_Init(IRSND_PORT, &GPIO_InitStructure);
-        GPIO_PinRemapConfig(, ENABLE);         // TODO: remapping 
required
+//        GPIO_PinRemapConfig(GPIO_*Remap*_TIM[IRSND_TIMER_NUMBER], 
ENABLE); // only in case of remapping, not necessary for default 
port-timer mapping
 #    endif

         /* TIMx clock enable */
diff -Nru IRMP1/irsndconfig.h IRMP2/irsndconfig.h
--- IRMP1/irsndconfig.h 2014-06-23 08:58:42.000000000 +0200
+++ IRMP2/irsndconfig.h 2014-07-04 16:03:28.815837848 +0200
@@ -113,10 +113,10 @@
  * ARM STM32 section:
  *----------------------------------------------------------------------- 
------------------------------------------------------------------------ 
----
  */
-#elif defined (ARM_STM32) 
// use A6 as IR output on STM32
-#  define IRSND_PORT_LETTER                     A
+#elif defined (ARM_STM32) 
// use B6 as IR output on STM32
+#  define IRSND_PORT_LETTER                     B
 #  define IRSND_BIT_NUMBER                      6
-#  define IRSND_TIMER_NUMBER                    10
+#  define IRSND_TIMER_NUMBER                    4
 #  define IRSND_TIMER_CHANNEL_NUMBER            1 
// only channel 1 can be used at the moment, others won't work

 /*---------------------------------------------------------------------- 
------------------------------------------------------------------------ 
-----

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Jörg,

Jörg R. schrieb:
> Ich habe IRMP und IRSND auf einen STM32F105 angepasst.

Danke für die Verbesserungsvorschläge. Ich schaue, dass ich die 
Änderungen in die nächste IRMP-Version mit einfließen lasse. Könnstest 
Du dann - wenn es soweit ist - das Resultat nochmal testen, um 
auszuschließen, dass ich etwas übersehen habe?

Könntest Du Deine diffs nochmal eingebettet in
1
[code]
2
...
[/code]

reinstellen? Das lässt sich wegen den Zeilenumbrüchen dann besser lesen.

Viele Grüße,

Frank

: Bearbeitet durch Moderator
von Jörg R. (jrie)


Lesenswert?

Hallo Frank,
ok, und hier nochmal in Code Tags:
1
--- IRMP1/irsnd.c       2014-06-23 08:58:42.000000000 +0200
2
+++ IRMP2/irsnd.c       2014-07-04 16:18:27.891586612 +0200
3
@@ -590,6 +590,7 @@
4
         RCC_AHBPeriphClockCmd(IRSND_PORT_RCC, ENABLE);
5
 #    elif defined (ARM_STM32F10X)
6
         RCC_APB2PeriphClockCmd(IRSND_PORT_RCC, ENABLE);
7
+//        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // only in case of remapping, not necessary for default port-timer mapping
8
 #    elif defined (ARM_STM32F4XX)
9
         RCC_AHB1PeriphClockCmd(IRSND_PORT_RCC, ENABLE);
10
 #    endif
11
@@ -607,7 +608,7 @@
12
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
13
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
14
         GPIO_Init(IRSND_PORT, &GPIO_InitStructure);
15
-        GPIO_PinRemapConfig(, ENABLE);         // TODO: remapping required
16
+//        GPIO_PinRemapConfig(GPIO_*Remap*_TIM[IRSND_TIMER_NUMBER], ENABLE); // only in case of remapping, not necessary for default port-timer mapping
17
 #    endif
18
19
         /* TIMx clock enable */
20
diff -Nru IRMP1/irsndconfig.h IRMP2/irsndconfig.h
21
--- IRMP1/irsndconfig.h 2014-06-23 08:58:42.000000000 +0200
22
+++ IRMP2/irsndconfig.h 2014-07-04 16:03:28.815837848 +0200
23
@@ -113,10 +113,10 @@
24
  * ARM STM32 section:
25
  *---------------------------------------------------------------------------------------------------------------------------------------------------
26
  */
27
-#elif defined (ARM_STM32)                                               // use A6 as IR output on STM32
28
-#  define IRSND_PORT_LETTER                     A
29
+#elif defined (ARM_STM32)                                               // use B6 as IR output on STM32
30
+#  define IRSND_PORT_LETTER                     B
31
 #  define IRSND_BIT_NUMBER                      6
32
-#  define IRSND_TIMER_NUMBER                    10
33
+#  define IRSND_TIMER_NUMBER                    4
34
 #  define IRSND_TIMER_CHANNEL_NUMBER            1                       // only channel 1 can be used at the moment, others won't work
35
36
 /*---------------------------------------------------------------------------------------------------------------------------------------------------
Viele Grüße,
Jörg

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


Lesenswert?

Jörg R. schrieb:
> ok, und hier nochmal in Code Tags:

Vielen Dank! Ich habe Deine Änderungen als Version 2.6.1 ins SVN 
eingecheckt.

Gruß,

Frank

von Jörg R. (jrie)


Lesenswert?

Hallo Frank,

hier noch zusätzliche Änderungen.

* C13 ist ungeeignet, daher lieber C6.
* includes für STM32F10x
1
diff -Nru I1/irmpconfig.h I2/irmpconfig.h
2
--- I1/irmpconfig.h     2014-07-21 11:05:03.000000000 +0200
3
+++ I2/irmpconfig.h     2014-07-25 16:33:35.819776900 +0200
4
@@ -121,9 +121,9 @@
5
  * Change hardware pin here for ARM STM32
6
  *---------------------------------------------------------------------------------------------------------------------------------------------------
7
  */
8
-#elif defined (ARM_STM32)                                               // use C13 as IR input on STM32
9
+#elif defined (ARM_STM32)                                               // use C6 as IR input on STM32
10
 #  define IRMP_PORT_LETTER                      C
11
-#  define IRMP_BIT_NUMBER                       13
12
+#  define IRMP_BIT_NUMBER                       6
13
14
 /*---------------------------------------------------------------------------------------------------------------------------------------------------
15
  * Change hardware pin here for Stellaris ARM Cortex M4
16
diff -Nru I1/irmpsystem.h I2/irmpsystem.h
17
--- I1/irmpsystem.h     2014-07-21 11:05:03.000000000 +0200
18
+++ I2/irmpsystem.h     2014-07-25 16:49:36.760388800 +0200
19
@@ -95,6 +95,11 @@
20
 #  define PROGMEM volatile
21
 #  define memcpy_P memcpy
22
 #  define APP_SYSTICKS_PER_SEC          32
23
+#elif defined(ARM_STM32F10X)
24
+#  include "stm32f10x_gpio.h"
25
+#  include "stm32f10x_rcc.h"
26
+#  define PROGMEM
27
+#  define memcpy_P                      memcpy
28
 #else
29
 #  define PROGMEM
30
 #  define memcpy_P                      memcpy

Und falls es jemanden interessiert, hier der Link zu meinem Projekt:
http://www.vdr-portal.de/board18-vdr-hardware/board13-fernbedienungen/p1204818-irmp-auf-stm32-ideen-f%C3%BCr-einen-usb-ir-empf%C3%A4nger-sender-einschalter-mit-rtc/

Viele Grüße,
Jörg

von Ulli (Gast)


Lesenswert?

Hallo zusammen,

ich bau gerade eine neue Schaltung auf und habe eine Frage an euch.
Ich möchte einen TSOP4836 über 5Volt versorgen, habe einen Pullup (10K) 
am Ausgang nach 5Volt, 100Ohm in Reihe und 4.7µF parallel. Wie im 
Datenblatt beschrieben.
Der Ausgang des TSOP4836 hängt an einen ADC Eingang eines Atmega 328p, 
welcher 3.3Volt versorgt ist.
Denkt Ihr das ich aufgrund der unterschiedlichen Versorgungsspannungen 
ein Problem bekomme, oder sollte das so funktionerien? ggf. den Pullup 
raus?

Wäre sehr dankebar über Hinweise. Habe die Schaltung nämlich schon beim 
Ätzer.....

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ulli schrieb:
> ich bau gerade eine neue Schaltung auf und habe eine Frage an euch.
> Ich möchte einen TSOP4836 über 5Volt versorgen, habe einen Pullup (10K)
> am Ausgang nach 5Volt, 100Ohm in Reihe und 4.7µF parallel. Wie im
> Datenblatt beschrieben.

Der TSOP4836 hat intern schon einen 30k Pullup, siehe Blockdiagramm. 
Daher ist ein weiterer Pullup nur optional und nicht unbedingt vonnöten.

> Der Ausgang des TSOP4836 hängt an einen ADC Eingang eines Atmega 328p,
> welcher 3.3Volt versorgt ist.

Warum nimmst Du dann keinen TSOP, der auch mit 3,3V als 
Versorgungsspannung auskommt?

> Denkt Ihr das ich aufgrund der unterschiedlichen Versorgungsspannungen
> ein Problem bekomme, oder sollte das so funktionerien? ggf. den Pullup
> raus?

Ja, nimm den Pullup raus. Ob der ATmega328 Dir das übel nimmt, wenn er 
über 30kOhm 5V sieht, kann ich nicht beurteilen. Aber schön ist anders 
;-)

von Ulli (Gast)


Lesenswert?

Das Problem ist die Schaltung ist schon fix...müsste aus der geätzten 
Platine dann mit dem Dremel die Leitung unterbrechen und fädeln...suche 
gerade eine Lösung für ein schon verbocktes Layout :)

Eigentlich wäre der TSOP34836 auf 3.3V die Lösung richtig?
Den gibt es nur weder bei Conrad noch bei Bürklin....

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ulli schrieb:
> Eigentlich wäre der TSOP34836 auf 3.3V die Lösung richtig?

Ja, der wäre richtig.

> Den gibt es nur weder bei Conrad noch bei Bürklin....

Alternative wäre TSOP 31238 bzw. TSOP 31236, den gibts bei Reichelt. 
Allerdings hat der ein anderes Pinout.

von Ulli (Gast)


Lesenswert?

Ja stimmt, das Problem sind überall die Versandkosten. Reichelt hat auch 
5.6€. Conrad und Bürklin kann ich abholen :)
Sehe nicht ein Cent Artikel zu bestellen und 6€ Versand dafür zu 
bezahlen.

von Michael K. (Gast)


Lesenswert?

Laut http://www.vishay.com/docs/82459/tsop48.pdf kann doch der TSOP4836 
mit 3.3V betrieben werden, oder sehe ich das falsch?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Michael K. schrieb:
> Laut http://www.vishay.com/docs/82459/tsop48.pdf kann doch der TSOP4836
> mit 3.3V betrieben werden, oder sehe ich das falsch?

Ja. Hier steht ab 2,5V. Gestern hatte ich über Google ein älteres 
erwischt (1. Link unterhalb der Bilder), das stand noch 4,5-5.V drin. 
Aber auch das Datenblatt, welches bei Conrad verlinkt ist, sagt ab 2,5V.

Passt also wohl.

von Joachim B. (Gast)


Angehängte Dateien:

Lesenswert?

hallo Frank, ich mal wieder....

ich habe immer noch Probleme mit der Entprellung der Tasten

bin ich zu doof spinnt meine Hardware ?

vielleicht schaust du noch mal

autorepeat geht, aber Einzelschritt halt nie, entweder es kommen gleich 
2 Schritte oder keiner was bei PRG++/-- doof ist

von Bruno M. (brumay)


Lesenswert?

Hallo,

Ich weiß nicht, ob meine Frage hier an die richtige Stelle kommt, aber 
ich bekomme den Code im Studio 4 nicht zum Laufen. Leider kenne ich bei 
"C" nur Grundbegriffe, bin schon eher in ASM zu Hause.

Die Fehlermeldung sieht wie folgt aus:

quote
Build started 6.8.2014 at 15:01:36
mmcu=atmega88 -Wall -gdwarf-2 -std=gnu99               -DF_CPU=8000000UL 
-Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD 
-MP -MT main.o -MF dep/main.o.d  -c  ../main.c
/usr/bin/sh: -Wall: command not found
make: [main.o] Error 127 (ignored)
mmcu=atmega88 -Wall -gdwarf-2 -std=gnu99               -DF_CPU=8000000UL 
-Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD 
-MP -MT irmp.o -MF dep/irmp.o.d  -c  ../irmp.c
/usr/bin/sh: -Wall: command not found
make: [irmp.o] Error 127 (ignored)
mmcu=atmega88 -Wl,-Map=irmp.map main.o irmp.o     -o irmp.elf
/usr/bin/sh: -Wl,-Map=irmp.map: command not found
make: [irmp.elf] Error 127 (ignored)
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  irmp.elf 
irmp.hex
avr-objcopy: 'irmp.elf': No such file
make: *** [irmp.hex] Error 1
Build failed with 1 errors and 0 warnings...
unquote

Ich habe den Ursprungscode nicht verändert.

Kann mir jemand helfen?

Gruß Bruno

von Joachim B. (Gast)


Lesenswert?

Bruno M. schrieb:
> Ich weiß nicht, ob meine Frage hier an die richtige Stelle kommt, aber
> ich bekomme den Code im Studio 4 nicht zum Laufen.

ist Studio 4 richtig installiert ?

schon einmal eine LED zum blinken bekommen ?

ich habe es gerade versucht

neues Projekt Test eröffnet

Source Code von IRMP eingestellt im Projektordner
MCU gewählt, Takt bekannt gemacht und läuft durch ohne Fehler.....



avr-gcc -mmcu=atmega88 -Wl,-Map=nurso.map nurso.o irmp.o irmpextlog.o 
-o nurso.elf
.....
Program:    2356 bytes (28.8% Full)
Build succeeded with 0 Warnings...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Build started 6.8.2014 at 15:01:36
> mmcu=atmega88 -Wall -gdwarf-2 -std=gnu99               -DF_CPU=8000000UL
> -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD
> -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
> /usr/bin/sh: -Wall: command not found

Da fehlt vorne am Anfang der Zeile der Compiler-Aufruf. Scheinbar ist 
Dein WinAVR (avr-gcc toolchain) zum AVR Studio nicht installiert bzw. 
AVR Studio hat es nicht gefunden.

von Joachim B. (Gast)


Lesenswert?

Frank M. schrieb:
> Da fehlt vorne am Anfang der Zeile der Compiler-Aufruf. Scheinbar ist
> Dein WinAVR (avr-gcc toolchain) zum AVR Studio nicht installiert bzw.
> AVR Studio hat es nicht gefunden.

Ich habe mir die Installationsreihenfolge so notiert:

1. winAVR
2. AVR-Studio

dann findet A-Studio auch gleich den AVR gcc und bindet ihn mit ein

Frank, kannst du bitte noch mal zu meiner Frage schauen 3 Beiträge höher 
?
danke

von Bruno M. (brumay)


Lesenswert?

Vorab herzlichen Dank für die verschiedenen Hinweise.

Auch wenn das Problem richtig erkannt wurde, hat es mir noch nicht 
geholfen.

Nachdem ich WINAVR und das Studio insgesamt 3 x in unterschiedlichen 
Verzeichnissen neu installiert habe und die Fehlermeldung gleich 
geblieben ist, habe ich versucht im Internet eine Antwort zu finden. Nun 
bin ich insoweit schlauer, dass bei meinem Studio 4.19 der Link zu 
WINAVR nicht mehr automatisch hergestellt wird, da jetzt eine eigene AVR 
- Toolchain integriert ist. Ich habe auch gefunden, wie und wo man die 
entsprechenden Links manuell eintragen kann, was ich dann mit älteren 
Codes, die früher schon mal gelaufen sind, erfolgreich versucht habe.

Bei IRMP hat aber auch das nicht zum Erfolg geführt. Es gibt jetzt eine 
neue Fehlermeldung, mit der ich nichts anfangen kann.

quote
rm -rf main.o irmp.o  irmp.elf dep/* irmp.hex irmp.eep irmp.lss irmp.map
Build succeeded with 0 Warnings...
gcc  -mmcu=atmega88 -Wall -gdwarf-2 -std=gnu99 
-DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct 
-fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  .
./main.c

gcc: CreateProcess: No such file or directory
make: *** [main.o] Error 1
Build failed with 1 errors and 0 warnings...
unquote

Bruno

von Joachim B. (Gast)


Lesenswert?

Bruno M. schrieb:
> dass bei meinem Studio 4.19

das kann der Ärger sein, ich glaube ich habe die 4.19 wieder 
rausgeworfen und arbeite überall mit der 4.18

von Joachim B. (Gast)


Lesenswert?

Bruno M. schrieb:
> gcc: CreateProcess: No such file or directory

hast du win-avr (gcc) nicht installiert ?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> gcc: CreateProcess: No such file or directory

Der Compiler heisst avr-gcc, nicht gcc. Schau doch mal in Deiner 
Toolchain im Verzeichnis bin nach.

von Bruno M. (brumay)


Lesenswert?

Frank M. schrieb:

> Der Compiler heisst avr-gcc, nicht gcc. Schau doch mal in Deiner
> Toolchain im Verzeichnis bin nach.

In meinem WINAVR heißt er tatsächlich gcc.exe und darauf habe ich den 
Link gesetzt. Auch ein Umbenennen der Datei in avr-gcc.exe ergibt den 
gleichen Fehler, nur eben dann mit avr-gcc.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> In meinem WINAVR heißt er tatsächlich gcc.exe [...]

Merkwürdig. Habe ich noch nie gesehen. Wo liegt er denn? Also in welchem 
Pfad? Ich habe mein WinAVR direkt unter C:\ liegen. Es könnte Probleme 
geben, wenn im Pfad Leerzeichen sind.

Ausserdem habe ich hier mittlerweile avr-gcc V.4.8.1 laufen.

Vorgehen:

  http://www.atmel.com/tools/ATMELAVRTOOLCHAINFORWINDOWS.aspx

Dort

    Atmel AVR 8-bit Toolchain 3.4.4 - Windows

heruntergeladen. Dieses habe ich dann unter C:\WinAVR\avr-gcc-4.8.1 
abgelegt, also dass avr-gcc.exe in dem Ordner 
C:\WinAVR\avr-gcc-4.8.1\bin zum Liegen kommt.

Dann folgendes als reg-Datei gespeichert und ausgeführt:
1
Windows Registry Editor Version 5.00
2
3
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinAVR]
4
"DisplayVersion"="20100110"
5
"UninstallString"="C:\\WinAVR\\avr-gcc-4.8.1\\WinAVR-20100110-uninstall.exe"

Das ist ein bisschen tricky: Das AVR Studio 4.18 (ja, ich benutze 18 und 
nicht 19) merkt sich im UninstallString, wo das WinAVR-Verzeichnis 
liegt.

Das dort angegebene Programm WinAVR-20100110-uninstall.exe existiert gar 
nicht. Ist auch vollkommen schnuppe. Es geht nur um den Pfad.

Dann kann man unter den Projekt-Eigenschaften (Project -> Configuration 
Options -> Custom Options) einfach bei "Use WinAVR" ein Häkchen machen 
und es wird der neue Compiler benutzt.

Achja, in dem alten Verzeichnis WinAVR-20100110 (oder so ähnlich) gibt 
es ein Unterverzeichnis namens utils. Es empfiehlt sich, dieses nach 
WinAVR\avr-gcc-4.8.1 rüberzukopieren und die Umgebungsvariable PATH 
entsprechend auf den Pfad ....\utils\bin auszurichten. Denn dort 
befinden sich make & Co, die nicht Bestandteil der avr-gcc-Toolchain 
sind.

Wenn das alles bei Dir nicht funktioniert, dann versuchs doch lieber mit 
einer aktuelleren IDE, z.B. Atmel Studio 6.2. Da hast Du alles 
"all-in-one".

von Bruno M. (brumay)


Lesenswert?

Hallo Frank,
Du gibst Dir wirklich Mühe. Ich bin beeindruckt.

> Merkwürdig. Habe ich noch nie gesehen. Wo liegt er denn? Also in welchem
> Pfad? Ich habe mein WinAVR direkt unter C:\ liegen. Es könnte Probleme
> geben, wenn im Pfad Leerzeichen sind.

Ich habe mir für Dein Projekt die aktuellste Version von WINAVR 
runtergeladen.

Der Pfad ist : C:\WINAVR\avr\bin

Nun aber die gute Nachricht:

Da ich es leid war habe ich mir das Studio 4.18 installiert und siehe da 
alles lief wie geschmiert.

Das diente aber nur zum Testen auf meinem alten XP-Rechner. Eigentlich 
arbeite ich auch schon länger mit Studio 6. Weil ich aber schon mehrfach 
Probleme hatte beim Import von Studio 4 Projekten, hatte ich das gar 
nicht erst versucht.
Nun habe ich aber auch das mit Erfolg gelöst. Importieren klappte zwar 
nicht, aber ein neues Projekt mit Einfügen der Dateien läuft jetzt 
problemlos. Ich mußte allerdings die PROGMEM Variablen von static in 
const ändern.

Nochmals herzlichen Dank für die Unterstützung.

Gruß Bruno

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Nun habe ich aber auch das mit Erfolg gelöst. Importieren klappte zwar
> nicht, aber ein neues Projekt mit Einfügen der Dateien läuft jetzt
> problemlos.

Eben, das habe ich auch so im Artikel IRMP beschrieben. Ist 
einfacher, als ein Projekt zu importieren.

> Ich mußte allerdings die PROGMEM Variablen von static in const ändern.

Wo hast Du denn diese Uralt-Version von IRMP her? Das habe ich bereits 
vor ca. 2 Jahren angepasst.

Hole Dir besser eine aktuelle Version, siehe Artikel.

von Joachim B. (Gast)


Lesenswert?

Bruno M. schrieb:
> Da ich es leid war habe ich mir das Studio 4.18 installiert und siehe da
> alles lief wie geschmiert.

sag ich doch, ich habe 4.19 auch von allen Rechnern runtergeworfen....


freut mich das es klappte 1

und so bin ich auch vorgegangen, neues Projekt und dort alles reingetan, 
klappt eben am Besten.

von Bruno M. (brumay)


Lesenswert?

Frank M. schrieb:

> Wo hast Du denn diese Uralt-Version von IRMP her? Das habe ich bereits
> vor ca. 2 Jahren angepasst.

Sorry, ich hatte mir wohl die aktuelle Version runtergeladen, dann aber 
offensichtlich bei wiederholtem Kopieren Dateien aus einem 
Anwendungsprojekt (IRMP-LCD) genommen.

von Karol B. (johnpatcher)


Lesenswert?

Hi Frank,

was hat es eigentlich mit der Differenz der Versionen im SVN und dem 
Wiki auf sich? Im Wiki ist Version 2.4.0 aktuell, im SVN findet sich 
schon Version 2.6.2 und ein entsprechender Tarball kann heruntergeladen 
werden.

Hast du nur vergessen den Wiki-Artikel zu aktualisieren, oder gibt es 
Gründe warum du Version 2.6.2 noch "zurück" hältst? Nicht, dass ich 
konkrete Probleme hätte, würde aber gerne stets so aktuell wie möglich 
bleiben, um später die notwendigen Anpassungsarbeiten so gering wie 
möglich zu halten.

Wie immer: Super Arbeit, welche du hier ablieferst, weiter so ;).

Mit freundlichen Grüßen,
Karol Babioch

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hi Karol,

Karol Babioch schrieb:

> was hat es eigentlich mit der Differenz der Versionen im SVN und dem
> Wiki auf sich?

Reine Faulheit ;-)

Ich habe mir angewöhnt, im SVN immer einen aktuellen (aber nicht 
instabilen) Stand zu halten, um dann Rückmeldungen (Korrekturen, 
Verbesserungen) der User zu den Neuerungen abzuwarten. Nach einer 
gewissen Zeit "erkläre" ich dann den aktuellen SVN-Stand zur stabilen 
Version und erstelle dann ein neues ZIP-Archiv zum Download und biete es 
im Artikel an.

Sozusagen eine "very stable" Version als Zip, eine "stable" Version im 
SVN. Eine "unstable" gibts nur auf meinem Rechner.

Leider habe ich aus Zeitgründen diese Abstände immer größer werden 
lassen, wobei ich mir denke, dass dies nicht ganz so schlimm ist. In die 
letzten SVN-Versionen sind eher exotische Protokolle wie Klimaanlagen 
mit eingeflossen. Größere Korrekturen an den bereits etablierten 
Protokollen gab es auch nicht.

Ein weiterer Grund für den großen Abstand ist auch die nötige Pflege des 
Artikels. Solange die Zip-Version sich nicht ändert, muss ich im Artikel 
auch nicht soviel ändern - auch wenn ich hier und da durchaus 
Aktualisierungen vornehme, z.B. die "Entschlüsselung" des 
LG-Air-Protokolls, damit man seine Klimaanlage per µC steuern kann.

> Hast du nur vergessen den Wiki-Artikel zu aktualisieren, oder gibt es
> Gründe warum du Version 2.6.2 noch "zurück" hältst? Nicht, dass ich
> konkrete Probleme hätte, würde aber gerne stets so aktuell wie möglich
> bleiben, um später die notwendigen Anpassungsarbeiten so gering wie
> möglich zu halten.

Wenn Dir an Aktualität gelegen ist, nimm einfach die aktuelle 
SVN-Version. Im allgemeinen ist es so, dass ich diese einfach irgendwann 
in das  Download-Zip-Archiv kopiere.

Aber Du hast recht: Es ist mal wieder Zeit für ein Update. Ich schaue, 
dass ich es bis zum Wochenende schaffe.

> Wie immer: Super Arbeit, welche du hier ablieferst, weiter so ;).

Vielen Dank :-)

Gruß,

Frank

von Jörg R. (jrie)


Lesenswert?

Hallo Frank,
hier weitere Änderungen für den STM32F10x.
1
diff -Nru B/irmpsystem.h A/irmpsystem.h
2
--- B/irmpsystem.h      2014-07-21 11:05:03.000000000 +0200
3
+++ A/irmpsystem.h      2014-08-19 00:24:52.346944900 +0200
4
@@ -37,6 +37,7 @@
5
 #  include <stm32f10x.h>
6
 #  define ARM_STM32
7
 #  define ARM_STM32F10X
8
+#  define F_CPU (SysCtlClockGet())
9
 #elif defined(STM32F4XX)                                                            // ARM STM32
10
 #  include <stm32f4xx.h>
11
 #  define ARM_STM32
12
@@ -95,6 +96,13 @@
13
 #  define PROGMEM volatile
14
 #  define memcpy_P memcpy
15
 #  define APP_SYSTICKS_PER_SEC          32
16
+#elif defined(ARM_STM32F10X)
17
+#  include "stm32f10x_gpio.h"
18
+#  include "stm32f10x_rcc.h"
19
+#  include "stm32f10x_tim.h"
20
+#  include "misc.h"
21
+#  define PROGMEM
22
+#  define memcpy_P                      memcpy
23
 #else
24
 #  define PROGMEM
25
 #  define memcpy_P                      memcpy
und für main.c:
1
/*---------------------------------------------------------------------------------------------------------------------------------------------------
2
 * STM32:
3
 *---------------------------------------------------------------------------------------------------------------------------------------------------
4
 */
5
#elif defined(ARM_STM32)
6
7
uint32_t
8
SysCtlClockGet(void)
9
{
10
    RCC_ClocksTypeDef RCC_ClocksStatus;
11
    RCC_GetClocksFreq(&RCC_ClocksStatus);
12
    return RCC_ClocksStatus.SYSCLK_Frequency;
13
}
14
15
void
16
timer2_init (void)
17
{
18
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
19
    NVIC_InitTypeDef NVIC_InitStructure;
20
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
21
22
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
23
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
24
    TIM_TimeBaseStructure.TIM_Period = 7;
25
    TIM_TimeBaseStructure.TIM_Prescaler = ((F_CPU / F_INTERRUPTS)/8) - 1;
26
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
27
28
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
29
30
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
31
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
32
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
33
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
34
    NVIC_Init(&NVIC_InitStructure);
35
36
    TIM_Cmd(TIM2, ENABLE);
37
}
38
39
void
40
TIM2_IRQHandler(void)                                                  // Timer2 Interrupt Handler
41
{
42
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
43
  (void) irmp_ISR();                                                        // call irmp ISR
44
  // call other timer interrupt routines...
45
}
46
47
int
48
main (void)
49
{
50
    IRMP_DATA irmp_data;
51
        
52
    irmp_init();                                                            // initialize irmp
53
    timer2_init();                                                          // initialize timer2
54
55
    for (;;)
56
    {
57
        if (irmp_get_data (&irmp_data))
58
        {
59
            // ir signal decoded, do something here...
60
            // irmp_data.protocol is the protocol, see irmp.h
61
            // irmp_data.address is the address/manufacturer code of ir sender
62
            // irmp_data.command is the command code
63
            // irmp_protocol_names[irmp_data.protocol] is the protocol name (if enabled, see irmpconfig.h)
64
        }
65
    }
66
}
Das sollte jetzt alles gewesen sein :-)
Gruß, Jörg

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Jörg,

Jörg R. schrieb:
> hier weitere Änderungen für den STM32F10x.

Vielen Dank, ich habe die Änderungen übernommen. Kommen in die nächste 
SVN-Version und ins ZIP-Release.

Gute Arbeit!

Gruß,

Frank

von Bruno M. (brumay)


Lesenswert?

Hallo Frank,

nachdem ich Deinen Code im Studio6 zum Laufen gebracht habe und auch die 
Hardware funktioniert, tun sich natürlich neue Frage auf:

Für mich als blutigen Anfänger in 'C' ist das Verstehen des Programms 
eine besondere Herausforderung, insbesondere durch die vielen if's.

Was jetzt funktioniert, ist das Loggen der Daten mittels UART. Wenn ich 
aber nun die Protokollnamen haben möchte, muß dann zwangsläufig auch das 
Loggen gewählt werden? Für mich ist das eine Frage des Speichers.

Gruß Bruno

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Für mich als blutigen Anfänger in 'C' ist das Verstehen des Programms
> eine besondere Herausforderung, insbesondere durch die vielen if's.

Du meinst wohl eher die vielen #if ;-)

Dies ist 2 Dingen geschuldet:

 1. Nur den Code für diejenigen Protokolle compilieren, die auch
    aktiviert sind. Das spart jede Menge Flash und RAM.

 2. Unterstützung von möglichst vielen µCs, u.a. AVR, STM32 und PICs.

> Was jetzt funktioniert, ist das Loggen der Daten mittels UART. Wenn ich
> aber nun die Protokollnamen haben möchte, muß dann zwangsläufig auch das
> Loggen gewählt werden? Für mich ist das eine Frage des Speichers.

Natürlich brauchst Du dafür kein Logging. Dies ist nur dann 
erforderlich, wenn man ein bislang unbekanntes Protokoll analysieren 
möchte. Schalte dies also ab.

Schaue Dir dann die Muster-Main-Datei an. Dort sieht man nach dem Aufruf 
von irmp_get_data(), was zu tun ist, nämlich Protokoll-, Adress und 
Kommando-Vergleich, um dann gezielt zu reagieren.

Viele Grüße,

Frank

von Bruno M. (brumay)


Lesenswert?

Frank M. schrieb:

So lag auch meine Interpretation.

> Schaue Dir dann die Muster-Main-Datei an. Dort sieht man nach dem Aufruf
> von irmp_get_data(), was zu tun ist, nämlich Protokoll-, Adress und
> Kommando-Vergleich, um dann gezielt zu reagieren.

Was passiert aber, wenn kein Protokoll erkannt wird, kommt dann eine 
Negativmeldung oder passiert einfach nichts?

Gruß Bruno

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Was passiert aber, wenn kein Protokoll erkannt wird, kommt dann eine
> Negativmeldung oder passiert einfach nichts?

Bitte schaue Dir im IRMP-Artikel den folgenden Abschnitt an:

  http://www.mikrocontroller.net/articles/IRMP#Anwendung_von_IRMP

Auszug:
1
   if (irmp_get_data (&irmp_data))
2
   {
3
      if (irmp_data.protocol == IRMP_NEC_PROTOCOL &&     // NEC-Protokoll
4
          irmp_data.address == 0x1234)                   // Adresse 0x1234
5
      {
6
         switch (irmp_data.command)
7
         {
8
            case 0x0001: key1_pressed(); break;          // Taste 1
9
            case 0x0002: key2_pressed(); break;          // Taste 2
10
            ...
11
            case 0x0009: key9_pressed(); break;          // Taste 9
12
         }
13
      }
14
   }

irmp_get_data() liefert also TRUE zurück, wenn ein Protokoll erkannt 
wurde, anderenfalls FALSE.

Im obigen Beispiel wird der Block nur durchlaufen, wenn irmp_get_data() 
TRUE zurückliefert.

Dann sollte man das Protokoll und die Adresse überprüfen, anschließend 
die Kommando-Codes, um dann entsprechend eine Aktion auszuführen.

Obige Werte sind natürlich fiktiv. Diese musst Du erst selbst empirisch 
für Deine Fernbedienung ermitteln, um sie dann verwenden zu können. Dazu 
kannst Du die erhaltenen Werte zunächst auf einem Display oder über UART 
ausgeben... oder was Du sonst noch so an Ausgabeschnittstellen hast.

Eine UART-Routine kann ich gerne hier posten, falls gewünscht.

von Bruno M. (brumay)


Lesenswert?

Bedeutet das, daß ich mit

>
1
>    if (irmp_get_data (&irmp_data))
2
>    {
3
>       if (irmp_data.protocol == FALSE
4
>    }
5
>

weiterarbeiten kann?

von Bruno M. (brumay)


Lesenswert?

Hallo Frank,

ich habe es einfach mal probiert, aber so geht es nicht.

Was muß ich tun um eine Negativmeldung ausgeben zu können?

von Karol B. (johnpatcher)


Lesenswert?

Bruno M. schrieb:
> Was muß ich tun um eine Negativmeldung ausgeben zu können?

Die Rückgabe von irmp_get_data() selbst auswerten.

Also in etwa so (ungetestet):
1
if (irmp_get_data(&irmp_data))
2
{
3
    // Es wurde irgendetwas erkannt
4
} else {
5
    // Es wurde nichts erkannt
6
}

Ich bin mir allerdings nicht so recht sicher was du überhaupt bezwecken 
möchtest. irmp_get_data() ruft man i.d.R. regelmäßig auf und es wird 
wohl weit aus öfter false zurück liefern als umgekehrt.

Mit freundlichen Grüßen,
Karol Babioch

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


Lesenswert?

Bruno M. schrieb:
> Bedeutet das, daß ich mit
>
>>
1
>>    if (irmp_get_data (&irmp_data))
2
>>    {
3
>>       if (irmp_data.protocol == FALSE
4
>>    }
5
>>
>
> weiterarbeiten kann?

Das erste if ist richtig. Dann wurden Daten empfangen und erkannt.

Bedenke auch: irmp_get_data() wartet nicht, sondern kommt sofort zurück, 
wenn nichts empfangen wurde!

Wenn Du warten willst:
1
     while (! irmp_get_data (&irmp_data))
2
     {
3
          ;                // warten
4
     }

Das zweite if ist falsch. Hier musst Du auf einen Wert prüfen, nämlich 
die Protokollnummer. IRMP unterstützt ca. 40 Protokolle. In 
irmp_data.protocol steht dann die erkannte Protokollnummer. Wenn Du sie 
nicht weisst, solltest Du erstmal alle Werte ausgeben, die Deine FB 
sendet, z.b. so:
1
    if (irmp_get_data (&irmp_data))
2
    {
3
        gebeWertaus (irmp_data.command);
4
        gebeWertaus (irmp_data.address);
5
        gebeWertaus (irmp_data.command);
6
        gebeWertaus (irmp_data.flags);
7
    }

Die Funktion gebeWertAus() musst Du selber schreiben, denn ich weiß ja 
nicht, was Du für Hardware benutzt.

Hier siehst Du das z.B. auf Youtube:

  https://www.youtube.com/watch?v=Q7DJvLIyTEI

Wenn Du dann alle Werte hast, kannst Du sie benutzen. Nehmen wir an, Du 
hast empfangen: Protokoll = 2, Adresse = 0x1234 mit

   Kommando = 0x1111   für Taste 1
   Kommando = 0x1112   für Taste 2

Dann kannst Du nun statt dem obigen Block schreiben:
1
    if (irmp_get_data (&irmp_data))
2
    {
3
        if (irmp_data.protocol == 2 && irmp_data.address == 0x1234)
4
        {
5
            switch (irmp_data.command)
6
            {
7
                case 0x1111: led_aus(); break;
8
                case 0x1112: led_an();  break;
9
            }
10
        }
11
    }

Die Funktionen led_aus() und led_an() sind natürlich nur Beispiele.

: Bearbeitet durch Moderator
von Karol B. (johnpatcher)


Lesenswert?

Frank M. schrieb:
> Das zweite if ist falsch.

Ich mag die Frage falsch verstanden haben, aber nach meiner Auffassung 
will er gerade denjenigen Fall abdecken, in welchem IRMP nichts erkannt 
hat, d.h. die Rückgabe von "irmp_get_data()" false ist.

Mit freundlichen Grüßen,
Karol Babioch

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karol Babioch schrieb:
> Ich mag die Frage falsch verstanden haben, aber nach meiner Auffassung
> will er gerade denjenigen Fall abdecken, in welchem IRMP nichts erkannt
> hat, d.h. die Rückgabe von "irmp_get_data()" false ist.

Okay, den hast Du ja schon beschrieben.

Das Wichtigste: irmp_get_data() wartet nicht.

Wenn man unbedingt warten will:
1
     while (1)                // Hauptschleife
2
     {
3
         ...
4
5
         while (! irmp_get_data (&irmp_data))
6
         {
7
             ;                // warten
8
         }
9
10
         // Jetzt wurde etwas empfangen
11
         verarbeite_daten();
12
     }

Wenn man zwischendurch etwas anderes machen will:
1
     while (1)                // Hauptschleife
2
     {
3
         if (irmp_get_data (&irmp_data))
4
         {
5
             // Jetzt wurde etwas empfangen
6
             verarbeite_daten();
7
         }
8
         else
9
         {
10
              tue_was_anderes ();
11
         }
12
     }

Es kommt also immer auf den Anwendungsfall an.

: Bearbeitet durch Moderator
von Bruno M. (brumay)


Lesenswert?

Ich glaube ich muß meine Frage doch noch etwas präzisieren. Wenn ich es 
richtig verstande4n habe, wird mit

if (irmp_get_data (&irmp_data))

auf ein IR Signal gewartet. Wenn es kommt, kann ich das Signal weiter 
auswerten.
Mir geht es aber jetzt nicht darum festzustellen, ob ein IR Signal 
empfangen wurde (das kann ich ja mit dem Loggen sehr einfach 
überprüfen), sondern ich möchte wissen ob ein passendes Protokoll 
gefunden wurde. Ich kann ja aus der Vielzahl der möglichen Protokolle 
einige auswählen, andere nicht. Das hängt ja schon davon ab wieviel 
Speicher man zur Verfügung hat.
Habe ich also das richtige Protokoll nicht eingeschlossen, reagiert IRMP 
gar nicht. Da hat man (oder auch nur ich) nun am Anfang das Problem, daß 
man nicht genau weiß warum IRMP nicht reagiert. Vielleicht liegt es ja 
auch nur an meinem Code.
Ich habe mir deshalb gedacht, es wäre sinnvoll eine Info zu bekommen, 
wenn zwar ein Signal empfangen wurde, aber kein passendes Protokoll 
gefunden wurde. Diese Info kann ich dann über UART ausgeben und eine 
andere Auswahl bei den Protokollen treffen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Habe ich also das richtige Protokoll nicht eingeschlossen, reagiert IRMP
> gar nicht.

Schalte am Anfang soviele Protokolle frei wie möglich. Also alle 
"typical protocols" (4 Stück) und die unter "more protocols" angegebenen 
(9 Stück).

Damit hast Du dann eine 95%-ige Chance, dass IRMP den Code kennt. 
Anschließend kannst Du die nicht benötigten Protokolle wieder 
deaktivieren.

Alternativ kopierst Du hier eine Zeile aus dem LOGGING-Protokoll rein. 
Ich brauche keine Minute, um festzustellen, ob IRMP das Protokoll 
versteht und welches das ist.

: Bearbeitet durch Moderator
von Bruno M. (brumay)


Lesenswert?

Inzwischen bin ich ein Stückchen weiter. Ich habe jetzt mal protocol und 
command abgefragt und bekomme bei einer Fernbedienung als Ausgabe 16 und 
10, bei der anderen nichts. Bedeutet 16 nun das NOKIA Protokoll?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Inzwischen bin ich ein Stückchen weiter. Ich habe jetzt mal protocol und
> command abgefragt und bekomme bei einer Fernbedienung als Ausgabe 16 und
> 10, bei der anderen nichts. Bedeutet 16 nun das NOKIA Protokoll?

10 = SAMSUNG32
16 = Nokia

Siehe auch irmpprotocols.h. Da stehen sie alle direkt am Anfang drin.

Insofern kann ich Deine Frage mit "Ja" beantworten :-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Frank M. schrieb:
>> Inzwischen bin ich ein Stückchen weiter. Ich habe jetzt mal protocol und
>> command abgefragt und bekomme bei einer Fernbedienung als Ausgabe 16 und
>> 10, bei der anderen nichts. Bedeutet 16 nun das NOKIA Protokoll?

Achso, 10 ist bei Dir ein empfangenes Kommando, nicht eine 
Protokollnummer.

Du solltest aber protocol immer in Kombination mit der Adresse abfragen. 
Denn es könnte durchaus Fernbedienungen in Deinem Haushalt geben, die 
dasselbe Protokoll (z.B. Fernseher und DVD-Player) sprechen, aber 
unterschiedliche Adressen verwenden. Wenn die Adresse verschieden ist, 
kannst Du davon ausgehen, dass gleiche Kommando-Codes nicht von 
derselben Fernbedienung stammen.

Also: Die meisten FBs senden immer dasselbe Protokoll und dieselbe 
Adresse - egal welche Taste gedrückt ist.[*]

Wenn Du diese prüfst, kannst Du davon ausgehen, dass der Anwender die 
richtige Fernbedienung in den Händen hat.

[*] Ausnahmen bestätigen die Regel.

: Bearbeitet durch Moderator
von Bruno M. (brumay)


Lesenswert?

Hallo Frank,
bis hierhin schon mal herzlichen Dank. Ich hatte keine Ahnung, daß 
Fernbedienungen so viel Spaß machen können. Ich habe jetzt mal etwas 
variiert und bekomme nur bei protocol die zwei Werte 10 und 16 
hintereinander. Wenn ich command hinzunehme und zwei bestimmte Tasten 
drücke, bekomme ich folgende ASCII Anzeige.

(10) (16) UNKNOWN (10)
(10) (16) SAMSG32 (10) (die Zahlenwerte sind DEZ)

Welche Erklärung hast Du dafür?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> bis hierhin schon mal herzlichen Dank. Ich hatte keine Ahnung, daß
> Fernbedienungen so viel Spaß machen können. Ich habe jetzt mal etwas
> variiert und bekomme nur bei protocol die zwei Werte 10 und 16
> hintereinander.

Von ein- und derselben FB bekommst Du 2 verschiedene Protokollnummern? 
Zu 99% kann ich das nicht glauben ;-)

> Wenn ich command hinzunehme und zwei bestimmte Tasten
> drücke, bekomme ich folgende ASCII Anzeige.
>
> (10) (16) UNKNOWN (10)
> (10) (16) SAMSG32 (10) (die Zahlenwerte sind DEZ)

Warum wird einmal UNKNOWN und einmal SAMSG32 ausgegeben, obwohl die 
Zahlenwerte identisch sind?

Welche Tasten sind das? Was ist das für eine Fernbedienung?

Zeige bitte mal Dein dazugehörendes Programm im Ausschnitt, also z.B. 
die while-Hauptschleife. Ich vermute da eher den Fehler.

von Bruno M. (brumay)


Lesenswert?

Frank M. schrieb:

> Warum wird einmal UNKNOWN und einmal SAMSG32 ausgegeben, obwohl die
> Zahlenwerte identisch sind?
>
> Welche Tasten sind das? Was ist das für eine Fernbedienung?

Es ist die FB für einen Panasonic DVD Player und es sind die Tasten 
'Pause' und 'Play'


> Zeige bitte mal Dein dazugehörendes Programm im Ausschnitt, also z.B.
> die while-Hauptschleife. Ich vermute da eher den Fehler.

[c]
for (;;)
    {
        if (irmp_get_data (&irmp_data))
        {
         irmp_uart_putc(0x0a);
    irmp_uart_puts(irmp_data.protocol);
    //irmp_uart_puts(irmp_data.address);
    //irmp_uart_puts(irmp_data.command);
    irmp_uart_putc(0x0a);
  }
    }
[c/]

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
>     irmp_uart_puts(irmp_data.protocol);

irmp_uart_puts() erwartet einen String und keine Nummer.

>     //irmp_uart_puts(irmp_data.address);

Dito.

>     //irmp_uart_puts(irmp_data.command);

Dito.

Das erklärt das Verhalten. Du bekommst absoluten Unsinn zu sehen. Die 
übergebene Nummer wird als String-Adresse interpretiert und damit greift 
irmp_uart_puts() irgendwo in Deinen Speicher und versucht das als String 
auszugeben, was da zufälligerweise rumliegt.

Du hast da keine Compiler-Warnung bekommen???

Ausserdem benutzt Du da die IRMP-Logging-Funktionen. Da hauen Dir ja 
noch jede Menge 1en und 0en in den Output. Nicht schön.

Schalte das Logging aus (das ist nur für Analysezwecke) und ersetze den 
kompletten(!) Inhalt Deines main.c mal durch diesen:
1
#include "irmp.h"
2
#define BAUD  9600L
3
#include <util/setbaud.h>
4
5
#ifdef UBRR0H
6
7
#define UART0_UBRRH                             UBRR0H
8
#define UART0_UBRRL                             UBRR0L
9
#define UART0_UCSRA                             UCSR0A
10
#define UART0_UCSRB                             UCSR0B
11
#define UART0_UCSRC                             UCSR0C
12
#define UART0_UDRE_BIT_VALUE                    (1<<UDRE0)
13
#define UART0_UCSZ1_BIT_VALUE                   (1<<UCSZ01)
14
#define UART0_UCSZ0_BIT_VALUE                   (1<<UCSZ00)
15
#ifdef URSEL0
16
#define UART0_URSEL_BIT_VALUE                   (1<<URSEL0)
17
#else
18
#define UART0_URSEL_BIT_VALUE                   (0)
19
#endif
20
#define UART0_TXEN_BIT_VALUE                    (1<<TXEN0)
21
#define UART0_UDR                               UDR0
22
#define UART0_U2X                               U2X0
23
        
24
#else
25
26
#define UART0_UBRRH                             UBRRH
27
#define UART0_UBRRL                             UBRRL
28
#define UART0_UCSRA                             UCSRA
29
#define UART0_UCSRB                             UCSRB
30
#define UART0_UCSRC                             UCSRC
31
#define UART0_UDRE_BIT_VALUE                    (1<<UDRE)
32
#define UART0_UCSZ1_BIT_VALUE                   (1<<UCSZ1)
33
#define UART0_UCSZ0_BIT_VALUE                   (1<<UCSZ0)
34
#ifdef URSEL
35
#define UART0_URSEL_BIT_VALUE                   (1<<URSEL)
36
#else
37
#define UART0_URSEL_BIT_VALUE                   (0)
38
#endif
39
#define UART0_TXEN_BIT_VALUE                    (1<<TXEN)
40
#define UART0_UDR                               UDR
41
#define UART0_U2X                               U2X
42
43
#endif //UBRR0H
44
45
static void
46
uart_init (void)
47
{
48
    UART0_UBRRH = UBRRH_VALUE;                                                                      // set baud rate
49
    UART0_UBRRL = UBRRL_VALUE;
50
51
#if USE_2X
52
    UART0_UCSRA |= (1<<UART0_U2X);
53
#else
54
    UART0_UCSRA &= ~(1<<UART0_U2X);
55
#endif
56
57
    UART0_UCSRC = UART0_UCSZ1_BIT_VALUE | UART0_UCSZ0_BIT_VALUE | UART0_URSEL_BIT_VALUE;
58
    UART0_UCSRB |= UART0_TXEN_BIT_VALUE;                                                            // enable UART TX
59
}
60
61
static void
62
uart_putc (unsigned char ch)
63
{
64
    while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE))
65
    {
66
        ;
67
    }
68
69
    UART0_UDR = ch;
70
}
71
72
static void
73
uart_puts (unsigned char * s)
74
{
75
    while (*s)
76
    {
77
        uart_putc (*s);
78
        s++;
79
    }
80
}
81
82
static uint8_t
83
itox (uint8_t val)
84
{
85
    uint8_t rtc;
86
87
    val &= 0x0F;
88
89
    if (val <= 9)
90
    {
91
        rtc = val + '0';
92
    }
93
    else
94
    {
95
        rtc = val - 10 + 'A';
96
    }
97
    return (rtc);
98
}
99
100
static void
101
itoxx (unsigned char * xx, unsigned char i)
102
{
103
    *xx++ = itox (i >> 4);
104
    *xx++ = itox (i & 0x0F);
105
    *xx = '\0';
106
}
107
108
static void
109
timer1_init (void)
110
{
111
#if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__)                // ATtiny45 / ATtiny85:
112
113
#if F_CPU >= 16000000L
114
    OCR1C   =  (F_CPU / F_INTERRUPTS / 8) - 1;                              // compare value: 1/15000 of CPU frequency, presc = 8
115
    TCCR1   = (1 << CTC1) | (1 << CS12);                                    // switch CTC Mode on, set prescaler to 8
116
#else
117
    OCR1C   =  (F_CPU / F_INTERRUPTS / 4) - 1;                              // compare value: 1/15000 of CPU frequency, presc = 4
118
    TCCR1   = (1 << CTC1) | (1 << CS11) | (1 << CS10);                      // switch CTC Mode on, set prescaler to 4
119
#endif
120
121
#else                                                                       // ATmegaXX:
122
    OCR1A   =  (F_CPU / F_INTERRUPTS) - 1;                                  // compare value: 1/15000 of CPU frequency
123
    TCCR1B  = (1 << WGM12) | (1 << CS10);                                   // switch CTC Mode on, set prescaler to 1
124
#endif
125
126
#ifdef TIMSK1
127
    TIMSK1  = 1 << OCIE1A;                                                  // OCIE1A: Interrupt by timer compare
128
#else
129
    TIMSK   = 1 << OCIE1A;                                                  // OCIE1A: Interrupt by timer compare
130
#endif
131
}
132
133
#ifdef TIM1_COMPA_vect                                                      // ATtiny84
134
#define COMPA_VECT  TIM1_COMPA_vect
135
#else
136
#define COMPA_VECT  TIMER1_COMPA_vect                                       // ATmega
137
#endif
138
139
ISR(COMPA_VECT)                                                             // Timer1 output compare A interrupt service routine, called every 1/15000 sec
140
{
141
  (void) irmp_ISR();                                                        // call irmp ISR
142
  // call other timer interrupt routines...
143
}
144
145
int
146
main (void)
147
{
148
    IRMP_DATA irmp_data;
149
    unsigned char buf[3];
150
151
    irmp_init();                                                            // initialize irmp
152
    timer1_init();                                                          // initialize timer1
153
    uart_init();                                                            // initialize uart
154
155
    sei ();                                                                 // enable interrupts
156
157
    for (;;)
158
    {
159
        if (irmp_get_data (&irmp_data))
160
        {
161
            uart_puts ((unsigned char *) "protocol: 0x");
162
            itoxx (buf, irmp_data.protocol);
163
            uart_puts (buf);
164
165
            uart_puts ((unsigned char *) "   address: 0x");
166
            itoxx (buf, irmp_data.address >> 8);
167
            uart_puts (buf);
168
            itoxx (buf, irmp_data.address & 0xFF);
169
            uart_puts (buf);
170
171
            uart_puts ((unsigned char *) "   command: 0x");
172
            itoxx (buf, irmp_data.command >> 8);
173
            uart_puts (buf);
174
            itoxx (buf, irmp_data.command & 0xFF);
175
            uart_puts (buf);
176
177
            uart_puts ((unsigned char *) "   flags: 0x");
178
            itoxx (buf, irmp_data.flags);
179
            uart_puts (buf);
180
181
            uart_puts ((unsigned char *) "\r\n");
182
        }
183
    }
184
}

Da sind entsprechende UART-Routinen drin, die unabhängig vom 
IRMP-Logging arbeiten. Ausserdem werden die Nummern hier in Hexwerte in 
Form von Strings gewandelt, die dann ausgegeben werden.

Wenn das dann funktioniert, Dir aber die Hex-Ausgabe nicht behagt, 
kannst Du dann in einem 2. Schritt die Aufrufe von itoxx() durch itoa() 
ersetzen (Achtung, andere Parameter!).

von Bruno M. (brumay)


Lesenswert?

Frank M. schrieb:

> Du hast da keine Compiler-Warnung bekommen???

der Compiler hat sich nicht gerührt!

> Ausserdem benutzt Du da die IRMP-Logging-Funktionen. Da hauen Dir ja
> noch jede Menge 1en und 0en in den Output. Nicht schön.
>
> Schalte das Logging aus (das ist nur für Analysezwecke) und ersetze den
> kompletten(!) Inhalt Deines main.c mal durch diesen:

Das Logging ist ausgeschaltet!
Ich habe aber die komlette UART Funktion aus irmp.c nach main.c 
verschoben.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Das Logging ist ausgeschaltet!
> Ich habe aber die komlette UART Funktion aus irmp.c nach main.c
> verschoben.

Achso... und weiterhin gleich genannt. Damit hast Du mich natürlich aufs 
Glatteis geführt. ;-)

Trotzdem hätte der Compiler meckern müssen, denn der Aufruf mit falschen 
Parametern kann einen Fehler bewirken, der hier (also in diesem 
speziellen Falle) ganz offensichtlich ist.

Wenn ich es probiere, bekomme ich sofort eine Warnung:
1
uart_puts (irmp_data.address);
2
3
../main.c:178:1: warning: passing argument 1 of 'uart_puts' makes pointer from integer without a cast [enabled by default]
4
../main.c:74:1: note: expected 'unsigned char *' but argument is of type 'uint16_t'

Schau mal unten in die Ausgabe Deiner IDE, da gibt es normalerweise noch 
"Reiter", mit denen man die Ansicht des Ausgabefensters ändern kann. 
Vermutlich schaust Du Dir den falschen Output an.

In meiner main.c (s. oben) habe ich die irmp_uart_xxxx() Funktionen in 
uart_xxx() (also ohne Prefix irmp_) umbenannt, damit es da keine 
Missverständnisse bzw. Konflikte gibt. Ausserdem habe ich sie auf die 
Zeilen eingestampft, die man im konkreten Fall (AVR) überhaupt braucht.

Versuche bitte mal meine Fassung von main.c (s. Posting oben) und 
berichte.

: Bearbeitet durch Moderator
von Bruno M. (brumay)


Lesenswert?

Frank M. schrieb:

> Versuche bitte mal meine Fassung von main.c (s. Posting oben) und
> berichte.

Ja, so sieht das natürlich ganz professionell aus. Jetzt ist es auch 
nicht mehr das Protokoll 10 oder 16, sondern 02.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Frank M. schrieb:
>
>> Versuche bitte mal meine Fassung von main.c (s. Posting oben) und
>> berichte.
>
> Ja, so sieht das natürlich ganz professionell aus. Jetzt ist es auch
> nicht mehr das Protokoll 10 oder 16, sondern 02.

Also NEC. Das klingt plausibel für Deine Panasonic-FB. Na also, dann 
hast Du ja die Haupthürde geschafft :-)

von Bruno M. (brumay)


Lesenswert?

Frank M. schrieb:

> Schau mal unten in die Ausgabe Deiner IDE, da gibt es normalerweise noch
> "Reiter", mit denen man die Ansicht des Ausgabefensters ändern kann.
> Vermutlich schaust Du Dir den falschen Output an.

Ich habe mein main.c nochmals laufen lassen und bekomme tatsächlich 
entsprechende Warnungen, aber keine Fehler, die einen Abbruch auslösen.

von Karol B. (johnpatcher)


Lesenswert?

Bruno M. schrieb:
> Ich habe mein main.c nochmals laufen lassen und bekomme tatsächlich
> entsprechende Warnungen, aber keine Fehler, die einen Abbruch auslösen.

Deswegen sind beim gcc die Compiler-Flags -Wall und -Werror immer eine 
gute Idee ;).

Mit freundlichen Grüßen,
Karol Babioch

von Jörg R. (jrie)


Lesenswert?

Logging für den STM32F10x:
1
diff -Nru A/irmp.c B/irmp.c
2
--- A/irmp.c  2014-08-28 01:54:03.770837120 +0200
3
+++ B/irmp.c  2014-08-28 01:54:08.585836842 +0200
4
@@ -564,6 +564,9 @@
5
 #  define  STM32_UART_COM     USART2
6
 #  define  STM32_UART_BAUD    115200                                  // mit 115200 Baud
7
 #  include "stm32f4xx_usart.h"
8
+#elif defined(ARM_STM32F10X)
9
+#  define  STM32_UART_COM     USART3                                  // UART3 an PB10
10
+#  include "stm32f10x_usart.h"
11
 #else
12
 #  if IRMP_EXT_LOGGING == 1                                           // use external logging
13
 #    include "irmpextlog.h"
14
@@ -661,7 +664,38 @@
15
 
16
     // UART enable
17
     USART_Cmd(STM32_UART_COM, ENABLE);
18
+#elif defined(ARM_STM32F10X)
19
+    GPIO_InitTypeDef GPIO_InitStructure;
20
+    USART_InitTypeDef USART_InitStructure;
21
+
22
+    // Clock enable vom TX Pin
23
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // UART3 an PB10
24
+
25
+    // Clock enable der UART
26
+    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
27
+
28
+    // UART als Alternative-Funktion mit PushPull
29
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
30
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
31
+
32
+    // TX-Pin
33
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
34
+    GPIO_Init(GPIOB, &GPIO_InitStructure);
35
+
36
+    // Oversampling
37
+    USART_OverSampling8Cmd(STM32_UART_COM, ENABLE);
38
+
39
+    // init mit Baudrate, 8Databits, 1Stopbit, keine Parität, kein RTS+CTS
40
+    USART_InitStructure.USART_BaudRate = 115200;
41
+    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
42
+    USART_InitStructure.USART_StopBits = USART_StopBits_1;
43
+    USART_InitStructure.USART_Parity = USART_Parity_No;
44
+    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
45
+    USART_InitStructure.USART_Mode = USART_Mode_Tx;
46
+    USART_Init(STM32_UART_COM, &USART_InitStructure);
47
 
48
+    // UART enable
49
+    USART_Cmd(STM32_UART_COM, ENABLE);
50
 #else
51
 #if (IRMP_EXT_LOGGING == 0)                                                                         // use UART
52
     UART0_UBRRH = UBRRH_VALUE;                                                                      // set baud rate
53
@@ -692,7 +726,7 @@
54
 irmp_uart_putc (unsigned char ch)
55
 {
56
 #ifndef UNIX_OR_WINDOWS
57
-#if defined(ARM_STM32F4XX)
58
+#if defined(ARM_STM32F4XX) || defined(ARM_STM32F10X)
59
     // warten bis altes Byte gesendet wurde
60
     while (USART_GetFlagStatus(STM32_UART_COM, USART_FLAG_TXE) == RESET)
61
     {
Gruß, Jörg

von E. K. (eku)


Lesenswert?

Hallo Frank,

die Definition von irmp_protocol_names führt auf AVR MCUs dazu, dass die 
Strings beim Start vom FLASH ins RAM dupliziert werden. Das vereinfacht 
zwar den Zugriff, verschwendet aber wertvollen RAM.

Besser ist folgende Implementierung:
1
static const char proto_unknown[] PROGMEM = "unknown";
2
static const char proto_sircs[] PROGMEM = "SIRCS";
3
static const char proto_nec[] PROGMEM = "NEC";
4
.....
5
6
const PGM_P const irmp_proto_names[] PROGMEM = {
7
  proto_unknown,
8
  proto_sircs,
9
  proto_nec,
10
....
11
};
12
13
14
15
  printf_P(PSTR("IRMP RX: proto %02" PRId8 " %S, address %04" PRIX16
16
                ", command %04" PRIX16 ", flags %02" PRIX8 "\n"),
17
           irmp_data_p->protocol,
18
           pgm_read_word(&irmp_proto_names[irmp_data_p->protocol]),
19
           irmp_data_p->address, irmp_data_p->command, irmp_data_p->flags);

von Karol B. (johnpatcher)


Lesenswert?

E. K. schrieb:
> Das vereinfacht
> zwar den Zugriff, verschwendet aber wertvollen RAM.

Ja.

E. K. schrieb:
> Besser ist folgende Implementierung:

Naja, ganz so einfach ist es dann doch nicht - zumindest wenn man 
plattformübergreifend funktionieren möchte ;).

E. K. schrieb:
> const PGM_P const irmp_proto_names[] PROGMEM = {

Zunächst einmal ist das hier doppelt gemoppelt. PGM_P ist bereits als 
"const char*" definiert, insofern kann man sich das erste (!) const 
sparen.

Das Problem ist aber, dass es pgm_read_word() auf anderen Plattformen 
nicht gibt. Man müsste also irgendwelche Hilfskonstrukte einführen, oder 
aber das Ganze von der aktuellen Plattform abhängig machen, was ggf. 
etwas unübersichtlich werden kann.

Prinzipiell halte ich das aber auch für eine gute Idee, weil das in etwa 
150 Byte RAM sind, der auch sinnvoller verwendet werden kann ;). Ich bin 
mir nur nicht sicher was die beste Option ist, um möglichst plattform 
kompatibel zu bleiben. Da hat Frank ggf. mehr Erfahrung bzw. bessere 
Ideen.

Mit freundlichen Grüßen,
Karol Babioch

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

E. K. schrieb:
> die Definition von irmp_protocol_names führt auf AVR MCUs dazu, dass die
> Strings beim Start vom FLASH ins RAM dupliziert werden. Das vereinfacht
> zwar den Zugriff, verschwendet aber wertvollen RAM.

Hm, ich hab das wohl übersehen. Normalerweise achte ich auf so etwas. 
Hat wohl historische Gründe - weil ich das Array ursprünglich nur für 
den Analyze-Modus auf dem PC brauchte.

Karol Babioch schrieb:
> Das Problem ist aber, dass es pgm_read_word() auf anderen Plattformen
> nicht gibt. [...]
> Da hat Frank ggf. mehr Erfahrung bzw. bessere Ideen.

Ja, normalerweise mache ich das mit

#define PROGMEM

auf Zielplattformen != AVR.

Ich kümmere mich drum. Im Moment bin ich aber ziemlich ausgelastet.

von SvenK (Gast)


Angehängte Dateien:

Lesenswert?

Hallo an Alle,

zuerst mal vielen Dank an die IRMP-Macher für die vielen wertvollen 
Infos. Möge sich Euer Sehspektrum immer weiter ins Langwellige 
vergrößern ;-)

Nach einigen Schwierigkeiten habe ich IRMP auf einem ATmega 1284P mit 8 
Mhz (auf Pollin Eval-Board) laufen und konnte mir von diversen 
Fernbedienungen (Samsung TV, Yamaha Receiver) die Codes auf einem LCD 
darstellen.

Ich benötige nun für ein Projekt die Codes der Fernbedienung eines JVC 
KW-NX7000 Navis. Die Fernbedienung mit dem Namen RM-RX250 wird aber 
leider nicht korrekt erkannt. Manchmal kam „Telefunken“, aber bei 
verschiedenen Tasten immer genau derselbe Code, teilweise auch kam auch 
„Siemens“ – alle Tasten gleicher Code

Mit der IRMP.exe auf dem PC analysiert erhalte ich eine weitere 
„Eigenartigkeit“:
Im Artikel bei Mikrocontroller.net sind die „dimensionslosen Zahlen“ 
1/100 der Zeit in µs
z.B.
1
 pulse avg: 91.0=9102.8 us
Bei mir sind es 1,5/100 !? – unabhängig von der Logging-Frequenz (10, 15 
oder 20 kHz)
z.B.
1
 pulse avg: 40.8=2720.0 us

Ich habe die Loggings der nötigen Befehle in einer ZIP-Datei angehäng – 
mit 10kHz jeweils 5-mal hintereinander aufgenommen und zusätzich nochmal 
alle zusammengefasst in einer Datei - falls das hilfreicher ist.

Einige Tasten der FB ergeben „kurze“ Sequenzen, andere ca. doppelt so 
lange.

Falls jdm damit etwas anfangen kann und mir einen Tip geben könnte, wie 
ich da weiterkomme wäre es schön wenn er sich melden würde.

Vielen Dank schon mal

SvenK

P.S.: die oben genannten Schwierigkeiten hatte ich bei der RS232 
Übertragung. Mit „U2X“ kam nichts oder nur „Matsch“ im PC an – ohne 
„U2X“ läuft es problemlos !?

von Karol B. (johnpatcher)


Lesenswert?

SvenK schrieb:
> Falls jdm damit etwas anfangen kann und mir einen Tip geben könnte, wie
> ich da weiterkomme wäre es schön wenn er sich melden würde.

Das müsste sich Frank mal genauer ansehen, der ist hier der Experte was 
die verschiedenen Protokolle und deren Dekodierung angeht ;).

SvenK schrieb:
> P.S.: die oben genannten Schwierigkeiten hatte ich bei der RS232
> Übertragung. Mit „U2X“ kam nichts oder nur „Matsch“ im PC an – ohne
> „U2X“ läuft es problemlos !?

Dies sollte eigentlich nicht der Fall sein. Das U2X Bit verkleinert den 
Baudraten-Teiler und verdoppelt damit die Frequenz. Für das Senden von 
Daten sollte das eigentlich überhaupt keine Konsequenz haben. Es wirkt 
sich laut Datenblatt nur auf das Empfangen von Daten aus, da es weniger 
Samples gibt.

Sicher, dass alle anderen Einstellungen (z.B. Baud Rate) stimmen und 
auch die richtigen Werte in den UBRR Registern stehen? Die Werte 
unterscheiden sich - je nachdem ob U2X gesetzt ist, oder eben nicht. 
Entweder händisch berechnen, die Tabelle im Datenblatt benutzen, oder 
die Hilfsfunktionalität aus <util/setbaud.h> benutzen, um Fehler zu 
vermeiden.

Mit welcher IDE entwickelst du? Hast du sicherheitshalber das Projekt 
einmal "gesäubert" und komplett neu kompiliert? Damit habe ich schon so 
allerlei unerklärliche Symptome beheben können, unter anderem auch 
Unstimmigkeiten in der Baud Rate, die sich in dem von dir beschriebenem 
Problem geäußert haben.

Mit freundlichen Grüßen,
Karol Babioch

: Bearbeitet durch User
von SvenK (Gast)


Lesenswert?

Hallo Karol,

danke für Deine Antwort. Ich arbeite mit AVR-Studio 6.1 bis dato 
funktionierte das auch immer ganz gut.

Mit der Holzhammermethode:
1
#if (IRMP_EXT_LOGGING == 0) //  use UART
2
UBRR0H  = 0;                   //  9600 Baud
3
UBRR0L  = 103;                 //  51 ohne / 103 mit U2X
4
UCSR0A |= (1<<1);              //  U2X
5
//         76543210
6
UCSR0C = 0b10000110;
7
UCSR0B = 0b00001000;

geht es jetzt auch mit U2X.

Den Rest der ganzen "#ifdef's in der Nähe" habe ich dann alle zu 
Kommentaren degradiert. Das könnte man wohl für diesen Bereich als 
"gesäubert" bezeichnen!?

Ansonsten habe ich die ganzen Möglichkeiten für Windows,Linux,Pic,STM 
etc. bis jetzt dringelassen, da der Rest ja (mit anderen 
Fernbedienungen) funktioniert.

...dann bin ich mal gespannt, ob Frank sich rührt / mit meinen Loggings 
was anfangen kann...

Viele Grüße

Sven

von Bruno M. (brumay)


Lesenswert?

Nachdem Frank so freundlich war mir ein UART-main hier reinzustellen, 
funktioniert das problemlos. Aber, der Mensch verlangt ja immer mehr und 
jetzt stehe ich wieder vor einem "C" Problem.

Ich habe versucht die Ausgabe um die Protokollnamen zu erweitern und 
dazu folgendes eingegeben:
1
uart_puts ((unsigned char *) "protocol: 0x");
2
      itoxx (buf, irmp_data.protocol);
3
      uart_puts (buf);
4
      uart_puts ((unsigned char *) " = ");
5
      uart_puts ((unsigned char *) irmp_protocol_names[irmp_data.protocol]);

Wenn ich dabei "define IRMP_PROTOCOL_NAMES" auf 1 stelle funktioniert 
das auch super. Stelle ich aber statt dessen "define IRMP_LOGGING" auf 1 
beschwert sich der Compiler, daß irmp_protocol_names nicht definiert 
ist, obwohl ich zusätzlich vor der gesamten Ausgabe ein

#if defined IRMP_PROTOCOL_NAMES == 1

gesetzt habe. Was muß ich tun um das zu bereinigen?

von Karol B. (johnpatcher)


Lesenswert?

Bruno M. schrieb:
> Wenn ich dabei "define IRMP_PROTOCOL_NAMES" auf 1 stelle funktioniert
> das auch super.

Ja, so ist das innerhalb der irmp.c auch definiert:
1
#if defined(UNIX_OR_WINDOWS) || IRMP_PROTOCOL_NAMES == 1
2
const char *
3
irmp_protocol_names[IRMP_N_PROTOCOLS + 1] =
4
// ...

Bruno M. schrieb:
> Stelle ich aber statt dessen "define IRMP_LOGGING" auf 1
> beschwert sich der Compiler,

Wie kommst du darauf, dass sie die beiden Optionen ausschließen bzw. 
warum schreibst du von "statt dessen"?

Bruno M. schrieb:
> obwohl ich zusätzlich vor der gesamten Ausgabe ein
>
> #if defined IRMP_PROTOCOL_NAMES == 1

Wozu? Übrigens verwendest du "defined" hier falsch. Damit prüfst du, ob 
ein bestimmtes Makro definiert ist, und nicht dessen Wert. Korrekt wäre
1
#if defined IRMP_PROTOCOL_NAMES && IRMP_PROTOCOL_NAMES == 1

Wobei man die Überprüfung mittels defined i.d.R. weglässt, da es zu 0 
ausgewertet wird, wenn das Makro nicht existiert, siehe [1].

Bruno M. schrieb:
> Was muß ich tun um das zu bereinigen?

Setzt doch einfach beides auf 1?

Mit freundlichen Grüßen,
Karol Babioch

[1]: https://gcc.gnu.org/onlinedocs/cpp/Defined.html

von Bruno M. (brumay)


Lesenswert?

Hallo Karol,

danke für die Hinweise!

> Setzt doch einfach beides auf 1?

das geht nicht, da es mein Speicher nicht zuläßt.

Gruß Bruno

von Karol B. (johnpatcher)


Lesenswert?

Bruno M. schrieb:
> das geht nicht, da es mein Speicher nicht zuläßt.

Von welcher Plattform und welchem Speicher (RAM oder Flash) sprechen wir 
denn hier? Ein paar Beiträge über dir wurde Frank darauf aufmerksam 
gemacht, dass die Stringkonstanten nicht im Programmspeicher landen. Das 
lässt sich optimieren, wodurch ein "wenig" (150?) Byte RAM frei würden.

Gibt es denn nicht eine Möglichkeit für dich bestimmte Protokoll 
abzuschalten? Oder einen größeren Mikrocontroller zu verwenden? Im 
Notfall müsstest du halt in den Quellen herumpfuschen und unnötiges 
herauswerfen. Ist aber nicht unbedingt empfehlenswert, wenn man 
kompatibel bleiben möchte und von zukünftigen Updates profitieren will.

Mit freundlichen Grüßen,
Karol Babioch

von Bruno M. (brumay)


Lesenswert?

> Von welcher Plattform und welchem Speicher (RAM oder Flash) sprechen wir
> denn hier?

Ich arbeite mit einem AT8, bei dem das Data Memory überläuft.

> Ein paar Beiträge über dir wurde Frank darauf aufmerksam
> gemacht, dass die Stringkonstanten nicht im Programmspeicher landen. Das
> lässt sich optimieren, wodurch ein "wenig" (150?) Byte RAM frei würden.

Das habe ich wohl gelesen, aber meine C-Kenntnisse reichen da bei weitem 
nicht.

> Gibt es denn nicht eine Möglichkeit für dich bestimmte Protokolle
> abzuschalten? Oder einen größeren Mikrocontroller zu verwenden?

Diese Möglichkeit gibt es sicher, aber da ich ja mit der Alternative 
loggen oder Protokoll gut klar kam, habe ich gar nicht weiter versucht.

> Im
> Notfall müsstest du halt in den Quellen herumpfuschen und unnötiges
> herauswerfen. Ist aber nicht unbedingt empfehlenswert, wenn man
> kompatibel bleiben möchte und von zukünftigen Updates profitieren will.

Das scheitert schon an meinen C-Kenntnissen.

Ich habe es jetzt mal mit

#if IRMP_PROTOCOL_NAMES == 1

versucht. Damit ist das Problem gelöst!

von Joachim B. (jar)


Lesenswert?

Karol Babioch schrieb:
> Von welcher Plattform und welchem Speicher (RAM oder Flash) sprechen wir
> denn hier? Ein paar Beiträge über dir wurde Frank darauf aufmerksam
> gemacht, dass die Stringkonstanten nicht im Programmspeicher landen. Das
> lässt sich optimieren, wodurch ein "wenig" (150?) Byte RAM frei würden.

ich bin ja grad beim Arduino

und diese kleine Änderung an vielen Stellen:

#ifdef IRMP_SUPPORT_KASEIKYO_PROTOCOL
  case IRMP_KASEIKYO_PROTOCOL: Serial.print("IR: "); 
Serial.print("KASEIKYO"); Serial.print(", Address: "); 
Serial.print(irmp_data.address); Serial.print(", Command: "); 
Serial.println(irmp_data.command); break;
#endif

zu

#ifdef IRMP_SUPPORT_KASEIKYO_PROTOCOL
  case IRMP_KASEIKYO_PROTOCOL: Serial.print(F("IR: ")); 
Serial.print(F("KASEIKYO")); Serial.print(F(", Address: ")); 
Serial.print(irmp_data.address); Serial.print(F(", Command: ")); 
Serial.println(irmp_data.command); break;
#endif

hat min. 800 Byte RAM freigemacht !

was so direktes Schreiben aus dem flash doch bewirken kann :-))) !

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


Lesenswert?

Hallo SvenK,

entschuldige bitte die späte Antwort. Ich war letzte Woche unterwegs.

SvenK schrieb:
> Ich benötige nun für ein Projekt die Codes der Fernbedienung eines JVC
> KW-NX7000 Navis. Die Fernbedienung mit dem Namen RM-RX250 wird aber
> leider nicht korrekt erkannt. Manchmal kam „Telefunken“, aber bei
> verschiedenen Tasten immer genau derselbe Code, teilweise auch kam auch
> „Siemens“ – alle Tasten gleicher Code

Ja, das scheint etwas neues zu sein, was IRMP noch nicht kennt.

> Mit der IRMP.exe auf dem PC analysiert erhalte ich eine weitere
> „Eigenartigkeit“:
> Im Artikel bei Mikrocontroller.net sind die „dimensionslosen Zahlen“
> 1/100 der Zeit in µs
> z.B.
1
 pulse avg: 91.0=9102.8 us
> Bei mir sind es 1,5/100 !? – unabhängig von der Logging-Frequenz (10, 15
> oder 20 kHz)
> z.B.
1
 pulse avg: 40.8=2720.0 us

Bei IRMP_INTERRUPTS = 10000 sollte man erhalten:

  pulse avg: 91.0=9102.8 us

Bei einer Scan-Frequenz von 15000 sollte der Zähler links aber das 
1,5-fache betragen, nämlich ungefähr:

  pulse avg: 136.0=9102.8 us

> Ich habe die Loggings der nötigen Befehle in einer ZIP-Datei angehäng –
> mit 10kHz jeweils 5-mal hintereinander aufgenommen und zusätzich nochmal
> alle zusammengefasst in einer Datei - falls das hilfreicher ist.

Danke. Ich habe gerade mal kurz reingeschaut. Das Protokoll sollte 
einfach in den IRMP einzubauen sein. Kann ich heute oder morgen machen. 
Ich stelle dann eine Testversion ins SVN.

> P.S.: die oben genannten Schwierigkeiten hatte ich bei der RS232
> Übertragung. Mit „U2X“ kam nichts oder nur „Matsch“ im PC an – ohne
> „U2X“ läuft es problemlos !?

Hm. Dafür habe ich leider keine Erklärung.

Gruß,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:

> Ich arbeite mit einem AT8, bei dem das Data Memory überläuft.

Ist dieser auf einem Sockel aufgesteckt? Wenn ja, dann könntest Du den 
ATmega8 durch einen ATmega328 ersetzen. Dieser ist pinkompatibel und hat 
den vierfachen Speicher.

>> Ein paar Beiträge über dir wurde Frank darauf aufmerksam
>> gemacht, dass die Stringkonstanten nicht im Programmspeicher landen. Das
>> lässt sich optimieren, wodurch ein "wenig" (150?) Byte RAM frei würden.
>
> Das habe ich wohl gelesen, aber meine C-Kenntnisse reichen da bei weitem
> nicht.

Ich kümmere mich kurzfristig darum.

> #if IRMP_PROTOCOL_NAMES == 1
>
> versucht. Damit ist das Problem gelöst!

Ich schaue mir die Stelle im Code mal an.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Bruno M. schrieb:
> Ich arbeite mit einem AT8, bei dem das Data Memory überläuft.

Ich habe nun irmp_protocol_names[] auf PROGMEM umgestellt und 
desweiteren in das Beispiel-main.c UART-Routinen aufgenommen, so dass 
man nun die Daten zum empfangenen Protokoll direkt auf dem UART ausgeben 
kann. Für PROGMEM-Strings habe ich neben uart_puts() auch uart_puts_P() 
implementiert. Damit schrumpft bei Verwendung von irmp_protocol_names[] 
der RAM-Bedarf um 300 Bytes. Damit sollte bei Dir genügend Speicher 
übrig bleiben.

Eingecheckt sind die Änderungen im SVN als Version 2.6.3.

Viel Spaß,

Frank

von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

Frank M. schrieb:
> Für PROGMEM-Strings habe ich neben uart_puts() auch uart_puts_P()
> implementiert.

könnte man nicht durch ein "geschicktes" #define

wie hier:
#define usart_write(format, args...)   usart_write_P(PSTR(format) , ## 
args)

diese Unterscheidung für den User eliminieren oder ist das schon drin 
und der User merkt davon nix ?

ich nutze da immer den Ulrich Radig Code und finde das so genial das ich 
mich nie drum kümmern muss, Textkonstanten kommen direkt aus dem Flash 
ohne Ramverbrauch und ich muss beim proggen auch nie darauf achten 
welche usart_write ich aufrufen muss

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


Lesenswert?

SvenK schrieb:
> Ich benötige nun für ein Projekt die Codes der Fernbedienung eines JVC
> KW-NX7000 Navis. Die Fernbedienung mit dem Namen RM-RX250 wird aber
> leider nicht korrekt erkannt.

Nach Analyse Deiner Scans konnte ich feststellen, dass es sich um das 
Kaseikyo-Protokoll handelt. Es wurde nur nicht von IRMP erkannt, weil 
das Timing Deiner Fernbedienung sich nicht ganz an das 
Kaseikyo-Protokoll hält.

IRMP toleriert beim Kaseikyo-Protokoll eine Abweichung des 
Startbit-Timings um 10 Prozent. Das reicht aber nicht für Deine FB.

Abhilfe in irmp.c:

Alt:
1
#define KASEIKYO_START_BIT_PULSE_LEN_MIN        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
2
#define KASEIKYO_START_BIT_PULSE_LEN_MAX        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
3
#define KASEIKYO_START_BIT_PAUSE_LEN_MIN        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
4
#define KASEIKYO_START_BIT_PAUSE_LEN_MAX        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)

Neu mit Toleranz von 20%:
1
#define KASEIKYO_START_BIT_PULSE_LEN_MIN        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
2
#define KASEIKYO_START_BIT_PULSE_LEN_MAX        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
3
#define KASEIKYO_START_BIT_PAUSE_LEN_MIN        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
4
#define KASEIKYO_START_BIT_PAUSE_LEN_MAX        ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)

Dann sollte es gehen. Die Änderung ist auch im SVN (Version 2.6.4) 
eingecheckt.

Was mir noch auffiel in Deinen Scans: Einige Tasten wiederholen den 
Frame ein zweites Mal (irmp_data.flag = 1). Das kann entweder daran 
liegen, dass Du diese Tasten länger gedrückt hast oder die FB es bei 
bestimmten Tasten prinzipiell macht. In diesem Fall könntest Du bei 
flag=1 den Frame ignorieren, falls die doppelte Erkennung Deine 
Anwendung "durcheinander bringen" könnte.

Gruß,

Frank

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> könnte man nicht durch ein "geschicktes" #define
>
> wie hier:
> #define usart_write(format, args...)   usart_write_P(PSTR(format) , ##
> args)
>
> diese Unterscheidung für den User eliminieren oder ist das schon drin
> und der User merkt davon nix ?

Nein. Dieses usart_write() erwartet IMMER einen konstanten String als 
Format. Eine Variable kannst Du da nicht übergeben! Das PSTR()-Makro 
funktioniert nämlich nur für konstante Strings. Wenn Du einen variablen 
String ausgeben willst, musst Du den ins Argument hinter das Format 
packen. Aber nur dann! Denn hier kannst Du wiederum keinen konstanten 
PROGMEM-String als Argument übergeben.

Daher ist dieses Makro gar nicht so genial, wie es ausschaut. Denn es 
funktioniert ausschließlich bei PROGMEM-Strings fürs Format.

Mein uart_puts() kann auch variable Strings (z.B. einen Buffer) 
ausgeben.

Da musst Du mit

   usart_write ("%s", buffer);

arbeiten. Die Unterscheidung (P vs. non P) machst Du also bei der 
Parameterübergabe, ich beim Funktions-Aufruf.

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Mein uart_puts() kann auch variable Strings (z.B. einen Buffer)
> ausgeben.
>
> Da musst Du mit
>
>    usart_write ("%s", buffer);
>
> arbeiten.

danke, nur dann verstehe ich nicht wieso folgendes funktioniert ?

aus Hyperterminal
1
NIC init:READY!

aus dem Sourcecode
1
/*NIC Initialisieren*/
2
usart_write("NIC init:");
3
ETH_INIT();
4
usart_write("READY!\r\n");

hier arbeite ich doch nicht mit:
>    usart_write ("%s", buffer);

und trotzdem funktioniert es ....

: Bearbeitet durch User
von Karol B. (johnpatcher)


Lesenswert?

Joachim B. schrieb:
> und trotzdem funktioniert es ....

Du gibst ja auch konstante Strings aus. Diese werden durch das PSTR() 
Makro im Flash abgelegt und können ausgegeben werden. Franks Aussage 
bezog sich auf Strings, welche zur Laufzeit zusammen gesetzt werden.

Mit freundlichen Grüßen,
Karol Babioch

von Joachim B. (jar)


Lesenswert?

gleich noch ne Frage hinterher

besser mit 2 Interrupts arbeiten oder einen

weil nicht jeder Atmel genug Timer hat und mir kein Interrupt entgehen 
soll

habe ich alles in einen Timer gepackt

der macht Interrups 15000, eine Var zählt bis 150 für 10ms und dort wird 
ne Menge gemacht was über 64µs dauern kann, Folge es entgehen mir 
Interupts für IR, ist zwar bis jetzt nicht so auffällig kritisch ABER

ich grübel gerade ob nicht nicht doch besser bei Vorhandensein 2er Timer 
diese Interrupts trenne und den 10ms Interrupt durch ISR(irmp) 
unterbrechbar mache, die kurze IRMP Unterbrechung stört in meiner 10ms 
Routine nicht.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> und trotzdem funktioniert es ....

Wie Karol schon wiederholte: Der Format-String muss bei Deiner 
usart_write() konstant sein.

Versuch doch mal folgendes:
1
char buffer[] = "Hello World";

oder
1
char buffer[64];
2
strcpy (buffer, "Es ist egal, wie dieser String in diesen Buffer gelangte");

und dann:
1
usart_write (buffer);

Das wird so nicht funktionieren.

: Bearbeitet durch Moderator
von Joachim B. (jar)


Lesenswert?

Karol Babioch schrieb:
> Franks Aussage
> bezog sich auf Strings, welche zur Laufzeit zusammen gesetzt werden.

OK ich glaube ich verstehe so langsam, aber bei der typischen

printf("%s", buffer); wirds genauso gemacht und stört doch kein bischen 
....

OK verschiedene Ansätze und Philosophien, kommt ja öfter mal vor bei C

ich werde nie begreifen warum irgendweche STRING Funktionen mal

(signed) char mal unsigned char sind und warum manche char Funktionen 
int (16-bit) zurück geben (wo nur ein Zeichen drin ist)


Frank M. schrieb:
> Versuch doch mal folgendes:

da sehe ich aber nicht den Zusammenhang, char buffer im PROGMEM

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


Lesenswert?

Joachim B. schrieb:
> printf("%s", buffer); wirds genauso gemacht und stört doch kein bischen
> ....

Wenn ich eine printf-ähnliche Funktion, die einen Format-String scannen 
kann, in das Beispiel-Main einpflanze, wird das ausführbare Programm 
ungleich viel größer als das jetzige.

Und genau darum geht es nicht bei IRMP! main.c ist lediglich ein 
Beispiel-Programm, welches möglichst ohne große Anforderungen zeigen 
soll, wie man schnell etwas auf die Beine stellen kann.

> ich werde nie begreifen warum irgendweche STRING Funktionen mal
>
> (signed) char mal unsigned char sind

Wenn man 8-Bit-Zeichen (also Umlaute etc) übertragen muss, dann kann man 
unter Umständen bei signed-chars Probleme bekommen. Denn dann werden 
diese Zeichen negativ. Leider sind aus historischen Gründen Strings in 
Gänsefüßchen immer char und nicht unsigned char. Das liegt daran, dass 
die Amerikaner, die Anfang der 70er Jahre C entwickelten, überhaupt 
nicht daran dachten, dass jemand mal mehr als 7-Bit-Zeichen (US-ASCII) 
braucht.

> und warum manche char Funktionen
> int (16-bit) zurück geben (wo nur ein Zeichen drin ist)

Das liegt wohl am Sonder"zeichen" EOF, welches unter UNIX den Wert -1 
hat. Ist auch eine historische Altlast. Auf Rechnern außerhalb von µCs 
ist das aber auch sehr sinnvoll so.

> da sehe ich aber nicht den Zusammenhang, char buffer im PROGMEM

char buffer im PROGMEM? Wie soll das gehen, wenn die Daten erst zur 
Laufzeit per I2C, ETH, RF oder sonstwie in den Buffer gelangt sind?

Die Welt ist nicht so einfach, wie Du sie Dir machst ;-)

: Bearbeitet durch Moderator
von Karol B. (johnpatcher)


Lesenswert?

Joachim B. schrieb:
> printf("%s", buffer);

printf() ist im aber gerade im Bereich der Mikrocontroller oft 
ziemlicher Overkill, gerade bei stark beschränkten Ressourcen.

Frank M. schrieb:
> Leider sind aus historischen Gründen Strings in
> Gänsefüßchen immer char und nicht unsigned char.

Ja, aber für char ohne Angabe von signed bzw. unsigned ist nicht 
festgelegt wie diese zu implementieren sind und hängt daher vom Compiler 
ab, siehe [1].

Aber ja, das korrekte Verwenden von Datentypen innerhalb von C ist oft 
gar nicht so einfach. Dabei sind die historische Altlasten nur ein 
Grund, ein weiterer ist es den verschiedenen Plattformen ohne viel 
Overhead gerecht zu werden. Dadurch ist kaum etwas festgelegt. Gibt es 
nicht sogar Plattformen auf denen gilt: sizeof(short) = sizeof(int) = 
sizeof(long).

Das ganze Rumgegurke mit uint8_t bei den kleinen Mikrocontrollern ist ja 
auch nicht unbedingt portabel. Besser wäre wohl uint8_fast_t, aber das 
kann wiederum zu Nebeneffekten führen, wenn man sich irgendwo (implizit) 
auf den Wertebereich und damit verbundene Wrap-Arounds verlässt.

Wirklich portablen C Code zu produzieren ist gar nicht so einfach [2], 
und dürfte in den meisten Fällen zu einem Dschungel aus typedefs und 
Konditionen beim Kompilieren führen.

Joachim B. schrieb:
> OK verschiedene Ansätze und Philosophien, kommt ja öfter mal vor bei C

In diesem Zusammenhang interessant ist auch die "Rückgabe" von Fehlern. 
Je nach Gusto ist es hier üblich negative Werte für Fehler 
vorzubehalten, oder auch nicht. Dass 0 "success" bedeutet, beißt sich 
manchmal auch etwas mit der ansonsten üblichen Notation von false = 0 
bzw. true = 1.

Wie du schon sagst: Da ist man in C relativ frei. Als jemand der mit 
besser typisierten Programmiersprachen angefangen hat, wünsche ich mir 
manchmal schon etwas mehr Vorgaben herbei, aber was solls, ist eh etwas 
Off-Topic.

Mit freundlichen Grüßen,
Karol Babioch

[1]: 
https://stackoverflow.com/questions/2054939/is-char-signed-or-unsigned-by-default
[2]: 
https://www.mikrocontroller.net/articles/Plattformunabh%C3%A4ngige_Programmierung_in_C

von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Die Welt ist nicht so einfach, wie Du sie Dir machst ;-)

dafür betreibst du aber eine Menge Aufwand (in IRMP) um es anderen Usern 
doch einfach zu machen :-)

wollen wir nicht alle irgendwie einfach ?

noch mal zur obigen Frage, doch besser meine 10ms Berechnungen aus der 
IRMP ISR rausnehmen und in meiner 10ms ISR lieber IRMP ISR erlauben ?

von Bruno M. (brumay)


Lesenswert?

Frank M. schrieb:

> Eingecheckt sind die Änderungen im SVN als Version 2.6.3.

Hallo Frank,

herzlichen Dank für den prompten Service.
Speicher habe ich jetzt genug! Allerdings bekomme ich keine Protokolle 
angezeigt. Das Loggen funktioniert normal.

Ich muß mir das morgen mal näher ansehen, heute habe ich keine Lust 
mehr;-)

Gruß Bruno

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> besser mit 2 Interrupts arbeiten oder einen

Es kommt so oder so auf dasselbe heraus.

> weil nicht jeder Atmel genug Timer hat und mir kein Interrupt entgehen
> soll
>
> habe ich alles in einen Timer gepackt
> der macht Interrups 15000, eine Var zählt bis 150 für 10ms und dort wird
> ne Menge gemacht was über 64µs dauern kann,

Das wird im WordClock-Projekt genauso gemacht. Die ISR ruft neben 
irmp_ISR() noch jede Menge anderer Funktionen auf, welche durch Zähler 
in der ISR "getimed" werden.

> Folge es entgehen mir Interupts für IR

Dann machst Du zuviel in der ISR.

> ich grübel gerade ob nicht nicht doch besser bei Vorhandensein 2er Timer
> diese Interrupts trenne

Nein. Das bringts nicht. Ganz im Gegenteil: Dein zweiter Timer sorgt 
u.U. dafür, dass der IRMP-Timer nicht immer in gleichen Zeitabständen 
aufgerufen wird, sondern erst, wenn die zweite ISR beendet wird. Das 
verfälscht das Scan-Ergebnis.

Schau lieber, dass Du Deine eigenen Timer-Routinen abkürzen kannst, z.B. 
durch Setzen eines Flags, welches von der Hauptschleife ausgewertet 
wird.

Wenn Du einen neueren avr-gcc hast (z.B. 4.7.2), kannst Du einiges 
herausholen durch folgende Flags:

Compiler:

 -Os                    # hast Du wahrscheinlich schon
 -flto
 -ffunction-sections
 -fdata-sections

Linker:
 -Os                    # ja, beim Linker!
 -flto
 -ffunction-sections
 -fdata-sections
 -Wl,--gc-sections

Diese Flags bewirken unter anderem, dass der avr-gcc sämtliche 
Funktionen, die aus einer ISR aufgerufen werden, inline behandeln kann - 
auch wenn sie in verschiedenen C-Quelltexten stecken. Dadurch können 
einige PUSH-/POP-Befehle eingespart werden. Der Nachteil, dass bei 
Funktionsaufrufen aus der ISR auf Verdacht viel zuviele Register 
gesichert werden, wird dadurch eliminiert und das Zeitverhalten 
verbessert sich etwas.

Sinnvoller ist natürlich, das Übel an der Wurzel zu packen - d.h. Deine 
ISR-Funktionen zu überarbeiten.

: Bearbeitet durch Moderator
von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> Dann machst Du zuviel in der ISR.

das ist ja klar, wenn IRMP Interrupts "verloren" gehen

> Schau lieber, dass Du Deine eigenen Timer-Routinen abkürzen kannst, z.B.
> durch Setzen eines Flags, welches von der Hauptschleife ausgewertet
> wird.

OK das hatte ich ja bei meinem anderen Projekt schon mit Erfolg gemacht, 
nun muss ich mal sehen wie ich das der Arduino IDE beibringe, die ist 
etwas zickiger sprich undurchsichtiger (für mich)

Danke.

> Nein. Das bringts nicht. Ganz im Gegenteil: Dein zweiter Timer sorgt
> u.U. dafür, dass der IRMP-Timer nicht immer in gleichen Zeitabständen
> aufgerufen wird, sondern erst, wenn die zweite ISR beendet wird. Das
> verfälscht das Scan-Ergebnis.

das verstehe ich nicht, ich kann am Anfang meiner 10ms Interrupts die 
IRMP Interrupt wieder erlauben und dann wird sofort meine 10ms ISR durch 
IRMP unterbrochen, im Timing passend !

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


Lesenswert?

Joachim B. schrieb:
> das verstehe ich nicht, ich kann am Anfang meiner 10ms Interrupts die
> IRMP Interrupt wieder erlauben und dann wird sofort meine 10ms ISR durch
> IRMP unterbrochen, im Timing passend !

Ja, das kannst Du natürlich machen, ist aber unüblich bei AVRs. Ich sehe 
da auch keinen Gewinn, denn 100% Auslastung bleibt 100% Auslastung.

Besser wäre ein µC mit priorisierten Interrupts. Das liefern die AVRs 
aber nicht von Haus aus.

von Joachim B. (jar)


Lesenswert?

>> ich kann am Anfang meiner 10ms Interrupts die
>> IRMP Interrupt wieder erlauben und dann wird sofort meine 10ms ISR durch
>> IRMP unterbrochen, im Timing passend !

Frank M. schrieb:
> Ja, das kannst Du natürlich machen, ist aber unüblich bei AVRs. Ich sehe
> da auch keinen Gewinn, denn 100% Auslastung bleibt 100% Auslastung.

ich glaube du hast was falsch verstanden, der Controller ist nicht zu 
100% ausgelastet, nur in meiner alle 10ms Routine kann es länger als 
64µs (INTERRUPT IRMP) dauern, was IRMP stört, ob ich meine maximal 100µs 
Berechnung im Hauptprogramm mache durch Flags oder in meiner 10ms 
Timerroutine und diese durch IRMP unterbrechen lasse ist doch egal.
Zudeinem ist doch unüblich lese ich hier durchaus anderes.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Unterbrechbare_Interruptroutinen

Aber ich will nicht mit dir streiten, ich danke dir für IRMP und freue 
mich über unseren fruchtbaren Gedankenaustausch (nicht furchtbar hoffe 
ich für dich)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Joachim B. schrieb:
> Zudeinem ist doch unüblich lese ich hier durchaus anderes.
>
> 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Unterbrechbare_Interruptroutinen

Zitat daraus:

"Bei unsachgemässer Handhabung kann dies zu erheblichen Problemen durch 
Rekursion wie einem Stack-Overflow oder anderen unerwarteten Effekten 
führen und sollte wirklich nur dann eingesetzt werden, wenn man sich 
sicher ist, das Ganze auch im Griff zu haben."

Genau deshalb sehe ich das als "unüblich", aber natürlich auch nicht als 
ausgeschlossen.

> Aber ich will nicht mit dir streiten, [...]

Ja, lassen wir das. Es wird auch langsam offtopic.

: Bearbeitet durch Moderator
von Bruno M. (brumay)


Lesenswert?

Hallo Frank,

> Allerdings bekomme ich keine Protokolle
> angezeigt. Das Loggen funktioniert normal.
>
> Ich muß mir das morgen mal näher ansehen, heute habe ich keine Lust
> mehr;-)

Ich komme leider nicht weiter! Da ich die Vorgängerversion schon 
gelöscht habe, kann ich auch nicht mehr vergleichen und testen.

Funktioniert es bei dir denn normal?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hallo Bruno,

Bruno M. schrieb:
> Ich komme leider nicht weiter! Da ich die Vorgängerversion schon
> gelöscht habe, kann ich auch nicht mehr vergleichen und testen.
>
> Funktioniert es bei dir denn normal?

Konnte ich leider selber nicht testen, weil ich momentan keinen µC in 
Griffweite habe. Da die Änderungen gegenüber der oben geposteten Version
nur marginal waren, muss ich da irgendwas verkorkst haben. Ich schaue 
gleich mal danach.

Hier findest Du die Version wieder, die ich damals für Dich hier 
gepostet hatte:

  Beitrag "Re: IRMP - Infrared Multi Protocol Decoder"

Wenn diese jetzt plötzlich auch nicht mehr funktioniert, dann machst Du 
aber was falsch und nicht ich ;-)

von Karol B. (johnpatcher)


Lesenswert?

Bruno M. schrieb:
> Ich komme leider nicht weiter! Da ich die Vorgängerversion schon
> gelöscht habe, kann ich auch nicht mehr vergleichen und testen.

Ein Grund mehr für den Einsatz einer Versionsverwaltung. Ohne ist das 
Selbstmord auf Raten.

Mit freundlichen Grüßen,
Karol Babioch

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karol Babioch schrieb:
> Ein Grund mehr für den Einsatz einer Versionsverwaltung. Ohne ist das
> Selbstmord auf Raten.

SVN ist eine Versionsverwaltung. ;-)

Aber das main.c, was Bruno vorher verwendet hatte, hatte ich hier damals 
lediglich in diesem Thread gepostet - speziell für Bruno als 
Einstiegshilfe.

Hier noch zu finden:

  Beitrag "Re: IRMP - Infrared Multi Protocol Decoder"

Verloren ist es also nicht.

EDIT:
Der Unterschied besteht im AVR-Teil der main.c nur durch neue Anwendung 
der uart_puts_P()-funktion. Sonst ist er identisch.

: Bearbeitet durch Moderator
von Joachim B. (jar)


Lesenswert?

Frank M. schrieb:
> "Bei unsachgemässer Handhabung kann dies zu erheblichen Problemen durch
> Rekursion wie einem Stack-Overflow oder anderen unerwarteten Effekten
> führen und sollte wirklich nur dann eingesetzt werden, wenn man sich
> sicher ist, das Ganze auch im Griff zu haben."
>
> Ja, lassen wir das. Es wird auch langsam offtopic.

so zum Abschluß, Testroutine geschrieben und das Tektronix TDS3014 
angehängt

meine 10ms Timerroutine braucht ca. 200µs damit entgehen mir 3 IRMP 
Impulse
deine IRMP ISR braucht 4µs (meine Hochachtung) an 16MHz atmega328p

ich sehe also keinerlei Problematik an Rekursion wenn ich mich an die 
Anleitung im AVR-GCC-Tutorial halte:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Unterbrechbare_Interruptroutinen

wenn meine 10ms ISR 200µs Ausführungsdauer hat -> keinerlei 
Rekusionsgefahr !

ich sehe nicht wenn in "meiner" ISR noch mal zusätzlich IRMP zum Zuge 
kommt, kostet mich lächerliche 4µs (oder 3x 4µs) die in meinen 200µs 
nicht auffallen

und alle sollten glücklich sein

noch jemand einen Einwand ?

vielen Dank, jar

PS, das ist mit einem Arduino nano (micro) mit atmega 328p die 
Vorbereitung zu 2x word clock

1x 25x25 cm Test mit IKEA ribba Rahmen LEDstripe WS2812b 60 LED/m
1x 50x50 cm Test mit IKEA ribba Rahmen LEDstripe WS2812b 30 LED/m

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


Lesenswert?

Joachim B. schrieb:
> meine 10ms Timerroutine braucht ca. 200µs damit entgehen mir 3 IRMP
> Impulse

Wofür zum Teufel brauchst Du 200µs? Zeig mal, was Du da alles machst.

> deine IRMP ISR braucht 4µs (meine Hochachtung) an 16MHz atmega328p

Womit gezeigt wäre, dass nicht die Länge, sondern die Geschwindigkeit 
einer ISR ausschlaggebend ist ;-)

> noch jemand einen Einwand ?

Grundsätzlich nicht, aber schön ist das nicht. Das kann man gewiss 
sauberer lösen.

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.