Experimente mit Hall Sensor und Multi Function Shield
Das Multi Function Shield, das ich ja bereits vorgestellt habe und das mittlerweile ja auch um einen Drehgeber erweitert wurde, bietet mit der Möglichkeit zur einfachen Anzeige von Daten auf seinem 4-fach-7-Segment-Display und den freien Anschlusspins eine gute Grundlage, Sensoren ausprobieren.Das Letzte mal ging es um Reed Kontakte / Sensoren. Heute geht es um die artverwandten Hall-Sensoren. Auch sie reagieren auf magnetische Felder. Von der Sensoren fand ich gleich drei Bauteile in meiner 37-in-one-Sensoren-Bulk-Sammlung.
Hardware: Hall-Sensoren

Hall Sensoren nutzen den nach Edwin Hall benannten Hall-Effekt, bei dem eine sogenannte Hall-Spannung entsteht, wenn ein magnetisches Feld einen Stromfluss schneidet.
Damit ist auch gleich klar, dass ein Hall-Sensor im Gegensatz zu einem Reed Kontakt eine Versorgungsspannung benötigt, um diesen Strom fließen lassen zu können. Ein weitere Nachteil ist, dass Hall-Sensoren gegen elektrostatische Entladungen zerstört werden können, was bei Reed-Kontakten nicht der Fall ist.
Dafür kann man Hall-Sensoren kleiner produzieren und sie vermögen, auch die Flußdichte in gewissen Grenzen zu messen, während Reedschalter nur die Zuständen an und aus kennen.
Auf dem Foto ist ganz links das Modul KY-035 mit einem 49E-Hall-Sensor.
In der Mitte des Foto findet sich das Modul KY-003 mit einem Sensor vom Typ 3144.
Diese beiden Module verfügen über 3 Anschlüsse (von oben nach unten, Vorderseite oben, Pins rechts):
- S = Data / Analog Out
- = +5V
- - = GND
Zu beachten ist auch, dass die Sensoren jeweils zu der Fläche, auf dem die Typenbezeichnung aufgedruckt ist, empfindlich sind und auf der anderen Seite nicht.
Technische Daten:
49E 3144
Vers.-Spannung 2.3 ... 10 V 4.5 ... 24 V
Ouput Spannung 2.3 ... 2.7 V
Leistungsaufnahme 6.5 mA typ. 4.4 mA (max 9 mA)
max. Temperatur 120 °C -40 ... 150 °C
Empfindlichkeit 1.7 ... 3.2 mV/Gauß 70 ... 350 Gauß
Rauschen 90 mV
Einschaltzeit typ. 0.04 µs (max 2)
Ausschaltzeit typ. 0.18 µs (max 2)
Ergebnisse sind temperaturabhängig
Gegenüber dem KY-035 verfügt das KY-003 noch über eine LED samt Vorwiderstand, die leuchtet, wenn ein fest eingestellter Schwellenwert (8mm-Neodym-Magnet auf ca. 1 cm Entfernung) erreicht ist.Ganz rechts auf dem Foto ein KY-024-Modul, ebenfalls mit einem 49E-Sensor und mit einem zusätzlichen LM393 Vergleichs-Chip und einem Potentiometer, um einzustellen, ab welchem analogen Wert der digitale Ausgang auf HIGH gehen soll.
Die Anschlussbelegung ist hier (von oben nach unten, Vorderseite oben, Pins rechts):
- AO = Analog Out
- G = GND
- + = +5V
- DO = Digital Out
Fidget Spinner ohne Rauschunterdrückung
Hier benutze ich den selben Versuchsaufbau mit der gleichen Software, die ich auch schon als Drehzahlmesser beim Reed-Sensor eingesetzt hatte.
Fidget Spinner mit Rauschunterdrückung
Die Software muss also nachgearbeitet werden, so dass das Rauschen ignoriert wird. Dazu nehme ich nun das analoge Signal her und schaue, ob dessen Wert im Kernbereich liegt, und auch (wichtig, wenn der Wert genau an der Kern-Grenze fluktuiert), ob das davor gemessene Signal darin lag.Der angepasste Code sieht dann so aus:
Source-Code
Hier der Source-Code für den Umdrehungsmesser:Umdrehungsmesser.ino (klicken, um diesen Abschnitt aufzuklappen)
////////////////////////////////////////////////////////
// (C) 2018 by Oliver Kuhlemann //
// Bei Verwendung freue ich mich über Namensnennung, //
// Quellenangabe und Verlinkung //
// Quelle: http://cool-web.de/arduino/ //
////////////////////////////////////////////////////////
#include <TimerOne.h> // für Timings und Interrupts
#include <MultiFuncShield.h> // API für das Multi Function Shield
#define PinData 5 // wo ist Digital Out angeschlossen?
#define PinAnalog A5 // wo ist Analog Out angeschlossen?
void setup() {
Timer1.initialize();
MFS.initialize(&Timer1); // initialize multi-function shield library
pinMode (PinData, INPUT_PULLUP);
Serial.begin (115200);
}
void loop() {
MFS.beep(1, 5, 2); // bereit
long mic=0;
long micBef=micros();
long micDelta=0;
byte stateBef=HIGH;
byte state=HIGH;
float upm=0;
int normal=analogRead(PinAnalog); // Wert ohne magnetischen Einfluß, kleiner ist höhere Flußdichte
int ana=normal;
int anaBefore=normal;
while (1) {
anaBefore=ana;
ana=analogRead(PinAnalog);
Serial.println(ana);
//state=digitalRead(PinData); // nein, stattdessen Methode mit Flimmerkompensation benutzen
state=0;
if (ana <= normal-70 or anaBefore <= normal-70) state=1; // ggf. muss die 70 angepasst werden
// piepen mit State, Beeper ist Pin 3
digitalWrite(3, !state);
MFS.writeLeds(LED_1, state);
// wenn Statusänderung
if (state != stateBef) {
// Zählbeginn, wenn Flanke auf HIGH (=geschlossen) wechselt
if (state == HIGH) {
mic=micros();
micDelta=mic-micBef;
micBef=mic;
upm=1./(micDelta/1000000.)*60.;
MFS.write( (int) upm);
}
}
stateBef=state;
delayMicroseconds(1000);
}
}

Festplatte mit Rauschunterdrückung
Als weiteren Test wollen wir die Umdrehungsgeschwindigkeit noch verdreifachen und führen das Experiment mit der Festplatte und 3322 UPM noch einmal durch:
Erkenntnis für mich aus diesem Experiment: nimm für einen Drehzahlmesser lieber einen Reed-Kontakt, das ist einfacher und zuverlässiger.
Messung der Magnetfeldstärke
Was ein Reed-Kontakt allerdings nicht kann, ist die magnetische Flußdichte stufenweise messen. Ein Hall-Sensor kann das und bei ihm macht der analoge Ausgang auch Sinn, denn er gibt nich tnur die Werte 0 und 1023 aus, sondern mehr Werte im Bereich von 400 und 600.Diese Werte schwanken aber je nach Sensortyp und Temperatur und darum sollte man vor jeder Messung kalibrieren, sprich den Minimalwert und den Maximalwert speichern und diese Grenzpunkte in Relation zu 100% und 0% setzen. Was ich mit dem nachfolgenden Programm gemacht habe.
Source-Code 2
Hier der Source-Code für den Flussdichtemesser:Flussdichte.ino (klicken, um diesen Abschnitt aufzuklappen)
////////////////////////////////////////////////////////
// (C) 2018 by Oliver Kuhlemann //
// Bei Verwendung freue ich mich über Namensnennung, //
// Quellenangabe und Verlinkung //
// Quelle: http://cool-web.de/arduino/ //
////////////////////////////////////////////////////////
#include <TimerOne.h> // für Timings und Interrupts
#include <MultiFuncShield.h> // API für das Multi Function Shield
//#define PinData 5 // wo ist Digital Out angeschlossen?
#define PinAnalog A5 // wo ist Analog Out angeschlossen?
void setup() {
Timer1.initialize();
MFS.initialize(&Timer1); // initialize multi-function shield library
//pinMode (PinData, INPUT_PULLUP);
Serial.begin (115200);
}
void loop() {
boolean silence=false;
MFS.beep(1, 5, 2); // bereit
int anaMin=1023;
int anaMax=0;
int ana=0;
int prozent=0;
while (1) {
ana=analogRead(PinAnalog);
if (ana < anaMin) anaMin=ana;
if (ana > anaMax) anaMax=ana;
Serial.print(ana);
Serial.print(", min: ");
Serial.print(anaMin);
Serial.print(", max: ");
Serial.println(anaMax);
prozent=map(ana, anaMax, anaMin, 0, 100);
if (anaMax - anaMin < 70) {
MFS.write("CAL.");
} else {
MFS.writeLeds(LED_4, (prozent >= 20));
MFS.writeLeds(LED_3, (prozent >= 40));
MFS.writeLeds(LED_2, (prozent >= 60));
MFS.writeLeds(LED_1, (prozent >= 80));
MFS.write(prozent);
}
delay(100);
}
}
Erreicht der Messbereich eine Größe von 70 oder mehr, gelten die Messwerte als genau genug, um Prozentzahlen auszugeben. Im Hintergrund werden die Min/Maxwerte aber trotzdem laufend aktualisiert, so dass zum Beispiel das Umdrehen des Magneten immer noch einen Einfluß hat, auch wenn nicht mehr "CAL." angezeigt wird.
So sieht das Programm in Aktion aus:

Reed oder Hall?
Ich werde dem Reed-Kontakt immer den Vorzug geben, es sei denn:- ich benötige eine sehr kleine Bauform
- ich benötige einen analogen Messwert der Feldstärke (wobei hier evtl. einem LSM303C der Vorzug zu geben wäre)