Hey liebe Community,
ich habe jetzt vor etwas über einer Woche mit der Arduino programierung angefangen durch ein Familienprojekt. Da ich absoluter Neuling in C/C++ und auch Elektrontechnik bin verstehe ich nicht unbedingt alles und versuche es mir durch try´n error selbst bei zu bringen mit Youtube und Foren durchlesen. Jedoch habe ich jetzt gerade den Punkt erreicht das ich seit einigen tagen nicht so wirklich das erziele was ich eigentlich haben möchte.
Jetzt aber erstmal zu meinem Problem.
Ich möchte einen Shotausschenker bauen, der nach drücken der Start-Taste (T1) einmal durchschaut welche der 4 weiteren Tasten belegt sind und somit welche Position angefahren werden muss.
Jetzt habe ich mich schonmal dran versucht das über eine Funktion (In meinem Code "Unterprogram" genannt) und bin mit delay und millis und berechnungen gerade derbe überfragt.
Hier nun mal mein Code. Ich habe absichtlich erstmal nur T1 & T2 verwendet um zu testen. die anderen Tasten ist ja meines wissens nach nur copy&paste mit ein paar änderungen zur tasterbelegung und position.
#include <Servo.h>
// Definierung der Taster
int T1 = 2; // Taste 1 Zyklus-Start
// Variablen für Taster 1
int T1_Status = 0; // Statusanzeige
int T2 = 4; // Taste 2 Servo Pos 1
// Variablen für Taster 2
bool T2_Aktiv = true; //Variable, die den tasterzustand verfolgt
int T3 = 7; // Taste 3 Servo Pos 2
// Variablen für Taster 3
bool T3_Aktiv = true; //Variable, die den tasterzustand verfolgt
int T4 = 8; // Taste 4 Servo Pos 3
// Variablen für Taster 4
bool T4_Aktiv = true; //Variable, die den tasterzustand verfolgt
int T5 = 12; // Taste 5 Servo Pos 4
// Variablen für Taster 3
bool T5_Aktiv = true; //Variable, die den tasterzustand verfolgt
// Definierung des Servos
int servoPin = 9; // Servo-Pin
Servo servo1; // Name für den Servo
//Angaben im Unterprogramm Servo
/*int Pause = 200; // Pausenzeit zwischen den Servo schritten
int letzteBewegung = 0; // Zeit der letzten bewegung
// Definierung der Positionen
int AktuellePos = 0; // Aktuelle Position
int Pos0 = 0; // Home Position*/
int Pos1 = 20; // Servoposition 1
int Pos2 = 40; // Servoposition 2
int Pos3 = 60; // Servoposition 3
int Pos4 = 80; // Servoposition 4
// Definierung des Motors
int motorPin = 5; // Motor-Pin
// Definierung der LED
int ledPin = 13; // LED für Ausgabe des Startsignal
// Beginn vom Setup
void setup()
{
Serial.begin(9600);
//Input Pins
pinMode(T1, INPUT); // Taster 1 ist Input
pinMode(T2, INPUT); // Taster 2 ist Input
pinMode(T3, INPUT); // Taster 3 ist Input
pinMode(T4, INPUT); // Taster 4 ist Input
pinMode(T5, INPUT); // Taster 5 ist Input
//Output Pins
pinMode(motorPin, OUTPUT); // Motorpin ist Output
pinMode(ledPin, OUTPUT); // LED-Pin ist Output
}
// Ende vom Setup
// Beginn Loop
void loop()
{
// Wenn Taste 1 Aktiv, halte das Signal
if(digitalRead(T1) == HIGH)
{
digitalWrite(ledPin, LOW);
T1_Status = 1;
Serial.println("T1 Aktiv");
}
else
{
digitalWrite(ledPin, HIGH);
//T1_Status = 0;
Serial.println("T1 nicht Aktiv");
goto reset;
}
// Wenn Taste 1 & Taste 2 Aktiv, verbinde den Servo & fahre auf Position 1
if((T1_Status == 1) && digitalRead(T2) == HIGH)
{
ArmRaus(Pos1);
}
// Abschalten von Taste 1
reset:
T1_Status = 0;
// Servo zurücksetzen
servo1.attach(servoPin);
servo1.write(0);
delay(500);
servo1.detach();
// Servo auf Position
}
// Ende vom Loop
// Unterprogramm Servo
void ArmRaus(int Pos)
{
int Pause = 200; // Pausenzeit zwischen den Servo schritten
int letzteBewegung = 0; // Zeit der letzten bewegung
int AktuellePos = 0; // Aktuelle Position
int Pos0 = 0; // Home Position
unsigned long currentMillis = millis();
// Servo Start befüllen
while(AktuellePos < Pos)
{
servo1.attach(servoPin);
AktuellePos = AktuellePos + 1;
servo1.write(AktuellePos);
Pause;
}
AktuellePos = 0;
servo1.detach();
Pumpe(1000);
// Servo auf Position
}
// Unterprogramm Ende
// Unterprogramm Pumpe
void Pumpe(int Dauer)
{
// Motor Start
digitalWrite(motorPin, HIGH);
delay(Dauer);
digitalWrite(motorPin, LOW);
delay(2000);
// Motor fertig
}
// Unterprogramm Ende
Wäre super wenn mir jemand recht Einsteigerfreundlich erklären könnte wo mein fehler liegt und was ich verbessern könnte.
Ich hoffe, du hast die Elektronik nicht so zusammengebaut, wie auf deinem Schaltplan gezeichnet, der M1 hängt in der Luft, der M2 würde deinen Controller grillen, die Schalter sind seltsam verdrahtet....
Der Code ist leider auch nicht besser.
Sorry, aber ich würde empfehlen, anhand der zahlreich verfügbaren Beispiele und einer guten c++-Lektüre erstmal mit kleinen Übungsaufgaben das Programmieren an sich erlernen. Und um Elektronik selber zu entwerfen ist schon deutlich mehr Wissen erforderlich. Nicht umsonst ist das ein Studiengang.
Ansonsten einmal durchatmen und präzise beschreiben, was genau der Servo machen soll, wofür der M1 und M2 da ist, was das ganze mit zeitgesteuertem verlangsamen zu tun hat, welche Komponenten du hast, wie der Ablauf Schritt für Schritt sein soll etc.
Guten Abend @combie, danke für deine schnelle Nachricht. Jedoch werde ich da gerade nicht so wirklich schlau draus... Das "int Pause" ist ja am Ende in Verwendung genau so wie "unsigned long currentMillis" und bei mir hat das arduino IDE auch keine Fehler ausgespuckt. Das einzige Problem weshalb ich mich jetzt hier halt gemeldet habe war halt das der Servo halt so garnichts mehr tut..
Und wie genau meinst du das mit den durchnummeriert Dingen?
Das Projekt soll ein Modell von einer Zapfseule werden mit 4 Stellplätzen für Schnapsgläser drum herum. Diese werden dann auf Podeste gestellt welche dann einen Endschalter betätigen. Und mit dem drücken von taste 1 soll dann einfach nur freigegeben werden das der Servo fahren darf. Die zeitgesteuert verlangsamung einfach nur damit das Modell ggf keinen Schaden durch zu rückartige Bewegung erhält und der Schlauch zum befüllen der gläser nicht anfängt durch die Gegend zu spritzen wenn noch ein Tropfen im Schlauch sein sollte.
Aktuell habe ich den Schaltplan nur mit tinkercad gemacht um halbwegs etwas darstellen zu können. An meinem arduino Uno ist bisher nur T1 auf D2 gesteckt für das Signal und T2 auf D4. Der Servo bekommt über D9 sein Signal.
Die Taste für T1 habe ich an 5V und über einen 10K Wiederstand an Masse angeschlossen.
Den Endschalter für T2 habe ich an 5V, Maße und Signal geschaltet.
Der Servo ist ebenso an 5V und Masse angeschlossen.
Für den Motor habe ich mir eine 12v Pumpe sowie die dazu passende 12v batteriebox bestellt um das Board nicht zu grillen. Die habe ich aber noch nicht hier und bevor ich die anschließe möchte ich mich erst in Ruhe um die Steuerung von Servo kümmern.
jeder Stellplatz hat einen Schalter, der durch das Glas betätigt werden soll
es gibt einen zentralen Taster, der den Vorgang startet
Der Servo soll den Schlauch zum Glas bringen? Was aber, wenn mehr als eins da steht?
Die Pumpe soll dann was ins Glas pumpen? hast du den Sprit in einem Eimer? Wie lange soll denn die Pumpe laufen?
Zum Schalten der Pumpe brauchst du mindestens noch ein Relais-Board
Jeder schalter benötigt einen eigenen Eingang am Controller, in dem Schaltplan hast du sie alle parallel auf einen Eingang gelegt, damit kannst du sie nicht auseinanderhalten.
Die Strategie von "teile und herrsche" hat sich bei größeren Projekten bewährt.
Hierbei wird das Projekt in logische Teilprojekte zerlegt, die einzeln programmiert und getestet werden können.
Teilprojekte:
Buttom-Manager
Servo-Controller
Pump-Controller
Timer Module
dass was mir nicht einfällt
Als Neuling empfehle ich dir mit dem Design und der Programmierung des Time-Modules zu beginnen.
Das Time-Module stellt Zeitschlitze bereit, in denen ein Stück Programm ausgeführt wird, wie z.B. das Entprellen der Tasten oder das Steuern von Servos und Motoren. So erhält man ein Echtzeitprogramm, das blockadefrei dreht und so zu jeder Zeit auf Ereignisse reagieren kann.
Das Time-Module läßt sich prima aus dem "BlinkWithOutDelay" Beispiel aus dem IDE ableiten.
Das Timer-Module hat die folgenden Funktionen:
init() -> Übergabe der Timer-Variablen
start(currentMillis) -> startet den Timer zur angegebenen Zeit
stop() -> stoppt den Timer
expired(currentMillis) -> prüfen, ob der Timer abgelaufen ist, um eine eine Funktion zu starten.
Perfekt. Danke dir schonmal für die gute und ausführliche Beschreibung. Ich werde mich mal nach der Arbeit dran setzen und schauen was ich aus dem Code blinkwithoutdelay so schönes zaubern kann. Damit sollte ich zumindest schonmal weiter kommen💪
Mein Tipp ist die Programmbibliothek MobaTools, wo Du die Servogeschwindigkeit einstellen kannst und Zeitgeber findest, wenn Dir die millis() Schwierigkeiten bereiten sollten. Kannst Du über die Bibliotheksverwaltung der IDE installieren. Schau mal in die pdf-Datei und die Beispiele.
Bei der ständig laufenden Schleife loop() ist eine Schrittkette (=finite state machine, =endlicher Automat) eine große Hilfe, ich sage sogar, unverzichtbar
Das ist auf jeden Fall mal eine falsche Annahme. Copy/Paste ist immer eine sehr schlechte Variante. Such mal nach 'Arrays C++' (konkreter Link ist ein Beispiel). Auch das genannte Stichwort 'endlicher Automat' oder 'Schrittkette' könnte dir weiterhelfen.
Sorry, aber das würde mir zu lange dauern. Lieber schreibe ich Dir ein Einstiegsprogramm mit Schrittkette, langsam laufendem Servo und Zeitgeber als Ausgangspunkt für eigene Erweiterungen:
Wow... Danke für den Code. Ich werde mich direkt mal mit auseinander setzen und den durchgehen bis ich verstehe wo, wie, was passiert und ausgeführt wird. Das du da noch die Kommentare bei gepackt hast wird mir das ganze wahrscheinlich sehr vereinfachen.
Hier nochmal der richtige Schaltplan nur statt 6V habe ich 12V weil meine peristaltische pumpe das benötigt. So würde ich das wohl aufbauen und ggf mein Vater (gelernter Elektriker) fragen ob das so korrekt ist bevor ich etwas anschließe.