Experimente mit dem  Super Starterkit - Teil 5: Einfache Sensoren, Mikrofon, Ultraschall-Sensor - AZ-Delivery


In diesem Beitrag geht es um die im Set enthaltenen einfachen Sensoren. Das sind der Neigungssensor, der Helligkeitssensor, der Temperatursensor und der Regensensor. Außerdem wird das Mikrofonmodul zum Schalten mittels Geräuschen und der Ultraschallsensor zur Entfernungsmessung behandelt.

Benötigte Hardware

Anzahl

Bauteil

Anmerkung

1

Super Starter Kit

 

1

9V-Blockbatterie oder 9V-Netzteil

optional

 

Neigungssensor SW520D

Der Neigungssensor ist ein sehr einfacher digitaler Sensor. In aufrechter Stellung sind die beiden Anschlusspins miteinander verbunden. Wird er mehr als circa 45° geneigt, wird diese Verbindung unterbrochen.

Zum Testen soll ein Sketch erstellt werden, der eine LED leuchten lässt, wenn die Verbindung im Neigungssensor unterbrochen wird. Der Neigungssensor wird zwischen den Eingang 2 und GND angeschlossen. Beim Eingang 2 soll der interne Pullup Widerstand aktiviert werden. Das bedeutet, wenn der Kontakt des Neigungssensors geschlossen ist, ist die Spannung am Eingang 2 0V sonst 5V. Die LED wird über einen 1kΩ Widerstand zwischen den Ausgang 3 und GND geschaltet.  Liegen am Ausgang 5V an, so leuchtet die LED. Der Sketch ist sehr einfach.

Zuerst werden wieder die verwendeten Pins definiert

#define SENSOR 2
#define LED 3

In der setup() Funktion wird der Pullup Widerstand für den Eingang aktiviert und der Pin 3 als Ausgang definiert.
void setup() {
  pinMode(SENSOR, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
}
In der loop() Funktion wird einfach der Zustand des Eingangs gelesen und auf den Ausgang ausgegeben.
void loop() {
  digitalWrite(LED, digitalRead(SENSOR));
}

Im Test werden Sie sehen, dass die LED nicht schon bei 45 Grad Neigung aufleuchtet. Dies liegt vor allem an der Adhäsion. Diese bewirkt, dass die Kugeln aneinander kleben bleiben. Andererseits reagiert der Neigungssensor auch auf Erschütterungen.

Temperatursensor NTC

Der Temperatursensor ist ein Widerstand mit starker Temperaturabhängigkeit und einem negativen Temperaturkoeffizienten. Das heißt, der Widerstandswert nimmt mit zunehmender Temperatur ab. Um mit dem Sensor Temperatur messen zu können, wird er als Teil eines Spannungsteilers verwendet. Da der Nennwiderstand 10kΩ beträgt, ist es sinnvoll, als zweiten Widerstand für den Spannungsteiler ebenfalls 10kΩ zu verwenden.


Die Spannung an A0 ist abhängig vom NTC-Widerstand Rt. Sie ergibt sich aus der Formel
UA0 = 5V / (Rt + 10kΩ) * 10kΩ
Damit erhält man folgende Kennlinie für die Temperatur abhängig von der gemessenen Spannung.


Man sieht die Kurve ist nicht linear. Betrachtet man aber einen eingeschränkten Temperaturbereich zwischen -20°C und 60°C so kann die Kurve als annähernd linear angesehen werden.


Die Steigung der Geraden ist 18,8 °C/V. Bei 0°C beträgt die Spannung 1,17V, Somit erhält man die Temperatur aus der gemessenen Spannung Ut
T = (Ut - 1,17) * 18,8

Der Sketch zum Testen gibt die Temperatur im Sekundenintervall auf die serielle Schnittstelle aus.
Zuerst werden der verwendete Eingang und die Referenzspannung für den Analog-Digital-Wandler definiert.

#define SENSOR A0
#define REFERENZ 5.0
In der setup() Funktion wird die serielle Schnittstelle aktiviert und der verwendete Pin als Eingang definiert
void setup() {
  Serial.begin(9600);
  pinMode(SENSOR, INPUT);
}

In der loop() Funktion wird zuerst der Wert vom Sensoreingang gelesen und mit Hilfe der Referenzspannung in Volt umgerechnet. Der Analog-Digital-Wandler hat eine Auflösung von 10 Bit. Sein Wertebereich geht daher von 0 bis 1023. Das heißt ein Wert von 1023 entspricht 5V. Es gilt daher U = Wert / 1023 * 5V. Dann wird die Spannung um den Wert bei 0°C vermindert und mit der Steigung multipliziert. Das Ergebnis wird auf die serielle Schnittstelle ausgegeben. Anschließend erfolgt eine Pause von 1000 ms.
void loop() {
  float spg = analogRead(SENSOR) / 1023.0 * REFERENZ;
  float temp = (spg - 1.17) * 18.8;
  Serial.print("Temperatur = ");
  Serial.print(temp);
  Serial.println(" °C");
  delay(1000);
}

Wenn man den ganzen Temperaturbereich ausnutzen will, muss die logarithmische Näherung verwendet werden. β ist der Kennwert des Thermistors. Er beträgt im vorliegenden Fall 3900. UREF ist die Referenzspannung. Sie beträgt 5V. TN ist die Nenntemperatur. Sie beträgt 25 °C. K ist schließlich 0 °C also 273,15 °K. Damit lautet die Formel:

T = β / (β / (K + TN) + ln((UN - U) / U))-K

Oder mit eingesetzten Konstanten

T = 3900 / (3900 / 298,15 + ln((5 – U) / U)) – 273,15

Im Sketch

float temp = 3900/(3900/298.15 + log((REFERENZ - spg)/spg))-273.15;

Mit dieser Formel erhält man im gesamten zulässigen Temperaturbereich von -50°C und +150°C brauchbare Werte.

Lichtsensor LDR

Der Light Dependent Resistor (LDR) ist ein Widerstand, dessen Widerstandswert mit zunehmender Beleuchtung abnimmt. Ein LDR besteht aus dem Halbleitermaterial Cadmiumsulfid. Durch Lichteinstrahlung werden freie Ladungsträger erzeugt, die einen Stromfluss ermöglichen. Damit man eine große Länge der gegenüberliegenden Elektroden erreicht, werden die Elektroden als Kammstruktur ausgeführt. Die Kennlinie ist beim LDR ebenfalls nichtlinear. Die folgende Kennlinie wurde über eine Versuchsanordnung ermittelt. Zur Vergleichsmessung diente ein Helligkeitssensor BH1750.

Mit der Formel

E = e( U * 1,4) / 0,4 [Lux]

Erhält man im Bereich zwischen 0 und 1000 Lux eine brauchbare Annäherung. Die Schaltung ist identisch zu der Schaltung für den Temperatur Sensor

Der Sketch ist ebenfalls weitgehend identisch. Nur die Berechnung des Messwertes ist abweichend.

Zuerst werden der verwendete Eingang und die Referenzspannung für den Analog-Digital-Wandler definiert.

#define SENSOR A0
#define REFERENZ 5.0
In der setup() Funktion wird die serielle Schnittstelle aktiviert und der verwendete Pin als Eingang definiert
void setup() {
  Serial.begin(9600);
  pinMode(SENSOR, INPUT);
}

In der loop() Funktion wird zuerst der Wert vom Sensoreingang gelesen und mit Hilfe der Referenzspannung in Volt umgerechnet. Der Analog-Digital-Wandler hat eine Auflösung von 10 Bit. Sein Wertebereich geht daher von 0 bis 1023. Das heißt, ein Wert von 1023 entspricht 5V. Es gilt daher U = Wert / 1023 * 5V. Dann wird mit der oben angegeben Formel die Beleuchtungsstärke berechnet.
void loop() {
  float spg = analogRead(SENSOR) / 1023.0 * REFERENZ;
  float lux = exp(spg * 1.4) / 0.4;
  Serial.print("Belecuhtung = ");
  Serial.print(lux);
  Serial.println(" Lux");
  delay(1000);
}

Regensensor
Der Regensensor ist sehr einfach aufgebaut. Er besteht aus einer Leiterplatte mit parallel verlaufenden Leiterbahnen. Die Leiterbahnen sind zum Schutz vor Korrosion vergoldet. Wenn die Leiterbahnen mit einer leitfähigen Flüssigkeit, zum Beispiel Wasser, in Berührung kommen, kann ein Strom zwischen den Leiterbahnen fließen. Am Signalausgang wird eine Spannung gemessen. Bereits ein Tropfen Wasser genügt, um eine Spannung messen zu können. Die Spannung hängt von der benetzten Fläche und von der Leitfähigkeit der Flüssigkeit ab. Eine Auswertung der Spannungshöhe bringt keinen Nutzen.

Die Schaltung links zeigt den internen Aufbau des Sensors.

Der Sketch soll die LED an Pin 2 einschalten, wenn Feuchtigkeit am Sensor erkannt wird. Der Sensor sollte immer nur für die Messung mit Spannung versorgt werden, damit es nicht zu Korrosion durch Elektrolyse kommt. Daher wird der Plus-Anschluss des Sensors mit dem Pin 3 des Arduino verbunden. Als Eingang für die Sensorspannung wird A0 verwendet.

Zuerst werden der verwendete Eingang und die Ausgänge für die LED und für die Stromversorgung des Sensors definiert

#define SENSOR A0
#define LED 2
#define POWER 3

In der setup() Funktion wird die serielle Schnittstelle aktiviert und die verwendeten Pins werden auf die entsprechende Betriebsart eingestellt.

void setup() {
  Serial.begin(9600);
  pinMode(SENSOR, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(POWER, OUTPUT);
}

In der loop() Funktion wird zuerst die Stromversorgung für den Sensor eingeschaltet. Dann wird die Spannung vom Sensor gelesen und in der Variablen val gespeichert. Nun kann die Stromversorgung wieder ausgeschaltet werden. Der gemessene Wert wird auf die serielle Schnittstelle ausgegeben. Ist der gemessene Wert größer als 100, wird die LED eingeschaltet, sonst abgeschaltet. Hier kann direkt das Ergebnis des Vergleichs mit digitalWrite(LED, val > 100); ausgegeben werden. Es folgen 10 Sekunden Pause bis zur nächsten Messung.

void loop() {
  digitalWrite(POWER, 1);
  uint16_t val = analogRead(SENSOR);
  digitalWrite(POWER, 0);
  Serial.print("Messwert = ");
  Serial.println(val);
  digitalWrite(LED, val > 100);
  delay(10000);
}

Mikrofon


Das Mikrofon-Modul enthält ein empfindliches Elektret-Mikrofon und einen Komparator.

Das Mikrofon hat einen Innenwiderstand von 1kΩ. Die Spannung an A0 wird im ersten Komparator mit der halben Betriebsspannung verglichen (Spannungsteiler R6 und R2). Um eine hohe Empfindlichkeit zu erzielen, sollte mit dem Potentiometer die Gleichspannung an A0 ebenfalls auf die halbe Betriebsspannung eingestellt werden. Ist die Spannung an A0 kleiner als die halbe Betriebsspannung, schaltet der Ausgang des Komparators und ebenfalls D0 auf die Betriebsspannung. Der zweite Komparator vergleicht die Spannung an D0 ebenfalls mit der halben Betriebsspannung und schaltet daher den Ausgang auf GND. Die LED L2 leuchtet. Die LED L1 zeigt die Betriebsspannung an. Das Sensormodul ist darauf ausgelegt Geräusche zu detektieren.
Benötigt man die Möglichkeit, den Schwellwert dynamisch zu ändern, muss man den Anschluss A0 verwenden. Für einen fest eingestellten Schwellwert ist der Anschluss D0 besser geeignet.


Im Beispiel-Sketch soll eine LED durch Händeklatschen ein- und ausgeschaltet werden. Es werden beide Varianten (analog oder digital) gezeigt. Für die analoge Variante wird der Anschluss A0 des Moduls mit A0 am Mikrocontroller verbunden (punktierte grüne Linie). Für die digitale Variante wird der Anschluss D0 des Moduls mit dem Anschluss A0 des Mikrocontrollers verbunden (durchgezogene grüne Linie).

Die LED wird über einen 1kΩ Widerstand an Pin 2 angeschlossen.

Der Sketch für die digitale Variante

Das Potentiometer muss so eingestellt werden, dass die LED neben dem Potentiometer gerade nicht leuchtet, aber bei Geräuschen aufblitzt.

Zuerst werden die verwendeten Pins definiert
#define SENSOR A0
#define LED 2


Es wird eine globale Variable benötigt, um den Zustand der LED zu speichern
boolean led = 0;

In der setup() Funktion wird die Betriebsart der verwendeten Pins eingestellt.

void setup() {
  pinMode(SENSOR, INPUT);
  pinMode(LED, OUTPUT);
}
In der loop() Funktion wird der Zustand des Eingangs A0 gelesen. Ist der Zustand HIGH, wird der Zustand der LED invertiert und der neue Zustand auf den Pin für die LED geschrieben. Damit ein einzelnes Geräusch nicht mehrfach wirksam wird, wird eine Verzögerung von einer Sekunde eingefügt. Das bedeutet zwischen dem Ein- und Ausschalten muss mindestens eine Sekunde vergehen.

void loop() {
  boolean on1 = digitalRead(SENSOR);
  if (on1) {
    led = !led;
    digitalWrite(LED,led);
    delay(1000);
  }
}

Der Sketch für die analoge Variante

Bei dieser Variante spielt die Einstellung des Potentiometers eine untergeordnete Rolle. Es sollte aber ungefähr so eingestellt werden, dass am Analoganschluss des Moduls zirka 2,5 V gemessen werden.

Es werden die verwendeten Pins definiert
#define SENSOR A0
#define LED 2


Es werden zwei globale Variablen benötigt. Eine für den aktuellen Status der LED und eine zum Speichern der Ruhespannung am Analogeingang.
boolean led = 0;
uint16_t ref = 0;

In der setup() Funktion wird die Betriebsart der Pins eingestellt. Dann wird die Ruhespannung am Analogeingang als Referenzwert in der globalen Variablen ref gespeichert.
void setup() {
  pinMode(SENSOR, INPUT);
  pinMode(LED, OUTPUT);
  ref = analogRead(SENSOR);
}


In der loop() Funktion wird die aktuelle Spannung am Analogeingang gemessen und in der Variablen val gespeichert. Nun wird die absolute Differenz zwischen der aktuellen Spannung und der Ruhespannung ermittelt. Diese Differenz wird in der Variablen delta gespeichert. Ist die Differenz größer als 20, war ein Geräusch aufgetreten. Der Status der LED wird invertiert und der neue Wert auf den Pin 2 ausgegeben. Danach wird eine Sekunde gewartet um eine Mehrfachreaktion zu vermeiden.
void loop() {
  uint16_t val = analogRead(SENSOR);
  int16_t delta = abs(ref-val);
  if (delta > 20) {
    led = !led;
    digitalWrite(LED,led);
    delay(1000);
  }
}

Elektronische Kerze
Verwendet man einen LDR zum Einschalten und das Mikrofonmodul zum Ausschalten, kann man eine LED „anzünden“ und „ausblasen“. Man erhält also eine „elektronische Kerze“.

Der LDR wird an A1 und das Mikrofon mit seinem Analogausgang an A0 angeschlossen. Die LED kommt über einen Widerstand von 1kΩ an Pin 2. Der Sketch ist sehr einfach.

Es werden die verwendeten Pins definiert
#define MIK A0
#define LDR A1
#define LED 2


Zwei globale Variablen werden zum Speichern des LED-Status und der Referenzspannung für das Mikrofon benötigt.
boolean led = 0;
uint16_t ref = 0;


In der setup() Funktion wird die Betriebsart der Pins eingestellt. Dann wird die Ruhespannung am Analogeingang als Referenzwert in der globalen Variablen ref gespeichert.
void setup() {
  pinMode(MIK, INPUT);
  pinMode(LDR, INPUT);
  pinMode(LED, OUTPUT);
  ref = analogRead(MIK);
}
In der loop() Funktion erfolgt eine unterschiedliche Verarbeitung je nach Status der LED. Ist die LED aus, wartet das Programm darauf, dass die Spannung am LDR über einen bestimmten Wert ansteigt. Das passiert dann, wenn eine helle Lichtquelle, z.B. ein brennendes Streichholz, vor den LDR gehalten wird. Wird der Schwellwert überschritten, wird der Status der LED auf HIGH gesetzt und an den Pin 2 ausgegeben.
Ist die LED an, wartet das Programm darauf, dass die Spannung am Analogeingang von der Referenzspannung abweicht. Das passiert dann, wenn das Mikrofon ein Geräusch, z.B. durch Blasen auf das Mikrofon, wahrnimmt. Der Status der LED wird dann auf LOW gesetzt und an Pin 2 ausgegeben.
void loop() {
  if (!led) {
    uint16_t val = analogRead(LDR);
    if(val > 800){
      led =1;
      digitalWrite(LED, led);
    }
  } else {
    uint16_t val = analogRead(MIK);
    int16_t delta = abs(val - ref);
    if (delta > 20) {
      led = 0;
      digitalWrite(LED,led);
    }
  }
}

Ultraschall Abstandssensor
Der Abstandssensor besteht aus einem Ultraschall-Sender links und einem Ultraschallempfänger rechts. Auf der Rückseite der Platine befindet sich die Auswerte-Elektronik.

Die Versorgungsspannung beträgt 5V. Wird am Trigger Eingang ein Impuls mit einer Dauer von mindestens 10µs angelegt, beginnt die Messung. Über den Ultraschall-Sender werden acht Schwingungen mit 40kHz gesendet. Die Elektronik ermittelt dann die Laufzeit, bis das Echo am Ultraschall-Empfänger eintrifft. Nach der Messung wird am Ausgang Echo ein Impuls erzeugt, dessen Dauer der ermittelten Laufzeit entspricht. Die Schallgeschwindigkeit beträgt 340 m/s oder 34 cm/ms. Da das Signal vom Sender bis zum Empfänger den doppelten Abstand zurücklegen muss, benötigt das Signal für einen Abstand von 1 cm 2 / 34 ms oder 2000/34 µs = 59 µs. Daher ist der Abstand gleich der gemessenen Zeit in µs durch 59. Zwischen zwei Messungen sollten mindestens 60 ms vergehen.

In der Versuchsanordnung wird der Trigger-Eingang mit Pin 3 und der Echo-Ausgang mit Pin 2 verbunden. Im Sketch wird alle Sekunden auf Pin 3 ein Impuls von 15 µs ausgegeben. Danach wird auf einen Impuls an Pin 2 gewartet und dessen Dauer gemessen. Genau zu diesem Zweck gibt es die Funktion
unsigned long pulseIn(uint8_t pin, uint8_t state)
Der Parameter pin enthält die Nummer des Pins, auf dem der Impuls auftritt. Der Parameter state ist HIGH oder LOW. Er gibt an, auf welchen Zustand gewartet werden soll. Der Rückgabewert ist die Pulse-Dauer in µs. Damit ergibt sich ein sehr einfacher Sketch, um mit dem Abstandssensor Abstände zu messen.

Zuerst werden wieder die benutzten Pins definiert.
#define TRIGGER 2
#define ECHO 3


In der setup() Funktion wird die serielle Schnittstelle gestartet, anschließend wird die Betriebsart der verwendeten Pins eingestellt und der Trigger-Ausgang auf LOW gesetzt.

void setup() {
  Serial.begin(9600);
  pinMode(TRIGGER, OUTPUT);
  pinMode(ECHO, INPUT);
  digitalWrite(TRIGGER, 0);
}

in der loop() Funktion wird der Trigger-Ausgang auf HIGH und nach einer Verzögerung von 15 µs wieder auf LOW gesetzt. Nun folgt die Funktion pulseIn(), die die Pulse-Dauer am Echo-Eingang in µs zurückgibt. Ist der zurückgegebene Wert größer als 38.000, befindet sich kein Objekt im erlaubten Messbereich. Eine entsprechende Fehlermeldung wird auf die serielle Schnittstelle ausgegeben. Ist der Wert kleiner als 38.000, erhält man mit einer Division durch 59 den Abstand in cm. Dieser Abstand wird an die serielle Schnittstelle ausgegeben. Dann wird eine Sekunde gewartet, ehe die nächste Messung beginnt.
void loop() {
  digitalWrite(TRIGGER, HIGH);
  delayMicroseconds(15);
  digitalWrite(TRIGGER, LOW);
  uint32_t echo = pulseIn(ECHO,HIGH);
  if (echo > 38000) {
    Serial.println("Außerhalb des Messbereichs");
  } else {
    float entfernung = echo/59;
    Serial.print(entfernung);
    Serial.println(" cm");
  }
  delay(1000);
}

Damit wurden alle im Set enthaltenen einfachen Sensoren beschrieben. Im nächsten Teil folgt der I2C-Bus, mit dem der intelligente Sensor DHT11 und das LCD-Display angesteuert werden.

Beitrag als PDF

Für arduinoProjekte für anfängerSensoren

Kommentar hinterlassen

Alle Kommentare werden von einem Moderator vor der Veröffentlichung überprüft

Empfohlene Blogbeiträge

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery