Hallo,
Treiber = Bibliothek
Vielleicht gibt es eine, welche den Regelkreis schon mitliefert.
Wir wissen ja nicht, welche Software er verwendet und was dieser Treiber so kann?
MfG Peter(TOO)
Druckbare Version
Von der Aussage her bin ich von Treiber = Hardware ausgegangen.
Wenn man nach einer anderen Bibliothek sucht, kann man den Treiber auch beibehalten wenn die Lib "Step" und "Dir" und ggf. noch "i-sense" und "brake" unterstützt.
Das wäre nämlich ein StromChopper per Software.
Wenn man einen Motortreiber nimmt der Stromchopper in Hardware kann und "Step" und "Dir", dann braucht man an der Software außer eventuell der Pinzuweisung nichts ändern.
Allerdings muß man sich da dann schon mit den Treibern die es am Markt für Nema 17 Stepper gibt schon etwas auskennen.
Aus dem bisherigen Threadverlauf schließe ich, das es hier noch etwas fehlt.
Da ich keine fertigen Shields nehme (Ausnahme ein Breakout Board und das RAMPS1.4) würde ich empfehlen in Richtung
A4988
DRV8825
DRV8835
und
TMC2100
zu schauen.
Der letzte hat soweit ich weis chopper mode.
Aber da muß man halt neue Hardware für etwas kaufen das man auch mit Software ohne Zusatzkosten korrigieren kann.
Bei einer Neuplanung macht es natürlich Sinn sich von vorneherein schon die passende Hardware zuzulegen.
Hallo,
danke für die Antworten (auch wenn mir manches davon zu hoch ist;))
Werd mir den
Stepper Motor 28BYJ-48 + Treiberplatine ULN2003
besorgen. Lichtschranken arbeiten, zumindest kann ich schon mal LEDs damit schalten.
Das ist der Code für zwei Lichtschranken die zwei LEDs schalten.
int sensorPin1 = A2;
int sensorPin2 = A3;
int sensorValue1 = 0;
int sensorValue2 = 0;
int ledPin1 = 12;
int ledPin2 = 13;
void setup()
{
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
Serial.begin(9600);
}
void loop()
{
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
Serial.println(sensorValue1);
if (sensorValue1 < 512) {
digitalWrite(ledPin1, HIGH);
}
else
{
digitalWrite(ledPin1, LOW);
}
if (sensorValue2 > 512) {
digitalWrite(ledPin2, HIGH);
}
else
{
digitalWrite(ledPin2, LOW);
}
delay(100);
}
Jetzt sollen aber nicht zwei LEDs geschaltet sondern ein Schrittmotor mit
zwei verschiedenen Drehzahlen und am Ende gestoppt werden.
Soll heissen
SensorValue1 >512 und SensorValue2 < 512 - Motordrehzahl X
SensorValue1 <512 und SensorValue2 < 512 - Motordrehzahl Y
SensorValue1 <512 und SensorValue2 > 512 - Motor STOP
Könnt ihr mir nen Tip geben wie ich das programmieren kann?
Vielen Dank
Andy
Hallo nochmal,
die Waage arbeitet soweit, allerdings fehlt noch die Bedienfreundlichkeit.
Vielleicht könnt ihr mir da weiterhelfen.
Der Code sieht bisher so aus:PHP-Code:
int sensorPin1 = A2;
int sensorPin2 = A3;
int sensorValue1 = 0;
int sensorValue2 = 0;
int motorPin1 = 8; // Blue - 28BYJ48 pin 1
int motorPin2 = 9; // Pink - 28BYJ48 pin 2
int motorPin3 = 10; // Yellow - 28BYJ48 pin 3
int motorPin4 = 11; // Orange - 28BYJ48 pin 4
// Red - 28BYJ48 pin 5 (VCC)
int motorSpeed = 0;
void setup() {
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
Serial.begin(9600);
}
void loop(){
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
Serial.println(sensorValue1);
if (sensorValue1 > 512 && sensorValue2 < 512)
{
motorSpeed = 1;
counterclockwise();
}
if (sensorValue1 < 512 && sensorValue2 < 512)
{
motorSpeed = 2;
counterclockwise();
}
if (sensorValue1 < 512 && sensorValue2 > 512)
{
motorSpeed = 0;
counterclockwise();
}
}
void counterclockwise (){
// 1
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 2
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay (motorSpeed);
// 3
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 4
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 5
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 6
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
delay (motorSpeed);
// 7
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(motorSpeed);
// 8
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(motorSpeed);
}
Der Motor dreht zuerst schnell, dann langsamer und schaltet bei Erreichen der Endstellung ab, aber natürlich beim runternehmen der Waagschale auch gleich wieder ein.
Ich hätte gerne dass der ganze Vorgang hier unterbrochen wird und erst nach drücken eines Tasters wieder startet. Ebenso soll nach dem Einschalten erst auf Tastendruck gestartet werden.
Wie krieg ich das denn rein?
Danke
Andy
Habe mir den Programmcode jetzt nicht angesehen, aber lösche wenn die Bedingung zum Abschalten des Motors erreicht ist einen Merker.
Den fragst Du bei jedem Programmzweig für Motor an ab.
Nur wenn er gesetzt ist, darf der Teil ausgeführt werden.
Im Definitionsteil wird er als nicht gesetzt vorbelegt.
Bei der Tasterabfrage wird er gesetzt.
Damit fährt beim Programmstart nichts los, weil der Merker als "0" vorgegeben ist.
Beim Tastendruck wird er auf "1" gesetzt und beim Erreichen der Abschaltbedingung des Motors wieder auf "0" gesetzt.
Ist halt eine "Hilfsvariable" die sich den Systemzustand merkt.
Ok, Taster is dran, vieleicht magst du mir noch sagen wo und wie ich die Merker einbauen sollte. Die Beispiele dazu im Netz hab ich durch, helfen mir aber nicht weiter.
[/PHP]PHP-Code:
[PHP]#include <Bounce2.h>
int buttonPin = 13;
int sensorPin1 = A2;
int sensorPin2 = A3;
int sensorValue1 = 0;
int sensorValue2 = 0;
int motorPin1 = 8; // Blue - 28BYJ48 pin 1
int motorPin2 = 9; // Pink - 28BYJ48 pin 2
int motorPin3 = 10; // Yellow - 28BYJ48 pin 3
int motorPin4 = 11; // Orange - 28BYJ48 pin 4
// Red - 28BYJ48 pin 5 (VCC)
int motorSpeed = 0;
int buttonState = 0;
void setup() {
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop(){
buttonState = digitalRead(buttonPin);
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
Serial.println(buttonState);
if (sensorValue1 > 512 && sensorValue2 < 512)
{
motorSpeed = 1;
counterclockwise();
}
if (sensorValue1 < 512 && sensorValue2 < 512)
{
motorSpeed = 2;
counterclockwise();
}
if (sensorValue1 < 512 && sensorValue2 > 512)
{
motorSpeed = 0;
counterclockwise();
}
}
void counterclockwise (){
// 1
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 2
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay (motorSpeed);
// 3
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 4
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 5
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
delay(motorSpeed);
// 6
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
delay (motorSpeed);
// 7
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(motorSpeed);
// 8
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
delay(motorSpeed);
}
Danke
Davon ausgehend, das motorSpeed = 0, Motorgeschwindigkeit = null bedeutet, sähe das dann so aus.
Allerdings muß dann der Taster mindestens solange gedrückt sein wie das Programm für einen Duchlauf braucht um immer sicher erkannt zu werden.Code:#include <Bounce2.h>
int buttonPin = 13;
int sensorPin1 = A2;
int sensorPin2 = A3;
int sensorValue1 = 0;
int sensorValue2 = 0;
int motorPin1 = 8; // Blue - 28BYJ48 pin 1
int motorPin2 = 9; // Pink - 28BYJ48 pin 2
int motorPin3 = 10; // Yellow - 28BYJ48 pin 3
int motorPin4 = 11; // Orange - 28BYJ48 pin 4
// Red - 28BYJ48 pin 5 (VCC)
int motorSpeed = 0;
int buttonState = 0;
int merker = 0; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
void setup() {
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop(){
buttonState = digitalRead(buttonPin);
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
Serial.println(buttonState);
if (buttonState != 0) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
{
merker = 1;
}
if (sensorValue1 > 512 && sensorValue2 < 512 && merker == 1) <<<<<<<<<<<<<<<<<<<<<<<<<<<<
{
motorSpeed = 1;
counterclockwise();
}
if (sensorValue1 < 512 && sensorValue2 < 512 && merker == 1) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
{
motorSpeed = 2;
counterclockwise();
}
if (sensorValue1 < 512 && sensorValue2 > 512)
{
motorSpeed = 0;
merker = 0; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
counterclockwise();
}
}
Üblicherweise fragt man Taster mit einem Interrupt ab und setzt in der ISR schon einen Merker dafür das der Taster gedrückt wurde. Wenn beim nächsten Schleifendurchlauf das Programm an die Stelle kommt wo der Taster ausgewertet werden soll wertet man anstelle des Tasters den Merker aus und setzt den selben dann auch zurück.
Das verhindert das man Timingprobleme bekommt wenn die Zykluszeiten mal länger werden wie beim Einsatz von Delay.
Delay befehle kann man auch komplett ersetzen, in dem mann mit micros() den Timer abfragt und in eine Variable schreibt, dann zieht man bei jedem Schleifendurchlauf den gespeicherten Wert vom aktuellen Wert ab und vergleicht das mit einer Variable oder Konstante die den Verzögerungswert enthällt. Bei Überschreiten ist die Zeit um und die Funktion kann beendet werden.
Ist nicht so genau wie Interrupts, aber spart dieselben für wichtigeres.
Der Vorteil von Interrupts und solschen Lösungen ist der, daß das Programm nicht anhält sonder nin der Zeit was anderes machen kann.
Hat man viele Taster, kann man Tasten nehmen die 2xUm oder 2xSchließer sind von allen Tasten wird jeweils ein Schaltkontakt parallel genommen (verodert) und auf einen Interrupt gelegt. Der jeweils andere Kontakt ist dann der Kontakt der in der ISR ausgewertet wird um festzustellen welche Taster betätigt wurde.
Super, danke.
Kleines Problem..;)
Arduino: 1.6.8 (Windows 7), Board: "Arduino/Genuino Uno"
C:\Users\ramirez\Documents\Arduino\StepperLicht4\S tepperLicht4.ino: In function 'void loop()':
StepperLicht4:32: error: expected primary-expression before '>' token
if (buttonState <> 0)
^
StepperLicht4:38: error: lvalue required as left operand of assignment
if (sensorValue1 > 512 && sensorValue2 < 512 && merker = 1)
^
StepperLicht4:45: error: lvalue required as left operand of assignment
if (sensorValue1 < 512 && sensorValue2 < 512 && merker = 1)
^
Bibliothek Bounce2-master in Version 2.21 im Ordner: C:\Users\ramirez\Documents\Arduino\libraries\Bounc e2-master wird verwendet
exit status 1
expected primary-expression before '>' token
Gruß
Andy
Falsche Sprache.
"<>" = ungleich = "!="
"=" = gleich = "==" ,natürlich nur bei den IF Bedingungen
https://www.arduino.cc/en/Reference/HomePage
Habs oben geändert.
Alles klar, funktioniert.
Test mit Hardware kann ich morgen erst machen.
Vielen Dank
Gruß
Andy