Hallo! Ich besitze hier ein Arduino UNO R3 Board mit einem ATmega328P. Weiterhin habe ich zwei ATmega8A, eine IR-Fernbedienung nach NEC-Protokoll, einen IR-Receiver und eine IR-LED. Nun zu meinem Problem: ich habe die Arduino-IR-Lib umgeschrieben, sodass ich diese auch ohne Arduino-IDE benutzen kann (also nur avr-gcc). Mein Problem: die ATmega8A bekommen es nicht hin, korrekt mit der LED Signale auszusenden noch mit dem Receiver welche zu empfangen. Genau der gleiche Code läuft auf dem ATmega328P fehlerfrei (nur den Output der LED kann ich nicht nachvollziehen, da ich keinen zweiten ATmega328P habe, um die Signale zu verarbeiten). Nun habe ich einmal testweise meinen USBASP an den ATmega328P angeschlossen, den auf den internen Oszillatoren mit 8MHz umgestellt und das Programm geflasht. Ergebnis: nun kann ich auch damit die Signale der Fernbedienung nicht mehr korrekt empfangen. Der Code ist sicher korrekt, das bin ich bereits alles durchgegangen. Dort ist alles sowohl mit 16MHz als auch mit 8MHz kompatibel. Der erlaubt auch relativ große Abweichungen. Falls relevant: es wird Timer1 ohne prescaler verwendet. Der Output geht über den entsprechenden PWM-Pin, Input über regelmäßige Interrupts im 20µs Intervall. Ist es möglich, dass das tatsächlich das Problem ist? Ich habe leider derzeit keinerlei Quarze herumliegen, um die an die ATmega8As anzuschließen und noch keine groß genuge Bestellung zusammen, dass sich eine Bestellung bei Reichelt lohnt. Sollte das das Problem sein, müsste ich zumindest nicht mehr länger den Fehler suchen. Danke!
Ich darf den leider nicht einfach so hochladen. Allerdings stehe ich für die Korrektheit des Codes ein. Wie gesagt, PWM wird einfach über den Timer an den Pin ausgegeben. Und empfangen wird, indem in dem genannten Intervall der aktuelle Status geprüft wird.
it_is_me schrieb: > Ich darf den leider nicht einfach so hochladen. Aha. > Allerdings stehe ich für die Korrektheit des Codes ein. Wenn er korrekt wäre, würde er ja laufen. Tut er aber nicht. > Wie gesagt, PWM wird einfach über den Timer an den Pin ausgegeben. Du siehst also mit dem Oszi die 38kHz-Modulation, die für NEC notwendig ist? Und was siehst Du sonst auf dem Oszi? Mach mal ein Foto oder eine Hardopy von Deinem Logic-Analyzer. Wenn Du gar nichts siehst, siehe IRMP und IRSND.
:
Bearbeitet durch Moderator
Ich habe eine fertige Fernbedienung, die nach dem NEC-Protokoll arbeitet. Damit schaue ich, ob das Empfangen der Daten klappt. Das Senden ist derzeit noch vollkommen nebensächlich. Das kann ich tatsächlich nicht so einfach überprüfen. Ich werde mir jetzt aber einfach einmal 8MHz Quarze und 16MHz Quarze holen. Die kann man immer gebrauchen. Der Code von IRMP ist mir viel zu aufgebläht. Aber ich lese mir den mal durch, vielleicht finde ich ja etwas verwertbares.
Oha, GEHEIM-Code für Allerwelts-IR-Fernbedienungen! Geheim kann bedeuten: "Besser als alles Vorherige" (dann würde er funktionieren), oder "nicht vorzeigbar"... Ein abgeglichener AVR-RC-Oszillator bei normaler Raumtemperatur sollte für übliche IR-Fernbedienungen bei Pulsfrequenz und Bit-Timing voll ausreichen!
Jakob schrieb: > Ein abgeglichener AVR-RC-Oszillator bei normaler Raumtemperatur > sollte für übliche IR-Fernbedienungen bei Pulsfrequenz und > Bit-Timing voll ausreichen! Geht auch unabgeglichen, jedenfalls mit IRMP - und zwar zuverlässig, gerade beim NEC Protokoll.
Matthias S. schrieb: > Geht auch unabgeglichen, jedenfalls mit IRMP - und zwar zuverlässig, > gerade beim NEC Protokoll. Kann ich bestätigen. Hab so viele Tiny85 als Moodlight mit FB gebaut, da sind garkeine Pins für nen Quarz mehr frei.
it_is_me schrieb: > Mein Problem: die ATmega8A bekommen es nicht hin, korrekt mit der LED > Signale auszusenden noch mit dem Receiver welche zu empfangen. Das sollte kein Problem darstellen die Ursache zu finden! Poste einfach den Code, einen Schaltplan und ein Foto vom Aufbau der Schaltung!
An einer stabilisierten Spannungsversorgung ist der interne RC-Oszillator kein Problem, an Batterien siehts anders aus.
batman schrieb: > An einer stabilisierten Spannungsversorgung ist der interne > RC-Oszillator kein Problem, an Batterien siehts anders aus. Jedenfalls IRSND läuft auch an unstabilisierten Tiny2313 zuverlässig. Da benutze ich zur Zeit nicht NEC, sondern RC5, aber es geht trotzdem. it_is_me schrieb: > Der Code von IRMP ist mir viel zu aufgebläht. Was heisst aufgebläht? Erstens solltest du nur die Protokolle aktivieren, die benötigt werden und zweitens hat IRMP/IRSND einen unschätzbaren Vorteil - es läuft nämlich, wird gut betreut und hat jede Menge Tester und Rückmeldungen.
Ich wollte nun einmal IRMP ausprobieren, es gibt allerdings folgende Probleme: in irmpconfig.h muss AVR_ATMEGA definiert sein, um das Ziel als Atmega zu identifizieren. Dieses Makro wird aber standardmäßig nicht definiert. Wahlweise man ergänzt beim Kompilieren -DAVR_ATMEGA="" oder man ändert es auf _AVR_, was sehr wohl definiert wird. Weitere Probleme sind, dass in irmpprotocols.h <stdint.h> eingebunden werden muss, damit uint8_t benutzt werden kann. Außerdem funktioniert der Mechanismus mit
1 | #if !defined(_IRMP_H_) && !defined(_IRSND_H_)
|
2 | # error please include only irmp.h or irsnd.h, not irmpprotocols.h
|
3 | #endif
|
nicht. Dies wird, warum auch immer, jedes Mal ausgelöst. Ich inkludiere aber nur irmp.h. Außerdem wird irgendwie F_CPU undefined. Ich schreibe #define F_CPU 16000000L ganz oben in main.c und trotzdem beschwert sich delay.h die ganze Zeit, dass F_CPU nicht definiert wurde. Wenn ich aber mit -DF_CPU=16000000 kompiliere, dann funktioniert es. Naja, ich flashe es jetzt einmal mit diesen Änderungen und mal sehen...
it_is_me schrieb: > Ich wollte nun einmal IRMP ausprobieren, es gibt allerdings folgende > Probleme: Welche Version mit welcher IDE?
Version 3.0.9 vom 19.02.18. Keine IDE, GCC 7.3.0. Auf dem ATmega328P läuft IRMP nach den oben genannten Änderungen problemlos. Auch wenn die eigentlich gesendeten Signale in einen Wert zwischen 0 und 255 umgewandelt werden. (aus 0xFF02FD wird 64, etc.) Da müsste ich allerdings noch einmal tiefer in den Code schauen. Auf dem ATmega8A funktioniert es weiterhin nicht. Dort wird das Signal gar nicht erst erkannt (vom IR Receiver schon, aber es kann eben nicht verarbeitet werden). Schaltplan habe ich leider nicht. Foto würde nicht viel bringen, da das lediglich Aufbauten auf zwei Breadboards sind, die mit viel zu viel Kabelgewirr verbunden sind. Daraus kann man nichts schließen. Die relevanten Anschlüsse sind aber: PD6-0 -> LCD PB1 -> IR Receiver Sowohl bei dem ATmega328P als auch ATmega8A. Was könnte euch denn sonst noch weiterhelfen? Der Code für das LCD ist der hier aus dem Tutorial.
it_is_me schrieb: > Auf dem ATmega328P läuft IRMP nach den oben genannten Änderungen > problemlos. it_is_me schrieb: > Da müsste ich allerdings noch einmal tiefer in den Code schauen. > Auf dem ATmega8A funktioniert es weiterhin nicht. Dann poste doch endlich mal den Code! Oder willst du uns verarschen?
Ich rede von IRMP. Den Code kannst du dir hier ganz einfach in dem oben verlinkten Artikel downloaden. Sämtliche Anpassungen, die ich daran vorgenommen habe habe ich oben erwähnt.
it_is_me schrieb: > Ich rede von IRMP. > Den Code kannst du dir hier ganz einfach in dem oben verlinkten Artikel > downloaden. Sämtliche Anpassungen, die ich daran vorgenommen habe habe > ich oben erwähnt. Wenn der Code von IRMP auf dem einen Boards läuft, aber auf deinem nicht dann poste: Marc Horby schrieb: > einen Schaltplan und ein Foto vom Aufbau der > Schaltung!
Schaltplan des ATmega328Ps ist der eines Arduino Uno R3-Boards. Hier einmal die Verbindungen des ATmega8As: IR Receiver: Data -> PB1 VCC -> +5V GND -> GND µC: GND -> GND VCC -> +5V AVCC -> +5V PB1 -> IR Receiver Data PD0 -> LCD D4 PD1 -> LCD D5 PD2 -> LCD D6 PD3 -> LCD D7 PD4 -> LCD Enable PD5 -> LCD RS Stromversorgung kommt über USB. Zwischen VCC und GND am µC noch ein 100nF KerKo. Ich kann sonst, wenn nötig, auch noch einen richtigen Schaltplan erstellen. Foto kommt gleich. Aber bitte nicht wundern, die Verkabelung ist sehr chaotisch, ist auch nur ein Testaufbau und keine fertige Schaltung.
Hier die Bilder. Wenn ihr noch einen Teilbereich genauer haben wollt einfach sagen.
Beitrag #5329310 wurde von einem Moderator gelöscht.
Beitrag #5329330 wurde von einem Moderator gelöscht.
it_is_me schrieb: > Ich wollte nun einmal IRMP ausprobieren, es gibt allerdings folgende > Probleme: > in irmpconfig.h muss AVR_ATMEGA definiert sein, um das Ziel als Atmega > zu identifizieren. Dieses Makro wird aber standardmäßig nicht definiert. > Wahlweise man ergänzt beim Kompilieren -DAVR_ATMEGA="" oder man ändert > es auf _AVR_, was sehr wohl definiert wird. Dieses Makro wird in irmpsystem.h definiert. Wenn du wie dokumentiert(!) irmp.h includierst, dann wird von diesem erst irmpsystem.h und später irmpconfig.h includiert. > Weitere Probleme sind, dass in irmpprotocols.h <stdint.h> eingebunden > werden muss, damit uint8_t benutzt werden kann. Auch diese Typen werden in irmpsystem.h definiert. > Außerdem funktioniert der Mechanismus mit >
1 | #if !defined(_IRMP_H_) && !defined(_IRSND_H_)
|
2 | > # error please include only irmp.h or irsnd.h, not irmpprotocols.h |
3 | > #endif |
> nicht. Dann machst du etwas falsch. > Außerdem wird irgendwie F_CPU undefined. Ich schreibe #define F_CPU > 16000000L ganz oben in main.c und trotzdem beschwert sich delay.h die > ganze Zeit, dass F_CPU nicht definiert wurde. Weil du es falsch machst. > Wenn ich aber mit -DF_CPU=16000000 kompiliere, dann funktioniert es. Weil es so richtig ist. Zusammenfassung: du hast die Dokumentation nicht gelesen (welches Headerfile sollst du im Anwendungscode includieren) und du hast keine Ahnung, wo man globale Makros wie F_CPU definieren muß. Kein Wunder, daß du permanent auf die Fresse^W den Mund fällst.
it_is_me schrieb im Beitrag #5329310: > it_is_me schrieb: >> Ich kann sonst, wenn nötig, auch noch einen richtigen Schaltplan >> erstellen. > > Ernsthaft jetzt? Liest du die Antworten auch durch? Oder suchst du nur > nach Schlagworte? Poste gefälligst den Code und halte uns nicht zum > Narren! Welchen Mehrwert würde dieser liefern? Ich habe bereits alle Verbindungen aufgelistet. it_is_me schrieb im Beitrag #5329330: > it_is_me schrieb: >> Ich darf den leider nicht einfach so hochladen. >> Allerdings stehe ich für die Korrektheit des Codes ein. > > Wenn der Code so aussieht wie die Schaltung auf den Fotos, ja, ich würde > dir als Elternteil dies auch verbieten! Es geht um IRMP. Axel S. schrieb: > it_is_me schrieb: >> Ich wollte nun einmal IRMP ausprobieren, es gibt allerdings folgende >> Probleme: >> in irmpconfig.h muss AVR_ATMEGA definiert sein, um das Ziel als Atmega >> zu identifizieren. Dieses Makro wird aber standardmäßig nicht definiert. >> Wahlweise man ergänzt beim Kompilieren -DAVR_ATMEGA="" oder man ändert >> es auf AVR, was sehr wohl definiert wird. > > Dieses Makro wird in irmpsystem.h definiert. Wenn du wie dokumentiert(!) > irmp.h includierst, dann wird von diesem erst irmpsystem.h und später > irmpconfig.h includiert. Ich habe es mir ja angeschaut. Ich habe auch herumprobiert. sowohl bei #ifdef IRMP_H als auch bei #ifndef IRMP_H wird #error ausgeführt. Ich habe auch nur irmp-main-avr.c genommen und es angepasst. >> Weitere Probleme sind, dass in irmpprotocols.h <stdint.h> eingebunden >> werden muss, damit uint8_t benutzt werden kann. > > Auch diese Typen werden in irmpsystem.h definiert. Ich habe nichts verändert. Und trotzdem hatte ich folgenden Fehler:
1 | irmpprotocols.h:103:9: error: unknown type name 'uint8_t' |
2 | typedef uint8_t PAUSE_LEN; |
>> Außerdem funktioniert der Mechanismus mit >>#if !defined(IRMP_H) && !defined(IRSND_H) >> # error please include only irmp.h or irsnd.h, not irmpprotocols.h >> #endif> nicht. > > Dann machst du etwas falsch. Aber was? >> Außerdem wird irgendwie F_CPU undefined. Ich schreibe #define F_CPU >> 16000000L ganz oben in main.c und trotzdem beschwert sich delay.h die >> ganze Zeit, dass F_CPU nicht definiert wurde. > > Weil du es falsch machst. Anbei der Code (mit IRMP). Ich verstehe nicht, was ich falsch mache. Ich definiere, bevor ich irgendetwas inkludiere, F_CPU. >> Wenn ich aber mit -DF_CPU=16000000 kompiliere, dann funktioniert es. > > Weil es so richtig ist. Es sollte eigentlich egal sein, ob ich etwas am Anfang der main.c definiere oder über den Compiler. > Zusammenfassung: du hast die Dokumentation nicht gelesen (welches > Headerfile sollst du im Anwendungscode includieren) und du hast keine > Ahnung, wo man globale Makros wie F_CPU definieren muß. Kein Wunder, daß > du permanent auf die Fresse^W den Mund fällst. Anbei der Code. Die Ausgabe müsste man nur noch ergänzen in main.c.
Zum Warmwerden vielleicht erstmal LED-Blinken im Sekundentakt, unter Verwendung von delay_ms(). Dann wäre schonmal der Basistakt klar.
batman schrieb: > Zum Warmwerden vielleicht erstmal LED-Blinken im Sekundentakt, > unter > Verwendung von delay_ms(). Dann wäre schonmal der Basistakt klar. Die Dauer zum Einpendeln der Frequenz sollte aber eigentlich nicht so lange sein. Und den Basistakt kenne ich ja, 8MHz beim ATmega8A. Als kleine Anmerkung: einfach das Bashskript ausführen, dann kommen genau die Warnungen, die ich erwähnt habe (nur habe ich das #error durch #warnung ersetzt, damit es kompiliert). Unter Windows muss man vermutlich allerdings die Programme natürlich austauschen.
it_is_me schrieb: > Und den Basistakt kenne ich ja, 8MHz beim ATmega8A. Gut für dich aber es kommt mehr drauf an, daß alle kompilierten Module ihn kennen.
Meinst du mit Module die Header und Source Files? Da läuft ja eigentlich erst einmal der Präprozessor drüber. Und dann sollte das eigentlich egal sein. Und das F_CPU ist eigentlich das kleinste Problem. Es läuft ja auch auf dem ATmega328P. Es geht darum, dass genau der gleiche Code nicht auf einem ATmega8A läuft (nur dass F_CPU von 16000000 auf 8000000 umdefiniert wird). Ich verstehe vor allem nicht, was blinkende LEDs damit zu tun haben?
Beitrag #5329466 wurde von einem Moderator gelöscht.
Beitrag #5329468 wurde von einem Moderator gelöscht.
it_is_me schrieb: > Axel S. schrieb: >>> in irmpconfig.h muss AVR_ATMEGA definiert sein, um das Ziel als Atmega >>> zu identifizieren. Dieses Makro wird aber standardmäßig nicht definiert. >> >> Dieses Makro wird in irmpsystem.h definiert. Wenn du wie dokumentiert(!) >> irmp.h includierst, dann wird von diesem erst irmpsystem.h und später >> irmpconfig.h includiert. > > Ich habe es mir ja angeschaut. Ich habe auch herumprobiert. sowohl bei > #ifdef IRMP_H als auch bei #ifndef IRMP_H wird #error ausgeführt. Was hat das eine mit dem anderen zu tun? >>> Weitere Probleme sind, dass in irmpprotocols.h <stdint.h> eingebunden >>> werden muss, damit uint8_t benutzt werden kann. >> >> Auch diese Typen werden in irmpsystem.h definiert. > > Ich habe nichts verändert. Und trotzdem hatte ich folgenden Fehler: >
1 | irmpprotocols.h:103:9: error: unknown type name 'uint8_t' |
2 | > typedef uint8_t PAUSE_LEN; |
Und was hast du getan, wofür du diesen Fehler bekommen hast? Wenn du, wie dokumentiert irmp.h includierst, dann wird die derart behandelte C-Unit danach immer noch compilieren. Wenn du irmpprotocols.h direkt includierst, dann nicht. Weil das falsch wäre. >>> Außerdem funktioniert der Mechanismus mit >>>#if !defined(IRMP_H) && !defined(IRSND_H) >>> # error please include only irmp.h or irsnd.h, not irmpprotocols.h >>> #endif> nicht. >> >> Dann machst du etwas falsch. > > Aber was? Da du nicht sagst, was du genau tust, wenn du eine Fehlermeldung bekommst ... keine Ahnung. Aber für mich compiliert das out of the box:
1 | ~ $cd /tmp |
2 | /tmp $unzip Irmp.zip |
3 | ... |
4 | /tmp $fgrep Version README.txt |
5 | Version IRMP: 3.0.9 2018-02-19 |
6 | Version IRSND: 3.0.9 2018-02-19 |
7 | /tmp $avr-gcc -mmcu=atmega8 -DF_CPU=8000000 -Os -std=c99 -Wall -pedantic -c irmp.c |
8 | /tmp $avr-gcc -mmcu=atmega8 -DF_CPU=8000000 -Os -std=c99 -Wall -pedantic -c irmp-main-avr.c |
9 | /tmp $avr-gcc -o test.elf irmp-main-avr.o irmp.o |
10 | /tmp $avr-size test.elf |
11 | text data bss dec hex filename |
12 | 2254 4 48 2306 902 test.elf |
Kein Fehler, keine Warnung (und das trotz -pedantic) >>> Außerdem wird irgendwie F_CPU undefined. Ich schreibe #define F_CPU >>> 16000000L ganz oben in main.c und trotzdem beschwert sich delay.h die >>> ganze Zeit, dass F_CPU nicht definiert wurde. >> >> Weil du es falsch machst. > >>> Wenn ich aber mit -DF_CPU=16000000 kompiliere, dann funktioniert es. >> >> Weil es so richtig ist. > > Es sollte eigentlich egal sein, ob ich etwas am Anfang der main.c > definiere oder über den Compiler. Jein. Ein #define gilt nur für die Übersetzungseinheit (vulgo: das .c File) in dem es steht. In irmp.c steht kein solches #define. Und wenn du es nicht reinschreiben willst (wäre eine blöde Idee <tm>) dann mußt du es in den globalen Projekteinstellungen respektive im Makefile definieren. Das ist auch deswegen sinnvoll, weil es überall den gleichen Wert haben sollte.
it_is_me schrieb: > in irmpconfig.h muss AVR_ATMEGA definiert sein, um das Ziel als Atmega > zu identifizieren. Nein, die Konstante AVR_ATMEGA wird nirgendwo im IRMP-Source abgefragt. Lediglich ATMEL_AVR. Und diese Konstante wird automatisch in irmpsystem.h gesetzt, wenn es weder ein PIC noch ein STM32 noch ein STM8 noch ein ESP8266 noch ein TI Stellaris noch ein Teensy noch Linux noch Windows ist. > Wahlweise man ergänzt beim Kompilieren -DAVR_ATMEGA="" oder man ändert > es auf AVR, was sehr wohl definiert wird. Das ist Unsinn. Wenn Du ausschließlich irmp.h includest - wie es im Artikel angegeben ist - kann dieser Fehler nicht auftreten. Siehe auch Bild oben. > Weitere Probleme sind, dass in irmpprotocols.h <stdint.h> eingebunden > werden muss, damit uint8_t benutzt werden kann. irmpprotocols.h wird automatisch von irmp.h included. Du brauchst nur irmp.h zu includen, also
1 | #include "irmp.h" |
> Außerdem funktioniert der Mechanismus mit#if !defined(IRMP_H) && > !defined(IRSND_H) > # error please include only irmp.h or irsnd.h, not irmpprotocols.h > #endif > nicht. > Dies wird, warum auch immer, jedes Mal ausgelöst. Ich inkludiere aber > nur irmp.h. Glaube ich nicht. Irgendwas machst Du falsch, denn irmp.h definiert IRMP_H und damit kann die obige Fehlermeldung *nicht kommen*:
1 | #ifndef _IRMP_H_
|
2 | #define _IRMP_H_
|
3 | |
4 | #include "irmpsystem.h" |
> Außerdem wird irgendwie F_CPU undefined. Ich schreibe #define F_CPU > 16000000L ganz oben in main.c und trotzdem beschwert sich delay.h die > ganze Zeit, dass F_CPU nicht definiert wurde. Das ist im Artkikel dokumentiert: Du solltest entweder in der IDE oder - wenn keine IDE eingesetzt wird - im Makefile -DFCPU=16000000UL definieren und nicht im Source. Siehe auch Bild oben - Hardcopy aus dem Artikel. Der Text ist im Artikel auch extra rot umrandet, damit man ihn nicht übersieht. > Wenn ich aber mit > -DF_CPU=16000000 kompiliere, dann funktioniert es. > Naja, ich flashe es jetzt einmal mit diesen Änderungen und mal sehen... So ist es auch richtig(!), siehe Artikel IRMP. it_is_me schrieb: > Auch wenn die eigentlich gesendeten Signale in einen Wert zwischen 0 und > 255 umgewandelt werden. (aus 0xFF02FD wird 64, etc.) > Da müsste ich allerdings noch einmal tiefer in den Code schauen. Die 64 (0x40) ist auch richtig so, Dein Code 0xFF02FD ist falsch! Gründe: 1. Die Adresse sowohl der Kommando-Code bei NEC ist Little-Endian, d.h. das LSB kommt zuerst, das MSB kommt zuletzt. 2. Der Kommando-Code bei NEC besteht nur aus einem Byte, denn im folgenden Byte sind die Bits zwecks Redundanz lediglich invertiert. D.h. Es ist nur ein Byte (abgesehen von der Adresse) notwendig, um den Kommando-Code eindeutig anzugeben. 3. IRSND generiert natürlich das invertierte 2. Byte automatisch aus dem einen Byte des Kommando-Code Siehe dazu auch: https://www.mikrocontroller.net/articles/IRMP#NEC_.2B_extended_NEC Da wird das NEC-Protokoll erklärt. Dein Code 0xFF02FD ist also falsch. Die Adresse FF stimmt hier nur zufällig, da ein FF sowohl im Little-Endian- also auch im Big-Endian-Format FF bleibt. Die 02 muss man aber umdrehen: 00000010 = 0x02 falsch 01000000 = 0x40 (=64 dez) richtig FD ist lediglich der inverte Wert: 11111101 = 0xFD falsch 10111111 = 0xBF richtig Dieser Wert dient nur der Überprüfung, ob der Kommando-Code richtig empfangen wurde und ist sonst zu ignorieren. Die Überprüfung nimmt IRMP automatisch vor und gibt die Werte des Frames nur dann an die Anwendung weiter, wenn der Kommando-Code mit dem invertierten Byte übereinstimmt. Daraus folgt: protocol = 2 (NEC) address = 0xFF (=255 dez) command = 0x40 (=64 dez)
:
Bearbeitet durch Moderator
Beitrag #5329647 wurde von einem Moderator gelöscht.
Ich habe die Beiträge vom gleichamigen Fake it_is_me (Gast) aus diesem Thread gelöscht, da er nichts beizutragen hat.
Axel S. schrieb: > it_is_me schrieb: >> Axel S. schrieb: > >>>> in irmpconfig.h muss AVR_ATMEGA definiert sein, um das Ziel als Atmega >>>> zu identifizieren. Dieses Makro wird aber standardmäßig nicht definiert. >>> >>> Dieses Makro wird in irmpsystem.h definiert. Wenn du wie dokumentiert(!) >>> irmp.h includierst, dann wird von diesem erst irmpsystem.h und später >>> irmpconfig.h includiert. >> >> Ich habe es mir ja angeschaut. Ich habe auch herumprobiert. sowohl bei >> #ifdef IRMP_H als auch bei #ifndef IRMP_H wird #error ausgeführt. > > Was hat das eine mit dem anderen zu tun? Dass ich irgendwie verwirrt bin, weil es mal definiert ist und mal nicht. Bei ansonsten genau dem gleichen Vorgehen. >>>> Weitere Probleme sind, dass in irmpprotocols.h <stdint.h> eingebunden >>>> werden muss, damit uint8_t benutzt werden kann. >>> >>> Auch diese Typen werden in irmpsystem.h definiert. >> >> Ich habe nichts verändert. Und trotzdem hatte ich folgenden Fehler: >>irmpprotocols.h:103:9: error: unknown type name 'uint8_t' >> typedef uint8_t PAUSE_LEN; > Und was hast du getan, wofür du diesen Fehler bekommen hast? Wenn du, > wie dokumentiert irmp.h includierst, dann wird die derart behandelte > C-Unit danach immer noch compilieren. Wenn du irmpprotocols.h direkt > includierst, dann nicht. Weil das falsch wäre. Ich habe nur "irmp.h" inkludiert und dann mit
1 | avr-gcc -Os -mmcu=atmega8 *.h *.c -o out |
kompiliert. >>>> Außerdem funktioniert der Mechanismus mit >>>>#if !defined(IRMP_H) && !defined(IRSND_H) >>>> # error please include only irmp.h or irsnd.h, not irmpprotocols.h >>>> #endif> nicht. >>> >>> Dann machst du etwas falsch. >> >> Aber was? > > Da du nicht sagst, was du genau tust, wenn du eine Fehlermeldung > bekommst ... keine Ahnung. Aber für mich compiliert das out of the box: > ~ $cd /tmp > /tmp $unzip Irmp.zip > ... > /tmp $fgrep Version README.txt > Version IRMP: 3.0.9 2018-02-19 > Version IRSND: 3.0.9 2018-02-19 > /tmp $avr-gcc -mmcu=atmega8 -DF_CPU=8000000 -Os -std=c99 -Wall -pedantic > -c irmp.c > /tmp $avr-gcc -mmcu=atmega8 -DF_CPU=8000000 -Os -std=c99 -Wall -pedantic > -c irmp-main-avr.c > /tmp $avr-gcc -o test.elf irmp-main-avr.o irmp.o > /tmp $avr-size test.elf > text data bss dec hex filename > 2254 4 48 2306 902 test.elf > > Kein Fehler, keine Warnung (und das trotz -pedantic) Wenn ich nur die beiden einzeln kompiliere und linke, dann habe ich tatsächlich auch keinen Fehler. Ergibt tatsächlich auch Sinn. Ich habe eben immer alles auf einmal kompiliert mit *.h *.c als Input. >>>> Außerdem wird irgendwie F_CPU undefined. Ich schreibe #define F_CPU >>>> 16000000L ganz oben in main.c und trotzdem beschwert sich delay.h die >>>> ganze Zeit, dass F_CPU nicht definiert wurde. >>> >>> Weil du es falsch machst. >> >>>> Wenn ich aber mit -DF_CPU=16000000 kompiliere, dann funktioniert es. >>> >>> Weil es so richtig ist. >> >> Es sollte eigentlich egal sein, ob ich etwas am Anfang der main.c >> definiere oder über den Compiler. > > Jein. Ein #define gilt nur für die Übersetzungseinheit (vulgo: das .c > File) in dem es steht. In irmp.c steht kein solches #define. Und wenn du > es nicht reinschreiben willst (wäre eine blöde Idee <tm>) dann mußt du > es in den globalen Projekteinstellungen respektive im Makefile > definieren. Das ist auch deswegen sinnvoll, weil es überall den gleichen > Wert haben sollte. Okay, danke. Irgendwie habe ich vergessen, dass irmp.c und main.c ja getrennt kompiliert werden. Frank M. schrieb: > it_is_me schrieb: >> in irmpconfig.h muss AVR_ATMEGA definiert sein, um das Ziel als Atmega >> zu identifizieren. > > Nein, die Konstante AVR_ATMEGA wird nirgendwo im IRMP-Source > abgefragt. Lediglich ATMEL_AVR. Und diese Konstante wird automatisch > in irmpsystem.h gesetzt, wenn es weder ein PIC noch ein STM32 noch ein > STM8 noch ein ESP8266 noch ein TI Stellaris noch ein Teensy noch Linux > noch Windows ist. Hier habe ich mich verguckt. Ja, ist ATMEL_AVR. >> Wahlweise man ergänzt beim Kompilieren -DAVR_ATMEGA="" oder man ändert >> es auf AVR, was sehr wohl definiert wird. > > Das ist Unsinn. Wenn Du ausschließlich irmp.h includest - wie es im > Artikel angegeben ist - kann dieser Fehler nicht auftreten. Siehe auch > Bild oben. Achso, ich dachte der Code geht davon aus, dass der Compiler dieses ATMEL_AVR Makro automatisch definiert. Wieder ein Fehler durch die Massenkompilierung und gleichzeitige Linkung. >> Weitere Probleme sind, dass in irmpprotocols.h <stdint.h> eingebunden >> werden muss, damit uint8_t benutzt werden kann. > > irmpprotocols.h wird automatisch von irmp.h included. Du brauchst nur > irmp.h zu includen, also#include "irmp.h" Ja, das habe ich auch so gemacht. >> Außerdem funktioniert der Mechanismus mit#if !defined(IRMP_H) && >> !defined(IRSND_H) >> # error please include only irmp.h or irsnd.h, not irmpprotocols.h >> #endif >> nicht. >> Dies wird, warum auch immer, jedes Mal ausgelöst. Ich inkludiere aber >> nur irmp.h. > > Glaube ich nicht. Irgendwas machst Du falsch, denn irmp.h definiert > IRMP_H und damit kann die obige Fehlermeldung *nicht kommen*:#ifndef > _IRMP_H_ > #define _IRMP_H_ > > #include "irmpsystem.h" Das lag wohl tatsächlich daran, dass ich alles mit *.h *.c kompiliert habe. >> Außerdem wird irgendwie F_CPU undefined. Ich schreibe #define F_CPU >> 16000000L ganz oben in main.c und trotzdem beschwert sich delay.h die >> ganze Zeit, dass F_CPU nicht definiert wurde. > > Das ist im Artkikel dokumentiert: Du solltest entweder in der IDE oder - > wenn keine IDE eingesetzt wird - im Makefile -DFCPU=16000000UL > definieren und nicht im Source. Siehe auch Bild oben - Hardcopy aus dem > Artikel. Der Text ist im Artikel auch extra rot umrandet, damit man ihn > nicht übersieht. Okay, danke. Lesen kann tatsächlich helfen. > it_is_me schrieb: >> Auch wenn die eigentlich gesendeten Signale in einen Wert zwischen 0 und >> 255 umgewandelt werden. (aus 0xFF02FD wird 64, etc.) >> Da müsste ich allerdings noch einmal tiefer in den Code schauen. > > Die 64 (0x40) ist auch richtig so, Dein Code 0xFF02FD ist falsch! > > Gründe: > > 1. Die Adresse sowohl der Kommando-Code bei NEC ist Little-Endian, > d.h. das LSB kommt zuerst, das MSB kommt zuletzt. > > 2. Der Kommando-Code bei NEC besteht nur aus einem Byte, denn > im folgenden Byte sind die Bits zwecks Redundanz lediglich > invertiert. D.h. Es ist nur ein Byte (abgesehen von der > Adresse) notwendig, um den Kommando-Code eindeutig anzugeben. > > 3. IRSND generiert natürlich das invertierte 2. Byte automatisch > aus dem einen Byte des Kommando-Code > > Siehe dazu auch: > > https://www.mikrocontroller.net/articles/IRMP#NEC_... > > Da wird das NEC-Protokoll erklärt. > > Dein Code 0xFF02FD ist also falsch. Die Adresse FF stimmt hier nur > zufällig, da ein FF sowohl im Little-Endian- also auch im > Big-Endian-Format FF bleibt. > > Die 02 muss man aber umdrehen: > 00000010 = 0x02 falsch > 01000000 = 0x40 (=64 dez) richtig > > FD ist lediglich der inverte Wert: > 11111101 = 0xFD falsch > 10111111 = 0xBF richtig > > Dieser Wert dient nur der Überprüfung, ob der Kommando-Code richtig > empfangen wurde und ist sonst zu ignorieren. Die Überprüfung nimmt > IRMP automatisch vor und gibt die Werte des Frames nur dann an die > Anwendung weiter, wenn der Kommando-Code mit dem invertierten Byte > übereinstimmt. > > Daraus folgt: > > protocol = 2 (NEC) > address = 0xFF (=255 dez) > command = 0x40 (=64 dez) Okay, vielen Dank für diese Erklärung. Ich bin von dem Code ausgegangen, der bei der Fernbedienung dabei war und habe diesen erweitert. Aber die Grundlage blieb eben gleich und anscheinend falsch. Danke für die Aufklärung! Stimmt es dann aber tatsächlich, dass mit NEC nur 255 verschiedene Signale möglich sind? Und, wenn man mehr will, mehrere kombinieren muss? Frank M. schrieb: > Ich habe die Beiträge vom gleichamigen Fake it_is_me (Gast) aus > diesem > Thread gelöscht, da er nichts beizutragen hat. Danke. Aber: Das Problem besteht leider immer noch. Auf dem ATmega328P läuft es. Auf dem ATmega8A nicht.
it_is_me schrieb: > Ich habe nur "irmp.h" inkludiert und dann mit
1 | > avr-gcc -Os -mmcu=atmega8 *.h *.c -o out |
> kompiliert. Und das ist falsch. Wenn du das "*.h" rausnimmst, ist es besser. Eigentlich würde man aber File für File compilieren wollen. Lern make. it_is_me schrieb: > Das Problem besteht leider immer noch. > Auf dem ATmega328P läuft es. > Auf dem ATmega8A nicht. Details? "läuft nicht" kann alles mögliche sein. Prüfe die Takteinstellung (FUSES, Prescaler). Ist der Timer für den Interrupt richtig konfiguriert? Stimmt die Angabe der Timerfrequenz in irmp_config.h?
Axel S. schrieb: > it_is_me schrieb: >> Ich habe nur "irmp.h" inkludiert und dann mit > >> avr-gcc -Os -mmcu=atmega8 *.h *.c -o out > >> kompiliert. > > Und das ist falsch. Wenn du das "*.h" rausnimmst, ist es besser. > Eigentlich würde man aber File für File compilieren wollen. Lern make. Ja, *.h muss definitiv raus. Genau diese verursachen natürlich obige Fehlermeldungen. Aber wenn man *.h rausnimmt, ist es immer noch falsch. Im Empfänger braucht man keinen IRSND. Außerdem schwirren im IRMP-Verzeichnis diverse xxxx-main.c rum, die nur als Beispiele dienen. Richtig ist:
1 | avr-gcc -Os -mmcu=atmega8 mein-irmp-main.c irmp.c -o irmp |
Später auf der Sender-Seite für IRSND:
1 | avr-gcc -Os -mmcu=atmega8 mein-irsnd-main.c irsnd.c -o irsnd |
:
Bearbeitet durch Moderator
it_is_me schrieb: > Achso, ich dachte der Code geht davon aus, dass der Compiler dieses > ATMEL_AVR Makro automatisch definiert. Wieder ein Fehler durch die > Massenkompilierung und gleichzeitige Linkung. Ja. > Das lag wohl tatsächlich daran, dass ich alles mit *.h *.c kompiliert > habe. Ja. *.h hat nichts beim Compiler-Aufruf zu suchen. > Stimmt es dann aber tatsächlich, dass mit NEC nur 255 verschiedene > Signale möglich sind? Und, wenn man mehr will, mehrere kombinieren muss? Nicht ganz, es sind nicht 255, sondern 256. Beim NEC-Protokoll gibt es nur 256 verschiede Kommandos, denn das 4. Byte im Frame ist immer der invertierte Wert vom 3. Byte. Mit "Kombinieren" meinst Du offenbar, mehrere Frames zu schicken bzw. zu empfangen? Dazu kommen aber noch 256 verschiedene Geräte-Adressen beim NEC-Standard-Protokoll. Dabei ist das Byte 1 die Adresse, und Byte 2 die invertierte Adresse - wie beim Kommando-Code. Später haben die Hersteller das aber aufgeweicht und die Forderung, dass das 2. Byte das invertierte 1. Byte sein muss, fallengelassen, um so mehr Geräte-Adressen zu bekommen. Diese Erweiterung hat man dann "Extended NEC" genannt. Damit sind nun 65536 verschiedene Adressen möglich. Aus diesem Grund beachtet IRMP die Adress-Bytes vollkommen unanbhängig voneinander. Deine Fernbedienung macht übrigens NEC-Standard, denn das zweite Byte ist bei Dir 0x00, welches der invertierte Wert von 0xFF ist. Siehe auch: https://www.mikrocontroller.net/articles/IRMP#NEC_.2B_extended_NEC Da sind die Bits erklärt - sowohl für NEC als auch Extended NEC. Du hast also beim NEC-Protokoll: Adresse irmp_data.address: Werte von 0x0000 bis 0xFFFF Kommando: irmp_data.command: Werte von 0x00 bis 0xFF Theoretisch kannst Du also 3 Bytes in einem Extended-NEC-Frame übertragen, wenn Du die Adressbytes nicht als Adressen, sondern als Daten betrachtest. Was willst Du eigentlich machen? Vielleicht Daten von einem µC auf einen anderen per IR übertragen? Dafür habe ich für IRMP in Version 3.0.8 das Protokoll "IRMP16" eingeführt. Damit kann man direkt 16 Bit mit einem Frame übertragen. Das geht dann etwas flotter als mit NEC. > Das Problem besteht leider immer noch. > Auf dem ATmega328P läuft es. > Auf dem ATmega8A nicht. Wahrscheinlich stimmen die Fuses auf dem ATmega nicht. Siehe auch: http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega8a
:
Bearbeitet durch Moderator
Axel S. schrieb: > it_is_me schrieb: >> Ich habe nur "irmp.h" inkludiert und dann mit> avr-gcc -Os -mmcu=atmega8 *.h *.c > -o out >> kompiliert. > > Und das ist falsch. Wenn du das "*.h" rausnimmst, ist es besser. > Eigentlich würde man aber File für File compilieren wollen. Lern make. Ja, danke. > it_is_me schrieb: >> Das Problem besteht leider immer noch. >> Auf dem ATmega328P läuft es. >> Auf dem ATmega8A nicht. > > Details? "läuft nicht" kann alles mögliche sein. > > Prüfe die Takteinstellung (FUSES, Prescaler). Ist der Timer für den > Interrupt richtig konfiguriert? Stimmt die Angabe der Timerfrequenz in > irmp_config.h? Ich habe gerade einmal in main.c die Werte für OCR1A ausgerechnet für 8MHz und 16MHz, das stimmt eigentlich beides. Dort habe ich auch nichts verändert. FUSES des ATmega8As sind E:FF, H:D9, L:E4. Frank M. schrieb: > Aber wenn man *.h rausnimmt, ist es immer noch falsch. > Im Empfänger braucht man keinen IRSND. Außerdem schwirren im > IRMP-Verzeichnis diverse xxxx-main.c rum, die nur als Beispiele dienen. Alles andere, was ich nicht brauche, habe ich schon gelöscht. Vielen Dank auch für deine Erklärungen zum NEC-Protokoll und den Hinweis auf IRMP16. Das ist nämlich eigentlich die bekannteste IR-Lib für Arduino, in der das so falsch stand. >> Das Problem besteht leider immer noch. >> Auf dem ATmega328P läuft es. >> Auf dem ATmega8A nicht. > > Wahrscheinlich stimmen die Fuses auf dem ATmega nicht. Siehe auch: > > http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega8a Fuses habe ich oben schon erwähnt. Nach diesem Calc ist also Watchdog deaktiviert. Wird das für IRMP benötigt? Eigentlich war für das high-fuse D9 auch der default-value.
it_is_me schrieb: > FUSES des ATmega8As sind E:FF, H:D9, L:E4. > Nach diesem Calc ist also Watchdog deaktiviert. Wird das für IRMP > benötigt? Nein, Watchdog wird nicht benötigt. Ich übersetze mal die Fuses: - Brown Out bei 2,7V, gut. - Interner Oszillator mit 8MHz, gut, wenn F_CPU=8000000UL eingestellt. - SPI enabled, gut. Sieht eigentlich gut aus. Auch schon mal einen anderen ATMega8 probiert? Hast Du einen 16MHz-Quarz am ATmega oder soll der über den internen Oszillator mit 8MHz getaktet werden?
An dem ATmega328P (Uno Board) ist ein 16MHz Quarz. Der funktioniert soweit auch. Der ATmega8A wird mit dem internen Oszillator (8MHz) betrieben. Ich werde einmal einen anderen testen und mich dann hier melden. Ich kann sonst auch noch einmal versuchen, den ATmega328P auf den internen Oszillator umzustellen es dann einmal dort zu flashen.
Ich habe jetzt einmal einen ganz neuen genommen und es funktioniert tatsächlich. Ich werde noch einmal mit dem alten ein wenig herumspielen, aber vllt. hat der einfach eine Macke. Könnte natürlich durch statische Ladung oder so kommen, wenn ich mal vergessen habe, mein Armband anzulegen. Danke euch allen.
it_is_me schrieb: > Ich habe jetzt einmal einen ganz neuen genommen und es funktioniert > tatsächlich. Freut mich. > Ich werde noch einmal mit dem alten ein wenig herumspielen, aber vllt. > hat der einfach eine Macke. Ja, wahrscheinlich. Warum nimmst Du so einen altertümlichen ATmega8? Der wurde doch schon längst durch den ATmeg88 (weitgehend kompatibel mit dem 328er) abgelöst. Viel Spaß!
:
Bearbeitet durch Moderator
Frank M. schrieb: > Ja, wahrscheinlich. Warum nimmst Du so einen altertümlichen ATmega8? Der > wurde doch schon längst durch den ATmeg88 (weitgehend kompatibel mit dem > 328er) abgelöst. Weil der ATmega8 billig ist. Ich weiß, dass der Unterschied nicht groß ist, aber am Anfang habe ich halt einfach einmal ein paar davon bestellt, auch weil es recht viele Informationen dazu zu finden gab. Aber warum der ATmega88? Der ist (zumindest bei Reichelt) genauso teuer wie ein ATmega328P (2.50€), hat aber deutlich weniger Speicher. Die max. Frequenz ist auch nicht höher. Was hat der sonst für Vorteile?
it_is_me schrieb: > Was hat der sonst für Vorteile? Gegenüber dem ATMega328? Keine. Gegenüber dem alten ATMega8? Jede Menge. Der 88er ist lediglich der kleine Bruder vom 328er. Bis auf RAM und Flash ist er weitgehend identisch. Die 328er sind lediglich so billig (im Verhältnis), weil sie wohl durch die Arduinos wesentlich mehr verbreitet sind. Eine andere Erklärung habe ich nicht. Aber das kommt immer auf die Stückzahl an. Bei 3 Stück wären mir die paar Cent Unterschied zum alten ATmega8 egal.
Frank M. schrieb: > it_is_me schrieb: >> Ich habe jetzt einmal einen ganz neuen genommen und es funktioniert >> tatsächlich. > > Freut mich. ACK. Aber auch <seufz> > Warum nimmst Du so einen altertümlichen ATmega8? Warum nicht? > Der wurde doch schon längst durch den ATmeg88 (weitgehend kompatibel > mit dem 328er) abgelöst. So etwas wie "Ablösung" gibt es da nicht. Geht doch nicht um eine Serienproduktion. Oder? Ich habe auch gerade wieder einen ATMega8 verbastelt. Weil ich nach Durchsicht der Bestände festgestellt habe, daß noch welche da sind. Und daß mir der ATMega88 in dieser Anwendung ohnehin keinen Vorteil bringt. Da hau ich doch lieber einen "alten" ATMega8 weg und spare den 88er für ein Projekt, das dessen spezielle Fähigkeiten auch benötigt.
Axel S. schrieb: > Ich habe auch gerade wieder einen ATMega8 verbastelt. Weil ich nach > Durchsicht der Bestände festgestellt habe, daß noch welche da sind. Da hast Du natürlich recht. Wenn man sie noch hat, sollte man sie auch noch nutzen. > Und daß mir der ATMega88 in dieser Anwendung ohnehin keinen Vorteil > bringt. Da hau ich doch lieber einen "alten" ATMega8 weg und spare > den 88er für ein Projekt, das dessen spezielle Fähigkeiten auch > benötigt. Stimmt auch wieder.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.