ARDUINO Sketch

http://sites.schaltungen.at/arduino-sketch/arduino-sketch

http://www.linksammlung.info/

http://www.schaltungen.at/

                                                                                             Wels, am 2018-05-20

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.sketch/arduino.sketch (xx Seiten)_1a.pdf




Computergestützte Experimente mit ARDUINO UNO R3
                                              in Europa
Genuino Uno R3
8-bit Mikrocontroller
https://de.wikipedia.org/wiki/Arduino_(Plattform)

ARDUINO / Genuino 101 - mit integrierte Bluetooth-Technik
SoC Mikrocontroller mit zwei 32-bit Cores (x86-Technik) der 101 ist eher ein PC als ein einfaches Mikrocontroller-Board wie der UNO
10x soviel Speicher als der UNO
https://www.elektormagazine.com/news/first-steps-with-arduino-genuino-101


Beschreibung
Das Genuino 101 Entwicklungsboard welches die Leistung und den niedrigen Energieverbrauch sowie die erweiterten Eigenschaften des Intel Curie Moduls mit der Einfachheit von Arduino zu einem niedrigen Einstiegspreis bietet.

Das Genuino 101 Entwicklungsboard ist der ideale Nachfolger von UNO und mit der neuesten Technik ausgerüstet.
Diese erkennt Bewegungen und ist mit einem 6-achsigen Beschleunigungsmesser und Gyroskop ausgestattet.
Über Bluetooth und ein Smartphone können Sie Ihre Erfindungen sogar fernsteuern!

Der robuste Formfaktor und das Zubehör von UNO bleiben Ihnen erhalten.
Zusätzlich können Sie Bluetooth Low Energy sowie den Beschleunigungsmesser und das Gyroskop mit 6 Achsen nutzen, die auf der Platine integriert sind.
Damit können Sie Ihrer Kreativität in der vernetzten Welt freien Lauf lassen.

Das Modul enthält zwei Prozessorkerne:
Einen x86-Quark und einen ARC, die beide auf 32 MHz eingestellt sind.
Der Quark-Prozessor läuft auf dem RTOS ViperOS und unterstützt den Arduino-Prozessor bei der Erledigung der schwierigsten Aufgaben.
Das Modul besitzt 14 digitale Ein- und Ausgangskontakte, von denen 4 als PWM-Ausgänge genutzt werden können, 6 analoge Eingänge, einen USB-Anschluss für das Hochladen von Programmen
und serielle Kommunikation, einen Stromanschluss sowie eine ICSP-Einheit mit SPI-Signalen und Kontakten für I²C.
Die Spannungen zur Versorgung des Betriebs und der Ein- und Ausgabe des Moduls betragen 3,3 Volt, wobei alle Kontakte gegen eine Überspannung von 5 Volt geschützt sind.
Das Genuino 101 Entwicklungsboard wurde in Zusammenarbeit mit Intel entwickelt.
 
Ausführung
Bluetooth® LE
6-Achsen Accelerometer/Gyro.
2 Prozessorkerne mit 32 MHz


Technische Daten
Mikrocontroller                       : Intel Curie
Betriebsspannung                  : 3.3 V (5 V-tolerante I/Os)
Eingangsspanung (empfohlen) : 7 - 12 V
Eingangsspanung (Limit)         : 6 - 20 V
Digitale I/O-Pins                     : 14 (davon 4 als PWM-Ausgang)
PWM-Digital-I/O-Pins              : 4
Analog-Input-Pins                   : 6
Serielle I/Os                           : 1 UART, 1 SPI, 1 I²C
DC-Strom pro I/O-Pin              : 7 mA
Flash-Memory                        : 384 kB (196 kB verfügbar für Sketch)
SRAM                                   : 80 kB (24 kB verfügbar für Sketch)
Onboard-Flash                       : 2 MB
Takt-Frequenz                        : 32 MHz

Typ                      : Genuino 101 ATLASEDGE.2
Hersteller             : Genuino
Kategorie             : Entwicklungsboard
Architektur           : 32-bit
Serie (Entwicklungs-Kits)             : Genuino
Serie (Embedded Mikrocontroller) :  Intel Quark
Technologie          : 32-bit MCU
Tool-Typ : Entwicklungs-Starter-Kit
Betriebsspannung : 3.3 V
Betriebsspannungsbereich : 7,0V bis 12 V
Abmessung                      : 68,6 x 54,3 mm
Quelle:
https://www.generationrobots.com/de/402563-genuino-101.html

Entwicklungsboard Genuino 101
CONRAD Bestell-Nr.: 1409250-62 € 45,-

Daher wollen Arduino und Intel den von Arduino-Mitgründer David Cuartielles entwickelten Physical-Computing-Kursus
"Creative Technologies in the Classroom" (CTC) für 11- bis 14-Jährige mit neuen Inhalten zum Genuino 101 ergänzen und stärker verbreiten.
Quelle:
https://store.arduino.cc/genuino-101#documentation


********************************************************I*

Multi Function Shield

In Ausgabe Make: 2/2018 der Make stellen wird das Multi Function Shield vor.

Das Multi Function Shield in Fritzing
Für das Multi-Function-Shield für Arduino, das wir in Heft 2/2018 vorstellen, gab es bisher kein Bauteil für den beliebten Schaltplaneditor Fritzing.

Wir haben uns nun rangesetzt und ein entsprechendes Bauteil für die Steckbrett-Ansicht (Breadboard) erstellt und bieten es als Download an:
Download Fritzing Part: Multi Function Shield

Sämtliche Kontakte an den Stiftleisten, Jumper und Buchsen sind als Anschlüsse vorhanden und können somit per Verbindung (Wire/Draht) an andere Bauteile angeschlossen werden.
Soll beispielsweise für den Betrieb ein Jumper auf J2 gesteckt sein, so kann zwischen den beiden Pins eine Verbindung eingezeichnet werden.
Um das neue Bauteil in Fritzing zu importieren, klicken Sie nach dem Download der Bibliothek
oben rechts in der Bauteilliste auf das (sehr kleine) Menü-Symbol (Pfeil in der Abbildung) und wählen Importieren.
Wählen Sie die herunter geladene Datei aus und anschließend steht das Bauteil zur Verfügung.
Beim Beenden von Fritzing werden Sie später einmalig gefragt, ob Sie die Bauteile in Ihrer Sammlung behalten wollen, was Sie bestätigen.
Im Forum können Sie sich mit anderen Nutzern austauschen und Ihre Projekte vorstellen.Quelle:
https://www.heise.de/make/artikel/Fritzing-Part-fuer-das-Multi-Function-Shield-4031506.html



********************************************************I*
                  Wird zum Experimentieren gebraucht 
Fa. Neuhold Graz oder Fa. CONRAD Linz

Simpleduino UNO (Arduino UNO Nachbau)  mit Mikrocontroller ATmega328p
BreadBoard

4 Kanal Relais-Modul
Ultraschall Messmodul HC-SR04

Fotowiderstand LDR03  500 k
Temperatursensor KTY81/222  KTY81-22
Luft-Feuchtigkeitssensor und Temperatursensor AM2301
Luftdrucksensor BOSCH  BMP180
Gyro- und Beschleunigssensor MPU-6050
GY-521 Breakout Board mit eingebauten MPU6050
3 Achsen Magnetometer HMC5883L
GY-273 Breakout Board mit eingebauten HMC5883L

LCD Display 16x2 mit I²C Modul

Schrittmotor DAYPOWER S-SPSM-5V
Schrittmotor 28BYJ-48 mit Treiberplatine
mini Taster

Widerstands Sortiment  160R  10k
Potentiometer 10k
Elektrolytkondensatoren Sortiment

Drahtbrückenset mit Box
Jumper Wires male
Jumper Wires female
Gesamtsumme  € 98,24

Quelle:
300_d_Pfannhofer-x_Diplomarbeit - Computergestützte Experimente mit ARDUINO UNO (121 Seiten)_1a.pdf




********************************************************I*
           Funduino - Anleitungen für ARDUINO UNO

Anleitungen

Anleitungen für Zubehör


Quelle:
https://funduino.de/nr-9-temperatur-messen


Vergleich von Temperatursensoren für den Arduino

Sensor          Temperaturmessbereich    Toleranz           
LM35DZ            0°C .. +100°C                ±0,4°C
DS18B20       -55°C .. +125°C                ±0,5°C
LM393           +20°C .. +80°C                  keine Angaben
DHT11               0°C .. +60°C                  ±2°C
DHT22           -40°C .. +80°C                  ±0,5°C
BME280         -40°C .. +85°C                  keine Angaben
SHT21           -40°C .. +125°C                ±0,3°C


Quelle:
https://draeger-it.blog/vergleich-von-temperatursensoren/




********************************************************I*

1) Ein simpler Rechteckgenerator mit dem Arduino

tone(10, frequenz);
Es lassen sich Frequenzen von 31 Hz bis 65535 Hz erzeugen.
Mit der Arduino tone() Anweisung lassen sich Töne / Rechteckfrequenzen auf einem beliebigen digitalen Pin ausgeben.
Damit ist es sehr einfach einen Rechteckgenerator zu realisieren.

// Simpler Rechteckgenerator an Pin 10//// Matthias Busse Version 1.0unsigned int frequenz=10000;void setup() {  tone(10,frequenz);}void loop() {}


Quelle:
http://shelvin.de/ein-simpler-rechteckgenerator-mit-dem-arduino/



2) Den Frequenzzähler mit LCD Display auf der Platine aufgebaut.

Quelle:
http://shelvin.de/den-frequenzzaehler-mit-lcd-auf-platine-aufgebaut/






********************************************************I*
Vom Prinzip her brauchst du 2 Signale zu denen du jeweils die millis bzw mikros misst.
Die zwei Werte ziehst du von einenander ab.
Da auch die strecke von sensor 1 und sensor 2 bekannt ist kannst du dir die Geschwindigkeit ausrechnen lassen.


100 kmh sind ca. 33 m/s, 3,6 kmh (laaaangsamer Fußgänger) sind 1 m/s.
WENN Du den Abstand 330 mm machst, dann prescht ein schnelles Auto in 1/100 sek durch, ein Fußgänger in etwa 0,3 sek.
Beides ist für nen Mikrocontroller easy zu messen - mit ausreichender Genauigkeit.
ABER wenn das Auto in diesem Abschnitt etwas nickt (z.B. kleine Bodenwelle) dann kann der Lichtstrahl an den beiden Messpunkten an
ERHEBLICH unterschiedlichen Punkten des Autos abgeschattet werden => der Messwert ist recht ungenau.
Beim Fußgänger kann z.B. der Fuß (Schuh) gemessen werden - der bewegt sich abschnittweise
z.T. mit fast doppelter Geschwindigkeit des Menschen . . . .
Daher eben die genaue Planung der zu messenden Geschwindigkeitsbereiche, der Messstelle(n) und der zulässigen Toleranzen.

3) Ballgeschwindigkeitsmesser eines Tischfußball / Wuzzler / Tischkicker / Schussgeschwindigkeitsmesser

Mit nur einer Lichtschranke Balldurchmesser / Impulsdauer in micro-Sekunden
Bei diesem ARDUINO Sketch wird mithilfe einer Lichtschranke die Geschwindigkeit eines Tischkickerballs bestimmt.
Es wird dazu gemessen, wie lange der Fotowiderstand im Schatten des Balls liegt.
Besser mit Laserdiode rot 650nm 4,5V / 5mW  und Fotodiode BDW34
Laserdiode Rot 635 nm 5 mW IMM Photonics U-LD-630551A Conrad Bestell-Nr.: 505664 - 62
650nm Dm=6mm Ub=4.5V 5mW Rot Laserdiode / Lasermodul Diode Module Laser Dot Lase X5E9
Problem ist der Laserstrahl muß genau durch die Mitte der Kugel messen

Ich halte die Methode der Dunkelphasenmessung per LDR übrigens für falsch.
LDR Fotowiderstände reagieren zu langsam
Da gehört ein Laserlichtschranken hin mit Fototransistor und dann geht's !

Der Durchmesser des Balls  35mm  wird durch diese Impuls-Zeit geteilt.

20km/h = 20.000m/60 = 333.3m/min/60  = 5,555m/sec = 5,555mm/ms = 5,555um/us

35mm/5,555mm=6,3ms = 6.300us

Geschwindigkeit (m/s) = Weg/Zeit
Geschwindigkeit (m/h) = Balldurchmesser/Impulszeit x 3600 = 35mm / 6,3ms x 3600  = 20.000m/h = 20,0km/h





Quelle:
https://www.youtube.com/watch?v=m4gGomP5DC8






********************************************************I*

4) Geschwindigkeitsmessung mit Arduino über zwei Laserlichtschranken

z.B Paintball Geschwindigkeit oder Geschoss-Dm 5,5 bis 12mm

Benötigte Teile:
1 x Arduino UNO
1 x LCD-Modul 20x4
1 x I2C Interfacemodule für LCD
2 x Fotodiode BPW34
2 x Laser rot 650nm 4,5V / 5mWLichtleistung
2 x 100R..150R (als Vorwiderstand für Laser)
2 x 39k   (als Messwiderstand für Fotodiode)

Laser Ub = 3,5V / 15mA = 52,5mW        I = 5V - 3,5V / 100R = 15mA
Abstand der beiden Lichtschranken 91mm

650nm  5x6mm  4,5V 5mW rot Laserdiode Lasermodul Diode Module Laser Dot Laserdiodenmodul
https://www.amazon.de/650nm-Laserdiode-Lasermodul-Module-Laserdiodenmodul/dp/B00P7S708U/ref=sr_1_2?ie=UTF8&qid=1458478840&sr=8-2&keywords=5x+650

Fotodiode, Empfänger, BPW34
https://www.amazon.de/Unbekannt-Fotodiode-Empf%25e4nger-BPW-34/dp/B016YH71WW/ref=sr_1_1?ie=UTF8&qid=1458478915&sr=8-1&keywords=fotodiode+bpw34

niceeshop(TM) 2004 LCD Modul für Arduino 20x4 / weiß auf Blauer Schirm Basierend auf Der Beliebten HD44780 Controller
https://www.amazon.de/niceeshop-Arduino-Basierend-Beliebten-Controller/dp/B00MODAKM4/ref=sr_1_1?ie=UTF8&qid=1458479137&sr=8-1&keywords=2004+LCD+Modul

IIC/I2C/TWI/SP​​I Serial Interface Board Module für Arduino 1602LCD
https://www.amazon.de/Serial-Interface-Module-Arduino-1602LCD/dp/B00LVQ7MH6/ref=sr_1_4?ie=UTF8&qid=1458479205&sr=8-4&keywords=IIC%2FI2C

Details siehe
Quelle:
http://sites.schaltungen.at/sie-fahren-km-h/weidmann

Quelle:
https://www.youtube.com/watch?v=iMvzBdijVwU





5) Drehzahlmessung und Geschwindigkeit gemessen mit einem ARDUINO

Im Versuch simuliere ich die Drehzahl eines Fahrrades und die eines Sportwagens und berechne aus der Drehzahl und dem Reifenumfang die Geschwindigkeit in km/h.
Die Messwerte werden auf einer LCD-Anzeige ausgegeben und das Ausgangssignal des

Details siehe

Quelle:
http://sites.schaltungen.at/sie-fahren-km-h/weidmann

Quelle:
https://www.youtube.com/watch?v=oT7__vTji7o




6) Geschwindigkeismessung mit zwei Lichtschranken

Bauteile
1x ARDUINO UNO
2x IR-LED
2x IR-Fotodiode
2x 220R Widerstand
2x 100k
8x Steckkabel 0,64mm rot blau gelb grün


Quelle:
https://schuelerlabor.informatik.rwth-aachen.de/sites/default/files/dokumente/Station 3 - Geschwindigkeitsmessung.pdf




7) Micros - Zeiterfassung / Geschwindigkeitsmessung mit zwei Lichtschranken

Ich habe mir eine kleine Funktion zur Geschwindigkeitsmessung von Autos mittels zweier Lichtschranken zusammengebastelt, den Sketch habe ich dazu unten angehängt.
Jetzt habe ich das ganze mal mit einem fahrenden Auto ausprobiert und stieß dabei auf ein Problem.
Die Funktion micros() wirft bei mir bis zu einer ganzen Stelle unterschiedliche Werte aus,
z.B. 400345 und 40034. Woran liegt das?
Für die Geschwindigkeitsberechnung war ich eigentlich der Meinung mit 10^-6 umzurechnen, aber nur mit 10^-5 komm ich annähernd auf den genauen Wert!?
Ich weiß, dass es mit dem Arduino möglich ist auf 4 us bzw. auf 0.5 us genau die Zeit zu erfassen, bin mir aktuell nur nicht sicher ob ich irgendwo noch ein Denkfehler drinnen habe!?!
Ist für micros() die Schnelligkeit wichtig - Serial.begin(19200); ?

Verwendet wir ein Arduino Mega 2560 der neuesten Generation.

// Variablendeklaration
byte li_start = 2;  // Pin Lichtschranke Start
byte li_ende = 3; // Pin Lichtschranke Ende
unsigned long start = 0;
unsigned long ende = 0;
unsigned int zeit_signaldauer = 0;
boolean zeitmessung_aktiv = false;

float result;
int ergebnis;
String myString;

double v = 0; // unsigned long


void setup() {
  Serial.begin(19200);
  pinMode(2, INPUT); // Lichtschranke Beginn
  pinMode(3, INPUT); // Lichtschranke Ende
  attachInterrupt(0, startabfrage, FALLING);
  attachInterrupt(1, zeitmessung, FALLING);
  }
  
void loop(){
  
  v = (2.0 / (zeit_signaldauer * pow(10, -5) ) );                     // Durchschnittsgeschwindigkeit
  result = v + 0.5;
  ergebnis = (int)result;
  
  
  Serial.print("Startzeit: ");
  Serial.println(start);
  
  Serial.print("Zeitdifferenz: ");
  Serial.println(zeit_signaldauer);
  
  Serial.print("Geschwindigkeit: ");
  Serial.println(v);
  Serial.println(result);
  Serial.println(ergebnis);
  
  Serial.print("\n");
  delay(0);
  }
  
void startabfrage(){
  if(digitalRead(li_start) == LOW && zeitmessung_aktiv == false){
    start = micros();  // Aktueller Zeitwert
    zeitmessung_aktiv = true;
    }
    }
void zeitmessung(){
  if(digitalRead(li_ende) == LOW && zeitmessung_aktiv == true){
    //ende = micros();  // Aktueller Zeitwert
    zeit_signaldauer = micros() - start ;  // Berechnung Zeitdifferenz
    zeitmessung_aktiv = false;
    }
}



Wenn ich das richtig sehe dann gibst du die Werte immer aus...
Vielleicht nur dann ausgeben wenn eine Messung wirklich erfolgt ist was du durch ein weiteres Flag regeln kannst.

Start und Ende hast du richtigerweise als unsigned long definiert.
Die Differenz aus beiden (zeit_signaldauer) sollte dann auch unsigned long und nicht int sein.
Sonst gibt es nach 65536 µs u.U. einen Überlauf der int Variablen bei der Differenzbildung.

Hat hierzu noch jemand eine Ahnung:
Für die Geschwindigkeitsberechnung war ich eigentlich der Meinung mit 10^-6 umzurechnen, aber nur mit 10^-5 komm ich annähernd auf den genauen Wert!?

Ist für micros() die Schnelligkeit wichtig - Serial.begin(19200); ?




********************************************************I*
8) Geschwindigkeit messen mit Arduino



Was man immer schon wissen wollte..
Wie schnell sind die kleinen Rennautos.
Mit einem Arduino und wenigen Bauteilen kann man die Geschwindigkeit messen.
Die Bauteile sind praktisch in der Bastelkiste oder im Starter-Kit und kosten wenig, allerdings muss man etwas sägen und hämmern um es zu bauen.
Man braucht einen Laserpointer und eine Fotodiode wie etwa BPW34 (LDR geht sicher auch), dann ein paar Oberflächenspiegel, die sind aus einer alten Harddisk ausgebaut und sehen so aus wie eine glänzende CD.
Mit der Blechschere werden daraus zwei Segmente geschnitten, das sind die Spiegel zum Umlenken des Laserstrahls. Zwei Bretter braucht man auch noch um das zu befestigen.


Download: Speedy.zip

/*
Arduino Speedy
measure time and calculate speed
uses a laserpointer, 2 mirrors and a photodiode for light barrier

photodiode signal goes to Input Capture Pin on PB0, Arduino pin8
measures time from falling edge to next falling edge = total time
first measures time from falling edge to next rising edge = time1 (low time)
useful to abt 50 us, minimum low time is 4 us

serial output and LCD defined/not used

GS 3-2014

This is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
*/


//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);
/*
* 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
*/

#ifndef F_CPU
#define F_CPU 16000000L
#endif

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

int pinLed=13; // on board Led
int pinStart=9; // HIGH to measure, LOW to adjust
int pinTrig=8; // ICP pin input

volatile unsigned char p_mlt = 0; // Timer1 Overflows total
volatile unsigned char p_mlt1 = 0; // Timer1 Overflows low time
volatile unsigned char p_ready; // Flag
volatile unsigned int StartTime = 0; // ICP pin 1st edge falling
volatile unsigned int EndTime1 = 0; // ICP pin next edge rising
volatile unsigned int EndTime2 = 0; // ICP pin last edge falling

ISR( TIMER1_CAPT_vect )
{
static unsigned char edge = 0;

if( p_ready ) return; // wait until display done

if( edge == 0 ) // 1st edge falling
{
StartTime = ICR1;
TIMSK1 = 0; // stop Interrupts , Capture & Overflow
p_mlt = 0;
p_mlt1 = 0;
TCCR1B |= (1<<ICES1); // then change to rising
++edge; //
TIMSK1 = (1<<ICIE1) | (1<<TOIE1); // enable Interrupts , Capture & Overflow
}

else if( edge == 1 ) // 2nd edge rising
{
EndTime1 = ICR1; // time high
TIMSK1 = 0; // stop Interrupts , Capture & Overflow
p_mlt1 = p_mlt;
TCCR1B &= ~(1<<ICES1); // then change ICES1 to falling
++edge; //
TIMSK1 = (1<<ICIE1) | (1<<TOIE1); // enable Interrupts , Capture & Overflow
}

else if( edge == 2 ) // 3rd edge falling
{
EndTime2 = ICR1; // total time
p_ready = TRUE; // p_ready to display
edge = 0;
}
}

ISR( TIMER1_OVF_vect ) // count overflow
{
p_mlt++;
}

void setup() {
pinMode(pinLed, OUTPUT); // on board led
pinMode(pinStart, INPUT_PULLUP); // start Input Capture, pin9
pinMode(pinTrig, INPUT); // Input Capture Pin on PB0, pin8
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.print("Speed Counter");
Serial.begin(9600); // prepare for serial out
Serial.println("Pulsewidth to Speed");

TCCR1A = 0; //
TIMSK1 = (1<<ICIE1) | (1<<TOIE1); // 2 Interrupts: Capture & Overflow
TCCR1B &= ~(1<<ICES1); // ICES1 trigger on falling
TIMSK2 &= ~(1<<OCIE2A); // disable Timer2 Interrupt, millis
sei();
}

void loop()
{
char FString[12];
double myTime = 0.0;
double pwpercent = 0.0;
unsigned long pwidth;
unsigned long pwidth1;

if (digitalRead(pinStart) == HIGH) // start ISR else adjust
{

if( p_ready )
{
TCCR1B = 0; // stop Input Capture

pwidth1 = (p_mlt1 * 65536) + EndTime1 - StartTime;
Serial.print("PW low= ");
Serial.print(pwidth1); //PW1 in counts

pwidth = (p_mlt * 65536) + EndTime2 - StartTime;
Serial.print(" PWtotal= ");
Serial.print(pwidth); //PW total in counts
Serial.print(" PW % = ");
pwpercent = pwidth1*100.0/pwidth;
dtostrf( pwpercent, 5, 2, FString ); // 2 digits
Serial.println(FString); //PW in counts

myTime = pwidth/16.0 ; // in usec
dtostrf( myTime, 8, 2, FString ); // 2 digits

Serial.print("Time= ");
Serial.print(FString);
Serial.print(" usec ");
lcd.print(FString);

myTime = (p_mlt * 65536) + EndTime2 - StartTime;
myTime = (F_CPU *25.0)/ myTime; // 25cm / t
dtostrf( myTime, 8, 3, FString ); // 3 digits

Serial.print("Speed= ");
Serial.print(FString);
Serial.println(" cm/sec");
lcd.print(FString);
//
p_ready = FALSE;
digitalWrite(pinLed,!digitalRead(pinLed)); // blink Led 13 on board
TCCR1B = (1<<ICES1) | (1<<CS10); // enable Input Capture Edge, PreScale 1
TCCR1B &= ~(1<<ICES1); // ICES1 trigger on falling

} //if( p_ready )
}
else // stop to adjust
{
TCCR1B = 0;
digitalWrite(pinLed,digitalRead(pinTrig)); // Led 13 on board shows status
}

// delay(50);

}


Quelle:
http://www.elektronik-labor.de/Arduino/Speed.html



********************************************************I*
9) Tropfenzähler mit Gabellichtschranke
Der Tropfenzähler soll als einzelner Baustein aber auch als Teil des Fraktionssammlerprojektes verwendbar sein.
In Erweiterung seiner Verwendbarkeit soll er auch als Blasenwächter für Glas- oder Silikonschläuche verwendbar sein.
Lichtschranken können fallende Tropfen erkennen. Gabellichtschranken helfen Fehljustierungen zu vermeiden.
Ein Wassertropfen besitzt ein Volumen von etwa 50 µl und damit einen entsprechenden Durchmesser von mehreren Millimetern.
Elektronische Bauteile wie die Lichtquelle und der Lichtsensor der Lichtschranke sind unbedingt vor Feuchtigkeit zu schützen.
Dieser Schutz kostet Spaltbreite / Raum.

Die Gabellichtschranke GP1A57HRJ00F besitzt eine Öffnungsweite von 10 mm.

Gabellichtschranke_m_Schmitdtrigger

Schaltplan des Breakoutboards:
https://www.sparkfun.com/datasheets/Sensors/Infrared/PhotoInterrupter-Breakout-v20.pdf

Datenblatt:
https://www.sparkfun.com/datasheets/Components/GP1A57HRJ00F.pdf

Auf der linken Seite des Bauteils ist die IR-LED untergebracht.
Die größere Länge des hinteren Beinchens wie auch die Prägung auf dem Bauteil
(obere Ansicht hier nicht gezeigt) gibt, weist daraus hin, dass es sich um die Kathode handelt.

Im Datenblatt mit Pin (2) bezeichnet. Das kürzere, vordere, rechte Beinchen ist somit die Anode.
Um die IR-LED ohne Schaden am Arduino UNO betreiben zu können, bedarf es eines 220 oder 330 Ohm Vorwiderstandes,

der am besten zwischen die Kathode (rechtes, hinteres Beinchen im Bild) und Masse (GND) geschaltet wird.Über die genaue Verwendung informiert dieser Forenbeitrag
http://forum.arduino.cc/index.php?topic=102418.0

oder der Schaltplan des Breakoutboards von Sparkfun.
https://cdn.sparkfun.com/datasheets/Sensors/Infrared/PhotoInterrupter-Breakout-2.2.pdf

Aus dem Schaltplan des Breakout-Boards geht auch nochmals die genaue Beschaltung hervor.
Auf der linken Seite der obigen Darstellung befindet sich demnach vorne der Massenanschluss (-) (Englisch Ground = GND).
Etwas zur Mitte versetzt befindet sich der im Datenblatt mit Vo bezeichnete Signalausgang und ganz hinten die Spannungsversorgung (+).
Ein Aufbau unmittelbar auf einem Breadboard funktioniert nicht. Die Beinchen sind zu dünn und falsch positioniert.
Für einen fliegenden Aufbau bleibt also nur ein Aufbau mit Lötkolben und Schrumpfschlauch an eine Steckerleiste, die entsprechend in des Steckbrett eingefügt werden kann.
Später wird der Aufbau mit einem Schrumpfschlauch mit größerem Durchmesser und weiblich-männlichen Patchkabeln im Einsatz getestet.
Zunächst aber die Funktionsprüfung mithilfe eines Sketches.
Der Signalausgang der Lichtschranke wird mit digitalPin2 verbunden (Dieser Eingang ist interrupttauglich, was später verwendet werden soll).
Dem Standard folgend verwenden wir zur Verbindung der Anode an Vcc ein rotes Jumperkabel und zur Verbindung mit GND ein schwarzes Jumperkabel.
Die eingebaute LED am Digitaleingangspin 13 soll bei Aufleuchten, wenn sich ein Hindernis im Spalt der Lichtschranke befindet.

// 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

Nach einer leichten Modifikation des Sketches (Zum Beispiel dem Einfügen einer Zeile „delay(500);“ nach dem „digitalWrite(Led13, HIGH);“
und vor allem vor das anschließende „}“) und dem Test der Lichtschranke mit einem dünnen Drahtstück, das schnell hindurchgezogen wird, stellen sich erste Irritationen ein.

Offensichtlich führt nicht jeder Durchgang eines Gegenstandes durch die Lichtschranke zu einer Auslösung des Signals.
Das Problem tritt noch deutlicher auf, wenn das Programm umfangreicher wird und eine Kommunikation auf den „Serial Monitor“ erfolgt.
Während der Arduino gerade mit anderen Dingen beschäftigt ist, mangelt es an Aufmerksamkeit für den Sensor.

Erik Bartmann hat dieses Problem in dem frei verfügbaren Ergänzungstext zur ersten Auflage seines Buches

„Die elektronische Welt mit dem Arduino entdecken“ ganz wunderbar beschrieben.
http://erik-bartmann.de/component/attachments/download/79.html

Die 2. Auflage des Buches deckt diesen Bereich zwar ab, ist aber nicht so prägnant.
Mit der entsprechenden Modifikation des Sketches funktioniert der Sensor jetzt in der beabsichtigten Weise.
Das Echtzeitmodul des Tropfenzählers ersetzen zunächst die Funktionen millis().

Diese Funktion gibt die Zeit seit dem Start des Programms an und kann damit ein Zeitintervall von fast 50 Tagen messen, bevor der Wert der Funktion überläuft und damit wieder bei Null beginnt.
Es soll zum Beispiel die Tropfgeschwindigkeit in Anzahl Tropfen pro Minute angegeben werden.

Die Variable vorwert soll den Zeitstempel des letzten Ereignisses beinhalten.
Sie wird vor der Setup-Funktion mit:
unsigned long vorwert;
eingeführt.

Die Tropfgeschwindigkeit kann durch Bestimmung der Differenz tropfzutropfzeit zwischen der istzeit und dem vorwert in der Einheit Millisekunden berechnet werden.
Damit diese Routine nur aufgerufen wird, wenn ein Tropfen gefallen ist, wird eine boolsche Variable „getropft“ eingeführt, die die Interruptroutine auf „TRUE“ setzt.

if (getropft== TRUE)
{
istzeit = millis();
tropfzutropfzeit = istzeit – vorwert;
vorwert = istzeit;
tropfgeschwindigkeit = tropfzutropfzeit / 60000;
getropft = FALSE;
}



Es sollte noch berücksichtigt werden, dass eine Tropfgeschwindigkeit erst bestimmt werden kann, wenn wenigstens der zweite Tropfen gefallen ist.
Die Geschwindigkeitsanzeige kann so angepasst werden, dass immer der gleitende Mittelwert
von einer zuvor festgelegten Anzahl von Ereignissen (zum Beispiel 3) ein Wert auf dem „Serial Monitor“ ausgegeben wird.


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



10) Tropfenzähler mit Gabellichtschranke

SHARP GP1A57HRJ00F

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.


// 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.
}


Quelle:
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);
   }
}



Quellen, die mich zu dieser Art des Codes bewegt haben:
Using a KY040 Rotary Encoder with Arduino“ von Big Dan The Blogging Man
Interrupts“ von Nick Gammon
Arduino Interruptsteuerung (Teil 1)“ von Erik Bartmann

303_c_Bartmann-x_#002 ARDUINO Intrrupt-Handling Teil 1_1a.pdf

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/


Für erste Gehversuche eignet sich auch das Breakoutmodul KY-010.
Erik Bartmann hat dieses Problem in dem frei verfügbaren Ergänzungstext zur ersten Auflage seines
Buches „Die elektronische Welt mit dem Arduino entdecken“ ganz wunderbar beschrieben.

http://erik-bartmann.de/component/attachments/download/79.html

Die 2. Auflage des Buches deckt diesen Bereich zwar ab, ist aber nicht so prägnant.


Quelle:

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

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



11) Tropfenzählerprobleme und Lösungen

Ziel:
Es gibt einen Strauß von Sensoren, die ausgelesen und dessen Daten ausgewertet werden wollen.
Natürlich sollen die Daten in regelmäßigen Intervallen gelesen, übermittelt und/oder gespeichert werden.
Regelmäßige Intervalle?
Gleichmäßige Pausen?
Klarer Fall, einfache Lösung „Delay“! Könnte man denken und versuchen.
Irgendwie funktioniert während der Delay-Zeit aber nicht alles wie geplant.
Das Problem und seine Ursache findet sich in der Hilfe der Arduino-IDE (bzw. auf der Arduino-Webseite).
Zitat:
 „No other reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function„.

Als mögliche Lösung bietet sich das Tutorial „Blink Without Delay“ der Arduino.cc-Webseite an.
Der Trick besteht in der Verwendung der millis().
Die Funktion millis() zählt die Zeit seit dem Einschalten des Arduino in Millisekunden.
Damit eine Aktion in gleichmäßigen Abständen stattfindet, benötigt man die aktuelle Zeit, die vorgesehene Zeitdifferenz und die Zeit des letzten Auftretens der Aktion.
Dafür sind entsprechend geeignete Variablen zu definieren.
unsigned long jetzt = 0;
unsigned long vorhin = 0;
long intervall = 60000;



Während des Programmablaufs wird stetig überprüft, ob der Unterschied zwischen der „jetzt“-Zeit und der „vorhin“-Zeit das vorgesehene Intervall übersteigt.
Ist das der Fall verzweigt das Programm zur geplanten Aktion.
Da hier eine der geplanten Aktionen ablaufen soll, ist es an der Zeit, den Zeitpunkt in der Variablen „vorhin“ festzuhalten.
Dem schließt sich die geplante Aktion an.



int photoPin = 2;
int interruptNumber = 0;
unsigned long vordropcount = 0;
volatile unsigned long dropCount = 0;
unsigned long jetzt = 0;
unsigned long vorhin = 0;
volatile boolean geaendert = false;
long intervall = 60000;
 
void setup() {
  // put your setup code here, to run once:
  pinMode(photoPin, INPUT);
  attachInterrupt( interruptNumber, interruptRoutine, RISING);
  Serial.begin(9600);
}
 
void loop() {
  // put your main code here, to run repeatedly:
  if (geaendert == true) {Serial.println(dropCount);}
  geaendert = false;
  jetzt = millis();
  if (jetzt - vorhin > intervall)
  {
    vorhin = jetzt;
    Serial.print((dropCount - vordropcount));
    Serial.println(" Tropfen pro Minute");
    vordropcount = dropCount;
    Serial.println(dropCount);  
  }
}
 
void interruptRoutine()
{
  dropCount++;
  geaendert = true;
  delay(2);
}


Der vorangestellte Sketch zählt mit Hilfe einer Lichtschranke Tropfen und gibt sowohl die Gesamtzahl der gezählten Tropfen als auch die pro Minute gezählten Tropfen an.
Die letztere Angabe erfolgt jeweils minütlich auf den Serial-Monitor.

Damit der Tropfenzählsensor kein Signal übersieht und zählen kann, muss die laufende Arbeit des Arduino unterbrochen werden.
Dies leistet die Interruptfunktion.
Der Arduino UNO kennt zwei externe Interrupts. Diese sind nur auf bestimmten Digitalpins verfügbar. https://www.arduino.cc/en/Reference/AttachInterrupt

Dem Aufruf der Funktion „AttachInterrupt“ sind einige Parameter beizugeben.
Für den Tropfenzähler hat sich ein Aufruf der Routine bei steigenden Signalen „RISING“ als geeignet herausgestellt.
Zudem wird eine Funktion benannt, die im Fall eines Signalanstiegs (LOW auf HIGH) am benannten Digitalpin ablaufen soll.
Die Funktion sollte möglichst knapp gehalten sein und keine (oder nur sehr kurze) Delay-Aufrufe enthalten.
Sollen im ganzen Programm gültige Variable innerhalb der Interruptfunktion verändert werden, müssen sie als Veränderliche „volatile“ deklariert werden,
damit andere Teile des Programms mit die jeweiligen Veränderungen geeignet aufnehmen und umsetzen können (Näheres siehe Link auf „Arduino Interruptsteuerung (Teil1)“) .
Getestet wird der Aufbau mit Hilfe zum Beispiel einer Lichtschranke / Fotounterbrecher aus einem der vielen Sensor-Kits für den Arduino.

Die Belegung geht aus der rückseitigen Beschriftung des Sensormoduls hervor.
Natürlich eignet sich auch ein eigener Ersatzaufbau mit Hilfe eines Tasters, wie im Beispielprogramm Button (https://www.arduino.cc/en/Tutorial/Button).


Quellen:
„Blink Without Delay“
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay


Erik Bartmann Arduino Interruptsteuerung (Teil1)

303_c_Bartmann-x_#002 ARDUINO Intrrupt-Handling Teil 1_1a.pdf

1 Gedanke zu “Tropfenzählerprobleme und Lösungen

Quelle:
http://technik-garage.de/tropfenzaehlerprobleme-und-loesungen/



********************************************************I*
12) Arduino UNO als Geiger-Müller-Zähler
Zählimpuls 100us Impulsverlängerung auf 5ms
Zeitdifferenzmessung
Für die Zählraten-Bestimmung hat man prinzipiell zwei Möglichkeiten.
Entwender man gibt eine Zeit vor und zählt wie viele Impulse man in dieser Zeit bekommt oder aber
man gibt die Zahl der Impulse vor, die man abwarten will und man mißt die Zeit die man benötigt bis man die vorgegebene Impulsanzahl erreicht.
In beiden Fällen ergibt sich die Impulsrate in dem man die Impulszahl durch die Zeit dividiert.
In vielen Fällen wird die erste Variante gewählt, weil sie naheliegender scheint.
Die zweite Variante hat aber einen großen Vorteil gegenüber der ersten:
Die Statistik (die Streuung) des Ergebnisses bleibt unabhängig von der Aktivität.
Das liegt daran, dass durch die Zufälligkeit der Zählimpulse ja immer eine Unsicherheit in der berechneten Zählrate bleibt,
die sich darin äußert, dass sie bei gleichbleibender Aktivität streut, da man sich auf eine endliche Anzahl an Zählpulsen zur Berechnung beschränken muss.
Diese Streuung hängt von der Zahl an Zählimpulsen ab und nicht von der Zeit.
Wenn man daher immer die gleich Zahl an Zählimpulsen abwartet, dann bleibt auch die Streuung des Ergebnisses gleich.
Dabei passt sich die Messzeit automatisch an die Verhältnisse an, wenn man eine hohe Aktivität hat,
erhält man aktualisierte Zählraten in rascher Folge, nur wenn die Zählrate niedrig ist, dauert die Messung länger.
Damit wartet man bei einer Änderung der Zählrate immer die kürzest mögliche Zeit (bei gegebener Statistik) für den nächsten Messwert.
Daher wird in diesem Beispiel die zweite Methode gezeigt.

ARDUINO Sketch  Zählraten-Bestimmung

// Sketch Geiger-Müller-Zähler - Zählraten-Bestimmung
#define MAXCNT 10      // maxCNT Zahl der Impulse 10 bis 200
#define CalFactor 1      // CalFactor  Umrechnung der Zählrate (cpm=counts per minute)  in eine Dosierleistung uSv/h

volatile int counter = 0;
unsigned long oldTime = 0;
int speaker = 5;                  // Lautsprecher an pin-5

void setup() {
    pinMode(speaker, OUTPUT);
    digitalWrite(speaker, LOW);
    Serial.begin(9600);
    attachInterrupt(0, count, FALLING);
}


void loop() {
    unsigned long time;
    unsigned long dt;
    float rate;

    if (counter == MAXCNT) {
      detachInterrupt(0);
      time = millis();
      dt = time-oldTime;
      rate = (float)MAXCNT*60.0*1000.0/(float)dt/CalF
            actor;
     Serial.println(rate);
     oldTime = time;
     counter = 0;
     attachInterrupt(0, count, FALLING);
    }
}


void count()
{
    counter++;
    digitalWrite(speaker, HIGH);
    delayMicroseconds(50000);     // 50ms Pause
    digitalWrite(speaker, LOW);
}



a
Quelle
303_Arduino-x_Bestimmung der Zählimpulsrate von Geiger-Müller-Sensoren (für Radioaktivität) mit dem ARDUINO_1a.pdf






********************************************************I*
Arduino als Zollstock
13) Ultraschall-Abstandsmessung mit Arduino
Es soll Schulen geben, da ist Abstandsmessung mit Ultraschall Teil des Praktikums im Fach Physiktechnik.
Mit Oszilloskop und Frequenzgenerator werden Impulspakete im 40-kHz-Bereich erzeugt.
Das alles soll den S/E-Kopf der Ultraschallprüfung verdeutlichen.
Für den Arduino wird zufällig ein ähnlicher Aufbau geliefert.

Quelle:
http://hjberndt.de/soft/ardping.html





********************************************************I*
Arduino als CompuLab (updated)

Compact erkennt Arduino
Quelle:
http://hjberndt.de/soft/ardcompact.htm





********************************************************I*
17.11.14: Sparrow-App: Reaktionstest
http://www.elektronik-labor.de/AVR/Sparrow/SparrowTeleBin.html#reaktion


3.3.15: LED-Kerzen mit induktiver Ladeschaltung
http://www.elektronik-labor.de/Labortagebuch/Tagebuch0315.html#led

Digispark-Luxmeter  

http://www.elektronik-labor.de/Arduino/Digispark-Luxmeter.html

: Bascom-AVR: Widerstandsmessung 1 k ... 10 M  
http://www.elektronik-labor.de/AVR/Rmessung.html

Schaltunsgtechnik: Resistiver Feuchtesensor
http://www.elektronik-labor.de/Notizen/FeuchteSensor.html

ATtiny13: Lernpaket Mikrocontroller über USB
http://www.elektronik-labor.de/AVR/LP-Mikrocontroller-clone.html#usb

19.12.14: Messtechnik: BPW34-Luxmeter
http://www.elektronik-labor.de/Lernpakete/Kalender14/Advent14.html#bpw34

13.12.14: Mikrocontroller: Motortreiber L293D
http://www.elektronik-labor.de/Lernpakete/Kalender14/Advent14.html#l293

27.11.14: Elektronik-Projekt: Gewitter-Monitor mit Grafik-LCD
http://www.elektronik-labor.de/Projekte/GewitterMonitor.html

12.5.14: Schaltungsnotizen: Solarleuchte als Durchgangsprüfer
http://www.elektronik-labor.de/Notizen/BauteileTester.html


9.5.14: Labortagebuch: 12-V-LED-Lampe an 230 V
http://www.elektronik-labor.de/Labortagebuch/Tagebuch0514.html

10.2.14: Labortagebuch: Schrittmotor am ULN2803
http://www.elektronik-labor.de/Labortagebuch/Tagebuch0214.html#uln

4.2.14: Labortagebuch: Solarlampe erhält Schottky-Diode
http://www.elektronik-labor.de/Labortagebuch/Tagebuch0214.html#solar

16.1.14: Schaltungswettbewerb: Reaktionstester
http://www.elektronik-labor.de/Lernpakete/Kalender13/Reaktion.html

15.1.14: Schaltungswettbewerb: Bleiakku-Vitalisierer  
http://www.elektronik-labor.de/Lernpakete/Kalender13/Akku.html

15.1.14: Schaltungswettbewerb: Ultraschallabstandsensor
http://www.elektronik-labor.de/Lernpakete/Kalender13/Ultraschall.html

15.1.14: Schaltungswettbewerb: Ei-Timerschaltungen
http://www.elektronik-labor.de/Lernpakete/Kalender13/Timer.html

15.1.14: Schaltungswettbewerb: PWM-Generator
http://www.elektronik-labor.de/Lernpakete/Kalender13/PWM2.html

14.1.14: Schaltungswettbewerb: Zweikanalvorsatz für Oszilloskop
http://www.elektronik-labor.de/Lernpakete/Kalender13/Zweikanal.html

13.1.14: Schaltungswettbewerb: Lichtschranke mit 4093
http://www.elektronik-labor.de/Lernpakete/Kalender13/Schranke.html

11.1.14: Schaltungswettbewerb: Logiktester  
http://www.elektronik-labor.de/Lernpakete/Kalender13/Logik.html

6.1.14: Schaltungswettbewerb: Mückenscheuche mit 4093
http://www.elektronik-labor.de/Lernpakete/Kalender13/Muecke.html

19.12.13: Mikrocontroller: Was ist Arduino?
http://www.b-kainka.de/Weblog/Mikrocontroller/Arduino.html

23.8.13: Bascom-AVR: Hot-Spot-Temperaturregler
http://www.elektronik-labor.de/AVR/HotSpot.html

20.8.13: Schaltungstechnik: Temperaturmessen mit 555 und PC
http://www.elektronik-labor.de/Notizen/Temp555.html

23.7.13: Elektronik-Dachbude: Strommessungan der Solaranlage

27.5.13: Bascom-AVR: Einfachedigitale Filter
http://www.elektronik-labor.de/AVR/Filter.html

21.5.13: Bastelecke: Minimalistische Geigerzäher
http://www.b-kainka.de/bastel76.htm#mini

6.5.13: ATtiny13: Stroboskop
http://www.elektronik-labor.de/AVR/dds/MicroDDS.html#strobo

22.4.13: Strahlenmessung: BPW34misst Betastrahlen
http://www.elektronik-labor.de/Projekte/Alpha7.html#k40

19.4.13: Strahlenmessung: RadioaktiveGlimmlampen
http://www.elektronik-labor.de/Labortagebuch/Tagebuch0413.html#glimm

9.4.13: Tiny13-Contest: Servo-Voltmeter
http://www.elektronik-labor.de/AVR/T13contest/Servo.html#volt

5.4.13: Tiny13-Contest: HelligkeitsempfindlicheLED
http://www.elektronik-labor.de/AVR/T13contest/Reaktiv.html

24.10.12: Elektronik-Grundlagen: Operationsverstärker-Schnellkurs
http://www.elektronik-labor.de/Lernpakete/OPV/OPV_6.html

29.6.12: HT46F47: Servo-Impulslängenmessung
http://www.elektronik-labor.de/Holtek/Holtek10.html

28.6.12: Labortagebuch: Stromwandlermit einer Relais-Spule
http://www.elektronik-labor.de/Labortagebuch/Tagebuch08/Tagebuch0408.html#rel

22.6.12: AVR-Controller: Bascom-Bootloaderfür Arduino
http://www.elektronik-labor.de/AVR/Bootloader.html#arduino

2.6.10: Elektronik-Labor: RS232-Programmierung
http://www.elektronik-labor.de/RS232//RS232_3.htm

5.4.10: In der Bastelecke: Der Kneipen-Reaktionstester
http://www.b-kainka.de/bastel122.html


23.1.07: Neues zum Software Defines Radio: Messungenan der Soundkarte
http://www.b-kainka.de/iqrx3.htm

3.11.06: Basteln, Umbauen und Reparieren: DieSolar-Gartenlampe
http://www.b-kainka.de/bastel111.htm

16.3.01: Die Bastelecke wird 50: Taschenrechnerals Digitalzähler
http://www.b-kainka.de/bastel50.htm






********************************************************I*

Zählerbau mit wenig Zeilen
Arduino als Frequenzzähler für Arduino in C
Der Aufruf pulseIn() macht Zählerbau mit dem Arduino einfach. Mit einer LCD-Anzeige wird ein eigenes Gerät daraus. Impulsratenzähler im Eigenbau.


Arduino als Zähler
14) Frequenzzähler mit Arduino
An manchen Schulen werden Zählraten und andere Ereignisse im Praktikum gemessen.
Ein GM-Zählrohr liefert Impulse, die der Intensität von
z.B. Gamma-Stahlen entsprechen. In der Mechanik können Geschwindigkeiten mittels Speichenrad in eine Frequenz gewandelt werden.
Interferenzübergänge erlauben Aussagen zu optischen Weglängenänderungen.


Arduino zeigt die Netzfrequenz bei offenem Eingang auf einem LCD-Display.



/* Frequenzzähler Gibt die Frequenz des Spannungsignals an Pin 7 aus */int pin = 7;unsigned long T;          //Periodendauer in usdouble 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.println(f*1e6);  //Ausgabe in Hertz } }


Ein Blick in die Referenz auf arduino.cc zeigt bei den Eingaben unter 'Advanced I/O' die Funktion pulseIn().
Die Beschreibung sagt, dass mit dem Aufruf pulseiIn(pin, HIGH) gewartet wird, bis das Signal an dem Eingangs-Pin (pin) auf Logikpegel HIGH geht.
Dann 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 Impulsdauer ti.
Die Impulspause tp kann mit pulsIN(pin,LOW) ermittelt werden. Die Periodendauer T ergibt sich aus T = ti+ tp.
Bei einem symmetrischen Rechtecksignal ist ti = tp, 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. Aus Mikrosekunden (1e-6) werden Megahertz (1e6). Um eine Anzeige in Hertz zu erreichen wird mit 1e6 multipliziert.



Probe mit DSO-Quad


Das Hosentaschenoszilloskop 'DSO-Quad' mit seinem eingebauten Frequenzgenerator soll als Testsignalgeber dienen.
Die Rechteckfrequenz kann in weiten Bereichen eingestellt werden. Mit zwei Verbindungen kann der Test beginnen.
Masse an Masse und Generatorausgang vom Quad an Pin 7 des Arduino.
Bei der Frequenz 5000 Hz wird in der Tat auch ein Wert um 5025 angezeigt.
Wer da jetzt im Recht ist, müsste eine Kalibrierung zeigen. Für einfache Messungen sollte das jedoch zunächst reichen.



Ratemeter oder Impulszähler

/* 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);}

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.



LCD-Anzeige


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);}

/* 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






********************************************************I*
Temperatur und Luftfeuchte mit einfachen Routinen (ohne Bibliotheken)
15) DHT11 am Arduino - Daten im Gänsemarsch


Wetter, Wetter, Wetter
Daten im Gänsemarsch für Arduino in C
Bibliotheken führen mit wenigen Klicks zum gewünschten Ergebnis, sie schirmen den Programmierer aber quasi ab.
Der hier eingesetzte Sensor für Temperatur und Luftfeuchte benutzt ein 1-Wire-Verfahren.
Ohne Bibliotheken sollen überschaubare Routinen den serielle Datenstrom verdeutlichen.

Im Netzt gibt es unzählige Sensoren für Arduino & Co. Der DHT11 ist dabei weit verbreitet und liefert einen positiven Temeraturwert in Celsius, sowie die Relative Luftfeuchte in Prozent.
Die Arduino-Gemeinde ist es gewohnt verwöhnt zu werden - anders ausgedrückt - es gibt zu jedem Sensor in kürzester Zeit eine Bibliothek
und schon kann der Küchentisch-Elektroniker und Patchwork-Programmierer mit drei Klicks seine Vorstellungen in kürzester Zeit realisieren.
Das Beispiel "Arduino als Zollstock" ist so zu verstehen.

Ist man allerdings interessiert, wie die Dinge im Untergrund der Technik und Bibliotheken funktionieren, wird die Sache schon schwieriger.



Im Blog embedded-lab.com wird eine ganz bequeme Art vorgestellt den Sensor ohne Breadboard zu benutzen.


Das DSO-Quad zeigt am Digitaleingang D den Beginn der Übertragung. Nach 18 Millisekunden LOW folgt etwa 40 us HIGH als Anforderung vom Arduino.
Der Sensor antwortet mit ca. 50 us LOW und ca 80 us HIGH.
Dann folgt eine Impulspause der festen Länge 50 us und das erste Bit mit kurzer Impulsbreite, also eine "0".
Die ersten Bits wären hiernach 0010010 ...


Dieser Sensor DHT11 sendet seine Informationen seriell im Gänsemarsch über die Leitung.
In der linken Darstellung sind die ersten Bits der seriellen Datenübertragung zu sehen.

Die Spezifikation ist im Netz weit verbreitet. Die erforderlichen Signale findet man unter anderem hier: DHT11 Humidity Temperature_Sensor_Brick Communication Process: Serial Interface Single-Wire_Two-Way.
Die Besonderheit ist, dass eine Leitung für beide Richtungen verwendet wird. So sendet der Arduino ein Signal und schaltet anschließend auf Empfang.
Der Ausgang wird also zum Eingang. Der Datenaustausch kann wie folgt aus dem Datenblatt entnommen und zusammengefasst werden:
Ausgabe des Startsignals (Arduino)
Abwarten der Bestätigung (Sensor)
Einlesen von 40 Bit (5 Byte) Messdaten und Kontrolldaten

Im Detail ist das Startsignal ein Impuls der mindesten 18 ms LOW und 20 bis 40 us HIGH ist.
Danach wird auf Empfang geschaltet und auf die Antwort des Sensors gewartet.
Dieser legt zur Bestätigung den Eingang nun für 80 us auf LOW und danach 80 us auf HIGH. Nun folgen die 40 Bits bzw. 5 Bytes mit folgendem Inhalt:
Byte 1: Relative Luftfeuchte in Prozent
Byte 2: Nachkommastellen der Luftfeuchte (DHT11 immer 0)
Byte 3: Temperatur in Celsiusgrad
Byte 4: Nachkommastellen der Temperatur (DHT11 immer 0)
Byte 5: Summe der ersten vier Bytes zur Kontrolle

Ob ein Bit "1" oder "0" ist entscheidet die Impulsbreite.
Nach einer immer gleich langen Impulspause (LOW) von 50 us folgt eine Impulsbreite (HIGH) von entweder 26 bis 28 us für eine "0" oder 70 us für eine "1".
Damit steht einer Dekodierung nichts mehr im Weg. Das Signal erinnert etwas an das Funkuhr-Signal vom DCF77-Sender - mit anderen Zeiten.



Vorbereitungen - setup

Die Messdaten werden vom Arduino über die RS232-Leitung geschickt.
Der Sensor lag in der Nähe des Heizkörpers an einem kalten Winterabend. Die Luft war trocken ...


Vier globale Variablen - wegen der Einfachheit - sind für die Messergebnisse vorgesehen.
Einmal zwei Ganzzahlen (Integer), da der DHT11 hier keine Nachkommastellen liefert und zwei Zeichenketten (Strings), die diese Werte als Text enthalten.
Für die Ausgabe über Serial.print macht das keinen Unterschied, für eine möglicherweise angeschlossene Anzeige aber schon.
Als Anschluss für den Sensor DHT11 ist Pin 2 rein willkürlich gewählt worden. In der Setup-Routine wird die RS232-Schnittstelle konfiguriert und danach eine Sekunde gewartet.
Der Quelltextauschnitt zeigt folgendes Bild:

#define DHT_PIN 2

int feuchte, temperatur;
char sfeuchte[10],stemperatur[10];


void setup()
{Serial.begin(9600);
Serial.println("DHT11 Messung.");
delay(1000);
}


Hauptschleife -  loop

In der Hauptschleife werden die Messungen einmal in der Sekunde abgerufen und zur Anzeige gebracht.
Die Funktion dht11(pin) führt die Konversation mit dem Sensor und liefert Messdaten für die Ausgabe.

void loop()
{dht11(DHT_PIN);
Serial.print("DHT11 Luftfeuchte[%]/Temperatur[C]: ");
Serial.print(sfeuchte);
Serial.print("/");
Serial.println(stemperatur);
delay(1000);
}



Datenabfrage - 1 oder 0


Die eigentliche Daten-Abfrage erfolgt so wie es der Hersteller angibt.
Nacheinander werden folgende Dinge ausgeführt:

Byte-Puffer auf Null setzen
Messanforderung senden
Bestätigung empfangen
Die 40 Bits einlesen und ablegen
Messwert in die Variablen übertragen


Die Funktion dht11 führt genau diese Schritte aus. Nach dem Rücksetzen der Byte-Puffer folgt die Anforderung (Request Sample) mit delay und delayMicroseconds.
Danach wird der Pin als Eingang geschaltet.
Mit pulseIn werden die ca. 70 us der Antwort (Acknowledge) abgewartet.
Zeitlich entspricht dies dem 5. Skalenteil des Oszillogramms oben.
Die 40 Bits (Read Output) werden nun anhand der Impulsbreite abgefragt, dabei liegt die zeitliche Schwelle bei 40 us.
Falls der Impuls länger ist, wird ein gesetztes Bit (1) bitcnt-mal nach links geschoben (<<), damit es im Byte an der richtigen Stelle steht.
Wenn ein Byte voll ist, wird der Bytezähler ix erhöht. Das wird so auch in der entsprechenden Bibliothek gemacht.

Sind alle 40 Bits eingelaufen, folgen die Variablenzuweisungen.
Für den DHT11 gibt es keine Kommastellen, darum wird das Byte 0 zur Luftfeuchte und das Byte 3 zur Temperatur.
An dieser Stelle müsste dies für Sensoren wie DHT22 etwas angepasst werden, ebenso wie die Checksummenabfrage (die im Hobbybereich auch entfallen kann).
Zum Schluss erfolgt die Umwandlung der Zahlen in Zeichenketten. In C ist das itoa (Integer zu Ascii).
Bei genauem Hinsehen erfolgt die Abfrage der Impulslänge der 40 Bit nicht mit der eingebauten pulseIn()-Funktion, da diese hier aus noch unklaren Gründen nicht so wie erwartet funktioniert.
Das liegt möglicherweise an der gerade benutzen Arduino-IDE.
Zur Umgehung dieses Problems wird eine ähnliche Routine aufgerufen, die hier das erwartete Ergebnis zeigt: mypulseIn


Pulslängenabfrage
- Eigenbau mypulseIn()

Die integrierte pulseIn-Funktion wurde schon beim Projekt "Arduino als Zähler" erfolgreich verwendet.
Falls Flanken nicht per Interrupt verarbeitet werden müssen, ist eine solche Funktion einfach in der Handhabung.
Wenn die Beschreibung der Funktion unter Arduino.cc richtig verstanden wurde, ergibt sich - ohne im Quelltext zu wühlen - etwa folgender Ablauf:

unsigned long mypulseIn(int pin,int level){unsigned long t0,t1,t2,timeout=200; t0=micros(); if(level==HIGH) {while(!digitalRead(pin) && (micros()-t0)<timeout);//Wait for _/  t1=micros();  while( digitalRead(pin) && (micros()-t1)<timeout);//Wait for \_  t2=micros(); } else {while( digitalRead(pin) && (micros()-t0)<timeout);//Wait for \_  t1=micros();  while(!digitalRead(pin) && (micros()-t1)<timeout);//Wait for _/  t2=micros(); } return t2-t1; }



Diese Eigenbauroutine mit festen 200us Timeout funktioniert hier mit dem Arduino Uno R3.

// H.-J. Berndt 2015 auf www.hjberndt.de// DHT11-Sensor mit 1-Draht-Datenprotokoll// ohne Bibliotheken abfragen#define DHT_PIN 2 int   feuchte,     temperatur;char sfeuchte[10],stemperatur[10];void setup(){  Serial.begin(9600);  Serial.println("DHT11 Messung.");  delay(1000);}void loop(){dht11(DHT_PIN); Serial.print("DHT11 Luftfeuchte[%]/Temperatur[C]: ");Serial.print(sfeuchte); Serial.print("/");Serial.println(stemperatur); delay(1000);}void dht11(int pin){int bitcnt=7,ix=0; uint8_t Byte[5]; for(int i=0;i<5;i++)Byte[i]=0;  pinMode(pin, OUTPUT); // REQUEST SAMPLE digitalWrite(pin, LOW); delay(18); digitalWrite(pin, HIGH);delayMicroseconds(30); pinMode(pin, INPUT); pulseIn(pin,HIGH); // ACKNOWLEDGE ~ 70 us for (int i=0; i<40; i++) // READ OUTPUT - 40 BITS = 5 BYTE  {if (mypulseIn(pin,HIGH) > 40) Byte[ix] |= (1 << bitcnt);  if (--bitcnt < 0)// next byte  {bitcnt = 7;    // restart   ix++;     } } feuchte    = Byte[0]; //BYTE[1] bei DHT11 immer 0 temperatur = Byte[2]; //BYTE[3] bei DHT11 immer 0 if (Byte[4] != Byte[0]+Byte[2]){feuchte=88;temperatur=88;} itoa(feuchte,sfeuchte,9); itoa(temperatur,stemperatur,9);}unsigned long mypulseIn(int pin,int level){unsigned long t0,t1,t2,timeout=200; t0=micros(); if(level==HIGH) {while(!digitalRead(pin) && (micros()-t0)<timeout);//Wait for _/  t1=micros();  while( digitalRead(pin) && (micros()-t1)<timeout);//Wait for \_  t2=micros(); } else {while( digitalRead(pin) && (micros()-t0)<timeout);//Wait for \_  t1=micros();  while(!digitalRead(pin) && (micros()-t1)<timeout);//Wait for _/  t2=micros(); } return t2-t1; }

Der Gesamtquelltext ist hier hinterlegt.



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







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