Impulszähler

http://sites.schaltungen.at/arduino-uno-r4/impulszaehler

http://www.linksammlung.info/

http://www.schaltungen.at/

                                                                                              Wels, am 2019-05-10

BITTE nützen Sie doch rechts OBEN das Suchfeld  [                                                              ] [ Diese Site durchsuchen]

DIN A3 oder DIN A4 quer ausdrucken
*******************************************************************************I**
DIN A4  ausdrucken   (Heftrand 15mm / 5mm)     siehe     http://sites.schaltungen.at/drucker/sites-prenninger
********************************************************I*
~015_b_PrennIng-a_arduino.uno.r4-impulszaehler (xx Seiten)_1a.pdf

Untergeordnete Seiten (4):



       ACHTUNG: Sketche könnten fehlerhaft sein ! ! !


vellemann  VMA209
MULTI-FUNCTION SHIELD EXPANSION BOARD FOR ARDUINO

https://www.velleman.eu/downloads/29/vma209_a4v01.pdf



ARDUINO UNO R3 Starter-Kit
https://www.arduino-tutorial.de/arduino-starter-kit-kaufberater/





Sensorabfrage mit Interrupt an tastePin = 2 (oder tastePin = 3)  - Seite 886 (BUCH: Die elektronische Welt mit Arduino entdecken)

                                                                                   Arduino Pin Map






Stückzähler mit dem KY-032 Modul zur Hinderniserkennung

Stückzähler mit dem KY-010

Infrarot Lichtschranke Modul  TCRT5000 IR
Infrarot Lichtschranke E18-D80NK
Reflexion Lichtschranke Modul  TCRT5000 IR
IR Hindernisserkennung Modul TCRT5000
Infrarot IR Line Tracker Reflexlichtschranke
TCRT5000 Infrarot Line Tracker


http://sensorkit.joy-it.net/index.php?title=KY-032_Hindernis_Detektor_Modul
https://www.az-delivery.de/products/hindernis-sensor-modul?ls=de&cache=false
https://www.youtube.com/watch?v=8QBLD4yW7uw
http://cool-web.de/arduino/multi-function-shield-einrichtung.htm
http://cool-online.de/arduino/multi-function-shield-mit-modul-ky-032-stueckzaehler-hindernis-erkennung.htm
http://cool-web.de/arduino/





Einfacher Impulszähler mit ARDUINO UNO

Simple Pulse Counter mit Arduino UNO R3 Board

Einfache Schaltung, die Impulse zählt und über den seriellen Monitor meldet.

Diese Schaltung zählt Impulse, die in pin-12 eingespeist werden.
In dieser Schaltung werden die Impulse durch einen Druckknopf erzeugt.
Der Arduino prüft den Zustand von pin-12 jede Millisekunde.
Wenn pin-12 HIGH geht, zählt der Arduino ihn als Impuls.
Die Anzahl der erkannten Impulse wird auf dem seriellen Monitor angezeigt.
Wenn pin-12 HIGH gehalten wird, zählt der Arduino ihn als Einzelimpuls.

Folgenden Code / Sketch verwenden

/* Simple Pulse Counter

Counts digital pulses fed into pin 12. For reliability, the minimum pulse width is 1 millisecond.
If the signal is held high, the arduino will count it as one pulse.

*/

const int input = 12; // This is where the input is fed.
int pulse = 0; // Variable for saving pulses count.
int var = 0;

void setup(){
  pinMode(input, INPUT);
 
  Serial.begin(9600);
  Serial.println(F("No pulses yet...")); // Message to send initially (no pulses detected yet).
}

void loop(){ 
  if(digitalRead(input) > var)
  {
    var = 1;
    pulse++;
   
    Serial.print(pulse);
    Serial.print(F(" pulse"));

    // Put an "s" if the amount of pulses is greater than 1.
    if(pulse > 1) {Serial.print(F("s"));}
   
    Serial.println(F(" detected."));
  }
 
  if(digitalRead(input) == 0) {var = 0;}
 
  delay(1); // Delay for stability.
}



Aber wenn ich Skizze hochlade und auf den seriellen Monitor klicke, sehe ich, dass der Start der automatischen Impulszählung fortgesetzt wird (ich drücke nicht auf den Schalter), und die automatische Impulszählung läuft automatisch weiter.
Ich kann nicht verstehen, wo das Problem im Code liegt. Bitte finden Sie eine Lösung und sagen Sie mir
Was ist mit Pin 12 verbunden?
Wie ist der Eingang verdrahtet?
Haben Sie einen Pulldown-Widerstand?
Ich bin ein Kabelplan. Siehe Abbildung
Und ich benutze 1k Widerstand
Diese taktilen Tasten haben geschaltete und nicht geschaltete Verbindungen.
Verbinden Sie das Arduino mit den diagonal gegenüberliegenden Ecken der Schaltfläche und nicht entlang einer Kante, wie Ihr Diagramm zeigt.
Sie werden garantiert die Schaltbeine hochheben.


Hallo, danke für deine Hilfe, jetzt funktioniert es perfekt. Ich danke dir sehr.

Quelle:
https://forum.arduino.cc/index.php?topic=541116.0



Arduino Code – Simple Counter

/* Simple Counter
* ——————
*
* This is a simple counter that takes a digital input
*
*/
int ledPin = 13; // choose the pin for the LED
int switchPin =2; // choose the input pin (for a pushbutton)
int val = 0; // variable for reading the pin status
int counter = 0;
int currentState = 0;
int previousState = 0;

void setup() {
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(switchPin, INPUT); // declare pushbutton as input
Serial.begin(9600);
}

void loop(){
val = digitalRead(switchPin); // read input value
if (val == HIGH) { // check if the input is HIGH (button released)
digitalWrite(ledPin, HIGH); // turn LED on
currentState = 1;
}
else {
digitalWrite(ledPin, LOW); // turn LED off
currentState = 0;
}
if(currentState != previousState){
if(currentState == 1){
counter = counter + 1;
Serial.println(counter);
}
}
previousState = currentState;
delay(250);
}



Quelle:
http://www.toddholoubek.com/classes/pcomp/?page_id=58





Impulse lesen und zählen mit Arduino

In diesem Teil des Codes erklären wir, dass er die Signale des Sensors mittels eines Interrupts zählt, ausführt und als RISING konfiguriert hat.
Er zählt also die Impulse vom Digitalsignal Null zum Digitalsignal Eins:

Sketch
int pin = 2; volatile unsigned int pulse; constintpulses_per_litre = 450;  void setup() { Serial.begin(9600);  pinMode(pin, INPUT); attachInterrupt(0, count_pulse, RISING); }  void loop() { pulse=0; interrupts(); delay(1000); noInterrupts();  Serial.print("Pulses per second: "); Serial.println(pulse); }  voidcount_pulse() { pulse++; } 

Pulse per second: 20
Pulse per second: 22
Pulse per second: 14
Pulse per second: 19


Quelle:
https://subscription.packtpub.com/book/web_development/9781785888564/3/ch03lvl1sec27/reading-and-counting-pulses-with-arduino





Interrupt-basierter Impulszähler
Beispiel einer Arduino-Skizze für die interruptbasierte Impulszählung


//Number of pulses, used to measure energy.long pulseCount = 0;//Used to measure power.unsigned long pulseTime,lastTime;//power and energydouble power, elapsedkWh;//Number of pulses per wh - found or set on the meter.int ppwh = 1; //1000 pulses/kwh = 1 pulse per whvoid setup(){    Serial.begin(115200);    // KWH interrupt attached to IRQ 1 = pin3    attachInterrupt(1, onPulse, FALLING);}void loop(){}// The interrupt routinevoid onPulse(){    //used to measure time between pulses.    lastTime = pulseTime;    pulseTime = micros();    //pulseCounter    pulseCount++;    //Calculate power    power = (3600000000.0 / (pulseTime - lastTime))/ppwh;    //Find kwh elapsed    elapsedkWh = (1.0*pulseCount/(ppwh*1000)); //multiply by 1000 to convert pulses per wh to kwh    //Print the values.    Serial.print(power,4);    Serial.print(" ");    Serial.println(elapsedkWh,3);}

Bereich von 0 bis 25 kW (typischer Bereich für Halbleiterzähler):
1000 Impulse pro kWh



Quelle:
https://learn.openenergymonitor.org/electricity-monitoring/pulse-counting/interrupt-based-pulse-counter





Impulse lesen und zählen mit Arduino

In diesem Teil des Codes erklären wir, dass er die Signale des Sensors mittels eines Interrupts zählt, ausführt und als RISING konfiguriert hat.
Er zählt also die Impulse vom Digitalsignal Null zum Digitalsignal Eins:


int pin = 2; volatile unsigned int pulse; constintpulses_per_litre = 450;  void setup() { Serial.begin(9600);  pinMode(pin, INPUT); attachInterrupt(0, count_pulse, RISING); }  void loop() { pulse=0; interrupts(); delay(1000); noInterrupts();  Serial.print("Pulses per second: "); Serial.println(pulse); }  voidcount_pulse() { pulse++; } 
Öffnen Sie den Arduino Serial Monitor und blasen Sie mit dem Mund Luft durch den Wasserflusssensor.
Die Anzahl der Impulse pro Sekunde wird auf dem Arduino Serial ... gedruckt.


Quelle:
https://www.oreilly.com/library/view/internet-of-things/9781785888564/ch03s02.html





Arduino UNO pulse counter


/*
Arduino UNO reads rising edge trigger pulses on pin 2 and displays counter on Sparkfun SerLCD LCD-10097 Photo of setup:
http://ompldr.org/vZGNlbA/photo.JPG Pariksheet
Mar 2012
*/


#define LCD_REFRESH_INTERVAL_MS 100
                                                                   /* Pin assignments */
#define INTERRUPT_INPUT 2

int pulse_counter = 0;


void setup()
{
        Serial.begin(9600);
        clear_LCD();

                                              // For noise suppression, enable pullup on interrupt pin

       digitalWrite(INTERRUPT_INPUT, HIGH);
      attachInterrupt(INTERRUPT_INPUT - 2,
                            interrupt_handler,
                           RISING);
}


void loop()
                      // Keep LCD blank till a pulse comes in
    if (pulse_counter > 0)
    {
     clear_LCD();
     Serial.println(pulse_counter);
     delay(LCD_REFRESH_INTERVAL_MS);
    }
}


void clear_LCD()
{
Serial.write(0xFE);
Serial.write(0x01);
}

void interrupt_handler()
{
pulse_counter = pulse_counter + 1;
}







After void loop() is there a "{" missing
void loop()
{
// Keep LCD blank till a pulse comes in
if (pulse_counter > 0)
{
clear_LCD();
Serial.println(pulse_counter);
delay(LCD_REFRESH_INTERVAL_MS);
}
}



Quelle:
https://gist.github.com/omsai/2363047





Zählimpulse mit Interrupt
volatile int IRQcount;int pin = 2;int pin_irq = 0; //IRQ that matches to pin 2void setup() {  // put your setup code here, to run once:  Serial.begin (9600);  attachInterrupt(pin_irq, IRQcounter, RISING);}void IRQcounter() {  IRQcount++;}void loop() {  // put your main code here, to run repeatedly:  cli();//disable interrupts  IRQcount = 0;  sei();//enable interrupts  delay(25);  cli();//disable interrupts  int result = IRQcount;  sei();//enable interrupts  Serial.print(F("Counted = "));  Serial.println(result);}



Quelle:
https://arduino.stackexchange.com/questions/4451/counting-pulses-with-interrupt





Stückzähler

Dieser besteht aus einem Arduino Uno, einer IR Einweglichtschranke und einem 20x4 Display (wahrscheinlich kommt dann noch eine 7-Segment Anzeige zur besseren, größeren Darstellung dazu).

Es sollen zwei Variablen hochgezählt werden. Eine, die die totale Produktionsmenge hochzählt und nicht zurückgesetzt werden kann. Und ein Zähler der in der Produktion hilft, alle 500 Stück den Zähler mit Hilfe eines Tasters zurückzusetzen.

Das Programm steht soweit, jedoch hänge ich an einem kleinen Problem bei der Anzeige auf dem Display. Wenn der Zähler auf eine 2-oder 3-stellige Zahl angestiegen ist und ich ihn dann zurücksetze, wird nur die erste Ziffer auf 0 gesetzt (aus 46 wird 06). Wenn dann das Zählen weiter geht, überschreibt er die 6 erst, wenn wieder eine 2-stellige Zahl erreicht wird.

Könnt ihr euch mein Programm ansehen und mir einen entsprechenden Tipp geben, wie ich dieses Problem beseitigen kann? Habe in der Liquid Crystal Bibliothek leider keinen passenden Befehl gefunden, mit welchem ich die Zellen "mit nichts überschreiben" kann.

***********Arduino Stückzähler*******************************************************

#include <LiquidCrystal.h>

const int  DetectorPin = 8;
const int  ResetButton = 10;

int Counter = 0;   // counter number of cookies temporarily
int CounterTotal = 0; // counter number of cookies total

int DetectorState = 1;         // current state of the Detector
int lastDetectorState = 1;     // previous state of the Detector
int ResetState = 0;            // state of the Reset Button

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // initialize the library with the numbers of the interface pins

void setup() {
  pinMode(DetectorPin, INPUT);
  pinMode(ResetButton, INPUT);
 
  lcd.begin(20, 4);
  lcd.print("Anzahl Gesamt:      Anzahl Momentan: ");
}

void loop() {
  lcd.setCursor(15, 0);
  lcd.print(CounterTotal);

  lcd.setCursor(17, 2);
  lcd.print(Counter);

  DetectorState = digitalRead(DetectorPin);
  ResetState = digitalRead(ResetButton);

  // compare the buttonState to its previous state
  if (DetectorState != lastDetectorState) {
    // if the state has changed, increment the counter
    if (DetectorState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      Counter++;
      CounterTotal++;
    }
  }
 
 lastDetectorState = DetectorState;

 if (ResetState == HIGH) {
  Counter = 0;
  lcd.setCursor(14, 1);
 }
 
delay(50);
}


Du must nicht nur den Counter auf Null setzen, sondern auch die Anzeige der jeweiligen Stellen im Display löschen.
Ok, das habe ich schon versucht aber dann schreibt er drei Nullen, sobald ich die Stellen im Display lösche. Welchen Befehl muss ich verwenden, dass er eine Null schreibt?
Ich löse das Problem, indem ich ein clear() sende und danach alle Texte neu übermittel.
Edit: Achja, man kann natürlich auch ein space an die Stelle schreiben, man muss dann den Cursor passend positionieren mit setCursor().


Rechtsbündige Ausgabe mit führenden Leerzeichen:
  lcd.setCursor(17, 0);
if (CounterTotal < 100) lcd.print(" ");
if (CounterTotal < 10) lcd.print(" ");
lcd.print(CounterTotal);

lcd.setCursor(17, 2);
if (Counter < 100) lcd.print(" ");
if (Counter < 10) lcd.print(" ");
lcd.print(Counter);

Ok, Super. Vielen Dank für die schnelle Hilfe.
Da stand ich wohl etwas auf dem Schlauch...

Wenn der "Gesamtzähler" vllt. über Tage / Wochen alles hochzählt, müsste ja auch irgend eine Sicherung (EEPROM?) für den Fall eines Stromausfalles berücksichtigt werden. (Ist je nach Relevanz auch für den 500er Zähler zu berücksichtigen)
Oder liege ich jetzt voll daneben?
In dem Fall wäre eine DS1307 als Speicher (nicht als Uhr) vorzuziehen. Sie bietet 56Byte gepufferten RAM. Dort kann man jeweils die Zahl der Kekse hineinschreiben. Das EEprom ist nur für 100.000 Schreibzyklen gedacht, was bei den Keksen, die in großen Stückzahlen durchlaufen, schnell erreicht wäre. Das Ram der 1307 kennt so eine Grenze nicht.
Danke für eure Ergänzung. Sollte das nachträglich noch benötigt werden, werde ich es so machen.

Jedoch wird nur die Produktionsmenge des Tages benötigt. Nach dem "Ausschalten" des Systems wird die Menge nicht mehr benötigt.
Ich könnte mir eher vorstellen, dass die Momentanen Zahlen über WLAN an den Hauptrechner gesendet werden

https://forum.arduino.cc/index.php?topic=435135.0



Personenzähler
Ein einfacher Personenzähler, der die Personen zählt, die an der Treppe vorbeikommen.


https://www.youtube.com/watch?v=1TZgSL8-uXg



Stückzähler mit dem KY-032 Modul zur Hinderniserkennung

http://cool-web.de/arduino/multi-function-shield-mit-modul-ky-032-stueckzaehler-hindernis-erkennung.htm



Infrarot Lichtschranke mit Arduino zum Auslesen des Stromzählers

https://www.kompf.de/tech/emeir.html




Ein Frequenzzähler für niedrige Frequenzen mit dem Arduino Uno und der Periodendauer Messung

Über die Messung der Pulslängen HIGH und LOW kann aus einem Rechtecksignal, oder einem ähnlichen Signal, die Frequenz bestimmt werden.
Der Arduino bietet hierzu die Funktion pulseIn(pin, signal) an. Die funktioniert an jedem Digital Pin und misst, wenn man die HIGH und die LOW Zeit addiert die Periodendauer T in Mikrosekunden.

Die Grenzwertbetrachtung

Bei einer Periodendauer von 100 Mikrosekunden entspricht +- 1 Mikrosekunde Fehler 1%, sodass bis ca. 10 kHz gemessen werden kann mit einem Fehler <1%.

Die Periodendauer T wird als unsigned long angegeben und kann somit bis maximal 4.294.967.295 zählen. Das entspricht 230 Mikroherz und somit ist der Millihertz Bereich voll erfasst und 3 Kommastllen sind bei niedrigen Frequenzen möglich.

Der Messbereich beträgt also 1 Millihertz bis 10 kHz.


void loop() {  time=micros();  do {    T = pulseIn(pin, HIGH) + pulseIn(pin, LOW);    if (T==0) {      Serial.println("Timeout.");    }    else {      f=1/(double)T;        // f=1/T         k++;        }      fsum+=f*1e6;  } while( micros() < (time+1e6)); // 1 Sekunde mitteln  f = fsum/k*0.9925;         // Korrekturwert einrechnen  Serial.println(f);  fsum=0.0;  k=0;}


Im Programm wird über 1 Sekunde (1e6 Mikrosekunden) gemittelt, deshalb sind nur Frequenzen bis runter zu ca. 3 Hz messbar.

Für niedrigerer Frequenzen muss entsprechend länger gemittelt werden, zum Beispiel 10, 100 oder 1000 Sekunden um 3 Millihertz erfassen zu können.

Fazit

Mit dieser einfachen und flexiblen Routine sind Messung von 3Hz bis 10 kHz möglich incl. einiger Nachkommastellen.






Quelle:
http://shelvin.de/ein-frequenzzaehler-fuer-niedrige-frequenzen-mit-dem-arduino-uno-und-der-pulslaengenmessung/



Ereignisse zählen - arduino-basics.com




Ereignisse zählen mit dem ARDUINO UNO R3
Aufgabe
Es soll gezählt werden, wie oft ein Taster gedrückt wurde.


Material
1x Arduino UNO R3
1x Taster
1x Widerstand 1kΩ
1x Breadboard
3x Leitungen 0,64mm

Beschreibung
Ein Anschluss des Tasters wird an 5Volt angeschlossen, der andere an einen digitalen Pin (hier Pin 8).
Wird der Taster gedrückt, dann liegt an Pin 8 eine Spannung von 5 Volt an (HIGH), die vom Mikrokontroller registriert wird.


Der 1kΩ Widerstand dient als Pulldown-Widerstand.
Anschluss an den Arduino


Vorüberlegungen
Die erste Überlegung ist, dass man eine Variable „Tasterzahl“ definiert, die erhöht wird, wenn am digitalen Pin 8 ein HIGH anliegt.
Der Wert der Variablen „Tasterzahl“ wird dann im seriellen Monitor ausgegeben.
Das Problem ist, dass die Variable ständig um 1 erhöht wird, solange der Taster gedrückt wird. Man kann den Wert auch beim kürzesten Druck nicht um 1 erhöhen.
Das liegt am Prellen des Schalters und an der schnellen Verarbeitung des Arduino.
Wenn man eine kurze Verzögerung einbaut, wird das Prellen ausgeschaltet, es ändert jedoch nichts daran, dass der Wert immer weiter erhöht, wenn der Taster lange gedrückt wird:


Die Lösung: Es darf nur hochgezählt werden, wenn der Taster gedrückt ist UND wenn er vorher nicht gedrückt war.
Man muss eine Variable einführen, die anzeigt ob der Taster schon gedrückt war oder nicht.
Das ArduBlock-Programm


Bedeutung der einzelnen Blöcke
(Steht unter dem Block keine Erklärung, dann wurde er bereits in einem Tutorial erklärt)


Der digitale Pin 8 wird abgefragt. Liegt an ihm eine Spannung von 5V (HIGH) an, dann erhält die Variable „TASTER“ den Wert „wahr“, sonst den Wert „falsch.

Es wird überprüft ob die Variable „TASTER“ den Wert „wahr“ hat und ob die Variable „VORHER“ den Wert „falsch“ hat. Wenn beides zutrifft, dann wird der Wert der Variable „ANZAHL“ um 1 erhöht.


Es wird überprüft, ob der Wert der Variable „TASTER“ „wahr“ ist. Falls ja, dann erhält die Variable „VORHER“ den Wert „wahr“, sonst den erhält sie den Wert „falsch“.
Damit weiß man bei der nächsten Abfrage, ob der Taster beim letzten Mal gedrückt war oder nicht.



Der Arduino-Sketch

(Steht keine Erklärung, dann wurde der Befehl bereits in einem Tutorial erklärt)


bool _ABVAR_1_TASTER;       // Die Variable ABVAR_1_TASTER wird angelegt. Sie kann nur die Werte „wahr“ (Taster gedrückt) oder „falsch“ (Taster nicht gedrückt) annehmen.
bool _ABVAR_2_VORHER;     // Die Variable ABVAR_2_VORHER wird angelegt. Sie kann nur die Werte „wahr“ (Taster war zuletzt gedrückt) oder „falsch“ (Taster zuletzt nicht gedrückt) annehmen.
int _ABVAR_3_ANZAHL;         // Die Variable ABVAR_3_ANZAHL wird angelegt. Sie kann ganze Zahlen annehmen.

 
void setup()
 {
  _ABVAR_1_TASTER = false;                  // Den Variablen werden Werte zum Start zugeordent.
  _ABVAR_2_VORHER = false;
  _ABVAR_3_ANZAHL = 0;
  Serial.begin(9600);
  pinMode( 8 , INPUT);                              // Pin 8 ist ein digitaler Eingang
 } 


  void loop()
 {
  _ABVAR_1_TASTER = digitalRead( 8) ; // Pin 8 wird abgefragt und das Ergebis wird gespeichert.
  delay( 100 );
  if (( _ABVAR_1_TASTER && !( _ABVAR_2_VORHER ) ))        // Wenn die Variable _ABVAR_1_TASTER den Wert „wahr“ und (&&) die Variable _ABVAR_2_VORHER den Wert“falsch“ (!) hat, dann...
  {
  ABVAR_3_ANZAHL = ( _ABVAR_3_ANZAHL + 1 ) ;               // ...wird der alte Wert der Variablen ABVAR_3_ANZAHL um 1 erhöht und unter dem Namen ABVAR_3_ANZAHL gespeichert.
  }
  Serial.print( "ANZAHL" );
  Serial.print( _ABVAR_3_ANZAHL );
  Serial.println("");
  if (_ABVAR_1_TASTER)                                                        // Wenn die Variable ABVAR_1_TASTER gedrückt ist (“wahr”) hat, dann …
  {
  _ABVAR_2_VORHER = HIGH ;                                               // ... soll die Variable ABVAR_2_VORHER „wahr“ sein.
  }
  else // ... sonst ...
  {
  _ABVAR_2_VORHER = LOW ;                                               // ... soll die Variable ABVAR_2_VORHER „falsch“ sein.
  }
}



Quelle:
http://arduino-basics.com/schaltungen/ereignisse-zaehlen/












https://www.arduino.cc/en/Tutorial/StateChangeDetection?from=Tutorial.ButtonStateChange

Code: [Select]
/*
State change detection (edge detection)

Often, you don't need to know the state of a digital input all the time, but
you just need to know when the input changes from one state to another.
For example, you want to know when a button goes from OFF to ON. This is called
state change detection, or edge detection.

This example shows how to detect when a button or button changes from off to on
and on to off.

The circuit:
- pushbutton attached to pin 2 from +5V
- 10 kilohm resistor attached to pin 2 from ground
- LED attached from pin 13 to ground (or use the built-in LED on most
Arduino boards)

created 27 Sep 2005
modified 30 Aug 2011
by Tom Igoe

This example code is in the public domain.

http://www.arduino.cc/en/Tutorial/ButtonStateChange
*/

// this constant won't change:
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPin = 13; // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button

void setup() {
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
// initialize serial communication:
Serial.begin(9600);
}


void loop() {
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
} else {
// if the current state is LOW then the button went from on to off:
Serial.println("off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;


// turns on the LED every four button pushes by checking the modulo of the
// button push counter. the modulo function gives you the remainder of the
// division of two numbers:
if (buttonPushCounter % 4 == 0) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}

}




/*
State change detection (edge detection)

Often, you don't need to know the state of a digital input all the time, but
you just need to know when the input changes from one state to another.
For example, you want to know when a button goes from OFF to ON. This is called
state change detection, or edge detection.

This example shows how to detect when a button or button changes from off to on
and on to off.

The circuit:
- pushbutton attached to pin 2 from +5V
- 10 kilohm resistor attached to pin 2 from ground
- LED attached from pin 13 to ground (or use the built-in LED on most
Arduino boards)

created 27 Sep 2005
modified 30 Aug 2011
by Tom Igoe

This example code is in the public domain.

http://www.arduino.cc/en/Tutorial/ButtonStateChange
*/

// this constant won't change:
const int buttonPin = 41; // the pin that the pushbutton is attached to
const int ledPin = 13; // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button

void setup() {
// initialize the button pin as a input:
pinMode(buttonPin, INPUT);
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
// initialize serial communication:
Serial.begin(9600);
Serial.print("läuft");
}


void loop() {
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);

if (buttonPushCounter == 0)
{digitalWrite (ledPin, 0);
Serial.println("nix");
}

else
if (buttonPushCounter == 1)
{digitalWrite (ledPin, 1);
Serial.println("lichtmodus == 1");

}

else
if (buttonPushCounter == 2)

{
Serial.println("lichtmodus == 2");

digitalWrite (ledPin, 0);}


else
if (buttonPushCounter == 3)
{digitalWrite (ledPin, 1);
Serial.println("lichtmodus == 3");

}
} else {
// if the current state is LOW then the button went from on to off:
Serial.println("off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;


// turns on the LED every four button pushes by checking the modulo of the
// button push counter. the modulo function gives you the remainder of the
// division of two numbers:
if (buttonPushCounter % 4 == 0) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}




Quelle:
https://forum.arduino.cc/index.php?topic=518119.15






Zeiten messen mit dem Timer


Timer können auch verwendet werden, um Zeiten zu messen.
Dazu kann die Interrupt-Funktioneinen Zähler hochzählen, der dann vom Hauptprogramm ausgelesen wird.
Hier ein Beispiel, um die Dauer eines Tastendrucks zu messen. 
Die Zeit wird in Millisekunden (ms) gemessen und auf dem LCD angezeigt.
Es werden zwei Taster nach Masse an D4 und D5 benötigt..


ZeitMessungMitTimer



Quelle:
http://laagewitt.de/wp-content/uploads/2018/07/Arduino-Kurs-Timer-und-Interrupts.pdf



Zählen von Tastenbetätigungen / Entprellen

Tastenbetätigungen zählen / entprellen

Ziel:
Die Anzahl von Tastenbetätigungen sollen gezählt und ausgegeben werden.
Für die Ausgabe der Zahl der Tastenbetätigungen wird das von früheren Experimenten her bekannte LCD-Shield benutzt.

Problem:
Das Betätigen einer Taste beinhaltet einen störenden Effekt, der sich "Prellen" nennt.
Statt des sofortigen elektrischen Kontaktes kommt es zum mehrfachen Schließen und öffnen.
Unser Arduino arbeitet so schnell, das z. B. das beim Zählen von Tastenbetätigungen jeder einzelne Prellvorgang mitgezählt werden würde.

Lösung:
Entprellen mittels Schaltungen, die Kondensatoren enthalten (Tiefpassfilter)
Oder einfacher: mit geschickt geschriebenem Programmcode

Schaltung:
Auf den Arduino stecken wir das LCD-Shield und verbinden einen Taster an den Eingang Analog_5 (=Digital19) und GND.

Programm:
Mit Hilfe eines Merkers ("set"), einer Zeitverzögerung (die länger als der Prellvorgang ist) und geschicktem Code wird hier zuverlässig jede Tastenbetätigung gezählt.
Man darf auch gerne die Taste dauerhaft drücken - es wird dann nicht weiter gezählt.


#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

int taste = 19; // Taste an Analog_5 = Digital_19
int zaehler = 0;
int set = 0; // soetwas nennt man auch "Merker"

void setup()
{
  lcd.clear();      // LCD löschen
  lcd.begin(16, 2); // verfügbare Spalten und Zeilen

  pinMode(taste, INPUT); // Eingang, an der die Taste hängt
  digitalWrite(taste, HIGH); // Für echtes High bei geöffneter Taste sorgen
}


void loop()
{
 
  if (digitalRead(taste) == LOW && set == 0) {
    zaehler++;
    lcd.setCursor(6,0);
    lcd.print( zaehler );
    set=1;
  }
 
  if (digitalRead(taste) == HIGH && set == 1) {
    delay(250);
    set=0;
  }

}



Quelle:
http://www.sachsendreier.com/asw/projekteundexperimente/entprellen/entprellen.php




Arduino als Impulszähler

 


Bei parallel laufenden, freien Praktika kann es vorkommen, dass plötzlich alle Impulszähler in Gebrauch sind. Abhilfe schafft da ein kleiner Arduino mit einem kleinen Sketch. Impulsraten sind Ereignisse aperiodischer Signale pro Zeiteinheit, wie zum Beispiel die Impulsfolge eines Geiger-Müller-Zählrohrs.

In wenigen Zeilen wird hier mittels pulseIN() und micros() die Impulsrate an Pin 7 gemessen. Als Zeitintervall T ist hier eine Sekunde, bzw. 1000000 (1e6) Mikrosekunden voreingestellt.

In der Hauptschleife wird die Einzelmessung initialisiert und dann während des Zeitintervalls T mittels pulseIn() auf eine ansteigende Flanke gewartet. Anschließend enthält N die Anzahl der Impulse pro Sekunde und wird via Serial.println gesendet.

Benutzt man symmetrische Signale (Rechteck, Sinus, Dreieck), so ergeben sich bei beiden Zählervarianten gleiche Ergebnisse, obwohl sie anders funktionieren.

Durch Änderung der Variablen T kann die Messdauer verändert werden. Für eine Zähldauer von z.B. 10 Sekunden würde T = 10*1e6 betragen



/* Impulszähler Gibt die Impulse pro Sekunde des Spannungsignals  an Pin 7 aus */int pin = 7;unsigned long N;          //Anzahl der Impulseunsigned long T;          //Zeitintervall in usunsigned long time;       //Startzeitvoid setup() { Serial.begin(9600);  pinMode(pin, INPUT);  T = 1e6;}void loop() { N = 0; time = micros();  do //what goes up must come down  {if (pulseIn(pin, HIGH)>0) N++;  }while( micros() < (time+T) );   Serial.println(N);}


LCD-Anzeige dazu

Wie beim 'Arduino als Zollstock' macht eine LCD-Anzeige die Messanordnung autonom. Auf einem 2x16-Display erfolgt die Darstellung durch Einbindung der 'LiquidCrystal'-Bibliothek, die unter http://arduino.cc/en/Tutorial/LiquidCrystal beschrieben ist. Das gesamte Programm wird dadurch kaum länger. Hier die Variante für den Frequenzzähler. Da die Umlaute wieder Probleme machen, zeigt das Display 'FrequencyCounter'. Bei offenem Eingang fängt sich der Zähler hier die Netzfrequenz ein.


/* Frequenzzähler   Gibt die Frequenz des Spannungsignals an Pin 7 aus */#include <LiquidCrystal.h>int pin = 7;unsigned long T;          //Periodendauer in usdouble f;                 //Frequenz in MHz char fm[] = " %8ld Hertz";LiquidCrystal lcd(12, 11, 5, 4, 3, 2);void setup() { lcd.begin(16, 2);  pinMode(pin, INPUT);  lcd.print("FrequencyCounter");}void loop() { char s[20];     // Messen von ti + tp = T  T = pulseIn(pin, HIGH) + pulseIn(pin, LOW);  T == 0 ? f = 0 : f=1/(double)T;  sprintf(s,fm,(unsigned long)(f*1e6));  lcd.setCursor(0, 1);  lcd.print(s);  delay(200);}



Quelle:
http://www.hjberndt.de/soft/ardfreq.html




Impulse zählen.

Ich möchte am Digitaleingang meines arduino uno Impulse zählen.
Die Impulse sollen in der Variable Puls mitgezählt bzw aufadiert werden.

// UNO mit Messung an Pin2

const byte messpin = 2;
volatile unsigned long zaehler;

void setup() {
Serial.begin(9600);
pinMode(messpin,INPUT_PULLUP);
attachInterrupt(0, messung, CHANGE);
}

void loop()
{
delay(1000); // every second
Serial.print("Zaehler: "); Serial.println(zaehler);
}

void messung() {
if (digitalRead(messpin)) zaehler++;
}






const int buttonPin = 6;     // the number of the pushbutton pin

int buttonState = 0;         // variable for reading the pushbutton status

int Puls;

boolean buttonState = digitalRead(buttonPin);
boolean oldButtonState;


void setup() {
     
pinMode(buttonPin, INPUT); 
Serial.begin(9600);


}

void loop(){



if ( buttonState != oldButtonState ) {
   // Wechsel erkannt
   oldButtonState = buttonState;
   delay(10); }// Entprellen
   if (buttonState == HIGH) { 
      Puls++;  // das hast du gefragt
      Serial.println(Puls);
   }
}



Dieser Sketch sollte gehen

const int buttonPin = 6;     // the number of the pushbutton pin
boolean buttonState, oldButtonState;
unsigned long anzeigeMillis, aktMillis;
const int anzeigeZeit = 1000;

void setup() {
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
buttonState = digitalRead(buttonPin);
oldButtonState = buttonState;
}

void loop() {
static int Puls;
aktMillis = millis();
buttonState = digitalRead(buttonPin);

if ( buttonState && !oldButtonState ) { // positive Flanke erkannt
delay(10); // Entprellen
Puls++;
}
oldButtonState = buttonState;
if (aktMillis - anzeigeMillis >= anzeigeZeit) {
anzeigeMillis = aktMillis;
Serial.print("Puls: ");
Serial.println(Puls);
}
}













Arduino UNO R3 als Zähler

Ereignis-Zähler

Möchte man verschiedene Ereignisse die als Signal an einem Eingang des Arduino vorliegen zählen, gibt es die einfache Möglichkeit über das sogenannte Polling-Verfahren die Werte einzulesen und zu verarbeiten. Beim Polling wird der Zustand des digitalen Eingangs durch eine Schleife in regelmäßigen Abständen abgefragt wird:


void loop() {
...
   if (digitalRead(switch_pin) == HIGH)
      doSomething();
   else doSomethingElse();
...
}

Der Nachteil bei dieser Methode ist, dass die Abfrageintervalle abhängig vom nachfolgenden Code verschieden lang sein können und dadurch kurze Ereignisse am digitalen Eingang (kurze Zustandswechsel zwischen HIGH und LOW) unbemerkt bleiben können. Der Vorteil dieser Methode ist aber die Einfachheit ihrer Implementierung.

Möchte man auch schnellere Ereignisse sicher erfassen, so bietet sich der Einsatz der Interrupt-Methode an. Der Arduino bietet zwei spezielle Interrupt-Eingänge (INT0 und INT1) an, an denen ein Zustandswechsel die Unterbrechung der bisherigen Programmabarbeitung und den Sprung in eine sogenannte Interrupt Service Routine (ISR) auslöst. Im Beitrag Interrupt-Programmierung wird darauf ausführlicher eingegangen.

Nach dem Durchlauf der ISR wird die Programmabarbeitung an der zuvor unterbrochenen Stelle fortgesetzt. Der Vorteil dieser Methode ist, dass keine Ereignisse am digitalen Eingang mehr “verpasst” werden können und die Reaktion auf einen Zustandswechsel unmittelbar darauf erfolgt.

Das nachfolgende Programm nutzt diesen Mechanismus, um die Signale einer Gabellichtschranke zu zählen. Dazu wurde ein kleiner Versuchsaufbau entwickelt, bei dem ein geregelter Elektromotor die Lichtschranke unterschiedlich schnell unterbricht.

Gabellichtschranke

Die Idee hinter diesem Aufbau besteht darin, eine kontinuierliche und definierte Auslösung der Lichtschranke zu erhalten. Ebenso ermöglicht er natürlich die Impulse der Lichtschranke mit Hilfe eines Oszilloskops genauer zu untersuchen.

Bild Oszi-Signale einfügen…

Impulse einer Lichtschranke zählen

Nach dem der erste Versuch erfolgreich abgeschlossen wurde, kann die Lichtschranke mit dem Arduino verbunden werden. Hier ist auf die Spannungspegel zu achten und ggf. über einen Spannungsteiler ein 5V Signal zu erzeugen.

Um nun die Impulse der Lichtschranke zu zählen gibt es verschiedene Möglichkeiten: Das nachfolgende Programm, definiert eine Interrupt Service Routine mit dem Namen counter(), in der die Ereignisse gezählt und ausgegeben werden.


// Einfacher Event-Zaehler
// PH 05.03.2017
//--------------------------------------
 
int const signal_pin = 2; // D2
int const signal_pin_interrupt_number = 0; // INT0,
void setup() {
Serial.begin(9600);
Serial.println("IMPULSZAEHLER");
pinMode(signal_pin, INPUT_PULLUP);
// attach an interrupt handler when the signal goes from low to high
attachInterrupt(signal_pin_interrupt_number, counter, RISING);
}
void loop() {
}
 
static int events = 0;
void counter() {
  ++events;
  Serial.print(" Events : ");Serial.println(events);
}



Impuls-Zähler pro Zeit

Der Arduino hat eine interessante Advanced IO-Funktion implementiert, die pulseIN(pin,HIGH/LOW) Funktion. Wie man mit dieser Funktion Impulse zählen und sogar Frequenzen messen kann, wird im folgenden Beitrag vorgestellt.

Impulsraten sind Ereignisse aperiodischer Signale pro Zeiteinheit, wie zum Beispiel die Impulsfolge eines Geiger-Müller-Zählrohrs oder die Signale einer Lichtschranke.  Im folgenden Programm wird auf einen Interrupt verzichtet, und mittels der Funktionen (pulseIN() und micros()) die Impulsrate an Pin 7 gemessen.


// Impulszähler
// Gibt die Impulse pro Sekunde
// des Spannungsignals an Pin 7 aus
//-------------------------
int pin = 7;
unsigned long N;          //Anzahl der Impulse
unsigned long T;          //Zeitintervall in us
unsigned long time;       //Startzeit
 
void setup(){
  Serial.begin(9600);
  pinMode(pin, INPUT);
  T = 1e6;
}
 
void loop(){
  N = 0;
  time = micros();
  do{  
     if (pulseIn(pin, HIGH)>0) N++;
    }
  while( micros() < (time+T) );
  Serial.println(N);
}


Als Zeitintervall T ist hier eine Sekunde, bzw. 1000000 (1e6) Mikrosekunden voreingestellt.

In der Hauptschleife wird die Einzelmessung initialisiert und dann während des Zeitintervalls T mittels pulseIn() auf eine ansteigende Flanke gewartet. Anschließend enthält N die Anzahl der Impulse pro Sekunde und wird via Serial.println gesendet.

Frequenz-Zähler

Der Arduino hat eine interessante Advanced IO-Funktion implementiert, die pulseIN(pin,HIGH/LOW) Funktion.

Mit dem Aufruf pulseIn(pin, HIGH) wird solange gewartet, bis das Signal an dem Eingangs-Pin (pin) auf den Logikpegel HIGH geht. In dem Moment wird ein Timer gestartet und gewartet, bis der Pegel LOW erreicht wird. Die verstrichene Zeit wird in Mikrosekunden zurück geliefert. Etwas anders ausgedrückt: puseIn(pin,HIGH) liefert die Dauer T1 des High-Anteils des Signals





Die Impulspause T2 (also der Low- Anteil) kann analog mit pulsIN(pin,LOW) ermittelt werden. Die Periodendauer T ergibt sich dann einfach aus T = T1 + T2.

Bei einem symmetrischen Rechtecksignal ist T1 = T2, also die Zeit für HIGH-Pegel gleich der Zeit für LOW-Pegel.

Die Funktion kehrt bei einem Timeout mit dem Wert 0 zurück, womit auch bei fehlendem Signal das Programm fortgesetzt werden kann.

Der Kehrwert der Periodendauer T entspricht der Frequenz f. Da die gemessene Zeit in  Mikrosekunden (10^-6s) vorliegt, wird bei der Frequenz-Berechnung dadurch ein Wert mit der Einheit Megahertz (MHz) heraus kommen. Um eine Anzeige in Hertz (Hz) zu bekommen, muss entsprechend umgerechnet werden.

Der Programmcode sieht in der einfachsten Form wie folgt aus:


unsigned long T;          //Periodendauer in us
double f;                 //Frequenz in MHz
 
void setup()
{Serial.begin(9600);
pinMode(pin, INPUT);
}
 
void loop(){
  T = pulseIn(pin, HIGH) + pulseIn(pin, LOW);
  if (T==0) Serial.println("Timeout.");
  else{
     f=1/(double)T;          // f=1/T                
     Serial.print("Frequenz des Signals : ");
     Serial.print(f*1e6); Serial.println(" Hz")
  }
}


Quelle:
http://profhof.com/arduino-als-frequenzzaehler/






Arduino Drehzahl Impulse zählen






void setup() {  pinMode(2, INPUT);                        // Eingangspin auf Eingang     attachInterrupt(0, readmicros, RISING );  // Interrupt 0 auf Routine}volatile unsigned long dauer=1;             // microsekunden volatile unsigned long last=0;              // Zählerwert long drehzahl;                              // selbstredendchar buf[17];                               // Pufferstring für sprintfvoid loop() {                               // Hauptprogramm  drehzahl =  dauer / 60000000;              // Drehzahl ausrechnen und  sprintf(buf, "%5lu", drehzahl);           // als 5 Zahl in den Puffer   serial.println(buf);                      // Puffer ausgeben  delay(500);                               // Eine halbe Sekunde warten}void readmicros() {                         // Interrupt-Routine  unsigned long m = micros();               // Microsekunden auslesen  dauer = m - last;                         // Differenz letzte  last = m;                                 // Letzten Wert merken}




Arduino Counter mit LCD-Display und Push Button Tutorial
Arduino Counter with LCD display and Push button Tutorial




Schematische Darstellung


Arduino Sketch


//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display


// this constant won't change:
const int  Up_buttonPin   = 2;    // the pin that the pushbutton is attached to
const int  Down_buttonPin = 3;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int up_buttonState = 0;         // current state of the up button
int up_lastButtonState = 0;     // previous state of the up button

int down_buttonState = 0;         // current state of the up button
int down_lastButtonState = 0;     // previous state of the up button
bool bPress = false;

void setup()
{
  Serial.begin(9600);
  pinMode( Up_buttonPin , INPUT_PULLUP);
  pinMode( Down_buttonPin , INPUT_PULLUP);
 
  lcd.init();                      // initialize the lcd
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Please Select:");
  lcd.setCursor(2,1);
  lcd.print(buttonPushCounter);
 
}


void loop()
{
   checkUp();
   checkDown();

   if( bPress){
       bPress = false;
      lcd.setCursor(2,1);
      lcd.print("               ");
      lcd.setCursor(2,1);
      lcd.print(buttonPushCounter);
   }
 
}

void checkUp()
{
  up_buttonState = digitalRead(Up_buttonPin);

  // compare the buttonState to its previous state
  if (up_buttonState != up_lastButtonState) {
    // if the state has changed, increment the counter
    if (up_buttonState == LOW) {
        bPress = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  up_lastButtonState = up_buttonState;
}
void checkDown()
{
  down_buttonState = digitalRead(Down_buttonPin);

  // compare the buttonState to its previous state
  if (down_buttonState != down_lastButtonState) {
    // if the state has changed, increment the counter
    if (down_buttonState == LOW) {
        bPress = true;
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter--;
     
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  down_lastButtonState = down_buttonState;
}





Quelle:
http://www.arduinotutorialonline.com/2018/01/arduino-counter-with-lcd-display-and.html





4 Digit 7 Segment 0 - 9999 Zähler mit Arduino
4 Digit 7 Segment 0 - 9999 counter using Arduino



Sparkfun COM-11408 4 Digit 7-Segment Display Hookup Guide









1k Widerstand

Arduino Sketch

#include "SevSeg.h"

//Create an instance of the object.
SevSeg myDisplay;

//Create global variables
unsigned long timer;
int deciSecond = 0;



void setup()
{

  int displayType = COMMON_CATHODE; //Your display is either common cathode or common anode

  /*
  //This pinout is for a regular display
   //Declare what pins are connected to the digits
   int digit1 = 2; //Pin 12 on my 4 digit display
   int digit2 = 3; //Pin 9 on my 4 digit display
   int digit3 = 4; //Pin 8 on my 4 digit display
   int digit4 = 5; //Pin 6 on my 4 digit display
   
   //Declare what pins are connected to the segments
   int segA = 6; //Pin 11 on my 4 digit display
   int segB = 7; //Pin 7 on my 4 digit display
   int segC = 8; //Pin 4 on my 4 digit display
   int segD = 9; //Pin 2 on my 4 digit display
   int segE = 10; //Pin 1 on my 4 digit display
   int segF = 11; //Pin 10 on my 4 digit display
   int segG = 12; //Pin 5 on my 4 digit display
   int segDP= 13; //Pin 3 on my 4 digit display
   */

  //This pinout is for OpenSegment PCB layout
  //Declare what pins are connected to the digits
  int digit1 = 2; //Pin 12 on my 4 digit display
  int digit2 = 3; //Pin 9 on my 4 digit display
  int digit3 = 4; //Pin 8 on my 4 digit display
  int digit4 = 5; //Pin 6 on my 4 digit display

  //Declare what pins are connected to the segments
  int segA = 6; //Pin 11 on my 4 digit display
  int segB = 7; //Pin 7 on my 4 digit display
  int segC = 8; //Pin 4 on my 4 digit display
  int segD = 9; //Pin 2 on my 4 digit display
  int segE = 10; //Pin 1 on my 4 digit display
  int segF = 11; //Pin 10 on my 4 digit display
  int segG = 12; //Pin 5 on my 4 digit display
  int segDP= 13; //Pin 3 on my 4 digit display

  int numberOfDigits = 4; //Do you have a 1, 2 or 4 digit display?

  myDisplay.Begin(displayType, numberOfDigits, digit1, digit2, digit3, digit4, segA, segB, segC, segD, segE, segF, segG, segDP);
  
  myDisplay.SetBrightness(100); //Set the display to 100% brightness level

  timer = millis();
}



void loop()
{
  //Example ways of displaying a decimal number
  char tempString[10]; //Used for sprintf
  sprintf(tempString, "%4d", deciSecond); //Convert deciSecond into a string that is right adjusted
  //sprintf(tempString, "%d", deciSecond); //Convert deciSecond into a string that is left adjusted
  //sprintf(tempString, "%04d", deciSecond); //Convert deciSecond into a string with leading zeros
  //sprintf(tempString, "%4d", deciSecond * -1); //Shows a negative sign infront of right adjusted number
  //sprintf(tempString, "%4X", deciSecond); //Count in HEX, right adjusted

  //Produce an output on the display
  myDisplay.DisplayString(tempString, 3); //(numberToDisplay, decimal point location)

  //Other examples
  //myDisplay.DisplayString(tempString, 0); //Display string, no decimal point
  //myDisplay.DisplayString("-23b", 3); //Display string, decimal point in third position

  //Check if 10ms has elapsed
  if (millis() - timer >= 1)
  {
    timer = millis();
    deciSecond++;
    if( deciSecond > 9999 ) deciSecond = 0;
  }

  delay(5);
}




https://www.hackster.io/meljr/sparkfun-com-11408-4-digit-7-segment-display-hookup-guide-4b4d9e
Quelle:
http://www.arduinotutorialonline.com/2018/08/4-digit-7-segment-0-9999-counter-using.html





Sparkfun 7 Segment display library for Arduino

SparkFun 7-Segment Serial Display - White

https://www.sparkfun.com/products/11629
https://www.sparkfun.com/products/11441
https://www.arduinolibraries.info/libraries/seven-segment-library



Interfacing Arduino with 7-segment display | 4-Digit counter example


https://simple-circuit.com/arduino-7-segment-display-4-digit/





Arduino LCD-Zähler
Arduino LCD-Counter
Erstellen Sie einen einfachen Arduino-LCD-Zähler mit einfachen Komponenten wie Drucktasten und LCD-Display
Schaltung


Erstellen Sie einen einfachen Arduino-LCD-Zähler mit einfachen Komponenten wie Drucktasten und LCD

Die Stückliste

Arduino Uno R3
16x2 LCD-Display
Drück Knöpfe
100k Potentiometer
10k Widerstand
220R Widerstand
BreadBoard
Kabel anschließen


//http://alialkarkuki.blogspot.com/
//Ali Al Karkuki

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int a =0;
int e = 7;


void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("Ali Al Karkuki");
pinMode(e,INPUT);
}


void loop() {
int button = digitalRead(e);

lcd.setCursor(3, 1);
lcd.print(a);

if (button == HIGH) {
a ++;
lcd.setCursor(3, 1);
lcd.print(a);
delay(200);
}



}


Wenn man den Knopf für eine lange Zeit drückt, wird er alle 200 ms kontinuierlich hochgezählt, ohne den Knopf loszulassen und erneut zu drücken. Ich möchte, dass es nicht mehr gezählt wird, wenn der Knopf nicht losgelassen und erneut gedrückt wird.



Quelle:
https://www.instructables.com/id/Arduino-Lcd-Counter/




Interruptgetriebene Zähler im Zeitformat auf einem LCD-Display

/*
The circuit:
* LCD RS pin to digital pin 7
* LCD Enable pin to digital pin 6
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
*/

// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

volatile int counter0 = 0; // Incremented by switch0
volatile int counter1 = 0; // Incremented by switch1

const int RTCLED = 13;
const int RTC = 20;
const int TAPE = 21;
int RTCstate = 0;
int sec0 = 00;
int min0 = 00;
int hour0 = 00;
int sec1 = 00;
int min1 = 00;
int hour1 = 00;

// Setup
void setup() {
pinMode(RTCLED, OUTPUT); // Pin13 as output
pinMode(RTC, INPUT); // Pin20 is input
digitalWrite(RTC, HIGH); // Switch on pull up
pinMode(TAPE, INPUT); // Pin21 is input
digitalWrite(TAPE, HIGH); // Switch on pull up
attachInterrupt(2, tapeINT, FALLING);
attachInterrupt(3, rtcINT, FALLING);

// set up the LCD's number of columns and rows:
lcd.begin(20, 4);
// Print a message to the LCD
lcd.print("Tape vs. Real Time");
}

// Zähler 0
void rtcINT(){
counter0++;
}

// Zähler 1
void tapeINT(){
counter1++;
}

void rtcZeit(){
char Cnt[30];
hour0=counter0/3600;
min0=(counter0/60)-(hour0*60);
sec0=counter0-(hour0*3600)-(min0*60);
lcd.setCursor(0, 2);
lcd.print("Real: ");
sprintf(Cnt,"%02d:%02d:%02d",hour0,min0,sec0);
lcd.print(Cnt);
}

void tapeZeit(){
char Cnt[30];
hour1=counter1/3600;
min1=(counter1/60)-(hour1*60);
sec1=counter1-(hour1*3600)-(min1*60);
lcd.setCursor(0, 3);
lcd.print("Tape: ");
sprintf(Cnt,"%02d:%02d:%02d",hour1,min1,sec1);
lcd.print(Cnt);
}

void loop(){
rtcZeit();
tapeZeit();
RTCstate = digitalRead(RTC);
if (RTCstate == HIGH) {
// turn LED on:
digitalWrite(RTCLED, HIGH);
} else {
// turn LED off:
digitalWrite(RTCLED, LOW);
}
}



was ich vielleicht machen würde:
mach in deine Interruptroutienen noch jeweils eine Variable rein:
rtcChanged=1
tapeChanged=1

If (rtcChanged==1){
rtcZeit();
rtcChanged=0;
}
if (tapeChanged==1{
tapeZeit();
tapeChanged=0;
}



Quelle:
https://forum.arduino.cc/index.php?topic=110240.0


Arduino Counter mit LCD-Anzeige
Arduino counter with LCD display

Arduino lesson – 4 Digit 7 Segment LED Display


Arduino uno von 0 bis 9999



4digit-7segment-12pin-arduino/0-to-9999-counter.c


Quelle:
http://e-diys.blogspot.com/2019/03/4-digits-7-segments-counter-0000-9999.html
http://osoyoo.com/2017/08/arduino-lesson-4-digit-7-segment-led-display/      (1A)
https://simple-circuit.com/arduino-7-segment-display-4-digit/                          (1A)
https://www.instructables.com/id/Arduino-4-digit-7-segment-display/


SparkFun 7-Segment display library for Arduino


https://github.com/sparkfun/SevSeg


SparkFun 7-Segment Serial Display - White

Das SparkFun 7-Segment Serial Display ist eine einfach zu bedienende und dennoch leistungsstarke Anzeigeoption für das mbed.
Dieses Display wird von demselben ATMega328 betrieben, das auf vielen Arduino-Boards zu finden ist, und unterstützt die SPI-, serielle UART- und I2C-Kommunikation.
Dieses Board ist von Sparkfun in verschiedenen Farben erhältlich, darunter rot, blau und grün.
Die Helligkeit der Karte hängt von der Eingangsspannung ab, da sie zwischen 3,3 V und 5 V akzeptiert.
Das Display ist außerdem bündig am Rand der Platine montiert.
Zusätzliche Pinbelegungen ermöglichen die einfache Reihenverdrahtung an einem einzelnen I2C-Bus.




Programmbeispiel MySparkfun7SegI2C:

#include <MySparkfun7SegI2C.h>
#include <Wire.h>

MySparkfun7SegI2C My7S(0x71);

void setup()
{

  Serial.begin(115200);

  if(My7S.isReady()) Serial.println("7-Segmentanzeige vorhanden");
  My7S.sendBlank(); //Dunkelsetzen der Anzeige
  delay(1000);
}

void loop()
{
  //Ausgabe eines Float-Wertes
  float FloatWert = 43.45;
  My7S.sendFloatVal(FloatWert); //Ausgabe der Float-Zahl "FloatWert"
  delay(1000);

  //Ausgabe eines Festkomma-Wertes
  int IntWert = 2345;
  byte dezStellen = 1; //Ausgabe mit einer Dezimalstelle
  bool blankZero = true; //Vornullen unterdrücken
  My7S.sendFixedVal(IntWert, dezStellen, blankZero);
  delay(1000);

  //Ausgabe von Zeichen (Zahlen + Buchstaben)
  My7S.sendChar('A','b',' ','d');
  delay(1000);

  //Ausgabe eines Textstrings (Zahlen + Buchstaben)
  String Text = "1AnE"; //Dieser Textstring soll angezeigt werden
  char string[5];
  Text.toCharArray(string, 5); //Umwandlung des Strings in ein Character-Array
  My7S.sendString(string);
  delay(1000);
}



Mehr Infos: https://arduino-projekte.webnode.at/meine-libraries/7-segmentanzeige-2/
https://arduino-projekte.webnode.at/meine-libraries/7-segmentanzeige-2/
https://learn.sparkfun.com/tutorials/using-the-serial-7-segment-display/all
https://www.sparkfun.com/products/11629



Vier Siebensegmentanzeigen steuern
Arduino uno von 0 bis 9999 zählen
Vierstellige 7 Segment Anzeige mit Arduino ansteuern
BCD Zähler 0-9999


https://funduino.de/nr-12-7-segment-anzeige
http://osoyoo.com/2017/08/arduino-lesson-4-digit-7-segment-led-display/

https://wlanowski.de/siebensegmentanzeige-arduino/
https://www.clickoslo.com/siebensegmentanzeige-tutorial.html
https://www.mymakerstuff.de/2016/05/12/die-siebensegmentanzeige/



Sevseg Library On 4 Digit Anode Segment

This library allows an Arduino to easily display numbers and characters on a 4 digit 7-segment display without a separate 7-segment display.







https://create.arduino.cc/projecthub/essoselectronic/sevseg-library-on-4-digit-anode-segment-ae7eed?ref=tag&ref_id=7%20segment&offset=0




Tropfenzähler Teil 1

Eine Gabellichtschranke (Photounterbrecher) ist zentraler Bestandteil des Tropfenzählers. Die lichte Weite der Gabel ist so groß zu wählen, dass ein freier Fall der Tropfen auch unter Bewegung sicher gewährleistet ist.

Gabellichtschranke_m_Schmitdtrigger

Die verwendete Lichtschranke besitzt eine Weite von 10 mm. Datenblatt Die Firma Sparkfun bietet ein Breakoutboard an, dem die geeignete Belegung und der Vorwiderstand (220 Ω) für die Verwendung mit dem Arduino UNO oder MEGA zu entnehmen ist.

Hieraus wurde ein fliegender Aufbau auf dem Breadboard entwickelt. Die „Beinchen“ der Lichtschranke sind dünn und beweglich, so dass es bei ungeeigneter Handhabung leicht zu Kurzschlüssen kommen kann. Eine Verwendung unmittelbar auf dem Breadboard ist nicht möglich.


Aufgabe dieses ersten Teils ist zunächst die sichere Erfassung fallender Tropfen. Zusätzlich soll anhand des Zeitabstandes zwischen zwei nacheinander fallenden Tropfen die Tropfgeschwindigkeit pro Minute geschätzt werden.

Hier der Code / Sketch

// dropcounter
/***************************************************/
int photoInterrupterPin = 2;          // Signal der Gabellichtschranke, Pegel bei Unterbrechung des Lichtweges "low" sonst "high"                  
int interruptNumber = 0;              // Pin 2 des Arduino Uno / Mega ist mit Interruptnummer 0 verbunden
int dropsPM = 0;                      // Ergebnisangabe in Tropfen pro Minute
volatile int dropNumber = 0;          // Variable zum Speichern der Tropfenzahl. "volatile" gewährleistet saubere Übergabe
int tempDropNumber = 0;               // dient zur Zwischenspeicherung der Tropfenzahl
volatile unsigned long deltaTime = 0; // Zeitabstand zwischen 2 aufeinanderfolgenden Unterbrechungen
volatile unsigned long lastInterruptTime = 0;  // Zwischenspeicherung des letzten Aufrufzeitpunktes
/***************************************************/
void setup()                                                   // Initialisierung der Pins, Einhängen und Typisieren des Interrupts
{
  pinMode(photoInterrupterPin, INPUT);                         // Pin 2 als Eingang definieren
  attachInterrupt(interruptNumber, interruptroutine, FALLING); // Immer wenn an Pin 2 der Pegel fällt, löst das Interrupt 0 aus
                                                               // und die Funktion "interruptroutine" wird aufgerufen
  Serial.begin(38400);                                         // Kommunikation mit Baudrate von 38400 initialisieren
                                                               // langsamere Geschwindigkeiten führen zu Datenverlusten
}
/***************************************************/
void loop()                                                    // Hauptprogrammschleife
{
  if ((dropNumber > tempDropNumber) and (dropNumber > 1))      // Hat sich die Tropfenzahl erhöht?
  {                                                            // Zeit zwischen 2 Tropfen nur bei mehr als 1 Tropfen sinnvoll
    dropsPM = 60000 / deltaTime;                               // 60000 ms = 1 Minute / Zeitdifferenz zwischen 2 Tropfen
    deltaTime = 0;                                             // Zeitdifferenz wieder auf Null setzen
    tempDropNumber = dropNumber;                               // Aktuelle Tropfenzahl zwischenspeichern
    Serial.println(dropNumber);
    Serial.print("Tropfen pro Minute: ");
    Serial.println(dropsPM);
  }  
  delay(5);                                                    // 5 ms warten. Das entspricht ebenfalls der Wartezeit der
                                                               // Interruptroutine. Es geht also keine Zeit verloren.
}
/******************************************************/
void interruptroutine()                                        // Wird aufgerufen, immer wenn der Pegel an Pin 2 abfällt.
{
  unsigned long        interruptTime = millis();               // Zeitpunkt zu dem der Interrupt aufgerufen wird
  deltaTime = interruptTime - lastInterruptTime;               // Da erst ab dem 2. Tropfen gezählt werden soll, gibt es
                                                               // einen vorangegangenen Zeitpunkt eines Interuoptaufrufs
    if (deltaTime > 5)                                         // Zeit zwischen 2 aufeinander folgenden Dropfen muss 5 ms
    {                                                          // überschreiten (verhindert Nebenefekte der Hardware)
      dropNumber++;                                            // Tropfenzahl wird um "1" erhöht wenn der Abstand zwischen
    }                                                          // 2 Ereignissen länger als 5 ms war.
    else                                                       // sonst
    {                                                          // war 's wohl ein Fehler und
      deltaTime = 0;                                           // der Zeitabstand wird auf "0" zurückgesetzt
    }  
    lastInterruptTime = interruptTime;                         // Zeitpunkt des aktuellen Pegelwechsels wird zwischengespeichert.
}

Die sichere Erfassung  zeitkritischer Vorgänge erfordert den Einsatz von Interrupts. Der Arduino UNO verfügt über 2 Pins / digitale Eingänge zur Erfassung externer Interrupts. Es sind dies die Pins 2 und 3. Hier wird Pin 2 als Eingang verwendet. Der Signalausgang der Gabellichtschranke funktioniert als Schmitt-Trigger. Die Signaländerungen verlaufen also sehr steil und schnell, so dass es kaum zu einer „Fehlinterpretation“ in Bezug auf eine Unterbrechung des Lichtweges kommen kann. Wird der Lichtweg unterbrochen fällt die Spannung am Signalausgang auf nahezu 0 V. Die Interruptroutine muss also stets bei fallendem Pegel („falling“)aufgerufen werden. Wird sie bei sich ändernden Peglen („change“) aufgerufen, ergeben sich pro Tropfenfall 2 Signale. Das erste entsteht zu Beginn der Unterbrechung des Lichtweges und das zweite beim Verlassen des Lichtweges durch den fallenden Tropfen.

Die Sprache des Arduino sieht die Funktion „millis()“ zur Bestimmung der Zeit vom Einschalten des Prozessors vor. Wie der Name nahe legt erfolgt die Angabe in Millisekunden. Damit lässt sich ein Zeitraum von bis zu 50 Tagen erfassen, da die Funktion den Datentyp „Long“ als Ergebnis liefert. Eine genauere Erfassung in z.B. Mikrosekunden wäre zwar möglich, ist auf Grund der  Größe der Tropfen und der maximal möglichen Fallgeschwindigkeit nicht nötig.

Die Ermittlung einer Zeitdifferenz erfordert die Bestimmung von mindestens 2 Zeitpunkten. Die Bestimmung der Tropfgeschwindigkeit kann also erst vom zweiten Tropfendurchgang an erfolgen, weshalb „dropNumber > 1“ eine notwendige Bedingung ist, die abgefragt wird sobald die Tropfenzahl „dropNumber“ größer als die vorangegangene temporär gespeicherte Tropfenzahl „tmpDropNumber“ ist. Die temporäre Variable wird mit „0“ initialisiert. Somit wäre „dropNumber > temDropNumer“ schon für den ersten fallen Tropfen erfüllt. Eine alternative – aber weniger transparente – Lösung wäre die Initialisierung von tempDropNumber mit „1“.

Die Kommunikation des Arduino über die serielle Schnittstelle mit dem PC (Serial Monitor) kostet Zeit. Experimentell stellte sich heraus, dass erst ab einer Baudrate von mehr als 38400 eine zuverlässige Tropfenerkennung möglich ist. Einer weiteren Erhöhung der Baudrate steht allerdings nichts im Wege.

Das eingefügte „delay(5)“ bgrenzt den unnötigen Energieverbrauch der Prozessors und damit Erwärmung. Die verwendeten 5 ms entsprechen der Zeit die ohnehin in der Interruptroutine gewartet wird. Der gewählte Zeitrahmen stammt auf dem Encoder-Beispiel und funktionierte auch hier.

Klare Plastikfolie oder Polycarbonat stören den Strahlengang nicht. Durch einen Ring aus Polycarbonat kann eine Kontamination der IR-LED oder des Sensors vermieden werden.

Die Folgeversion der Software soll zusätzlich eine Funktion zur Näherung der Tropfgeschwindigkeit aus der Mittelung mehrerer Tropfzeitdifferenzen enthalten. Ein Ausgangssignal auf einen Digitalausgang soll zudem den sicheren und frei definierbaren Zeitrahmen für die Bewegung des Tropfenzählers zum nächsten Gefäß signalisieren.


Quelle:
http://technik-garage.de/tropfenzaehler-teil-1/





Rundenzähler für die Autorennbahn mit ARDUINO UNO R3

Interrupts am Arduino: Rundenzähler


Adafruit LEDBackpack       Adafruit_LEDBackpack.h
Adafruit GFX                                      Adafruit_GFX.h
LCD-Display 16x2                               LiquidCrystal.h



#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <LiquidCrystal.h>
//
Adafruit_7segment matrix = Adafruit_7segment();
LiquidCrystal lcd(9, 8, 5, 4, 6, 7);
//
volatile unsigned long zaehlerrechts = 0;
volatile unsigned long millisrechts = 0;
volatile unsigned long speedrechts = 65000;
volatile unsigned long zaehlerlinks = 0;
volatile unsigned long millislinks = 0;
volatile unsigned long speedlinks = 65000;
//
void setup() {
    Wire.begin();
    attachInterrupt(0, rechtsHoch, CHANGE);
    attachInterrupt(1, linksHoch, CHANGE);
    matrix.begin(0x70);
    millisrechts = millislinks = millis();
    lcd.begin(16, 2);
    delay(500);
}
//
void loop() {
    lcd.setCursor(0, 0);
    lcd.print("schnellste Runde" );
    lcd.setCursor(0, 1);
    lcd.print(" ");
    lcd.setCursor(0, 1);
    if (speedrechts < 65000) {
        lcd.print(speedrechts + "ms");
    } else {
        lcd.print("---- ms");
    }
    lcd.setCursor(8, 1);
    lcd.print(" ");
    lcd.setCursor(8, 1);
    if (speedlinks < 65000) {
        lcd.print(speedlinks + " ms");
    } else {
        lcd.print("---- ms");
    }
    int zaehler = 100 * zaehlerrechts + zaehlerlinks;
    matrix.writeDigitNum(0, (zaehler / 1000), false);
    matrix.writeDigitNum(1, (zaehler / 100) % 10, false);
    matrix.drawColon(true);
    matrix.writeDigitNum(3, (zaehler / 10) % 10, false);
    matrix.writeDigitNum(4, zaehler % 10, false);
    matrix.writeDisplay();
    delay(100);
}
void rechtsHoch() {
    unsigned long temprechts = millis() - millisrechts;
    if (temprechts > 700) {
        zaehlerrechts++;
        if (speedrechts > temprechts) {
            speedrechts = temprechts;
        }
        millisrechts = millis();
    }
}
void linksHoch() {
    unsigned long templinks = millis() - millislinks;
    if (templinks > 700) {
        zaehlerlinks++;
        if (speedlinks > templinks) {
            speedlinks = templinks;
        }
        millislinks = millis();
    }
}





Quelle:
https://iludis.de/?page_id=38








Drehzahlmesser
ch will ein Messsgerät bauen das Strom, Spannung und Drehzahl (Propellerdrehzahl) misst, die Daten auf LCD ausgibt und auf SD card schreibt. Strommessung, Spannungsmessung und das Schreiben auf SD funktioniert mittlerweile.

// Drehzahlmesser auf PIN 2 = Interrupt 0

volatile unsigned long ende;
volatile unsigned long start;
volatile int tics;
unsigned long rpm;
unsigned long delta;


void setup() {

  Serial.begin(9600);
  attachInterrupt(0, CountTics, RISING);
  tics = 0;
  rpm = 0;
  start = 0;
  ende = 0;

}


void loop() {

  if (tics > 101) {//ich zähle 100 tics um einen guten Mittelwert zu erhalten

    delta = ende - start;
    rpm = 60000 * 100 / delta/2; //wegen Zweiblattpropeller

    Serial.print ("delta = ");
    Serial.println(delta);

    Serial.print ("rpm = ");
    Serial.println(rpm);

    Serial.println ("");

    tics = 0;
  }
  delay(1000);
}


void CountTics() {
  Serial.print ("tics = "); //hier sehe ich wie die tics kommen
  Serial.println(tics); //hier sehe ich wie die tics  am serieal Monitor --- wird im endgültigen Sketch ausgeblendet
  if (tics == 1) {
  
    start = millis();
  }
  if (tics == 101) {
    ende = millis();
  }
  tics++;
}







Quelle:
https://www.arduinoforum.de/arduino-Thread-Drehzahlmessung











Stückzähler mit dem KY-032 Modul zur Hinderniserkennung

Arduino / Stückzähler mit dem KY-032 Modul und dem Multi Function Shield



Multi Function Shield Einrichtung und Nutzung

Bei meiner Suche nach Sensoren für den Arduino bin ich auch über dieses Multi Function Board gestolpert, das aus Fernost über eBay nur zwei bis drei Euro kostet.
Bei dem Preis habe ich mir natürlich gedacht: "Dafür kannst du nichts falsch machen!" und es bestellt.
Mittlerweile sind ein paar Wochen vergangen und es ist endlich angekommen.

Das erste was mir auffiel, war die aufgedruckte Bezeichnung: "Mulie-function Shidle" heißt es da. Ich frage mich dann immer, ob es für Chinesen genau so schwierig ist, lateinische Zeichen zu erkennen und wiederzugeben wie für uns Europäer chinesische.
Sun3Drucker Multi-Function Shield Expansion
Board Prototype Module with Buzzer LED
Indicator Compatible Arduino 2009 UNO LENARDO Mega2560


Danach ist der Shield aber vorbereitet und kann auf einen Arduino Uno gesteckt werden. Damit stehen dann folgende Komponenten zur Verfügung:
  • 4-fach Sieben-Segment-Anzeige (über 2x 74HC595 und D4, D7, D8 angesteuert)
  • Buzzer (GPIO 3)
  • 4 LEDs (D1 - D4, GPIO 13 - 10)
  • 2 Jumper J1 (Pullup 10KΩ A0-A3=1023; muss gesetzt sein für Tasterfunktion) und J2 (Pullup 10KΩ A4=1023)
  • 3 Taster S1 - S3 (Analog 1 - 3)
  • ein Potentiometer (Analog 0)
  • oben links ein 7-Pin-Female-Header für Module "APC 220 Bluetooth Voice Rec.". Belegung von oben nach unten:
    • 1: -
    • 2: -
    • 3: GPIO 0
    • 4: GPIO 1
    • 5: -
    • 6: 5V
    • 7: GND
  • mittig ein 6-Pin-Female-Header für Module "U4-IR-2" und "U5-18b20-LM35-A4". Belegung von links nach rechts:
    • 1: GPIO 2
    • 2: GND
    • 3: +5V
    • 4: GND
    • 5: Analog 4
    • 6: +5V
  • unten rechts ein 3x4-Pin-Male-Header-Feld. Links GND, mittig +5V, rechts oben nach unten:
    • 1: GPIO 5
    • 2: GPIO 6
    • 3: GPIO 9
    • 4: Analog 5



https://www.amazon.de/Multi-Function-Expansion-Prototype-Indicator-Compatible/dp/B07B2D1C7Y/ref=as_li_ss_tl?s=ce-de&ie=UTF8&qid=1539697958&sr=1-2-spell&keywords=mulit+function+shield&linkCode=sl1&tag=httcoowebde-21&linkId=153e6a253cdd5b2f05d6c4372802727e&language=de_DE




Quelle:
http://cool-web.de/arduino/multi-function-shield-einrichtung.htm
http://cool-web.de/arduino/multi-function-shield-einrichtung.htm

http://cool-web.de/arduino/multi-function-shield-mit-drehgeber-erweitern.htm
http://cool-web.de/arduino/multi-function-shield-mit-modul-ky-032-stueckzaehler-hindernis-erkennung.htm





Durchflussmesser mit Display und Reset-Taste - wie mit Arduino realisieren


Habe mal soweit auf die Schnelle überhaupt möglich meinen Code auf Deine Anwendung hin angepasst, soll Dir als Beispiel dienen wie soetwas realisiert werden könnte. Hoffe das Du damit etwas anfangen kannst.

Mal ein paar Hinweise/Tipps:
Bei meinem XSensor habe ich die Berechnung der aktuellen Durchflussmenge und dem Gesamtverbrauch bereits realisiert, vielleicht schaust Du Dir dort mal etwas ab.
Hierbei bin ich aber auf die kleinste Einheit, die uL / Puls, gegangen. So fallen Messtoleranzen nicht ins Gewicht.
Wichtig ist auch die Verwendung von float Variablen (wo notwendig) damit bei Berechnungen keine Rundungsfehler entstehen.
Im Interrupt, wurde schon drauf hingewiesen, so wenig wie möglich machen. Auf gar keinen Fall irgendwelche Library-Aufrufe ...
Variablentyp mit vorangestellten "volatile" zwingt den Compiler den Code so zu generieren das die Variable IMMER eingelesen wird. Wichtig da Sie sich im IRQ ändert.

Sensor Benzin : BioTech FCH-m-PP-LC
- Durchflussmenge 15mL - 800mL
- 10500Pulse / Liter
> 1mL = 10,5 Pulse
> 0,095mL = 1 Pulse



Sketch
// der IRQ-PIN 2/3 auf dem der Sensor geschaltet ist#define PIN_FUEL  2#define FLOW_AVG_CNT   8#define FLOW_AVG_MSK   0x07#define FLOW_AVG_SH    3                          // n/8, # shift right für Divisonvolatile uint32_t MesureAvg[FLOW_AVG_CNT];  // die jeweils letzten n Messungen in uSstatic uint32_t FlowCntTank;                // # Impulse gesamt entnommenvoid setup(){  // da der Sensor fallende Flanken liefert den PIN intern mit einem PULL-UP versehen  pinMode( PIN_FUEL, INPUT_PULLUP );  // dann die Interrupt-Service Routine für diesen PIN definieren, IRQ Auslöser ist fallende Flanke  attachInterrupt( digitalPinToInterrupt(PIN_FUEL), FlowIRQ, FALLING );}// ============================// capture Durchfluss interrupt// ============================void FlowIRQ( void )    // >> ISR( PCINT1_vect ) PIN change IRQ{ static uint8_t  CaptureIdx; static uint32_t LastMicros; register uint32_t uS = micros();  // Pulse/Min und entspr. Abstände  //   1mL = 10,5 Pulse = 5714,29mS  //  50mL =  525 Pulse =  114,29mS  // 800mL = 8400 Pulse =    7143uS  // für Flowanzeige je n Messungen zur Durchschnittsberechnung sichern  if( LastMicros )                                // aus irgendeinem Grund löst der IRQ nach Init 1x aus, 1. IRQ verwerfen    MesureAvg[CaptureIdx++] = uS - LastMicros;  CaptureIdx &= FLOW_AVG_MSK;  LastMicros = uS;  FlowCntTank++;                               // Summe der Pulse, entnommenes Volumen}#define  TIM_BASE 10                                                                     // Timeraufruf alle 10mSstatic uint8_t TmoVolumeRefresh;  #define TMO_VOL_REFRESH  (1000/TIM_BASE)  // jede Sek. das Restvolumen berechnenstatic uint8_t  TmoFlowCalc;  #define TMO_FLOW_CALC     (500/TIM_BASE)  // alle 500mS die akt. Durchflussmenge berechnenstatic uint8_t TmoFlowOff;  #define TMO_FLOW_OFF  TMO_FLOW_CALC + (100/TIM_BASE)  // mS ohne Flow Impulsstatic float Flow;                            // akt. Flow in mLstatic uint16_t VolumeConsumed;               // akt. entnommene Menge in mLstatic uint32_t FlowCntLast = -1;// dann noch eine Routine die alle 10mS aufgerufen wird// davon abgeleitet dann alle 500mS eine Flowberechnung und jede Sek. eine Restvolumen// ==========// 10mS Timer// ==========void Tim10mS(){  // ------------------------------------  // Durchflussmenge berechnen, alle n mS  // ------------------------------------  if( TmoFlowCalc )    TmoFlowCalc--;  else if( FlowCntTank != FlowCntLast )       // liegt neue Messung vor ? oder Init ?    {    uint32_t Avg = 0L;    uint8_t Idx;    Idx = FLOW_AVG_CNT;    while( Idx-- )      Avg += MesureAvg[Idx];                    // Summe der Messungen in uS    Avg >>= FLOW_AVG_SH;                        // Sum/n, Mittelwert Impulsabstand in uS    // Impuls Anzahl auf 1 Min hochrechnen, akt. Flow    float FCntMin;    if( Avg )                                   // Division durch 0 vermeiden ;)      {      FCntMin = (60L*1000L*1000L) / Avg;      // # uL/Pulse auf ml/Min umrechnen      Flow = (FCntMin * uL_OnePulse) / 1000.0;  // uL > mL      }    // akt. entnommene Menge    VolumeConsumed = ((float)FlowCntTank * uL_OnePulse) / 1000.0;    FlowCntLast = NV_FlowCntTot;    TmoFlowCalc = TMO_FLOW_CALC;            // nur alle n mS bewerten und das nur bei Änderungen    TmoFlowOff  = TMO_FLOW_OFF;             // Zeit ohne Impulse bis Durchfluss Stopp erkannt    }  // ----------------------------  // Motor steht, kein Durchfluss  // ----------------------------  if( TmoFlowOff && (--TmoFlowOff == 0) )   // entnommene Menge sichern nur wenn wir ausreiched Flow hatten    {    Flow = 0;                          // Flow Anzeige = 0mL/Min    //memset( MesureAvg, 0, sizeof(MesureAvg) );  // Durchnitt neu berechnen    }}






























Quelle:
http://www.rc-network.de/forum/showthread.php/704808-Durchflussmesser-mit-Display-und-Reset-Taste-wie-mit-Arduino-realisieren





6.3    Experiment: Am Drehgeber drehen
Ein Drehgeber (siehe Abb. 6-7) misst eine Drehbewegung.
Ein Absolutwertgeber meldet dabei die Stellung (»Position ist 83°«), ein Relativwertgeber die Änderung (»von der letzten Position um 23° gedreht«).
     Wir verwenden einen Relativwertgeber.
Wenn Sie den Knopf drehen, sendet der Drehgeber Taktimpulse an den Taktpin.
Bei einem Anstieg am Taktpin (das Taktsignal geht von LOW auf HIGH) geht beim Datenpin ein Datenimpuls ein, beim Abfall (Übergang von HIGH zu LOW) ein weiterer.
     Ist der Datenimpuls HIGH, so liegt eine Drehung nach rechts vor (im Uhrzeigersinn, also gegen den mathematischen Drehsinn), bei LOW eine Drehung nach links.

Abb. 6-7    Drehwertgeber

6.3.1    Code und Schaltung für den Drehgeber am Arduino
Der Code verwendet Interrupts, weshalb er ein wenig anders aussieht als die meisten Arduino-Programme, die Sie bis jetzt kennengelernt haben.
Bauen Sie die Schaltung gemäß Abbildung 6-8 auf und führen Sie den Sketch aus Listing 6-5 aus.

Abb. 6-8    Drehgeberschaltung für den Arduino

ARDUINO UNO R3  Sketch

// rotary_encoder.ino - Gibt die Stenlung des Drehgebers aus
// (c) BotBook.com - Kimmo Karvinen, Tero Karvinen, Ville Valtokari

const int clkPin = 2;
const int dtPin = 4 ;

volatile unsigned int encoderPos = 0;

void setup()

{
Serial begin(115200) ;
pinMode(clkPin, INPUT);
digital Write(clkPin, HIGH);     // Pullup-Widerstand    2
pinMode(dtPin, INPUT);
digitalWrite(dtPin, HIGH);       // Pullup-Widerstand

attachInterrupt(0, processEncoder, CHANGE);           3
}

void loop()
{
Serial .println(encoderPos);
delay(100);
}

void processEncoder()                                          4
{
     if(digitalRead(clkPin) == digitalRead (dtPin))            5
     {
          encoderPos++;       // Drehung nach rechts
      } eise {
          encoderPos--;
      }
}

Listing 6-5    rotary encoder.ino


1. Die Variable encoderPos wird als volatile (flüchtig) gekennzeichnet, da sie in der Interruptfunktion geändert wird.
Das Schlüsselwort volatile teilt dem Arduino-Compiler mit, dass sich der Wert »hinter dem Rücken« der Hauptschleife im Arduino-Sketch ändern kann.
2. Wenn Sie HIGH auf einen Eingangspin schreiben, wird dieser über einen 20k Ohm  Pullup-Widerstand mit +5V verbunden.
Dies dient dazu, einen potenzialfreien Zustand zu vermeiden.
3. Immer wenn eine Änderung (CHANGE) auftritt, also ein Anstieg oder Abfall, wird die Funktion processEncoder aufgerufen.
Beim ARDUINO UNO R3 überwacht der Interrupt 0 den Digitalpin 2
Beim ARDUINO UNO R3 überwacht der Interrupt 1 den Digitalpin 3
Die Callbackfunktion processEncoder wird ohne nachfolgende Klammern angegeben, da sie noch nicht ausgeführt werden soll, sondern erst später, wenn sie vom Interrupt aufgerufen wird.
(Dies geschieht hinter den Kulissen.)
4. Während die Interruptfunktion ausgeführt wird, werden alle anderen Vorgänge angehalten.
5. Wenn der Datenpin (dtPin) denselben Pegel aufweist wie der Taktpin (clkPin), liegt eine Drehung nach rechts vor, anderenfalls eine Drehung nach links.


Quelle:
BUCH: Sensoren Seite 145





Problematische Sensorabfrage ohne Interrupt (Seite 884)
Sensorabfrage mit Interrupt an tastePin = 2 (oder tastePin = 3)  - Seite 886 (BUCH: Die elektronische Welt mit Arduino entdecken)





********************************************************I*
BUCH: AVR-Mikrocontroller und BASCOM


Pulsmesser
Ein Analogeingang (Potenziometer) wird zur Einstellung der Schaltgrenze für den anderen Eingang
(Finger/Ohrclip mit LDR empfängt pulsierend Licht einer hellen LED) benutzt.
Seite 128


Herzfrequenzsensor "Pulsesensor"

https://pulsesensor.com/



https://pulsesensor.com/pages/installing-our-playground-for-pulsesensor-arduino
https://pulsesensor.com/pages/code-and-guide
https://pulsesensor.com/pages/getting-advanced
https://pulsesensor.com/pages/pulse-sensor-speaker-tutorial
https://pulsesensor.com/pages/pulse-sensor-speaker-tutorial
https://pulsesensor.com/pages/pulse-sensor-servo-tutorial
https://pulsesensor.com/pages/two-or-more-pulse-sensors
https://pulsesensor.com/pages/pulsesensor-playground-toolbox
https://pulsesensor.com/pages/pulse-transit-time

Auf der Internetseite www.pulsesensor.com gibt es weitere Anleitungen und detaillierte Informationen zu dem Sensor.

Nr.21 – Herzfrequenzmessung

int SensorPin = A0;  // Signalleitung an Analoa A0  int LED=13; // LED an Port 13 wird verwendetint Sensorwert;                // Variable für den Sensworwertint Grenzwert = 510;       // Grenzwert, ab dem die LED an Pin13 später leuchten sollvoid setup() {pinMode(LED,OUTPUT);    // Pin 13 ist ein Ausgang, damit die LED mit Spannung versorgt wirdSerial.begin(9600);       // Serielle Verbindung starten, damit Daten am Seriellen Monitor angezeigt werden können  }void loop() {Sensorwert = analogRead(SensorPin);  // Sensorwert vom Sensor auslesen und unter der Variablen "Sensor" abspeichernSerial.println(Sensorwert);          // Sensorwert über die Serielle Schnittstelle an den PC senden.if(Sensorwert > Grenzwert) // Hier wird eine Verarbeitung gestartet. Wenn der Sensorwert über dem Grenzwert ist...{                          digitalWrite(LED,HIGH);  // ...dann soll die LED leuchten} else                       // Ansonsten...{digitalWrite(LED,LOW);    //  ...ist die LED aus}delay(10);  // Kurze Pause im Code, damit die Messwerte besser zu erkennen sind.     }


https://www.funduinoshop.com/epages/78096195.sf/de_DE/?ObjectPath=/Shops/78096195/Products/C-6-5
https://www.funduinoshop.com
https://funduino.de/nr-21-herzfrequenzmessung





Sie fahren ...?  Smiley-Blitzer
Mit 2 Lichtschranken im Abstand von 5m
In einer verkehrsberuhigkten Zone oder einer Dorfdurchfahrt kann es sinnvoll sein, die Autofahrer auf freundliche Weise an die Einhaltung der zulässigen Höchstgeschwindigkeit zu erinnern.
Zur Messung der Geschwindigkeit werden zwei Kontakte im Abstand von 5 Metern benötigt (Lichtschranken oder Kontaktschläuche).
Beim Überfahren der Kontakte wird die gefahrende Geschwindigkeit ermittelt und dem Autofahrer sofort per 7-Segment-Großanzeige mitgeteilt.
Zusätzlich erscheint ein lachender oder ein weinender Smiley — je nachdem, ob die Geschwindigkeit angemessen oder zu hoch war.


Anmerkungen:
Die drei Siebensegment-Anzeigen sind zu Experimentierzwecken so schaltbar wie im Schaltplan
gezeigt. Im endgültigen Aufbau muss eine Großanzeige aus vielen LEDs mit Treibertransistoren bzw.



Treiber-ICs aufgebaut werden.
Durch die Ausgänge PD5 bis PD7 wird die Smiley-Anzeige 9 LEDs (davon 6 LEDs wechselnd) angesteuert.
Im Testaufbau reicht eine gelbe - LED an PD5, eine grüne LED an PD6 und eine rote LED an PD7.
Im endgültigen Aufbau muss eine größere Smiley-Anzeige aus vielen LEDs aufgebaut und durch Treiber-Transistoren angesteuert werden.
Mit PD5 wird der Kreis und die Augen des Smiley angesteuert.
PD6 bzw. PD7 steuern den lachenden bzw. den weinenden Mund des Smiley an.
In der Anzeige sind beide Münder vorhanden aber es wird jeweils nur einer angesteuert.
Seite 246


ARDUINO Geschwindigkeitsmessung

Ich verwende zwei Taster mit Pullup zur Simulation der Lichtschranken.
Um die Übergangserkennung zu vereinfachen benutze ich Bounce2.
Funktioniert in beide Richtungen.

Mess-Lichtschranke
warte...
erst Links
dann Rechts
Dauer 771060 micro Sekunden
naechste Messung
warte...
erst Rechts
dann Links
Dauer 971768 micro Sekunden
naechste Messung
warte...



Dann im fertigen Projekt braucht eine Lichtschranke keine Entprellung weil sie nicht prellt.


#include <Bounce2.h>

// Lichtschranken Zeitmessung
// Eingabesimulation mit Tasten (INPUT_PULLUP)

typedef enum Zustand {
warte = 1,
vonRechts,
vonLinks,
gemessen,
} tZustand;

void naechsterZustand(const __FlashStringHelper* msg, tZustand neuerZustand);

const byte lsLinksPin = 2;
const byte lsRechtsPin = 3;

int aktuellerZustand;
bool uebergaengeAnzeigen = false;

Bounce SchrankeL;
Bounce SchrankeR;

unsigned long WertLinks;
unsigned long WertRechts;

unsigned long Ergebnis;

unsigned long topLoop;
unsigned long zustandErreicht;

void setup() {
SchrankeL.attach(lsLinksPin, INPUT_PULLUP);
SchrankeR.attach(lsRechtsPin, INPUT_PULLUP);
Serial.begin(115200);
naechsterZustand(F("Mess-Lichtschranke"), warte);
}

void loop() {
topLoop = micros();
SchrankeL.update();
SchrankeR.update();
switch (aktuellerZustand) {
case warte:
if (SchrankeR.fell()) {
WertRechts = topLoop;
naechsterZustand(F("erst Rechts"), vonRechts);
}
if (SchrankeL.fell()) {
WertLinks = topLoop;
naechsterZustand(F("erst Links"), vonLinks);
}
break;
case vonRechts:
if (SchrankeL.fell()) {
WertLinks = topLoop;
Ergebnis = WertLinks - WertRechts;
naechsterZustand(F("dann Links"), gemessen);
}
break;
case vonLinks:
if (SchrankeR.fell()) {
WertRechts = topLoop;
Ergebnis = WertRechts - WertLinks;
naechsterZustand(F("dann Rechts"), gemessen);
}
break;
case gemessen:
Serial.print(F("Dauer "));
Serial.print(Ergebnis);
Serial.println(F(" micro Sekunden"));
naechsterZustand(F("naechste Messung"), warte);
break;
}
}

void naechsterZustand(const __FlashStringHelper* msg, tZustand neuerZustand) {
if (msg != NULL) {
Serial.println(msg);
}
if (neuerZustand == warte) {
Serial.println(F("warte..."));
}
zustandErreicht = millis();
if (uebergaengeAnzeigen) {
Serial.print(zustandErreicht);
Serial.print(F(" von "));
Serial.print(aktuellerZustand);
Serial.print(F(" in "));
Serial.println(neuerZustand);
}
aktuellerZustand = neuerZustand;
}




https://forum.arduino.cc/index.php?topic=396341.0


Geschwindigkeitsanzeige für Tischfussball
Ich hab damals eine Geschwindigkeitsanzeige für einen Kicker gebaut.
Vielleicht hilft dir das weiter. Jegliche Beschreibungen und Downloads sind dabei.
aa
Geschwindigkeitsanzeige am Kicker / Tischfussball



ich wollte hier ein Projekt vorstellen, dass ich in meinen Semesterferien im Laufe einer Hausarbeit für das Studium erstellt habe.



Aufgabenstellung:

Messung der Geschwindigkeit eines Balles auf einem Tischfussball / Kicker / Kickertisch bei der verschiedene Dinge über ein LCD eingestellt werden können.

Inhaltsverzeichnis des Projektes:

1. Aufgabenstellung
2. Einführung
3. Hardware im Detail + Kostenberechnung
4. Software im Detail
5. Messungen um die Genauigkeit zu bestimmen
6. Ergebnisse
7. Zeitaufwand
8. Interpretation der Ergebnisse
9. Quellen

Downloads:
https://github.com/Jomelo/Kicker-Geschwindigkeitsmessung
300_d_Feldkämper-x_Geschwindigkeitserfassung am Tischfußball_1a.pdf

Funktionsbeschreibung:
Die Geschwindigkeit kann über verschiedene Wege mit der Hilfe von Lichtschranken ermittelt werden.
1. Möglichkeit:
Messung mit zwei Lichtschranken in dem Abstand zwischen den Lichtschranken bekannt ist. (Abstand L1 <-> L2)
2. Möglichkeit:
Messung mit einer Lichtschranke in dem die Größe des zu messenden Objektes bekannt ist. (Objekt Größe)
3. Möglichkeit:
Messung mit zwei Lichtschranken in dem die Größe des zu messenden Objektes bekannt ist. (Objekt Größe)
Aus den beiden Geschwindigkeit wird der Mittelwert gebildet.
4. Möglichkeit:
Messung mit zwei Lichtschranken in dem die Größe des zu messenden Objektes und der Abstand zwischen den beiden Lichtschranken bekannt ist. (Abstand L1 <-> L2) && (Objekt Größe)
Aus den drei Geschwindigkeit wird der Mittelwert gebildet. Somit kann die Messung noch genauer vorgenommen werden.

Die verschieden Möglichkeiten können über ein LCD Menü eingestellt werden auf das ich weiter unten eingehe.

Die Geschwindigkeiten werden mit einer Genauigkeit von zwei Nachkommastellen gemessen.

Die beste Geschwindigkeit wird dauerhaft unter der aktuellen und zuletzt Gemessenen Geschwindigkeit als Vergleichswert angezeigt.
Die besten 3 Geschwindigkeit werden nicht flüchtig gespeichert und können auch zu späteren Zeitpunkt über den Menüpunkt "Bestenliste" eingesehen werden.

Unter den Einstellungen kann man die Objekt größe sowie den Abstand zwischen den Lichtschranken einstellen. Die Einstelung lässt einen Bereich zwischen maximal 99,999 cm und minimal 0,009 cm zu.
Je nachdem wieviele Lichtschranken eingesteckt und welche Einstellungen getroffen werden ergeben sich oben die 4 Möglichkeiten wie die Geschwindigkeit bestimmt wird.

Die Lichtschranken lassen sich während des Betriebes an und ab stecken. Es wird solange man im Hauptmenü ist und die Messung neu startet die richtige Möglichkeit aus automatisch ausgewählt.

Damit die Lichtschranken (Infrarot) leichter genau eingestellt werden können, gibt es im Menü die Funktion Kalibrierung. Hierbei wird überprüft ob die Lichtstrecke zwischen den Lichtschranken in Ordnung ist. Wenn ja wird "ok" angezeigt. Wenn dies nicht der Fall ist, wird "nicht ok" angezeigt.
Im nächsten Punkt der Kalibrierung muss man objekte durch die Lichtschranken ziehen. Jedes Objekt wird gezählt. Wenn bei schnellen Bewegungen der Counter nicht hochzählt sind die Lichtschranken nicht genau justiert und müssen genauer eingestellt werden.
Wenn die Kalibrierung nicht erfolgreich abgeschlossen wird, kann keine genaue Geschwindigkeit gemessen werden.

Über eine Tastatur lässt sich ein Menü mit verschiedenen Ebenen bedienen. Hinter jedem Button befindet sich entweder eine neue Ebene oder eine Funktion die Ausgeführt wird.

Die Menü Struktur ist wie folgt aufgebaut:
1. Start
2. Bestenliste
3. Information
4. Einstellungen
4.1. Objekt Länge
4.2. Abstand Lichtschranke 1 zu Lichtschranke 2 (L1<->L2)
4.3. Kalibrierung
4.4. Bestenliste zurücksetzen.
4.5. Werkseinstellungen

Um alle Details des Projektes zu verstehen oder um es nachbauen zu können sollte man sich das oben verlinkte PDF Dokument durchlesen. Alles (Verdrahtungspläne, Libs, Software, Kosten, Bilder) befindet sich in diesem Dokument.

Es hat sich am Ende des Projektes herausgestellt, dass sich nicht nur die Geschwindigkeit von Bällen gut bestimmen lassen, sondern von beliebigen Objekten (RC - Autos, Fahrrädern, ...).
Der Messbereich liegt zwischen 0,01 - 99,99 km/h.
Mit einer Maximalen Abweichung von
2,5 % ab 90 km/h
1,5 % ab 60 km/h
0,5 % ab 50 km/h
<0,5 % unter 50 km/h

Es befindet sich sehr viele Bilder zu allen Schritten im PDF Dokument.




https://github.com/Jomelo/Kicker-Geschwindigkeitsmessung




https://forum.arduino.cc/index.php?topic=73751.msg554584#msg554584




Geschwindigkeitsmessung mit Arduino

Doppler-Radar-Geschwindigkeitsmessung - von H.-J. Berndt



Um eigene Lötarbeiten zu vermeiden, wurde ein fertiges Modul (links) mit Verstärkerplatine bei weidmann-elektonik.de geordert (rechts das HC-06 Bluetooth-Modul). Die stilvolle Platine passt sich dem Modul völlig an. Dort im Shop gibt es auch noch weitere 'nützliche' Dinge ...

Mit dem IPM-165 - 24 GHz Mono-CW-Radarsensor bietet InnoSenT GmbH ein interessantes Radar-System an. Der Sensor arbeitet als Dauerstrichradar (Continous Wave) und hat einen analogen Ausgang, der mit 300 mV angegeben ist.
Das Doppler-Prinzip kommt aus der Wellenlehre und nutzt bei bewegten Gegenständen die Frequenzänderung. Im Straßenverkehr wurde/wird dieses Verfahren bei Geschwindigkeitskontrollen eingesetzt. Wenn ein Sender eine Welle ausstrahlt und diese, von einem bewegten Gegenstand reflektiert, wieder empfangen wird, entsteht die so genannte Doppler-Frequenz bzw. eine Frequenzdifferenz zwischen Sende- und Empfangsfrequenz. Diese Frequenz liefert das Modul an seinem Analog-Ausgang. Bei 24 GHz berechnet sich 44 Hz pro 1 km/h.


http://www.hjberndt.de/soft/radar/index.html







Arduino Bike Speedometer

https://www.instructables.com/id/Arduino-Bike-Speedometer/
https://www.instructables.com/id/Arduino-Bike-Speedometer/

Arduino Based Speed Detector

http://www.mikechambers.com/blog/2010/08/11/accelerate-flash-arduino-based-speedometer/



https://forum.arduino.cc/index.php?topic=396341.0




Ereignisse zählen


http://arduino-basics.com/schaltungen/ereignisse-zaehlen/


Tastenbetätigungen zählen / entprellen

Ziel:
Die Anzahl von Tastenbetätigungen sollen gezählt und ausgegeben werden.
Für die Ausgabe der Zahl der Tastenbetätigungen wird das von früheren Experimenten her bekannte LCD-Shield benutzt.

Problem:
Das Betätigen einer Taste beinhaltet einen störenden Effekt, der sich "Prellen" nennt.
Statt des sofortigen elektrischen Kontaktes kommt es zum mehrfachen Schließen und öffnen.
Unser Arduino arbeitet so schnell, das z. B. das beim Zählen von Tastenbetätigungen jeder einzelne Prellvorgang mitgezählt werden würde.

Lösung:
Entprellen mittels Schaltungen, die Kondensatoren enthalten (Tiefpassfilter)
Oder einfacher: mit geschickt geschriebenem Programmcode

Schaltung:
Auf den Arduino stecken wir das LCD-Shield und verbinden einen Taster an den Eingang Analog_5 (=Digital19) und GND.

Programm:
Mit Hilfe eines Merkers ("set"), einer Zeitverzögerung (die länger als der Prellvorgang ist) und geschicktem Code wird hier zuverlässig jede Tastenbetätigung gezählt.
Man darf auch gerne die Taste dauerhaft drücken - es wird dann nicht weiter gezählt.

Sketch

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);

int taste = 19; // Taste an Analog_5 = Digital_19
int zaehler = 0;
int set = 0; // soetwas nennt man auch "Merker"

void setup()
{
  lcd.clear();      // LCD löschen
  lcd.begin(16, 2); // verfügbare Spalten und Zeilen

  pinMode(taste, INPUT); // Eingang, an der die Taste hängt
  digitalWrite(taste, HIGH); // Für echtes High bei geöffneter Taste sorgen
}


void loop()
{
 
  if (digitalRead(taste) == LOW && set == 0) {
    zaehler++;
    lcd.setCursor(6,0);
    lcd.print( zaehler );
    set=1;
  }
 
  if (digitalRead(taste) == HIGH && set == 1) {
    delay(250);
    set=0;
  }

}



Quelle:
http://www.sachsendreier.com/
http://www.arduinospielwiese.de/





Arduino Uno Tutorial für die erste Benutzung von Christian Sommer


MC1_Skript_Arduino_Tutorial - Arduino Uno Tutorial für die erste Benutzung_1a.pdf

https://esg-bretten.de/home.html





Arduino als Zähler

Arduino als Zähler – profhof.com


Ereignis-Zähler

Impulse einer Lichtschranke zählen


Impuls-Zähler pro Zeit

Frequenz-Zähler





http://profhof.com/arduino-als-frequenzzaehler/



Infrarot Lichtschranke mit Arduino zum Auslesen des Stromzählers
Elektromagnetische Ferraris-Stromzähler kommen noch in vielen Haushalten zur Verbrauchsmessung zum Einsatz.
Sie besitzen keine direkte Schnittstelle zur elektronischen Datenerfassung.
Auf der anderen Seite hilft jedoch eine präzise und minutengenaue Erfassung des Stromverbrauchs beim Energiesparen, da sich so Standbyverbrauch und Lastspitzen besser analysieren lassen.
Eine Möglichkeit, dennoch an diese Daten zu kommen, besteht in der optoelektronischen Abtastung der Zählscheibe.
Die Signalerfassung erledigt dabei ein Arduino Nano.



Arduino Lichtschranke



Die eigentliche Lichtschranke besteht aus einer Infrarot-Leuchtdiode SFH 409 (alternativ: SFH 4346) und einem Infrarot-Fototransistor SFH 309 FA (Abb. 1). Die Ansteuerung erfolgt mit einem Arduino Nano. Prinzipiell sind natürlich auch andere Modelle des Arduino geeignet, der Nano kommt hauptsächlich wegen seiner geringen Abmessungen zum Einsatz. Die Anschlussbezeichnungen in Abb. 1 beziehen sich direkt auf die Beschriftung des Arduino Boards.


Abb. 1: Schaltbild der Infrarot-Reflex-Lichtschranke

Gegenüber einem «herkömmlichen» Aufbau einer Lichtschranke mit analogen Triggerschaltkreisen oder gar diskreten Transistoren bietet die Verwendung eines Mikrocontrollers viele Vorteile. So sind neben den beiden Infrarot-Bauelementen nur zwei weitere passive Bauteile notwendig: Ein Widerstand von 120 Ω dient zur Begrenzung des Stroms durch die Leuchtdiode und der Widerstand 2,2 kΩ wandelt den durch den Fototransistor fließenden Strom in eine Spannung um. Sie gelangt direkt an den Analogeingang A7 des Arduino.

Die Anode der Leuchtdiode ist nicht direkt mit der Betriebsspannung V5V, sondern mit dem Digitalausgang D2 verbunden. Dadurch lässt sich eine wirksame Unterdrückung von störender Umgebungsstrahlung erreichen. Das Messprogramm schaltet sehr schnell über D2 die Leuchtdiode an und aus und misst jeweils die an A7 entstehende Spannung. Die anschließende Differenzbildung eliminiert das auf den Sensor treffende Umgebungslicht, das Resultat enthält ausschließlich das von der Leuchtdiode erzeugte Licht. Dieses Messprinzip ließe sich ohne einen Mikrocontroller nur sehr aufwändig realisieren.

Die beiden weiteren Bauelemente LED grün und Widerstand 560 Ω sind für die eigentliche Funktion der Lichtschranke nicht erforderlich. Sie dienen ausschließlich zur visuellen Rückmeldung der korrekten Funktion des Gerätes. Abgleichwiderstände oder Potentiometer sucht man in der Schaltung vergeblich. Die Einstellung der Triggerpegel zur Anpassung der Lichtschranke an unterschiedliche Umgebungen erfolgt per Software.

Der Preis für einen Arduino Nano bewegt sich zwischen 8 US $ für einen «China-Klon» und 50 €. Beim Einkauf lohnt daher ein Preisvergleich! Man muss auch keinen Nano nehmen, wenn man genügend Platz hat, lässt sich durchaus ein anderes Modell verwenden.


arduino_sketch/ReflectorLightBarrier.ino

/*
* Program to read the electrical meter using a reflective light sensor
* This is the data acquisition part running on an Arduino Nano.
* It controls the infrared light barrier, detects trigger
* and communicates with a master computer (Raspberry Pi)
* over USB serial.

* Copyright 2015 Martin Kompf
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/



#include <avr/eeprom.h>
const int analogInPin = A7; // Analog input pin that the photo transistor is attached to
const int irOutPin = 2; // Digital output pin that the IR-LED is attached to
const int ledOutPin = 12; // Signal LED output pin

int sensorValueOff = 0; // value read from the photo transistor when ir LED is off
int sensorValueOn = 0; // value read from the photo transistor when ir LED is on


                                                       // command line
#define MAX_CMD_LEN 80
char command[MAX_CMD_LEN];     // command buffer
int inCount = 0;                               // command buffer index
boolean cmdComplete = false;


                                                  // Mode of serial line:
                                                // C - command, D - data output
char mode = 'D';


                                             // Data output mode:
                                          // R - raw data
                                             // T - trigger events
                                             // C - counter
char dataOutput = 'T';


                                              // trigger state and level
int triggerLevelLow;
int triggerLevelHigh;
boolean triggerState = false;


                                               // Address of trigger levels in EEPROM
uint16_t triggerLevelLowAddr = 0;
uint16_t triggerLevelHighAddr = 4;


/**
* Set trigger levels (low high) from the command line
* and store them into EEPROM
*/
void setTriggerLevels() {
char *p = &command[1];
while (*p != 0 && *p == ' ') {
++p;
}
char *q = p + 1;
while (*q != 0 && *q != ' ') {
++q;
}
*q = 0;
eeprom_write_word(&triggerLevelLowAddr, atoi(p));


p = q + 1;
while (*p != 0 && *p == ' ') {
++p;
}
q = p + 1;
while (*q != 0 && *q != ' ') {
++q;
}
*q = 0;
eeprom_write_word(&triggerLevelHighAddr, atoi(p));
}



/**
* Read trigger levels from EEPROM
*/
void readTriggerLevels() {
triggerLevelLow = (int)eeprom_read_word(&triggerLevelLowAddr);
triggerLevelHigh = (int)eeprom_read_word(&triggerLevelHighAddr);
Serial.print("Trigger levels: ");
Serial.print(triggerLevelLow);
Serial.print(" ");
Serial.println(triggerLevelHigh);
}


/**
* Detect and print a trigger event
*/
void detectTrigger(int val) {
boolean nextState = triggerState;
if (val > triggerLevelHigh) {
nextState = true;
} else if (val < triggerLevelLow) {
nextState = false;
}
if (nextState != triggerState) {
triggerState = nextState;
Serial.println(triggerState? 1 : 0);
// control internal LED
digitalWrite(ledOutPin, triggerState);
}
}


/**
* Read one line from serial connection and interpret it as a command
*/
void doCommand() {
                                                         // print prompt
Serial.print(">");
while (! cmdComplete) {
                                                           // read input
while (Serial.available()) {
                                                        // get the new byte:
char inChar = (char)Serial.read();
if (inChar == '\n' || inChar == '\r') {
command[inCount] = 0;
Serial.println();
cmdComplete = true;
break; // End of line
} else if (inCount < MAX_CMD_LEN - 1) {
command[inCount] = inChar;
inCount++;
                                                              // echo
Serial.print(inChar);
}
}
}


                                                               // interprete command
switch (command[0]) {
case 'D':
                                                                // start raw data mode
mode = 'D';
dataOutput = 'R';
break;
case 'T':
                                                              // start trigger data mode
mode = 'D';
dataOutput = 'T';
break;
case 'S':
                                                              // set trigger levels
setTriggerLevels();
readTriggerLevels();
break;
}


                                                             // clear command buffer
command[0] = 0;
inCount = 0;
cmdComplete = false;
}



/**
* Setup.
*/
void setup() {
                                                             // initialize serial communications at 9600 bps:
Serial.begin(9600);
                                                            // initialize the digital pins as an output.
pinMode(irOutPin, OUTPUT);
pinMode(ledOutPin, OUTPUT);
                                                             // read config from EEPROM
readTriggerLevels();
}



/**
* Main loop.
*/
void loop() {
if (mode == 'C') {
doCommand();
} else if (mode == 'D') {
if (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == 'C') {
                                                            // exit data mode
mode = 'C';
}
}
}
if (mode == 'D') {
                                                    // perform measurement
                                                    // turn IR LED off
digitalWrite(irOutPin, LOW);
                                                     // wait 10 milliseconds
delay(10);
                                                         // read the analog in value:
sensorValueOff = analogRead(analogInPin);
                                                     // turn IR LED on
digitalWrite(irOutPin, HIGH);
delay(10);
                                                    // read the analog in value:
sensorValueOn = analogRead(analogInPin);


switch (dataOutput) {
case 'R':
                                                    // print the raw data to the serial monitor
Serial.println(sensorValueOn - sensorValueOff);
break;
case 'T':
                                                // detect and output trigger
detectTrigger(sensorValueOn - sensorValueOff);
break;
}
}
delay(10);
}
 



https://github.com/skaringa/emeir/blob/master/arduino_sketch/ReflectorLightBarrier.ino
https://www.kompf.de/tech/emeir.html




ARDUINO Tropfenzähler Personenzähler

https://forum.arduino.cc/index.php?topic=437466.0


Tropfenzähler Teil 1

Die verwendete Lichtschranke besitzt eine Weite von 10 mm. Datenblatt Die Firma Sparkfun bietet ein Breakoutboard an, dem die geeignete Belegung und der Vorwiderstand (220 Ω) für die Verwendung mit dem Arduino UNO oder MEGA zu entnehmen ist.


dropcounter
/***************************************************/
int photoInterrupterPin = 2;          // Signal der Gabellichtschranke, Pegel bei Unterbrechung des Lichtweges "low" sonst "high"                  
int interruptNumber = 0;              // Pin 2 des Arduino Uno / Mega ist mit Interruptnummer 0 verbunden
int dropsPM = 0;                      // Ergebnisangabe in Tropfen pro Minute
volatile int dropNumber = 0;          // Variable zum Speichern der Tropfenzahl. "volatile" gewährleistet saubere Übergabe
int tempDropNumber = 0;               // dient zur Zwischenspeicherung der Tropfenzahl
volatile unsigned long deltaTime = 0; // Zeitabstand zwischen 2 aufeinanderfolgenden Unterbrechungen
volatile unsigned long lastInterruptTime = 0;  // Zwischenspeicherung des letzten Aufrufzeitpunktes
/***************************************************/
void setup()                                                   // Initialisierung der Pins, Einhängen und Typisieren des Interrupts
{
  pinMode(photoInterrupterPin, INPUT);                         // Pin 2 als Eingang definieren
  attachInterrupt(interruptNumber, interruptroutine, FALLING); // Immer wenn an Pin 2 der Pegel fällt, löst das Interrupt 0 aus
                                                               // und die Funktion "interruptroutine" wird aufgerufen
  Serial.begin(38400);                                         // Kommunikation mit Baudrate von 38400 initialisieren
                                                               // langsamere Geschwindigkeiten führen zu Datenverlusten
}
/***************************************************/
void loop()                                                    // Hauptprogrammschleife
{
  if ((dropNumber > tempDropNumber) and (dropNumber > 1))      // Hat sich die Tropfenzahl erhöht?
  {                                                            // Zeit zwischen 2 Tropfen nur bei mehr als 1 Tropfen sinnvoll
    dropsPM = 60000 / deltaTime;                               // 60000 ms = 1 Minute / Zeitdifferenz zwischen 2 Tropfen
    deltaTime = 0;                                             // Zeitdifferenz wieder auf Null setzen
    tempDropNumber = dropNumber;                               // Aktuelle Tropfenzahl zwischenspeichern
    Serial.println(dropNumber);
    Serial.print("Tropfen pro Minute: ");
    Serial.println(dropsPM);
  }  
  delay(5);                                                    // 5 ms warten. Das entspricht ebenfalls der Wartezeit der
                                                               // Interruptroutine. Es geht also keine Zeit verloren.
}
/******************************************************/
void interruptroutine()                                        // Wird aufgerufen, immer wenn der Pegel an Pin 2 abfällt.
{
  unsigned long        interruptTime = millis();               // Zeitpunkt zu dem der Interrupt aufgerufen wird
  deltaTime = interruptTime - lastInterruptTime;               // Da erst ab dem 2. Tropfen gezählt werden soll, gibt es
                                                               // einen vorangegangenen Zeitpunkt eines Interuoptaufrufs
    if (deltaTime > 5)                                         // Zeit zwischen 2 aufeinander folgenden Dropfen muss 5 ms
    {                                                          // überschreiten (verhindert Nebenefekte der Hardware)
      dropNumber++;                                            // Tropfenzahl wird um "1" erhöht wenn der Abstand zwischen
    }                                                          // 2 Ereignissen länger als 5 ms war.
    else                                                       // sonst
    {                                                          // war 's wohl ein Fehler und
      deltaTime = 0;                                           // der Zeitabstand wird auf "0" zurückgesetzt
    }  
    lastInterruptTime = interruptTime;                         // Zeitpunkt des aktuellen Pegelwechsels wird zwischengespeichert.
}


http://technik-garage.de/tropfenzaehler-teil-1/





// Testprogramm Gabellichtschranke

int Led13 = 13;
int signalSchranke = 2;
int val;

void Setup () // Pins und Co initialisieren
{
pinMode Led13, OUTPUT); // Digitalpin 13 als Ausgang schalten
pinMode (signalSchranke, INPUT); // Digitalpin 2 als Eingang schalten
}

void Loop ()
{
val = digitalRead(signalSchranke);
if (val == HIGH)
{
digitalWrite (Led13, HIGH);
}
else
{
digitalWrite (Led13, LOW);
}
}

Für erste Gehversuche eignet sich auch das Breakoutmodul KY-010.

https://tkkrlab.nl/wiki/Arduino_KY-010_Optical_broken_module




http://technik-garage.de/tropfenzaehler/






https://forum.arduino.cc/index.php?topic=76565.0






Lichtschranke (mit dem Arduino)



https://www.kollino.de/elektronik/lichtschranke-mit-dem-arduino/







Counter - Timer als Counter
Timer als Zähler
Ein Timer wird normalerweise durch einen internen oder externen Takt weitergezählt.
Man kann einen Timer auch so konfigurieren, dass extern anliegende Signale gezählt werden z.B.
Rundenzähler bei einer Autorennbahn mit Timer als Counter.
Seite 257
http://profhof.com/arduino-als-frequenzzaehler/


Frequenzzähler
Hier wird das Prinzip eines Frequenzmessers dargestellt.
Es werden 1 Sekunde lang die eingehenden Impulse gezählt und — in diesem Fall seriell — ausgegeben.
Ähnlich ließe sich auch ein Fahrradcomputer oder ein Geschwindigkeits- und Rundenmesser für eine
Autorennbahn bauen.
Eine Ausgabe auf LC-Display oder mit Siebensegmentanzeigen ist selbstverständlich ebenso möglich.
Seite 258



Drehimpulsgeber  -  ENCODER
Ein Drehimpulsgeber — auch Encoder genannt — besteht im Prinzip aus zwei Tastern, die bei Drehung versetzte Impulse erzeugen.
Aus der Art der Versetzung kann man auf die Drehrichtung schließen.
Drehimpulsgeber werden häufig als eleganter Ersatz von Potenziometern verwendet — signalisieren aber keine absolute Dreh-Einstellung sondern die Drehrichtung und die Drehgeschwindigkeit.
Der jeweils zuletzt eingestellte Wert muss ggf. aus dem EEPROM gelesen werden oder man beginnt bei einem Neustart mit Standardwerten.
Oft haben Drehencoder zusätzlich eine Tasterfunktion, die beim Drücken auf die Achse aktiviert wird.

ENCODER
variable = ENCODER ( pinl, pin2, linkslabel, rechtslabel, modus)
pin1 und pin2 sind zwei verschiedene Pins eines beliebigen Ports.
pin2 und pin2 müssen als Input definiert sein und (interne) Pullupwiderstände haben.
Seite 297


Nr. 33 – Der Rotary Encoder KY-040



#include <Encoder.h>    // Verwendung der <Encoder.h> Bibliothek const int CLK = 6;      // Definition der Pins. CLK an D6, DT an D5. const int DT = 5;const int SW = 2;       // Der Switch wird mit Pin D2 Verbunden. ACHTUNG : Verwenden Sie einen interrupt-Pin!long altePosition = -999;  // Definition der "alten" Position (Diese fiktive alte Position wird benötigt, damit die aktuelle Position später im seriellen Monitor nur dann angezeigt wird, wenn wir den Rotary Head bewegen)Encoder meinEncoder(DT,CLK);  // An dieser Stelle wird ein neues Encoder Projekt erstellt. Dabei wird die Verbindung über die zuvor definierten Varibalen (DT und CLK) hergestellt.void setup()   // Beginn des Setups{  Serial.begin(9600);       pinMode(SW, INPUT);   // Hier wird der Interrupt installiert.    attachInterrupt(digitalPinToInterrupt(SW), Interrupt, CHANGE); // Sobald sich der Status (CHANGE) des Interrupt Pins (SW = D2) ändern, soll der Interrupt Befehl (onInterrupt)ausgeführt werden.}void loop(){    long neuePosition = meinEncoder.read();  // Die "neue" Position des Encoders wird definiert. Dabei wird die aktuelle Position des Encoders über die Variable.Befehl() ausgelesen.         if (neuePosition != altePosition)  // Sollte die neue Position ungleich der alten (-999) sein (und nur dann!!)...        {        altePosition = neuePosition;               Serial.println(neuePosition);      // ...soll die aktuelle Position im seriellen Monitor ausgegeben werden.        }}void Interrupt() // Beginn des Interrupts. Wenn der Rotary Knopf betätigt wird, springt das Programm automatisch an diese Stelle. Nachdem...{  Serial.println("Switch betaetigt"); //... das Signal ausgegeben wurde, wird das Programm fortgeführt.}

https://funduino.de/nr-32-der-rotary-encoder-ky-040




Quelle:
www.bascom-buch.de









DIN A4  ausdrucken
********************************************************I*
Impressum: Fritz Prenninger, Haidestr. 11A, A-4600 Wels, Ober-Österreich, mailto:[email protected]
ENDE