Forum: Mikrocontroller und Digitale Elektronik IR Fernbedienung mit IRSND


von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

wende mich nun an euch, da ich aktuell nicht mehr weiter weiß.

Habe versucht eine IR Fernbedienung zu Programmieren.
Dazu das IRSND Projekt verwendet.
In ein Atmel Studio 6 Projekt geladen.

Wenn ich eine Taste drücke, wird die IR LED auch angesteuert.
(Mit der Digitalkamera angeschaut)

Zur Kontrolle der Befehle verwende ich das IRMP mit UART Ausgabe.
Dies funktioniert mit einer "echten" Fernbedienung super. :-)
Hier werden auch die originalen NEC Codes problemlos dargestellt.


Nur leider meine mit IRSND programmierte Sache wird nicht erkannt.
Somit denke ich, dass da irgendwas in meinem Code nicht passt.
Verwende hierbei die gleichen Codes wie meine richtigen Fernbedienungen, 
die erkannt werden.


HW ist ein:
Mega8 mit 8MHz Quarz
Alternativ auch mit einem Mega16 probiert.
Bei beiden das gleiche.
FuseBits sind auf externen Quarz eingestellt (mit internem Takt hats 
auch nicht funktioniert)

IR LED blinkt zwar, aber scheinbar werden nicht die richtigen Werte 
gesendet.
IR LED am richtigen Ausgang vom Mega8 angeschlossen.
In der IRSNDconfig.h eingestellt.
Aufbau der IR LED genau wie im Artikel beschrieben (mit Transistor usw).

Anbei der c Code.
Hier werden aktuell nur zwei Taster abgefragt, die dann das NEC Signal 
senden sollten.
Aber leider ist das gesendete Signal nicht passend?
(Ob ein Signal gesendet wird, oder die LED nur irgendwie blinkt kann ich 
leider nicht testen)

Hab zwar den IRSND Artikel schon mehrmals gelesen, aber irgendwie mach 
ich scheinbar was falsch :-)
Nur ich weiß nicht was.
Hat jemand einen Tipp für mich was ich falsch mache?


Später möchte ich natürlich mehrere Taster und mehrere Signale senden.
Auch (sofern ich es schaffe) soll eine Taster wenn er länger als 1 sek 
betätigt wird ein anderes Signal senden.
So zumindest der Plan :-)

Grüße
Andreas

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

wie jeder leicht erkennt, ist die irsnd.h -Datei zwar eingebunden, aber 
niemand außer Dir kann den geheimen Inhalt mit den magischen 
Einstellungen erkennen. Vielleicht wird sich dort noch ein Fehler 
finden, den es zu korrigieren gilt. Möglichkeiten gibt es sicher 
genügend.

MfG

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Hi Christian,

danke für deine schnelle Antwort.
Anbei nun alle Dateien, die im Gesamtverbund verwendet werden.
Angepasst habe ich die
irsndconfig.h wegen der Zuordnung des Ausganges der IR LED
Sowie meine Fernbedienung...c Datei, in der ich etwas rumgewurschtelt 
habe.
Der Rest ist noch original aus dem Grundprojekt.

Gruß
Andreas

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Andreas schrieb:
> Mega8 mit 8MHz Quarz
> ...
> FuseBits sind auf externen Quarz eingestellt (mit internem Takt hats
> auch nicht funktioniert)

Nenne bitte die Werte der Fusebits und vergleiche sie mit

http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega8

> Zur Kontrolle der Befehle verwende ich das IRMP mit UART Ausgabe.

Sehr gut. Aktiviere bitte IRMP_LOGGING und zeige bitte die UART-Ausgabe, 
wenn Du etwas von der FB empfängst und dann nochmal, was reinkommt, wenn 
Du IRSND verwendest. Läuft IRMP bei Dir auch auf einem ATmega8? Sind die 
Fusebits identisch?

Es wäre auch hilfreich, wenn Du den Schaltplan, wie Du die IR-LED 
ansteuerst, hier zeigst. Ebenso eine Skizze, wie die Taster 
angeschlossen sind.

Ich vermute, dass der ATmega8 für IRSND gar nicht mit 8 MHz läuft. Das 
kannst Du leicht überprüfen mittels folgender Schleife und einer 
beliebigen LED mit sichtbarem Licht:
1
    while (1)
2
    {
3
        schalte_led_ein ();
4
        _delay_ms (1000);
5
        schalte_led_aus ();
6
        _delay_ms (1000);
7
    }

Die LED müsste dann im Sekundenrhytmus blinken.

P.S.
Nicht vergessen, den Optimizer einzuschalten, am besten mit -Os. Sonst 
laufen die Delay-Routinen nicht korrekt.

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


Lesenswert?

Nachtrag:

Ich sehe in Fernbedienung_mit_IRSND_mega8.c folgendes:
1
#define F_CPU 8000000L
2
#include "irsnd.h"

Das ist unschön. F_CPU sollte global im Projekt Deiner 
Entwicklungsumgebung und nicht im Source definiert werden. Das wird so 
auch ausdrücklich in der Doku zu IRMP/IRSND empfohlen.

Grund: Das Schreiben in den Source kann zu Inkonsistenzen führen, 
nämlich zum Beispiel, wenn Du einen abweichenden Wert in irsnd.c und in 
Fernbedienung_mit_IRSND_mega8.c schreibst, weil Du vergessen hast, an 
beiden Stellen zu ändern.

Also lösche bitte alle #defines von F_CPU in den Sourcen und definiere 
F_CPU einmal in Deinem Atmel Studio 6 Projekt. Wie das geht, findest 
Du hier in diversen Threads.

P.S.
Wenn ich mir das angehängte irsnd.c anschaue, dann sehe ich folgendes:
1
#include "irsnd.h"
2
3
#ifndef F_CPU
4
#  error F_CPU unkown
5
#endif

Wenn das wirklich der Stand ist, den Du verwendest, sollte das 
Compilieren abbrechen, da Du hier kein F_CPU definiert ist. Wenn es 
trotzdem genau so durch den Compiler geht, dann musst Du ja schon eine 
projektweite Einstellung gemacht haben. Wie lautet dann diese und warum 
hast Du F_CPU dann doch nochmal Fernbedienung_mit_IRSND_mega8.c 
definiert, was dann gar nicht mehr notwendig ist?

Irgendwas stimmt hier nicht....

: Bearbeitet durch Moderator
von Andreas (Gast)


Lesenswert?

Hi Frank,

danke für die super Antwort :-)

Habe mein eigenes
1
#define F_CPU 8000000L
aus meiner Fermbedienung...c Datei gelöscht, es kam kein Fehler beim 
compilieren.
Danach die F_CPU mit 8MHz global im Projekt gesetzt.
Jetzt weiß ich auch, dass man sowas auch machen kann.
Hab hier im Forum einen super Screenshot dazu gefunden :-)

-> jetzt funktioniert es
im putty, das ich mit dem IRMP (läuft auch auf einem Mega 8 mit 8MHz) 
verbunden habe sehe ich nun die IRSND Signale.
Sind die gleichen wie mit der richtigen Fernbedienung.
TOP
Freut mich jetzt richtig, dass es funktioniert.

Im IRMP hab ich das F_CPU setzen auch über den Source Code gesetzt.
War scheinbar Zufall, dass es geklappt hat.

Auf das globale Setzen der F_CPU wäre ich niemals alleine drauf 
gekommen.

Aber jetzt weiß ich wie sowas geht und werde es zukünftig immer so 
machen.
Vielen vielen Dank Frank.

Jetzt muss ich nur noch schauen wie man es macht, eine Taste mit zwei 
Signalen zu belegen.
Taste kurz drücken ist "Wert1"
Taste länger drücken ist "Wert2"

Gruß
Andreas

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Andreas schrieb:
> -> jetzt funktioniert es

Freut mich!

> im putty, das ich mit dem IRMP (läuft auch auf einem Mega 8 mit 8MHz)
> verbunden habe sehe ich nun die IRSND Signale.
> Sind die gleichen wie mit der richtigen Fernbedienung.

Sehr gut.

> Im IRMP hab ich das F_CPU setzen auch über den Source Code gesetzt.
> War scheinbar Zufall, dass es geklappt hat.

Ja, das solltest Du auch noch anpassen. Lohnt sich.

> Taste kurz drücken ist "Wert1"
> Taste länger drücken ist "Wert2"

Du könntest in der Timer-ISR einen Zähler (static uint16_t in der ISR) 
mitlaufen lassen, wenn Du eine Taste drückst. Überschreitet der Zähler 
einen magischen Wert, setze ein Flag (muss dann global als volatile 
definiert werden), dass die Taste länger gedrückt wurde. Beispiel: Wenn 
der Wert 7500 erreicht hat, weisst Du, dass eine halbe Sekunde vergangen 
ist.

Sobald Du die Taste loslässt, setzt Du den Zähler auf 0.

Das Flag wertest Du dann in der Hauptschleife aus. Nicht vergessen, 
dieses wieder zurückzusetzen!

Viel Spaß, Frank

von Andreas (Gast)


Lesenswert?

Hi Frank,

das mit dem Tastendruck hab ich nun auch geschafft.
Zwar anders, da das mit den Flags nicht hinbekommen, aber es 
funktioniert :-)

Mittlerweile auf einen Tiny4313 mit Taster auf Low, aktivierten internen 
Pullups sowie internen 8MHz zum Laufen gebracht.
Funktioniert sogar wie ich mir das vorgestellt habe :-)

Habe meine Fernbedienung auch soweit fertig.
Macht genau das was sie soll.

Jetzt wollte ich noch der Interesse halber Versuche mit dem Sleep Modus 
machen, da mein langfristiges Ziel eine 2032 Knopfzelle als 
Spannungsversorgung wäre.
Funktioniert auch seit 2 Tagen, aber die Batterie wird das denke nicht 
sonderlich lange mitmachen ohne leer zu werden.

Dachte an IDLE, da ich zum Aufwecken nur die Taster habe, die ein Low 
Signal an den Tiny senden.

Also wollte ich zum Anfang mal IDLE ausprobieren und die Unterschiede im 
Stromverbrauch messen.
Schaue seit Tagen die Beiträge an, die google so anzeigt.
Aber im Endeffekt kappier ich nicht wie und an welcher Position im Code 
ich IDLE aktiviere soll und was ich angeben muss, dass per Tastendruck 
das Ganze wieder aufwacht, Signal sendet und sich dann "zur Ruhe 
begibt".
Viele viele Seiten an Treffern und Beschreibungen, aber keine die ich 
verstehe und umsetzen kann.
(Meine selbst beigebrachten ProgrammierKenntnisse reichen eben nur fürs 
ganz Grobe)

wenns nicht wird, dann versuch ich mich vielleicht später mal mit dem 
Kombinieren von IRMP und IRSND als "Repeater" :-)

Gruß
Andreas

von S. Landolt (Gast)


Lesenswert?

idle bringt nicht allzu viel, warum nicht power-down? Der ATtiny4313 
hat auf allen Pins die PCINT-Fähigkeit.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Schau Dir mal den Source zu

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

an. Dort beträgt der Ruhestrom ca. 1µA. Damit hält die Batterie über 
viele Monate, wenn nicht Jahre.

: Bearbeitet durch Moderator
von Andreas (Gast)


Lesenswert?

Hi Frank,

danke für den Link.
Hab die letzten 3,5 Stunden damit verbracht den Code anzuschauen.
Da hier viel mit Zuordnungen und so gearbeitet wird und Ein und Ausgänge 
vorher mit einem Namen oder so definiert werden und viel mit Variablen 
gearbeitet wird ist es für mich sehr schwer zu verstehen was da 
eigentlich gemacht wird bzw. was ich davon vür mein Vorhaben "verwenden" 
kann.
Dafür langt leider mein Wissen bei weitem nicht :-(

Wenn es nicht z.B. so in der Art ausschaut bin ich total überfordert.
1
if ((!(PINB & (1<<PINB3))) && (Zustand == 1))

Habe mal alles so angepasst wie ich meine, dass es für mich passen 
sollte.
Was sogar beim Kompilieren "ohne Meldungen", aber in Sleep geht er (wie 
erwartet) natürlich nicht so einfach.

Mein Tiny benötigt ca. 2.3mA im Ruhezustand.
Also ist nix mit Einschlafen.
War aber fast klar, da ich hierfür die absolute Pfeife bin.

Aber trotzdem Frank für die Unterstützung.

Gruß
Andreas

von S. Landolt (Gast)


Lesenswert?

Ohne mich mit diesen Libraries befasst zu haben, hätte ich gesagt, dass 
das kein Hexenwerk sein kann: vor den PINx- bzw. PINxn-Abfragen die 
entsprechenden PCINT-Interrupts freigeben, dann den ATtiny4313 per 
sleep in den Power-down-mode versetzen und in der dazugehörigen ISR 
den Interrupt wieder sperren.

Wenn das aktuelle Programm (auch für einen Assemblerprogrammierer) 
halbwegs lesbar ist, würde ich gerne mal hineinschauen.

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

danke für die Antwort.
Anbei mal der Code.
Aber bitte nicht auslachen o.ä..
Bin schon froh das so hinbekommen zu haben.

Gruß
Andreas

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Andreas schrieb:
> Bin schon froh das so hinbekommen zu haben.

Ist doch schon mal ein Anfang. Noch ein Tipp: Du musst nicht bei jedem 
Kommando das Protokoll und die Adresse setzen, es reicht, das Kommando 
neu zu beschreiben. Also
1
irmp_data.protocol = IRMP_NEC_PROTOCOL;  //verwende NEC protocol
2
irmp_data.address  = 0xFF00;        // set address to 0xFF00 -> Code 1396
machst du einmal beim Start des Programms und musst das dann nicht immer 
wieder machen. Es wäre auch zu überlegen, ob du die Senderei nicht in 
ein kleines Unterprogramm tust, dann wirds noch übersichtlicher.

von S. Landolt (Gast)


Lesenswert?

> Aber bitte nicht auslachen o.ä..

Kann ich jetzt auch sagen, da muss noch optimiert werden, aber mal so 
auf die Schnelle:
1
ISR(PCINT0_vect)
2
{
3
PCMSK0 = 0;  // PCINT-Gruppe sperren
4
};
5
...
6
  for (;;)
7
  {
8
  GIMSK  = (1<<PCIE0);
9
  GIFR   = (1<<PCIF0);          // prellte da etwas?
10
  PCMSK0 = (1<<PCINT3);         // Taster auf PB3
11
  MCUCR  = (1<<SE)|(1<<SM0);    // power-down-mode
12
  sleep_mode();
13
...
14
  if (!(PINB & (1<<PINB3)))     // Wenn Taster PB3 low gedrückt
15
...

von S. Landolt (Gast)


Lesenswert?

PS:
Da könnte noch ein Problem dadurch bestehen, dass PCINT ja auf beide 
Flanken reagiert. Aber zumindest die grundsätzliche Idee, wie um 18:54 
geschrieben, sollte klar werden.

von Forist (Gast)


Lesenswert?

S. Landolt schrieb:
> ... wie um 18:54 geschrieben ...
Warum verlinkst du deinen Beitrag nicht einfach, damit man direkt 
hinspringen kann?
Beitrag "Re: IR Fernbedienung mit IRSND"

von S. Landolt (Gast)


Lesenswert?

Weil ich davon ausgehe, dass zumindest Andreas auf Anhieb weiß, worauf 
ich mich beziehe.

von Andreas (Gast)


Lesenswert?

Hallo zusammen,

danke für die Antworten.
Probiere seit gestern bissl rum.
Leider hat das so auch nicht funktioniert.

Habe jetzt aus Frust, da ich zum programmieren eindeutig zu blöd bin 
eine andere Lösung.
2x AA Batterie mit ca. 3000mAh Kapazität, die halten dann grob 
Überschlagen 2 Monate durch.
Oder ich bau einfach einen Ein/Aus Schalter dazu ;-)

Der Sleep Mode wäre zwar generell für mich interessant gewesen, da ich 
noch ein anderes Projekt habe, bei dem Sleep sicher nicht schaden würde.
(Schaltung mit Mega88A ist 24/7 an, macht aber im Endeffekt insg. nur 
paar Minuten im Jahr was "sinnvolles")

Gruß
Andreas

von S. Landolt (Gast)


Lesenswert?

> Leider hat das so auch nicht funktioniert.
Was genau hat nicht funktioniert, power-down im sleep oder die 
Tastenfunktion?
  Wenn Sie möchten, bin ich gerne bereit, das Problem mit Ihnen im 
Dialog anzugehen; dazu wäre (wieder) das aktuelle Programm nötig. Kann 
aber auch verstehen, wenn erstmal die Frustrationsschwelle erreicht ist.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Angehängte Dateien:

Lesenswert?

Ich hänge dir mal meinen Code für eine IR Fernbedienung mit Tiny2313 und 
16 Tasten an. Im Powerdown zieht sie etwa 0,4µA(!) und ist damit schon 
recht sparsam.
Die Includes für IRSND lasse ich mal weg, die sind ja klar.
Hier das Dings in voller Schönheit:
Beitrag "Re: Quick&dirty - schnelle Problemlösungen selbst gebaut"

Läuft übrigens seit 2017 ohne Nachladen der Zelle.

: Bearbeitet durch User
von Andreas (Gast)


Lesenswert?

Hallo zusammen,

hab heute seit Mittag pausenlos nur probiert und probiert.

Der Tiny schläft irgendwie. (glaub ich zumindest)
Gemessen hab ich 17.2µA beim nichts tun.
Allerdings funktionieren nur noch 2 Tasten.
Die beiden, bei denen ich eine 3Fach Belegung gemacht habe.
PB3 und PB4
Die anderen gehen nicht mehr. :-(
Obwohl ich diesen Bereich im Code nicht verändert hab.

Muss ich morgen mal schauen, für heute reichts mir.

Den "GIFR" erkennt mein Compiler nicht, dann mal vorsichtshalber eiskalt 
weggelassen ;-)

Irgendwie sind 17µA aberetwas seltsam.
Kann aber auch an meinem Multimeter liegen.
(MetraHit X-Tra; kalibriert 06/2020)
Ohne Chip hab ich 1µA gemessen ;-)


Einen Mega88A für mein anderes Projekt konnte ich auch einschläfern, 
wacht aber nicht mehr auf.
Am INT0 hängt ein IR Empfänger, der wird nun nicht mehr eingelesen :-(
Das IR Signal hätte ihn wecken sollen.
Am Mega88A hab ich "sleep" "geübt" ;-)


Gruß
Andreas

von S. Landolt (Gast)


Lesenswert?

> Den "GIFR" erkennt mein Compiler nicht

Äußerst merkwürdig - mit meinem ATtiny2313A klappt das, und dieser steht 
doch im selben Datenblatt wie der ATtiny4313 (auch wenn es von 09/11 
ist).

Ebenfalls merkwürdig sind die 17 uA, bei mir messe ich unter 0.5 uA, ist 
aber erstmal zweitrangig.

von S. Landolt (Gast)


Lesenswert?

PS:
Ich habe hier ein tn4313def.inc, darin steht '.equ GIFR = EIFR  ; For 
compatibility', aber im Datenblatt finde ich nichts von 'EIFR'.

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

So,
anbei noch der Code.

Das mit dem "Zusammenfassen" der IR Signale wie von Matthias 
vorgeschlagen hab ich noch nicht gemacht.

Taster an PB3 und PB4 funktionieren.
Senden die Befehle problemlos.
Nach dem Loslassen der Tasten wieder ca. 17µA

Bei allen anderen Tastern blinkt die IR LED nur einmal ganz kurz auf, 
das wars dann auch.
Signale werden dadurch keine brauchbaren gesendet.
Sollte aber bei denen genauso funktionieren wie bei PB3 und PB4 oder?
Das PCMSK ist dafür "konfiguriert".?

Gruß
Andras

von S. Landolt (Gast)


Lesenswert?

Eigentlich hätte ich gesagt, dass auch PB3 und PB4 nur einmal 
funktionieren, denn in der ISR wird PCMSK=0 gesetzt, das war's dann; das 
'PCMSK=(1<<PCINT0)|...' gehört unmittelbar vor 'sleep_mode()', oder eben 
gleich, wie von mir vorgeschlagen, das ganze 'sleep_mode_init()', auf 
die paar zusätzlichen Befehle kommt es erstmal ja nicht an.

Dass trotz Power-down-mode 17 uA fließen, wird wohl an der Schaltung 
liegen. Oder die Fuses stehen nicht auf Werkseinstellung, d.h. der BOD 
ist aktiv, die 17 uA würden gut zu 'Figure 23-63. Brownout Detector 
Current vs. VCC' im Datenblatt passen.

von Andreas (Gast)


Lesenswert?

so,
es gibt Neuigkeiten.

Habe bei den Tastern, bei denen es nicht funktioniert hat das if gegen 
while ersetzt.
Siehe da, jetzt wird schön gesendet :-)

Der BOD war auf 1.8V gestellt.
Wenn dieser deaktiviert ist hab ich ca 0,2µA gemsessen.

Nochmals vielen Dank an alle :-)
Habe hierbei viel gelernt.

Gruß
Andreas

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.