Guten Abend liebe Community,
ich möchte einen Motortreiber ( L298N für zwei Motoren) über einen 16 Kanal Analog/Digital Mulitplexer an einem ESP8266 betreiben.
Wenn ich den Motortreiber an meinen ESP direkt abnschließe, funktioniert alles Tadellos.
Da mir aber die PIN´s ausgingen, möchte ich durch solch einen 16 Kanal Analog/Digiatal Mulitplexer erweitern.
Zusätzlich hatte ich dank dem Mulitplexer jetzt genug Pins um 4 Endschalter anzuschließen und diese am ESP auszulesen. Endschalter funktionieren am Mulitplexer super.
Nun zum Eigentlichen Problem:
Ich möchte unbedingt diesen Motortreiber (6 Pins = ENA, IN1, IN2, ENB, IN3, IN4)
über den Mulitplexer betreiben. ENA und ENB sind Pins, über die die Motorgeschwindigkeit übergeben wird. IN1 bis IN4 schalten nur HIGH und LOW um eben die Motoren rechts oder links drehen zu lassen.
Seltsamer weiße habe ich vorhin, als ich Kanal 6 mit HIGH angeseteuert habe, im halben Sekunden takt 3,3V dann 0V dann 3,3 V dann wieder 0V..
Jetzt habe ich die Kontakte auf dem Motortreiber mit meinem Finger alle geerdet und jetzt zucken die Motoren ein Wenig aber nicht so wie ich diese schalte.
Masse ist aber vom Motortreiber zum ESP verbunden. sie werden auch von der gleichen Spannungsquelle versorgt ( Laderegler) der ESP hängt am 5V USB ausgang vom Laderegler und der Motortreiber am 12V Verbraucheranschluss.
Es hat schon alles Funktioniert, ich möchte lediglich den Motortreiber jetzt über den Mulitplexer an steuern..
Vielen dank für eure Mühe und Hilfe
Grüße
Stefan
Ich packe mal den ganzen Code rein:
Es ist alles kommentiert.. ich weiß etwas lang mitlerweile
// Informationen zur Blynk Verbindung
#define BLYNK_TEMPLATE_ID "TMPL4MpBp0Ka7"
#define BLYNK_TEMPLATE_NAME "Panel Handsteuerung"
#define BLYNK_AUTH_TOKEN "RvVA3b4QjZ2k5DYvxhJZpWbVt-8i5D34"
#define BLYNK_PRINT Serial
// Einbinden der Bibliotheken----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;
// Adressen von Mulitplexer und Lux-Sensoren----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#define TCA9548A_ADDRESS 0x70
#define BH1750_ADDRESS 0x23
// Definieren der Motor Pins am ESP8266-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//#define ENA D0
//#define IN1 D6
//#define IN2 D7
//#define IN3 D3
//#define IN4 D4
//#define ENB D5
// Globale Variablen für Manuell-Modus festlegen----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int PanelYlinksG = 0;
int PanelYrechtsG = 0;
int PanelXlinksG = 0;
int PanelXrechtsG = 0;
int MotorSpeed;
// Globale Variablen für Luxwerte definieren--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
unsigned int luxValue1 = 0;
unsigned int luxValue2 = 0;
unsigned int luxValue3 = 0;
unsigned int luxValue4 = 0;
// Globale Variablen für Ueberstrom + Glaettung
int durchnittX_mA = 0; //Durchnitt Milliampere Motor X
int durchnittY_mA = 0; //Durchnitt Milliampere Motor Y
int zX = 0; //Zählervariable
int zY = 0;
int Fehlerzustand = 0;
// Digitale Pins für die Steuerleitungen des Multiplexers
const int s0Pin = D0; // Verbinde mit S0 des CD74HC4067
const int s1Pin = D6; // Verbinde mit S1 des CD74HC4067
const int s2Pin = D7; // Verbinde mit S2 des CD74HC4067
const int s3Pin = D3; // Verbinde mit S3 des CD74HC4067
// Ausgangspin des CD74HC4067 zum ESP8266
const int outputPin = D5; // Verbinde mit dem gewünschten Pin am ESP8266
// WLAN-Name und WLAN-Passwort------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
char ssid[] = "WLAN-763442_EXT";
char pass[] = "1234567891";
// Timer Funktion um Betriebsdauer aufzuzeichnen -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BlynkTimer timer;
// Blynk App Schalter Zustand wird später auf diese Variable geschrieben----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int schalterPin = 0; // Initialer Wert auf 0 setzen
// Variablen wird von App übergeben-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BLYNK_WRITE(V0){ // Mit BLYNK_WRITE wird der Wert V0 aus der Blynk App ausgelesen und als Integer auf Schalter PIN geschrieben
schalterPin = param.asInt(); // Wert von V0 zuweisen
Blynk.virtualWrite(V1, schalterPin); // Wert von schalterPin auf V1 zurück in die Blynk App übergen
Serial.print("Wert von schalterPin: ");
Serial.println(schalterPin); // Ausgabe von schalterPin im seriellen Monitor für Fehler Behebung
}
// Zustand Pin V8 wird aus Blynk App ausgelesen---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BLYNK_WRITE(V8) { //Befehl BLYNK_WRITE() ließt Virtuelle Variable 8 aus
PanelYlinksG = param.asInt(); //Variablewert V8 wird als Integer der gloabelen Variable PanelYlinksG zugewiesen
}
// Zustand Pin V9 wird aus Blynk App ausgelesen---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BLYNK_WRITE(V9) { //Befehl BLYNK_WRITE() ließt Virtuelle Variable 9 aus Blynk App aus
PanelYrechtsG = param.asInt(); //Variablewert V9 wird als Integer der globalen Variable PanelYrechtsG zugewiesen
}
// Zustand Pin V10 wird aus Blynk App ausgelesen---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BLYNK_WRITE(V10) { //Befehl BLYNK_WRITE() ließt Virtuelle Variable 10 aus Blynk App aus
PanelXlinksG = param.asInt(); //Variablewert V10 wird als Integer der globalen Variable PanelXlinksG zugewiesen
}
// Zustand Pin V11 wird aus Blynk App ausgelesen---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BLYNK_WRITE(V11) { //Befehl BLYNK_WRITE() ließt Virtuelle Variable 11 aus Blynk App aus
PanelXrechtsG = param.asInt(); //Variablewert V11 wird als Integer der globalen Variable PanelXrechtsG zugewiesen
}
// Zustand Pin V7 wird aus Blynk App ausgelesen---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BLYNK_WRITE(V7) { //Befehl BLYNK_WRITE() ließt Virtuelle Variable 7 aus Blynk App aus
MotorSpeed = param.asInt(); //Variablewert V7 wird als Integer der Variable Motorspeed zugewiesen um den Integer Wert aus der App im Manuell Modus zu verwenden
}
// Zustand Pin V4 wird aus Blynk App ausgelesen---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BLYNK_WRITE(V4) { //Befehl BLYNK_WRITE() ließt Virtuelle Variable 4 aus Blynk App aus
Fehlerzustand = param.asInt(); //Variablewert V4 wird als Integer der globalen Variable Fehlerzustand zugewiesen
Blynk.virtualWrite(V3, Fehlerzustand); //Quittieren Fehlerzustand
}
void setup() //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Im steup werden Serieller Monitor zur Fehlerbehebung gestartet, die I2C Kommunikation zum Mulitplexer gestartet,
// es werden Wlan Name und Schlüssel eingegeben um eine Verbindung zum Blynk Serversherzustellen sowie die Kalibrierung des Strom Sensors.
{
Serial.begin(115200); //Seriellen Monitor des ESP8266 starten
Wire.begin(true); //I2C Kommunikation starten
// Initialisiere die Steuerleitungs-Pins des Multiplexers als Output
pinMode(s0Pin, OUTPUT);
pinMode(s1Pin, OUTPUT);
pinMode(s2Pin, OUTPUT);
pinMode(s3Pin, OUTPUT);
// Setze den Multiplexer auf Kanal 0
setMultiplexerChannel(0);
// Setze den Multiplexer auf Kanal 1
setMultiplexerChannel(1);
// Setze den Multiplexer auf Kanal 2
setMultiplexerChannel(2);
// Setze den Multiplexer auf Kanal 3
setMultiplexerChannel(3);
// Setze den Multiplexer auf Kanal 4
setMultiplexerChannel(4);
// Setze den Multiplexer auf Kanal 5
setMultiplexerChannel(5);
// Setze den Multiplexer auf Kanal 6
setMultiplexerChannel(6);
// Setze den Multiplexer auf Kanal 7
setMultiplexerChannel(7);
// Setze den Multiplexer auf Kanal 8
setMultiplexerChannel(8);
// Setze den Multiplexer auf Kanal 9
setMultiplexerChannel(9);
// Initialisiere den Ausgangspin als Input
//pinMode(outputPin, INPUT);
//pinMode(ENA, OUTPUT); // ENA wird als Output deklariert
//pinMode(IN1, OUTPUT); // IN1 wird als Output deklariert
//pinMode(IN2, OUTPUT); // IN2 wird als Output deklariert
//pinMode(IN3, OUTPUT); // IN3 wird als Output deklariert
//pinMode(IN4, OUTPUT); // ENA wird als Output deklariert
//pinMode(ENB, OUTPUT); // ENA wird als Output deklariert
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass); // Verbindung zum Blynk-Server herstellen
timer.setInterval(1000L, myTimerEvent); // Hier wird Funktion myTimerEvent() alle 1000 Millisekunden ausgeführt und den Wert der aktuellen Zeit an den virtuellen Pin V2 der Blynk App gesendet.
ina219.setCalibration_32V_2A(); //Kalibrierung des INA219 Sensors
}
void loop() // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Hier werden alle essenziellen Funktionen ausgeführt
// Funktionen im Loop können je nach Aktivierung auf andere Funktionen im späteren Code zugreifen welche nicht direkt im Loop aufgeführt sind.
{
// Blynk-Verbindung aktualisieren
Blynk.run(); // Blynk Funktion - Blynk-Verbindung aktualisieren
timer.run(); // Timer Funktion im Loop ausführen
Motorueberwachung(); // Motorueberwachung Funktion im Loop ausführen
Endschalter();
Serial.print("Wert von Fehlerzustand: "); // Ausgeben Fehlerzustand
Serial.println(Fehlerzustand); // Fehlerzustand
if (schalterPin == 1 && Fehlerzustand == 0) // Abfrage ob SchalterPin auf Manuell steht und kein Fehlerzustand vorhanden ist dann wird Manuell() ausgeführt
{
Manuell(); // Funktion für Motorsteuerung X & Y per Blynk APP Manuell
}
if (schalterPin == 0 && Fehlerzustand == 0) // Automatik() wird ausgeführt wenn in Blynk App Automatik ausgewählt ist und kein Fehlerzustand vorhanden ist
{
Automatik(); // Funktion für Automatische Ausrichtung des Panels mittels Lux-Sensoren
}
else if(Fehlerzustand == 1) // Stopp Funktion wird ausgeführt sobald Bedingung Fehlerzustand durch Ueberstrom und Endschalter aktiviert wird
{
MotorStopp(); // MotorStopp() Funktion
}
}
void myTimerEvent() //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// myTimerEvent() Funktion aufrufen um Betriebsdauer anzuzeigen
{
Blynk.virtualWrite(V2, millis() / 1000); // Akutelle Zeit wird in Millis angegeben, geteilt durch 1000 um Sekunden zu erhalten. Dieser Wert wird an Pin V2 zurück zur Blynk APP gesendet
}
void Motorueberwachung() //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Motorueberwachung mittels INA219 Strom Sensoren
// In Motorueberwachung() werden die Strommessplatinen INA219 über den I2C Mulitplexer ausgelesen.
// Dazu wird der Kanal 4 des Mulitplexer zum Motor der X-Achse gechaltet um Informationen des INA219 auszulesen.
// Kanal 5 wird geschaltet um Werte des Motor der Y-Achse auszulesen.
{
// Multiplexer Kanal 4: Sensor 1 X-Achse (INA219 über I2C)
Wire.beginTransmission(TCA9548A_ADDRESS); // Durch diesen Befehl wird die I2C Kommunikation gestartet und sich die define TCA9548A_ADDRESS geholt
Wire.write(1 << 4); // Kanal 4 aktivieren
Wire.endTransmission();
delay(100);
// INA219 Messungen ausführen
int currentX_mA = 0; // lokale Variable erstellen um diese mit dem Wert des Sensors immer neu zu beschreiebn
ina219.begin(); // Annahme: Der Sensor wird immer erkannt
ina219.setCalibration_32V_1A(); // Kalibrierung einstellen
while(zX <= 30 ) // While Schleife um aus 30 Messungen eine Glättung zu bilden.--> Durchschnittswert um hohen Anlaufstrom gegenzuwirken
{
currentX_mA = ina219.getCurrent_mA(); // Variable currentX_mA wird durch Befehl beschrieben
durchnittX_mA = durchnittX_mA + currentX_mA; // Hier werden die 30 Messungen summiert
zX++; // Zählvariable um 1 erhöhen
}
zX= 0; // Zählvariable auf 0 setzen um beim nächsten Schleifen durchlauf wieder bei 0 zu beginnen
durchnittX_mA = durchnittX_mA / 30; // Formel um einen Durchschnittswert zu erhalten
// Wert auf dem Seriellen Monitor ausgeben
Serial.print("durchnittX_mA: "); // Durch die Ausgabe konnten wir wesentlich ruhigere Zahlen sehen
Serial.println(durchnittX_mA);
// Multiplexer Kanal 5: Sensor 2 Y-Achse (INA219 über I2C)-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Wire.beginTransmission(TCA9548A_ADDRESS); // Durch diesen Befehl wird die I2C Kommunikation gestartet und sich die define TCA9548A_ADDRESS geholt
Wire.write(1 << 5); // Kanal 5 aktivieren
Wire.endTransmission();
delay(100);
// INA219 Messungen ausführen
int currentY_mA = 0; // lokale Variable erstellen um diese mit dem Wert des Sensors immer neu zu beschreiebn
ina219.begin(); // Annahme: Der Sensor wird immer erkannt
ina219.setCalibration_32V_1A(); // Kalibrierung einstellen
while(zY <= 30 ) // While Schleife um aus 30 Messungen eine Glättung zu bilden.--> Durchschnittswert um hohen Anlaufstrom gegenzuwirken
{
currentY_mA = ina219.getCurrent_mA(); // Variable currentX_mA wird durch Befehl beschrieben
durchnittY_mA = durchnittY_mA + currentY_mA; // Hier werden die 30 Messungen summiert
zY++; // Zählvariable um 1 erhöhen
}
zY=0; // Zählvariable auf 0 setzen um beim nächsten Schleifen durchlauf wieder bei 0 zu beginnen
durchnittY_mA = durchnittY_mA / 30; // Formel um einen Durchschnittswert zu erhalten
// Wert auf dem Seriellen Monitor ausgeben
Serial.print("durchnittY_mA: "); // auch hier konnten wir urch die Ausgabe wesentlich ruhigere Zahlen sehen
Serial.println(durchnittY_mA);
}
void Ueberstrom() //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// In dieser Funktion werden die Ampere Werte der Motoren X und Y per Motorueberwachung eingelsen und durch
// abgleichen der eingestellten Werte verarbeitet. Sollte ein Motor durch eine Blockade oder Defekt Ueberstrom
// produzieren wird hier der Stromfluss unterbrochen
// Der gemessene Wert wird aufgrund von rechts und links Drehung des Motors einmal in den positiven und negativen Bereich verglichen
{
Motorueberwachung(); // Motorueberwachung wird immer in Ueberstrom ausgeführt, da diese die Werte der Strom Sensoren auslesen und der Funktion Ueberstrom bereit stellen
if (durchnittX_mA < -800) { // Sollte der mA Wert des Motor X -800 unterschreiten wird ein Fehler generiert
Fehlerzustand = 1;
Serial.println("Motor gestoppt aufgrund von Motorstromüberschreitung");
Blynk.virtualWrite(V3, Fehlerzustand); // Für die Anzeige Fehlerzustand in der Blynk App wird virtuelle Variable V3 beschrieben
}
if(durchnittX_mA > 800){ // Sollte der mA Wert des Motor X +800 unterschreiten wird ein Fehler generiert
Fehlerzustand = 1;
Serial.println("Motor gestoppt aufgrund von Motorstromüberschreitung");
Blynk.virtualWrite(V3, Fehlerzustand); // Für die Anzeige Fehlerzustand in der Blynk App wird virtuelle Variable V3 beschrieben
}
if(durchnittY_mA < -700){ // Sollte der mA Wert des Motor Y -700 unterschreiten wird ein Fehler generiert
Fehlerzustand = 1;
Serial.println("Motor gestoppt aufgrund von Motorstromüberschreitung");
Blynk.virtualWrite(V3, Fehlerzustand); // Für die Anzeige Fehlerzustand in der Blynk App wird virtuelle Variable V3 beschrieben
}
if(durchnittY_mA > 700){ // Sollte der mA Wert des Motor X +800 unterschreiten wird ein Fehler generiert
Fehlerzustand = 1;
Serial.println("Motor gestoppt aufgrund von Motorstromüberschreitung");
Blynk.virtualWrite(V3, Fehlerzustand); // Für die Anzeige Fehlerzustand in der Blynk App wird virtuelle Variable V3 beschrieben
}
durchnittX_mA = 0; // nach Prürung der Werte werden hier die Variablen auf 0 gesetzt um beim nächsten Durchlauf wieder verwendet werden zu können
durchnittY_mA = 0;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void Manuell()//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// In der Manuell() Funktion wird zuerst die Ueberstrom() Funktion ausgeführt um sofort Sicherheitsmaßnahmen zu ergreifen bei Fehlfunktionen.
// Sollte die Funktion Ueberstrom keinen Fehler erkennen, wird ausgelesen ob sich zb PanelYlinksG auf 1 gesetzt hat. Das G hinter Variable steht für Global.
// Die gloaben Variablen werden oben per Blynk App aktiviert, dies geschieht in Zeile 74 bis 97.
// Sollte nun einer dieser Variablen auf 1 gehen wird sofort einer der Fahrbefehle, welche weiter unten aufgeführt sind, ausgeführt. Das zurücksetzen auf 0 der Variablen wird durch einen Push Button in der
// Blynk App realisiert.
//
{
Ueberstrom();
if (PanelYlinksG == 1) { // Wert Abfrage ob PanelYlinksG gleich 1
PanelYlinks(); // Wenn 1, dann führe Funktion PanelYlinks() aus
Serial.println("PanelYlinks"); // PanelYlinks wird ausgegeben
} else if (PanelYrechtsG == 1) { // Wert Abfrage ob PanelYrechtsG gleich 1
PanelYrechts(); // Wenn 1, dann führe Funktion PanelYrechts() aus
Serial.println("PanelYrechts"); // PanelYrechts wird ausgegeben
} else if (PanelXlinksG == 1) { // Wert Abfrage ob PanelXlinksG gleich 1
PanelXlinks(); // Wenn 1, dann führe Funktion PanelXlinks() aus
Serial.println("PanelXlinks"); // PanelXlinks wird ausgegeben
} else if (PanelXrechtsG == 1) { // Wert Abfrage PanelXrechtsG gleich 1
PanelXrechts(); // Wenn 1, dann führe Funktion PanelYrechts() aus
Serial.println("PanelXrechts"); // PanelXrechts wird ausgegeben
} else if (PanelYlinksG == 0 && PanelYrechtsG == 0 && PanelXlinksG == 0 && PanelXrechtsG == 0) { //Abfrage ob alle Variablen 0 sind,
MotorStopp(); // Wenn kein Fahrbefehl ausgeführt wird, dann führe Funktion MotorStopp() aus
Serial.println("Panel Stopp"); // Panel Stopp wird ausgegeben
}
}
void PanelYlinks()
// die nachfolgenden vier funktionen Werden per Blynk App aktiviert. Sobald ein Fahrbefehl in der App aktivert wird,
// setzt sich zb PanelYlinks auf aktiviert und es wird einer der folgenden Funktionen ausgeführt
{
setMultiplexerChannel(4);
pinMode(outputPin, OUTPUT);
analogWrite(outputPin, MotorSpeed); // Motorspeed auf ENA
setMultiplexerChannel(5);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH); // HIGH auf IN1
setMultiplexerChannel(6);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW); // LOW auf IN2
}
void PanelYrechts() //Funktion PanelYrechts()
{
setMultiplexerChannel(4);
pinMode(outputPin, OUTPUT);
analogWrite(outputPin, MotorSpeed); // Motorspeed auf ENA
setMultiplexerChannel(5);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW); // LOW auf IN1
setMultiplexerChannel(6);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH); // HIGH auf IN2
}
void PanelXlinks() //Funktion PanelXlinks()
{
setMultiplexerChannel(7);
pinMode(outputPin, OUTPUT);
analogWrite(outputPin, MotorSpeed); // Motorspeed auf ENB
setMultiplexerChannel(8);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW); // LOW auf IN3
setMultiplexerChannel(9);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH); // HIGH auf IN4
}
void PanelXrechts() //Funktion PanelXrechts()
{
setMultiplexerChannel(7);
pinMode(outputPin, OUTPUT);
analogWrite(outputPin, MotorSpeed); // Motorspeed auf ENB
setMultiplexerChannel(8);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH); // HIGH auf IN3
setMultiplexerChannel(9);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW); // LOW auf IN4
}
void MotorStopp() //Funktion MotorStopp()
{
setMultiplexerChannel(5); //Variable IN1 wird auf LOW geschrieben
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
setMultiplexerChannel(6); //Variable IN2 wird auf LOW geschrieben
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
setMultiplexerChannel(8); //Variable IN3 wird auf LOW geschrieben
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
setMultiplexerChannel(9); //Variable IN4 wird auf LOW geschrieben
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
Serial.println("STOPP");
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void Automatik()//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Hier wird Automatik() mit Funktionen gefüllt.
// Wenn die Bedingungen im Loop entsprechen, wird Automatik() ausgeführt und sofort Ueberstrom() gestartet.Wegen Schutzmaßnahmen muss diese zuerst gestartet werden,
// danach get LuxWerte(), setMotorX() und setMotorY() ausgeführt
// Als erstes werden in getLuxwerte() die benötigten Kanäle zu den BH1750 Lux-Sensoren geschaltet und ausgelesen. Vier an der Zahl
// In setMotorX() werden die gemessen Werte von Sensor drei und vier verglichen und der Motor entprechend gefahren bis ähnliche Werte entstehen.
// Das gleiche passiert bei Motor Y mit Sensor eins und zwei. Durch vergleichen der Sensoren können sich die Motoren automatisch ausrichten.
{
Ueberstrom();
getLuxwerte();
setMotorX(); //Funktion getLuxwerte(), setMotorX() und setMotorY() werden hier in die Funktion Automatik() zusammengefasst
setMotorY();
}
void getLuxwerte() //Funktion getLuxwerte()
{
// Multiplexer Kanal 0: Sensor 1
Wire.beginTransmission(TCA9548A_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte Mulitplexer Adresse zurück
Wire.write(1 << 0); // Kanal 0 aktivieren
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden. Gleichzeitig ist es eine Bestätigung für das Gerät welches den befehl bekommt diesen auszuführen
delay(100); // delay() wird hier verwendet damit der Mulitplexer Zeit hat den Befehl auszuführen
Wire.beginTransmission(BH1750_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte BH1750 Adresse zurück
Wire.write(0x10); // Kontinuierliche Hochauflösungsmessung einschalten
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
delay(200); // delay() hier, damit der BH1750 Sensor zeit hat seine Auflösung anzupassen
Wire.beginTransmission(BH1750_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte BH1750 Adresse zurück
Wire.requestFrom(BH1750_ADDRESS, 2); // Wire.requestFrom() fordert von den Sensoren 2 Bytes Daten an (Größe eines Bh1750) und speichert diese im Puffer Speicher des ESP8266
if (Wire.available() == 2){ // Hier wird abgefragt ob die eben eingelesen 16 bit im Puffer verügbar sind
uint16_t luxValue = Wire.read() << 8; // LuxValue wird als lokale 16 Bit integer Variable erstellt, Wire.read ließt das erste von den zwei bytes und verschiebt es um 8 bits nach vorne um es als erstes einzuordnen.
luxValue |= Wire.read(); // Nun werden die letzten 8 Bit der Variable LuxValue mit den letzten 8 bit im Speicher beschrieben, bevor der Speicher beim nächsten Sensor neu beschrieben wird
luxValue1 = luxValue;
}
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Multiplexer Kanal 1: Sensor 2
Wire.beginTransmission(TCA9548A_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte Mulitplexer Adresse zurück
Wire.write(1 << 1); // Kanal 1 aktivieren
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
delay(100); // delay() wird hier verwendet damit der Mulitplexer Zeit hat den Befehl auszuführen
Wire.beginTransmission(BH1750_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte BH1750 Adresse zurück
Wire.write(0x10); // Kontinuierliche Hochauflösungsmessung einschalten
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
delay(200); // delay() hier, damit der BH1750 Sensor zeit hat seine Auflösung anzupassen
Wire.beginTransmission(BH1750_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte BH1750 Adresse zurück
Wire.requestFrom(BH1750_ADDRESS, 2); // Wire.requestFrom() fordert von den Sensoren 2 Bytes Daten an (Größe eines Bh1750) und speichert diese im Puffer Speicher des ESP8266
if (Wire.available() == 2) { // Hier wird abgefragt ob die eben eingelesen 16 bit im Puffer verügbar sind
uint16_t luxValue = Wire.read() << 8; // LuxValue wird als lokale 16 Bit integer Variable erstellt, Wire.read ließt das erste von den zwei bytes und verschiebt es um 8 bits nach vorne um es als erstes einzuordnen.
luxValue |= Wire.read(); // Nun werden die letzten 8 Bit der Variable LuxValue mit den letzten 8 bit im Speicher beschrieben, bevor der Speicher beim nächsten Sensor neu beschrieben wird
luxValue2 = luxValue;
}
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Multiplexer Kanal 2: Sensor 3
Wire.beginTransmission(TCA9548A_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte Mulitplexer Adresse zurück
Wire.write(1 << 2); // Kanal 2 aktivieren
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
delay(100); // delay() wird hier verwendet damit der Mulitplexer Zeit hat den Befehl auszuführen
Wire.beginTransmission(BH1750_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte BH1750 Adresse zurück
Wire.write(0x10); // Kontinuierliche Hochauflösungsmessung einschalten
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
delay(200); // delay() hier, damit der BH1750 Sensor zeit hat seine Auflösung anzupassen
Wire.beginTransmission(BH1750_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte BH1750 Adresse zurück
Wire.requestFrom(BH1750_ADDRESS, 2); // Wire.requestFrom() fordert von den Sensoren 2 Bytes Daten an (Größe eines Bh1750) und speichert diese im Puffer Speicher des ESP8266
if (Wire.available() == 2) { // Hier wird abgefragt ob die eben eingelesen 16 bit im Puffer verügbar sind
uint16_t luxValue = Wire.read() << 8; // LuxValue wird als lokale 16 Bit integer Variable erstellt, Wire.read ließt das erste von den zwei bytes und verschiebt es um 8 bits nach vorne um es als erstes einzuordnen.
luxValue |= Wire.read(); // Nun werden die letzten 8 Bit der Variable LuxValue mit den letzten 8 bit im Speicher beschrieben, bevor der Speicher beim nächsten Sensor neu beschrieben wird
luxValue3 = luxValue;
}
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Multiplexer Kanal 3: Sensor 4
Wire.beginTransmission(TCA9548A_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte Mulitplexer Adresse zurück
Wire.write(1 << 3); // Kanal 3 aktivieren
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
delay(100); // delay() wird hier verwendet damit der Mulitplexer Zeit hat den Befehl auszuführen
Wire.beginTransmission(BH1750_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte BH1750 Adresse zurück
Wire.write(0x10); // Kontinuierliche Hochauflösungsmessung einschalten
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
delay(200); // delay() hier, damit der BH1750 Sensor zeit hat seine Auflösung anzupassen
Wire.beginTransmission(BH1750_ADDRESS); // I2C Kommunikation wird durch Wire.beginTransmission gestartet und greift auf definirte BH1750 Adresse zurück
Wire.requestFrom(BH1750_ADDRESS, 2); // Wire.requestFrom() fordert von den Sensoren 2 Bytes Daten an (Größe eines Bh1750) und speichert diese im Puffer Speicher des ESP8266
if (Wire.available() == 2) { // Hier wird abgefragt ob die eben eingelesen 16 bit im Puffer verügbar sind
uint16_t luxValue = Wire.read() << 8; // LuxValue wird als lokale 16 Bit integer Variable erstellt, Wire.read ließt das erste von den zwei bytes und verschiebt es um 8 bits nach vorne um es als erstes einzuordnen.
luxValue |= Wire.read(); // Nun werden die letzten 8 Bit der Variable LuxValue mit den letzten 8 bit im Speicher beschrieben, bevor der Speicher beim nächsten Sensor neu beschrieben wird
luxValue4 = luxValue; // lokale Variable luxValue übergibt ihren Wert der globalen Variable LuxValue4
}
Wire.endTransmission(); // Wire.endTransmission() wird verwendet um die Kommunikation mit einem I2C Gerät zu beenden
}
void setMotorX()
// Es werden die Maximal Werte beider Sensoren (hier Sensor 3 und 4) ermnittelt, sowie der minimal Wert, um eine Differenz zu errechnen. Sollte diese Differenz größer als 25 000 Lux betragen, wird automatisch nachjustiert.
{
if ((max(luxValue3,luxValue4)) - (min(luxValue3,luxValue4)) < 1000) { //Wenn Differenz kleiner 25000 ist, wird IN3 und IN4, welche für Motor X verantwortlich sind auf LOW geschaltet
Serial.println("Beide Sensoren haben den gleichen Lichtwert, der Motor X stoppt");
Serial.print("Lux-Wert Sensor 3: ");
Serial.println(luxValue3); // Ausgeben des Wertes von Sensors 3
Serial.print("Lux-Wert Sensor 4: ");
Serial.println(luxValue4); // Ausgeben des Wertes von Sensors 4
Serial.println();
setMultiplexerChannel(8); //IN3 wird auf LOW gesetzt
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
setMultiplexerChannel(9); //IN4 wird auf LOW gesetzt
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
}
else if (luxValue3 > luxValue4) {
Serial.println("Sensor 3 hat mehr Licht, der Motor dreht sich nach links");
Serial.print("Lux-Wert Sensor 3: ");
Serial.println(luxValue3); // Ausgeben des Wertes von Sensors 3
Serial.print("Lux-Wert Sensor 4: ");
Serial.println(luxValue4); // Ausgeben des Wertes von Sensors 4
Serial.println();
setMultiplexerChannel(8); //IN3 wird auf LOW gesetzt
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
setMultiplexerChannel(9); //IN4 wird auf HIGH gesetzt
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH);
setMultiplexerChannel(7);
pinMode(outputPin, OUTPUT);
analogWrite(outputPin, 100); // ENB auf 100
}
else if (luxValue4 > luxValue3) {
Serial.println("Sensor 4 hat mehr Licht, der Motor dreht sich nach rechts");
Serial.print("Lux-Wert Sensor 3: ");
Serial.println(luxValue3); // Ausgeben des Wertes von Sensors 3
Serial.print("Lux-Wert Sensor 4");
Serial.println(luxValue4); // Ausgeben des Wertes von Sensors 4
Serial.println();
setMultiplexerChannel(8); //IN3 wird auf HIGH gesetzt
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH);
setMultiplexerChannel(9); //IN4 wird auf LOW gesetzt
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW);
setMultiplexerChannel(7);
pinMode(outputPin, OUTPUT);
analogWrite(outputPin, 100); // ENB auf 100
}
}
void setMotorY()
{
if ((max(luxValue1,luxValue2)) - (min(luxValue1,luxValue2)) < 1000) { //Wenn Differenz kleiner 25000 ist, wird IN3 und IN4, welche für Motor X verantwortlich sind auf LOW geschaltet
Serial.println("Beide Sensoren haben den gleichen Lichtwert, der Motor Y stoppt");
Serial.print("Lux-Wert Sensor 1: ");
Serial.println(luxValue1); // Ausgeben des Wertes von Sensors 1
Serial.print("Lux-Wert Sensor 2: ");
Serial.println(luxValue2); // Ausgeben des Wertes von Sensors 2
Serial.println();
setMultiplexerChannel(5);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW); //IN1 auf LOW
setMultiplexerChannel(6);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW); //IN2 auf LOW
}
else if (luxValue1 > luxValue2) {
Serial.println("Sensor 1 hat mehr Licht, der Motor dreht sich nach rechts,Panel links");
Serial.print("Lux-Wert Sensor 1: ");
Serial.println(luxValue1); // Ausgeben des Wertes von Sensors 1
Serial.print("Lux-Wert Sensor 2: ");
Serial.println(luxValue2); // Ausgeben des Wertes von Sensors 2
Serial.println();
setMultiplexerChannel(5);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW); //IN1 auf LOW
setMultiplexerChannel(6);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH); //IN2 auf HIGH
setMultiplexerChannel(4);
pinMode(outputPin, OUTPUT);
analogWrite(outputPin, 100); //ENA auf 100
}
else if (luxValue2 > luxValue1) {
Serial.println("Sensor 2 hat mehr Licht, der Motor dreht sich nach links,Panel rechts");
Serial.print("Lux-Wert Sensor 1: ");
Serial.println(luxValue1); // Ausgeben des Wertes von Sensors 1
Serial.print("Lux-Wert Sensor 2");
Serial.println(luxValue2); // Ausgeben des Wertes von Sensors 2
Serial.println();
setMultiplexerChannel(5);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH); //IN1 auf HIGH
setMultiplexerChannel(6);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, LOW); //IN2 auf LOW
setMultiplexerChannel(4);
pinMode(outputPin, OUTPUT);
analogWrite(outputPin, 100); //ENA auf 100
}
}
void Endschalter()
{
setMultiplexerChannel(0); // Stelle den Multiplexer auf Kanal 0 ein
pinMode(outputPin, INPUT);
// Lese den Zustand des Endschalters auf Kanal 0 ein
int endschalterStatus0 = digitalRead(outputPin);
// Überprüfe den Zustand des Endschalters auf Kanal 0
if (endschalterStatus0 == LOW) {
Fehlerzustand = 1;
Serial.println("Endschalter 1 betätigt");
Blynk.virtualWrite(V3, Fehlerzustand);
}
setMultiplexerChannel(1); // Stelle den Multiplexer auf Kanal 1 ein
pinMode(outputPin, INPUT);
// Lese den Zustand des Endschalters auf Kanal 1 ein
int endschalterStatus1 = digitalRead(outputPin);
// Überprüfe den Zustand des Endschalters auf Kanal 1
if (endschalterStatus1 == LOW) {
Fehlerzustand = 1;
Serial.println("Endschalter 2 betätigt");
Blynk.virtualWrite(V3, Fehlerzustand);
}
setMultiplexerChannel(2); // Stelle den Multiplexer auf Kanal 2 ein
pinMode(outputPin, INPUT);
// Lese den Zustand des Endschalters auf Kanal 2 ein
int endschalterStatus2 = digitalRead(outputPin);
// Überprüfe den Zustand des Endschalters auf Kanal 2
if (endschalterStatus2 == LOW) {
Fehlerzustand = 1;
Serial.println("Endschalter 3 betätigt");
Blynk.virtualWrite(V3, Fehlerzustand);
}
setMultiplexerChannel(3); // Stelle den Multiplexer auf Kanal 3 ein
pinMode(outputPin, INPUT);
// Lese den Zustand des Endschalters auf Kanal 3 ein
int endschalterStatus3 = digitalRead(outputPin);
// Überprüfe den Zustand des Endschalters auf Kanal 3
if (endschalterStatus3 == LOW) {
Fehlerzustand = 1;
Serial.println("Endschalter 4 betätigt");
Blynk.virtualWrite(V3, Fehlerzustand);
}
}
void setMultiplexerChannel(int channel)
{
// Setze die Steuerleitungs-Pins entsprechend des gewünschten Kanals
digitalWrite(s0Pin, bitRead(channel, 0));
digitalWrite(s1Pin, bitRead(channel, 1));
digitalWrite(s2Pin, bitRead(channel, 2));
digitalWrite(s3Pin, bitRead(channel, 3));
}