Fortbildung (11-20/33)

Die digitale Welt als Herausforderung für Schule und Elternhaus MS - OS

Bildschirmfoto 2021-10-26 um 11.09.09Hier finden Sie eine Liste mit den im Webinar "Die digitale Welt als Herausforderung für Schule und Elternhaus MS - OS" verwendeten Links:


Präsentation Rahmenrichtlinien MS/OS

Jung sein heute

Coding und Robotik

  • Scratch: Eine Online-Programmierumgebung mit Blocksyntax für Kinder und Jugendliche, ab ca. 8 Jahren.
  • SPIKE Prime: Das aktuelle Roboterset der Firma Lego ab der 5. Klasse
  • Mindstorms Robot Inventor: Das aktuelle Roboterset der Firma Lego für die Oberschule.
  • code.org: Eine Lernumgebung zum kindgerechten Programmieren in verschiedenen Anforderungs- und Altersstufen.
  • BBC micro::bit: Ein Mini-Computer mit verschiedenen Sensoren, mit Blöcken, in Python und Javascript programmierbar.
  • Arduino: Ein Mini-Computer mit zahlreichen Erweiterungsmöglichkeiten, programmierbar in C++

Konstruieren und gestalten

  • SketchUp: Ein 3D-Konstruktionsprogramm, kann mit einem snets.it-Account kostenlos benutzt werden.
  • clara.io: Eine 3D-Online-Konstruktionsumgebung mit vielen, auch ausgefeilten Funktionen.
  • CoSpacesEDU: Erlaubt das Gestalten von 3D-Welten mit vorgefertigten Element und der Möglichkeit die Figuren zu animieren.
  • Unity3D: Eine komplexe für den Privatgebrauch kostenlose Entwicklungsumgebung für 2D- und 3D-Spiele.
Virtual Reality
  • Merge Cube: Ein Angebot zum Einsatz von Augmented Reality für privat und im Unterricht.
  • Google Arts & Culture: Kunst, Museen, Landschaften u. a., manes davon in Virtual-Reality-Umgebung
  • Thinglink: Eine Online-Umgebung zum Gestalten von interaktiven Bildern in 2D, 3D und VR.

Podcasts und Musik

  • Audacity: Ein universelles Bearbeitungsprogramm für Audiodateien, mit mehreren Spuren, zahlreichen Effekten und kostenlos.

Raus aus dem Haus

  • Actionbound: Ein Angebot für virtuelle Schnipseljagden, Stadtralleys u. ä.
  • Geocaching: Schatzsuchportal für Caches auf der ganzen Welt.
Eltern Medienfit

Selbsterklärung zur Teilnahme

Angerer Harald - Dienstag, 26. Oktober 2021 (Zuletzt geändert: Dienstag, 9. November 2021) - - Kategorien: InformationenUnterlagen - Noch kein Kommentar ...

Arduinotutorials, -experimente und -projekte in den Naturwissenschaften

Die hier veröffentlichen Anleitungen (Tutorials) gehen von den einfachsten Grundlagen der Elektronik und des Aubaus von Experimentierschaltungen über einfache Programmierung bis hin zu komplexeren Programmen. Die Teile bauen beim Verständnis der Komponenten im Prinzip aufeinenader auf, sind aber in sich selbst abgeschlossen.

Grundlagen

1. Das Steckbrett (Breadboard)

2. Steckbrett: Schaltplan und Steckbrett-Aufbau

3. Widerstands-Farbwerte

4. Arduino-Projekt: Blinkschaltung

Projekte und Experimente

5. Arduino-Projekt: Temperaturmessung mit analogem Temperatursensor

6. Experiment Verdunstungskälte

7. Experiment Albedo

8. Arduino-Projekt: Glättung von Messreihen

9. Arduino-Projekt: Helligkeitsmessung mit Fotowiderstand

10. Arduino-Projekt: Temperaturmessung mit digitalem IC DS18B20

11. Arduino-Projekt: CO2-Messung mit dem Sensor MHZ19B

12. Arduino-Projekt: Luftdruck mit BMP280-Sensor messen

 

Link zu dieser Seite:

arduino-qrcode

https://s.blikk.it/arduino-natwi

Angerer Harald - Mittwoch, 11. Dezember 2019 (Zuletzt geändert: Dienstag, 17. Dezember 2019) - - Kategorien: ArduinoExperimenteTutorials - Noch kein Kommentar ...

12. Arduino-Projekt: Luftdruck und Temperatur mit BMP280-Sensor messen

Die Hardware

Der Sensor BMP280 kann wegen seiner winzig kleinen SMD-Bauweise (Surface Mounted Device) nicht direkt an den Arduino angeschlossen werden.

Zum Glück finden sich im Internet sogenannte Breakout-Boards, das sind kleine Platinen, auf denen die Kleinteile mit arduinotauglichen Füßchen aufgelötet sind. Oft haben die Breakout-Boards auch Spannungsregler und Widerstände um die Arduinospannung an die Sensorspannung anzupassen.

Das ist beim BMP-280-Sensor auch notwendig, da er mit 3,3 Volt arbeitet. Beim Kauf also auf Arduinokompatibilität achten und auch darauf, dass das Breakout-Board die I2C-Schnittstelle des Sensor nach außen führt.

IMG_20191217_151847
Breakout-Board für BMP280 mit I2C-Schnittstelle

Die I2C-Verbindung ist ein serieller Zweidrahtbus bestehend aus einer Datenleitung (SDA), welche in beiden Richtungen funktioniert und einer Synchronisationsleitung (SCL), die den Übertragungstakt vorgibt.

Die Verdrahtung kann wie folgt vorgenommen werden:

bmp280_schaltplan

Und so könnte der Steckbrettaufbau aussehen:

bmp280_bestueckung

Die beiden von den I2C-Leitungen zur positiven Versorgungsspannung geschalteten Widerstände von 10 kΩ dienen als sogenante "Pull-Up-Widerstände" mit dem Zweck, die Leitungen im unbelastetem Zustand positiv zu halten. Bei vielen Breakout-Boards sind sie schon mit bestückt und könnten hier entfallen - andererseits schadet eine Doppelbeschaltung auch nicht.

Die Software

Zwar gibt es für die I2C-Schnittstelle eine eingebaute Arduino-Library, aber die Umrechnung der Kalibrierungswerte für den BMP280 ist laut Datenblatt etwas aufwendig, so dass sich die Installation einer Library lohnt (Quelle: https://arduino-projekte.webnode.at/meine-libraries/luftdrucksensor-bmp280/).

Die Library ist wie üblich in das Library-Verzeichnis der Arduino-Installation zu kopieren, damit sie vom Compiler gefunden werden kann. Alternativ kann auch das Library-Verzeichnis unter "Dokumente/Arduino" verwendet werden.

/*
 * Luftdruck- und Temperaturmessung mit dem Sensor BMP280
 */

// Für das Einlesen und die Kalibrierungsberechnung wird
// die Library von Retian (https://arduino-projekte.webnode.at/meine-libraries/luftdrucksensor-bmp280/)
// verwendet. Die entsprechenden Dateien dazu in das Arduino-
// Libraryverzeichnis kopieren. Die Library verwendet intern
// die Wire-Library von Arduino. Auf die entsprechende Verdrahtung achten!

#include <MyBMP280.h>

// Hier wird eine Instanz der Libraryklasse MyBMP280 definiert
// und dazu die I2C-Adresse des Bausteins übergeben: standard-
// mäßig laut Datenblatt 0x76 (Hexadezimal 76).

MyBMP280 Bmp(0x76);

// Initialisierungen

void setup() {

  // Serielle Schnittstelle zum PC initialisieren

  Serial.begin(9600);

  // Verfügbarkeit und Verdrahtung prüfen

  if ( ! Bmp.isReady()) Serial.println("Error");

  // Messgenauigkeit einstellen

  Bmp.setPressOversampling(BMP280_P_OVERSAMPLING_x2);

  // und initialisieren

  Bmp.init();

}

// Messungen periodisch durchführen und Ergebnisse im seriellen
// Monitor oder Plotter anzeigen

void loop() {

  // Temperaturmessung

  float temperature = Bmp.readTemp();
  Serial.print("Temperatur: ");
  Serial.print(temperature);
  Serial.println(" Grad Celsius");

  // Luftdruckmessung

  float pressure = Bmp.readPress();
  Serial.print("Luftdruck: ");
  Serial.print(pressure);
  Serial.println(" hPa");

  // 1 Sekunde pausieren

  delay(1000);

}

Jedes Gerät, das am I2C-Bus hängt, muss eine Adresse haben, unter der es erreichbar ist. Die Adresse wird als Byte-Wert angegeben und ist vom Gerät vorgegeben und aus dem Datenblatt abzulesen. Oft kann durch entsprechende Verdrahtung eines Pins am Sensor eine zweite Adresse gewählt werden, damit zwei baugleiche Sensoren über denselben Bus angesprochen werden können. Die erste Adresse des BMP280 ist 0x76 und wird gleich beim Erzeugen der Instanz mit übergeben (an den sogenannten "Konstruktor" der Klasse):

MyBMP280 Bmp(0x76);

Wenn die Funktion Bmp.isReady() einen als "falsch" eingestuften Wert zurückgibt, z. B. 0, dann ist der Sensor nicht erreichbar, da u. U. falsch verdrahtet, und es wird die Fehlermeldung "Error" ausgegeben:

  // Verfügbarkeit und Verdrahtung prüfen

  if ( ! Bmp.isReady()) Serial.println("Error");

Screenshots wurden mit Fritzing erstellt, falls nicht anders angegeben (https://fritzing.org)

Angerer Harald - Mittwoch, 11. Dezember 2019 (Zuletzt geändert: Mittwoch, 16. Dezember 2020) - - Kategorien: ArduinoTutorials - Noch kein Kommentar ...

11. Arduino-Projekt: CO2-Messung mit dem Sensor MHZ19B

Sensor und Messprinzip

Der Sensor MHZ19B, erhältlich z. B. bei Reichelt oder Banggood, ist ein Sensor zur Messung des CO2-Gehalts der Luft und der Temperatur.

 mhz19b
Quelle: www.banggood.com

Die CO2-Messung basiert auf dem sogenannten nichtdispersiven Infrarotprinzip, dabei wird ein Infrarotlichtstrahl durch eine mit der zu messenden Luft gefüllten Glasröhre geschickt. Ein spezieller Infrarotsensor misst am anderen Ende, wie viel Licht vom CO2 absorbiert wurde, indem die Differenz des einfallenden mit dem austretenden Licht gebildet wird.

ndir-prinzip.fwNDIP-Messung

Der CO2-Gehalt der Luft wird in PPMs (Parts per Million) angegeben. 1 ppm entspricht bei Gasen 1 µL pro Liter Gas. Normale Luft hat etwa 400 ppm CO2-Gehalt, das entspricht 0,04% CO2-Anteil.

Der Sensor funktioniert mit Spannungen bis 5,5 V und besitzt 5V-kompatible Signalein- und -ausgänge, was wichtig für den Betrieb am Arduino ist.

Der Messwert wird entweder als pulsweitenmoduliertes Rechtecksignal ausgegeben, bei dem die Länge der positiven Halbwelle dem PPM-Wert entspricht oder als serieller Digitalwert über die im Sensor befindliche serielle Schnittstelle (UART = Universal Asynchronous Receiver Transmitter). Genauere Angaben finden sich im Datenblatt. Der Sensor misst entweder 0-2000ppm oder 0-5000ppm. Der Wertebereich kann über die serielle Schnittstelle eingestellt werden.

mhz19bpinoutMHZ19B-Pinout

Im Datenblatt konnte kein Hinweis auf die Defaulteinstellung des Messbereichs gefunden werden, es scheint so, als ob verschiedene Typen des Sensors verkauft würden. Der eingestellte Messbereich kann über die UART abgefragt werden: mhtz19b_uart_get_range.ino

Die Hardware

Die Verdrahtung mit dem Arduino wird etwas erschwert, da die Anschlüsse des MHZ19B-Sensors nicht auf ein Steckbrett passen - die Verdrahtung erfolgt also "fliegend".

Es folgen zwei Verdrahtungsvarianten, die auch kombinierbar sind: einmal für die PWM-Messung und zweitens für die Messung über die UART (serielle Schnittstelle).

PWM-Messung (Pulse Width Modulation)

1280px-Pulse_wide_wave.svgMatthiasDD - Eigenes Werk, basierend auf: Square wave.svg - CC BY-SA 3.0

Der Messwert ist das Verhältnis von t1/T ausgelesen und dann auf den Wertebereich des CO2-Sensors hochgerechnet. Im Datenblatt kann man die entsprechenden Bezugwerte finden, so wird z. B. bei einer Messbereichswahl von 0-2000ppm der 0ppm-Wert mit einer Zeitdauer von 2ms (Millisekunden) angegeben und der Wert 2000ppm entspricht einer Pulsdauer von 1002ms. Die Gesamtpulsbreite T hat eine Dauer von 1004ms.

Der Anschluss an den Arduino ist sehr einfach und könnte so aussehen:

mhz19b_schaltung_pwm

So gestaltet sich die Verdrahtung mit dem Arduino bei der PWM-Messung:

mhz19b_steckbrett_pwm

UART-Messung von CO2 und Temperatur

Für die UART-Messung werden zwei beliebige Pins als RX/TX-Paar verwendet, im Beispiel Pin 2 und Pin 3.

Wichtig: Nicht die mit TXD und RXD gekennzeichneten Pins (0 und 1) verwenden! Sie gehören zur Hardware UART des Arduino und werden schon für die Programmierung über das USB-Kabel verwendet!

mhz19b_schaltplan_usart

Wichtig: Die UART-Verbindungen müssen "gekreuzt" werden: es müssen also der Arduino-RX-Pin (im Beispiel Pin 2) mit dem Sensor-TX-Pin verbunden werden und der Arduino-TX-Pin mit dem Sensor-RX-Pin.

mhz19b_steckbrett_usart

Die Software

Messung der CO2-Werte mit PWM

/**
 * CO2-Messung mit Sensor Typ MHZ19B
 * Messwerterfassung durch PWM-Signal
 */

// Der Sensor hängt an Pin 7

const int pwmpin = 7;

// Der eingestellte Messbereich (0-5000ppm)

const int range = 5000;

// Die setup()-Funktion

void setup() {

  // PWM-Pin auf Eingang setzen
  
  pinMode(pwmpin, INPUT);

  // Serielle Übertragung über USB initialisieren

  Serial.begin(9600);
  
}

// Die loop()-Funktion
 
void loop() {
  
  // Messung der PWM-Länge mittels einer eigenen Funktion
  
  int ppm_pwm = readCO2PWM();

  // Ausgabe der Werte über die serielle USB-Verbindung
  
  Serial.print("PPM PWM: ");
  Serial.println(ppm_pwm);

  // Messungen alle 3 Sekundn
  
  delay(3000);
  
}

// Die Messung der PWM-Länge erfolgt in einer eigenen
// Funktion readCO2PWM(), was die loop()-Schleife etwas "aufgeräumter"
// erscheinen lässt. Die Funktion gibt eine Ganzzahl zurück (int).

int readCO2PWM() {

  // Es werden die für die Umrechnung der Zeitdauer auf
  // die PPM-Werte benötigten Variablen definiert.
  // Da es sich bei th um große Werte handeln kann - die verwendete
  // Arduino-Funktion gibt Mikrosekunden zurück - wird diese Variable
  // als vorzeichenlose (unsigned) große Ganzzahl (long) definiert.
  
  unsigned long th;
  int ppm_pwm = 0;
  float pulsepercent;

  // Alles, was in der do ... while-Schleife steht, wird
  // solange ausgeführt, bis der Ausdruck nach while, hier
  // th == 0 als zutreffend (wahr) erkannt wird.
  // Da die Arduino-Funktion pulseIn() 0 zurückgibt, solange
  // sie am Messen ist, dient die Schleife dazu, auf den
  // Messwert zu warten.
  
  do {

    // pulseIn gibt die Dauer des am Pin (pwmpin) anliegenden
    // Signals in Mikrosekunden an. Die maximale Signallänge ist
    // 1004ms. Der Timeoutwert der pulseIn-Funktion muss also
    // mindestens 1004000µs betragen. Für ungünstige Fälle wird
    // sicherheitshalber ein größerer Wert von 2500000µs gewählt.
    // Die Ausgabe der pulseIn()-Funktion wird durch 1000 geteilt
    // und ergibt so für th die Signallänge in Millisekunden (ms).
    
    th = pulseIn(pwmpin, HIGH, 2500000) / 1000;

    // Pulslänge in Prozent (%)

    float pulsepercent = th / 1004.0;

    // PPM-Werte bei gegebenem Range
    
    ppm_pwm = range * pulsepercent;
    
  } while (th == 0);
  
  // Der gemessene Wert wird an die loop()-Funktion zurückgegeben,
  // wo er dann ausgegeben wird.
  
  return ppm_pwm; 
}

Folgendes ist neu:

 int ppm_pwm = readCO2PWM();

Neben den beiden Standard-Arduino-Funktionen setup() und loop() wird hier eine eigene neue Funktion verwendet: readCO2PWM(). Die Funktion gibt im Unterschied zu den anderen beiden Funktionen den Typ int zurück.

unsigned long th;

Der Typ "unsigned long" kann sehr große Ganzzahlen fassen: 0 - 4.294.967.295, wobei "unsigned" bedeutet, dass keine negativen Zahlen möglich sind.

 do {

   ...
    
  } while (Audruck);

Die do ... while-Schleife läuft, solange der Ausdruck gültig (wahr) ist. Da die Prüfung des Ausdrucks am Ende der Schleife erfolgt ("fußgesteuert") wird der Inhalt der Schleife auf alle Fälle mindestens einmal ausgeführt.

Messung der CO2-Werte mit UART

Die Messung über die UART erfolgt über standardisierte Befehle (commands) von 9 Byte Länge (s. Datenblatt) und ebenso langen Antworten (responses).

/**
 * CO2-Messung mit Sensor Typ MHZ19B
 * Messdatenerfassung über UART (serielle Schnittstelle)
 */

// Da die Hardware-UART des Arduino vom USB-Kabel belegt
// und über die Funktionen der Serial-Klasse schon 
// verwendet werden, braucht es die SoftwareSerial-Klasse
// (gehört zu den Arduino-Standardklassen) mit deren Hilfe
// beliebige Pins als RX/TX-Verbindungen verwendet werden
// können (mit Ausname von Pin 0 und Pin 1)

#include <SoftwareSerial.h>

// Hier wird eine Instanz der Klasse mit den Pins 2 (RX) und 3 (TX)
// initialisiert

SoftwareSerial co2Serial(2, 3); // define MH-Z19 RX TX

// In der setup()-Funktion werden sowohl die Hardware-
// als auch die Software UART initialisiert
 
void setup() {
  
  Serial.begin(9600);
  
  co2Serial.begin(9600);
  
}

// Die loop() Funktion liest mit Hilfe der eigenen
// Funktion readSensor() die
// Sensorwerte aus und schreibt sie über die serielle
// USB-Verbindung auf den angeschlossenen Computer.
 
void loop() {

  int ppm, temperature = 0;

  readSensor(&ppm, &temperature);

  Serial.print("PPM: ");
  Serial.print(ppm);
  Serial.print(" Temperature: ");
  Serial.println(temperature);
  
  delay(5000);
}

// Die Funktion liest die CO2-Werte über die UART des
// Sensors ein und schreibt die ermittelten Werte mit
// Hilfe der übergebenen Pointer in die Variablen ppm
// und temperature.

void readSensor(int *ppm, int *temperature){

  // Die Befehlskette zum Einlesen des PPM-Wertes laut Datenblatt
  
  byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};

  // Speicherplatzreservierung von 9 Byte für die Antwort des Sensors.
  // Alles Befehle und Antworten des Sensors haben eine Länge von
  // 9 Byte, wobei das letzte Byte eine Prüfsumme zur Kontrolle
  // der Übermittlung darstellt.
  
  byte response[9]; 

  // Befehl zum Auslesen schreiben
  
  co2Serial.write(cmd, 9);

  // Zuerst den Eingangsbuffer löschen (mit 0 füllen) und
  // danach in einer while-Schleife darauf warten, bis 
  // die Funktion co2Serial.available() einen Wert ungleich 0
  // zurückgibt.
  
  memset(response, 0, 9);
  while (co2Serial.available() == 0) {
    delay(1000);
  }

  // Die Antwort wird in den Speicher eingelesen.
  
  co2Serial.readBytes(response, 9);

  // Die Prüfsumme mit Hilfe einer eigenen Funk-
  // tion errechnen, um zu klären, ob die 
  // Übertragung fehlerfrei abgelaufen ist.
  
  byte check = getCheckSum(response);
  
  if (response[8] != check) {
    Serial.println("Fehler in der Übertragung!");
    return;
  }
 
  // PPM-Wert errechnen, sie finden sind
  // im 3. und 4. Byte der Antwort im Format
  // HIGH-Byte und LOW-Byte und müssen über die
  // folgende Formel zu einem Word (int) verkettet
  // werden.
  
  *ppm = 256 * (int)response[2] + response[3];

  // Temperaturwert wird als 5. Byte der Response
  // übermittelt (im Datenblatt nicht angegeben).
  // Damit auch negative Temperaturen übertragen 
  // werden können, wurde der Wert 40 dazuaddiert,
  // der jetzt wieder entfernt werden muss.
  
  *temperature = response[4] - 40;

}

// Die Funktion errechnet eine Prüfsumme über die
// durch einen Zeiger übergebene Befehls- oder
// Antwortkette. Der Algorithmus zur 
// Prüfsummenberechnung findet sich im
// Datenblatt.

byte getCheckSum(byte *packet) {
  byte i;
  byte checksum = 0;
  for (i = 1; i < 8; i++) {
    checksum += packet[i];
  }
  checksum = 0xff - checksum;
  checksum += 1;
  return checksum;
}

 Was ist neu:

void readSensor(int *ppm, int *temperature) { ... }

Die Definition der eigenen Funktion readSensor() ist wie folgt zu verstehen: die Funktion gibt keinen Wert zurück (void) und erhält zwei Zeiger (Pointer) auf int-Werte, durch das Sternchensymbol angedeutet. Der Grund für diese Vorgangsweise ist die Tatsache, dass Funktionen immer nur einen einzigen Wert zurückgeben können, wir hier aber zwei Werte haben wollen. Deswegen erhält die Funktion die Adressen von zwei Variablen, in die sie die Werte schreiben kann. Diese Werte können dann von der aufrufenden Funktion ausgelesen und weiterverwendet werden. Beim Aufruf der readSensor()-Funktion müssen die Adressen der beiden Variablen angegeben werden, was durch das vorangestellt "&" gekennzeichnet wird:

 readSensor(&ppm, &temperature);

Beim Beschreiben der Variablen ist dann ebenfalls die Pointer-Schreibweise zu verwenden, damit nicht die Adressen überschrieben werden:

*temperature = response[4] - 40;

Die Funktion

 memset(response, 0, 9);

ist fest in Arduino eingebaut. Die Funktionen

co2Serial.available(), co2Serial.write() und co2Serial.readBytes()

sind in der eingebunden SoftwareSerial-Klasse verfügbar (bzw. deren Instanz co2Serial).

 

Weiterführendes

CO2-Ampel selber bauen (Robert Helling)


Screenshots wurden mit Fritzing erstellt, falls nicht anders angegeben (https://fritzing.org)

Angerer Harald - Montag, 9. Dezember 2019 (Zuletzt geändert: Dienstag, 15. März 2022) - - Kategorien: ArduinoTutorials - 9 Kommentare

10. Arduino-Projekt: Temperaturmessung mit digitalem IC DS18B20

Der digitale Temperatursensor DS18B20 ist ein IC (Integrated Circuit), das die Temperaturwerte über einen seriellen Datenbus an den Arduino weitergibt. Laut Datenblatt arbeitet der Sensor in einem Temperaturbereich von -55°C bis +125°C.

Durch die serielle digitale Datenleitung kann der Sensor auch über eine relativ lange Leitung (ein Meter und mehr) ohne Messwertverfälschung angeschlossen werden.

Es gibt im Internet verschiedene "vergossene" Varianten mit Verbindungskabel, z. B. hier: https://www.az-delivery.de:

ds18b20
Quelle: https://www.az-delivery.de

Hardware

Die Verdrahtung des Sensors ist sehr einfach:

ds18b20_schaltplan

Für die Funktion wird der Widerstand R1 (Pullup-Widerstand genannt, weil er die Spannung bei fehlendem Signal auf die Versorgungsspannung hochzieht) benötigt, was im Datenblatt so nicht gleich ersichtlich ist.

Hier der Steckbrettaufbau:

ds18b20_steckbrett

Und so eine reale Verdrahtung:

IMG_20191206_163955

Programmierung

Der serielle Datenbus (1-Wire-Bus) und das vom Sensor verwendete Protokoll erfordern erheblichen Programmieraufwand, zum Glück kann die Arduino-IDE um externe Zusatzmodule (Libraries) erweitert werden und für den Sensor gibt es eine solche. Es werden folgende Libraries benötigt:

Die beiden entpackten Verzeichnisse müssen in das Libraries-Verzeichnis der Arduinoinstallation kopiert werden, z. B. nach C:\Program Files (x86)\Arduino\libraries.
 
/**
 * Temperaturmessung mit dem Sensor D18B20
 */

// Die benötigten Libraries werden eingebunden

#include <OneWire.h>
#include <DallasTemperature.h>

// Definition des Pin, an dem der Sensor hängt

#define SENSOR 9

// Jetzt wird ein OneWire-Instanz mit dem Namen "wire" erzeugt. 
// Das ist eine Variable, die alle Funktionen der Klasse 
// OneWire enthält, wie sie in der OneWire-Library definiert ist. 
// Die Instanz erhält gleich die Pinnumber mitgeteilt an der 
// der Sensor hängt. Das ist die One-Wire-Bus-Verbindung.

OneWire wire(SENSOR);

// Jezt wird eine Instanz der Klasse DallasTemperature
// erzeugt, wie sie in der gleichnamigen Library definiert
// ist. Die Instanz heißt "sensors" und bekommt bei der
// Erzeugung eine Referenz (Zeiger) auf die wire-Variable.
// Dass es sich um eine Referenz handelt, wird durch das
// vorangestellte "&" deutlich gemacht.

DallasTemperature sensors(&wire);

// Die setup()-Funktion

void setup(void)
{
  
  // Serielle Verbindung initialisieren
  
  Serial.begin(9600);

  // Die Library initialisieren
  
  sensors.begin();

}
  

// In der loop()-Funktion werden die Temperaturwerte eingelesen und 
// über die serielle Schnittstelle ausgegeben.

void loop(void)
{
  
  // Die Sensoren am Bus (es sind auch mehrere möglich!) werden
  // angewiesen die Temperaturwerte zu eruieren
  
  sensors.requestTemperatures(); // Send the command to get temperatures

  // Nun werden die Temperaturwerte in Grad Celsius vom ersten (und
  // einzigen) Sensor geholt, der den Index 0 hat.
  
  float temperature = sensors.getTempCByIndex(0);

  // Hier wird geprüft, ob eine sinnvolle Temperatur zurückgegeben
  // wird oder der Wert -127 (der in der DallasTemperature-Library
  // als DEVICE_DISCONNECTED_C definiert ist).
  
  if(temperature != DEVICE_DISCONNECTED_C) {

    // anzeige der Temperatur
    
    Serial.print("Grad Celsius: ");
    Serial.println(temperature);
    
  } else  {

    // Ausgabe einer Fehlermeldung
    
    Serial.println("Error: Die Temperatur kann nicht gelesen werden!");
    
  }
}

 Einige Erläuterungen:

// Die benötigten Libraries werden eingebunden

#include <OneWire.h>
#include <DallasTemperature.h>

Damit der Arduino-Sketch Zugriff auf die Funktionen der Libraries hat, müssen diese ins Programm eingebunden werden, was diese beiden Anweisungen bewirken.

// Definition des Pin, an dem der Sensor hängt

#define SENSOR 9

Das ist ein Variante zu Definition einer Konstante und wirkt im Wesentlichen wie eine const-Definition.

OneWire wire(SENSOR);

In C++ kann man Objekte definieren, die verschiedene Variablen, Konstanten und Funktionen beinhalten. Wir haben das bei der Klasse "Serial" gesehen. Im Gegensatz zur Serial-Klasse wird bei der OneWire-Klasse aber nicht direkt auf die Funktion in der Klasse zugegriffen, sondern es wird zuerst eine Instanz (Objekt) der Klasse mit dem Namen "wire" definiert. Auf diese Weise könnten auch mehrere unabhängige Instanzen der Klasse "OneWire" definiert werden, z. B. wireOne, wireTwo, was notwendig wäre, wenn mehrere Sensoren am Arduino hingen.

Die Klasseninstanz "wire" erhält die Pinnummer SENSOR (Pin 9) gleich bei der Erzeugung mitgeteilt.

DallasTemperature sensors(&wire);

Genauso ist "sensors" eine Instanz der Klasse "DallasTemperature", die in der gleichnamigen Library definiert ist. Die Instanz "sensors" erhält bei der Erzeugung ebenfalls gleich einen Wert übergeben, der allerdings durch das vorangestellte & etwas Besonderes ist, nämlich eine Referenz oder Zeiger auf eine Klasse. Im speziellen Fall eine Referenz auf die Instanz von "wire".

Referenzen sind nicht die Objekte selber, sondern nur Verweise darauf, ähnlich wie Adressen oder Internet-Links. Die Referenz spart Speicherplatz, da das referenzierte Objekt (hier die Instanz "wire") nur einmal mit allem Drum und Dran im Speicher existiert und die Funktionen der Instanz "sensors" trotzdem darauf zugreifen können.

Kniffliges

1. Modifizieren Sie die Hard- und Software so, dass ein zweiter Sensor desselben Typs angeschlossen werden kann.

2. Kombinieren Sie einen analogen Sensor des Typs TMP36 wie hier beschrieben und vergleichen Sie die Messwerte.

Screenshots wurden mit Fritzing erstellt, falls nicht anders angegeben (https://fritzing.org)

Angerer Harald - Freitag, 6. Dezember 2019 - Kategorien: ArduinoTutorials - Noch kein Kommentar ...

9. Arduino-Projekt: Helligkeitsmessung mit Fotowiderstand

Ein Fotowiderstand, auch LDR - Light Dependend Resistor - genannt, ändert seinen Widerstandswert mit dem einfallenden Licht: Je mehr Licht, desto geringer ist der Widerstand.

Hardware

Wird ein Fotowiderstand wie in der vorgeschlagenen Schaltung unten als Spannungsteiler geschaltet, ist die gemessene Spannung am Teiler (U2) umso größer, je mehr Licht auf den Widerstand fällt, d. h. je geringer sein Wert ist (vgl. die Formel):

helligkeit_schaltplan

Der Steckbrettaufbau kann wie folgt aussehen:

helligkeit_bestueckung

Programmierung

Das folgende Programm misst die Rohwerte der Spannung an A1, d. h. Werte im Bereich von 0 - 1023, denn der Arduino Analog-Digital-Wandler, der für die Messung verwendet wird, hat eine Auflösung von 10 Bit in der Standardeinstellung. Wird als Referenzspannung die Versorgungsspannung von 5V verwendet entspricht das einem Wertebereich von 0V - 5V.

Wir müssen uns mit den Rohwerten begnügen, da in den seltesten Fällen ein Lichtmessgerät (Luxmeter o. Ä.) zum Eichen zur Verfügung steht.

/**
 * Helligkeitsmessung mit einem Fotowiderstand
 */

// Pinbezeichnung des analogen Messeingang

const byte lightSensor = A1;

// In der setup()-Funktion wird die serielle
// Schnittstelle zum Anzeigen der Werte initialisiert
// und der Pin "lightSensor" auf INPUT geschaltet (braucht es
// eigentlich nicht, denn nach dem Reset sind alle
// Pins auf INPUT.

void setup() {

  Serial.begin(9600);

  pinMode(lightSensor,INPUT);
  
}

// Im loop() wird die Spannung am Pin "sensor" gemessen
// und in eine Tempteraturangabe in °C umgerechnet und
// über die serielle Anzeige (USB-Kabel übernimmt diese
// Funktion) ausgegeben.

void loop() {

  // Messwert als Rohwert im Bereich 0 - 1023
  // einlesen

  int light = analogRead(lightSensor);

  // Rohwerte ausgeben

  Serial.print("Helligkeit: ");
  Serial.println(light);

  // und etwas warten für die nächste Messung
  
  delay(1000);

}

Kniffliges

1. Verändern Sie die Schaltung so, dass die Messlogik umgekehrt funktioniert, d. h. bei weniger Licht steigt der gemessene Wert.

2. Sie können die Schaltung in Kombination mit der für die Albedomessung vorgeschlagenen Temperaturmessung verwendung um die Bestrahlungsleistung der Heizquelle (Lampe) in beiden Versuchen konstant zu halten.

Screenshots wurden mit Fritzing erstellt, falls nicht anders angegeben (https://fritzing.org)

Angerer Harald - Freitag, 6. Dezember 2019 - Kategorien: ArduinoTutorials - Noch kein Kommentar ...

8. Arduino-Projekt: Glättung von Messreihen

Im "5. Arduino-Projekt: Temperaturmessung mit analogem Temperatursensor" haben Sie vielleicht gemerkt, dass durch die Messfehler starke Ausschläge im seriellen Plot oder Schwankungen in den Daten aufgetreten sind.

Ohne den Aufbau der Schaltung zu ändern kann das programmtechnisch durch eine größere Samplerate (Messungen pro Sekunde) und Durchschnittsbildung der Messwerte aufgefangen werden.

/**
 * Temperaturmessung mit TMP36 und Durchschnittsbildung
 */

// Pinbezeichnung des analogen Messeingang

const byte sensor = A0;

// Anzahl der Summanden, Zähler und summe

const int sampleTime = 1000;
const int num = 100;
int counter = 0;
float sum = 0.0;

// In der setup()-Funktion wird die serielle
// Schnittstell zum Anzeigen der Werte initialisiert
// und der Pin "sensor" auf INPUT geschaltet (braucht es
// eigentlich nicht, denn nach dem Reset sind alle
// Pins auf INPUT.

void setup() {

  Serial.begin(9600);

  pinMode(sensor,INPUT);
  
}

// Im loop() wird die Spannung am Pin "sensor" gemessen
// und in eine Tempteraturangabe in °C umgerechnet und
// über die serielle Anzeige (USB-Kabel übernimmt diese
// Funktion) ausgegeben.

void loop() {

  float temperature;
  float avg;

  // Anzahl der Summanden schon erreicht?
  if (counter >= num) {

    // durchschnitt errechnen
    avg = sum / num;
    
    // Ausgabe der Werte über die serielle Schnittstelle
  
    Serial.print("Grad Celsius: ");
    Serial.println(avg);

    // Zähler und summe zurücksetzen
    
    counter = 0;
    sum = 0.0;
    
  }

  // sensorValue enthält den Rohwert der gemessenen
  // Spannung. Der Arduino kann in der Standard-
  // konfiguration Spannungen mit einer Auflösung
  // von 10 Bit lesen. Damit lassen sich Werte von
  // 0 - 1023, also 1024 Werte abbilden.
  // Als Referenzspannung wird in der
  // Standardkonfiguration dabei die Betriebsspannung
  // von 5V verwendet. Man erhält also Rohwerte 
  // zwischen 0 (0V) und 1024 (5V).
  
  int sensorValue = analogRead(sensor);

  // Umrechnung des Rohwertes in Volt (s. oben)

  float volt = (sensorValue / 1024.0) * 5.0;

  // Umrechnung der Spannung in Temperatur. Die
  // verwendeten Werte ergeben sich aus dem Datenblatt
  // des Sensors.

  temperature = (volt - 0.5) * 100;

  // werte aufsummieren

  sum += temperature;

  // counter erhöhen
  
  counter++;

  // und etwas warten für die nächste Messung
  
  delay(sampleTime / num);

}

Einige Erläuterungen:

// Anzahl der Summanden, Zähler und summe

const int sampleTime = 1000;
const int num = 100;
int counter = 0;
float sum = 0.0;

sampleTime : die Konstante ist die Zeitdauer zwischen zwei Messausgaben in Millisekunden
num : Anzahl der Messungen pro Sampletime. Die Werte bedeuten, dass alle 10 ms (1000 ms / 100) eine Messung durchgeführt und 100 Messungen aufaddiert und als Durchschnitt ausgegeben werden
counter : zählt von 0 - 99, also 100 Messungen
sum : die Summe der Messungen, sie wird nach 100 Messungen durch 100 dividiert. Die Variable muss float sein und wird deshalb mit 0,0 initialisiert.

  float temperature;
  float avg;

temperature : enthält die aus den Spannungen am Sensor errechnete temperatur
avg : Durchschnittswert der Messungen, wird alle 1000 ms ausgegeben

Achtung: die beiden Variablen sind innerhalb der loop()-Funktion definiert und können nur dort verwendet werden und sie sind nicht initialisiert, haben also keinen Anfangswert. Das ist deshalb nicht notwendig, da die Variablen weiter unten in der loop()-Funktion einen definierten Wert erhalten.

  // Anzahl der Summanden schon erreicht?
  if (counter >= num) {

    // durchschnitt errechnen
    avg = sum / num;
    
    // Ausgabe der Werte über die serielle Schnittstelle
  
    Serial.print("Grad Celsius: ");
    Serial.println(avg);

    // Zähler und summe zurücksetzen
    
    counter = 0;
    sum = 0.0;
    
  }

if (Ausdruck) { Anweisungen; ... } : wenn der Ausdruck "wahr" ist, werden alle Anweisungen zwischen den geschwungenen Klammer ausgeführt, sonst übersprungen
counter >= num : gibt "wahr" zurück, wenn der counter größer als oder gleich groß wie num ist

Konkret heißt das, dass die in den geschwungenen Klammern stehende Durchschnitssberechnung und die serielle Ausgabe 100 mal übersprungen werden, dann einmal gemacht, wieder 100 mal übersprungen usw. Wichtig: das Zurücksetzen des Zählers und Durchschnitts (counter, sum) darf nicht vergessen werden.

  // werte aufsummieren

  sum += temperature;

  // counter erhöhen
  
  counter++;

sum += temperature : ist die kurze Form für sum = sum + temperature
counter++ : ist die kurze Form für counter = counter + 1, counter wir bei jedem Durchlauf um eins erhöht

Achtung: die Ausdrücke sind nicht als mathematische Formeln zu lesen, sonst würden sie im ersten Beispiel nur für einen speziellen Fall und im zweiten Beispiel überhaupt nie zutreffen. Das Programm macht vielmehr Folgendes: der rechts vom "ist gleich" (=) stehende Teil wird berechnet und danach in der Variablen links abgespeichert, wobei der alte Inhalt überschrieben wird. Beispiel: counter hat den Wert 4, der rechte Teil ist also 4 +1 ergibt 5, jetzt wird counter = 5 gesetzt, der alte Wert (4) ist verloren.

Kniffliges

1. Erweitere die Temperaturmessschaltung mit Hilfe der if-Anweisung und zusätzlicher Hardware so, das das Überschreiten oder Unterschreiten einer oderer mehrer Temperaturgrenzwerte mit Hilfe einer oder mehrer Leds signalisiert wird.

2. Erweitere die oben angeführte Schaltung so, dass eine angeschlossene Led mit zunehmender Temperatur schneller blinkt.

Angerer Harald - Freitag, 6. Dezember 2019 - Kategorien: ArduinoTutorials - Noch kein Kommentar ...

7. Experiment Albedo

Als Albedo wird das Maß für das Rückstrahlvermögen von Oberflächen beschrieben. Es spielt u. a. in der Glaziologie (Gletscherkunde) eine wichtige Rolle. Helle Oberflächen haben eine größere Albedo als dunkle Oberflächen. Das kann mit einem Experiment nachgewiesen werden, das sich des in "5. Arduino-Projekt: Temperaturmessung mit analogem Temperatursensor" vorgestellten Aufbaus und Programms bedient.

1. Platziere Arduino und Steckbrett mit Sensor auf weißem Grund und halte möglichst nahe eine Wärmequelle, z. B. Glüh- oder Halogenlampe und halte den Temperaturverlauf mit dem seriellen Monitor fest und kopiere zum Schluss die Daten in ein Tabellenkalkulationsarbeitsblatt.

IMG_20191206_124953

2. Wiederhole die Messung mit einem schwarzen Untergrund. Idealerweise sollte auch das weiße Steckbrett bis auf eine Sensoröffnung mit schwarzem Papier abgedeckt werden. Zuvor allerdings muss die gesamte Schaltung samt Steckbrett wieder auf die Zimmertemperatur zurückgegangen sein.

IMG_20191206_100657

3. Die Messreihen können nun mit Hilfe einer Tabellenkalkulation miteinander verglichen und als Liniengrafiken angezeigt werden.

Angerer Harald - Freitag, 6. Dezember 2019 - Kategorien: ArduinoExperimente - Noch kein Kommentar ...

6. Experiment Verdunstungskälte

Bei der Verdunstung von Flüssigkeiten (z. B. Wasser) entsteht Kälte. Das kann mit der in "5. Arduino-Projekt: Temperaturmessung mit analogem Temperatursensor" vorgestellten Schaltung experimentell überprüft werden.

1. Ein Wattebausch wird mit Alkohol getränkt, da Alkohol bei Zimmertemperatur viel schneller als z. B. Wasser verdunstet.

IMG_20191206_090514

2. Den Wattebausch mit einem Stück Klarsichtfolie als Isolierung an den Temperatursensor der Schaltung geben und den seriellen Plotter oder den seriellen Monitor starten. Nicht vergessen, die Klarsichtfolie oben zu öffnen, damit die Verdunstung schneller vor sich geht.

IMG_20191206_090530

Jetzt heißt es ein bisschen Geduld aufzubringen und die Temperaturverläufe zu beobachten.

Nach einiger Zeit (10 - 20 Minuten) zeigen sich um 2 - 3 Grad niedrigere Temperaturen:

rtmp://fms.blikk.it/vod_forum:::mp4:neuemedien/fb/uploads/media/video_5dea3e3b321f8.mp4:::./forums/neuemedien/fb/uploads/media/video_5dea3e3b321f8.jpg

Angerer Harald - Freitag, 6. Dezember 2019 - Kategorien: ArduinoExperimente - Noch kein Kommentar ...

5. Arduino-Projekt: Temperaturmessung mit analogem Temperatursensor

Der Sensor

Für dieses Projekt wird der dem Arduino-Kit beiligende Temperatursensor oder ein ähnlicher verwendet:

IMG_20191206_072324TMP36 - Temperatursensor

Der Sensor kann laut Datenblatt mit einer Spannung bis 7V betrieben werden und liefert am Ausgang eine Spannung von 100 mV bis 2000 mV:

tmp36datasheet

Bei 25° C sind das 750 mV. Der Sensor liefert 10mV/1°C und hat einen Temperaturbereich von -40° C bis +125° C:

tmp36datasheet2

Das bedeutet, dass 0° C ein Spannungswert von 750mV - 25 * 10mV = 500mV anliegen.

tmp36datasheet1
Pin-Out des TMP36

Die Hardware

Der Anschluss des Temperatursensor TMP36 gestaltet sich sehr einfach, es wird der Ausgang des Sensors mit dem analogen Eingang A0 des Arduino verbunden:

tmp36schaltung

Und so kann der Aufbau mit dem Steckbrett aussehen:

tmp36aufbau

So könnte der Aufbau in echt aussehen:

IMG_20191206_090335

Programmierung

/**
 * Temperaturmessung mit TMP36
 */

// Pinbezeichnung des analogen Messeingang

const byte sensor = A0;


// In der setup()-Funktion wird die serielle
// Schnittstell zum Anzeigen der Werte initialisiert
// und der Pin "sensor" auf INPUT geschaltet (braucht es
// eigentlich nicht, denn nach dem Reset sind alle
// Pins auf INPUT.

void setup() {

  Serial.begin(9600);

  pinMode(sensor,INPUT);
  
}

// Im loop() wird die Spannung am Pin "sensor" gemessen
// und in eine Tempteraturangabe in °C umgerechnet und
// über die serielle Anzeige (USB-Kabel übernimmt diese
// Funktion) ausgegeben.

void loop() {

  // sensorValue enthält den Rohwert der gemessenen
  // Spannung. Der Arduino kann in der Standard-
  // konfiguration Spannungen mit einer Auflösung
  // von 10 Bit lesen. Damit lassen sich Werte von
  // 0 - 1023, also 1024 Werte abbilden.
  // Als Referenzspannung wird in der
  // Standardkonfiguration dabei die Betriebsspannung
  // von 5V verwendet. Man erhält also Rohwerte 
  // zwischen 0 (0V) und 1024 (5V).
  
  int sensorValue = analogRead(sensor);

  // Umrechnung des Rohwertes in Volt (s. oben)

  float volt = (sensorValue / 1024.0) * 5.0;

  // Umrechnung der Spannung in Temperatur. Die
  // verwendeten Werte ergeben sich aus dem Datenblatt
  // des Sensors.

  float temperature = (volt - 0.5) * 100;

  // Ausgabe der Werte über die serielle Schnittstelle

  Serial.print("Grad Celsius: ");
  Serial.println(temperature);

  // und etwas warten für die nächste Messung

  delay(1000);

}

Was ist neu?

  Serial.begin(9600);

Der Arduino bietet die Möglichkeit Werte und Texte über das USB-Kabel, das im Betrieb als serielle Datenverbindung zum PC fungiert, auszugeben. Die Werte werden mit dem "seriellen Monitor" angezeigt, der über das Symbol oben rechts in der Arduino-IDE geöffnet wird:

arduino_seriellermonitor

Serial : stellt den Bezug zu einer Klasse (oder einem Objekt) mit dem Namen "Serial" her, das fest in Arduino eingebaut ist. Die Klasse "Serial" besitzt eine Funktion "begin()".
Serial.begin() : ruft diese Funktion auf. Der Punkt (.) trennt den Klassen- vom Funktionsnamen.
9600 : gibt die sogenannte Baud-Rate an, das ist die Übertragungsgeschweindigkeit in Bits/s an. Der in der Serial.begin()-Funktion angegebene Wert muss mit den Einstellungen des seriellen Monitors oder des seriellen Plotters übereinstimmen.

 int sensorValue = analogRead(sensor);

analogRead() : die Pins A0 bis A5 können Analoge Spannungswerte mit Hilfe dieser Funktion einlesen, standardmäßig in 10-Bit-Auflösung (0-1023)
int sensorValue : eine Variable vom Typ "integer" (ganzzahlig), die Werte von -32,768 to 32,767 erfassen (ein byte-Typ wäre hier zu klein gewählt)

float volt = (sensorValue / 1024.0) * 5.0;

float volt : definiert eine Varibale mit Namen "volt" vom Typ "float", hier können sogenannte Fließkommazahlen abgespeichert werden, das sind sehr große und sehr kleine Zahlen, auch mit Nachkommastellen
1024.0 und 5.0 : der Punkt ist ein (angelsächsisches) Komma und wird hier angegeben, damit der Compiler, der den Arduino-Sketch in Maschinensprache übersetzt, gezwungen wird, das Ergebnis mit Nachkommastellen zu berechnen (da sensorValue ja eine Ganzzahl ist)

  Serial.print("Grad Celsius: ");
  Serial.println(temperature);

Serial.print : gibt die Zeichenkette "Grad Celsius: " über die serielle Verbindung am PC aus. Die Anführungszeichen markieren eine Zeichenkette, sonst würde der Compiler davon ausgehen, das "Grad" oder "Celsius" Variablen sind
Serial.println : dasselbe wie Serial.print, hängt aber zusätzlich einen Zeilenumbruch (ln) an, so dass die nächste Ausgabe in eine neue Zeile geschrieben wird. Hier wird der Inhalt der Variable "temperature" ausgegeben

Kniffliges

1. Den Aufbau und das Programm so erweitern, das bei jeder Messwertausgabe ein Led kurz blinkt.

2. Die Werte über den seriellen Plotter unter "Werkzeuge" im Arduino-Menu plotten lassen.

 

Screenshots wurden mit Fritzing erstellt, falls nicht anders angegeben (https://fritzing.org)

Angerer Harald - Freitag, 6. Dezember 2019 - Kategorien: ArduinoTutorials - Noch kein Kommentar ...