Hallo,
ich Hobbybastler, habe seit längerer Zeit ein Projekt offen, bei dem ich
nun nicht weiterkomme.
Ziel war es, über den Arduino mit Hilfe eines PIR einen Motor
anzusteuern, welcher eine Spinne abseilt, wartet und wieder hochzieht,
bis die Spinne einen Schalter betätigt und den Motor ausstellt.
Eigentlich simple.
Nun habe ich versucht dies über Tinkerpad zu simulieren, scheitere aber.
Eventuell liegt es an den fehlenden Bauteil in Tinkercad.
Ich nutze einen DC Motor Driver MX1508 und in Tinkercad den
komplizierteren Pololu Motor controller.
Ich bitte hier um Betrachtung meiner Schaltung speziell auf diesem
Bereich.
Code und Schaltplan, wie auch Link zu Tinkercad sind dabei.
https://www.tinkercad.com/things/g8yfKmDvUAT-spider-drop-not-working
1
// constants won't change. They're used here to set pin numbers:
2
constintPIRpin=2;
3
//const int LEDpin =1; //digispark
4
constintLEDpin=13;//UNO
5
constintlimitPin=7;// the number of the pushbutton pin
6
//const int motorFWD = 0; //digispark
7
// const int motorREV = 4; //digispark
8
9
constintmotorFWD=5;//UNO
10
constintmotorREV=6;//UNO
11
constintfrightDelay=10000;//delay between actions
12
13
constintacceleration=25;//how fast the motor starts to int acceleration delay in ms
14
15
// variables will change:
16
intlimitState=1;// variable for reading the pushbutton status
17
intPIRstate=0;
18
intMOTdirection=1;
19
intPWMValue=200;// starting PWM value
20
21
voidsetup(){// initialize the LED pin as an output:
22
pinMode(LEDpin,OUTPUT);
23
pinMode(PIRpin,INPUT);
24
pinMode(motorFWD,OUTPUT);
25
pinMode(motorREV,OUTPUT);
26
pinMode(limitPin,INPUT_PULLUP);
27
}
28
29
voidloop(){
30
31
PIRstate=digitalRead(PIRpin);
32
if(PIRstate==HIGH){PWMValue=200;digitalWrite(LEDpin,HIGH);do{limitState=digitalRead(limitPin);driveMotor();}while(limitState!=0);//state is 1 button is not activated
Michael schrieb:> scheitere aber.
Was erwartest du und was passiert stattdessen?
> Eventuell liegt es an den fehlenden Bauteil in Tinkercad.> Ich nutze einen DC Motor Driver MX1508 und in Tinkercad den> komplizierteren Pololu Motor controller.
Wenn du andere Bauteile verwendest, dann musst du sie logischerweise
natürlich entsprechend dem Datenblatt auch anders ansteuern.
> Ich bitte hier um Betrachtung meiner Schaltung speziell auf diesem> Bereich.
Wie wäre es, wenn du diese einfache Schaltung genauso einfach Schritt
für Schritt und Komponente für Komponente in Betrieb nimmst?
Denn aus langjähriger Erfahrung kann ich sicher sagen: eine
Inbetriebnahme nach dem Motto "bau alles zusammen und schalte es ein"
funktioniert in 99,9% der Fälle nicht.
Ich erwarte, dass man diesen einfachen Aufbau mit konsequentem
schrittweisen Vorgehen leicht an 1 Abend zum Laufen bekommt.
Hallo Lothar!
Lothar M. schrieb:> Was erwartest du und was passiert stattdessen?
Meine Erwartung wäre, dass wenn der PIR aktiviert wird, der Motor
gestartet wird.
Es passiert aber nichts.
Lothar M. schrieb:> Wenn du andere Bauteile verwendest, dann musst du sie logischerweise> natürlich entsprechend dem Datenblatt auch anders ansteuern.
Daher erwähne ich ja ausdrücklich diesen Teil. Ich finde den Controlelr
komplizierter als meinen und finde auch in verschiedenen Beispielen
immer unterschiedliche Arten der Verwendung.
Also auch mit Nachbauten, habe ich keinen Erfolg verbuchen können.
Und der Schritt für Schritt Teil ist logisch. Bis zu diesem Punkt
funktionierte auch alles. Wobei der Code entsprechend auch geändert
werden musste (sollte aber passen).
Lothar M. schrieb:> Ich erwarte, dass man diesen einfachen Aufbau mit konsequentem> schrittweisen Vorgehen leicht an 1 Abend zum Laufen bekommt.
Als Hobbybasteler mit zwei Stunden pro Woche Zeit bin ich froh, dass ich
überhaupt dazulernen möchte. Und Programmierung und Mikroelektronik
standen vorher nicht auf meinem Stundenplan.
Aber ja, ich hätte auch erwartet, dass an einem Abend zu schaffen.
Ich finde den Fehler aber nicht, grenze ihn aber auf diesem Controller
ein.
Wobei, ich habe aus Frust das Teil auch schon zusammengelötet, leider
mit dem gleichen Ergebnis.
Deshalb wende ich mich jetzt an das Forum und Experten, welche im
Gegensatz zu mir, vermutlich den Fehler innerhalb zwei Sekunden gefunden
haben werden.
Danke und Gruß
Michael schrieb:> Meine Erwartung wäre, dass wenn der PIR aktiviert wird, der Motor> gestartet wird.> Es passiert aber nichts.
Also erste Frage: gibt der PIR überhaupt ein Signal aus?
Welche Pegel kannst du an dessen Ausgang mit einem Multimeter im
"inaktiven" und "aktiven" Zustand messen?
> Es passiert aber nichts.
Kannst du den Motor mit einem kleinen Dreizeiler z.B. in einer
Dauerschleife [2s links, 2s rechts] (ganz ohne besonderen Schnickschnack
wie "Beschleunigung") zum Laufen bringen? Wenn nein: warum nicht? Läuft
der Motor, wenn du die nötigen logischen Pegel ganz ohne µC direkt mit
Drähten an den Controller anlegst?
Michael schrieb:> Ich nutze einen DC Motor Driver MX1508
Den simplen urzeitigen L298-Verschnitt hier?
- https://www.pololu.com/product/1381> und in Tinkercad den komplizierteren Pololu Motor controller.
Den da?
-
https://www.roboter-bausatz.de/p/mx1508-dc-motor-treiber-modul-ln298n-1.5a
Das ist wie wenn du eigentlich nur Roller fahren willst, dafür aber zum
Test schon mal das Raumschiff klar machst...
> Ich finde den Controlelr komplizierter als meinen
Dann interessiert der dich doch auch nicht. Du willst ja deine
Schaltung zum Laufen bekommen, nicht irgendeine andere mit irgendwelchen
anderen Bauteilen.
Aus diesem Grund: vergiss die nutzlose Simulation.
Verwende deine täglichen 2 Stunden besser darauf, deinen konkreten
Aufbau Schritt für Schritt in Betrieb zu nehmen:
1. Lass mit einem Dreizeiler-Programm eine LED an einem Ausgang
blinken.
2. Zeige mit einem neuen Dreizeiler auf dieser LED an, ob du den PIR
richtig eingelesen bekommst.
3. Steuere mit einem weiteren Dreizeiler den Motor so an, dass er das
macht, was du willst.
4. usw.
5. ...
19. usf.
20. Lass die Spider tanzen.
Michael schrieb:> Ich liefere gerne mehr Infos dazu wenn nötig.
Verlinke mal die real verwendeten Teile (Motor, Treiber, Sensor) oder
nenne deren exakte Bezeichnung, damit man das Datenblatt suchen kann.
Ob ein 9V Block einen Motor versorgen kann?
Hi Michael,
wie Lothar schon sagt, probier doch mal die Funktionen jede für sich
allein. Wenn die sicher funktionieren, dann macht es Sinn, sich über den
Ablauf Gedanken zu machen. (In dem Ablauf ist definitiv was falsch. Es
sei denn, du hast für den Anschlag oben UND unten einen Taster. Aber das
kommt aus deiner Beschreibung so nicht raus.)
Hier mal ein paar Beispiele, die bei dir funktionieren sollten:
LED leuchtet, wenn PIR was detektiert/PIR Ausgang high ist.
Lothar M. schrieb:> Denn aus langjähriger Erfahrung kann ich sicher sagen: eine> Inbetriebnahme nach dem Motto "bau alles zusammen und schalte es ein"> funktioniert in 99,9% der Fälle nicht.
Über die Nachkommastelle können wir streiten, aber ich unterschreibe das
gerne, geht überwiegend schief.
Elias K. schrieb:> wie Lothar schon sagt, probier doch mal die Funktionen jede für sich> allein. Wenn die sicher funktionieren, dann macht es Sinn, ...
Das füttert wieder meine Vorurteile: Anstatt selbst logisch zu agieren,
lieber im Internet schreiben. Ich weiß garnicht, wie viele Stunden ich
schon auf eigenen Fehlern gekaut habe, gerne Kleinigkeiten, die man
einfach übersieht.
Elias K. schrieb:> LED leuchtet, wenn PIR was detektiert/PIR Ausgang high ist.
1
voidloop(){
2
limitState=digitalRead(limitPin);
3
if(limitState==LOW)
4
digitalWrite(LEDpin,HIGH);// LED
5
else
6
digitalWrite(LEDpin,LOW);
7
}
Das bekomme ich sogar in eine Zeile:
1
voidloop(){
2
digitalWrite(LEDpin,digitalRead(limitPin));
3
}
Nachtrag : Bei Arduino hat man USB dran und den seriellen Monitor - da
setze ich meist serial.print und gucke mir am Bildschirm an, was los
ist.
Hallo und danke.
Ich habe das Ding inzwischen zusammengebastelt und diverse Codes
versucht.
Die Komponenten funktionieren alle, Schaltung ist auch richtig (Hatte in
Tinkercad den falschen Motor Driver).
Mittlerweile habe ich den Code umgeschrieben und unnötiges rausgenommen:
1
// constants won't change. They're used here to set pin numbers:
2
constintPIRpin=2;
3
constintlimitPin=7;
4
constintmotorFWD=5;
5
constintmotorREV=6;
6
constintfrightDelay=10000;
7
constintacceleration=25;
8
9
// variables will change:
10
intlimitState=1;
11
intPIRstate=0;
12
intMOTdirection=1;
13
intPWMValue=200;
14
15
voidsetup(){
16
pinMode(PIRpin,INPUT);
17
pinMode(motorFWD,OUTPUT);
18
pinMode(motorREV,OUTPUT);
19
pinMode(limitPin,INPUT_PULLUP);
20
}
21
22
voidloop(){
23
PIRstate=digitalRead(PIRpin);
24
if(PIRstate==HIGH){
25
PWMValue=200;
26
do{
27
limitState=digitalRead(limitPin);
28
driveMotor();
29
}while(limitState!=0);
30
31
if(MOTdirection==0){
32
MOTdirection=1;
33
}else{
34
MOTdirection=0;
35
}
36
37
stopMotor();
38
delay(500);
39
lockMotor();
40
delay(1000);
41
stopMotor();
42
delay(frightDelay);
43
}
44
}
45
46
voiddriveMotor(){
47
if(PWMValue<255){
48
++PWMValue;
49
}
50
delay(acceleration);
51
52
if(MOTdirection==1){
53
analogWrite(motorFWD,PWMValue);
54
analogWrite(motorREV,0);
55
}else{
56
analogWrite(motorFWD,0);
57
analogWrite(motorREV,PWMValue);
58
}
59
}
60
61
voidstopMotor(){
62
analogWrite(motorFWD,0);
63
analogWrite(motorREV,0);
64
}
65
66
voidlockMotor(){
67
digitalWrite(motorFWD,1);
68
digitalWrite(motorREV,1);
69
}
Der Motor fährt vorwärts, bis der Knopf gedrückt wird.
Eigentlich sollte er aber erst vorwärts fahren, pausieren und nach einer
kurzen Zeit rückwärts fahren, bis der Knopf gedrückt wird.
Der Motor selbst ist dazu in der Lage (bereits getestet durch umgekehrte
Batteriekabel).
Was mir auch auffällt ist, dass die Geschwindigkeit des
rückwärtsdrehenden Motors leider nicht langsamer ist.
Das langsame Drehen des Motors habe ich noch gar nicht hinbekommen (z.B.
PBW auf 50).
Seht ihr den Fehler?
Danke und lieben Gruß
Michael schrieb:> Mittlerweile habe ich den Code umgeschrieben und unnötiges rausgenommen
Ich hatte nicht umsonst gesagt: nimm jede Komponente einzeln für sich in
Betrieb. Lies einfach nochmal meinen Post und melde dich, wenn du darin
etwas nicht verstanden hast.
> Der Motor selbst ist dazu in der Lage (bereits getestet durch umgekehrte> Batteriekabel).
Dann steuere den Motorcontroller erst mal ganz ohne µC mit
Drahtverbindungen nach high und low so an, dass der Motor mal in die
eine und in die andere Richtung fährt.
Dann ersetzt du diese Drahtverbindungen durch µC-Pins und steuerst den
µC mit einem Dreizeiler lass so an, dass er statische high und low Pegel
ausgibt und der Motor in die Richtung läuft, die du erwartest.
Und dann schreib einen Dreizeiler, mit dem du per PWM-Wert die
Motorgeschwindigkeit einstellen kannst.
Und dann schreib einen weiteren Dreizeiler, mit dem der Motor mit
unterschiedlichen Geschwindigkeiten periodisch vor und zurück läuft.
Und dann kläre noch, was denn der Unterschied zwischen stopMotor() und
lockMotor() ist. Und vor allem: ob du diesen Unterschied überhaupt
brauchst.
> Eigentlich sollte er aber ...
Mein Vorschlag: lies dich mal zum Thema FSM (Zustandsautomaten) ein. Das
ist wesentlich weniger wild als es sich anhört, aber du bekommst damit
die blockierenden delay() raus. Denn im Grunde ist ein delay() einfach
nur aktive Rechenzeitverschwendung, weil der Prozessor da "nebenher"
nichts anderes machen kann.
Kurz gesagt: wenn ich irgendwo im Ablauf ein delay() sehe, dann sehe ich
einen Programmfehler.
Und wie gesagt:
1
delay(acceleration);
lass den Käse mit der Beschleunigung erst mal weg. Besonders, wenn da
schon wieder ein delay() im Spiel ist!
Ich würde daher sowas ansetzen:
1
:
2
intSchritt=0;// Ablaufschritte / 0 = warte auf PIR
3
intStartzeit,Jetzt;
4
:
5
:
6
voidloop(){
7
Jetzt=millis();
8
switch(Schritt)
9
case0:// warte auf PIR und fahre dann vorwärts
10
if(digitalRead(PIRpin)){
11
PWMValue=200;
12
driveMotor(1);// vorwärts
13
Startzeit=Jetzt;
14
Schritt=1;
15
}
16
break;
17
18
case1:// fahre 500 ms und halte dann an
19
if(Jetzt-Startzeit>500){
20
stopMotor();
21
Startzeit=Jetzt;
22
Schritt=2;
23
}
24
break;
25
26
case2:// warte 500 ms und fahre dann rückwärts
27
if(Jetzt-Startzeit>500){
28
PWMValue=50;
29
driveMotor(0);// rückwärts
30
Startzeit=Jetzt;
31
Schritt=3;
32
}
33
break;
34
35
case3:// rückwärts bis Endschalter belegt, dann anhalten und von vorn
Hallo.
Danke für die Hilfe.
Leider haben mich die Code-Erweiterungen eher neuen Problemen ausgesetzt
oder generell überfordert ;-) .
Habe nochmal neu angefangen (versucht "delay" zu vermeiden) und es
funktioniert auch fast wie gewünscht.
1
constintpirPin=2;// PIR sensor pin
2
constintswitchPin=7;// Switch pin
3
constintmotorPin1=5;// Motor driver pin 1
4
constintmotorPin2=6;// Motor driver pin 2
5
constintforwardSpeed=255;// Motor speed during forward movement (range: 0-255)
6
constintreverseSpeed=30;// Motor speed during reverse movement (range: 0-255)
7
constintstopDelay=3000;// Delay in ms after motor stops
8
9
voidsetup(){
10
pinMode(pirPin,INPUT);
11
pinMode(switchPin,INPUT_PULLUP);
12
pinMode(motorPin1,OUTPUT);
13
pinMode(motorPin2,OUTPUT);
14
Serial.begin(9600);
15
}
16
17
voidloop(){
18
// Wait for PIR sensor to detect movement
19
while(digitalRead(pirPin)==LOW){
20
delay(1000);
21
}
22
23
// Wait 30 seconds before detecting movement again
24
delay(30000);
25
26
// Start moving motor forward at full speed
27
analogWrite(motorPin1,forwardSpeed);
28
analogWrite(motorPin2,0);
29
delay(3000);
30
31
// Stop motor and wait for 3 seconds
32
analogWrite(motorPin1,0);
33
analogWrite(motorPin2,0);
34
delay(stopDelay);
35
36
// Start moving motor backwards slowly
37
analogWrite(motorPin1,0);
38
analogWrite(motorPin2,reverseSpeed);
39
40
// Wait for switch to be pressed or 3 seconds to elapse
ABER, die Geschwindigkeit beim Rückwärtsfahren ist zu schnell und
jegliche Änderungen unter 50 bringen den Motor dazu hohe Töne abzugeben
oder sich gar nicht mehr zu bewegen.
Meine Frage also nun:
Wie lasse ich den Motor langsam rückwärts fahren ohne diese hohen Töne?
Danke und Gruß
Und bitte keine neuen Code-Teile mehr besser komplett.
ich blicke schon bald echt nicht mehr durch ;-)