Funktionsaufrufe und deren Umsetzung?!

Moin alle zsm,

ich bin neu hier und beschäftige mich seit einigen Tagen mit dem Arduino. Nach Stundenlangem lesen habe ich die ersten Versuche schon hintermir.

Lampe an aus, Motor steuern, Taster Schalter etc…

Ich würde jetzt gerne das halbwissen einfach mal zusammenstecken und ein gesammtes Programm mit einer Sinnvollen Anwendung schreiben. Derzeit fehlt es mir jedoch irgendwie an der Umsetzung.

Ich habe zum Bespiel ein kleines Programm geschrieben mit 3 verschiedenen State’s. Womit ich je nachdem welchen Taster ich drücke den Motor anhalte,links-rum oder rechtsrum drehen lasse.
Gleichzeitig leuchtet je nachdem was der Motor macht eine andere LED. Über einen Poti kann ich die Geschwindigkeit ändern.

Es wäre toll wenn mal jmd über das Programm drüber schaut und sagt ob es vielleicht eine bessere/einfachere Methode gibt sowas zu programmiern.

const int LED1 = 10;   // the pin for the LED
const int BUTTON1 = 4; // the input pin where the

const int LED2 = 11;   // the pin for the LED
const int BUTTON2 = 2; // the input pin where the

const int LED3 = 12;   // the pin for the LED
const int BUTTON3 = 3; // the input pin where the
#define poti 0
int potiwert;
int potiwert4;
int potiwert5;


//Motor
const int motorPin1 = 7;
const int motorPin2 = 8;
const int enablePin = 5;
int speed = 150; // Geschwindigkeit 50%, max. 255

// pushbutton is connected
int val1 = 0;    // val will be used to store the state
int old_val1 = 0; // this variable stores the previous
int state1 = 0;   // 0 = LED off and 1 = LED on

int val2 = 0;    // val will be used to store the state
int old_val2 = 0; // this variable stores the previous
int state2 = 0;   // 0 = LED off and 1 = LED on

int val3 = 0;    // val will be used to store the state
int old_val3 = 0; // this variable stores the previous
int state3 = 0;   // 0 = LED off and 1 = LED on



void setup() {
pinMode(LED1, OUTPUT);   // tell Arduino LED is an output
pinMode(BUTTON1, INPUT); // and BUTTON is an input
pinMode(LED2, OUTPUT);   // tell Arduino LED is an output
pinMode(BUTTON2, INPUT); // and BUTTON is an input
pinMode(LED3, OUTPUT);   // tell Arduino LED is an output
pinMode(BUTTON3, INPUT); // and BUTTON is an input

pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);

Serial.begin(9600);


}


void loop(){

potiwert = analogRead(poti);
potiwert4 = potiwert/4;
potiwert5 = ((potiwert/4) * 100)/255;
Serial.print("GESCHW: ");
 Serial.print(potiwert5);
 Serial.println(" %");

  
//LED1  
val1 = digitalRead(BUTTON1); 
if ((val1 == HIGH) && (old_val1 == LOW)){
state1 = 1 - state1;
}
old_val1 = val1;  
if (state1 == 1) {
digitalWrite(LED1, HIGH); // turn LED ON
state2 = 0;
state3 = 0;
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
analogWrite(enablePin, potiwert4);   
 digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, LOW);
 Serial.println("LED1-Motor-Links");

} else {
//digitalWrite(LED1, LOW);
}


//LED2  
val2 = digitalRead(BUTTON2); 
if ((val2 == HIGH) && (old_val2 == LOW)){
state2 = 1 - state2;
}
old_val2 = val2;  
if (state2 == 1) {
digitalWrite(LED2, HIGH); // turn LED ON
state1 = 0;
state3 = 0;
digitalWrite(LED1, LOW);
digitalWrite(LED3, LOW);


analogWrite(enablePin, potiwert4);   
 digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, HIGH);
 Serial.println("LED2-Motor-Rechts");
} else {
//digitalWrite(LED2, LOW);
}


//LED3  
val3 = digitalRead(BUTTON3); 
if ((val3 == HIGH) && (old_val3 == LOW)){
state3 = 1 - state3;
}
old_val3 = val3;  
if (state3 == 1) {
digitalWrite(LED3, HIGH); // turn LED ON
state1 = 0;
state2 = 0;
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
analogWrite(enablePin, 0);  
Serial.println("LED3-Motor-AUS"); 


} else {
//digitalWrite(LED3, LOW);
}
}

Ich würde gerne ein wenig mehr Richtung Achsansteuerung und solche Sachen gehen. Es soll sowas wie ein Ablaufprogramm werden. Über verschiedene Tasten wähle ich zwischen Manuell und Automatik.
Im Manuellen Modus kann ich die Achsen bewegen und im Automatik modus soll eine fest definierte Reihenfolge der Achsen angesteuert werden. Die Achsen bremsen jeweils ab sobald ein Endschalter berührt wird.

Könnte ich nun die Umschaltung zwischen Manuell und Automatik wieder als State machen? Oder gibt es ne bessere Alternative?

Ich bedanke mich im vorraus!

Viele Grüße

Ben

bens0r:
Es wäre toll wenn mal jmd über das Programm drüber schaut ...

Ich habe Dein Programm nur grob überflogen und kann Dir zum Inhalt keine Tipps geben.

Statt dessen etwas zur Form: Du solltest gucken, dass Du „schönen“ Code schreibst. Damit meine ich Code, der sich „leicht“ lesen und nachvollziehen lässt. Hilfreich sind auf jeden Fall sinnvolle und einheitliche Einrückungen und Klammerung. Eine schnelle Hilfe hierbei ist die „Automatische Formatierung“ im Werkzeuge-Menü (oder STRG-T).

Abgesehen davon, dass es für „Code-fremde“ Personen besser zu lesen ist, hilft es Dir bei der Fehlersuche (bzw. um Fehler zu vermeiden).

Ich hoffe, das hilft schonmal.

Gruß

Gregor

Es gibt zwei wichtige Dinge: Datenstrukturen und Algorithmen

Wenn man sowas sieht:

int val1 = 0;    // val will be used to store the state
int old_val1 = 0; // this variable stores the previous
int state1 = 0;   // 0 = LED off and 1 = LED on

Sollte einem sofort auffallen dass man das in einem struct zusammenfassen kann. Aus dem struct kann man dann evtl. ein Array bilden. Ob das sinnvoll ist hängt davon ab was man damit macht.

Vom Algorithmus her willst du einen endlichen Automaten/Zustandsautomaten/Finite State Machine. Das wurde hier schon häufig behandelt.
Die einfachste Version ist ein enum für die Zustände, eine Variable um den aktuellen Zustand zu speichern und dann ein switch/case um darauf abzufragen in welchem Zustand man ist. Gibt aber auch andere Optionen.

Könnte ich nun die Umschaltung zwischen Manuell und Automatik wieder als State machen? Oder gibt es ne bessere Alternative?

Ja.
Nöö.

int val1 = 0;    // val will be used to store the state
int old_val1 = 0; // this variable stores the previous
int state1 = 0;   // 0 = LED off and 1 = LED on

Wenn val1 einen state speichert, warum nennst du es dann nicht state1? Analog auch old_state etc.
Dein state1 heißt dann besser LED_state1 oder LED1_state.
Und ein int ist zu groß für den Wertebereich, ein byte genügt. Das sind bei einem kleinen Programm zwar nur "peanuts", aber bei nur 2k RAM sollte man sparen, wo man kann :slight_smile:

int val1 = 0;    // val will be used to store the state
int old_val1 = 0; // this variable stores the previous
int state1 = 0;   // 0 = LED off and 1 = LED on

Für Zustände von I/Os reicht bool anstelle int (zwei Byte); globale Variablen erhalten immer den Wert "0":

bool val1, val2, val3;    // val will be used to store the state
bool old_val1, old_val2, old_val3; // this variable stores the previous
bool state1, state2, state3;   // 0 = LED off and 1 = LED on
potiwert5 = ((potiwert/4) * 100)/255;

Erst durch Vier und dann mal Einhundert kann bei Integeroperationen zu unerwarteten Ergebnissen führen. Hier ist das wohl nicht relevant, aber mal 25 reicht doch auch. Den Ursprung der Überlegung dann in den Kommentar:

potiwert5 = potiwert * 25 / 255;  ((potiwert/4) * 100)/255
if ((val1 == HIGH) && (old_val1 == LOW))

Die Flankenauswertung kann man, wenn man möchte, abkürzen:

if (val1 && !old_val1)

Verstehe dies bitte als Anregungen.

Anleitung Ein Endlicher Automat entsteht
Anleitung: Endlicher Automat mit millis()

Erst durch Vier und dann mal Einhundert kann bei Integeroperationen zu unerwarteten Ergebnissen führen. Hier ist das wohl nicht relevant, aber mal 25 reicht doch auch.

Schon richtig, aber wenn wir schonmal dabei sind:

" /255 " ist auch "immer" falsch :wink:

Wenn du wirklich die 256 Werte 0 .. 255 gleichmässig auf die 101 Werte 0 .. 100 abbilden willst, solltest du
*101/256  rechnen. (Wobei /256 für einen µController und den Compiler ein Klacks ist, deswegen ist der Ursprungsbereich ja 256 Werte groß.)