Browse Category: Arduino

Port-Erweiterung durch Schieberegister

Ein Schieberegister ist eine logische Schaltung, die mehrstellige binäre Signale taktgesteuert aufnehmen, speichern und wieder abgeben kann. Schieberegister ermöglichen die Transformation serieller Daten in parallele Daten und umgekehrt. Sie bestehen im Grunde aus hintereinander geschalteten D- oder JK-FlipFlops. Die Takteingänge aller Stufen werden zusammengeschaltet und über einen gemeinsamen Takt versorgt.

Da ein Flip-Flop nur ein Bit speichern kann, müssen je nach Anwendung mehrere Flip-Flops zu einem Schieberegister zusammengeschaltet werden. Bei dem weit verbreiteten IC vom Typ 74HC595 beispielsweise sind 8 FlipFlops integriert, so kann man mit lediglich 3 Arduino-Pins 8 Ausgangspins ansteuern.

Der Schaltkreis hat folgende Pin-Belegung:

Funktionsweise

Die Funktionsweise eines Schieberegisters kann man sichwie in obiger Abbildung vorstellen: Ein serieller Datenstrom wird über eine Datenleitung an den Daten-Pin DS des Bausteins übertragen. Solange das ShiftClock-Pin (SHCP) auf Low steht passiert vorerst gar nichts. Erst wenn ein Pegelwechsel von LOW nach HIGH am ShiftClock-Pin erfolgt, wird der Zustand der am DS-Pin anliegt in den Zwischenspeicher geschoben.

Funktions-Schema eines Schieberegisters

Dieser Vorgang kann beliebig oft wiederholt werden, bis der Zwischenspeicher voll ist oder genügend Daten aufgenommen wurden. Da ein Schieberegister genau genommen aus zwei Registern besteht: dem Schieberegister, in welches der Zustand der einzelnen Ausgangspins seriell, also Bit für Bit gesteuert über das ShiftClock-Pin (SHCP) geschoben wird. Und das Ausgangsregister, in das der Zustand des Schieberegisters über ein weiteres Signal am sogenannten Storage Register Clock-Pin (SRCP) hin kopiert wird.

Es handelt sich somit um zwei separierte Register deren Datenströme kontrolliert Über die Pegelwechsel von LOW nach HIGH an den beiden Steuer-Pins ShiftClock-Pin (SHCP) und Storage Register Clock-Pin (SRCP) zusammen gefügt werden können.

Beispiel Programm

//------------------------------
// Schiebregister Test
//------------------------------

int shiftPin = 4; //SH_CP_PIN
int storePin = 2; //ST_CP_PIN
int dataPin = 7;  //DS_PIN
// Dieses Muster soll ausgegeben werden
int muster[8] = {1,1,1,1,1,1,0,0}; 
 
void setup() {
 pinMode(storePin, OUTPUT);
 pinMode(shiftPin, OUTPUT);
 pinMode(dataPin, OUTPUT);
 
 digitalWrite(storePin, LOW); // storePin sicherheitshalber auf LOW

 for (int i=0; i<8; i++) {
     digitalWrite(shiftPin, LOW);
     digitalWrite(dataPin, muster[i]);
     digitalWrite(shiftPin, HIGH);
    } // end for
 
// wenn alle Daten übertragen, auf Ausgabe schalten   
 digitalWrite(storePin, HIGH);
}
 
void loop () {
}

 

Mehrere Schieberegister zusammenschalten

Als Beispiel für die Möglichkeiten mehr als 8 Ausgänge zu steuern, habe ich eine Schaltung mit 3 IC 74595 entwickelt. Aufgebaut als Experimentierplattform für den Arduino und entsprechenden Anschlussmöglichkeiten auf einer Lochrasterplatine prototypisch umgesetzt.

Prototyp einer 24Bit-Port-Erweiterung mit 3 IC 74595 Bausteinen

Die Ansteuerung erfolgt wie bei einem einzelnen Schaltkreis d.h. alle Steuersignale an den Pins SHCP und SRCP werden parallel an alle ICs angeschlossen. Nur die DS-Leitungen der zweiten und folgenden Schieberegister werden kaskadiert. Dh. der Überlauf-Ausgang Q7S des ersten Schieberegisters wird mit dem DS-Eingang des 2. Registers verbunden usw. Das folgende Blockschaltbild verdeutlicht das Prinzip.

Drehstellgeber

In Bearbeitung…

Das Funktionsprinzip: Im Innern eines Encoders (Impulsgebers) sind zwei Taster integriert. Sie schalten um einen halben Klick Phasenverschoben. Detektiert man auf dem Kanal 1 (also vom ersten Taster) einen Wechsel von LOW zu HIGH prüft man, ob Kanal 2 LOW ist. Ist dieser LOW, wurde in die eine Richtung gedreht, ist er HIGH, wurde er in die andere Richtung gedreht.

Das Ganze funktioniert natürlich auch in die andere Richtung: Detektiert man auf dem Kanal 1 (also vom ersten Taster) einen Wechsel von HIGH zu LOW prüft man, ob Kanal 2 HIGH ist. Ist dieser HIGH, wurde in die eine Richtung gedreht, ist er LOW, wurde er in die andere Richtung gedreht.

Dazu muss man zu Beginn festlegen wie man die beiden möglichen Drehrichtungen benennen möchte, da sonst Verwirrungen entstehen können.

int encoderPinA = 2;
int encoderPinB = 3;
int encoderPos = 0;
int encoderPinALast = LOW;
int encoderPinANow = LOW;

void setup() {
  pinMode (encoderPinA, INPUT_PULLUP);
  pinMode (encoderPinB, INPUT_PULLUP);
  Serial.begin (115200);
}

void loop() {
  encoderPinANow = digitalRead(encoderPinA);
  if ((encoderPinALast == HIGH) && (encoderPinANow == LOW)) {
    if (digitalRead(encoderPinB) == HIGH) {
      encoderPos++;
    } else {
      encoderPos--;
    }
    Serial.println(encoderPos);
  }
  encoderPinALast = encoderPinANow;
}

Temperatursensoren

DS18B20

Beim DS18B20 handelt es sich um einen digitalen Temperatursensor im TO92 Gehäuse, der über einen One-Wire-Bus angesprochen wird. Auf diese Weise ist es möglich mehrere Sensoren an einem Mikrocontroller-Pin anzuschließen. Der Sensor besitzt eine Auflösung von 12 Bit und eine Messgenauigkeit von ±0.5°C im Messbereich von -55°C bis +125°C.

PIN Belegung (Quelle: AZ-Delivery.com)

Für die Funktion wird der Widerstand R1 = 4,7kOhm (Pullup-Widerstand genannt) zwischen Vcc und dem Daten Pin benötigt, weil er die Spannung bei fehlendem Signal auf die Versorgungsspannung hochzieht), was im Datenblatt so nicht gleich ersichtlich ist.

Der serielle Datenbus (1-Wire-Bus) und das vom Sensor verwendete Protokoll erfordern erheblichen Programmieraufwand, daher wird in den meisten Fällen auf vordefinierte Funktionsbibliotheken zurück gegriffen.

DHT 11 und DHT 22

Der DHT22 ist ein zuverlässiger Sensor zum ermitteln von Temperatur und Luftfeuchtigkeit. Da der Sensor sowohl mit 3,3V als auch 5V betrieben werden kann, eignet er sich zum Anschluss an alle gängige Boards

DHT 22 Sensor PIN Belegung (Quelle: Adafruit.com)

ESPLORA Board

Der Arduino Esplora ist ein Board aus den Anfängern der Arduino Ära, das heute nicht mehr gebaut wird. Die Besonderheit dieses Boards, ist die Ausstattung mit unterschiedlichen Bausteinen. Für Eingaben gibt es einen Joystick, vier Tasten, einen Lichtsensor, einen Schieberegler, ein Mikrofon, einen Temperatursensor und einen Beschleunigungsmesser. Für die Ausgänge gibt es einen Summer und eine dreifarbige LED. Auf den ersten Blick sieht es aus wie ein Videospiel-Controller.

ESPLORA Board (Quelle: Arduino.cc)

Infolgedessen unterscheidet sich die Programmierung etwas von der für andere Arduino-Boards. Es verfügt über eine eigene Bibliothek, die das Lesen von den Eingangssensoren und das Schreiben auf die Ausgangsaktoren erleichtert. Informationen zur Verwendung der Bibliothek finden Sie in diesem Handbuch und auf den Referenzseiten der Esplora-Bibliothek.

Der Arduino Esplora verfügt über eine Reihe von Funktionen für die einfache Verbindung mit den auf der Platine montierten Sensoren und Aktoren. Auf die Funktionen kann über die Esplora-Klasse zugegriffen werden. Die Bibliothek bietet einfachen Zugriff auf die Daten von den integrierten Sensoren und bietet die Möglichkeit, den Status der Ausgänge zu ändern.

Esplora Temperatur Sensor

Das folgende Programm zeigt, wie man den Temperatursensor des Esplora verwenden kann. Die Funktion Esplora.readTemperature () ruft den Wert vom Temperatursensor ab. Je nach Ihrer Wahl erhalten Sie die Temperatur in Grad Celsius oder Grad Fahrenheit. Es wird ein Parameter benötigt, DEGREES_C für Celsius oder DEGREES_F für Fahrenheit.

#include <Esplora.h>

void setup() {
  Serial.begin(9600);      // initialize serial communications with your computer
}

void loop() {
  // read the temperature sensor in Celsius, then Fahrenheit:
  int celsius = Esplora.readTemperature(DEGREES_C);
  int fahrenheit = Esplora.readTemperature(DEGREES_F);

  // print the results:
  Serial.print("Temperature is: ");
  Serial.print(celsius);
  Serial.print(" degrees Celsius, or ");
  Serial.print(fahrenheit);
  Serial.println(" degrees Fahrenheit.");
  Serial.println("     Fahrenheit = (9/5 * Celsius) + 32");

  delay(1000);
}

Esplora Digital Write

Um Daten Auszugeben, können die üblichen Funktionen verwendet werden. Auf dem oben abgebildeten “inoffiziellen” Esplora Diagramm kann man entnehmen, dass ein Ausgang über den Digitalen Pin 3 am Thinkerboard Stecker möglich ist.

// include the Esplora library
#include <Esplora.h>

void setup() {

pinMode(3,OUTPUT);
digitalWrite(3,HIGH);
}

void loop() {
}

DC Motor-Steuerung

Elektromotoren können relativ einfach gesteuert werden. Motorsteuerung bedeutet im einfachsten Fall, den Motor in Bewegung zu versetzen. Dies geschieht in dem die Wicklungen des Motors mit Spannung versorgt werden. Dabei gibt es nur zwei Zustände: der Motor ist mit Spannung versorgt und dreht sich oder im anderen Fall eben nicht.

Um die Richtung des Motors zu wechseln, muss der Stromfluss in der Spule umgekehrt werden. Um dies ohne manuelles umpolen der Spannungsquelle zu erreichen, ist eine spezielle Schaltung erforderlich, die auf geschickte Art das automatische Umpolen ermöglicht. Die Schaltung hat ihren Namen von der Form wie die Schalter angeordnet sind. Da sie wie ein „H“ aus sieht wird sie als H-Schaltung oder H-Brücke bezeichnet. Eine solche H-Brücke sieht schematisch so aus:

Die rote Linie zeigt den Stromweg für die jeweilige Drehrichtung. Sind die Schalter 1 und 4 geschlossen, so dreht sich der Motor rechts herum. Schliesst man die Schalter 2 und 3 dreht sich der Motor in die andere Richtung. Wobei zu beachten ist, dass nicht alle theoretisch möglichen Schalterstellung zugelassen werden, um beispielsweise Kurzschlüsse zu vermeiden. Die Betriebsspannung U ist die Spannung für den Motor, die meist unabhängig von der Logik ist und auch höher gewählt werden kann als 12 V.

Steuerung der Motor-Geschwindigkeit

Die Geschwindigkeit eines Motors ist direkt proportional zur angelegten Spannung. Dies ermöglicht eine Geschwindigkeitsregulierung, indem eine Puls-Weiten-Modulation (PWM) verwendet wird.

Pulsweitenmodulation oder PWM ist eine Technik, die digitale Methoden verwendet, um analoge Ergebnisse zu erhalten. Bei der Pulsweitenmodulation nimmt man ein Rechtecksignal mit einer festen Frequenz und variiert die Breite der jeweiligen Pulse. Den Abstand zweier aufeinander folgender Pulse bezeichnet man als Periodendauer, die Breite des aktiven Pulses als Pulsweite. Das Verhältnis von Pulsweite zu Periodendauer bezeichnet man auch als “Duty Cycle”(also die Zeit, in der der Pin im Dienst ist).

Programmtechnisch kann ein PWM-Signal wie in der Graphik gezeigt erzeugt werden, und beispielsweise zur Geschwindigkeitsregelung an einem Gleichstrommotor verwendet werden. Dies ist möglich, weil die Geschwindigkeit eines Motors direkt proportional zur angelegten Spannung ist. Somit ermöglicht die Veränderung der Spannung über das erzeugte Verhältnis T1 zu T1+T2 die Geschwindigkeitsregulierung am Motor.

Standardmäßig bietet der Arduino mit dem Befehl AnalogWrite(…) die Möglichkeit, PWM-Signale mit einer Auflösung von 8 Bit und einer PWM-Frequenz von 490 Hz (Pin D3, D9, D10 und D11) bzw. 980 Hz (Pin D5 und D6) auszugeben. Die Funktion AnalogWrite sendet pseudo-analoge Werte mittels einer hardwarebasierten Pulsweiten Modulation (PWM) an den adressierten Ausgangspin. Diese arbeitet nach folgendem Prinzip: Ein Wert 0 generiert eine gleichmäßige Spannung von 0 Volt; Ein Wert von 255 generiert eine gleichmäßige Spannung von 5 Volt an einem festgelegten PIN. Für Werte zwischen 0 und 255 wechselt der PIN sehr schnell zwischen 0 und 5 Volt – je höher der Wert, desto länger ist der PIN auf HIGH (5 Volt).

In der nachfolgenden Tabelle werden einige markante Tastwerte den entsprechenden PWM Werten gegenüber gestellt. Würde man beispielsweise analogWrite(5, 64); eingeben, so würde am Pin 5 ein Signal mit einem Tastgrad von 25% ausgegeben werden.

Tastgrad0 %25%50%75%100%
PWM-Wert064128191255

Ansteuerung eines DC Motors

In der Praxis verwendet man keine einzelnen Transistoren sondern hochintegrierte Schaltkreise, die sämtliche Bauteile für eine Motorsteuerung enthalten. Ein Beispiel wäre der Baustein L293 D, der über 600mA Strom liefern kann. Daneben gibt es noch weit leistungsstärkere wie den L298 D der mit über 2A Motoren steuern kann. Im nachfolgenden Blockschaltbild ist der prinzipielle Aufbau schematisch dargestellt:

Blockschaltbild des IC L293 (Quelle www.ti.com)

Die Ansteuerung eines Motors ist damit relativ unkompliziert machbar. Wichtig ist dabei auf die unterschiedlichen Spannungsversorgungen zu achten. Der Baustein kann ohne Probleme mit 5V Spannung vom Arduino betrieben werden. Da die zu steuernden Motoren aber meist größere Spannungen benötigen, besteht die Möglichkeit eine externe Spannungsquelle an PIN 8 des Bausteins anzuschliessen. Der Masse Anschluss wird dagegen von beiden Spannungen verwendet.

Die Steuerung des Motors erfolgt über die beiden Eingänge IN1 und IN2 die mit den digitalen Ausgängen des Arduinos verbunden werden. Dabei können folgende vier Zustände auftreten:

Eingang IN 1Eingang IN 2Motor Verhalten
LOWLOWMotor Stoppt
LOWHIGHMotor dreht sich nach Links
HIGHLOWMotor dreht sich nach rechts
HIGHHIGHMotor stoppt

Eine elementare Steuerung mit dem Arduino sieht im einfachsten Fall so aus:

const int PIN_A = 7;
const int PIN_B = 8;

void setup () {
  Serial.begin(9600); 
  pinMode(PIN_A , OUTPUT);
  pinMode(PIN_B , OUTPUT); 
 
  // Motor nach rechts drehen
  digitalWrite(PIN_A, LOW); 
  digitalWrite(PIN_B, HIGH);

  // Motor nach links drehen
   digitalWrite(PIN_A, HIGH); 
   digitalWrite(PIN_B, LOW);
void loop() { }

Wii Nunchuk Controller als Steuerelement am Arduino

In Bearbeitung …

Der Nunchuck Controller ist ein Eingabe-Instrument für die bekannte Wii-Spieleconsole. Er verfügt über 2 Druckknöpfe, einen Joystick und einen eingebauten 3-Achsen-Beschleunigungssensor. Dieser Controller ist aufgrund der hohen Verbreitung für wenig Geld erhältlich, sehr robust und verfügt über eine gut dokumentierte I2C-Schnittstelle, die es erlaubt, diesen mit dem Arduino zu verbinden. Somit kann der Controller für die verschiedensten Steuerungsaufgaben zweckentfremdet werden.

Älterer Wii-Nunchuk-Controller

Da viele Maker diesen Controller bereits in Ihren Projekten verwenden, finden sich viele Programm-Bibliotheken im Internet, die eine einfache Verwendung erlauben. Die hier verwendete Bibliothek stellt folgende Funktionen bereit:

void nunchuk_setpowerpins()void nunchuk_init()
int nunchuk_get_data()void nunchuk_calibrate_joy()
inline unsigned int nunchuk_zbutton()inline unsigned int nunchuk_cbutton()
inline int nunchuk_joy_x()inline uint16_t nunchuk_accelx()
inline int nunchuk_cjoy_x()inline uint16_t nunchuk_accely()
inline int nunchuk_cjoy_y()inline uint16_t nunchuk_accelz()
inline int nunchuk_joyangle()void nunchuk_calibrate_accelxy()
inline int nunchuk_rollangle()void nunchuk_calibrate_accelz()
inline int nunchuk_pitchangle()
Funktionen der wiinunchuk-Bibliothek

Die Bibliothek bereitet die Daten vom Controller so auf, dass diese über eine Anweisung ausgelesen werden können. Insgesamt benötigt man einen Speicherpuffer mit 75 Zeichen, in die sämtliche Sensorwerte geschrieben werden. Wie das geht, zeigt das erste Beispiel-Programm, dass nur die Joystick-Position und die Zustände der beiden Schalter C und Z ausliest.

#include <Wire.h>
#include <wiinunchuck.h>

void setup() { 
  Serial.begin(9600);
  nunchuk_init(); // Nunchuk initialisieren, Joystick auf Mittelposition
  delay(100);
  nunchuk_calibrate_joy();
  delay(100);
}
 
void loop() {
  nunchuk_get_data();   // Daten (6 Byte) vom Nunchuk Controller auslesen 
  char buffer[25];
  sprintf(buffer, "X:%3d Y:%3d Z:%1d C:%1d", 
          nunchuk_cjoy_x(), nunchuk_cjoy_y(), 
          nunchuk_zbutton(), nunchuk_cbutton() );
  Serial.println(buffer);   // Zusammengesetzten String an seriellen Monitor schicken
  delay(50);
}

Der Nunchuk wird über ein einfaches I²C Protokoll angesprochen. Mit Hilfe eines Befehles können wir alle Daten aus dem Nunchuk lesen. Die Daten kommen dabei als Paket von 6 Bytes in folgendem Format:

Byte 1: Joystick – X
Byte 2: Joystick – Y
Byte 3: ACC X (9..2)
Byte 4: ACC Y (9..2)
Byte 5: ACC Z (9..2)
Byte 6: ist aufgeteilt in Bits
Bit 0: Z-Taste
Bit 1: C-Taste
Bit 2,3: fehlenden Bits 0,1 vom ACC X
Bit 4,5: fehlenden Bits 0,1 vom ACC Y
Bit 6,7: fehlenden Bits 0,1 vom ACC Z

Um die Daten mit einem Arduino verarbeiten zu können, muss der Controller natürlich mit dem Arduino verbunden werden. Es gibt sechs Steckplätze, wobei nur die vier Äusseren belegt sind.

Wii-Steckerbelegung, die Farben können allerdings variieren.

Es gibt Adapter, aber aufgrund der Tatsache, dass ich meine nicht mehr anderswo benötige, habe ich den Stecker einfach abgeschnitten und Arduino-kompatibel mit Steckbrücken versehen.

Steuerpult fürs Hobbylabor

Beitrag befindet sich in Bearbeitung ….

Mit dem Arduino lassen sich ja sehr einfach verschiedenste Steuerungsaufgaben erledigen. Die Möglichkeit über Steckbretter und Steckbrücken, die Aufbauten schnell umzusetzen sind schon sehr praktisch. Wenn man allerdings, verschiedene Steuerungen und Anzeigeeinheiten immer wieder benötigt, habe ich mir überlegt ein Arduino-Steuerpult zu bauen. Mit dem Ziel immer wieder benötigte Module stationär in ein Gehäuse mit Netzteil zu integrieren, so dass immer wieder darauf zugegriffen werden kann.

In meinem Steuerpult sind in der ersten Ausbaustufe folgende Module enthalten:

  • Netzteil mit 12V und 5V bei ca. 2A Ausgangsleistung
  • Digitales Voltmeter
  • LCD-Anzeige, 4 Zeilen und I2C Schnittstelle
  • 2×14-Segement-Anzeigen mit I2C Schnittstelle
  • Potentiometer
  • Dreh-Encoder
  • 3-Tasten, mit Pulldowns Widerständen
  • 12er Tastenfeld
  • Thermo-Drucker
  • Bepper um Töne zu erzeugen
  • Schalt-Transistoren (in Ausbaustufe 2)
  • Motor-Regler (in Ausbaustufe 2)

Dazu wurde eine Frontplatte entworfen Mund mit einer Holzfräse von Inventables realisiert:

Frontplatten-Entwurf mit Easel

Nach dem die Frontplatte entworfen und ausgefräst war, habe ich dazu passend ein Gehäuse geplant… und mit Hilfe von MDF Platten in meiner Holzwerkstatt zusammengebaut.

Die Idee ist nun, die Anschlüsse Module an der Vorderseite über Klemmleisten heraus zu führen, um diese von einem Arduino ansteuern zu können. Die immer wieder verwendeten Leitungen wie die Strom-Versorgung werden intern fest mit dem Netzgerät verdrahtet, so dass der Arduino davon unbelastet bleibt. Einzig die gemeinsame Masseleitung wird benötigt. Das verringert den Verkabelungsaufwand bei neuen Projekten erheblich.

Am Ende sieht das Ganze dan beispielsweise so aus:

Natürlich können noch wesentlich mehr Funktionsmodule eingebaut werden. Der Phantasie sind hier keine Grenzen gesetzt.

Thermodrucker mit dem Arduino ansteuern

Es gibt verschiedene Anwendungen wo es Sinn macht, dass Daten ausgedruckt werden können. Dazu ist kein großer Drucker erforderlich, kompakte Thermodrucker ähnlich einem Kassenbon-Drucker eignen sich ganz hervorragend dafür.

Im Internet (z.B. bei Adafruit) kann man an verschiedenen Stellen einen günstigen Thermo-Drucker bestellen. Dieser Drucker entspricht einfachen Kassenbon-Drucker. Der Thermodrucker nimmt ein 2,55″ (57 mm) breites Thermopapier mit einem maximalen Rollendurchmesser von 1,5″ (39 mm) auf. Möglicherweise muss etwas Papier von diesen Rollen entfernen, damit es in den Drucker passt. Aber man kann immer das überschüssige Papier im Drucker verwenden, da kein “Kern” im Papier vorhanden sein muss, damit es eingezogen werden kann.

Die Rückseite meines Druckers hat zwei Anschlüsse; einen für die Stromversorgung und einen (5-poligen) für die serielle Kommunikation (Varianten die davon abweichen sind möglich). Der Thermodrucker wird mit einer Standard-Baudrate von 19200 Bit ausgeliefert. Wenn der Drucker in Verbindung mit einem Arduino verwendet werden soll, muß ein externes Netzteil (5V/2A) angeschlossen werden, da der Drucker mehr Strom aufnimmt, als USB liefern kann.

Rückseite mit Anschlussbildern des Thermodruckers

Ich habe den Drucker in ein einfaches Holzgehäuse eingebaut um erste Test durchführen zu können. Zum Test habe ich 3 der 5 Leitungen verwendet und zwar die blaue mit dem RX-Pin und die grüne mit dem TX-Pin am Arduino (näheres siehe im Quellcode). Ebenso wurde die schwarze Leitung mit GND am Arduino verbunden und natürlich die externe Stromversorgung des Druckers mit 5-9V. Wichtig ist noch auf die Baudrate zu achten. Hier gibt es 2 Versionen. Die 19200 und die 9600 Rate… je nach dem mit welcher der Drucker vorkonfiguriert wurde.

Ich habe den Drucker in ein einfaches Holzgehäuse eingebaut um erste Test durchführen zu können. Zum Test habe ich 3 der 5 Leitungen verwendet und zwar die blaue mit dem RX-Pin und die grüne mit dem TX-Pin am Arduino (näheres siehe im Quellcode). Ebenso wurde die schwarze Leitung mit GND am Arduino verbunden und natürlich die externe Stromversorgung des Druckers mit 5-9V. Wichtig ist noch auf die Baudrate zu achten. Hier gibt es 2 Versionen. Die 19200 und die 9600 Rate… je nach dem mit welcher der Drucker vorkonfiguriert wurde.

Ansteuerung

Um Daten an den Drucker zu übertragen, wird eine 5V TTL Verbindung aufgebaut. Bitte nicht verwechseln, mit der RS232 Schnittstelle eines PCs, die mit 10V arbeitet, damit würde man den Drucker zerstören.

Die Verwendung mit dem Arduino ist sehr einfach möglich, da Adafruit eine entsprechende Bibliothek entwickelt hat, die die Kommunikation mit dem Drucker sehr erleichtert. Die Bibliothek stellt folgende Funktionen bereit:

  • Inverted text: this is invoked by calling inverseOn() — you will get text that’s white-on-black instead of black-on-white. inverseOff() turns this off.
  • Double height: this makes text thats extra tall, call doubleHeightOn() — likewise, turn off with doubleHeightOff()
  • Left/Center/Right justified: this aligns text to the left or right edge of the page, or centered. You can set the alignment by calling justify(‘R’) (for right-justified), justify(‘C’) (for centered) or justify(‘L’) (for left-justified). Left-justified is the default state.
  • Bold text: makes it stand out a bit more, enable with boldOn() and turn off with boldOff()
  • Underlined text: makes it stand out a bit more, enable with underlineOn() and turn off with underlineOff()
  • Large/Medium/Small text: by default we use small, medium is twice as tall, large is twice as wide/tall. Set the size with setSize(‘L’)setSize(‘M’) or setSize(‘S’)
  • Line spacing: you can change the space between lines of text by calling setLineHeight() where numpix is the number of pixels. The minimum is 24 (no extra space between lines), the default spacing is 32, and double-spaced text would be 64.

Der erste Test erfolgte mit der Library von Adafruit und funktionierte nach einigem Drucken einwandfrei. Das Beispiel-Programm basiert auf dem das mit der Bibliothek mit geliefert wird. Ich habe es etwas modifiziert, da bei mir keine Bitmaps ausgedruckt werden sollen, sondern im wesentlichen Texte.

//==============================
// PH TestThermo Printer
//==============================
#include "Adafruit_Thermal.h"
#include "SoftwareSerial.h"

#define TX_PIN 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 5 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor

void setup() {
  mySerial.begin(9600);  // Initialize SoftwareSerial
  printer.begin();       // Init printer 

  // Test inverse on & off
  printer.inverseOn();   printer.println(F("Inverse ON"));
  printer.inverseOff();

  // Test character double-height on & off
  printer.doubleHeightOn(); printer.println(F("Double Height ON"));
  printer.doubleHeightOff();

  // Set text justification (right, center, left) 
  //-- accepts 'L', 'C', 'R'
  printer.justify('R');
  printer.println(F("Right justified"));
  printer.justify('C');
  printer.println(F("Center justified"));
  printer.justify('L');
  printer.println(F("Left justified"));

  // Test more styles
  printer.boldOn();
  printer.println(F("Bold text"));
  printer.boldOff();

  printer.underlineOn();
  printer.println(F("Underlined text"));
  printer.underlineOff();

  printer.setSize('L');   // Set type size, accepts 'S', 'M', 'L'
  printer.println(F("Large"));
  printer.setSize('M');
  printer.println(F("Medium"));
  printer.setSize('S');
  printer.println(F("Small"));

  printer.justify('C');
  printer.println(F("normal\nline\nspacing"));
  printer.setLineHeight(50);
  printer.println(F("Taller\nline\nspacing"));
  printer.setLineHeight(); // Reset to default
  printer.justify('L');

  printer.sleep();      // Tell printer to sleep
  delay(3000L);         // Sleep for 3 seconds
  printer.wake();       // MUST wake() before printing again, even if reset
  printer.setDefault(); // Restore printer to defaults
}

void loop() {}

Eventzähler

In Bearbeitung

Mit folgendem Testaufbau kann man sehr einfach mit dem Arduino Ereignisse zählen. Der Testaufbau zeigt einen Gleichstrommotor der mit einem kleinen Zeiger verbunden ist, auf dem wiederum ein Magnet aufgeklebt wurde. Dieser Motor wird über einen selbstgebauten PWM-Motor-Regler auf NE555 Basis geregelt.

Versuchsaufbau für den Event-Zähler

Über diesem “Event-Generator” befindet sich ein Reedkontakt, der über einen Pulldown Widerstand, beim Schliessen eindeutige Impulse generiert, die über die PulsIn-Funktion des Arduino erfasst und ausgewertet werden können.

Mit folgendem Programm können die Events erfasst und gezählt werden:

int pin = 8;
unsigned long T;          //Periodendauer in us
double f;                 //Frequenz in MHz 

void setup() 
{Serial.begin(9600);
Serial.println("IMPULSZAEHLER/FREQUENZZAEHLER");
 pinMode(pin, INPUT);
}

void loop() {
  T = pulseIn(pin, HIGH) + pulseIn(pin, LOW);
 if (T==0) Serial.println("Timeout.");
 else 
 {f=1/(double)T;          // f=1/T                 
  Serial.print(f*1e6); Serial.println(" HZ"); //Ausgabe in Hertz
 } 
}

Kapazitätsmesser

Mit Hilfe eines astabilen Multivibrator, dessen primäre Aufgabe es ist, in Abhängigkeit von einem RC-Glied Rechteck-Impulse zu erzeugen, ist es leicht möglich zusammen mit einem Arduino die Kapazität von Kondensatoren zu bestimmen. Die Länge dieser Impulse dient in unserem Aufbau, als Basis um die Kapazitäten von Kondensatoren zu bestimmen.

Schaltbild des Kapazitätsmessers

Der IC Baustein NE555 eignet sich besonders, um mit nur wenigen zusätzlichen Bauteilen eine derartige Kippstufe zu entwickeln. Für die Funktionsweise sind im wesentlichen die Bauteile R1 , R2 und C1 verantwortlich. Der Kondensator C2 sorgt nur dafür, dass die Schaltung nicht schwingt.


Die Dimensionierung der Bauteile kann entsprechend dem gewünschten Messbereich angepasst werden. Im vorliegenden Meßaufbau haben wir folgende Werte verwendet: R1 = 1 k und R2 = 10 k. Damit werden ausgeglichene Signallaufzeiten erreicht. Ein nachgeschalteter Schmitt-Trigger (zB SN7414) erzeugt für den nachfolgenden Arduino-Eingang steile Signalflanken und damit eindeutige Signalpegel.

Die Periodendauer eines astabilen Multivibrators berechnet sich nach folgenden Beziehungen:

    \[T = t_i + t_p\]

    \[t_i = \ln(2) \cdot (R_1+R_2) \cdot C_1\]

    \[t_p = \ln(2) \cdot R_2 \cdot C_1\]

Somit ergibt sich für die Periodendauer folgende Gleichung:

    \[T = \ln(2) \cdot (R_1+ 2\cdot R_2) \cdot C_1\]

Das Programm um die Kapazitäten mit dem Arduino zu bestimmen ist sehr übersichtlich. Es beginnt mit der Deklaration der benötigten Variablen. Im Hauptteil werden die Zeiten wo der Impuls auf HIGH und auf LOW steht bestimmt und gemittelt. Die  Kapazität des zu bestimmenden Kondensators ergibt sich dann über die Formel:

    \[C= \frac{1} {\ln(2) \cdot (R_1+ 2\cdot R_2) \cdot f}\]

Der Programmcode für den Testaufbau beinhaltet noch beide Ausgabeformen über den integrierten Monitor der IDE und über ein 4 Zeilen LCD mit I2C Schnittstelle und lässt sich natürlich beliebig an individuellen Vorstellungen anpassen:

//-----------------------------------
// Messen von Kapazitäten mit NEE555
// Version 2.0, (c) PHOF 18.01.2020
//-----------------------------------

long Htime;
long Ltime;
float Ttime;
float frequency;
float capacitance;
const int inputPin=8;

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
 LiquidCrystal_I2C lcd(0x27,20,4);

void setup(){
  Serial.begin(9600);
  lcd.init(); lcd.backlight();
  lcd.setCursor(0,0);  lcd.print("Kapazitaetsmesser");
  pinMode(inputPin,INPUT);
}

void loop() {
 for (int i=0;i<5;i++){
      Ltime=(pulseIn(inputPin,HIGH)+Ltime)/2;
      Htime=(pulseIn(inputPin,LOW)+Htime)/2;
     }//end for
  Ttime = Htime+Ltime;
  frequency=1000000/Ttime;
  capacitance = (1.44*1000000000)/(20800*frequency);

// Ausgabe auf LCD Display
   lcd.setCursor(1,2);
   lcd.print("C:= "); lcd.print(capacitance);
   lcd.print(" nF         "); 
 
// Ausgabe auf Monitor
 Serial.println("=========================="); 
 Serial.println("Kapazitätsbestimmung");
 Serial.println("=========================="); 
 Serial.print(" Periodendauer T: ");
 Serial.print(Ttime);
 Serial.println(" s   "); 
 Serial.println("-------------------------"); 
 Serial.print(" Frequenz "); 
 Serial.print(frequency);  
 Serial.println(" Hz "); 
 Serial.println("-------------------------"); 
 Serial.print(" Kapazität: ");
 Serial.print(capacitance);
 Serial.println(" nF   "); 
 Serial.println("========================="); 
 Serial.println(""); Serial.println(""); 
 delay(750);
 }//end loop

Das ermittelte Ergebnis ist erstaunlich genau, wie die nachfolgende Rechnung un der Blick aufs Osszilloskop zeigen.

Ergebnis der Messung vom Arduino und Überprüfung mit dem Osszilloskop

Wie man sieht stimmen Messung und Rechnung für diese sehr einfache Schaltung erstaunlich gut überein.