PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Pulverwaage elektronisch geregelt



Shag
24.06.2016, 16:46
Hallo, mein Name ist Andy,
hab mich grad registriert nachdem ich schon ne ganze Weile mitgelesen hab.

Ich hoffe ihr könnt mir helfen bei meinem neuesten Projekt.

Ich habe eine mechanische Waage über die ich Pulver abwiegen kann. Das Pulver kommt über ein sich drehendes Rohr in die Waagschale und hebt bei einem bestimmten Gewicht den Waagbalken an bis er irgendwann Strich auf Strich steht. Fertig.

Das Rohr möchte ich nun gerne über einen Schrittmotor drehen, und zwar auf zwei verschiedenen Drehzahlstufen.
Zuerst höhere Drehzahl, und sobald sich der Balken hebt auf sehr niedriger Drehzahl bis die Markierungen übereinstimmen.
Die Stellung des Balkens wird durch zwei Lichtschranken abgefragt.

Zu meiner Hardware:
Arduino Uno Board mit Motor Shield R3
Schrittmotor Emis E547-52500 0.25 Nm 0.6 A
Lichtschranken TCST 2103

Motor läuft, mit einigen Sketches ausprobiert.

Zu meiner ersten Frage:

Bei ständiger Drehung werden Motor und Shield leicht warm, aber je niedriger die Drehzahl wird umso heisser wird beides.
Zum Schluß des Wägevorganges muss sich der Motor ca 10 Sekunden nur noch Schrittweise bewegen und dabei wird er so heiss dass ich ihn nicht mehr anfassen kann. Gleiches gilt für den Prozessor auf dem Shield.

Wie kann ich die Temperaturen so niedrig wie möglich halten?
Der Motor braucht so gut wie keine Kraft aufzuwenden, schon gar keine Haltekraft.
Gibts ne Möglichkeit den Strom zu begrenzen oder ähnliches?


Vielen Dank schon mal
Andy

Peter(TOO)
24.06.2016, 21:44
Hallo Andy,

Wie kann ich die Temperaturen so niedrig wie möglich halten?
Der Motor braucht so gut wie keine Kraft aufzuwenden, schon gar keine Haltekraft.
Gibts ne Möglichkeit den Strom zu begrenzen oder ähnliches?

Ist alles Klar, der Motostrom ist viel zu hoch.

Das Problem bei Schrittmotoren ist, dass mit zunehmender Drehzahl und konstanter Spannung die Stromaufnahme ab nimmt. Im Stand ist dann nur noch der Ohmsche Widerstand der Wicklung massgebend.

Das Shield hat einen PWM-Eingang und einen CurrentSensing Analogausgang um den Motorstrom zu messen.

Entweder hast du da die Jumper falsch gesetzt und/oder due verwendest eine falsche Software.
Über den PWM-Eingang kann man den Motorstrom festlegen.

In deinem Fall, kann es genügen mit nur zwei PWM-Einstellungen zu arbeiten. Also mehr Strom bei der hohen Drehzahl und ein kleiner, wenn du nur noch Einzelschritte fährst oder der Motor steht.

Kannst du natürlich selber programmieren oder eine passenden Treiber/Bibliothek verwenden.

MfG Peter(TOO)

RoboHolIC
24.06.2016, 22:47
Das passt leider alles gut zusammen:

Dein Motor hat einen Wicklungswiderstand von etwas über 3 Ohm.
Der Motortreiber ist ein L298; der will (aus dem Kopf) wenigsten 7,5..8V Motorspannung haben. (vermutlich arbeitest du mit 12V !? )
Mit dieser Motorspannung fließen je Windung weit mehr als zwei Ampere. Das ist in jedem Falle jenseits der Leistungsfähigkeit eines L298, erst recht für die verwendete SMD-Variante.
(real ist der Strom wegen der Spannungsverluste im L298 deutlich geringer, was aber seinerseits das thermische Problem verschärft)
Die Schaltung des Shields macht auch keine Strombegrenzung, sie bereitet lediglich die Spannungen der Messshunts auf.

Bei höheren Schrittfrequenzen, also beim anfänglichen schnellen Lauf, begrenzt die Motorinduktivität den maximalen Spulenstrom.
Je langsamer der Motor dreht, desto länger werden die Einschaltzeiten der Wicklungen und desto höhere Werte erklimmt die Induktivitäts-"gebremste" Stromrampe.
Im Beinahe-Stillstand tritt dann der worst case ein: Der Spulenstrom wird zu hoch, weil er nur noch durch den ohmschen Wicklungswiderstand begrenzt wird.

Edit: Da hatte ich Mist geschrieben - das muss der Nachwelt nicht erhalten bleiben. Ja, mit PWM ist das Shield durchaus zu gebrauchen, aber zeitgemäß ist es trotzdem nicht mehr.

Shag
27.06.2016, 12:38
Danke erstmal. Seh schon, Profis am Werk..

Könnt ihr mir das mit dem Jumpern noch näher erklären bzw. wo setz ich die?
Wieviel Spannung ist denn optimal?
Ich hab mit 12 Volt getestet.
Wo find ich die entsprechenden Treiber/Bibliothek?

Sorry für die dummen Anfängerfragen.. ;-)

Gruß
Andy

i_make_it
27.06.2016, 16:16
Die Jumper sind auf der Rückseite vom Shield

To avoid possible damage to the Arduino board on which the shield is mounted, we reccomend using an external power supply that provides a voltage between 7 and 12V. If your motor require more than 9V we recommend that you separate the power lines of the shield and the Arduino board on which the shield is mounted. This is possible by cutting the "Vin Connect" jumper placed on the back side of the shield. The absolute limit for the Vin at the screw terminals is 18V.
Function pins per Ch. A pins per Ch. B
Direction D12 D13
PWM D3 D11
Brake D9 D8
Current Sensing A0 A1

If you don't need the Brake and the Current Sensing and you also need more pins for your application you can disable this features by cutting the respective jumpers on the back side of the shield.
https://www.arduino.cc/en/Main/ArduinoMotorShieldR3

Shag
27.06.2016, 18:11
Ah, cutting Vin Connect.

Hab immer nach Pins zum Jumper setzen gesucht.
Gut, wird heute Abend probiert.

Danke

Shag
29.06.2016, 13:00
Also Jumper trennen bringt nichts.

Zitat Peter(TOO)
"über den PWM Eingang kann man den Strom begrenzen" - wie geht das?

Noch was:
Wenn ich am UNO die Lichtschranke anschliesse bekomme ich die richtigen Signale, also von 180 - 1023 im Serial Monitor.
Wenn ich das selbe mit aufgestecktem Motor Shield mache bekomme ich 34 - 36.
Was stimmt da jetzt nicht?

Der Code, falls interessant:

int sensorPin = A0;
int sensorValue = 0;
int ledPin = 13;

void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}

void loop()
{
sensorValue = analogRead(sensorPin);
Serial.println(sensorValue);

if (sensorValue > 512) {
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
}

delay(100);
}


Danke,
Andy

i_make_it
29.06.2016, 15:15
int sensorPin = A0;



Current Sensing A0 A1

https://www.arduino.cc/en/uploads/Main/arduino_MotorShield_Rev3-schematic.pdf
Man beachte R1 mit 0R15 zwichen SNSA und GND.
Also anderen Analogeingang als A0 oder A1 nehmen oder SNS0-ENABLE auftrennen, sonst wirken die 0,15Ohm nochmal als unterer Zweig eines Spannungsteilers dessen oberer Teil die Lichtschranke ist, die selbst wohl auch schon ein Spannungsteiler ist.
Also eine Parallelschaltung von Wiederständen im unteren Zweig. und dazu noch mit einem ziemlich kleinen Wiederstand.
Daß da alles in Richtung deutlich keinerer Spannungen verschoben ist, wundert da nicht wirklich.
Die Info hatte ich Dir aber zwei Posts weiter oben geliefert.


Function pins per Ch. A pins per Ch. B
Direction D12 D13
PWM D3 D11
Brake D9 D8
Current Sensing A0 A1
If you don't need the Brake and the Current Sensing and you also need more pins for your application you can disable this features by cutting the respective jumpers on the back side of the shield.
https://www.arduino.cc/en/Main/ArduinoMotorShieldR3

Prüf mal ab ob Du einen (oder mehrere) dieser 8 Pins für was anderes als zu Ansteuerung des Shields nutzt. Wenn ja kann es nicht funktionieren

Shag
29.06.2016, 18:09
Das Shield ist direkt auf den UNO draufgesteckt.
Aber ok, ich besorg mir nen anderen treiber, dann sind die Pins frei, und das Wärmeproblem müsste auch gelöst sein.

Danke
Andy

i_make_it
01.07.2016, 06:28
Das Shield ist direkt auf den UNO draufgesteckt.
Aber ok, ich besorg mir nen anderen treiber, dann sind die Pins frei,


Mann könnte auch:


int sensorPin = A0;

ändern in:
int sensorPin = A2;
oder bis
int sensorPin = A6;
dürfte kostengünstiger sein als neue Hardware zu kaufen.



ich besorg mir nen anderen treiber
und das Wärmeproblem müsste auch gelöst sein.


Das Motorshield hat als Einflußmöglichkeit:
PWM
Brake
und
Current Sensing
als feedback, damit ist es möglich einen Regelkreis zu programmieren, bei dem der Strom bei kleinen Drehzahlen reduziert wird.
OK, nicht einfach aber es geht.
Was soll ein anderer Treiber an dem Problem ändern.
Du nimmst einen größeren Treiber?
Gut daß ändert nichts am Wiederstand der Motorwicklung.
Dann wird halt nicht der Treiber heiß, sondern der Motor brennt durch.

Weißt Du denn was der Treiber können muß, damit das Problem der Erwärmung bei kleinen Drehzahlen nicht auftritt?

Peter(TOO)
01.07.2016, 10:21
Hallo,

Was soll ein anderer Treiber an dem Problem ändern.
Du nimmst einen größeren Treiber?
Gut daß ändert nichts am Wiederstand der Motorwicklung.
Dann wird halt nicht der Treiber heiß, sondern der Motor brennt durch.

Weißt Du denn was der Treiber können muß, damit das Problem der Erwärmung bei kleinen Drehzahlen nicht auftritt?
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)

i_make_it
02.07.2016, 19:35
Das Shield ist direkt auf den UNO draufgesteckt.
Aber ok, ich besorg mir nen anderen treiber, dann sind die Pins frei, und das Wärmeproblem müsste auch gelöst sein.


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.

Shag
02.07.2016, 20:56
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

Shag
06.07.2016, 08:51
Hallo nochmal,

die Waage arbeitet soweit, allerdings fehlt noch die Bedienfreundlichkeit.
Vielleicht könnt ihr mir da weiterhelfen.

Der Code sieht bisher so aus:


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

i_make_it
06.07.2016, 11:34
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.

Shag
06.07.2016, 19:08
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.




#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

i_make_it
06.07.2016, 19:40
Davon ausgehend, das motorSpeed = 0, Motorgeschwindigkeit = null bedeutet, sähe das dann so aus.


#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();

}
}


Allerdings muß dann der Taster mindestens solange gedrückt sein wie das Programm für einen Duchlauf braucht um immer sicher erkannt zu werden.
Ü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.

Shag
06.07.2016, 20:57
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

i_make_it
06.07.2016, 21:08
Falsche Sprache.

"<>" = ungleich = "!="
"=" = gleich = "==" ,natürlich nur bei den IF Bedingungen

https://www.arduino.cc/en/Reference/HomePage
(https://www.arduino.cc/en/Reference/HomePage)
Habs oben geändert.

Shag
06.07.2016, 22:16
Alles klar, funktioniert.
Test mit Hardware kann ich morgen erst machen.

Vielen Dank
Gruß
Andy

Shag
07.07.2016, 21:10
Hallo, alles bestens.
Lichtschranken, Motor, Drehzahl, alles funktioniert.

Hab grad versucht das selbe für den größeren Motor mit dem TB6560 Treibermodul anzupassen, aber da klappt das ganze weniger gut.
Das Treibermodul hat ja nur zwei Eingänge CW+ und CLK+, die beiden anderen gehen auf Masse.

Kannst Du mir sagen wie ich mein Programm umschreiben soll?
Momentan läuft es so:
#include <Bounce2.h>

int buttonPin = 13;
int sensorPin1 = A2;
int sensorPin2 = A3;
int sensorValue1 = 0;
int sensorValue2 = 0;

int motorPin1 = 8;
int motorPin2 = 9;




int motorSpeed = 0;
int buttonState = 0;
int merker = 0;

void setup() {

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

digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);



pinMode(buttonPin, INPUT);


Serial.begin(9600);
}
void loop(){
buttonState = digitalRead(buttonPin);
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
Serial.println(buttonState);
if (buttonState != 1)
{
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();

}
}



void counterclockwise (){
// 1


digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);

delay(motorSpeed);


// 2

digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);

delay (motorSpeed);

}




Motor läuft sehr langsam bei motorSpeed = 1, etwa 6 sek für eine Umdrehung.
Bei motorSpeed = 2 dann die Hälfte, klar.
Aber bei Motor Speed = 0 wieder in etwa so schnell wie auf motorSpeed = 1


Hast du vielleicht ne Idee was ich anders machen könnte?
Die Beispielprogramme aus dem Netz hab ich schon durchprobiert, aber die anzupassen ist mir leider zu hoch.

Vielen Dank
Andy

i_make_it
07.07.2016, 22:08
Probier es mal so:


#include <Bounce2.h>

int buttonPin = 13;
int sensorPin1 = A2;
int sensorPin2 = A3;
int sensorValue1 = 0;
int sensorValue2 = 0;

int motorPin1 = 8;
int motorPin2 = 9;

int motorSpeed = 0;
int buttonState = 0;
int merker = 0;

void setup() {
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}

void loop(){
buttonState = digitalRead(buttonPin);
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
Serial.println(buttonState);
if (buttonState != 1)
{
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;
}
}

void counterclockwise (){
// 1
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
delay(motorSpeed);

// 2
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
delay (motorSpeed);
}

Shag
07.07.2016, 22:16
Gut, test ich morgen früh. Hab Nachtschicht. :roll:

Danke
Gruß

Shag
08.07.2016, 06:28
Moin..

Alles klar, funktioniert.
Grad hatte ich noch das Problem dass der Motor zwar mit nem Testprogramm sauber gelaufen ist, aber mit den Lichtschranken nur noch sehr langsam.
Hatte den Verdacht dass das UNO nicht mit Lichtschranken überwachen und Motor regeln hinterher kommt.
Zuerst wollte ich die Lichtschranken nicht bei jedem Durchlauf abfragen, hab aber keine Ahnung ob und wie das geht..
Also hab ich den letzten Teil jetzt zehnmal drin, und erst dann werden die Lichtschranken wieder abgefragt. Klappt wunderbar.
Liegt also anscheinend am UNO bzw. dessen fehlender Geschwindigkeit.

Hier nochmal der Code, vielleicht hilfts jemandem. Nicht schön, aber funktioniert.

Danke für die Hilfe.


#include <Bounce2.h>

int buttonPin = 13;
int sensorPin1 = A2;
int sensorPin2 = A3;
int sensorValue1 = 0;
int sensorValue2 = 0;

int PinCLK = 9;
int PinCW = 8;

int ledPin1 = 2;
int ledPin2 = 4;
int ledPin3 = 7;

int motorSpeed = 0;
int buttonState = 0;
int merker = 0;

void setup() {

pinMode(PinCLK, OUTPUT);
pinMode(PinCW, OUTPUT);

digitalWrite(PinCLK, LOW);
digitalWrite(PinCW, LOW);

pinMode(buttonPin, INPUT);

pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);

Serial.begin(9600);
}
void loop(){

buttonState = digitalRead(buttonPin);
sensorValue1 = analogRead(sensorPin1);
sensorValue2 = analogRead(sensorPin2);
Serial.println(buttonState);

if (buttonState != 1)
{
merker = 1;
}
if (sensorValue1 > 512 && sensorValue2 < 512 && merker == 1)
{
motorSpeed = 420;
digitalWrite (ledPin1, HIGH);
digitalWrite (ledPin2, LOW);
digitalWrite (ledPin3, LOW);
counterclockwise();

}
if (sensorValue1 < 512 && sensorValue2 < 512 && merker == 1)
{
motorSpeed = 12000;
digitalWrite (ledPin1, HIGH);
digitalWrite (ledPin2, HIGH);
digitalWrite (ledPin3, LOW);
counterclockwise();
}
if (sensorValue1 < 512 && sensorValue2 > 512)
{
motorSpeed = 0;
digitalWrite (ledPin1, HIGH);
digitalWrite (ledPin2, HIGH);
digitalWrite (ledPin3, HIGH);
merker = 0;
}
}

void counterclockwise (){

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

digitalWrite(PinCLK, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PinCLK, LOW);
delayMicroseconds(motorSpeed);

}


Gruß
Andy

i_make_it
08.07.2016, 06:50
Die Timingproblem liegen an den "delayMicroseconds()" Befehlen.
Der µC macht dann solange genau "nichts" (NOP = non operating).
Damit verzögert man den Schleifendurchlauf und macht das Programm langsam.
Der nächste Schritt beim Lernen von Arduino wäre Dein programm von einfach auf effektiv umzustellen und dann auf elegant und effektiv.
Ich habe ja weiter oben schon darüber geschrieben wie man das mit Timerabfagen und Interrupts machen kann.

Wenn es so läuft und das der einzige Zweck ist, kannst Du es auch so lassen (never change a running system).
Wenn Du Dich verbessern willst, gehe den nächsten Schritt.

Shag
08.07.2016, 07:06
Erstmal lass ich es so, was aber nicht heißt dass ich nicht noch dran rumfeile.

Bin für Vorschläge offen, vielleicht hast du ein Beispiel für ein Programm mit Interrupts das auch ein Anfänger versteht.
Aus Teilen was zusammenbasteln klappt schon einigermaßen..

Grad freu ich mich noch dass es funktioniert, steck das USB Kabel ab und der Motor fängt an zu laufen. Gut, mach die Lichtschranke zu, Motor aus. Lichtschranke wieder auf, läuft wieder an ohne Taster gedrückt zu haben. USB wieder dran, alles bestens. USB weg, spinnt.

Was ist da nun los?

Externe Stromversorgungen sind natürlich dran..

Auch wenn ich dem UNO USB nur Strom geb über ein Handy-Ladegerät funktioniert alles.

Wenn Netzteil und USB angeschlossen sind, auch. Nur 12V Netzteil, dann nicht.