Archiv verlassen und diese Seite im Standarddesign anzeigen : Alles PWM oder wie?
hallo allerseits,
diese teile (https://www.ebay.de/itm/272687842726?ViewItem=&item=272687842726&ppid=PPX000608&cnac=DE&rsta=de_DE(de_DE)&cust=8GV38563JN902513L&unptid=a25e2858-c7cd-11e7-995c-441ea14e5834&t=&cal=37518358bc166&calc=37518358bc166&calf=37518358bc166&unp_tpcid=email-receipt-auction-payment&page=main:email&pgrp=main:email&e=op&mchn=em&s=ci&mail=sys) werden vielerorts angeboten, sie würden für manche anwendung ja auch reichen...
In der überschrift wird auch PWM versprochen, weiter im text aber nicht mehr erwähnt. Auch fehlen mir die "EN" pinns irgendwie...
Habe ich was übersehen? Hat jemand die dinger schon mal eingesetzt?
Auch fehlen mir die "EN" pinns irgendwie
"En" Pin brauchst du für PWM nicht zwingend. Auch mit In1/In2 kannst du PWM ausgeben, sogar einfacher als mit In1/In2/En. Ich nehme gerne z.B. den L9110 (https://www.elecrow.com/download/datasheet-l9110.pdf), der so angesteuert wird.
Was mir fehlt, ist eine vollständige Beschreibung mit Wahrheitstabelle und Timing Diagramm. Hinter dem Hinweis auf Truth Table und function diagram sehe ich in der Beschreibung nichts, wahrscheinlich nicht vollständig kopiert.
Ein gescheites Datenblatt zu diesem MXL508 oder wie auch immer der Chip heißt wäre wahrscheinlich bei dem Preis zu viel verlangt. Was der L298N in der Beschreibung zu suchen hat habe ich auch nicht begriffen.
RoboHolIC
19.02.2018, 21:59
Sieh dir mal die Breakouts für den TB6612FNG an. Die haben je einen expliziten PWM-Eingang pro H-Brücke und kosten aus China genauso unverschämt wenig.
i_make_it
20.02.2018, 06:16
Mit den selben Bildern wird das auch als L298N Modul angeboten.
https://www.banggood.com/de/5pcs-Dual-Channel-L298N-DC-Motor-Driver-Board-PWM-Speed-Dual-H-Bridge-Stepper-Module-p-1167075.html
Demnach hat der Chip 2 En Eingänge. Die sind einfach fest auf High gelegt.
@i_make_it:
https://www.banggood.com/de/5pcs-Dual-Channel-L298N-DC-Motor-Driver-Board-PWM-Speed-Dual-H-Bridge-Stepper-Module-p-1167075.html (https://www.banggood.com/de/5pcs-Dual-Channel-L298N-DC-Motor-Driver-Board-PWM-Speed-Dual-H-Bridge-Stepper-Module-p-1167075.html)
Demnach hat der Chip 2 En Eingänge. Die sind einfach fest auf Highgelegt.
was bedeutet das genau? Immer nur die maximale geschwindigkeit?
@witkatz:
"En"Pin brauchst du für PWM nicht zwingend. Auch mit In1/In2 kannst duPWM ausgeben, sogar einfacher als mit In1/In2/En. Ich nehme gernez.B. denL9110 (https://www.elecrow.com/download/datasheet-l9110.pdf),der so angesteuert wird.
hast Du da evtl. ein codebeispiel? Leider habe ich nichts in derrichtung gefunden...
@RoboHolIC:
Siehdir mal die Breakouts für den TB6612FNG an. Die haben je einenexpliziten PWM-Eingang pro H-Brücke und kosten aus China genausounverschämt wenig.
diese hier (https://www.ebay.de/itm/L9110S-Schrittmotortreiber-Schrittmotor-Stepper-Motor-Driver-Board-H-Bridge/152752628932?hash=item2390c424c4:g:umoAAOSwoRBaibR b) aber nicht… Gibt es da verschiedene?
Mit den selben Bildern wird das auch als L298N Modul angeboten.
Mit dem L298N hat dieser Chip aber nichts zu tun, ist vielleicht nur ein Suchbegriff.
Ich vermute, dass hier der fernöstliche MX1508 (http://sales.dzsc.com/486222.html) oder so was ähnliches verbaut ist.
- - - Aktualisiert - - -
hast Du da evtl. ein codebeispiel?
so in der Art mache ich das:
void Motor1Forw(char velo){
Motor1_In1 = 0;
Motor1_Pwm = velo;
}
void Motor1Backw(char velo){
Motor1_In1 = 1;
Motor1_Pwm = 255 - velo;
}
i_make_it
20.02.2018, 08:50
@Witzkatz: stimmte das Pinout von dem MX1508 passt zumindest auf das was man auf der Platine sieht.
@inka: Enable braucht man nicht unbedingt.
Bei größeren Motorreglern nimmt man das halt, um sicherzustellen das die Steuerung bereit ist bevor die Motoren bestromt werden.
Das verhindert, daß beim Einschalten die Motoren rucken weil unbestimmte Pegel irgendwo anliegen, die der Regler als Fahrbefehl versteht.
Pro Motor braucht es halt bei dem Teil je ein PWM für Clockwise und ein PWM für Counter Clockwise.
Ob man das Richtungssignal auf 1 legt und per Enable ein PWM ausgibt oder ob man das PWM direkt an den Richtungsausgängen ausgibt ist eine reine Software Sache.
So spart man halt pro Motor einen Pin (bei DIR-CW plus DIR-CCW).
Wenn man so eine Treiber mit einem DIR und einem PWM ansteuern will, braucht man zwei UND und ein NICHT Gatter.
PWM je auf IN1 der beiden UND's und DIR einmal auf IN2 des einen UND und einmal auf das NICHT und von da auf IN2 des zweiten UND.
Dann kann man die Ausgänge der Beiden UND's auf den Treiber legen.
Coden ist aber schneller und braucht keine Hardware.
so in der Art mache ich das:
void Motor1Forw(char velo)
{
Motor1_In1 = 0;
Motor1_Pwm = velo;
}
void Motor1Backw(char velo){
Motor1_In1 = 1;
Motor1_Pwm = 255 - velo;
}
so habe ich versucht das umzusetzen:
int Motor_1_Pwm;
.
.
.
void Motor_1_Backw(char velo)
{
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
Motor_1_Pwm = 255 - velo;
}
mit dem aufruf von "Motor_1_Backw(200);"
dreht der motor zwar, allerdings unabhängig von der zahl "velo", also immer voll power...
so habe ich versucht das umzusetzen:
int Motor_1_Pwm;
.
.
.
void Motor_1_Backw(char velo)
{
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
Motor_1_Pwm = 255 - velo;
}
mit dem aufruf von "Motor_1_Backw(200);"
dreht der motor zwar, allerdings unabhängig von der zahl "velo", also immer voll power...
du übergibst doch auch überhaupt keinen velo-Wert an irgendeienen Pin - wie soll es dann was bewirken?
Stattdessen musst du 1 pin HIGH oder LOW setzen für die Richtung und den anderen per PWM (velo) für die Geschwindigkeit.
du übergibst doch auch überhaupt keinen velo-Wert an irgendeienen Pin - wie soll es dann was bewirken?
Stattdessen musst du 1 pin HIGH oder LOW setzen für die Richtung und den anderen per PWM (velo) für die Geschwindigkeit.
aber die pins haben dann trotzdem keine verbindung zur hardware, also zum motortreiber? Das ist das was ich nicht verstehe...
verstehe nicht was du meinst.
du hast 2 Pins pro Motor, einer ist für die Richtung, der andere für die PWM.
welcher wofür, weiß ich nicht, möglicherweise der erste für PWM, der 2. für die Richtung. Oder umgekehrt - frag ggf. beim Händler an.
PS,
und lass mal das seltsame
255 - velo
weg - das ist normalerweise Unsinn.
velo alleine ist die PWM, für beide Richtungen.
i_make_it
20.02.2018, 15:15
Du übergibst fest "200"?
Dann kann aber auch nur der Wert verarbeitet werden.
Schon mal Versucht einfach eine Geschwindigkeitsrampe zu erzeugen?
0 bis max. Rückwärts und zurück zu 0 und bis max. Vorwärts und zurück zu 0.
Bsp.:
int speed;
void loop(){
for (int speed=0; speed <=255; speed++){
void Motor_1_Backw(speed);
delay(10);
}
for (int speed=255; speed >=0; speed--){
void Motor_1_Backw(speed);
delay(10);
}
for (int speed=0; speed <=255; speed++){
void Motor_1_Forw(speed);
delay(10);
}
for (int speed=255; speed >=0; speed--){
void Motor_1_Forw(speed);
delay(10);
}
}
void Motor1Forw(char velo){
Motor1_In1 = 0;
Motor1_Pwm = velo;
}
void Motor1Backw(char velo){
Motor1_In1 = 1;
Motor1_Pwm = 255 - velo;
}
Was macht er denn mit diesem Code?
Wenn es zu langsam ist die "delay" rauswerfen.
Vorschlag:
void Motor_1_Forw(char velo)
{
analogWrite(IN1, velo);
digitalWrite(IN2, HIGH);
}
void Motor_1_Backw(char velo)
{
analogWrite(IN1, velo);
digitalWrite(IN2, LOW);
}
das ist jetzt der code, der sich auch kompilieren lässt:
int speed;
void setup() {
// put your setup code here, to run once:
}
void loop(){
for (int speed=0; speed <=255; speed++){
Motor_1_Backw(speed);
// delay(10);
}
for (int speed=255; speed >=0; speed--){
Motor_1_Backw(speed);
// delay(10);
}
for (int speed=0; speed <=255; speed++){
Motor_1_Forw(speed);
// delay(10);
}
for (int speed=255; speed >=0; speed--){
Motor_1_Forw(speed);
// delay(10);
}
}
void Motor_1_Forw(char velo){
int Motor1_In1 = 0;
int Motor1_Pwm = velo;
}
void Motor_1_Backw(char velo){
int Motor1_In1 = 1;
int Motor1_Pwm = 255 - velo;
}
aber nach dem hochladen passiert nichts...
ich muss mir das noch genauer anschauen...
i_make_it
20.02.2018, 16:12
Wie ist den der komplette Code bei dem,
"Motor_1_Backw(200);"
zu einem drehenden Motor geführt hat?
Mein Code ist ein Sniplet, das einzufügen ist.
das
int speed;
halt ganz am Anfang um die Variable zu deklarieren.
den Abschnitt void setup()
{
bla bla
}
habe ich komplett weggelassen, da der ja bereits existieren muß wenn
"Motor_1_Backw(200);"
etwas bewirkt.
(ich weis ja nicht wie, welche Pins definiert sind)
In die Hauptschleife void loop()
halt die For Schleifen um speed zu inkrementieren und zu dekrementieren.
Und die beiden Funktionen unverändert von witzkatz.
- - - Aktualisiert - - -
aber die pins haben dann trotzdem keine verbindung zur hardware, also zum motortreiber? Das ist das was ich nicht verstehe...
Wenn sich der Motor dreht, was ist denn angeschlossen?
Plus und Minus zu einer Stromquelle und zwei Anschlüsse zu einem Motor sind das mindeste damit überhaupt was passieren könnte.
Ist außer diesen 4 Drähten sonst noch irgendeine Leitung irgendwo angeschlossen?
das ist jetzt der code, der sich auch kompilieren lässt:
int speed;
void setup() {
// put your setup code here, to run once:
}
void loop(){
for (int speed=0; speed <=255; speed++){
Motor_1_Backw(speed);
// delay(10);
}
for (int speed=255; speed >=0; speed--){
Motor_1_Backw(speed);
// delay(10);
}
for (int speed=0; speed <=255; speed++){
Motor_1_Forw(speed);
// delay(10);
}
for (int speed=255; speed >=0; speed--){
Motor_1_Forw(speed);
// delay(10);
}
}
void Motor_1_Forw(char velo){
int Motor1_In1 = 0;
int Motor1_Pwm = velo;
}
void Motor_1_Backw(char velo){
int Motor1_In1 = 1;
int Motor1_Pwm = 255 - velo;
}
aber nach dem hochladen passiert nichts...
ich muss mir das noch genauer anschauen...
jetzt hast du ja immer noch das bescheuerte 255-velo drin, was soll das?
und wo hast du definiert, was in1 und in2 für Pin-Nummern haben?
Und dass die pinMode Output haben??
Außerdem habe ich oben andere Funktionen hingeschrieben! (edit, c+p verrutscht)
void Motor_1_Forw(char velo)
{
analogWrite(IN1, velo);
digitalWrite(IN2, HIGH);
}
void Motor_1_Backw(char velo)
{
analogWrite(IN1, velo);
digitalWrite(IN2, LOW);
}
i_make_it
20.02.2018, 16:28
jetzt hast du ja immer noch das bescheuerte 255-velo drin, was soll das?
Was daran ist bescheuert?
(255-velo) ist die Inversion von (velo).
Das eine nimmt man bei einer positiv Logik das andere bei einer negativ Logik.
Bei witzkatz funktioniert es.
Ob es mit dieser Hardware funktioniert oder das Ergebniss invertiert ist, muß sich erst noch zeigen.
Nur "pauschal" bescheuert ist es halt nicht.
üblich ist bei L293D, L298N, BTS7960 und IRF3205/MC33886 das pwm für Geschwindigkeit, unabhängig von der Richtung.
der 2. Pin bei diesen H-Brücken (bei 2-pin Logik) wird für die eine Richtung auf HIGH, für die andere auf LOW gesetzt.
In jedem Fall müssen aber in setup() die GPIO-Pins definiert und auf OUTPUT gesetzt werden!
so habe ich versucht das umzusetzen:
int Motor_1_Pwm;
.
.
.
void Motor_1_Backw(char velo)
{
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
Motor_1_Pwm = 255 - velo;
}
Ich hätte vielleicht etwas Erklärung dabei schreiben sollen, sorry. Also du wählt bspsw. IN1 für Richtung und IN2 für speed. Dann musst du auch IN1 an einen Digitalausgang und IN2 an den PWM Ausgang anschließen.
Wenn IN1 == 0 dann geht der PWM Wert proportional zu velo
Wenn IN1 == 1 dann (Richtungsumkehr) geht der PWM Wert umgekehrt proportional zu velo, von 100% auf 0.
Bei mir ist der PWM Wert vom typ char, daher diese 255 - velo für Richtungsumkehr. Bei int oder anderen Wertebereichen muss man die Funktion entspr. anpassen.
In jedem Fall müssen aber in setup() die GPIO-Pins definiert und auf OUTPUT gesetzt werden!
z.B.
#define in1 3
#define in2 4
//...
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
@witkatz:
ich glaube dein Beispiel mit dem 255-velo ist extrem verwirrend ud führt hier auch (bei L298-Logik) auch nicht weiter.
Wie ist den der komplette Code bei dem,
"Motor_1_Backw(200);"
zu einem drehenden Motor geführt hat?
Wenn sich der Motor dreht, was ist denn angeschlossen?
Plus und Minus zu einer Stromquelle und zwei Anschlüsse zu einem Motor sind das mindeste damit überhaupt was passieren könnte.
Ist außer diesen 4 Drähten sonst noch irgendeine Leitung irgendwo angeschlossen?
- das ist der code der zu einem drehendem motor geführt hat:
int IN1 = 9;
int IN2 = 8;
int IN3 = 7;
int IN4 = 6;
int Motor_1_Pwm;
int Motor_2_Pwm;
//char velo;
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
Serial.begin(9600);
Serial.println("Enter number for control option:");
Serial.println("1. FORWARD");
Serial.println("2. REVERSE");
Serial.println("3. STOP");
Serial.println();
}
void loop()
{
char user_input;
while (Serial.available())
{
user_input = Serial.read();
/*
digitalWrite(IN1, LOW); //OFF
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
*/
if (user_input == '1')
{
Forward();
}
else if (user_input == '2')
{
Reverse();
}
else if (user_input == '3')
{
Stop();
}
else
{
Serial.println("Invalid option entered.");
}
}
}
void Forward()
{
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
Serial.print("Motor 1 Forward");
Serial.println();
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println("Motor 2 Forward");
Serial.println();
}
void Reverse()
{
Motor_1_Backw(50);
Motor_2_Backw(50);
//digitalWrite(IN1, LOW);
//digitalWrite(IN2, HIGH);
Serial.print("Motor 1 Reverse");
Serial.println();
//digitalWrite(IN3, LOW);
//digitalWrite(IN4, HIGH);
Serial.println("Motor 2 Reverse");
Serial.println();
}
void Stop()
{
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
Serial.print("Motor 1 Stop");
Serial.println();
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
Serial.println("Motor 2 Stop");
Serial.println();
}
/*
void Motor1Forw(char velo)
{
Motor1_In1 = 0;
Motor1_Pwm = velo;
}
void Motor1Backw(char velo)
{
Motor1_In1 = 1;
Motor1_Pwm = 255 - velo;
}
*/
void Motor_1_Forw(int velo)
{
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
Motor_1_Pwm = velo;
}
void Motor_1_Backw(int velo)
{
digitalWrite(IN1, LOW);
digitalWrite(IN2, velo);
//Motor_1_Pwm = 255 - velo;
}
void Motor_2_Forw(int velo)
{
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Motor_2_Pwm = velo;
}
void Motor_2_Backw(int velo)
{
digitalWrite(IN3, LOW);
digitalWrite(IN4, velo);
//Motor_2_Pwm = 255 - velo;
}
- angeschlossen ist +/-/ IN1/IN2/IN3/IN4/motor 1/motor 2
ok, ich bin raus, macht was ihr wollt... ](*,)
i_make_it
20.02.2018, 16:55
@Inka wie vertraut bist Du denn mir dem allgemeinen Aufbau eines Arduino Sktechs?
konstanten und Variablen Deklaration
void setup()
{
Eingänge, Ausgänge konfigurieren
Initialationen und Code der einmalig beim Controller Power On ausgeführt werden soll.
}
void loop()
{
Hauptschleife die immer wieder durchlaufen wird
}
void <funktionname>()
{
Funktionen und Interrupt Service Routinen die aus der Hauptschleife oder durch IRQ's aufgerufen werden
}
Ist dieses allgemeine Schema bekannt oder kopierst Du eher bestehenden Code zusammen und variierst ihn dann für Deine Bedürfnisse?
@Inkawie vertraut bist Du denn mir dem allgemeinen Aufbau eines ArduinoSktechs?
konstantenund Variablen Deklaration
voidsetup()
{
Eingänge,Ausgänge konfigurieren
Initialationenund Code der einmalig beim Controller Power On ausgeführt werdensoll.
}
voidloop()
{
Hauptschleife die immer wieder durchlaufen wird
}
void<funktionname>()
{
Funktionenund Interrupt Service Routinen die aus der Hauptschleife oder durchIRQ's aufgerufen werden
}
Istdieses allgemeine Schema bekannt oder kopierst Du eher bestehendenCode zusammen und variierst ihn dann für Deine Bedürfnisse?
ja,dieses allgemeine schema ist mir bekannt. Und ich richte mich im allgemeinenn auch danach. Trotzdem kopiere ich mir schon mal ein paar codeblöcke zusammen und versuche sie mir zurecht zu schnitzen...
Ichhätte vielleicht etwas Erklärung dabei schreiben sollen, sorry.Also du wählt bspsw. IN1 für Richtung und IN2 für speed. Dannmusst du auch IN1 an einen Digitalausgang und IN2 an den PWM Ausganganschließen.
WennIN1 == 0 dann geht der PWM Wert proportional zu velo
WennIN1 == 1 dann (Richtungsumkehr) geht der PWM Wert umgekehrtproportional zu velo, von 100% auf 0.
Beimir ist der PWM Wert vom typ char, daher diese 255 - velo fürRichtungsumkehr. Bei int oder anderen Wertebereichen muss man dieFunktion entspr. anpassen.
dieseerklärung hätte mir genügt, danke...
@inka: Welchen Treiber hast du denn jetzt tatsächlich da dran?
Nur um sicher zu gehen dass ich das noch richtig verstehe. Es geht immer noch um Anteuerung über IN1 und IN2 für einfache Brückentreiber wie L9110 oder den MX1508 vom Eröffnungspost, die allein über IN1 und IN2 (ohne En!) angesteuert werden. Oder?
Weil für den echten L298N oder dem vom RoboHolIc aufgeführten TB6612FNG gilt das so nicht. Da darfst du das PWM nicht negieren.
- - - Aktualisiert - - -
Deswegen finde ich die Beschreibung des Teils aus dem Eröffnungspost auch zum kotzen. L298N wird nur als buzzword benutzt um mehr Interesse zu wecken. Tatsächlich haben die Teile damit nichts zu tun und Versuche mit Ansteuerung und Codebeispielen für L298 führen in eine Sackgasse.
- - - Aktualisiert - - -
Sorry, wenn mein 8-bit Beispiel nicht so ganz in die Arduino Umgebung gepasst hat, aber ich habe aus meiner "bescheidenen" 8-bit Welt gepostet was ich habe. @inka: wenn du den Brückentreiber an Arduino am laufen hast, kannst du vielleicht dein funktionierendes Arduino Codesnippet für die Nachwelt präsentieren, um den Thread rund zu machen. Von mir aus kannst du auch einen Sketch daraus drehen ;)
i_make_it
20.02.2018, 21:59
So,
anhand des Sketches vermute ich mal daß das auf einem Due oder Mega 2560 läuft.
Auf einem Uno oder Nano funktioniert das nicht mit PWM und diesen PIN's.
PWM Pins
Nano: 3; 5; 6; 9; 10; 11
Uno: 3; 5; 6; 9; 10; 11
Due: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
Mega 2560: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
int IN1 = 9;
int IN2 = 8;
int IN3 = 7;
int IN4 = 6;
- - - Aktualisiert - - -
Dann kann der Motor nur mit 100% laufen,
void Forward() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
Serial.print("Motor 1 Forward");
Serial.println();
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println("Motor 2 Forward");
Serial.println();
}
Für PWM sollte es aber ein
analogWrite(pin, value)
sein.
https://www.arduino.cc/en/Tutorial/PWM
https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
- - - Aktualisiert - - -
So, das ist jetzt mit der heißen Nadel gestrickt.
Habe hier keine Hardware auf dem ich es laufen lassen kann.
Lässt sich aber fehlerfrei comilieren.
/*
PWM Pins
Nano: 3; 5; 6; 9; 10; 11
Uno: 3; 5; 6; 9; 10; 11
Due: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
Mega 2560: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
*/
int IN1 = 9;
int IN2 = 8;
int IN3 = 7;
int IN4 = 6;
int speed;
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
Serial.begin(9600);
Serial.println("Enter number for control option:");
Serial.println("1. FORWARD");
Serial.println("2. REVERSE");
Serial.println("3. STOP");
Serial.println();
}
void loop()
{
for (int speed=0; speed <=255; speed++){
Forward(speed);
delay(10);
}
for (int speed=255; speed >=0; speed--){
Forward(speed);
delay(10);
}
for (int speed=0; speed <=255; speed++){
Backward(speed);
delay(10);
}
for (int speed=255; speed >=0; speed--){
Backward(speed);
delay(10);
}
for (int speed=0; speed <=255; speed++){
Rotateleft(speed);
delay(10);
}
for (int speed=255; speed >=0; speed--){
Rotateleft(speed);
delay(10);
}
for (int speed=0; speed <=255; speed++){
Rotateright(speed);
delay(10);
}
for (int speed=255; speed >=0; speed--){
Rotateright(speed);
delay(10);
}
}
void Forward(int speed){
analogWrite(IN1, speed);
digitalWrite(IN2, LOW);
Serial.print("Motor 1 Forward");
Serial.println();
analogWrite(IN3, speed);
digitalWrite(IN4, LOW);
Serial.println("Motor 2 Forward");
Serial.println();
}
void Backward(int speed){
digitalWrite(IN1, LOW);
analogWrite(IN2, speed);
Serial.print("Motor 1 Backward");
Serial.println();
digitalWrite(IN3, LOW);
analogWrite(IN4, speed);
Serial.println("Motor 2 Backward");
Serial.println();
}
void Rotateleft(int speed){
digitalWrite(IN1, LOW);
analogWrite(IN2, speed);
Serial.print("Motor 1 Backward");
Serial.println();
analogWrite(IN3, speed);
digitalWrite(IN4, LOW);
Serial.println("Motor 2 Forward");
Serial.println();
}
void Rotateright(int speed){
analogWrite(IN1, speed);
digitalWrite(IN2, LOW);
Serial.print("Motor 1 Forward");
Serial.println();
digitalWrite(IN3, LOW);
analogWrite(IN4, speed);
Serial.println("Motor 2 Backward");
Serial.println();
}
void Stop(){
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
Serial.print("Motor 1 Stop");
Serial.println();
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
Serial.println("Motor 2 Stop");
Serial.println();
}
Wenn ich keinen Fehler drin habe, müssten sich die Räder einmal vorwärts drehen.
Und zwar von Stillstand bis zur Maximaldrehzahl und wieder bis zum Stillstand.
Dann einmal rückwärts.
Einmal Gegenläufig für drehen auf der Stelle, linksrum und einmal rechtsrum.
oderlachs
21.02.2018, 11:19
Hallo, habe das mal mit Interesse verfolgt.
Ich habe das auch mal gemacht und es müsste auch noch wo Code "rumliegen" der funktioniert.
Darum die Frage, macht es noch Sinn danach zu suchen, oder hat ihr es alles zum Laufen bekommen ??
Ich bin damals nach dem Chip Datenblatt gegangen.
Gerhard
So, anhand des Sketches vermute ich mal daß das auf einem Due oder Mega 2560 läuft.
Auf einem Uno oder Nano funktioniert das nicht mit PWM und diesen PIN's.
Wenn ich keinen Fehler drin habe, müssten sich die Räder einmal vorwärts drehen.
Und zwar von Stillstand bis zur Maximaldrehzahl und wieder bis zum Stillstand.
Dann einmal rückwärts.
Einmal Gegenläufig für drehen auf der Stelle, linksrum und einmal rechtsrum.
genauso ist es, mega 2560 und läuft wie von dir vorhergesagt. Jetzt kann ich es anhand eines funktionierendes codes ausgiebig testen... Danke noch einmal allen beteiligten...
i_make_it
21.02.2018, 11:34
Wenn ich heute abend zuhause bin fange ich mal einen etwas anderen Sketch an, der hat dann nur eine Funktion mit 4 Parametern.
Da kannst Du dann alleine durch die Parameter alles gestalten.
Also Stop, Vorwärts, Rückwärts, auf der Stelle Links und Rechts drehen, aber auch Kurvenfahrt oder drehen über ein stehendes Rad.
Das wäre dann die flexibelste Variante.
Dadurch das es einzelne Parameter sind, kann man dann auch später problemlos eine Geschwindigkeits oder Positionsregelung integrieren (Odometrie).
In der momentanen Variante mit dem einem Parameter ist das unschön, da müsste man die Regelung in jede einzelne Fahrfunktionen reinlegen.
Das würde später mal ein riesen Code Wust ergeben.
i_make_it
21.02.2018, 18:52
So, hier die Fassung mit den vier Parametern.
/*
PWM Pins
Nano: 3; 5; 6; 9; 10; 11
Uno: 3; 5; 6; 9; 10; 11
Due: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
Mega 2560: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
*/
int IN1 = 9;
int IN2 = 8;
int IN3 = 7;
int IN4 = 6;
int speedl1;
int speedl2;
int speedr1;
int speedr2;
int loopcount;
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
void loop()
{
// Vorwärts
for (int loopcount=0; loopcount <=255; loopcount++){
speedl1 = loopcount;
speedl2 = 0;
speedr1 = loopcount;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
for (int loopcount=255; loopcount >=0; loopcount--){
speedl1 = loopcount;
speedl2 = 0;
speedr1 = loopcount;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
// Rückwärts
for (int loopcount=0; loopcount <=255; loopcount++){
speedl1 = 0;
speedl2 = loopcount;
speedr1 = 0;
speedr2 = loopcount;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
for (int loopcount=255; loopcount >=0; loopcount--){
speedl1 = 0;
speedl2 = loopcount;
speedr1 = 0;
speedr2 = loopcount;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
// Links Drehen über Mittelpunkt
for (int loopcount=0; loopcount <=255; loopcount++){
speedl1 = loopcount;
speedl2 = 0;
speedr1 = (255 - loopcount);
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
for (int loopcount=255; loopcount >=0; loopcount--){
speedl1 = loopcount;
speedl2 = 0;
speedr1 = (255 - loopcount);
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
// Rechts Drehen über Mittelpunkt
for (int loopcount=0; loopcount <=255; loopcount++){
speedl1 = (255 - loopcount);
speedl2 = 0;
speedr1 = loopcount;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
for (int loopcount=255; loopcount >=0; loopcount--){
speedl1 = (255 - loopcount);
speedl2 = 0;
speedr1 = loopcount;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
// Links Drehen über linkes Rad
for (int loopcount=0; loopcount <=255; loopcount++){
speedl1 = loopcount;
speedl2 = 0;
speedr1 = 0;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
for (int loopcount=255; loopcount >=0; loopcount--){
speedl1 = loopcount;
speedl2 = 0;
speedr1 = 0;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
// Rechts Drehen über rechtes Rad
for (int loopcount=0; loopcount <=255; loopcount++){
speedl1 = 0;
speedl2 = 0;
speedr1 = loopcount;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
for (int loopcount=255; loopcount >=0; loopcount--){
speedl1 = 0;
speedl2 = 0;
speedr1 = loopcount;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
// Vorwärts Kurve Links Radius = Roboterbreite
for (int loopcount=0; loopcount <=127; loopcount++){
speedl1 = (loopcount * 2);
speedl2 = 0;
speedr1 = loopcount;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
for (int loopcount=127; loopcount >=0; loopcount--){
speedl1 = (loopcount * 2);
speedl2 = 0;
speedr1 = loopcount;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
// Rückwärts Kurve Rechts Radius = Roboterbreite
for (int loopcount=0; loopcount <=127; loopcount++){
speedl1 = 0;
speedl2 = loopcount;
speedr1 = 0;
speedr2 = (loopcount * 2);
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
for (int loopcount=127; loopcount >=0; loopcount--){
speedl1 = 0;
speedl2 = loopcount;
speedr1 = 0;
speedr2 = (loopcount * 2);
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(10);
}
}
void PWMDrive(int speedl1,int speedl2,int speedr1,int speedr2){
analogWrite(IN1, speedl1);
analogWrite(IN2, speedl2);
analogWrite(IN3, speedr1);
analogWrite(IN4, speedr2);
}
@i_make_it,
danke für den code, die demo funktioniert gut...
werde jetzt versuchen die hardware hier (https://www.roboternetz.de/community/threads/71450-self_balancierer) einzubauen und den code entsprechend anzupassen. Hiermit (https://www.ebay.de/itm/TB6612-PCA9685-Motor-Stepper-Servo-Robot-Shield-for-Arduino-I2C-V2-PWM-Driver-/162707139765?hash=item25e219ecb5) ging es nicht gut, zumindest nicht gut genug...
i_make_it
22.02.2018, 11:53
Freut mich zu hören.
Dadurch das da jetzt 4 Parameter sind, kannst Du falls der Gradeauslauf, wegen Toleranzen in den Motoren nicht stimmt (fährt eine leichte Kurve) eine Koriktur für Links oder Rechts einbauen.
Oder noch besser, anhand von Odometrie einen Korrekturwert errechnen und alles in der Regelung verarbeiten.
Auch kannst Du , bei entsprechenden Sensoren z.B. bei mehr als 2m Platz nach vorne auf Maximalgeschwindigkeit gehen und wenn es enger wird z.B. bei unter 1,5m auf 75% bei unter1m auf 50% und bei unter 0,5m auf 25% gehen. Und wenn er z.B schräg auf eine Wand fährt, braucht man nicht auf der Stelle zu drehen, sondern kann, wenn man z.B. Maximalgeschwindigkeit mit 230 definiert, das Rad auf dessen Seite ein Sensor den kürzerne Abstand zur Wand misst, die Geschwindigkeit erhöhen, so das er parallel zur Wand fährt.
Sprich man kann das ganze Fahrverhalten später viel dynamischer und flüssiger gestalten als es bei dem üblichen Beispielcode ist, wo er immer anhält und dreht oder gar anhält, zurücksetzt und dann dreht.
Aber erstmal ist es die Luft nach oben für viel später um sowas ohne komplette Neuprogrammierung einbauen zu können.
Stopp, hatte ich in der Demo weggelassen, da man dazu ja einfach alle nur 4 Parameter auf 0 setzen muß.
Falls es von Interesse ist, heute morgen habe ich die Schaltpläne für die Sensoren meines aktuellen Projektes hochgeladen.
https://www.roboternetz.de/community/threads/68437-Vorstellung-eines-aktuellen-kleinen-Weihnachtsurlaub-Projekts-(ab-22-12-)/page3?p=642759&viewfull=1#post642759
Das hat jetzt 2 Jahre auf Eis gelegen, bis ich mir Weihnachten mal alle Schmierzettel angesehen habe und zumindest für die HW das meiste riengezeichnet habe.
(Es fehlen noch die Sharp Sensoren für Abgründe und als Nahbereichs Distanzsensoren)
PS da mein aktuelles Projet für meine Großneffen geplant war, ist das nicht so ambitioniert wie Dein Balancer.
Bei mir soll der am Ende erst mal nur in alle Räume fahren und dort Helligkeit, Luftdruck, Luftfeuchte und Temperatur messen und mit einem Zeitstempel versehen, abspeichern. Das dann aber so ungefähr alle Stunde einmal. und wenn die Wohnungstür offensteht, darf er im Treppenhaus halt nicht die Treppe runterfahren sondern soll den Abgrund erkennen und wieder rein kommen.
Übrigens bin ich selbst kein Fan von Shields, da man da oft nur dem folgen kann was sich der Shieldentwickler gedacht hat. und einem manschmal was verbaut wird.
Für meine Arduino Nanos habe ich mir nur ein Breakout Board geholt und arbeite ansonsten viel mit Steckbrettern.
Da ich in dem aktuellen Projekt 5 Interrupteingänge benötige, stören Shields auch, wenn ich mit attachedinterrupt() eine doch recht individuelle PIN Konfiguration einstelle.
Wenn es geht, verpass Deinem Balancer doch mal vorne und hinten Stützräder, so das er nicht mehr als 10° kippen kann. Wenn er es dann schafft sich wiederholt auszubalancieren, dürfte die Regelung passen.
Ggf. kann es aber auch sein, das Deine Motoren nicht die Reserven haben um genug Dynamik für die Regelung zu entwickeln.
Ich habe auch 2 von den Sets hier liegen, bin aber noch nicht dazu gekommen damit zu basteln. Kann also nichts über deren Leistungsfähigkeit sagen.
ich verwende fast ausschliesslich die TT-getriebemotoren, als verteiler meistens diese prototypeboards hier:
33285
mit den steckbretteren habe ich eher schlechte erfahrungen, da weiss man nie, hat er nun kontakt oder nicht?
@i_make_it:
alle beispiele in Deiner demo sind als for-schleife ausgelegt. Warum laufen die motoren hier z.b. in der loop aufgerufen, ohne for schleife nicht?
void vorwaerts()
{
speedl1 = 255;
speedl2 = 0;
speedr1 = 255;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(500);
Serial.println("vorwärts");
}
void rueckwaerts()
{
speedl1 = 0;
speedl2 = 255;
speedr1 = 0;
speedr2 = 255;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(500);
Serial.println("rückwärts");
}
zuerst dachte ich es liegt an zu kleinem delay, das ist es aber nicht :-(
das ist der aufruf in der loop:
void loop()
{
vorwaerts();
//delay(500);
//delay(500);
rueckwaerts();
//delay(500);
}
jetzt wirds aber noch geheimnisvoller: solange das usb kabel zum pc angeschlossen ist läufts, ziehe ich es ab nicht mehr. Die akkuspannung (6xAA) liegt bei 7,3V
i_make_it
01.03.2018, 18:08
Die For Schleifen habe ich nur zum Rampen von 0 auf 255 und zurück genutzt.
Man kann natürlich auch vor dem Aufruf feste Werte eingeben.
Wenn man keinen Entscheidungsbaum hat kann man ein festes Fahrprogramm mit delay() schreiben (wodurch man aber nichts anderes merh machen kann).
Üblicherweise würde man (nicht bei Deinem Balancer) Bumper auswerten für STOP und dann auswerten welcher Bumper ausgelöst wurde und entsprechend eine gewisse Strecke oder Zeit nach hinten fahren und dann auf der Stelle drehen um die Ausrichtung weg vom Hinderniss zu verändern.
Bei den Fernsensoren würde man z.B.:
bei einem Hinderniss vorne Rechts mit Abstand < 10cm den Linken Motor auf 50 drosseln und den rechts auf 230 lassen. (231 bis 255 sind Regelreserve).
Bei einem Hinderniss vorne Rechts mit Abstand < 20cm den Linken Motor auf 90 drosseln und den rechts auf 230 lassen.
Bei einem Hinderniss vorne Rechts mit Abstand < 30cm den Linken Motor auf 130 drosseln und den rechts auf 230 lassen.
Bei einem Hinderniss vorne Rechts mit Abstand < 40cm den Linken Motor auf 170 drosseln und den rechts auf 230 lassen.
Bei einem Hinderniss vorne Rechts mit Abstand < 50cm den Linken Motor auf 200 drosseln und den rechts auf 230 lassen.
Bei einem Hinderniss vorne Rechts mit Abstand >= 50cm den Linken Motor auf 230 lassen und den rechts auf 230 lassen.
Das selbe noch für links und man hat ein relativ flüssiges Fahren, bei dem der Roboter Annäherungen unter 50cm an erkannte Hindernisse versucht zu vermeiden und bei Unterschreitung immer stärker gegenlenkt ohne zu langsam zu werden.
Delay() sollte man im fertigen Program vermeiden.
An dem Rechner hier habe ich keine Arduino IDE, der Code ist rein im Notepad geschrieben, ich kann also nicht sicher sagen ob er fehlerfrei ist.
Er sollte die Buildin LED blinken lassen und 1 Sekunde vorwärts fahen mit blinkender LED.
Dann 1 Sekunde rückwärts fahren mit delay(), wodurch die LED nicht blinken kann.
Dann 1 Sekunde auf der Stelle rechts drehen mit blinkender LED und 1 Sekunde ein enge Kurve nach links fahren mit delay(), wodurch die LED wieder nicht blinken kann.
/*
PWM Pins
Nano: 3; 5; 6; 9; 10; 11
Uno: 3; 5; 6; 9; 10; 11
Due: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
Mega 2560: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
*/
int IN1 = 9;
int IN2 = 8;
int IN3 = 7;
int IN4 = 6;
int speedl1;
int speedl2;
int speedr1;
int speedr2;
unsigned long prev1micros = 0;
const long waittime1 = 1000;
int togglestate1 = LOW;
unsigned long prev2micros = 0;
const long waittime2 = 100;
int togglestate2 = LOW;
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
//Blinken der Build in LED
unsigned long cur2micros = millis();
if (cur2micros - prev2micros >= waittime2) {
prev2micros = cur2micros;
if (togglestate2 == LOW){
togglestate2 = HIGH;
digitalWrite(LED_BUILTIN, HIGH);
}else{
togglestate2 = LOW;
digitalWrite(LED_BUILTIN, LOW);
}
}
// Warten ohne delay
unsigned long cur1micros = millis();
if (togglestate1 == LOW){
if (cur1micros - prev1micros >= waittime1) {
prev1micros = cur1micros;
// rückwärts mit delay
speedl1 = 0;
speedl2 = 200;
speedr1 = 0;
speedr2 = 200;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(1000);
togglestate1 = HIGH;
}else{
// vorwärts ohne Delay (LED Blinkt)
speedl1 = 200;
speedl2 = 0;
speedr1 = 200;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
}
}
if (togglestate1 == LOW){
if (cur1micros - prev1micros >= waittime1) {
prev1micros = cur1micros;
// linksrum mit delay
speedl1 = 50;
speedl2 = 0;
speedr1 = 200;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(1000);
togglestate1 = LOW;
}else{
// Rechts drehen ohne Delay (LED blinkt)
speedl1 = 200;
speedl2 = 0;
speedr1 = 0;
speedr2 = 200;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
}
}
}
void PWMDrive(int speedl1,int speedl2,int speedr1,int speedr2){
analogWrite(IN1, speedl1);
analogWrite(IN2, speedl2);
analogWrite(IN3, speedr1);
analogWrite(IN4, speedr2);
}
Update: Fehler im Code beseitigt.
i_make_it
02.03.2018, 19:06
jetzt wirds aber noch geheimnisvoller: solange das usb kabel zum pc angeschlossen ist läufts, ziehe ich es ab nicht mehr. Die akkuspannung (6xAA) liegt bei 7,3V
Du hast den Akku über den VIN Pin oder den Klinkenstecker angeschlossen?
Der Code den Du in Deinem letzten Post hast, Da ist keine Funktion PWMDrive zu sehen. Hast Du Die nur nicht dargestellt, oder ist die auch nicht im Sketch?
Denn diese Funktion wird ja in den Funktionen vorwaerts und rueckwaerts aufgerufen.
Du hast den Akku über den VIN Pin oder den Klinkenstecker angeschlossen?
ja, über Vin
Der Code den Du in Deinem letzten Post hast, Da ist keine Funktion PWMDrive zu sehen. Hast Du Die nur nicht dargestellt, oder ist die auch nicht im Sketch?
Denn diese Funktion wird ja in den Funktionen vorwaerts und rueckwaerts aufgerufen.
ich habe jetzt hier noch einmal die geänderte "demo" version.
/*
PWM Pins
Nano: 3; 5; 6; 9; 10; 11
Uno: 3; 5; 6; 9; 10; 11
Due: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
Mega 2560: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
*/
int IN1 = 8;//9
int IN2 = 9;//8
int IN3 = 10;//7
int IN4 = 11;//6
int speedl1;
int speedl2;
int speedr1;
int speedr2;
int loopcount;
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
Serial.begin(115200);
Serial1.begin(115200);
}
void loop()
{
/*
vorwaerts_rampe_hoch();
delay(500);
vorwaerts_rampe_runter();
delay(500);
rueckwaerts_rampe_hoch();
delay(500);
rueckwaerts_rampe_runter();
delay(500);
*/
vorwaerts();
//delay(500);
//delay(500);
rueckwaerts();
//delay(500);
}
void vorwaerts()//geht nicht
{
speedl1 = 255;
speedl2 = 0;
speedr1 = 255;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(500);
Serial.println("vorwärts");
Serial1.println("vorwärts");
}
void rueckwaerts()//geht nicht
{
speedl1 = 0;
speedl2 = 255;
speedr1 = 0;
speedr2 = 255;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(500);
Serial.println("rückwärts");
Serial1.println("rückwärts");
}
void PWMDrive(int speedl1, int speedl2, int speedr1, int speedr2)
{
analogWrite(IN1, speedl1);
analogWrite(IN2, speedl2);
analogWrite(IN3, speedr1);
analogWrite(IN4, speedr2);
}
in den funktionen vorwaerts() und rueckwaerts() habe ich nur die schleife rausgenommen und die werte direkt eingesetzt. Noch einmal ausprobiert bei gleicher hardware: Deine demoversion geht, die von mir korrigierte (ohne FOR schleife) nur bei eingestecktem USB kabel. Man spürt nur am auf dem motor aufgelegtem finger, dass der motor alle halbe sekunde kurz tickt...
i_make_it
04.03.2018, 06:57
bei gleicher hardware:
Deine demoversion geht, die von mir korrigierte (ohne FOR schleife) nur bei eingestecktem USB kabel
Ich vermute mal, das der Anlaufstrom der Motoren die Spannung einbrechen lässt.
Mit USB hast Du ein halbes Ampere mehr.
Beim Rampe mit den For Schleifen, wird die Drehzahl ja in diskreten Schritten erhöht, was den Motorstrom zeitlich entzerrt.
Bei einem direkten Sprung von 0 auf 255 ziehen die Motoren halt Maximalstrom.
Da kann man mal Stützkondensatoren in der Stromversorgung des Motorreglers versuchen oder halt mehrere Fahrstufen.
Man spürt nur am auf dem motor aufgelegtem finger, dass der motor alle halbe sekunde kurz tickt...
Das deutet allerdings eher auf den Effekt durch EIN (1) delay(500) hin.
Zum Testen, kannst Du mal diesen Code in void setup() einfügen
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
delay(800);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
Das sollte ein Count Down Blinken der Build in LED verursachen, einmalig wenn der µC startet.
Sollte die LED nach dem Rucken der Motoren wieder den Count Down blinken, dann bricht die Spanung ein und der µC geht durch den "brown out" in Reset.
Zweite Maßnahme ist den Motoren statt 255 erst mal 10 als wert fürs PWM zu geben.
Der folgene Code führt den Count Down Blink durch, rampt dann Vorwärts bis 250 hoch, stoppt und geht dann von 0 auf 255 in Rückwärts.
Das sollte ggf. schon zeigen an welcher Stelle es hängt.
// PWM Pins Due: 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13
int IN1 = 8;//9
int IN2 = 9;//8
int IN3 = 10;//7
int IN4 = 11;//6
int speedl1;
int speedl2;
int speedr1;
int speedr2;
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
delay(800);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
}
void loop()
{
speedl1 = 20;
speedl2 = 0;
speedr1 = 20;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(50);
speedl1 = 40;
speedl2 = 0;
speedr1 = 40;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(50);
speedl1 = 80;
speedl2 = 0;
speedr1 = 80;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(50);
speedl1 = 120;
speedl2 = 0;
speedr1 = 120;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(50);
speedl1 = 160;
speedl2 = 0;
speedr1 = 160;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(50);
speedl1 = 200;
speedl2 = 0;
speedr1 = 200;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(50);
speedl1 = 250;
speedl2 = 0;
speedr1 = 250;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(50);
speedl1 = 0;
speedl2 = 0;
speedr1 = 0;
speedr2 = 0;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(50);
speedl1 = 0;
speedl2 = 255;
speedr1 = 0;
speedr2 = 255;
PWMDrive(speedl1, speedl2, speedr1, speedr2);
delay(350);
}
void PWMDrive(int speedl1, int speedl2, int speedr1, int speedr2)
{
analogWrite(IN1, speedl1);
analogWrite(IN2, speedl2);
analogWrite(IN3, speedr1);
analogWrite(IN4, speedr2);
}
das blinken der eingebauten LED zeigt eindeutig, dass die motoren, bzw. der strom den sie ziehen den arduino zum reset zwingen...
danke erstmal, ich habe jetzt genügend "stoff" zum üben und testen...
i_make_it
04.03.2018, 10:34
Eventuell mal zwichen Akku und VIN eine kleine Schaltung einfügen. Direkt nach der Aufteilung (Steuerungsversorgung/Motorenversorgung) eine Diode (Germanium wegen dem kleineren Spannungasabfall) in die Steuerungsversorgung und danach einen Stützkondensator. Bei der Motorversorgung auch einen Stützkondensator rein.
Beide Kondensatoren werden durch den Akku geladen. Ziehen die Mororen zu viel Strom, kann der Stützkondensator im Motorzweig kurzfristig den Akku unterstützen.
Reicht das nicht, verhindert die Diode einen Stromfluß von der Steuerungsseite zur Motorseite und der Stützkondensator dort kann kurzfristig den Arduino versorgen.
Das ist aber nur für wirklich kurze Stromspitzen gut.
Ein Step Up/Down Regler, der bei schwankender Eingangsspannung direkt 5V für den Arduino liefert Zusammen mit einem Stützkondensator ist insgesammt vermutlich besser.
Wenn ich mich richtig erinnere ist hinter VIN ein Längsregler, der benötigt typisch mindestens 1,5V mehr Eingangsspannung als er liefern kann.
Da VIN mit 7-12V angegeben ist, hat dein Akku nur 0,3 V (oder maximal 0,8V) die er einbrechen kann bevor der Arduino den Saft abgedreht bekommt.
Bei einem Regler der auch mit deutlich weniger Eingangsspannung auskommt, wird auch die Einsatzzeit zwichen zwei Ladervorgängen erhöht, da der Akku tiefer entladen werden kann bevor die Spannung nicht mehr reicht.
bei meinen robotern geht die spannungsversogung vom akku zu einem verteiler und von dort zu dem motorregler, zum arduino und zu einem stepp-up-converter über den alle 5V verbraucher versorgt werden. Ein stepp-up in den strang zum arduino würde das problem beheben - meinst du das so?
edit:
ich habe jetzt den arduino über 5V und GND auch an den 5V step-up converter angeschlossen, jetzt laufen die motoren auch ohne rampe, also direkt bei 255 an, ohne den arduino zu resetten...
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.