Go Down

Topic: Lichtschranke mit Widerständen zeitverzögern (Read 1 time) previous topic - next topic

Bloqq

Feb 14, 2017, 09:08 pm Last Edit: Feb 14, 2017, 09:14 pm by Bloqq
Hallo zusammen,

ich bräuchte Hilfe bei einem Projekt das ich gerade verfolge und hoffe, dass mir hier geholfen werden kann.


Folgendes ist die Ausgangssituation:

Ich habe mir eine Lichtschranke gebastelt, mit einer Fotodiode die mit einem Spannungsteiler gemessen wird, einem Lasermodul, einer Kontroll LED und dem Arduino.
Über den Sketch löse ich eine angeschlossene Kamera bisher für 2 Sekunden aus, sobald der gemessene Wert der Lichtschranke unter einen bestimmten Wert fällt, wenn sie unterbrochen wird.
Die Kontroll LED leuchtet, sobald ich mit dem Laser die Fotodiode "treffe" einfach um anzuzeigen, dass ein Signal da ist.


Da ich nun gerne die Auslösungezeit der Kamera variieren möchte, ohne immer wieder den Delay im Sketch zu ändern, dachte ich mir, dass ich das über eine Widerstandmessung umsetzen könnte.

Dazu habe ich mit einen Stellschalter mit 6 Positionen besorgt. An diesen wollte ich jetzt je nach Stellung unterschiedliche Widerstände anschliessen und diese auslesen lassen.

Bei Stellung 1, Widerstandswert=XXXOhm, resultiert in der Auslösezeit 1s
Bei Stellung 2, Widerstandswert=XXXOhm, resultiert in der Auslösezeit 1,5s
.
.
.


Ich stehe nun vor dem Problem der realisierung der Schaltung sowie der einbettung der Funktion in den vorhandenen Sketch.

Soweit wie ich bisher gekommen bin, sollte man dazu einen bekannten Widerstand in die GND Leitung und den unbekannten Widerstand in die + Leitung zu legen.
Diesen, dem Arduino unbekannten Wert errechnen lassen und in einer anderen Delay Zeit ausgeben zu lassen.

Ich würde mich sehr über einen Kontakt freuen, der mir bei der bestehenden Problematik behilflich sein kann.
Im Anhang ist der aktuelle Sketch zu finden.


Beste Grüsse
Alex


Code: [Select]


int sensorPin=A0;
int sensorValue=0;
int ledPin=13;
int ledPin2=12;

void setup ()
{
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  sensorValue=analogRead(sensorPin);
 Serial.println(sensorValue);


  if (sensorValue<500) {
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin2, HIGH);
    delay(400);
    
    
  }
  else{
  
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin2, LOW);
   delay(2000);
  }

}


ardubu

wenn du genügend Pin's auf dem Arduino frei hast, lege die 6 Schalterpositionen auf 6 digitale Eingänge und den gemeinsamen des Schalters auf GND. Dann nutzt du die 6 Eingänge mit dem internen Pullup und fragst die Eingänge ab.

HotSystems

Ich verstehe nicht, warum du es mit Widerständen machen willst.
Das wird sicher nicht funktionieren.
Eine Verzögerung solltest du besser im Sketch programmieren.
Verwende dazu millis(), auf keinen Fall delay().
Gruß Dieter

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

sschultewolter

Mit der Widerstandsmessung wird das eher nichts. Die Kennlinie dürfte sich zu sprungartig ändern. Wie bereits von HotSystem geschrieben, ist das Problem nicht die externe Verschaltung, sondern der Sketch, welcher entsprechend eine Verzögerung dann haben muss. Tutorial BlinkWithoutDelay
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

Kickboxer

Hallo,

die überall angebotenen "Keypad shields" benutzen genau diese Klappmatik. Sie lesen die unterschiedlichen Schalter mit einem Analog-Eingang ein. Je nach analogem Eingangswert zeigt es die unterschiedlichen Tastendrücke an. Hier der Code dazu:

Code: [Select]
//Sample using LiquidCrystal library
#include <LiquidCrystal.h>

/*******************************************************

This program will test the LCD panel and the buttons
Mark Bramwell, July 2010

********************************************************/

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor
 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 // For V1.1 us this threshold
 if (adc_key_in < 50)   return btnRIGHT; 
 if (adc_key_in < 250)  return btnUP;
 if (adc_key_in < 450)  return btnDOWN;
 if (adc_key_in < 650)  return btnLEFT;
 if (adc_key_in < 850)  return btnSELECT; 

 // For V1.0 comment the other threshold and use the one below:
/*
 if (adc_key_in < 50)   return btnRIGHT; 
 if (adc_key_in < 195)  return btnUP;
 if (adc_key_in < 380)  return btnDOWN;
 if (adc_key_in < 555)  return btnLEFT;
 if (adc_key_in < 790)  return btnSELECT;   
*/


 return btnNONE;  // when all others fail, return this...
}

void setup()
{
 lcd.begin(16, 2);              // start the library
 lcd.setCursor(0,0);
 lcd.print("Push the buttons"); // print a simple message
}
 
void loop()
{
 lcd.setCursor(9,1);            // move cursor to second line "1" and 9 spaces over
 lcd.print(millis()/1000);      // display seconds elapsed since power-up


 lcd.setCursor(0,1);            // move to the begining of the second line
 lcd_key = read_LCD_buttons();  // read the buttons

 switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnRIGHT:
     {
     lcd.print("RIGHT ");
     break;
     }
   case btnLEFT:
     {
     lcd.print("LEFT   ");
     break;
     }
   case btnUP:
     {
     lcd.print("UP    ");
     break;
     }
   case btnDOWN:
     {
     lcd.print("DOWN  ");
     break;
     }
   case btnSELECT:
     {
     lcd.print("SELECT");
     break;
     }
     case btnNONE:
     {
     lcd.print("NONE  ");
     break;
     }
 }

}


Jetzt musst Du nur die Werte anpassen :-)

Viele Grüße

Jörg
Deutsches Forum zum ESP8266:

WWW.ESP-FORUM.DE

Kickboxer

#5
Feb 15, 2017, 08:09 am Last Edit: Feb 15, 2017, 08:19 am by Kickboxer
...
Verwende dazu millis(), auf keinen Fall delay().

Wie "sschultewolter" schrieb:"Tutorial BlinkWithoutDelay"
-> !!!!! ;-) :-)


Ansonsten kann man auch Hardware-entprellen falls wirklich notwendig...
Deutsches Forum zum ESP8266:

WWW.ESP-FORUM.DE

guntherb

#6
Feb 15, 2017, 10:28 am Last Edit: Feb 15, 2017, 10:33 am by guntherb
Dazu habe ich mit einen Stellschalter mit 6 Positionen besorgt. An diesen wollte ich jetzt je nach Stellung unterschiedliche Widerstände anschliessen und diese auslesen lassen.
zwei Varianten:
a) analog:
 Eine Kette aus 5 gleichen Widerständen von 5V auf GND, die Spannungknoten werden über den Schalter ausgewählt und analog eingelesen.
Code: [Select]
int ad = analogRead(A0);
  int Stufe;
  if      (ad < 102)  Stufe = 0;
  else if (ad < 307)  Stufe = 1;
  else if (ad < 512)  Stufe = 2;
  else if (ad < 716)  Stufe = 3;
  else if (ad < 921)  Stufe = 4;
  else                Stufe = 5;


b) digital:
mit Stufenschalter jeweils einen digitalen Pin  (pinMode(Dx, INPUT_PULLUP);) auf GND schalten.




Und für die Verzögerung: Blink Without Delayoder die Nachtwächtererklärung
Grüße
Gunther

Tommy56

#7
Feb 15, 2017, 12:09 pm Last Edit: Feb 15, 2017, 12:10 pm by Tommy56
[OT]@guntherb: Kannst Du mir sagen, womit Du diese Schaltungen malst?

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

Bloqq

Hallo zusammen,

vielen Dank schonmal für die zahlreichen Antworten!

Ich verstehe nicht, warum du es mit Widerständen machen willst.
Das wird sicher nicht funktionieren.
Eine Verzögerung solltest du besser im Sketch programmieren.
Verwende dazu millis(), auf keinen Fall delay().

Auf Widerstände habe ich mich bisher noch nicht festgelegt, aber ausgewählt einfach deshalb, weil ich es nicht besser weiss.
Bei der Realisierung bin ich flexibel, aber mangels Kenntnissen weiss ich leider nicht was es für (bessere) Alternativen gibt.

Hättest du einen anderen Vorschlag, wie ich diese Auswahl/Prüfung realisieren könnte?


Vielen Dank für den Hinweis mit der millis() Funktion, diese kannte ich bisher noch nicht.
Dazu werde ich mich erst noch einlesen müssen.


--

Hallo,

die überall angebotenen "Keypad shields" benutzen genau diese Klappmatik. Sie lesen die unterschiedlichen Schalter mit einem Analog-Eingang ein. Je nach analogem Eingangswert zeigt es die unterschiedlichen Tastendrücke an.

Jetzt musst Du nur die Werte anpassen :-)

Viele Grüße

Jörg
Danke für die Anregung. Leider weiss ich bisher noch nicht, was ich mit deiner Information anfangen kann.
Kann ich über dieses Keypad Shield in einer Art Menü meine Zeit, die ich meinen Auslöser vom Arduino betätigen lassen will jeweils individuell einstellen?
Zusätzlich hätte ich das große Problem, dass das programmieren einer solchen Menüführung meine Fähigkeiten leider weit übersteigt.


--


So wie guntherb die Analoge Messung beschreibt, war ja anfangs meine Idee auch, bis oben der hinweis kam, dass das so nicht funktionieren würde.

Welche andere Lösung wäre denn denkbar?
Am liebsten wäre natürlich möglichst wenig material und eine Anfängerfreundliche Programmierung. :)



Freundliche Grüsse

Alex

guntherb

Das ist jetzt einfach in einem Zeichenprogramm gemalt. Ist ja keine Schaltung, eher eine Skizze.
Sonst Eagle, Fritzing oder LTSpice.
Grüße
Gunther

guntherb

#10
Feb 15, 2017, 03:55 pm Last Edit: Feb 15, 2017, 03:57 pm by guntherb
So wie guntherb die Analoge Messung beschreibt, war ja anfangs meine Idee auch, bis oben der hinweis kam, dass das so nicht funktionieren würde.
Keine Sorge. Das funktioniert.

Ich denke die Aussage von HotSystem war eher ein Missverständnis. Ich glaube, er dachte, du würdest mit den Widerständen direkt die Verzögerung erwirken wollen.
Grüße
Gunther

Theseus

Damit du ein erstes Erfolgserlebnis hast, kannst du auch mit variablen Delays arbeiten. Delay hat den Nachteil, dass der Controller während der Pause blockiert ist. Du kannst mit Delay z.B. sehr schlecht programmieren, dass die Lichtschranke 2s. länger, als sie ausgelöst wurde, aktiv bleibt, da der Controller sobald er in der Delay steckt für die Lichtschranke blind ist. Erst wenn er zwei 2s. vertrödelt hat, schaut er wieder nach der Lichtschranke. Auch die Abfrage einer zweiten Lichtschranke funktioniert so nicht richtig.

Kuchenbackerklärung zu millis und delay: https://forum.arduino.cc/index.php?topic=400102.msg2752141#msg2752141

Wenn du dir der Beschränkungen von delay bewusst bist, kannst du es benutzen.

Bloqq

Keine Sorge. Das funktioniert.

Ich versuche gerade den von dir oben angefügten Code zu verstehen, dabei stellt sich mir aber allgemein noch die Frage ob ich das eher Digital auslesen lassen soll oder doch beim Analog bleiben.

Wäre digital nicht etwas einfacher im Sketch umzusetzen, würde jedoch mehr Pins auf dem Board belegen?
Analog wäre komplizierter zu programmieren, würde aber weniger Pins auf dem Board belegen?

HotSystems

Ich denke die Aussage von HotSystem war eher ein Missverständnis. Ich glaube, er dachte, du würdest mit den Widerständen direkt die Verzögerung erwirken wollen.
Das stimmt.
So habe ich das verstanden. Das bezog sich nur auf die Widerstände.
Daher auch der Hinweis, es mit millis() zu machen.
Gruß Dieter

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

Bloqq

#14
Feb 16, 2017, 04:57 pm Last Edit: Feb 16, 2017, 05:02 pm by Bloqq
Hallo zusammen,

ich habe mich vorhin weiter mit dem Thema beschäftigen können und meinen Schalter nach der Analogschaltung von gunterb gebastelt. 5 Widerstände mit 1K Ohm an auf je einen Knotenpunkt.

Mit dem Code aus dem Ohmmeter von http://www.elektronik-labor.de/Arduino/Ohmmeter.html habe ich mir nun für die verschiedenen Schalterstellungen einen Ohmwert ausgeben lassen.

Bei Schalterstellung 0 beträgt der Widerstand 0Ohm, Schalterstellung 1 3990 Ohm, Schalterstellung 2 1495 Ohm etc...

Leider fehlen mir weiterhin die Programmierkenntnisse, um dem Arduino zu sagen, dass bei Stufe 1 mit 0Ohm, Widerstand die Lichtschranke, wenn unterbrochen, für 1 Sek auslöst.

- Bei Stufe 1 mit 3990 Ohm Widerstand für 1,5 Sek auslöst

- Bei Stufe 2 mit 1495 Ohm Widerstand für 2 Sek auslöst

Etc.


Kann mir dabei jemand behilflich sein oder hat dazu vielleicht einen guten Artikel parat, wie ich das am besten mit welchen Programmierfunktionen umsetzen kann?


Beste Grüsse

Alex

Go Up