PIEZO sprengt IR-Empfang

Hey Leute,

ich stehe vor einem Problem, das ich mir einfach nicht erklären kann. Ich baue seit ein paar Monaten an einem Lasertag-System und habe nun ein paar Aim-Module entwickelt.

Die Dinger haben zwei Modi: Test und Training. Ersterer blinkt nur kurz bei Beschuss. Zweiterer schießt in zufällig Intervallen IR zurück, warnt vorher mit einem Ton. Und der Ton ist mein Problem. Der Zusammenhang will nicht in meinen Kopf.

Im Test-Modus funzt alles. Im Training-Modus kann das Modul aber nicht mehr abgeschossen werden, weil er zufällig wirkende Daten empfängt. Derselbe IR-Sequenz (z.B. Fernbedienung Ausschalten) hat jedes Mal ein anderes Ergebnis. Im Test-Modus aber nicht. Da ist es immer dasselbe Ergebnis bei selbem Fernbedienungsknopf. Gleiches Spiel bei den LaserTaggern.

Nun habe ich herausgefunden, dass wenn ich die Zeilen

   tone(PIN_PIEZO, 1000);   
   delay(10);  
   noTone(PIN_PIEZO);

lösche, alles IR wieder richtige gelesen werden. Der Piezo an sich funktioniert übrigens wie gewünscht, nur macht er die IR-Lesung kaputt.

Ein zurückschalten in den Test-Modus hilft nicht - der geht dann auch nicht mehr. Nur Reset des Arduinos hilft.

  • getestet wurden mehrere Geräte.
  • Piezo wurde getauscht, an andere Pins gehängt etc.

Da ich denke, dass es ein Programmierfehler ist, habe ich jetzt noch keinen Schaltplan angefertigt, weil das viel Arbeit macht, denn ich bin Hobbybastler. Vielleicht erkennt ihr auch so einen Denkfehler.



#include <IRremote.h>
#include <Arduino.h>
#include <Wire.h>

#define PIN_RED1 2
#define PIN_RED2 3
#define PIN_GREEN 4

#define PIN_RESET 5
#define PIN_TRAINING 7

#define PIN_PIEZO A0

#define PIN_RECEIVER 10
#define PIN_IRFEEDBACK 9
#define PIN_SENDER 12

#define PIN_GND1 6
#define PIN_GND2 8
#define PIN_GND3 11

int statusHit = 0;
int nametag = 13;

IRsend irsend(PIN_SENDER);
IRrecv irrecv(PIN_RECEIVER);
decode_results results;

unsigned long previousMillis = 0;
long interval = 3000;
bool renew = false;

void setup () {
  
  Serial.begin(9600);
  Serial.println("START");
  irrecv.enableIRIn();
  irsend.enableIROut(38);
  pinMode(PIN_RED1, OUTPUT);
  pinMode(PIN_RED2, OUTPUT);  
  pinMode(PIN_GREEN , OUTPUT); 
   
  pinMode(PIN_SENDER, OUTPUT);
  pinMode(PIN_IRFEEDBACK, OUTPUT);
  pinMode(PIN_RECEIVER, INPUT);
  
  pinMode(PIN_TRAINING, INPUT_PULLUP);
  pinMode(PIN_RESET, INPUT_PULLUP);

  pinMode(PIN_PIEZO, OUTPUT);

  pinMode(PIN_GND1, OUTPUT);
  pinMode(PIN_GND2, OUTPUT);
  pinMode(PIN_GND3, OUTPUT);

  digitalWrite(PIN_GND1, LOW);
  digitalWrite(PIN_GND2, LOW);
  digitalWrite(PIN_GND3, LOW);

  randomSeed(analogRead(1));

   
}


void loop () {

  if(renew == true)
  {
    interval = random(1000,10000);  // Abstand zwischen Schüssen von 1 bis 7 Sek.
    renew = false;
    Serial.print ("NEW SHOT IN MS: ");
    Serial.println (interval);
  }


 if(digitalRead(PIN_TRAINING) == LOW && statusHit == 0)     // TRAINING-MODE ON
 {
  digitalWrite(PIN_RED1,HIGH); 
  digitalWrite(PIN_RED2,HIGH); 
  digitalWrite(PIN_GREEN,LOW);

  unsigned long currentMillis = millis(); 
  if (currentMillis - previousMillis >= interval) { 
   previousMillis = currentMillis; 
   
   tone(PIN_PIEZO, 1000);   
   delay(10);  
   noTone(PIN_PIEZO);

   
   
   digitalWrite(PIN_RED1,LOW);
   digitalWrite(PIN_RED2,LOW);
   delay(50); 
   digitalWrite(PIN_RED1,HIGH);
   digitalWrite(PIN_RED2,HIGH);
   
   renew = true;

   irsend.sendSony(nametag, 32);
  }
 } 
 else if(digitalRead(PIN_TRAINING) == HIGH)     // TEST-MODE ON
 {
  statusHit = 0;
  digitalWrite(PIN_RED1,LOW);
  digitalWrite(PIN_RED2,LOW);
  digitalWrite(PIN_GREEN,HIGH);
 }

 if (irrecv.decode(&results) && results.value > 0 && results.value != 13 && results.value < 50 && digitalRead(PIN_TRAINING) == HIGH)
 {
    Serial.print ("HIT BY DEVICE No. ");
    Serial.println (results.value);
    digitalWrite(PIN_GREEN, LOW);

    for(int i=0; i<5; i++)
    {
      digitalWrite(PIN_RED1, HIGH);
      digitalWrite(PIN_RED2, HIGH);
      delay(100);
      digitalWrite(PIN_RED1, LOW);
      digitalWrite(PIN_RED2, LOW);
      delay(100);
    }
    digitalWrite(PIN_GREEN, HIGH);
 }

 if (irrecv.decode(&results) && results.value > 0 && results.value != 13 && results.value < 50 && digitalRead(PIN_TRAINING) == LOW)
 {
    Serial.print ("HIT BY DEVICE No. ");
    Serial.println (results.value);
    digitalWrite(PIN_RED1, LOW);
    digitalWrite(PIN_RED2, LOW);
    digitalWrite(PIN_GREEN, HIGH);
    statusHit = 1;
 } 

 if (digitalRead(PIN_TRAINING) == LOW && digitalRead(PIN_RESET) == LOW)
 {
    Serial.println ("REACTIVATED" );
    digitalWrite(PIN_RED1, HIGH);
    digitalWrite(PIN_RED2, HIGH);
    digitalWrite(PIN_GREEN, LOW);
    statusHit = 0;
 }


 Serial.println (results.value);
 irrecv.resume();
 delay(10);
}

Ich tippe darauf, dass für den Piezo der selbe Timer verwendet wird, wie ber der IRremote-Library.
Setze testweise eine Led mit passendem Code ein und prüfe ob es geht. Dann kannst du einen aktiven Piezo verwenden.
Bei dem aktuellen Sketch brauchst du die Library wire.h nicht.

Deine Vermutung ist korrekt. Beide benutzen timer2
Bei IRremote kann für den ATmega328P auch auf den Timer 1 gewechselt werden.
Dazu muss die Datei IRTimer.hpp der IRremote Bibliothek angepasst werden.

// ATmega328 and ATmega88
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__)
#  if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2)
//#define IR_USE_AVR_TIMER1   // send pin = pin 9
#define IR_USE_AVR_TIMER2     // send pin = pin 3
#  endif
1 Like

Deine IRremote-Library ist veraltet, beim Kompilieren gibst doch sehr viele Warnungen versuch mit der IRremonte 3.9.0
Der Sketch muss danach ein wenig umgebaut werden, die neue Lib arbeitet beschien anders nimm nicht IRremote.h nur IRremote.hpp

Uff, da sind sie wieder: die Grenzen meines Verständnisses :smiley:

Okay, ich muss einen anderen Timer verwenden. Kann ich das umgehen, wenn ich auf die neue IR-Library wechsele? Ansonsten möchte ich ungern von dem alten System (das tatsächlich Warnungen auswirft aber dennoch sauber funktioniert) wechseln.

Wenn das so nicht funktioniert, wie kann ich denn in dieser von dir genannten Datei etwas ändern. Ich binde die ja nur oben ein und bekomme die sonst nicht zu Gesicht.

Sie liegt auf deiner Platte!
Die ausführlichen Meldungen sagen dir sogar wo.

1 Like

Gefunden! Es hat geklappt. Ich danke euch!!!

Mach folgendes kopiere die IR Lib in dein Sketch Ordner. und dort bearbeite die
IRTimer.hpp so wie @Kai-R schreibt, öffnen kannst du mit jedem Editor sogar mit den vom Windows, jedoch aufpassen das die Endung ist hpp nicht TXT

OK war zu langsam :slight_smile:

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.