Lichtschranken die XXXte

Hallo Leute,

erstmal möchte ich sagen das ich ein kompletter Neuling hier bin.
Nun hat mich der Ehrgeiz gepackt ein Projekt umzusetzen und so bin ich schnell ein Arduino ( UNO SMD ) kaufen ge"laufen" noch keine Ahnung wie das Teil funktioniert oder ich es bediene dachte ich mir schlau wie ich bin kaufst dir gleich ein Einsteiger Lernpaket dazu. So Leute nun nach vielen herum Experimentieren bin ich nochmals Einkaufen gegangen und kaufte mir das Material was ich dachte zu benötigen für mein Experiment.

2 x IR LED Link IR LED
2 x IR Empfänger TSOP4838

So vor die IR LED noch schnell einen 100 Ohm Widerstand gehängt, TSOP angehängt.

#include <IRremote.h>

#define IR_PIN      3
#define DET_PIN  2
#define OK_PIN  13

IRsend irsend;

void setup()
{
  Serial.begin(9600);
  
  pinMode(DET_PIN, INPUT);
  pinMode(OK_PIN, OUTPUT);
  irsend.enableIROut(38);
  irsend.mark(0);
}

void loop() 
{
  Serial.print(digitalRead(DET_PIN));
  digitalWrite(OK_PIN, !digitalRead(DET_PIN));
}

Code zusammen geschnipselt, wenn ich das jetzt in Serial Monitor mir so ansehe kommt da andauernd ein “0” Signal rein unterbreche ich die Schranke nun kommt andauernd ein “1” Signal. Ist ja schon mal nicht schlecht. Wie Kann ich das auf eine 0 beschränken und nur bei Unterbrechung eine 1 zeigen !?

Nun meine Fragen:

Kann der Code noch Optimiert werden ?! Braucht der TSOP kein Widerstand um die mA runterzuschrauben ?! Nun möchte ich noch ein Lichtschranken dazu hängen & die Zeit messen ? Ist mein Ansatz von millis() richtig ?! oder mach ich hier kompletten sch**** ?! Ich hoffe ihr könnt mir helfen …

Ein Anfänger freut sich auf eure Antworten…

100 Ohm sind zuwenig. Der Arduino braucht mindestens einen 150 Ohm oder zwei 100 Ohm in Reihe.

Wie Kann ich das auf eine 0 beschränken und nur bei Unterbrechung eine 1 zeigen !?

Du speicherst in einer Variablen, daß Du eine 0 empfangen hast und resetierst die Variable sobald eine 1 kommt.

Besserungsvorschlag die 38kHz mit einem Timer machen, dann brauchst Du die IR Bibiothek nicht

#define RXTSOP 2      //Pin output TSOP 
#define TXIR 11        //or pin 3 LED IR
#define LED13 13      //LED on pin 13


//flag
boolean transmitting_IR; //transmission flag

// turn_off , turn_on, detect functions come as is from
// http://www.eng.utah.edu/~cs1410/Labs/lab09.html
void turn_off_IR ()
{
  // Instead of just adjusting the output on pin 11, this code also
  // turns off the timer controlling the PWM output on pin 11
  
  TCCR2A = 0; // Disconnect PWM
  TCCR2B = 0; // Stops the timer
  OCR2A = 0;  // No timer top
  digitalWrite(TXIR, LOW);  // Ensure output is off
  
  transmitting_IR = false;
}

void turn_on_IR ()
{
  //   Set up Timer2 (which can be connected to pins 3 and 11)
  //   For full details, see:
  //   arduino.cc/en/Tutorial/SecretsOfArduinoPWM
  //   The syntax here has me baffled, but the patterns of usage
  //   are clear if you look at the ATMega328 diagrams.
  //   _BV appears to stand for 'bit value'
  //   Different bits need to be set to control each timer
  //   Refer to diagrams for clarity

  TCCR2A = _BV(WGM21) | _BV(COM2A0); // This mode toggles output once per timer cycle
  TCCR2B = _BV(CS20);  // Do not scale the clock down - use 16 MHz timer rate.
  OCR2A = 210; // Divide sys. clock by 210, 1/2 cycle = 76 khz, 1 cycle = 38 khz
  
  // Output pin 11 should now be emitting a 38 khz signal.
  
  transmitting_IR = true;
}


void detectIR()
{
    if(digitalRead(RXTSOP)){
    digitalWrite(LED13 ,LOW);
    }else{
    digitalWrite(LED13 ,HIGH);
    }
}


void setup(){  
  pinMode(TXIR, OUTPUT);
  pinMode(RXTSOP, INPUT);
  turn_on_IR();
  delay(100);
}

void loop(){
  detectIR(); // search for IR
  delay(50);  
}

Grüße Uwe

Halle Uwe erstmal danke habe soeben die IR Bibliothek entfernt und den Widerstand getauscht und deinen Code ausprobiert die LED (Onboard) bleibt mir nun konstant auf HIGH und beobachte ich im Seriellen Monitor “RXTSOP” sendet er nun dauerhaft eine 1 und unterbreche ich den Lichtschranken haut er mit kurz eine 0 rein und sendet dann weiter eine 1 jetzt komm ich gar nicht mehr mit ^^

marvv90:
Code ausprobiert die LED (Onboard) bleibt mir nun konstant auf HIGH und beobachte ich im Seriellen Monitor "RXTSOP"

Vorsicht, Du hast für Deine Lichtschrankenanwendung möglicherweise ein Hardwareproblem, ohne es zu bemerken. Diese TSOP-Empfänger sind im wesentlichen für Burstmode-Betrieb gemacht und NICHT für Lichtschrankenanwendungen:

Wenn ein "Burst" von 10 bis 100 IR-38kHz Impulsen empfangen wird, schaltet der Empfänger seinen Ausgang HIGH, ansonsten LOW (oder umgekehrt) und ansonsten hat er den entgegengesetzten Status. Die sind zum Empfang von kurzen Impulsfolgen aus IR-Fernbedienungen gemacht.

Und für IR-38kHz "Dauerstrich als Lichtschrankenanwendung" sind die Empfänger nicht gemacht und zeigen auf Dauer folgenden Fehler:

  • nach einigen (z.B. 10) Sekunden IR-Dauerimpulsen schaltet der Empfänger einmal kurz auf "Empfang unterbrochen" und liefert am Ausgang kurz den Ausgangswert für "kein IR-Burst" bevor er kurz darauf wieder das richtige Ausgangssignal liefert.

Mit einem delay(50) in der loop würde sich eine scheinbare Unterbrechung von 0,0002s locker in den 50ms verstecken können, ohne dass Du es bemerkst.

Für Lichtschrankenanwendungen besser TSOP Module verwenden, die auch "continous mode" zusätzlich zum "burst mode" unterstützen. Sonst bekommst Du möglicherweise alle 10s eine Phantom-Unterbrechung, wo keine da ist, insbesondere in delay-freiem Code und wenn Du hohe Anforderungen an die zeitliche Auflösung hast, wäre das ärgerlich, wenn die Lichtschranke nach spätestens 10s von alleine eine Unterbrechung anzeigt, wo nichts unterbrochen wurde.

Bei diesem Modul sehe ich im Datenblatt, dass auch "continous mode" unterstützt wird:

Bei Deinem Modul würde ich lieber nochmal ausgibig testen, ob es wirklich auch bei Dauerstrich ausreichend funktioniert, wobei es auch auf die Messzeit ankommt: Wenn Du sowieso nur extrem kurze Zeitmessungen unter 1s machen möchtest, würde ein burst mode TSOP sicher auch reichen. Und kurze Fehlimpulse kann man natürlich auch per Software ausfiltern.

Man kann auch ein 38KHz Signal einfach mit tone() generieren.
Wahrscheinlich ist es auch besser wenn der TSOP ein Interrupt generiert anstatt es dauerend im Loop() zu testen.
Der Code unten toleriert auch ein kurz Unterbruch um ein Fehlalarm zu vermeiden. Ich habe schon etwas ähnliches in Einsatz (Briefkasten Monitor)

volatile unsigned long lastPulseMs ;

setup() {
  . . .
  attachInterrupt(0, IRdetectISR, CHANGE);    // Interupt 0; detect changes on digitalPin 2 (TSOP)
  . . .
}

void IRdetectISR() {
  // here if interupt 0 generated by TSOP IR receiver state change
  lastPulseMs = millis() ;  // we have got a pulse. Record the time.
}

void loop() {

   if (millis % 50  == 0 ) {
       tone(IR_PIN, 38000  ) ;  // 1ms burst @ 38'000 Hz (=38 cycles) to LED on pin IR_PIN every 50 mS
    }
    else 
       notone( IR_PIN ) ;  //  stop burst
    }

    if ( millis() - lastPulseMs > 200 ) {
       // no pulse detected for 200 ms.
       // beam broken. 
       Serial.print("Alarm");
     }
  . . .
  . . .

}

Sry das ich bis jetzt nicht geantwortet habe , bin nicht dazu gekommen... habe mir das alles durchgelesen herum probiert und habe nun eine "passende Lösung" am Freitag teste ich das Projekt richtig & danach hau ich alles hier rein .... Danke erstmal euch allen ! Aber trotzdem habe ich noch ein paar Fragen für die Zukunft:

Ich würde gerne 10 Lichtschranken betreiben mit einem Arduino Board ein LCD Display & 6 Taster wobei die nur an einen Pin gehängt werden ( die Taster ) & das ganze würde ich dann gerne per "USB" weitergeben an ein "Rasperry 3" und dort grafisch aufwerten... Ist dies möglich & wenn mit welchen Board ?!

Ich würde mich sehr freuen wenn ihr mir hier noch helfen könntet !!

Es würde auch nicht stören wenn es 2 Board´s sein müssen die ich verbinden kann miteinander !!

Wie willst Du verhindern, daß die vielen Lichtquellen nicht mehrere Sensoren beeinflussen? IR Empfänger decken einen relativ weiten Winkel ab, und empfangen Reflexionen aus allen Richtungen. Deshalb wäre es evtl. besser, nacheinander einen Burst auf jede Sendediode auszugeben, und den zugehörigen Empfänger abzufragen.

Das denke ich ist ganz einfach ?! LS1 <-> LS2 haben einen Abstand von 0.5 Meter wobei die Empfänger in einer Nut drinnen sind ! LS3 - LS4 haben einen seitlichen Abstand zu LS1 - LS2 von ca. 20cm ! Und so weiter ! IR Sender und Empfänger sind ca. 15 cm auseinander. Im Notfall sollten die LED wirklich so strahlen bekommen Sie von mir ein Rohr in das Sie gesteckt werden um es zu bündeln ?!

Die Empfindlichkeit eines TSOPs ist nicht unterschätzen. Die sind auch von extern Lichtquellen (zB Neonröhre) betroffen und brauchen eine gewisse Anpassungszeit. Aber du hast dass anscheinend im Griff.

Für möglichst wenig Arduino Pins zu benutzen, du kannst folgendes probieren die ich auch in meinem oben erwähnten "Briefkasten Monitor" eingesetzt habe:

  1. Der 'Round Robin' Ansatz als von DrDietrich beschrieben zu verwenden.
  2. Alle TSOPs auf dem gleichen Arduino [Interrupt] Pin , je mit einem Diode zB 1N4148 getrennt so die nicht gegen einander 'kämpfen'. Da nur ein Sendediode zu einer bestimmten Zeit aktiv ist, du weisst welche IR Strahl unterbrochen ist.
  3. Ein Demux chip (zB CD74HC4051E ) welche bis 8 Sendediode steuern kann (braucht Arduino 3 Pins)