Weiter geht's!
Es steht die Aufgabe an, einen Blinker zu setzen.
Schaltung:
Auf einen neuen Schalter für das "links Blinken" habe ich verzichtet. Das habe ich Code einfach "hart" gesetzt. Die Implementierung und Schaltung ist analog zum Taster vorzunehmen.
Code Zentrale:
Code:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 12); // RX, TX
int LED = 13; // Status-LED auf dem Board
byte sendeByte = 0; // das Byte, welches an die Front und ans Heck gesendet wird
int tasterHupe = 7; // Taster für Hupe ist am PIN 7
int tasterstatusHupe = 0; // Initial wird der Status auf "nicht gedrueckt" gesetzt
void setup() {
pinMode(LED, OUTPUT);
pinMode(tasterHupe, INPUT); //Der Pin mit dem Taster (Pin 7) ist jetzt ein Eingang.
mySerial.begin(9600);
}
// Alle Betriebsarten werden parallel in einem Byte
// uebertragen:
// Bit 0 (Wert 1) = Licht
// Bit 1 (wert 2) = Tagfahrlicht
// Bit 2 (Wert 4) = Bremslicht
// Bit 3 (Wert 8) = Blinker links
// Bit 4 (Wert 16) = Blinker rechts
// Bit 5 (Wert 32) = Hupe
// Bit 6 (Wert 64) = Innenraumbeleuchtung
// Bit 7 (Wert 128) = --Reserve--
void loop() {
sendeByte = 0; // das zu sendende Byte zu Beginn loeschen
// Lichtschalter abfragen
if (zustandLichtschalter())
{
sendeByte = 1;
}
// Tagfahrlichtschalter abfragen
if (zustandTagfahrlicht())
{
sendeByte += 2;
}
// Bremslichttaster abfragen
if (zustandBremslicht())
{
sendeByte += 4;
}
// Blinkerschalter links abfragen
if (zustandBlinkerLi())
{
sendeByte += 8;
}
// Blinkerschalter rechts abfragen
if (zustandBlinkerRe())
{
sendeByte += 16;
}
// Hupenschalter abfragen
if (zustandHupe())
{
sendeByte += 32;
}
// Innenraumbeleuchtungsschalter abfragen
if (zustandInnenraumbel())
{
sendeByte += 64;
}
// Byte senden
mySerial.write(sendeByte);
delay(10);
}
bool zustandLichtschalter()
{
return false;
}
bool zustandTagfahrlicht()
{
return false;
}
bool zustandBremslicht()
{
return false;
}
bool zustandBlinkerLi()
{
return true;
}
bool zustandBlinkerRe()
{
return false;
}
bool zustandHupe()
{
tasterstatusHupe = digitalRead(tasterHupe);
if ( tasterstatusHupe == LOW ) // durch Pull-Up-Widerstand zieht der Taster beim Druecken den Eingang auf Masse
{
digitalWrite(LED, HIGH); // LED auf dem Board einschalten
return true; // Bit fuer Hupe setzen
}
else
{
digitalWrite(LED, LOW); // LED auf dem Board ausschalten
return false; // Bit fuer Hupe auf null setzen
}
}
bool zustandInnenraumbel()
{
return false;
}
Einzige Änderung in diesem Code: Die Funktion "zustandBlinkerLi()" gibt "true" zurück, womit das Bit für den Zustand "links Blinken" gesetzt und gesendet wird.
Code Front:
Code:
#include <SoftwareSerial.h>
int LED=13; // Status-LED
SoftwareSerial mySerial(2, 3); // Rx, Tx
char a;
// digitale Eingaenge
int ausgangHupe = 5;
int ausgangBlinkerLinks = 6;
unsigned long zeitBlinkerAn = 0;
unsigned long zeitBlinkerAus = 0;
void setup() {
pinMode(LED, OUTPUT);
mySerial.begin(9600); // initialize serial
// digitale Ausgaenge
pinMode(ausgangHupe, OUTPUT);
pinMode(ausgangBlinkerLinks, OUTPUT);
}
// Alle Betriebsarten werden parallel in einem Byte
// uebertragen:
// Bit 0 = Licht
// Bit 1 = Tagfahrlicht
// Bit 2 = Bremslicht
// Bit 3 = Blinker links
// Bit 4 = Blinker rechts
// Bit 5 = Hupe
// Bit 6 = Innenraumbeleuchtung
// Bit 7 = --Reserve--
void loop() {
if (mySerial.available()) {
a = mySerial.read();
if (a & 1) {
// licht(true);
} else {
// licht(false)
}
if (a & 2) {
// tagfahrlicht(true);
} else {
// tagfahrlicht(false);
}
if (a & 4) {
// bremslicht(true);
} else {
// bremslicht(false);
}
if (a & 8) {
blinkerLinks(true);
} else {
schalteDigitalOut(ausgangBlinkerLinks, false); // kann hier direkt auf AUS gesetzt werden; u.U. kollidiert dies spaeter mit Warnblinken
}
if (a & 16) {
// blinkerRechts(true);
} else {
// blinkerRechts(false);
}
if (a & 32) {
schalteDigitalOut(ausgangHupe, true);
} else {
schalteDigitalOut(ausgangHupe, false);
}
if (a & 64) {
// innenraumbeleuchtung(true);
} else {
// innenraumbeleuchtung(false);
}
}
}
void schalteDigitalOut(int pin, bool zustand)
{
if (zustand)
{
digitalWrite(pin, HIGH); // Pin einschalten
}
else
{
digitalWrite(pin, LOW); // Pin einschalten
}
}
void blinkerLinks(bool zustand)
{
if (zustand)
{ // es soll Blinker links gesetzt werden
if (zeitBlinkerAn == 0) // wenn es noch keine Startzeit fuer "AN" gibt, dann holen
{
zeitBlinkerAn = millis(); // die aktuelle Zeit seit Programmstart holen
}
if (millis()-zeitBlinkerAn < 750) // Blinker soll fuer 750msec an sein, was 1.5Hz entspricht
{
schalteDigitalOut(ausgangBlinkerLinks, true);
}
else
{ // der Blinker war fuer 750msec an, nun fuer die gleiche Zeit ausschalten
if (zeitBlinkerAus == 0) // wenn keine Startzeit fuer "AUS" existiert, dann holen
{
zeitBlinkerAus = millis(); // die aktuelle Zeit seit Programmstart holen
}
if (millis()-zeitBlinkerAus < 750) // Blinker soll fuer 750msec an sein, was 1.5Hz entspricht
{
schalteDigitalOut(ausgangBlinkerLinks, false);
}
else
{
zeitBlinkerAn = 0; // ein kompletter Blinkvorgang ist abgeschlossen
zeitBlinkerAus = 0; // deshalb beide Startzeiten wieder zuruecksetzen
}
}
}
}
Änderungen für den Nano: Den linken Blinker habe ich an Pin 6 gehängt und diesen Pin analog zum "Hupen-Pin" angemeldet als digitalen Ausgang.
Für eine Zeitmessung benötigen wir noch zwei Variablen, in denen wir Zeiten speichern können. Diese sind vom Typ "unsigned long", da eben auch die Funktion, welche die Zeit zurückgibt, diesen Typ als Rückgabewert hat.
In der "loop" rufe ich bei gesetztem Blinker-links-Bit die entsprechende Methode auf. Ist das Bit nicht gesetzt, dann wird der Pin gleich in der if-Bedingung ausgeschaltet.
Die Methode "blinkerLinks()" schaut nun zunächst, ob der Blinker blinken soll. Dieses "if" könnte man wohl auch weglassen, da diese Entscheidung bereits oben beim Auswerten des Bits erfolgte.
Der Rest ist im Code kommentiert. Die 750msec habe ich aus dem passenden
Wikipedia-Eintrag.
Was macht das Programm?
Die Hupe funktioniert weiterhin mittels Taster. Die zweite LED blinkt mit 1.5Hz permanent.
An dieser Stelle würde ich nun vorerst abbrechen. Es tauchen sicher beim Implementieren aller Funktionen Fragen auf, die wir hier gerne besprechen können. Interessant würde sicher noch die Warnblinkanlage werden. Als Basis sollte aber jetzt alles vorhanden sein:
- Abfragen von Schaltern und Tastern
- Zustände von einem Arduino zum anderen per serieller Schnittstelle übertragen
- Ein- und Ausschalten einer LED -> kann mit Relais/MOSFET für größere Verbraucher genommen werden
- Blinken einer LED in einem definierten Takt
Bei Fragen: Fragen!
Ich bin nicht allwissend und sicher kann man wie immer vieles anders lösen. Aber für diese doch recht kurze Zeit mit dem Arduino ist - wie ich finde - noch überschaubarer und erweiterbarer Code entstanden.
Grüße
Heiko