PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Motor Shield Steuerung - Up/Down geht nicht...



MrMiffy08
01.01.2014, 22:44
Hallo Community,
ich brauche mal wieder Hilfe. Ich habe mir eine DC Motorsteuerung zurechgefummelt, aus einem Uno R3, einem RN Mini-Motorshield (http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=65&products_id=90) und einem Keypad-Aufsatz (http://www.sainsmart.com/sainsmart-1602-lcd-keypad-shield-for-arduino-duemilanove-uno-mega2560-mega1280.html) von Sainsmart. Der Sketch funktioniert soweit, bis auf die up/down - Zählerei. Mit den Tasten auf dem Keypad funktioniert die rechts-Linkssteuerung des Motors, nur die Routine mit
case UP_KEY:
SollSpeed = (SollSpeed+10);
break;
case DOWN_KEY:
SollSpeed = (SollSpeed-10);
break;
will einfach nicht, da passiert nichts. Wahrscheinlich hab ich mal wieder einen Hänger, aber ich seh einfach nicht wo. Die Keypad Abfrage ist eine Mod., die Library dazu stammt von Phaiax (https://github.com/Phaiax/sainsmartkeypad).

Habt Ihr Tipps für mich wo ich anfangen kann was zu ändern, damit das so funktioniert wie es soll?

Vielen Dank!

Der vollständige Code:



// modified from: http://itp.nyu.edu/physcomp/Labs/DCMotorControl
// erster Versuch, einen motor an der RN-mini-Motor-Bridge erst mal zum Drehen zu bringen
// funktioniert sogar, wenn auch nur mit poti...
// hier fehlt noch der Drehencoder - kommt später

// Achtung, das LiquidCrystal braucht die Pins (8, 9, 4, 5, 6, 7), auch 10, 12, 13
// der Encoder 2, 3 für A & B und die 1 für den Switch, ist alles n.n implementiert....
// bleiben noch Pin A1=15 fürs Poti, 3 für die PWM, A3=17, A4=18 für Motor In A und B und A5=19 für Enable sowie 0 (frei)

/* Phaiax Sainsmart LCD keypad shield - code returns the following variables:

UP_KEY
DOWN_KEY
RIGHT_KEY
LEFT_KEY
SELECT_KEY
*/


#include <avr/interrupt.h>
#include <avr/io.h>
#include "Arduino.h"
#include "LiquidCrystal.h"
#include "sainsmartkeypad.h" //from phaiax' example

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
SainsmartKeypad keypad(0);
uint8_t key;


const int switchPin = 1; // switch input, switch to gnd
const int motor1_IN_A = 17; // H-bridge leg 1A = A3
const int motor1_IN_B = 18; // H-bridge leg 1B = A4
const int enablePin = 19; // H-bridge enable pin Enable A+B = A5
const int PWM_Pin = 3; // PWM Output = must be on Pin 3, 10 oder 11!
const int SollSpeedPin = A2; // Poti-Pin: Sollwert für Geschwindigkeit

int SollSpeed = 0; // Eingelesene Sollgeschwindigkeit, Startwert

void motor_stop() {

// put motor back to a safe 'LOW'
digitalWrite(motor1_IN_A, LOW);
digitalWrite(motor1_IN_B, LOW);
}

void setup() {
TCCR2B = (TCCR2B & 0xF8) | 6; // PWM Port setzen

pinMode(PWM_Pin, OUTPUT);
pinMode(switchPin, INPUT);
// set all the other pins you're using as outputs:
pinMode(motor1_IN_A, OUTPUT);
pinMode(motor1_IN_B, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(SollSpeedPin, INPUT);


digitalWrite(enablePin, LOW); //Pull-down für den enable-pin
digitalWrite(switchPin, HIGH); //Pull-up, der Switch zieht ihn auf low

lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("Poti - PWM -");
lcd.setCursor(0,1);
lcd.print("Motor-Test:");
delay(3000);
}
// in der loop soll der Motor mit eingestellter pwm laufen, dir kommt später
void loop() {

// Sollwert einlesen:
SollSpeed = analogRead(SollSpeedPin) / 5; // Ausgabe der PWM
analogWrite(PWM_Pin, SollSpeed);

// LCD-Ausgabe von Text und Soll-Speed:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Poti - PWM");
lcd.setCursor(0,1);
lcd.print("Speed:");
lcd.setCursor(8,1);
lcd.print(SollSpeed);
delay(100);
// Hier kommt die mod. Lib. von Phaiax zum Zug - die das Keypad besser ausliest.
key = keypad.getKey_fastscroll();

if(key != SAMPLE_WAIT) // Do not refresh screen every loop
{
switch(key)
{
case SELECT_KEY:
motor_stop();
break;
case UP_KEY:
SollSpeed = (SollSpeed+10);
break;
case DOWN_KEY:
SollSpeed = (SollSpeed-10);
break;
case RIGHT_KEY:
digitalWrite(enablePin, HIGH); // if the switch is pressed/low, motor will turn in one direction:
analogWrite(PWM_Pin, SollSpeed);
digitalWrite(motor1_IN_A, LOW); // set leg 1 of the H-bridge low
digitalWrite(motor1_IN_B, HIGH); // set leg 2 of the H-bridge high
break;
case LEFT_KEY:
analogWrite(PWM_Pin, SollSpeed);
digitalWrite(enablePin, HIGH);
digitalWrite(motor1_IN_A, HIGH); // set leg 1 of the H-bridge high
digitalWrite(motor1_IN_B, LOW); // set leg 2 of the H-bridge low
break;
}

lcd.setCursor(5,1);
lcd.print("Speed: ");
lcd.print(SollSpeed);
lcd.print(" ");
}
}

[/QUOTE]


und die keypad-Lib im Anhang.....

- - - Aktualisiert - - -

So, ich hab nochmal umgestellt, so dass der Sollwert auch eingelesen wird. Aber: Da zuckt der Motor nur mal kurz mit dem höheren/niedrigeren Wert, und in der nächsten loop ist natürlich wieder der Wert vom Poti drin. Wie macht man das, dass der neue Wert übernommen wird?

Der aktuelle Code:
[QUOTE]// modified from: http://itp.nyu.edu/physcomp/Labs/DCMotorControl
// erster Versuch, einen motor an der RN-mini-Motor-Bridge erst mal zum Drehen zu bringen
// funktioniert sogar, wenn auch nur mit poti...
// hier fehlt noch der Drehencoder - kommt später

// Achtung, das LiquidCrystal braucht die Pins (8, 9, 4, 5, 6, 7), auch 10, 12, 13
// der Encoder 2, 3 für A & B und die 1 für den Switch, ist alles n.n implementiert....
// bleiben noch Pin A1=15 fürs Poti, 3 für die PWM, A3=17, A4=18 für Motor In A und B und A5=19 für Enable sowie 0 (frei)

/* Sainsmart LCD keypad shield - code returns the following variables:

UP_KEY
DOWN_KEY
RIGHT_KEY
LEFT_KEY
SELECT_KEY
*/


#include <avr/interrupt.h>
#include <avr/io.h>
#include "Arduino.h"
#include "LiquidCrystal.h"
#include "sainsmartkeypad.h" //from phaiax' example

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
SainsmartKeypad keypad(0);
uint8_t key;


const int switchPin = 1; // switch input, switch to gnd
const int motor1_IN_A = 17; // H-bridge leg 1A = A3
const int motor1_IN_B = 18; // H-bridge leg 1B = A4
const int enablePin = 19; // H-bridge enable pin Enable A+B = A5
const int PWM_Pin = 3; // PWM Output = must be on Pin 3, 10 oder 11!
const int SollSpeedPin = A2; // Poti-Pin: Sollwert für Geschwindigkeit

int SollSpeed = 0; // Eingelesene Sollgeschwindigkeit, Startwert


void motor_stop() {
// And put is all back to a safe 'LOW'
digitalWrite(motor1_IN_A, LOW);
digitalWrite(motor1_IN_B, LOW);
}

void motor_up() {
// And put the pwm up with 10
SollSpeed = SollSpeed+10;

}
// And put the pwm down with 10
void motor_down() {
SollSpeed = SollSpeed-10;

}

void setup() {
TCCR2B = (TCCR2B & 0xF8) | 6; // PWM Port setzen, Teiler02 : 8 : 3980 kHz

pinMode(PWM_Pin, OUTPUT);
pinMode(switchPin, INPUT);
// set all the other pins you're using as outputs:
pinMode(motor1_IN_A, OUTPUT);
pinMode(motor1_IN_B, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(SollSpeedPin, INPUT);


digitalWrite(enablePin, LOW); //Pull-down für den enable-pin
digitalWrite(switchPin, HIGH); //Pull-up, der Switch zieht ihn auf low

lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("Poti - PWM -");
lcd.setCursor(0,1);
lcd.print("Motor-Test:");
delay(3000);
}
// in der loop soll der Motor mit eingestellter pwm laufen, dir kommt später
void loop() {

// Sollwert einlesen:
SollSpeed = analogRead(SollSpeedPin) / 5; // Ausgabe der PWM


// Hier kommt die mod. Lib. von Phaiax zum Zug - die das Keypad besser ausliest als das Original
key = keypad.getKey_fastscroll();

if(key != SAMPLE_WAIT) // Do not refresh screen every loop
{
switch(key)
{
case SELECT_KEY:
motor_stop();
break;
case UP_KEY:
motor_up();
break;
case DOWN_KEY:
motor_down();
break;
case RIGHT_KEY:
digitalWrite(enablePin, HIGH); // if the switch is pressed/low, motor will turn in one direction:
analogWrite(PWM_Pin, SollSpeed);
digitalWrite(motor1_IN_A, LOW); // set leg 1 of the H-bridge low
digitalWrite(motor1_IN_B, HIGH); // set leg 2 of the H-bridge high
break;
case LEFT_KEY:
analogWrite(PWM_Pin, SollSpeed);
digitalWrite(enablePin, HIGH);
digitalWrite(motor1_IN_A, HIGH); // set leg 1 of the H-bridge high
digitalWrite(motor1_IN_B, LOW); // set leg 2 of the H-bridge low
break;
}
}

// hier wird der Sollwert an die PWM übergeben
analogWrite(PWM_Pin, SollSpeed);

// LCD-Ausgabe von Text und Soll-Speed:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Poti - PWM");
lcd.setCursor(0,1);
lcd.print("Speed:");
lcd.setCursor(8,1);
lcd.print(SollSpeed);
delay(100);



lcd.setCursor(5,1);
lcd.print("Speed: ");
lcd.print(SollSpeed);
lcd.print(" ");

}

Hubert.G
02.01.2014, 11:15
Du wirst entweder den Tasten oder dem Poti Vorrang geben müssen, beides gleichzeitig wird nicht gehen.
Du könntest mit den Poti-Wert starten und dann die Tasten abfragen.
Ich nehme mal an das die Frage so gemeint war.

MrMiffy08
02.01.2014, 22:41
Hallo Hubert,
ja genau, das ist das Problem. Ich würde gerne mit dem Startwert vom Poti starten und dann mit den Tastern um 10+ aufaddieren, aber im Moment geht das nur für einen loop, im nächsten ist wieder der Poti-Wert dran. Oder man hält den Taster 10+ gedrückt, dann rennt der Motor auch schneller. Wie bekommt man das hin, dass der letzte Wert gespeichert wird?

Hubert.G
03.01.2014, 08:58
Du fragst in deiner Loop den Analogwert auch immer wieder ab. Das darfst du natürlich nur am Anfang, vor dem Loop

MrMiffy08
06.01.2014, 22:45
Hallo Hubert, das leuchtet mir ein. Nur, wenn ich die Zeile
int SollSpeed = analogRead(SollSpeedPin) / 4; // Ausgabe der PWM
vor die loop stelle, meckert der compiler, dass das ein redefine ist, klar, oben steht ja,
int SollSpeed = 0
Wenn ich das wegkommentiere, meckert er,
'SollSpeed' was not declared in this scope', denn darüber stehen ja die voids mit den Motor- 10er Sprüngen bei up/down Tastern.

Ich bin zu doof, das zu lösen, wie muss ich das umstellen, damit das läuft?

Hier noch mal der gesamte code, mit der besagten Zeile vor der loop:


// modified from: http://itp.nyu.edu/physcomp/Labs/DCMotorControl
// erster Versuch, einen motor an der RN-mini-Motor-Bridge erst mal zum Drehen zu bringen
// funktioniert sogar, wenn auch nur mit poti...

// Achtung, das LiquidCrystal braucht die Pins (8, 9, 4, 5, 6, 7), auch 10, 12, 13
// der Encoder 2, 3 für A & B und die 1 für den Switch, ist alles n.n implementiert....
// bleiben noch Pin A1=15 fürs Poti, 3 für die PWM, A3=17, A4=18 für Motor In A und B und A5=19 für Enable sowie 0 (frei)

/* Sainsmart LCD keypad shield - code returns the following variables:

UP_KEY
DOWN_KEY
RIGHT_KEY
LEFT_KEY
SELECT_KEY
*/

#include <avr/interrupt.h>
#include <avr/io.h>
#include "Arduino.h"
#include "LiquidCrystal.h"
#include "sainsmartkeypad.h" //from phaiax' example

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
SainsmartKeypad keypad(0);
uint8_t key;


const int switchPin = 1; // switch input, switch to gnd
const int motor1_IN_A = 17; // H-bridge leg 1A = A3
const int motor1_IN_B = 18; // H-bridge leg 1B = A4
const int enablePin = 19; // H-bridge enable pin Enable A+B = A5
const int PWM_Pin = 3; // PWM Output = must be on Pin 3, 10 oder 11!
const int SollSpeedPin = A2; // Poti-Pin: Sollwert für Geschwindigkeit

// int SollSpeed = 0; // Eingelesene Sollgeschwindigkeit, Startwert


void motor_stop() {
// put it all back to a safe 'LOW'
digitalWrite(motor1_IN_A, LOW);
digitalWrite(motor1_IN_B, LOW);
}

void speed_up() {
// put the pwm up with 10
SollSpeed = SollSpeed+10;

}
// put the pwm down with 10
void speed_down() {
SollSpeed = SollSpeed-10;

}

void setup() {
TCCR2B = (TCCR2B & 0xF8) | 5; // PWM Port setzen, Teiler05

pinMode(PWM_Pin, OUTPUT);
pinMode(switchPin, INPUT);
// set all the other pins you're using as outputs:
pinMode(motor1_IN_A, OUTPUT);
pinMode(motor1_IN_B, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(SollSpeedPin, INPUT);

digitalWrite(enablePin, LOW); //Pull-down für den enable-pin
digitalWrite(switchPin, HIGH); //Pull-up, der Switch zieht ihn auf low

lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("Poti - PWM -");
lcd.setCursor(0,1);
lcd.print("Motor-Test:");
delay(3000);

// Sollwert einlesen:
int SollSpeed = analogRead(SollSpeedPin) / 4;

}

// in der loop soll der Motor mit eingestellter pwm vom poti laufen,

void loop() {



// Hier kommt die mod. Lib. von Phaiax zum Zug - die das Keypad besser ausliest als das Original
key = keypad.getKey_fastscroll();

if(key != SAMPLE_WAIT) // Do not refresh screen every loop
{
switch(key)
{
case SELECT_KEY:
motor_stop();
break;
case UP_KEY:
speed_up();
break;
case DOWN_KEY:
speed_down();
break;
case RIGHT_KEY:
digitalWrite(enablePin, HIGH); // if the switch is pressed/low, motor will turn in one direction:
analogWrite(PWM_Pin, SollSpeed);
digitalWrite(motor1_IN_A, LOW); // set leg 1 of the H-bridge low
digitalWrite(motor1_IN_B, HIGH); // set leg 2 of the H-bridge high
break;
case LEFT_KEY:
analogWrite(PWM_Pin, SollSpeed);
digitalWrite(enablePin, HIGH);
digitalWrite(motor1_IN_A, HIGH); // set leg 1 of the H-bridge high
digitalWrite(motor1_IN_B, LOW); // set leg 2 of the H-bridge low
break;
}
}
// hier wird der Sollwert an die PWM übergeben
analogWrite(PWM_Pin, SollSpeed);


// LCD-Ausgabe von Text und Soll-Speed:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Poti - PWM");

lcd.setCursor(0,1);
lcd.print("Speed:");

lcd.setCursor(8,1);
lcd.print(SollSpeed);
delay(100);

lcd.setCursor(5,1);
lcd.print("Speed: ");
lcd.print(SollSpeed);
lcd.print(" ");

}



Weiterhin danke für Hinweise!

Hubert.G
07.01.2014, 09:45
Schon mal probiert anstelle von
int SollSpeed = 0; // Eingelesene Sollgeschwindigkeit, Startwert
diese Zeile einzufügen
int SollSpeed = analogRead(SollSpeedPin) / 4;

Klebwax
07.01.2014, 10:21
Schon mal probiert anstelle von
int SollSpeed = 0; // Eingelesene Sollgeschwindigkeit, Startwert
diese Zeile einzufügen
int SollSpeed = analogRead(SollSpeedPin) / 4;

Oder sich angewöhnen, Definition und Zuweisung von Variablen zu trennen.

int SollSpeed; // an den Anfang des Codes
.
.
.
SollSpeed = 0; // oder
SollSpeed = analogRead(SollSpeedPin) / 4;

Man mach das zwar heute gerne anders, das führt aber zu Threads wie diesem.

MfG Klebwax

MrMiffy08
07.01.2014, 14:13
Hallo Hubert und Klebwax,

ja, hatte ich beides schon mal gestern probiert, bei dieser Anordnung


const int switchPin = 1; // switch input, switch to gnd
const int motor1_IN_A = 17; // H-bridge leg 1A = A3
const int motor1_IN_B = 18; // H-bridge leg 1B = A4
const int enablePin = 19; // H-bridge enable pin Enable A+B = A5
const int PWM_Pin = 3; // PWM Output = must be on Pin 3, 10 oder 11!
const int SollSpeedPin = A2; // Poti-Pin: Sollwert für Geschwindigkeit
int SollSpeed;
// int SollSpeed = 0; // Eingelesene Sollgeschwindigkeit, Startwert
// Sollwert einlesen:
SollSpeed = analogRead(SollSpeedPin) / 4; // Ausgabe der PWM

kommt der Error: expected constructor, destructor, or type conversion before '=' token

Muss die Zeile mit analogRead woanders hin?

Weiterhin Dank für Eure Tipps!

MrMiffy

Klebwax
07.01.2014, 19:13
kommt der Error: expected constructor, destructor, or type conversion before '=' token

Sorry "constructor, destructor" kenne ich von C nicht, kann auch nichts dazu sagen.

MfG Klebwax

MrMiffy08
24.04.2014, 00:31
Ok, also nach diversem Suchen hab ich das Problem gelöst:
Man muss die Zeile


SollSpeed = 0; // oder

in eine Void schreiben, nicht davor... ](*,)
Manche Dinge sind einfach, aber nicht einfach zu finden...

So, jetzt muss ich nur noch die Hardware anschrauben und kann mal das halbautomatische Vorschieben ausprobieren....

Rabenauge
24.04.2014, 15:25
Muss man nicht. Man kanns auch direkt beim deklarieren mit einem Wert füllen, mach ich dauernd:

int SollSpeed=0; // funktioniert auch oberhalb der setup() schon
Nur sollte man dann später nicht irgendwo SollSpeed noch mal als Int definieren:

void loop()

{
int Sollspeed= 12; //funktioniert nicht, da es diese Variable schon gibt(und zwar, da ausserhalb deklariert, als globale), da schreibt man dann nur
SollSpeed=12; // das geht.
}