Ich benötige wieder einmal Hilfe.
Ich versuche zwei Servo Motoren mit jeweils einem Poti zu steuern und diesen Bewegungsablauf zu speichern.
Habe dafür einen Sketch gefunden zur Steuerung eines Roboterarmes.
Es funktioniert soweit.
Jetzt stehe ich vor dem Problem, daß ich das ganze ohne PC betreiben möchte.
So kam mir die Idee, die Anzeige des verbleibenden Speichers mit LED‘s auszugeben. Sowie Record und Play über zwei Button zu steuern.
Der erste Schritt war die LED Ausgabe. Der Sketch funktioniert mit der Ansteuerung über den Seriellen Monitor.
[code]
/*
Robotic ARM with Record and Play option using Arduino
Code by: B. Aswinth Raj
Website: www.circuitdigest.com
Dated: 05-08-2018
*/
#include <Servo.h> //Servo Bibliothek
Servo Servo_0;
Servo Servo_1;
//Servo Servo_2;
//Servo Servo_3;
//Servo Gripper;
const int buttonR = 8;
const int buttonP = 12;
int ledBlau = 7;
int ledGelb = 4;
int ledRot = 13;
int ledBlauStatus = LOW; //der LED-Blau-Status
int ledRotStatus = LOW; //der LED-Rot-Status
int ledGelbStatus = LOW; //der LED-Gelb-Status
int buttonRStatus; //zum zwischenspeichern des aktuellen Record-Schalter-Status
int buttonPStatus; //zum zwischenspeichern des aktuellen Play-Button-Status
int letzterButtonRStatus = LOW; //zum zwischenspeichern des letzten Record-Schalter-Status
int letzterButtonPStatus = LOW; //zum zwischenspeichern des letzten Play-Schalter-Status
//long ist ein Datentyp für große Zahlen; unsigned bedeutet, dass nur positive Zahlenwerte angenommen werden können.
unsigned long letzteAenderungR = 0; //der letzte Zeitpunkt, an dem eine Änderung am Record-Schalter stattfand
unsigned long letzteAenderungP = 0; //der letzte Zeitpunkt, an dem eine Änderung am Play-Schalter stattfand
unsigned long pause = 50; //Pause, die nach Schalter-Aktion folgen soll
int S0_pos, S1_pos;
int P_S0_pos, P_S1_pos;
int C_S0_pos, C_S1_pos;
int POT_0,POT_1;
int saved_data[600]; //Array zu speichern der Record-Daten
int array_index=0;
char incoming = 0;
int action_pos;
int action_servo;
void setup() {
Serial.begin(9600); //Serial Monitor für Fehlersuche
pinMode(buttonR, INPUT_PULLUP); //Record-Taster mit internen PULLUP-Widerstand
pinMode(buttonP, INPUT_PULLUP); //Play-Taster mit internen PULLUP-Widerstand
pinMode(ledBlau, OUTPUT);
pinMode(ledRot, OUTPUT);
pinMode(ledGelb, OUTPUT);
digitalWrite(ledBlau, ledBlauStatus);
digitalWrite(ledRot, ledRotStatus);
digitalWrite(ledGelb, ledGelbStatus);
//deklarieren der Servo-Pins
Servo_0.attach(3);
Servo_1.attach(5);
//Fahren der Servomotoren in die Grundstellung
Servo_0.write(70);
Servo_1.write(100);
Serial.println("Press 'R' to Record and 'P' to play"); //Instruktion für den Benutzer
}
void Read_POT() //Funktion zum Lesen des Analogwertes vom POT und dessen Zuordnung zum Servowert
{
POT_0 = analogRead(A0);
POT_1 = analogRead(A1);
S0_pos = map(POT_0,0,1024,10,170); //Map it for 1st Servo (Base motor)
S1_pos = map(POT_1,0,1024,10,170); //Map it for 2nd Servo (Hip motor)
}
void Record() //Funktion zur Aufzeichnung der Bewegungen
{
Read_POT(); //Lesen der POT-Werte zum 1. mal
//Speichern in einer Variablen, um sie später zu vergleichen
P_S0_pos = S0_pos;
P_S1_pos = S1_pos;
Read_POT(); //Lesen Sie den POT-Wert zum 2. mal
if (P_S0_pos == S0_pos) //Wenn 1. und 2. Wert gleich sind
{
Servo_0.write(S0_pos); //Ansteuerung des Servos
if (C_S0_pos != S0_pos) //Wenn der POT gedreht wurde
{
saved_data[array_index] = S0_pos + 0; //Speichern der neuen Position im Array.
array_index++; //Erhöhen des Array-Index
}
C_S0_pos = S0_pos; //Speichert den vorherigen Wert, um zu prüfen, ob der POT gedreht wurde
}
//In ähnlicher Weise für alle Servomotoren wiederholen
if (P_S1_pos == S1_pos)
{
Servo_1.write(S1_pos);
if (C_S1_pos != S1_pos)
{
saved_data[array_index] = S1_pos + 1000; //1000 wird für den 1. Servomotor als Unterscheidungsmerkmal addiert
array_index++;
}
C_S1_pos = S1_pos;
}
if (array_index >= 20) { // ab Speicherplatzbelegung 300 LED Blau an
digitalWrite(ledBlau, HIGH);
}
if (array_index >= 300){ // ab Speicherplatzbelegung 300 LED Blau aus und LED Gelb an
digitalWrite(ledBlau, LOW);
digitalWrite(ledGelb, HIGH);
}
if (array_index >= 580){ // ab Speicherplatzbelegung 580 LED Gelb aus und LED Rot an
digitalWrite(ledGelb, LOW);
digitalWrite(ledRot,HIGH);
}
//Den Wert zur Fehlersuche ausgeben
Serial.print(S0_pos); Serial.print(" ");
Serial.print(S1_pos); Serial.print(" ");
Serial.print ("Index = "); Serial.println (array_index);
delay(100);
}
void Play() //Funktion zum Abspielen der aufgezeichneten Bewegungen
{
for (int Play_action=0; Play_action<array_index; Play_action++) //Navigieren durch jedes gespeicherte Element im Array
{
action_servo = saved_data[Play_action] / 1000; //Das erste Zeichen des Array-Elements wird geteilt, um die Servonummer zu kennen
action_pos = saved_data[Play_action] % 1000; //Die letzten drei Zeichen des Array-Elements werden aufgeteilt, um die Servoposition zu ermitteln
switch(action_servo){ //Prüfen welcher Servo-Motor angesteuert werden soll
case 0: //If zeroth motor
Servo_0.write(action_pos);
break;
case 1://If 1st motor
Servo_1.write(action_pos);
break;
}
delay(50);
}
}
void loop() {
if (Serial.available() > 1) //Wenn etwas vom seriellen Monitor empfangen wird
{
incoming = Serial.read();
if (incoming == 'R')
Serial.println("Aufnahme gestartet......");
if (incoming == 'P')
Serial.println("Wiedergabe der aufgezeichneten Sequenz");
}
if (incoming == 'R') //Wenn der Benutzer den Aufnahmemodus gewählt hat
Record();
if (incoming == 'P') //Wenn der Benutzer den Wiedergabemodus ausgewählt hat
Play();
}
[/code]
Nun habe ich in der Loop Schleife die Steuerung über den Seriellen Monitor mit Button ersetzt.
void loop() {
//aktuellen Schalter-Messwert lesen
int gelesenR = digitalRead(buttonR);
//...Wenn der Record-Schalter-Status sich geändert hat (durch drücken oder auch prellen)
if (gelesenR != letzterButtonRStatus) {
// setze den Timer zurück
letzteAenderungR = millis();
}
if ((millis() - letzteAenderungR) > pause) {
//Der aktuell-gelesene Wert kann nun als zuverlässig angesehen werden, da dieser länger als 50ms vorliegt.
if (gelesenR != buttonRStatus) { //falls sich der Status verändert hat...
buttonRStatus = gelesenR; //...setze diesen als buttonRStatus
//...und starte Record, falls der Knopf gedrückt wurde
if (buttonRStatus == HIGH) {
Record();
}
}
}
letzterButtonRStatus = gelesenR;
//aktuellen Schalter-Messwert lesen
int gelesenP = digitalRead(buttonP);
//...Wenn der Record-Schalter-Status sich geändert hat (durch drücken oder auch prellen)
if (gelesenP != letzterButtonPStatus) {
// setze den Timer zurück
letzteAenderungP = millis();
}
if ((millis() - letzteAenderungP) > pause) {
//Der aktuell-gelesene Wert kann nun als zuverlässig angesehen werden, da dieser länger als 50ms vorliegt.
if (gelesenP != buttonPStatus) { //falls sich der Status verändert hat...
buttonPStatus = gelesenP; //...setze diesen als buttonRStatus
//...und starte Play , falls der Knopf gedrückt wurde
if (buttonPStatus == HIGH) {
Play();
}
}
}
letzterButtonPStatus = gelesenP;
}
Leider habe ich hier keinen Erfolg. Kann jemand meinen Anfängerfehler finden und mir helfen?