ich bin Arduino Anfänger und versuche mir alles etwas selber beizubringen möglicherweise sind in meinem Sketch einige fehler drinnen..
Benutzter Arduino/Genuino = Genuino MKR1000
nun zum Problem, ich habe mir zu Hause eine Kräuterbewässerung gebastelt mit einem 10l Wassertank dazu eine Wasserpumpe (Kreiselpumpe, 12V, Maximale Stromaufnahme 770mA bei Nominalspannung).
Die Pumpe kann Per Taster (Schliesser, Pin 4) oder Per APP (Blynk App Virtueller Button V0) gestartet werden und sollte dann 90000ms giessen. Die Pumpe hängt an einen Relais (min 3,3V Input) und wird über eine Batterie (12V / 7Ah wovon der - Pol ausgangsseitig am Relais hängt) betrieben. Zusätzlich zur Pumpe zeigt eine LED (Pin 3) und eine Virtuelle LED (Blynk App Virtuelle LED V1) an wann gerade gegossen wird.
Im Tank befindet sich zusätzlich ein Schwimmer (Reedkontakt, Pin 0) der Das Giessprogramm stoppt wenn Wasser leer und zusätzlich eine Rote LED (Pin 2) leuchten lässt. Der Genuino und das Relais sind in einer Tupperwarebox verbaut und die 12V Batterie ist extern. Der Genuino hängt mit einem Netzteil (5V, 1000mA OUTPUT) an einer Steckdose.
Das Problem dabei ist das sich der Genuino nach ungewisser Zeit (manchmal 6h, manchmal 3 Tage) komplett aufhängt dann kann man weder per Button noch per Virtual Button die Begiessung starten und die Blynk APP geht offline.
Zuerst dachte ich mir es liegt an den Raffstoren die wenn ich sie zumache das W-Lan abschirmen da immer wenn ich zugemacht habe ein paar Stunden dannach nichts mehr ging (ich dachte das sich der Genuino solange probiert wieder ins W-Lan einzuwählen bis er sich irgendwo verhängt). Die nächste vermutung war das die Pumpe über die Leitung zum Relais ein Magnetfeld erzeugt und irgendwie den Arduino nach einiger Zeit nach der begiessung zum hängen bringt. Ich habe jetzt die Raffstoren mal drei Tage offen gelassen und in der Zeit dreimal gegossen, und er war bis Heute Online (insg. 3 Tage). Was mir aufgefallen ist, ist das der Genuino warscheinlich immer nur nach begiessung hängt, da ich den Arduino auch schon 1 Woche Online hatt jedoch diese Woche per Hand gegossen habe (zur Fehlereingrenzung) nach dieser Woche habe ich mal per App gegossen und nach einiger Zeit verhängte sich alles wieder...
ich bin mit meiner Fehlereingrenzung am ENDE... die einzige idee wäre noch das ich den Sketch unnötig komplex oder durcheinander gemacht habe und sich der Genuino darum aufhängt.. vielleicht habt Ihr ideen hier der Sketch:
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <WiFi101.h>
#include <BlynkSimpleWiFiShield101.h>
#include <SimpleTimer.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "ff08f959f06b44558613636f3cffa622";
char ssid[] = "UPCFA246C8";
char pass[] = "MhAycvynbr2p";
int lastConnectionAttempt = millis(); // timer der die Zeit ab WiFi verbindungsabbruch prüft
int connectionDelay = 5000; // timerzeit nach Verbindungsabbruch wird alle 5000ms (5sec.) dei Verbindung geprüft
WidgetLED wasserLedV(V1); // register to virtual pin 1
WidgetLED wasserLedleerV(V2); // register to virtual pin 2
const int sensorPin = 0; // select the input pin for the sensor
int switchPin = 4; // select the input pin for the switch
int pumpPin = 1; // select the pin for the Pump LED
const int wasserLed = 2; // Pin for Waterpump
int pumpLed = 3; // pin for LED Water flows
boolean isMotorAn = false; // boolean isWasserleer = false;
boolean isWasserleer = false;
byte switchValue; // variable to store the value coming from the switch
int sensorValue = 0; // variable to store the value coming from the float sensor
unsigned long water_timestore; // Variable Speicher für Systemzeit Wasser fliesst.
//unsigned long water_empty; // Variable Speicher für Systemzeit Wasser leer.
BLYNK_WRITE(0) // Blynk write Virtual switch V0 (Virtueller switch zum Starten der Bewässerung)
{
int i=param.asInt();
if (!isMotorAn && sensorValue == LOW && switchValue == HIGH or i==1) {
// Wenn die Pumpe nicht an ist und der Taster (4) gedrückt wird oder der Virtuelle
// Taster (V0) gedrückt wird --> anschalten
Serial.print("Taster High"); // Taster High ins serielle Terminal schreiben
Serial.print("\t"); // Tabulator im seriellen Terminal schreiben
digitalWrite(pumpLed, HIGH); // Blaue LED "PumpLed" (3) einschalten
wasserLedV.on(); // Virtuelle Blaue LED "WasserLedV" (V1) einschalten
digitalWrite(pumpPin, HIGH); // Wasserpumpe "pumpPin" (1) einschalten
water_timestore = millis(); // Timer "water_timestore" starten
isMotorAn = true; // Wert "isMotorAn" auf "true" schalten
}else // anderfalls
{
if (isMotorAn && millis() - water_timestore > 90000) {
// Wenn die Pumpe an ist und der Timer "water_timestore" 90000ms (1,2min.) erreicht hat
digitalWrite(pumpPin, LOW); // Wasserpumpe "pumpPin" (1) ausschalten
digitalWrite(pumpLed, LOW); // Blaue LED "PumpLed" (3) ausschalten
wasserLedV.off(); // Virtuelle Blaue LED "WasserLedV" (V1) ausschalten
isMotorAn = false; // Wert "isMotorAn" auf "false" schalten
}
}
}
void connection() { // abfolge für das testen der WiFi Verbindung
// WiFi Verbindung prüfen
if (WiFi.status() != WL_CONNECTED)
{
if (millis() - lastConnectionAttempt >= connectionDelay)
{
lastConnectionAttempt = millis(); // wenn die Verbindung länger als 5000ms getrennt ist timer starten
Serial.print ("WiFi connection lost");
// "Wifi connection lost" ins serielle Terminal schreiben
Serial.print ("\t"); // Tabulator im seriellen Terminal schreiben
// versucht eine Verbindung zum Netzwerk herzustellen
if (pass && strlen(pass))
{
WiFi.begin((char*)ssid, (char*)pass);
}
else
{
WiFi.begin((char*)ssid);
}
}
}
else
{
Blynk.run();
}
}
void setup() {
Blynk.begin(auth, ssid, pass);
// You can also specify server:
// Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
// Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
while (Blynk.connect() == false) {
// Wait until connected
}
pinMode (sensorPin, INPUT); // sensorPin als INPUT setzen (float sensor)
pinMode (4, INPUT); // switchPin als INPUT setzen (Switch for Waterpump on) _PULLUP
pinMode(pumpPin, OUTPUT); // pumpPin als Output setzen (Waterpump)
pinMode(wasserLed, OUTPUT); // wasserLed als Output setzen ("Water empty" LED)
pinMode(pumpLed, OUTPUT); // pumpLed als Output setzen ("Water On" LED)
// Debug console
Serial.begin(9600);
}
void loop() {
{Blynk.run();}
switchValue = digitalRead(switchPin);
// nur wenn der Motor nicht an ist und der Schalter betätigt
if (!isMotorAn && switchValue == HIGH && sensorValue == LOW) {
// anschalten
Serial.print("Button High"); // schereibt in den Serial Monitor "Button High"
Serial.print("\t"); // schereibt in den Serial Monitor einen Tabulator
digitalWrite(pumpLed, HIGH); // schaltet die Led für Pumpe läuft ein
wasserLedV.on(); // schaltet die Virtuelle Led (Blynk) für Pumpe läuft ein
digitalWrite(pumpPin, HIGH); // schaltet die Pumpe ein
water_timestore = millis(); // startet den Timer
isMotorAn = true; // schreibt die variable isMotorAn auf wahr also Motor läuft
}
if (isMotorAn && millis() - water_timestore > 90000) {
// wenn der TImer 90000ms abgelaufen und die Pumpe an ist ausschalten
digitalWrite(pumpPin, LOW); // schaltet die Pumpe aus
digitalWrite(pumpLed, LOW); // schaltet die Led für Pumpe läuft ein
wasserLedV.off(); // schaltet die Virtuelle Led (Blynk) für Pumpe läuft aus
isMotorAn = false; // schreibt die variable isMotorAn auf false also Motor aus
}
sensorValue = digitalRead(sensorPin); //liest den Pin für den Schwimmerschalter, An oder Aus
if (!isWasserleer && sensorValue == HIGH)// wenn das Wasser nicht schon leer ist und der Sensor Wasser leer zeigt
{
digitalWrite (wasserLed, HIGH); // schaltet die Led für Wasser leer ein
digitalWrite (pumpPin, LOW); // schaltet die Pumpe aus
digitalWrite (pumpLed, LOW); // schaltet die Led für Pumpe läuft aus
//wasserLedV.off();
isMotorAn = false; // schreibt die variable isMotorAn auf false also Motor aus
//wasserLedleerV.on();
//Serial.write ("\t");
//Serial.write ("Wasser leer");
//water_empty = millis();
isWasserleer = true; // schreibt die variable isWasserleer auf true also Wasser leer
}
//if (isWasserleer && millis() - water_empty > 10000) { //
else{ // anderfalls also wenn Wasser nicht leer
digitalWrite (wasserLed, LOW); // schaltet die Led für Wasser leer aus
// wasserLedleerV.off();
isWasserleer = false; // schreibt die variable isWasserleer auf false also Wasser nicht leer
}
//Blynk.syncAll();
connection();
}
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <WiFi101.h>
#include <BlynkSimpleWiFiShield101.h>
#include <SimpleTimer.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "ff08f959f06b44558613636f3cffa622";
char ssid[] = "UPCFA246C8";
char pass[] = "MhAycvynbr2p";
int lastConnectionAttempt = millis(); // timer der die Zeit ab WiFi verbindungsabbruch prüft
int connectionDelay = 5000; // timerzeit nach Verbindungsabbruch wird alle 5000ms (5sec.) dei Verbindung geprüft
WidgetLED wasserLedV(V1); // register to virtual pin 1
WidgetLED wasserLedleerV(V2); // register to virtual pin 2
const int sensorPin = 0; // select the input pin for the sensor
int switchPin = 4; // select the input pin for the switch
int pumpPin = 1; // select the pin for the Pump LED
const int wasserLed = 2; // Pin for Waterpump
int pumpLed = 3; // pin for LED Water flows
boolean isMotorAn = false; // boolean isWasserleer = false;
boolean isWasserleer = false;
byte switchValue; // variable to store the value coming from the switch
int sensorValue = 0; // variable to store the value coming from the float sensor
unsigned long water_timestore; // Variable Speicher für Systemzeit Wasser fliesst.
//unsigned long water_empty; // Variable Speicher für Systemzeit Wasser leer.
BLYNK_WRITE(0) // Blynk write Virtual switch V0 (Virtueller switch zum Starten der Bewässerung)
{
int i=param.asInt();
if (!isMotorAn && sensorValue == LOW && switchValue == HIGH or i==1) {
// Wenn die Pumpe nicht an ist und der Taster (4) gedrückt wird oder der Virtuelle
// Taster (V0) gedrückt wird --> anschalten
Serial.print("Taster High"); // Taster High ins serielle Terminal schreiben
Serial.print("\t"); // Tabulator im seriellen Terminal schreiben
digitalWrite(pumpLed, HIGH); // Blaue LED "PumpLed" (3) einschalten
wasserLedV.on(); // Virtuelle Blaue LED "WasserLedV" (V1) einschalten
digitalWrite(pumpPin, HIGH); // Wasserpumpe "pumpPin" (1) einschalten
water_timestore = millis(); // Timer "water_timestore" starten
isMotorAn = true; // Wert "isMotorAn" auf "true" schalten
}else // anderfalls
{
if (isMotorAn && millis() - water_timestore > 90000) {
// Wenn die Pumpe an ist und der Timer "water_timestore" 90000ms (1,2min.) erreicht hat
digitalWrite(pumpPin, LOW); // Wasserpumpe "pumpPin" (1) ausschalten
digitalWrite(pumpLed, LOW); // Blaue LED "PumpLed" (3) ausschalten
wasserLedV.off(); // Virtuelle Blaue LED "WasserLedV" (V1) ausschalten
isMotorAn = false; // Wert "isMotorAn" auf "false" schalten
}
}
}
void connection() { // abfolge für das testen der WiFi Verbindung
// WiFi Verbindung prüfen
if (WiFi.status() != WL_CONNECTED)
{
if (millis() - lastConnectionAttempt >= connectionDelay)
{
lastConnectionAttempt = millis(); // wenn die Verbindung länger als 5000ms getrennt ist timer starten
Serial.print ("WiFi connection lost");
// "Wifi connection lost" ins serielle Terminal schreiben
Serial.print ("\t"); // Tabulator im seriellen Terminal schreiben
// versucht eine Verbindung zum Netzwerk herzustellen
if (pass && strlen(pass))
{
WiFi.begin((char*)ssid, (char*)pass);
}
else
{
WiFi.begin((char*)ssid);
}
}
}
else
{
Blynk.run();
}
}
void setup() {
Blynk.begin(auth, ssid, pass);
// You can also specify server:
// Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
// Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
while (Blynk.connect() == false) {
// Wait until connected
}
pinMode (sensorPin, INPUT); // sensorPin als INPUT setzen (float sensor)
pinMode (4, INPUT); // switchPin als INPUT setzen (Switch for Waterpump on) _PULLUP
pinMode(pumpPin, OUTPUT); // pumpPin als Output setzen (Waterpump)
pinMode(wasserLed, OUTPUT); // wasserLed als Output setzen ("Water empty" LED)
pinMode(pumpLed, OUTPUT); // pumpLed als Output setzen ("Water On" LED)
// Debug console
Serial.begin(9600);
}
void loop() {
{Blynk.run();}
switchValue = digitalRead(switchPin);
// nur wenn der Motor nicht an ist und der Schalter betätigt
if (!isMotorAn && switchValue == HIGH && sensorValue == LOW) {
// anschalten
Serial.print("Button High"); // schereibt in den Serial Monitor "Button High"
Serial.print("\t"); // schereibt in den Serial Monitor einen Tabulator
digitalWrite(pumpLed, HIGH); // schaltet die Led für Pumpe läuft ein
wasserLedV.on(); // schaltet die Virtuelle Led (Blynk) für Pumpe läuft ein
digitalWrite(pumpPin, HIGH); // schaltet die Pumpe ein
water_timestore = millis(); // startet den Timer
isMotorAn = true; // schreibt die variable isMotorAn auf wahr also Motor läuft
}
if (isMotorAn && millis() - water_timestore > 90000) {
// wenn der TImer 90000ms abgelaufen und die Pumpe an ist ausschalten
digitalWrite(pumpPin, LOW); // schaltet die Pumpe aus
digitalWrite(pumpLed, LOW); // schaltet die Led für Pumpe läuft ein
wasserLedV.off(); // schaltet die Virtuelle Led (Blynk) für Pumpe läuft aus
isMotorAn = false; // schreibt die variable isMotorAn auf false also Motor aus
}
sensorValue = digitalRead(sensorPin); //liest den Pin für den Schwimmerschalter, An oder Aus
if (!isWasserleer && sensorValue == HIGH)// wenn das Wasser nicht schon leer ist und der Sensor Wasser leer zeigt
{
digitalWrite (wasserLed, HIGH); // schaltet die Led für Wasser leer ein
digitalWrite (pumpPin, LOW); // schaltet die Pumpe aus
digitalWrite (pumpLed, LOW); // schaltet die Led für Pumpe läuft aus
isMotorAn = false; // schreibt die variable isMotorAn auf false also Motor aus
isWasserleer = true; // schreibt die variable isWasserleer auf true also Wasser leer
}else{
// anderfalls also wenn Wasser nicht leer
digitalWrite (wasserLed, LOW); // schaltet die Led für Wasser leer aus
isWasserleer = false; // schreibt die variable isWasserleer auf false also Wasser nicht leer
}
//Blynk.syncAll();
connection();
}
Im Anhang noch das Fritzing (mein erstes Fritzing, habe es gerade noch schnell gemacht)!
Edit:
Und was ist das für ein Relais, das du direkt am Arduino-Pin angeschlossen hast.
Der Pin liefert sicher nicht genug Strom für die Relaisspule.
Und die Pins D0 und D1 solltest du nie extern beschalten. Die werden für den Upload mit dem USB-Serialwandler benötigt und können den Upload stören bzw. verhindern.
Das ändert alles.
Das Relais (SSR) kannst du nicht einsetzen, Es ist nicht zum Schalten von Gleichspannung geeignet.
Okay, kannst Du mir vielleicht in kurzen Worten erkären wieso das einen unterschied macht?
Die Begiessung funktioniert mit dem Relais, ist bei einem Wechselsromrelais eine höhere Induktion?
Was die Dioden betrifft, sieh dir meinen Link zu Wicki an.
hab es mir schon angesehen aber befürchte dafür etwas zu wenig fachwissen.
sandrokoeldorfer:
Okay, kannst Du mir vielleicht in kurzen Worten erkären wieso das einen unterschied macht?
Die Begiessung funktioniert mit dem Relais, ist bei einem Wechselsromrelais eine höhere Induktion?
Ok, das übersteigt leider mein Fachwissen.
Ein Versuch:
Es ist hier kein echtes Relais sondern ein Halbleiter, der nur richtig mit Wechselspannung funktioniert.
Also sicher ist dies nicht.
hab es mir schon angesehen aber befürchte dafür etwas zu wenig fachwissen.
Diese Diode wird "antiparallel" angeschlossen, also Anode an Minus und Katode an Plus der jeweiligen Spule.
Diese verhindert beim Abschalten das die entstehende Spannung den Halbleiter zerstört.
An deinem Relais ist es hier nicht nötig, aber das Relais ist falsch.
Ok, das übersteigt leider mein Fachwissen.
Ein Versuch:
Es ist hier kein echtes Relais sondern ein Halbleiter, der nur richtig mit Wechselspannung funktioniert.
Also sicher ist dies nicht.
Verstehe ich schon etwas, Checke nur nicht wieso das Relais fehlerlos anzieht usw.
Diese Diode wird "antiparallel" angeschlossen, also Anode an Minus und Katode an Plus der jeweiligen Spule.
Diese verhindert beim Abschalten das die entstehende Spannung den Halbleiter zerstört.
An deinem Relais ist es hier nicht nötig, aber das Relais ist falsch.
Okay, ich verstehe. Danke!
Ich halte mal fest, ich werde mir wohl ein neues Relais (Gleichstrom) besorgen und die Freilaufdioden an der Pumpe und am Coil des Relais einbringen.
Dieses SSR hat als Ausgang einen Triac. Einen Triac kann man durch einen Strom am Gate einschalten aber nicht mehr auschalten. Der Triac schaltet sich aus, wenn der Strom zwischen A1 und A2 auf null fällt. Bei 50 Hz Wechselstrom ist das alle 20mS der Fall. Bei Gleichstrom ist das nie der Fall.
Der Schalter S1 ist falsch geschaltet. Du brauchst einen Pullup/pulldown Widerstand (Widerstand in Reihe zum Taster zwischen Masse und +5V und Eingang an Kontakt Taster-Widerstand) Wie bei S2.
Ich hatte auch mal das Problem, dass sich der Controller gerne aufgehangen hat. Es lag an der seriellen Kommunikation im Programm: wurde sie auch nur initialisiert, so hing sich der Controller auf, wenn er nicht mit einem Computer verbunden war.
Also alle Zeilen mit Serial. rausnehmen oder extra als Debug-Zeilen benutzen.
Dass die Pins D0 und D1 nicht beschaltet werden sollten wurde ja schon geschrieben
uwefed:
Dieses SSR hat als Ausgang einen Triac. Einen Triac kann man durch einen Strom am Gate einschalten aber nicht mehr auschalten. Der Triac schaltet sich aus, wenn der Strom zwischen A1 und A2 auf null fällt. Bei 50 Hz Wechselstrom ist das alle 20mS der Fall. Bei Gleichstrom ist das nie der Fall.
Nicht ganz korrekt.
Der Strom muß nicht 0 sein.
Der Triac (Thyristor genauso) bleibt nach der Zündung so lange eingeschaltet bis der Haltestrom unterschritten wird. Im Datenblatt wird für diese SSR ein Minimalstrom von 0,05A angegeben. Wenn dieser unterschritten wird, schaltet der enthaltene Triac ab. Wenn jetzt die Pumpe also jetzt kurzzeitig weniger als die 50mA zieht, schaltet der Triac ab wenn der im SSR enthaltene Optokoppler am Eingang kein Signal mehr hat.
Habe jetzt wie folgt änderungen vorgenommen:
Eine Diode wurde bei der Pumpe eingebracht, der Schwimmerschalter (Reedkontakt) wurde auf Pin 5 geändert, die Pumpe (Relais) auf Pin 6. Der 10kOhm Widerstand beim Schwimmerschalter (Reedkontakt) wurde entfernt und dafür der 220Ohm Widerstand beim Schalter S2 (Schalter für "Pumpe Start") auf 10kOhm geändert (siehe Fritzing und Sketch im Anhang, siehe Genuino im Fritzing wurde jetzt richtig beschriftet, es gibt nämlich keinen MKR1000 im Fritzing, die "5V" im Fritzing sind eig. 3,3V wie beim MKR1000).
Dieses SSR hat als Ausgang einen Triac. Einen Triac kann man durch einen Strom am Gate einschalten aber nicht mehr auschalten. Der Triac schaltet sich aus, wenn der Strom zwischen A1 und A2 auf null fällt. Bei 50 Hz Wechselstrom ist das alle 20mS der Fall. Bei Gleichstrom ist das nie der Fall.
Evtl. Zufall ?
wie gesagt komischerweise Schaltet das Relais einwandfrei Ein und nach der abgelaufenen Zeit (90000ms) wieder aus.
Oder einen Transistor. Mosfet N-Channel IRFZ34 sollte da funktionieren.
Allerdings mit Relais-Modul ist es einfacher.
kann beim Genuino MKR1000 nur eine Spannung von 3,3V schalten (habe MOSFET´s abe diese schalten glaube ich erst ab 5V..?!)
und die Relais Module ebenfalls (jedenfalls die, die ich Online gefunden habe) darum habe ich ziemlich Blind eines für Wechselstrom bestellt das ab 3V schaltet :-P.
bin jetzt gespannt wie lange der Controller Online bleibt habe jetzt mal alles hochgeladen und somit einen Reboot gemacht. Werde euch auf jedenfall auf dem laufenden halten!