Go Down

Topic: IR-Signal 4x empfangen obwohl Taste nur 1x betätigt (Read 1 time) previous topic - next topic

arduino-wasser

Jan 15, 2018, 05:55 pm Last Edit: Jan 15, 2018, 06:55 pm by arduino-wasser
Hallo,
ich weiß nicht wie ich es genau schildern soll. Ich habe einen IR1261 an einem Nano angeschlossen. Signal empfange ich korrekt jedoch stets 4x in Folge nun bin ich mir nicht sicher ob meine Fernbedienung ein soooo langes Signal sendet, oder ob es an etwas anderem liegt.

Ich würde das ganze gerne elegant ohne delays im Code lösen. Da werden noch ein paar Interrupts dazukommen wegen Phasenschnitt also würd ich am liebsten von Anbeginn an die delays umschiffen.

Es ist bei mir nur zulässig eine Taste zu drücken und dadurch 1x Impuls auszulösen. Auch bei extrem schneller Betätigung sollen so "prellende" Tastenfehlbedienungen (Nutzerfehler) ausgeschlossen werden.

Danke schonmal :D

Hiermal die Ausgabe ausm SerialMonitor, wie Ihr seht immer in 4er Häppchen.
Code: [Select]
Start IR Decoding
Ergebniss:0
HEX: F32F72D7
DEC: 4079973079
Taste 0
Ergebniss:1
HEX: F32F72D7
DEC: 4079973079
Taste 0
Ergebniss:2
HEX: F32F72D7
DEC: 4079973079
Taste 0
Ergebniss:3
HEX: F32F72D7
DEC: 4079973079
Taste 0
Ergebniss:4
HEX: C9767F76
DEC: 3379986294
Taste 1
Ergebniss:5
HEX: C9767F76
DEC: 3379986294
Taste 1
Ergebniss:6
HEX: C9767F76
DEC: 3379986294
Taste 1
Ergebniss:7
HEX: C9767F76
DEC: 3379986294
Taste 1
Ergebniss:8
HEX: 55F2B93
DEC: 90123155
Taste 8
Ergebniss:9
HEX: 55F2B93
DEC: 90123155
Taste 8
Ergebniss:10
HEX: 55F2B93
DEC: 90123155
Taste 8
Ergebniss:11
HEX: 55F2B93
DEC: 90123155
Taste 8



Code: [Select]
/* IR-Reciever: IR1261 358kHz;
 * Fernbedienung 38kHz NEC DirecTV H-24
 *
 * CHANGELOG:
 *
 * 14.01.18: Wertetabelle für Tastencodes eingebunden
 * 0-9; Prg+; Prg-; Pfl hoch,runter,links,rechts; OK;
 *
 *
*/

#include <IRremote.h>

//Pin-Port zuweisungen;
int RECV_PIN = 7; //Pin D7 als DataPort

#define LED LED_BUILTIN
#define Relais1 1
#define Relais2 2
#define Relais3 3
#define Relais4 4

//IR-CODE;
#define Taste0       4079973079
#define Taste1       3379986294
#define Taste2       3356842673
#define Taste3       3063508398
#define Taste4       2526734404
#define Taste5       1253026919
#define Taste6       2620035948
#define Taste7       2201932595
#define Taste8       90123155
#define Taste9       3732451536

#define TastePrgUP   374608567
#define TastePrgDOWN 1477816464

#define PfeilUP      4064352766
#define PfeilDOWN    3028878891
#define PfeilLEFT    3308754100
#define PfeilRIGHT   197779206
#define PfeilOK      1974032039

#define rot          3274898107
#define gruen        2349545635
#define gelb         630309136
#define blau         1349183883

//IRremote.h
IRrecv irrecv(RECV_PIN);
decode_results results;

//Variablen;
int counterKeysRecieved = 0;
unsigned long keyRecieved = 0;

//Initialisierung;
void setup()
{
  pinMode(LED, OUTPUT);
 
  Serial.begin(9600);
  Serial.println("Start IR Decoding");
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.print("Ergebniss:");
    Serial.println(counterKeysRecieved);
    Serial.print("HEX: ");
    Serial.println(results.value, HEX);
    Serial.print("DEC: ");
    Serial.println(results.value, DEC);
    keyRecieved = results.value;
    counterKeysRecieved++;
    digitalWrite(LED, HIGH);

    //Werte werden im DEC Format verwaltet
    switch (keyRecieved) {
      case Taste0:
        Serial.println("Taste 0");
        break;
      case Taste1:
        Serial.println("Taste 1");
        break;
      case Taste2:
        Serial.println("Taste 2");
        break;
      case Taste3:
        Serial.println("Taste 3");
        break;
      case Taste4:
        Serial.println("Taste 4");
        break;
      case Taste5:
        Serial.println("Taste 5");
        break;
      case Taste6:
        Serial.println("Taste 6");
        break;
      case Taste7:
        Serial.println("Taste 7");
        break;
      case Taste8:
        Serial.println("Taste 8");
        break;
      case Taste9:
        Serial.println("Taste 9");
        break;
      default:
        Serial.println("Tastencode nicht bekannt");
    }
   
    // Receive the next value
    irrecv.resume();
    keyRecieved = 0;
  }
digitalWrite(LED, LOW);

 
}

HotSystems

#1
Jan 15, 2018, 06:13 pm Last Edit: Jan 15, 2018, 06:27 pm by HotSystems
Dein Beitrag, seriell-Anzeige  und der Sketch sind schwer zu lesen.

Bitte ändere die "Quote-Tags in Code-Tags um.

Dann wird auch alles besser lesbar und auch auf mobilen Geräten wird dein Beitrag lesbar.

Zu deiner Frage:
Ich bin sicher, die FB sendet den Code öfter aus.
Du kannst das doch eigentlich durch vergleichen beim Empfang unterdrücken.
Bzw. je nachdem was du damit steuern möchtest auch nur einmal darauf reagieren.

Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

agmue

... nun bin ich mir nicht sicher ob meine Fernbedienung ein soooo langes Signal sendet, ...
Der verwendeten Programmbibliothek IRremote liegt ein Testprogramm bei, mit dem Du das testen kannst.

Wenn tatsächlich der selbe Code viermal geschickt wird, solltest Du die Zeit von einem zum nächsten Code mitprotokollieren. Wenn diese Zeit plus etwas Sicherheit bei x Millisekunden liegt, dann kannst Du den gleichen Code nach x Millisekunden ignorieren.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

arduino-wasser

Der verwendeten Programmbibliothek IRremote liegt ein Testprogramm bei, mit dem Du das testen kannst.

Wenn tatsächlich der selbe Code viermal geschickt wird, solltest Du die Zeit von einem zum nächsten Code mitprotokollieren. Wenn diese Zeit plus etwas Sicherheit bei x Millisekunden liegt, dann kannst Du den gleichen Code nach x Millisekunden ignorieren.

Also mein oben gepostetes Programm ist im Grunde das Testprogramm nur bereits mit den Codes der Fernbedienung.

Leider weiß ich nicht genau was du mit Zeit mitprotokollieren meinst. Hast du damit im Sinn das ich mir bei jedem empfangenen Protokoll-Signal die millis() mit dazu speichere. Wie kann ich dann den Empfangenen Code direkt zum Zeitwert verküpfen?
Oder will ich das ganze viel zu umständlih machen?

agmue

Hast du damit im Sinn das ich mir bei jedem empfangenen Protokoll-Signal die millis() mit dazu speichere.
Wenn ein IR-Code empfangen wurde, in einer Variablen die Zeit (millis) merken. Wenn der nächste Code kommt, dann die Zeitdifferenz zur aktuellen Zeit bilden. Ist die Zeit kleiner einem Grenzwert, ist es eine Codewiederholung, sonst wurde die selbe Taste zweimal gedrückt.

Inzwischen habe ich eine IR-Tastatur gefunden, die den Code solange wiederholt, wie die Taste gedrückt ist. Die gemessene Zeit beträgt 112 ms, weshalb ich die Schwelle auf 130 ms festgelegt habe. Mein Testsketch sieht dann so aus:

Code: [Select]
#include <IRremote.h>
int recvPin = 11;
IRrecv irrecv(recvPin);
const uint16_t TASTE1 = 0xC11, TASTE2 = 0xC10; // Codes an die Tastatur anpassen!
const uint32_t SCHWELLE = 130;
uint32_t aktMillis, codeMillis;

void  setup ( )
{
  Serial.begin(9600);   // Status message will be sent to PC at 9600 baud
  irrecv.enableIRIn();  // Start the receiver
  Serial.println("Programmanfang");
  Serial.print("USECPERTICK: ");
  Serial.println(USECPERTICK, DEC);
}

void  loop ( )
{
  aktMillis = millis();
  decode_results  results;        // Somewhere to store the results

  if (irrecv.decode(&results)) {  // Grab an IR code
    Serial.print("Code      : ");
    Serial.print(results.value, HEX);
    Serial.print('\t');
    Serial.print(aktMillis - codeMillis);
    Serial.println();
    if (aktMillis - codeMillis > SCHWELLE)
    {
      switch (results.value)
      {
        case TASTE1:
          Serial.println("Taste 1");
          break;
        case TASTE2:
          Serial.println("Taste 2");
          break;
      }
    }
    codeMillis = aktMillis;
    irrecv.resume();              // Prepare for the next value
  }
}
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

michael_x

Manche IR-Fernbedienungen wiederholen regelmäßig solange eine Taste gedrückt ist, aber wechseln den Code, wenn dieselbe Taste zweimal gedrückt wurde.

So kann man z.B. kontinuierliche Lautstärke-Änderungen von mehrziffrigen Kanal-Auswahlen unterscheiden, ohne sich groß um das Timing kümmern zu müssen.
- Solange der gleiche Code kommt, ist es ein langer Tastendruck.
- Ein anderer Code kennzeichnet einen neuen Tastendruck (auch wenn es dieselbe Taste nochmal ist)

( Macht meine Panasonic-Fernseher-FB jedenfalls so. )

dony

Hallo,

Ich habe mich mit so einem ähnlichen Sketch (Kommt ja aus dem Beispiel) eine Zeit lang gespielt. Meine LG Fernbedienung hat den Code 1mal gesendet und dann nur noch 0xFFFFFFF, ich glaub bei Samsung wars das selbe.

Wie bereits beschrieben kannst du das mit einer Zeitabfrage umgehen.

lg dony
Grüße, Donny

arduino-wasser

Manche IR-Fernbedienungen wiederholen regelmäßig solange eine Taste gedrückt ist, aber wechseln den Code, wenn dieselbe Taste zweimal gedrückt wurde.

So kann man z.B. kontinuierliche Lautstärke-Änderungen von mehrziffrigen Kanal-Auswahlen unterscheiden, ohne sich groß um das Timing kümmern zu müssen.
genau da hackte es bei mir im Verständniss, habe das nun erledigt das Problem.

Danke an alle, nun funktioniert es. Habe nun den Vergleich zum vorherigen Signal + eine Zeitverzögerung eingebaut. Klappt eigentlich sehr gut.

Danke an alle

Tommy56

Nach allgemein anerkannten Regeln für Foren solltest Du nun den funktionierenden Code hier veröffentlichen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

agmue

Nach allgemein anerkannten Regeln für Foren solltest Du nun den funktionierenden Code hier veröffentlichen.
Dem stimme ich ausdrücklich zu, denn ein Forum sollte ein Geben und Nehmen sein :)
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

arduino-wasser

ist bis jetzt nur der Code der IR-Fernbedienung für die Schaltausgänge. Morgen oder so implementiere ich noch die "Taste gehalten" Funktion für eine stufenlose Regelung (von evtl. PWM Ausgängen).

Aus dem switch-case werde ich dann mittels Funktionsaufruf herausspringen und die enstprechende Fernbedienungsreaktion ausführen.

Code: [Select]
/* IR-Reciever: IR1261 38kHz;
 * Fernbedienung 38kHz NEC DirecTV H-24
 *
 * CHANGELOG:
 *
 * 16.01.18: Funktionierendes Prell-Delay, alle Tasten werden erkannt;
 * 14.01.18: Wertetabelle für Tastencodes eingebunde;
*/

#include <IRremote.h>

//Pin-Port zuweisungen;
int RECV_PIN = 7; //Pin D7 als DataPort

#define LED LED_BUILTIN
//Pin-Array der Schaltausgänge
byte Schaltausgang[] = {};

//IR-CODE in DEC/HEX;
#define Taste0            4079973079   //F32F72D7
#define Taste1            3379986294   //C9767F76
#define Taste2            3356842673   //C8155AB1
#define Taste3            3063508398   //B6996DAE
#define Taste4            2526734404   //969AE844
#define Taste5            1253026919   //4AAFAC67
#define Taste6            2620035948   //9C2A936C
#define Taste7            2201932595   //833ED333
#define Taste8            90123155     //55F2B93
#define Taste9            3732451536   //DE78B0D0 

#define TastePrgUP        374608567    //165412B7
#define TastePrgDOWN      1477816464   //5815B090
#define TastePfeilUP      4064352766   //F24119FE
#define TastePfeilDOWN    3028878891   //B489062B
#define TastePfeilLEFT    3308754100   //C53794B4 
#define TastePfeilRIGHT   197779206    //BC9DF06
#define TastePfeilOK      1974032039   //75A956A7   
#define TasteROT          3274898107   //C332FABB
#define TasteGRUEN        2349545635   //8C0B38A3
#define TasteGELB         630309136    //2591C110
#define TasteBLAU         1349183883   //506AE98B


//IRremote.h
IRrecv irrecv(RECV_PIN);
decode_results results;

//Variablen Global;
int counterKeysReceived;
unsigned long lastResult;
unsigned long codeMillis;
unsigned long diffMillis;
unsigned long lastcodeMillis;
int delayPressKey = 200;

//Initialisierung;
void setup()
{
  pinMode(LED, OUTPUT);
 
  Serial.begin(9600);
  Serial.println("Start IR Decoding");
  irrecv.enableIRIn(); // Start the Receiver
  //Relay INIT;
  for (byte n = 0; n < sizeof(Schaltausgang); n++)
  {
    pinMode(Schaltausgang[n], OUTPUT);
  }
 
}

void relayAction(byte uebergabewert)
{
 
}

void loop()
{
//Variablen loop;
unsigned long keyReceived;

  //Aufrufen der IR Library, wenn Signal empfangen; 
  if (irrecv.decode(&results))
  {
    codeMillis = millis();
    if (lastcodeMillis < codeMillis)
    {
      diffMillis = codeMillis - lastcodeMillis; 
    }       
    keyReceived = results.value;
    counterKeysReceived++;

    //Actuator Reaction;         
    if ((keyReceived != lastResult) || (diffMillis >= delayPressKey))
    {           
      /*Serial Monitor
      Serial.print("Ergebniss: "); Serial.print(counterKeysReceived); Serial.print("\t");
      Serial.print("HEX: "); Serial.print(keyReceived, HEX); Serial.print("\t");
      Serial.print("Timecode: "); Serial.print(codeMillis); Serial.print("ms"); Serial.print("\t");   
      Serial.print("Intervall: "); Serial.print(diffMillis); Serial.print("ms"); Serial.print("\t");   
      */
      //Flash LED if Signal received;
      digitalWrite(LED, HIGH);
      //im DEC Format Taste benannt +++ Actuator Reaction;
      switch (keyReceived)
      {
        case Taste0:
          Serial.print("Taste 0"); Serial.print("\t");
          break;
        case Taste1:
          Serial.print("Taste 1"); Serial.print("\t");
          break;
        case Taste2:
          Serial.print("Taste 2"); Serial.print("\t");
          break;
        case Taste3:
          Serial.print("Taste 3"); Serial.print("\t");
          break;
        case Taste4:
          Serial.print("Taste 4"); Serial.print("\t");
          break;
        case Taste5:
          Serial.print("Taste 5"); Serial.print("\t");
          break;
        case Taste6:
          Serial.print("Taste 6"); Serial.print("\t");
          break;
        case Taste7:
          Serial.print("Taste 7"); Serial.print("\t");
          break;
        case Taste8:
          Serial.print("Taste 8"); Serial.print("\t");
          break;
        case Taste9:
          Serial.print("Taste 9"); Serial.print("\t");
          break;

        case TastePrgUP:
          Serial.print("Taste PrgUP"); Serial.print("\t");
          break;
        case TastePrgDOWN:
          Serial.print("Taste PrgDOWN"); Serial.print("\t");
          break;
        case TastePfeilUP:
          Serial.print("Taste PfeilUP"); Serial.print("\t");
          break;
        case TastePfeilDOWN:
          Serial.print("Taste PfeilDOWM"); Serial.print("\t");
          break;
        case TastePfeilLEFT:
          Serial.print("Taste PfeilLEFT"); Serial.print("\t");
          break;
        case TastePfeilRIGHT:
          Serial.print("Taste PfeilRIGHT"); Serial.print("\t");
          break;
        case TastePfeilOK:
          Serial.print("Taste PfeilOK"); Serial.print("\t");
          break;
        case TasteROT:
          Serial.print("Taste ROT"); Serial.print("\t");
          break;
        case TasteGRUEN:
          Serial.print("Taste GRUEN"); Serial.print("\t");
          break;
        case TasteGELB:
          Serial.print("Taste GELB"); Serial.print("\t");
          break;
         case TasteBLAU:
          Serial.print("Taste BLAU"); Serial.print("\t");
          break;               
        default:
          Serial.print("Code n.B."); Serial.print("\t");         
      }
      Serial.println();
      lastResult = keyReceived;
     }
     else
     {
      /*Serial Monitor     
      Serial.print("Ergebniss: "); Serial.print(counterKeysReceived); Serial.print("\t");
      Serial.print("Timecode: "); Serial.print(codeMillis); Serial.print("ms"); Serial.print("\t"); 
      Serial.print("Intervall: "); Serial.print(diffMillis); Serial.print("ms"); Serial.print("\t");
      */
      Serial.print("repeated"); Serial.print("\t");
      Serial.println();
     }       
    // end of recieving-loop => receive the next value
    lastcodeMillis = codeMillis;
    irrecv.resume();
 
  }
//LED wieder ausmachen so das flash-Effekt bei Signalempfang entsteht;
digitalWrite(LED, LOW);

//ab hier weiter "normalen loop Code;


}
//ende loop; 

agmue

Allgemein zum Hintergrund: Bei einem öffentlichen, von Freiwilligen getragenen Forum sollte es selbstverständlich sein, daß derjenige, der nimmt, auch die Bereitschaft zeigt, zu geben. Nur so kann es funktionieren.

Da Thommys Bitte in einem anderen Thema pampig beantwortet wurde, habe ich ihn hier ausdrücklich unterstützt.

@arduino-wasser: Danke :)
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

arduino-wasser

Ach so ok, sollte keinenfalls von mir geheimgehalten werden, oder arrogant oder so klingen :D ich wollte halt "eigentlich" noch warten bis ich heute Abend zuhause den Aufruf der Relais Routinen fertig habe und den zum Dimmen der PWM Kanäle. Aber das kann ich ja dann immer noch posten.

Mal drei dämliche Fragen:
1. was genau liefert mir der Wert "USECPERTICK" zurück, es schein eine sich nicht ändernde konstante zu sein. Ist auch in diversen der Beispiel-Code's zu finden. Es scheint irgendwas mit der Umlaufzeit eines "Signalempfanges" zu tun zu haben -ala use clocks per tick-

2. kann man das switch-case irgendwie eleganter lösen? Ich weiß nicht die Verschachtelung gefällt mir irgendwie noch nicht so richtig. Hat da jemand schonmal was gemacht, denn eigentlich alle Beispiele die ich bis dato fand in den Bibliotheken nutzen zur "Fallunterscheidung" switch-case.

3. ich laufe des öfteren mal in das Problem, nicht genau zu wissen was ich alles für Funktionen/Klassen/Befehle ich in einer Bibliothek aufrufen kann. Also eine Art Befehlsauflistung mit deren Parameterliste, sowas ähnlich der ArduinoReference. Hab ich da irgendwas bis dato übersehen, oder muss man sich dass Häppchenweise aus den Beispielen herausarbeiten?

agmue

DU hast es richtig gemacht, ich wollte nur Thommy unterstützen. Wenn Du so willst ein Nacbeben aus einem anderen Thema. Poste wann immer Du möchtest und es für sinnvoll erachtest :)

Zu 2: Alternativ kannst Du die Tastencodes in ein Feld tun und dann über den Index eine Aktion auslösen. Ob es dadurch eleganter wird, wäre zu probieren.

Zu 3: Das hängt von der Bobliothek und seinem Programmierer ab. Ich schaue zuerst in die *.h Datei, dort sind meist die Methoden und Parameter zu erkennen, manchmal auch mit Beschreibung. Der nächste Blick geht in die *.cpp Datei, manchmal ist die Beschreibung auch dort zu finden. AccelStepper beispielsweise hat eine eigene HTML-Datei mit Beschreibung.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

arduino-wasser

Nun mal der Code im aktuellen Stand, es funktionieren mitlerweile alle Sachen die ich vorerst für meine "intelligente Steckerleiste" und für meine Wohnzimmerbeleuchtung (LED-Streifen) brauche.

Eventuell werde ich noch eine Triac Ansteuerung implementieren um 230V Lampen/LSR zu dimmen.
Also PhasenAn/Abschnittsdimmung mit Jumperwahlstellung.

Da die Codelänge mittlerweile 450 Zeilen sind und somit zum direkt posten zu groß wurde (>9000Zeichen) hänge ich mal mein .ino File an.

Go Up