PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : outdoor I



Seiten : [1] 2 3

inka
21.10.2019, 11:18
hallo allerseits,

bin beim leistungsfähigerem RP6 (https://www.roboternetz.de/community/threads/73437-Leistungsf%C3%A4higerer-Nachfolger-f%C3%BCr-RP6) ausgestiegen und habe mir die zeit genommen um eine vernünftige, preiswerte mechanik zu entwerfen und zu bauen. Hier (https://youtu.be/FuLFUji4FiM) der erste überblick...

Die grundfläche entspricht in etwa einem DIN A4 blatt, antreiben sollen es vier NEMA17 schrittmotoren, akku 12V 9.800mAh, steuerung mit einem Arduino mega 2560, kommunikation nach außen mit einem ESP32, intern über I2C.

Die kosten bewegen sich bei ca. 200 bis 220€, je nach dem was man an sensoren noch verbauen will. Habe aber nicht jede schraube und stück litze mitgezählt....

Kann hier gerne auch die auflistung der teile und die bezugsquellen posten. Der roboter fährt noch nicht, wie man in dem video sehen kann - der accu fehlt noch. Auch die verdrahtung muss noch ein bischen optimiert werden, an der software schraube ich noch...

Es würde mich freuen, wenn sich jemand findet der hier mitentwickelt...

Moppi
21.10.2019, 11:25
Sieht sehr solide aus, find ich gut!

Zum mitentwickeln müsste man das Teil dann schon mal so weit nachbauen - oder dachtest Du an was anderes?
Eine Stückliste und wie man es zusammenbaut wäre daher schon auf jeden Fall wichtig.

Ansonsten, wenn Du Hilfe brauchst, solltest Du sie hier bekommen.


MfG

inka
21.10.2019, 13:53
als anhang die liste der teile, die ich verwendet habe...

Die abmessungen ergaben sich im wesentlichen aus den makerbeamprofilen:

- die längsprofile haben die originallänge von 300mm
- die querprofile sind 230mm lang, die höhe ergibt sich aus dem rest...

für die befestigung der motortreiber habe ich teile gedruckt, es sind insgesamt drei pro treiber, mir ist nichts einfacheres eingefallen :-(

die adapter zwischen dem stepper und den rädern sind auch druckteile, bei bedarf kann ich die files zur verfügung stellen...

ansonsten - bei bedarf - fragen...

ansonsten - mitentwickeln - dachte ich daran meine entwicklung hier einfach mal zur verfügung zu stellen und darüber diskutieren, was man evtl. noch besser machen kann. Aber es wäre natürlich toll, wenn es mehrere leute gäbe die die gleiche hardware hätten...

HaWe
21.10.2019, 14:41
ich könnte mir vorstellen, dass dein Modell mit deiner Fahrgestell-Geometrie auf Teppich, auf Rasen oder im Sand nicht ohne weiteres auf der Stelle drehen kann (und auch sonst nicht in engen Kurven), insb. wenn er mit 10kg++ beladen ist?

inka
21.10.2019, 15:07
ich könnte mir vorstellen (als ausbaustufe) zwischen die schrittmotor-winkel und den rahmen so etwas (https://www.ebay.de/itm/Druckkugellager-Drehlager-Flanschlager-Lager-57-x-57-Drehteller-Neue-Ausf%C3%BChrung/290675182276?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2060353.m1438.l2649) einzusetzen und die räder dann mit einem servo auszurichten. Ich wolte den roboter aber weder an die Ostsee mitnehmen, noch mit 10kg++ belasten. Das ginge beides natürlich nicht. Eigentlich ist mein ziel mit dem roboter feinere aufgaben im gelände zu erledigen. Einen sixpack Jever oder Radeberger müsste aber zu schaffen sein :-)

HaWe
21.10.2019, 15:36
es funktioniert grundsätzlich mit dem Drehen besser, wenn die Radachsen länger sind als der Abstand der Räder vorn-hinten!

inka
21.10.2019, 15:56
istmaße:

radachse (über alles gemessen) = 370mm

radabstand (mitte - mitte) = 270mm

HaWe
21.10.2019, 16:03
das hätte ich jetzt nicht aus dem Video heraus lesen können, aber wenn die Radachse (bis Reifen-Mitte) 10cm (ca. 1/3) länger ist als der Radabstand (Achse-Achse), müsste es tatsächlich so gehen!

inka
21.10.2019, 17:17
ok, also radabstand (mitte-mitte) zu achslänge (mitte reifen) ist 270/330. Die achslänge wird ja auch durch die adapter zwischen rad und schrittmotor mit-bestimmt, die lassen sich im notfall auch noch etwas länger drucken...

- - - Aktualisiert - - -

Moppi
21.10.2019, 19:12
Die Batterie beschäftigt mich etwas. Der Spitzenstrom ist i.O.. Aber wenn Dauerstrom max. 5A sind, dann kann man die Leistung für die Motoren wohl nicht ausnutzen. Die brauchen ca. 1.5 bis 1.7A pro Motor, bei voller Leistung. Hier könnte man 2 Packs verbauen, falls es nicht ausreicht. Zunächst kann man aber über die Treiber den Strom auf 1A pro Motor drosseln. Muss man dann schauen, wie es um die Kraft bestellt ist. Evtl. an die Kühlkörper für die Treiber denken (z.B.: https://www.amazon.de/gp/product/B07JVNJ36J/ref=ppx_yo_dt_b_asin_title_o07_s01?ie=UTF8&psc=1)

Es gibt auch noch andere Treiber, die mehr Leistung zur Verfügung stellen (8825): https://www.amazon.de/AZDelivery-DRV8825-Schrittmotor-Treiber-Modul-K%C3%BChlk%C3%B6rper-CNC-Shield/dp/B07YWV6W4W/ref=sr_1_7?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3 %91&keywords=DRV8825&qid=1571684542&s=industrial&sr=1-7&th=1



MfG

inka
22.10.2019, 08:06
die anderen treiber haben die gleichen abmessungen und die gleichen anschlüsse, wie mir scheint. Also auch zum späteren zeitpunkt einsetzbar, denke ich. Aber danke für die ausführungen :-)

Ein zweiter akku hätte natürlich auch platz im gehäuse...

Was mich aber im moment beschäftigt sind die stepper und treiber ( A4988 ) und deren behandlung im sketch:

den ersten code habe ich mit der accelstepper lib geschrieben, komme damit aber nicht so gut zurecht



// https://www.makerguides.com/a4988-stepper-motor-driver-arduino-tutorial/

/*Example sketch to control a stepper motor with A4988 stepper motor driver, AccelStepper library and Arduino:
acceleration and deceleration. More info: https://www.makerguides.com */
// Include the AccelStepper library:
#include <AccelStepper.h>


uint8_t idx;

enum stepper_e
{ stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX };


AccelStepper stepper[stepper_MAX]
{
AccelStepper(1, 2, 3),
AccelStepper(1, 4, 5),
AccelStepper(1, 6, 7),
AccelStepper(1, 8, 9)
};

void setup()
{

Serial.begin(115200);

Serial.println("code---- /home/georg/Arduino/outdoor_robo/stepper/test_vier_stepper/vier_stepper_acceleration_and_decceleration_1");

for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].setMaxSpeed(400);
stepper[idx].setAcceleration(30);
// stepper[idx].setDirection(CCW);
// stepper[idx].rotate(1);


}
}


void loop()
{

vorwaerts();

delay(1000);

rueckwaerts();

delay(1000);
}

void vorwaerts(void)
{
// rotate_li = true;

for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].moveTo(600);
stepper[idx].runToPosition();
stepper[idx].setSpeed(300);
// stepper[idx].rotate(1);
}

/* for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].moveTo(600);
stepper[idx].runToPosition();
// stepper[idx].setDirection(CW);
// stepper[idx].rotate(1);
}*/
}

void rueckwaerts(void)
{
// rotate_li = true;

for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].moveTo(0);
stepper[idx].runToPosition();
stepper[idx].setSpeed(300);
// stepper[idx].rotate(1);
}

/* for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].moveTo(0);
stepper[idx].runToPosition();
// stepper[idx].setDirection(CW);
// stepper[idx].rotate(1);
}*/
}


Vorher verwendete ich die customstepper lib, allerdings mit dem stepper_28BYJ_48 und ULN2003 treiber. Geht die customstepper auch mit den NEMA17 schrittmotoren und den A4988 treibern? Da gibt es ja nur die pinns "step" und "dir". Wie mache ich das? Zum beispiel die richtungsangabe (CW / CCW). Da finde ich den zugang dazu irgendwie nicht:-(

Moppi
22.10.2019, 08:41
die anderen treiber haben die gleichen abmessungen und die gleichen anschlüsse, wie mir scheint. Also auch zum späteren zeitpunkt einsetzbar, denke ich. Aber danke für die ausführungen :-)

Deswegen hatte ich das erwähnt, falls Du später evtl. ein Problem haben solltest, dass Du gleich einen Ausweg parat hast. Allerdings ist es so, dass meine NEMA17, die ich zuhause habe (heute Morgen nochmals ins Datenblatt geschaut) 1.5A Nennstrom haben, bei 2.xV (2.5 .. 2.8V). Die Spannung am Treiber soll möglichst hoch sein, damit bei schnellen Umdrehungen viel Kraft aufgebaut werden kann. 24V wären da evtl. überlegenswert.

Um nochmal einen Tip zu der Treibersteuerung zu geben:
Die ist wirklich sehr, sehr einfach. Einfach die Steuerpins eines Treibers mit Pins vom Arduino verbinden und Quellen zur Ansteuerung durchlesen und programmieren. Ich würde keine LIB von jemand anderem verwenden. Ich hatte Dir ja schon Quellen geschickt.
Step und Dir brauchst Du ja auch nur, um einen Schritt (Step) in die eingestellte Richtung (Dir) zu machen. Ansonsten kannst Du noch Vollschritt, Halbschritt, 16tel Schritt etc. über die Steuerpins einstellen (damit kann mal herumprobieren - ist recht interessant aber nicht "überlebenswichtig").
Ich sehe gerade: runToPosition();
Ein Stepper ist ja kein Servo. Eine bestimmte Position anzufahren, ist mit einem Stepper nur möglich, wenn Du die Ausgangslage kennst. Der kann soundsoviele Schritte pro Umdrehung machen (steht in der Doku wieviele), das ist alles.

Vieles oder einiges wirst Du schon wissen ... nur nochmal so erwähnt.

Ich habe mir nochmals Mühe gemacht und die essentiellen Sachen zur Steppersteuerung, mit dem 4988, aus meinem Blog kopiert, um zu ermutigen:



//-----------------------------------------------------------------------------
//A4988
#define Dir 8
#define Step 9
#define Sleep 10
#define MS3 11
#define MS2 12
#define MS1 13
//-----------------------------------------------------------------------------


//Ausgänge für Motortreiber
pinMode(Dir, OUTPUT);
pinMode(Step, OUTPUT);
pinMode(Sleep, OUTPUT);
pinMode(MS3, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(MS1, OUTPUT);

//-----------------------------------------------------------------------------


//Den Schrittmodus am Motortreiber einstellen:
//-----------------------------------------------------------------------------
void StepMode(byte mode){
switch(mode){
case 0:
digitalWrite(MS1, LOW);
digitalWrite(MS2, LOW);
digitalWrite(MS3, LOW);
break;
case 1:
digitalWrite(MS1, HIGH);
digitalWrite(MS2, LOW);
digitalWrite(MS3, LOW);
break;
case 2:
digitalWrite(MS1, LOW);
digitalWrite(MS2, HIGH);
digitalWrite(MS3, LOW);
break;
case 3:
digitalWrite(MS1, HIGH);
digitalWrite(MS2, HIGH);
digitalWrite(MS3, LOW);
break;
case 4:
digitalWrite(MS1, HIGH);
digitalWrite(MS2, HIGH);
digitalWrite(MS3, HIGH);
}
}
//-----------------------------------------------------------------------------

//einen Schritt machen:
digitalWrite(Step, HIGH);
delayMicroseconds(i); //i bestimmt die Pause zwischen den Signalflanken und damit die Geschwindigkeit (abhängig vom eingestellten Step-Mode)
digitalWrite(Step, LOW);
delayMicroseconds(i);


//-----------------------------------------------------------------------------
//Richtung bestimmen:


digitalWrite(Dir,LOW); //digitalWrite(Dir,HIGH);




//-----------------------------------------------------------------------------
//Die Motor Start-/Stopfunktionen. Wie man sieht, wird hier nur der Treiber schlafen geschickt; damit wird der Motorstrom abgeschaltet.
//Wird der Motor hier "gestartet", wird er unter Strom gesetzt, dreht sich aber noch nicht.


void power_a4988_disable(){
digitalWrite(Sleep, LOW);
}
void power_a4988_enable(){
digitalWrite(Sleep, HIGH);
}





MfG

HaWe
22.10.2019, 08:57
auch wegen Steuerung und Odometriefähigkeit halte ich Stepper für den Antrieb für suboptimal, denn zusätzlich zum Schlupf kommen auch noch verschluckte Steps und passive Verdrehungen unter Last als Problem dazu, sodass man die aktuelle Drehposition noch unzuverlässiger ermitteln kann als bei DC-Motoren mit Rotationsencodern.

Klebwax
22.10.2019, 09:35
Geht die customstepper auch mit den NEMA17 schrittmotoren und den A4988 treibern?

Die Frage lässt sich so nicht beantworten. NEMA17 beschreibt nur das Flanschmass des Motors. Über die elektrischen Eigenschaften wie Strom, Spannung, Leistung Uni oder Bipolar sagt der NEMA-Wert nichts aus. Nema 17 bedeutet der Motor hat eine Front mit 42x42mm und die Befestigungslöcher haben einen Abstand von 31mm. Das hat mit dem Treiber alles nichts zu tun.


Da gibt es ja nur die pinns "step" und "dir". Wie mache ich das? Zum beispiel die richtungsangabe (CW / CCW). Da finde ich den zugang dazu irgendwie nicht:-(

Ist doch recht einfach. Für jeden Puls am step-Eingang dreht der Motor um einen Schritt. Und in welcher Richtung bestimmt das direction, das Richtungs-Signal. Dabei kann der Motor ClockWise also rechtsrum wie die Uhr oder CounterClockWise, linksrum drehen. Amis kürzen das halt gern ab.

MfG Klebwax

inka
22.10.2019, 15:23
Die ist wirklich sehr, sehr einfach. Einfach die Steuerpins eines Treibers mit Pins vom Arduino verbinden und Quellen zur Ansteuerung durchlesen und programmieren. Ich würde keine LIB von jemand anderem verwenden. Ich hatte Dir ja schon Quellen geschickt.


gutes beispiel aus Deinem blog, danke für deine mühe, ich habe es aber rein zufällig entdeckt, weil ich selten nach hinten blätere, so entgehen einem die nachträglichen editierungen... Wäre schade drum gewesen...
Eine durchaus interessante möglichkeit der direkten programmierung ohne eine lib. Ich finde das aber nicht unbedingt übersichtlicher als eine lib bzw. die befehle aus einer lib:


void vorwaerts(void)
{
for (idx = stepper_VL; idx < stepper_VR; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(-100);
}

for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(100);
}
}

hier sehe ich spätestens auf den zweiten blick was da passiert und muss mich nicht unbedingt mit der "hintergrundaktivität auf bitebene" belasten...

Moppi
22.10.2019, 15:37
Ist kein Problem! :)

Jeder macht es so, wie er am besten damit zurecht kommt.


MfG

inka
22.10.2019, 16:22
inzwischen drehen die stepper brav alle gleichzeitig und gleichmässig vor sich hin... Jetzt habe ich das teil hochgebockt und betreibe es mit einem steckernetzteil, weil ja der akku noch fehlt...
Wie war das noch mal mit der strombegrenzung an den treibern?

Moppi
22.10.2019, 16:24
an dem kleinen Drehpoti drehen!

Nach einer Richtung bleiben die Stepper stehen (weil Strom zu niedrig wird), nach der andern Richtung gedreht gelangt ein höherer Strom zum Stepper (max 1.5 bis 1.7 A oder mehr - kommt auf die Treiberplatine an). Man kann das auch messen/bestimmen, ist aber recht fummelig. Habe ich deshalb nie gemacht, weil auch nicht gebraucht.

Willst Du wissen wie? Schau hier: https://www.derpade.de/3d-drucker-a4988-motortreiber-stromstaerke-einstellen/
Und nochmal mit einem DRV8825: https://www.my-home-fab.de/de/dokumentationen/technische-beschreibungen/drv8825-schrittmotor-strom-einstellen


MfG

inka
22.10.2019, 16:32
Willst Du wissen wie? Schau hier: https://www.derpade.de/3d-drucker-a4988-motortreiber-stromstaerke-einstellen/

das kenne ich, die fummeligen potis auch. Als ich versucht habe daran zu drehen merkte ich nicht mal dass sich was ändert? Ich dachte da gäbe es noch ein softwaremässige möglichkeit um den strom zu begrenzen?

Moppi
22.10.2019, 16:35
Nein, bei den Teilen nicht, da gibts andere Treiber, wo man den Strom digital einstellen kann, sind auch einiges teurer.

Du merkst da so nicht viel, wenn die Last fehlt, musst Du ein Rad festhalten und probieren.

Stell auf Max-Strom ein (Anschlag links oder rechts) damit der Motor den maximalen Strom für jede Wicklung bekommen kann. Je höher dann die "Motor"-Spannung am Treiber, desto "kraftvoller" dreht der Motor auch bei schnelleren Schrittfolgen. So Pi mal Daumen ausgedrückt. Wenn der Schrittmotor sehr schnell sehr warm wird, ist es vielleicht etwas viel des Guten gewesen.

Klebwax
22.10.2019, 17:58
Als ich versucht habe daran zu drehen merkte ich nicht mal dass sich was ändert?

Es wäre sicher hilfreich einige elektrische Daten der Stepper zu kennen. Wie hoch ist die Nennspannung und wie hoch der Strom?

MfG Klebwax

inka
22.10.2019, 18:59
so viel weiss ich von den steppern nicht, die chinesen sind manchmal recht sparsam:

Nema 17 motor 42BYGH 1.5A 38mm 17HS4401. Betrieben hab ich den mit 12V

Moppi
22.10.2019, 19:34
Die Nennspannung soll angeblich 3.6V betragen. Der Verkäufer bei Amazon meint er kann problemlos bei 12V oder 24V mit dem Schrittmotortreiber betrieben werden. Nennstrom soll 1.5A sein. Es gibt denselben Typ 17HS4401, der in Datenblättern mit Rated Current = 1.7A ausgewiesen ist.




MfG

Klebwax
23.10.2019, 08:11
... dem Schrittmotortreiber betrieben ...

Den Treiber gibts nicht. Typisch haben die kleinen Platinchen aus dem 3-D Drucker Umfeld einen A4988 oder einen DRV8825 drauf. Beide steuern den Stepper über den Strom, können 2A oder mehr, passen also. An Spannung verträgt der A4988 35V und der DRV8825 45V. Wenn man ein hohes Drehmoment oder eine hohe Drehzahl braucht, sollte die Differenz zwischen Motornennspannung und Betriebsspannung des Treibers möglichst groß sein, damit der Treiber auch was zu regeln hat. 3,6V Nennspannung zu 12V Treiberversorgung könnte da passen, sind aber eher an der unteren Grenze.

Wenn so ein Motor langsam und ohne Last betrieben wird, läuft der wahrscheinlich auch mit 0,5A oder weniger. Das macht das Einstellen des Stroms schwieriger, da man nur merkt, wenn der Strom zu gering ist.

MfG Klebwax

Moppi
23.10.2019, 08:37
Den Treiber gibts nicht.

Das war bezogen auf den, den Inka hat, o.Ä., mit Stromregelung.


MfG

- - - Aktualisiert - - -

Ich betreibe meine NEMA17 auch nur mit 12V Motorspannung, am Treiber und hatte auch das Gefühl, dass die so noch nicht die volle Leistung erreichen. Aber auch das, was die Motoren bei 12V erreichen brauche ich nicht, für meine Zwecke, nur einen Bruchteil davon.

inka
25.10.2019, 07:22
Ich experimentiere immer noch ohne den akku, also mit einem streckernetzteil. Das handling damit ist warscheinlich schuld daran, dass die dinger bei mir wie die fliegen sterben! Einmal hab ich sogar alle vier auf einmal geschafft, ich weiss nicht wie. Die waren alle schon "richtig " an der seitenwand befestigt, allerdings gab es etwas druck auf den kühlkörper und damit den treiberbaustein. Die waren sachte angeklemmt. Kann das die ursache sein? Wie macht ihr eigentlich die dinger fest?

Moppi
25.10.2019, 07:35
ich habe es so gemacht, ist aber auch nicht richtig fest: https://www.roboternetz.de/community/attachment.php?attachmentid=33857&d=1545060175
Das ist generell irgendwie etwas unglücklich, weil ich auch aufpassen musste, dass der Kühlkörper nicht irgendwelche Überbrückungen erzeugt, was evtl. Kurzschluss auf der Platine bedeuten könnte (der Kühlkörper sollte nicht verrutschen). Ich glaub der liegt bei mir auf dem IC auf und auf den daneben angebrachten SMD-Widerständen, da ist nichts passiert.
Bei mir ist nicht einer kaputt gegangen, obwohl ich immer damit gerechnet habe.
Ich habe die Kühlkörper aber auch aufgebracht, weil ich die Treiber einlöte und so Wärme vom IC-Chip abtransportiert wird, ich wollte die Schädigung beim Löten vermeiden oder verringern.

Wackelkontakt in der provisorischen Stromversorgung sollte vielleicht auch vermieden werden.

Eine Idee wäre auch, einen Aufsatz für die Platine zu drucken (wie eine Klammer die von oben drauf zu setzen geht), wo eine Aussparung für den Kühlkörper drin ist, so dass der dort durchschaut und also nicht verrutschen kann (wenn das Teil jetzt ständig durchgerüttelt wird), wegen der Hitzebeständigkeit aber wohl kein PLA sondern etwas, was erst bei höheren Temperaturen weich wird (PLA bereits ab 50°C).

Meine letzter Einfall: ist die Spannung vom Netzteil genügend geglättet? Nicht das dies der 4988-Platine schadet. Ich arbeite nur mit Akku und habe keinerlei Erwärmung des 4988 (allerdings auch nur geringe Leistungsabnahme bei kurzer Laufzeit bis max. 30sec).
Hast Du einen Kondensator 100/220µF, zwischen Vmot und GND, an der Platine? Wenn nicht, bitte mal anbringen!

Zum Probieren geht auch kurzfristig: Varta longlife MONO-D-Zellen zusammenschalten / löten. Da kommt man i.R. im nächsten Supermarkt dran. Habe ich auch schon gemacht.



MfG

inka
25.10.2019, 08:16
also ob die spannung vom netzteil geglättet ist kann ich nicht sagen, ein handelsübliches steckernetzteil halt. Die treiber sind bei mir mit solchen teilen befestigt:34423

in den seitenteilen ist gewinde, das teil wird von aussen, durch die seitenwand mit 2x M3 angeschraubt. Die zwei schenkel sind kürzer als die platine mit kühlkörper, allerdings wird dadurch druck erzeugt, sodass kontakt zu den drei SMD widerständen besteht - darauf habe ich bisher garnicht geachtet! Wie kann man sowas entwickeln und verkaufen? Gut, china-zeug, aber ist das bei den pololu originalen anders? Allerdings - auf dem kühlkörper ist ja die klebefolie angebracht - ob man die durch das anschrauben überhaupt durchdrücken kann?

Moppi
25.10.2019, 08:53
Die neben dem IC liegenden Bauteile werden teils sehr warm, wenn die mit gekühlt werden ist es gut. Ich habe auch dort keine Kurzschlüsse. Vielleicht haben die das extra so gemacht, weil die Bauteile neben dem IC exakt dieselbe Höhe haben, dass die Teile mit dem Kühlkörper Kontakt bekommen sollen? Wenn eine abziehbare Folie drauf ist, runter machen, darunter ist eine Wärmeleitpaste, sonst wird die Wärme ja nicht abgeleitet, wenn die Schutzfolie drauf bleibt. Manche Kühlkörper haben keine Schutzfolie. Wenn Du Schrauben durch die Platine drehst, könnten die Köpfe auch was überbrücken, das ist alles sehr knapp dort an den Bohrlöchern, mal mit einer Lupe schauen.

Kondensator nicht vergessen.

Wenn Du eine Nahaufnahme, von der verbauten Platine, mit einer Kamera machen könntest, hätten wir gleich ein vergrößertes Bild. Dann kann man was sehen und muss nicht so viel raten.


MfG

inka
25.10.2019, 09:43
also auf den kühlkörpern die ich bisher draufgemacht habe war immer eine schutzfolie von unten, drunter eine klebende wärmeleitfolie, keine wärmeleitpaste...

die schrauben, die ich zur befestigung der U-klemme benutze haben ja garkein kontakt zu der platine...

welchen kondensator meinst du?

Moppi
25.10.2019, 09:45
Hast Du einen Kondensator 100/220µF, zwischen Vmot und GND, an der Platine? Wenn nicht, bitte mal anbringen!
siehe: https://www.roboternetz.de/community/threads/74136-outdoor-I?p=655699&viewfull=1#post655699

Bei mir hier rechts Mitte, gut zu sehen: https://www.roboternetz.de/community...7&d=1545060175 (https://www.roboternetz.de/community/attachment.php?attachmentid=33857&d=1545060175)

Welche Kühlkörper hast Du?




MfG

inka
25.10.2019, 09:54
ich habe den originalkühlkörper verwendet, der den treiben beiliegt und konnte bei der versuchen auch keine übermässige erwärmung feststellen...

Und die C's muss ich erst besorgen - die sollen wohl der spannungsglättung dienen? Mögliche ursache für das fliegensterben bei mir?

Moppi
25.10.2019, 10:05
dir Originalen hatten bei mir auch keine Folie drauf, lagen mit der Paste drauf einfach so mit im Beutel, bei der Platine.

Na ja, der Motor produziert auch eine Rückspannung (Wicklungsspulen ...), manche Leute reden von Störimpulsen (ich habe das nie kontrolliert - gemessen) und meinen, damit könnte man den Treiber überlasten. Zu der Schaltung auf der Platine könnte ich spekulieren, dass dort Vorsorgemaßnahmen getroffen sind - Freilaufdioden oder wie auch immer, will ich aber nicht. Kondensator ist immer gut und schadet nicht (zum glätten, filtern .. was auch immer).

Auf der Pololu-Seite (https://www.pololu.com/product/1182) steht dazu, übersetzt:


Stromanschlüsse

Der Treiber benötigt eine logische Versorgungsspannung (3 - 5,5 V) zwischen VDD- und GND-Pins und eine Motorversorgungsspannung (8 - 35 V) zwischen VMOT und GND. Diese Versorgungen sollten in der Nähe der Platine geeignete Entkopplungskondensatoren haben und die erwarteten Ströme liefern können (Spitzen bis zu 4 A für die Motorversorgung).

Warnung: Auf dieser Trägerplatine werden Keramikkondensatoren mit niedrigem ESR verwendet. Dies macht sie anfällig für zerstörerische LC-Spannungsspitzen, insbesondere bei Verwendung von Stromkabeln, die länger als einige Zoll sind. Unter den richtigen Bedingungen können diese Spannungsspitzen die maximale Spannung von 35 V für den A4988 überschreiten und die Platine dauerhaft beschädigen, selbst wenn die Motorversorgungsspannung nur 12 V beträgt. Eine Möglichkeit, den Treiber vor solchen Spannungsspitzen zu schützen, besteht darin, a großer (mindestens 47 µF) Elektrolytkondensator über Motorleistung (VMOT) und Masse in der Nähe der Platine.




MfG

inka
25.10.2019, 10:18
Dies macht sie anfällig für zerstörerische LC-Spannungsspitzen, insbesondere bei Verwendung von Stromkabeln, die länger als einige Zoll sind.

die leitungslänge von der 12 versorgungsplatine zu den treibern bei der "aufgeräumten" verlegung, so wie sie jetzt ist, liegt zwischen 15 und 45cm...

Moppi
25.10.2019, 10:20
15 und 45cm...6 und 17 Zoll

Die originalen Flachbandkabel vom Motor zur Platine sind auch länger.

inka
25.10.2019, 10:31
naja, morgen kommen die neuen treiber und die C's hab ich dann auch - mal sehen, ob das fliegensterben weitergeht...

Moppi
25.10.2019, 12:08
Nein, geht es nicht! Ich sag doch, bei mir ist nicht einer kaputt gegangen. Dafür an anderer Stelle schon 3 nodeMCU - was ne andre Geschichte ist :)

1. Kondensator 100µF, 50V, 100V oder 250V (ich habe bei einem Stepper nur 100µF/35V verbaut, bei 12V an Vmot). Zwischen Vmot und GND, direkt nahe an der 4988-Platine
2. Gleichspannung verwenden. Akku oder Batterie.
3. Aufpassen wegen Brücken mit Kühlkörper. Für die ersten Versuche kann man den auch weglassen, sollte so heiß nicht werden. Wenn dann später doch, eben drauf setzen.

Bei mir hats von Anfang an super funktioniert, auch mit fliegender Verdahtung, beim ersten Versuchsaufbau.


MfG

- - - Aktualisiert - - -

Achso, was mir noch auffällt:

wenn die schon was von 4A-Spitzen schreiben, müsste man drüber nachdenken, ob die Versorgung nachher ausreichend ist. Dein Akku hatte 10A für kurzzeitige Spitzen. 4*4 wären aber schon 16A. Weiß nicht, ob ich damit so richtig liege.
Aber auch damit habe ich kein Problem zu irgend einer Zeit, weil ich LiPo nehme, die Ströme von 40A bis 65A wegstecken (je nach Akku, z.B. 1200mAh LiPo: 65A max Entladestrom, damit könnte ich kurzzeitig mein Auto starten ;) ).



MfG

- - - Aktualisiert - - -

Habe gerade ein wenig gelesen, Pololu hat auch diese Boards, wo man die Strombegrenzung digital einstellen kann: https://www.pololu.com/product/2968

Klebwax
25.10.2019, 12:13
Wie kann man sowas entwickeln und verkaufen? Gut, china-zeug, aber ist das bei den pololu originalen anders?

Wohlfeiles Chinesen-Bashing. An diesen Teilen ist nichts entwickelt, bei Pololu heißen die ja auch "breakout board for Allegro’s A4988". Es ist also eigentlich nur der Chip. Um dem Entwickler (also dir) für den Prototypenbau das Erstellen einer Platine und das SMD Löten abzunehmen und die Pins lochrastertauglich zu machen, gibt es dieses Modul.. Dazu sind noch die Teile, die in der Beispielschaltung aus dem Datenblatt dicht am Chip sein sollen, gleich mit aufgelötet. Das heißt aber nicht, daß zu einer vollständigen Schaltung nicht noch weitere Bauteile gehören.

Der Chip liefert seine Wärme an dem Pad auf der Unterseite und den Massepads ab. Von dort wird sie durch Durchkontaktierungen auf die Rückseite der Platine geführt und dort gehört auch ein Kühlkörper hin, falls einer nötig ist. In vielen Anwendungen kann man die Kupferfläche groß genug machen und sich einen Kühlkörper sparen. Ist alles im Datenblatt beschrieben.

Dort ist aber auch beschrieben, daß der Baustein einen eingebauten Übertemperaturschutz hat. Wird er zu heiß, schaltet er ab. Daran liegts also nicht, wenn er stirbt. Was man aber allenthalben im Netz findet, sind Probleme beim manuellen Drehen von Schrittmotoren. Dieser wird dabei zum Generator, die Bodydioden im Treiber bilden einen Gleichrichter und es baut sich eine Spannung auf. Diese kann die maximale Spannung des Chips überschreiten. Inwieweit es auch Rückwirkungen auf Vdd gibt, ist auch nicht klar.

Am einfachsten ist es, die Motore nie von Hand zu drehen, solange sie mit dem Treiber verbunden sind. Das ist bei den typischen CNC-Anwendungen leicht zu erreichen, man greift einfach mit den Fingern nicht in die Maschine. Man kann aber auch elektrisch etwas tun. Zuerst einen dicken Elko in die nähe des Chips, der die Spannung abfedert. Dazu dann eine Z-Diode, die die Maximalspannung begrenzt.

Pololu schreibt dazu


Warning: This carrier board uses low-ESR ceramic capacitors, which makes it susceptible to destructive LC voltage spikes, especially when using power leads longer than a few inches. Under the right conditions, these spikes can exceed the 35 V maximum voltage rating for the A4988 and permanently damage the board, even when the motor supply voltage is as low as 12 V. One way to protect the driver from such spikes is to put a large (at least 47 µF) electrolytic capacitor across motor power (VMOT) and ground somewhere close to the board.

Die Kombination von Induktivitäten und Halbleitern ist immer problematisch. Da sollte man schon vorsichtig rangehen.

MfG Klebwax

inka
25.10.2019, 12:16
Habe gerade ein wenig gelesen, Pololu hat auch diese Boards, wo man die Strombegrenzung digital einstellen kann: https://www.pololu.com/product/2968

kling gut :-), auch der preis :-(

erstmal damit probieren, was morgen kommt, vielleicht brauchts die begrenzung ja garnicht...

Moppi
25.10.2019, 12:20
Hier nochmal auf Deutsch: https://www.exp-tech.de/module/motorsteuerung/schrittmotoren/8426/mp6500-stepper-motor-driver-carrier-digital-curreent-control



Was man aber allenthalben im Netz findet, sind Probleme beim manuellen Drehen von Schrittmotoren. Dieser wird dabei zum Generator, die Bodydioden im Treiber bilden einen Gleichrichter und es baut sich eine Spannung auf. Diese kann die maximale Spannung des Chips überschreiten. Inwieweit es auch Rückwirkungen auf Vdd gibt, ist auch nicht klar.

Solche Gedanken hatte ich auch mal. Ich drehe oft manuell dran und manchmal auch schneller, es passiert bei meiner Schaltung mit LiPo nichts offensichtlich Negatives.



MfG

Klebwax
25.10.2019, 13:21
Solche Gedanken hatte ich auch mal. Ich drehe oft manuell dran und manchmal auch schneller, es passiert bei meiner Schaltung mit LiPo nichts offensichtlich Negatives.

Solange ein Akku dran ist, lädt es ihn auf. Da muß schon eine Menge passieren, bis da die Spannung zu hoch wird. Bei einem Netzteil kann das schon mal anders sein. Da fließt rückwärts kein Strom rein, die Spannung kann also steigen. Es ist aber auch ein Kondensator drin. Wieviel der hilft, hängt nun wiederum von der Leitungslänge und von anderen Schaltungsteilen, die auch an dieser Versorgung angeschlossen sind ab.

MfG Klebwax

inka
25.10.2019, 13:41
also ich hab schon an den rädern von hand gedreht (wer würde es nicht tun, wenn alles so gut passt :-) ), ohne zu wissen dass man es tunlichst vermeiden sollte :-(

auf den bildern die ich kenne, sind die kühlkörper direkt auf dem chip angebracht, die durchkontaktierung würdfe ich nur auf dem original von pololu vermuten...

Moppi
25.10.2019, 14:01
Bin mal gespannt, wenn die bei Dir laufen, wie es sein soll, welche Last sich damit bewegen läßt.

Dauert ja noch was, bis die neuen Teile bei Dir sind, deshalb hier noch etwas zum Lesen, bis dahin: https://www.filamentpreis.de/alles-ueber-schrittmotor-treiber/

Interessant finde ich dort die Beschreibung zu den Trinamic-Treibern, die auch Schrittverluste erkennen sollen.

Klebwax
25.10.2019, 15:10
auf den bildern die ich kenne, sind die kühlkörper direkt auf dem chip angebracht,
Sieht auf den Bildern besser aus, unten gibts da möglicherweise mechanische Probleme mit den Steckerleisten. Aber es ist doch ganz klar, daß der Kunstoff des Gehäuses die Wärme viel schlechter leitet als das Metall des Pads auf der Unterseite. Die Photos hat sicher auch ein Verkäufer und nicht ein Entwickler gemacht.



die durchkontaktierung würdfe ich nur auf dem original von pololu vermuten...

Warum? Achso sind ja Chinesen. Und was ist original? Das ist die Schaltung aus dem Datenblatt von Allegro. Und wie das zu Layouten ist, steht da auch. Wenn es ein Original gibt, findet man es da. Alle malen da nur ab.

Ich hab nur welche mit dem DRV8825. Da kann man die Thermal Vias von der Rückseite gut sehen, Und die ganze Fläche ist auch beim Lötstoplack ausgespart. Auch an Leiterbahnen, die die Ströme leiten müssen, sind da mehrfach Vias gesetzt. Besser gehts auf der kleinen Fläche kaum.

Wenn du dir die Bilder bei Pololu mal ansiehst und sie mit der "Black Edition" vergleichst kannst du sehen, daß auch die nochmal nachgebessert haben.

MfG Klebwax

inka
25.10.2019, 15:39
ich hab ja nix gegen die chinesen, kaufe doch das meiste material was ich brauche dort :-) , könnte mir das garnicht leisten das hier zu kaufen... naja, bis auf die lieferzeiten...

habe mir noch einmal die geschrotteten stepsticks angeschaut: also unten, auf der seite, wo die stiftkontakte rausschauen ist wirklich keine fläche zu sehen, vier durchkontaktierungen, mal mit mal ohne lötstopplack...

Moppi
25.10.2019, 15:56
Ich habe auch nochmal nachgeschaut. Es gibt viele Boards, wo die Treibermodule draufgesteckt werden können, eins neben dem andern. Da wärs nicht möglich, den Kühlkörper unten anzubringen. Also kommt der oben auf den IC drauf.
Bei den Pololu 4988 haben die extra große Kupferflächen, um viel Wärme abzuleiten. Dennoch sind die dann mit Lack überzogen. Die Wärme, die über die Kupferflächen abgeführt wird, gelangt über die Pins direkt vom Chip an die CU-Flächen. Dennoch kommt aber auch Wärme an der IC-Gehäuseoberfläche selber an. Wenn die Oberfläche sehr heiß wird, spräche nichts dagegen dort auch einen Kühlkörper direkt aufzukleben. Die überschüssige Wärme von dem Gehäuse wird nach unten auf die Platine abgestrahlt und gelangt so auf die Außenseite. Das ist sicher nicht effektiver, als ein Kühlkörper direkt auf dem IC-Gehäuse aufgebracht, wenn man mal davon ausgeht, dass der Chip im Gehäuse vertikal genau mittig plaziert ist.



MfG

Klebwax
25.10.2019, 17:52
Daß SMD-Bausteine ihre Wärme über die Pads in die Platine bringen ist üblich, der Einsatz von Thermal Vias als Hilfe dabei auch. Natürlich kann man einen Kühlkörper auf ein Kunststoffgehäuse kleben, man darf sich nur nicht zuviel davon versprechen.

Hier mal ein Bild

34424

Da sind bei einem Treiber die Steckerleisten rückwärts eingelötet. So passt dann ein Kühlkörper gut rauf und die warme Luft kann gut abfließen. Am Ende gehts aber nur darum, daß der Stepper nicht mitten im Lauf wegen Übertemperatur anhält. Kaputt geht er davon nicht.

MfG Klebwax

Moppi
26.10.2019, 09:27
ich könnte mir vorstellen (als ausbaustufe) zwischen die schrittmotor-winkel und den rahmen so etwas (https://www.ebay.de/itm/Druckkugellager-Drehlager-Flanschlager-Lager-57-x-57-Drehteller-Neue-Ausf%C3%BChrung/290675182276?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2060353.m1438.l2649) einzusetzen und die räder dann mit einem servo auszurichten. Ich wolte den roboter aber weder an die Ostsee mitnehmen, noch mit 10kg++ belasten. Das ginge beides natürlich nicht. Eigentlich ist mein ziel mit dem roboter feinere aufgaben im gelände zu erledigen. Einen sixpack Jever oder Radeberger müsste aber zu schaffen sein :-)

Ich kann mir vorstellen, dass der ein oder andere gleich eine Lenkung einsetzen würde. Wobei Du verschiedene Möglichkeiten hast: nur die vorderen Zwei gemeinsam zu lenken, nur die vorderen Zwei einzeln zu lenken oder eventuell sogar alle Vier einzeln zu lenken.

Als Alternative sind die Mecanum-Räder hier schon öfter erwähnt worden. Davon gibt es mittlerweile eine größere Auswahl, hier mal ein Link (https://www.amazon.de/s?k=mecanum+wheels&__mk_de_DE=ÅMÅŽÕÑ&crid=1KKHUH1GI7VGL&sprefix=mecanum%2Caps%2C158&ref=nb_sb_ss_i_3_7).

Vielleicht solltest Du von Anfang eine Variante mit einplanen(?).


MfG

- - - Aktualisiert - - -

Jetzt kam mir gerade nochmal die Frage zum Gewicht, dass die Plattform bewegen könnte., deshalb mache jetzt mal hier explizit einen Frageabsatz draus:
Diese NEMA17 haben ca. 40ncm Max.-Drehmoment; wenn das so richtig ist und ich Pi mal Daumen drüber nachdenke - mit Radgröße, dürften etwa max. 1.5kg pro Motor rauskommen; die Plattform jetzt könnte - geschätzt - etwa 1.5kg auf die Waage bringen; da kommt noch der Akku dazu der einiges an Gewicht mit bringt; die spätere Nutzlast könnte bei 3 bis 4kg liegen? Inka was hattest Du so für eine Vorstellung?

inka
26.10.2019, 11:14
Ich kann mir vorstellen, dass der ein oder andere gleich eine Lenkung einsetzen würde. Wobei Du verschiedene Möglichkeiten hast: nur die vorderen Zwei gemeinsam zu lenken, nur die vorderen Zwei einzeln zu lenken oder eventuell sogar alle Vier einzeln zu lenken.
ich dachte hier wirklich nur an eine alternative als "notlösung", wenn es ohne nicht geht, weil ja die notwendige mechanik das ganze komplizierter und störungsanfälliger macht. Und die möglichkeiten des 3D-drucks sind ja auch begrenzt...


Als Alternative sind die Mecanum-Räder hier schon öfter erwähnt worden. Davon gibt es mittlerweile eine größere Auswahl, hier mal ein Link (https://www.amazon.de/s?k=mecanum+wheels&__mk_de_DE=ÅMÅŽÕÑ&crid=1KKHUH1GI7VGL&sprefix=mecanum%2Caps%2C158&ref=nb_sb_ss_i_3_7).
Vielleicht solltest Du von Anfang eine Variante mit einplanen(?).
ich habe schon die kombination aus 3 rädern durchmesser ca. 50mm
34425

und vier rädern mit einem durchmesser von ca. 70mm
34426
ausprobiert. In innenräumen ok, draussen nur begrenzt, weil sie doch recht schnell und gründlich verdrecken :-(
Abgesehen vom preis, bei 100 mm durchmesser sind es sicher 30€ pro rad...


Jetzt kam mir gerade nochmal die Frage zum Gewicht, dass die Plattform bewegen könnte., deshalb mache jetzt mal hier explizit einen Frageabsatz draus:
Diese NEMA17 haben ca. 40ncm Max.-Drehmoment; wenn das so richtig ist und ich Pi mal Daumen drüber nachdenke - mit Radgröße, dürften etwa max. 1.5kg pro Motor rauskommen; die Plattform jetzt könnte - geschätzt - etwa 1.5kg auf die Waage bringen; da kommt noch der Akku dazu der einiges an Gewicht mit bringt; die spätere Nutzlast könnte bei 3 bis 4kg liegen? Inka was hattest Du so für eine Vorstellung?

entspricht in etwa Deiner schätzung, die platform wiegt schon ohne den akku fast 2kg, die nutzlast schätze ich auf maximal 4-5kg...

inka
27.10.2019, 10:02
also, die treiber sind mit einem C (100µF, 63V) an den versorgungspinns der stepper versehen, sie laufen, das fliegensterben ist wohl gestoppt. Gleich eine frage: Die stepper sind beim einschalten betromt, d.h. sie sind fest in der einschaltposition fixiert.

- Macht es den steppern oder treibern etwas aus?
- Sollten sie nicht besser stromlos sein beim einschalten des roboters? Da werden sie ja noch nicht gebraucht, erst beim befehl zum fahren.
- ist es nur über den enable-pin möglich?

Moppi
27.10.2019, 10:38
Da gibt es den Enable- und den Sleep- Pin.

Weiß nicht, ob Dir das hilft: Ich habe den Enable mit GND verbunden und mit einem 47k gegen +5V. Ich steuer das EIN/AUS nur über den Sleep und die Logikspannung. Den Pin für die Logikspannung habe ich dazu mit dem Sleep-Pin verbunden. D.h., wenn ich den schlafen schicke, dann ist die Logikspannung auch abgeschaltet.

Wenn der nicht schläft - oder wie bei mir dann abgeschaltet ist - kann man das auch über Enable steuern. Enable = Off sollte den Motor stromlos machen. Bei Sleep passiert aber dasselbe.

Wenn die Position sicher gehalten werden soll, muss der Motor aktiv sein.

Nachtrag
-------------------------------------
Sleep-Mode deaktiviert + Enable aktiviert = Motor unter Strom
Sleep-Mode deaktiviert + Enable deaktiviert = Motor nicht unter Strom
Sleep-Mode aktiviert + Enable deaktiviert = Motor nicht unter Strom
Sleep-Mode aktiviert + Enable aktiviert = Motor nicht unter Strom


MfG

inka
28.10.2019, 15:22
mit diesem code kann ich den roboter (zunächst einmal) per IR fernbedienung steuern, hier erstmal die befehle "vorwärts" und "stopp". Die schrittmotoren werden mit


digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH) stromlos geschaltet, nach Deinen ausführungen hätte ich eigentlich das gegenteil erwartet, nämlich "LOW"...



#include <AccelStepper.h>
//#include <LCD.h>
//#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <IRremote.h>
//#include <stepper_standard.h>

//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

uint8_t RECV_PIN = 13;
uint8_t taste = 0;

uint8_t idx;
uint8_t zitter;
uint8_t anzahl;


#define dirPin_VL 2
#define stepPin_VL 3
#define dirPin_HL 4
#define stepPin_HL 5
#define dirPin_VR 6
#define stepPin_VR 7
#define dirPin_HR 8
#define stepPin_HR 9

#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43

IRrecv irrecv(RECV_PIN);

decode_results results;

enum stepper_e
{ stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX };


AccelStepper stepper[stepper_MAX]
{
AccelStepper(1, stepPin_VL, dirPin_VL),
AccelStepper(1, stepPin_HL, dirPin_HL),
AccelStepper(1, stepPin_VR, dirPin_VR),
AccelStepper(1, stepPin_HR, dirPin_HR)
};




void setup()
{
Serial1.begin(115200);
Serial.begin(115200);

Serial.println("code----//home/georg/Arduino/outdoor_robo/stepper/test_vier_stepper/remote_vier_stepper_switch_1_enbl");


irrecv.enableIRIn(); // Start the receiver
/*
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.setBacklight(HIGH);
lcd.print("remot FB schwarz");
lcd.setCursor(0, 1);
lcd.print("switch 1");
delay(2000);
lcd.clear();
lcd.setBacklight(LOW);
*/
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].setMaxSpeed(1000);
stepper[idx].setSpeed(800);
stepper[idx].setAcceleration(30);
// stepper[idx].disableOutputs();
// stepper[idx].setDirection(CCW);
// stepper[idx].rotate(1);

}

digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

}

void loop()
{

if (irrecv.decode(&results))
{
taste = results.value;
Serial.println(taste);
irrecv.resume(); // Receive the next value
}
tasten_abfrage();



}


/************************************************** *********/

void tasten_abfrage(void)
{
switch (taste)
{

case 151 ://taste 1 große FB
{
if (taste == 151 )
{
Serial.println("szenario_1");
Serial1.println("szenario_1");
/*
lcd.setCursor(0, 0);
lcd.setBacklight(HIGH);
lcd.print("szenario_1");
delay(1000);
lcd.clear();
lcd.setBacklight(LOW);
*/
//fahre szenario_1

delay (1000);

break;
}
}

case 103://taste 2 große FB
{
if (taste == 103)
{
Serial.println("szenario_2");
Serial1.println("szenario_2");

//fahre szenario_2

delay (1000);

break;
}
}

case 79://taste 3 große FB
{
if (taste == 79)
{
Serial.println("szenario_3");
Serial1.println("szenario_3");

//fahre szenario_3

delay (1000);

break;
}
}


case 207://taste 4 große FB
{
if (taste == 207)
{
Serial.println("szenario_4");
Serial1.println("szenario_4");

//fahre szenario_4

delay (1000);

break;
}
}


case 253://OK taste, motor stop
{
if (taste == 253)
{
alle_stepper_stop();
fahrt_ausfuehren();

break;
}
}


case 61:// rotate rechts große FB
{
if (taste == 61)
{
// rechts_drehen();

break;
}
}


case 221:// rotate links große FB
{
if (taste == 221)
{

// links_drehen();

break;
}

}


case 157:// fahre vor große FB
{
if (taste == 157)
{
/*
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
*/
vorwaerts();
fahrt_ausfuehren();
break;
}
}


case 87:// fahre rückwärts große FB
{
if (taste == 87)
{

// rueckwaerts();

break;
}
}
}


}


/************************************************** *********/
void alle_stepper_stop(void)
{
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{

stepper[idx].stop();

}

digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
}

/************************************************** *********/
void vorwaerts(void)
{

digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

for (idx = stepper_VL; idx < stepper_VR; idx++)
{
// stepper[idx].moveTo(600);
stepper[idx].runSpeed();
stepper[idx].move(-100);
// stepper[idx].run();
// stepper[idx].rotate(1);
}

for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
// stepper[idx].moveTo(600);
stepper[idx].runSpeed();
stepper[idx].move(100);
// stepper[idx].setDirection(CW);
// stepper[idx].rotate(1);
}
}


/************************************************** *********/
void rotate_right_deg(void)
{

}

/************************************************** ********/
void rotate_left_deg(void)
{

}

/************************************************** *********/

boolean fahrt_fertig()
{

return stepper[stepper_VL].isRunning() && stepper[stepper_HL].isRunning() && stepper[stepper_VR].isRunning()
&& stepper[stepper_HR].isRunning();

}

/************************************************** **********/
void fahrt_ausfuehren()
{
while ( ! fahrt_fertig() )
{
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].run();
// delay(1);
}
}
}

Moppi
28.10.2019, 17:22
Ich schau nochmal nach ...

Ich habe mich mit dem 47k vertan, der hat nichts mit dem Enable zu tun, sondern gehört bei mir zu einem Spannungsteiler. Enable liegt bei mir ständig auf LOW (auch wenn der 47k von dort nach +5V verbunden ist) und aktiviert also die Ausgänge.
Laut Datenblatt von Pololu soll der Enable-Pin ein invertierender Eingang sein.

Pololu schreibt dazu:


This input turns on or off all of the
FET outputs. When set to a logic high, the outputs are disabled.

So ist es dann richtig.

Auf welchem Pegel hast Du denn die Steuereingänge MS1 bis MS3 vom 4988?



MfG

inka
28.10.2019, 19:35
wenn mich nicht alles täuscht - hab jetzt nicht nachgeschaut - sind die garnicht belegt?

Moppi
28.10.2019, 19:52
Wenn die offen / nicht belegt sind, müsste der Motor im Full-Step-Modus laufen (200 Steps / Umdrehung). Laut Datenblatt haben die Eingänge 100 bzw. 50kOhm-Pull-Down-Widerstände. Step-Mode geht von Full bis 1/16tel.
Vorsichtshalber könnten die MS1 bis MS3 zusammengeschaltet und auf GND gelegt werden. Im Datenblatt sind die Eingänge per Beispiel nicht unbeschaltet.

inka
29.10.2019, 15:43
Vorsichtshalber könnten die MS1 bis MS3 zusammengeschaltet und auf GND gelegt werden. Im Datenblatt sind die Eingänge per Beispiel nicht unbeschaltet.

ich hab aber auch beispiele gefunden, wo die einfach frei sind:
34428

ich werde mich mit den MS-pinns beschäftigen müssen...
Hat die schrittweite (also full- bis 1/16) einfluss auf z.b. anzahl verlorener schritte oder die kraft des steppers, oder ist es nur für ein genaueres positionieren wichtig?

Was mir noch aufgefallen ist - ich betreibe das ganze immer noch mit dem netzteil, weil der akku immer noch nicht da ist - wenn ich einschalte, rattern alle stepper ca. eine sekunde lang als würden sie irgendwas suchen. Dabei sollen sie beim einschalten stromlos sein - code siehe weiter oben...

Moppi
29.10.2019, 16:05
Der Step-Mode hat unmittelbaren Einfluss auf das Drehmoment. Kommt drauf an, wie man damit umgeht. Ich habe Mode 4 gewählt, wäre dann 1/16tel , wegen der Laufruhe. Bei mir hatte sich das auch auf die Geschwindigkeit ausgewirkt (drehte etwas schneller), wie dieser Zusammenhang besteht, ist mir aber bislang unklar. Aber die Kraft ist im 16tel-Step nicht so hoch. Anstatt sprunghaft auf 1/200 Umdrehung zu fahren, fährt der Motor bei meiner Anwendung in 16 Schritten auf 1/200 Umdrehung, das ist für so eine Rollosteuerung im Wohnumfeld sehr angenehm, da der Motor nur vor sich hinsurrt. Bei Full Step ist er schon richtig laut; weil der Motor dabei in einem Plastikgehäuse sitzt. Bei einem Fahrzeug, als Antrieb, würde ich wohl auch bei Full Step bleiben, dort sollte der Motor das höchste Drehmoment erreichen.

Ja, es gibt Schaltungen, wo die Eingänge offen gelassen sind. Aber es würde - evtl. zur Störsicherheit - nicht schaden, die gemeinsam auf GND zu legen.

Was das Rattern beim Einschalten angeht: das habe ich nicht. Beim Einschalten des Treibers fährt der Motor in eine Art Ausgangsposition, der bewegt sich ein klein wenig in eine Richtung (Millimeterbruchteil und hält dann die Position). Ein kleines bißchen unruhig ist er dabei auch, soll heißen, dass er bei 1/16tel Step minimal summt (wenn ich mit dem Ohr dran gehe hör ich es etwas). Bei Full Step kann das lauter sein und dauert so lange an, bis der Motor über den Treiber abgeschaltet wird. Vielleicht liegts an der Bibliothek, die Du verwendest, was immer darin passiert. Aber bedenke, dass Du MS1 bis MS3 unbeschaltet hast, vielleicht kommts auch daher, dass der Motor rattert. Wahrscheinlich nutzt Du auch den Sleep Mode nicht. Du müsstest mal messen, was am Enable-Pin für eine Spannung anliegt, nachdem Du gerade eingeschaltet hast. Ohne Sleep Mode liegt das dann nur an dem Pin. Dann weißt Du, was passiert. Lege MS1 bis MS3 versuchsweise auf GND und schaue, ob das was ändert. Ohnehin kann es passieren, dass die Motoren im Stillstand, wenn sie die Position auch nur halten, etwas summen oder brummen. Mit dem Netzteil wirst Du auch keine richtige Gleichspannung erhalten, da wird bestimmt noch ein Wechselspannungsanteil dabei sein, das könnte auch das Brummen/Summen verstärken.


MfG

inka
01.11.2019, 12:23
ich hab mir jetzt noch einmal die beispiele ohne lib angeschaut, schwierig ist es wirklich nicht. Zumindest der anfang :-)



// Define stepper motor connections and steps per revolution:

#define dirPin_VL 2
#define stepPin_VL 3
#define dirPin_HL 4
#define stepPin_HL 5
#define dirPin_VR 6
#define stepPin_VR 7
#define dirPin_HR 8
#define stepPin_HR 9

#define stepsPerRevolution 200


#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43


void setup()
{
// deklariere pins als output:
pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);


Serial.begin(115200);
// mache enaable pins stromlos:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

Serial.print("code---- /home/georg/Arduino/outdoor_robo/stepper/test_vier_stepper/ohne_lib/vier_stepper_ohne_lib_basic_example_idx_enbl_1");
}
void loop()
{

// bestrome enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);



// drehe alle vier stepper langsam vorwaerts einmal herum:

//set dir pinns vorwarts

digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < stepsPerRevolution; i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}
delay(1000);

// drehe alle vier stepper schnell rueckwaerts einmal herum:

//set dir pinns rueckwaerts

digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);

for (int i = 0; i < stepsPerRevolution; i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(1000);
}
delay(1000);


// drehe alle vier stepper langsam vorwaerts fünf mal herum:

//set dir pinns vorwarts

digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < 5* stepsPerRevolution; i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}
delay(1000);

// drehe alle vier stepper schnell rueckwaerts fünf mal herum:

//set dir pinns rueckwaerts

digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);

for (int i = 0; i < 5* stepsPerRevolution; i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
delay(1000);

}


der code funktioniert soweit, was mich noch ein bischen stört, sieht und hört man in dem video hier (https://youtu.be/Onh9XL1klDs) . Wenn zusätzlich zur stromversorgung (immer noch ein steckernetzteil) der atmega 2560 an der USB verbindung zum PC hängt passiert es nicht. Das kenne ich von den steppern 28BYJ_48 und ULN2003 treibern so nicht, da stand der stepper beim einschalten.... Ob sich das bei akkuversorgung ändert?

Moppi
01.11.2019, 12:57
Ich gebe noch mal den Tip. ein paar Varta-Batterien zu holen "D", hatte ich irgendwo schon mal genauer geschrieben. Einfach um sicher zu gehen und diese Frage zu beantworten.
Das ist jetzt mehr so ein Rätselraten, als für mich jedenfalls. Vielleicht weiß jemand anders mehr.
Nach dem Einschalten des Treibers kann sich der Stepper nicht bwegen, es sei denn, der Treiber bekommt die entsprechenden Signale.


MfG

inka
01.11.2019, 13:29
gesagt, getan, ich hab ja (fast) alles zuhause :-)

video (https://youtu.be/_yHNVt-ZdMU)

und nun? Woran kann das nun liegen?

Moppi
01.11.2019, 14:22
An der Ansteuerung des Treibers, der bekommt Step-Signale etc. :)
Du hast es doch im lopp() so geschrieben!?

Verstehe jetzt nicht, was Du meinst! Was stört Dich jetzt daran, dass er links und rechts herum dreht, wenn das im Programm so steht? Ich stehe wohl etwas auf'm Schlauch, hilf mir mal!




MfG

inka
01.11.2019, 14:43
in beiden videos sieht und hört man, dass die stepper beim einschalten hin und her rattern, bevor sie das links- rechts- drehen starten...

hier (https://youtu.be/_yHNVt-ZdMU) und hier (https://youtu.be/Onh9XL1klDs)

Moppi
01.11.2019, 15:22
Jetzt weiß ich was Du meinst. Aber ich kenne das nicht. Ich habe das zu keiner Zeit. Allerdings steuere ich meine Treiber auch über den Sleep-Pin und kann da mit dem Enable-Pin nicht so mitreden, der ist bei mir dauerhaft auf GND geschaltet.


MfG

inka
01.11.2019, 16:52
habe mir Dein codebeispiel noch einmal angeschaut:

- definiert (und verdrahtet?) hat du SLEEP und STEP

- den stepper schaltest du an- und aus- per SLEEP

- ENABLE hast Du nicht verdrahtet

- bewegt wird er per STEP

bedeutet also, dass du den jumper zwischen SLEEP und RESET, wie er in vielen anleitungen beschriben wird, nicht hast?

34444

Moppi
01.11.2019, 17:10
Ich habe meine Zeichnung zum Aufbauen meiner Schaltungen verwendet, habe die Zeichnungen hinterher noch entsprechend geändert. Daher betreibe ich es so, wie es dort abgebildet ist.

Ursprünglich schaltete ich nur den Sleep, weil ich die Akkus schonen will. Dann, weil das nicht ausreichte, habe ich die Logikspannung gleich mitgeschaltet, so dass die Elektronik komplett abgeschaltet ist - mehr Sleep geht wohl nicht. Hat aber denselben Effekt auf den Motor, wie wenn ich nur den Sleep geschaltet habe. ENABLE liegt auf GND. D.h wenn der Treiber unter Logik-Spannung steht, wird der wach und ich steuer direkt den Motor per Step etc., ist die Position errreicht, dann geht es bei mir wieder in den Sleep - Modus (heißt bei mir auch, Logikspannung abschalten).


Steht bei mir im Blog unter: Schaltung neu (https://www.roboternetz.de/community/entries/436-Rolloantrieb-1#comments)
Das ist allerdings nicht ganz aktuell. Da müsste noch die endgültige Schaltung rein. Die habe ich aber weggelassen, weil ich nicht mehr Verwirrung stiften wollte. So, wie es dort abgebildet ist, funktionierte es ja auch und so war auch der Quellcode dafür geschrieben. Und auch damit hatte ich keine Probleme, nur dass der Stromverbrauch im Sleep-Mode evtl. höher war.

Deshalb hier gerne nochmal meine endgültiger Plan:


34445




bedeutet also, dass du den jumper zwischen SLEEP und RESET, wie er in vielen anleitungen beschriben wird, nicht hast?
Wenn ich den RESET nicht benötige (extra steuern möchte), verbinde ich den mit VDD. Natürlich nicht mit SLEEP, wenn ich SLEEP alleine schalten möchte.
In andern Schaltungen wird SLEEP nicht gesteuert und daher mit RESET verbunden.



MfG

Klebwax
01.11.2019, 18:03
in beiden videos sieht und hört man, dass die stepper beim einschalten hin und her rattern, bevor sie das links- rechts- drehen starten...

hier (https://youtu.be/_yHNVt-ZdMU) und hier (https://youtu.be/Onh9XL1klDs)

Das ist ziemlich schlecht, wenn das schon bei unbelastetem Motor auftritt. Mach mal ein Rad ran, und sieh wie es sich entwickelt.

Die Logik-Signale an den Anschlüssen sind doch nun wirklich nicht kompliziert:

ENABLE (erlauben/einschalten) hat einen Überstrich, ist also active Low. Ein Low schaltet den Chip also an. SLEEP hat auch einen Überstrich, bei Low legt sich der Chip schlafen und schaltet sich auch intern das meisste ab. RESET ist ebenfalls active Low, muß also auf High damit der Chip nicht im Reset hängt.

Also muß also ENABLE auf Low und SLEEP und RESET auf High, dann arbeitet der Chip. Und im ersten Schritt legt man die Abschlüsse mit Pull-Ups oder Pull-Downs fest auf den richtigen Pegel. Ein Pulse an Step lässt dann den Motor einen Schritt machen. Wenn erstmal alles funktioniert, kann man sich ums Stromsparen oder andere Sachen kümmern.


Zum Testen würde ich einen Taster an den Prozessor schalten und ein kleines kleines Programm schreiben: Taster entprellen und für jeden Druck einen Puls ausgeben. Je nach dem Pegel von DIR muß der Motor einen Schritt nach links oder rechts machen.

MfG Klebwax

Moppi
02.11.2019, 06:28
nochmal zum Überbrücken SLEEP und RESET:

Der SLEEP - Eingang am Treiber kann von außerhalb unbeschaltet bleiben, weil der mit einem 5k-Widerstand gegen VDD verbunden sein soll. Wenn man Sleep also nicht braucht, muss der nicht zusätzlich beschaltet werden. Wird RESET auch nicht benötigt, wird der gerne einfach mit dem SLEEP verbunden, somit liegt der RESET dann auch über 5kOhm an VDD.



MfG

inka
02.11.2019, 08:59
Das ist ziemlich schlecht, wenn das schon bei unbelastetem Motor auftritt. Mach mal ein Rad ran, und sieh wie es sich entwickelt.
es rattert weniger, weil eine grössere masse bewegt werden muss...


Die Logik-Signale an den Anschlüssen sind doch nun wirklich nicht kompliziert:
stimmt. Ich habe auch inzwischen keine probleme mit dem eigentlichen code. Das problem liegt im einschalten. Seltsamer weise ratterts nur wenn vier stepper gleichzeitig eingeschaltet werden, beim einzelnen passiert es nicht...

Moppi
02.11.2019, 09:27
Das letztere war ein Gedanke, den ich auch schon hatte.
Prüfe mal, ob beim Einschalten, aller 4 Motoren gleichzeitig, die Spannung einbricht! Bei Batterien geht nur runter, sinkt evtl. auf 5V ab oder was ähnliches. Beim Netzteil könnte es sein, dass die Spannung bei Überlast kurzzeitig ganz abgeschaltet wird und dann zu diesen Aussetzern führt. Wenn ich es richtig gelesen habe, brauchen die Stepper-Treiber am Eingang wenigstens 8V.

Da ist es: Load Supply Voltage Range VBB Operating 8 – 35 V


Kannst ja mal an allen Treibern das Trimpoti (frühere Strombegrenzung = weniger Strom für die Motorspulen) verstellen, dass die Stepper noch anlaufen und nicht stehen bleiben. Bei jedem einzeln einstellen (nicht alle zusammen an der Spannungsquelle hängen lassen). Dann noch mal alle zusammen ausprobieren. Funktioniert es dann, liefert Deine Spannungsquelle nicht ausreichend Strom, bei wenigstens 8V.




MfG

inka
02.11.2019, 09:43
habe ich jetzt gemessen, allerdings ist beim ausgeschalteten steckernetzteil ja alles stromlos. Beim einschalten habe ich erstmal (ganz kurz nur) so um 3.5V gemessen, bevor es auf 12V ging...

Ich muss jetzt wirklich auf den akku warten, die chinesen zieren sich aber irgendwie. Zwei verkäufer haben schon einen rückzieher gemacht, die kapazität von 10.000 mAh beim preis von ca. 15€ scheint nicht so ganz easy zu liefern zu sein...

Habe jetzt ein akku über amazon bestellt, natürlich mehr als doppelt so teuer. Mal sehen ob und wann er kommt. Und ob er dann auch in die knie geht...

vielleicht die motoren mit einer kleinen verzögerung schalten?

Moppi
02.11.2019, 10:32
Nutzt Dir später nicht viel. Die müssen auch alle zur selben Zeit laufen können. Wenn das Teil mal was transportieren soll, arbeiten die sich richtig warm. Dafür brauchen die Motoren Energie.



MfG

inka
02.11.2019, 12:31
das hier entspricht in etwa den daten des akkus, auf den ich warte:



Spannung: 12V
Kapazität: 15Ah
Energie: 180Wh


kann man daraus auf den strom schliessen den die stepper ziehen können?

Du sprichst von "laufen"... - ist der stromverbrauch beim laufen und an-laufen gleich?

Moppi
02.11.2019, 13:10
Wenn die ausgelastet sind, können die ständig MAX-Strom benötigen, der wird ja vom Treiber begrenzt.
Daher kann der im Betrieb genau so hoch sein, wie beim ersten Step.
Du kannst den Max-Strom am Treiber mit dem Trimpoti einstellen.
Beim Anfahren dürfte der größte Strom fließen.

Müsste man mal messen, wenn das Fahrzeug fährt, was für ein Strom durchschnittlich insgesamt fließt (Strommessgerät).
Sind vielleicht auch maximal nur 6 bis 8A. Pro Treiber sind es max. 1.5 bis 2A, dann mit Kühlung, dass der Treiber nicht
wegschaltet, falls er thermisch überlastet wird.



MfG

inka
03.11.2019, 13:29
eine andere frage:
ich bin mit der von mir realisierten befestigung der steppertreiberplatinen nicht sehr zufrieden, das erreichen des einstellpotis ist im eingebauten zustand so gut wie unmöglich, austausch schwierig. Jetzt begegnete mir das hier:
34449
wäre das geeignet? Was bedeutet z.b. die bitte 9V zu verwenden? Ich habe auch keine anleitung gefunden, wie es zu verwenden ist...

Moppi
03.11.2019, 14:20
Habe ich auch gesehen.
Da gibt es noch andere Boards, wo gleich 5 Treibermodule drauf passen. Die sind eigentlich für 3D-Drucker gedacht oder Fräsen.
Ich habe das hier nur nicht verlinkt, weil ich Dein Konzept nicht beeinflussen wollte.

Ich schau mal, wo die waren... melde mich dann wieder ...

MfG

- - - Aktualisiert - - -

Die Teile nennen sich RAMPS 1.4 Control Board
Da sind noch "Hochleistungsteile" verbaut (weiß nicht ganeu - FETs oder so) für die Druckdüse und das Heizbett am 3D-Drucker, darüber kann man auch andere Sachen steuern.
Es gibt auch sonst ganze Pakete, wie so was hier: https://www.amazon.de/perfk-Steuerplatinen-Hauptsteuerplatine1-4-Treiberplatine-Elektronische/dp/B07T9ZTDRH/ref=sr_1_50?__mk_de_DE=ÅMÅŽÕÑ&crid=URF8HJ98HHQI&keywords=4988+treiber&qid=1572790269&sprefix=4988+%2Caps%2C164&sr=8-50

Für einen Roboter als Grundlage wäre so was natürlich ideal. Wer es nachbauen will, bestellt so ein Kit.
Es gibt auch fertige Fahrplattformen, die durchaus bis zu 10kg tragen können, mit Kettenantrieb z.B. für so ca. 100,- bis 180,-€.

- - - Aktualisiert - - -

Benutzen kann man das natürlich alles.

- - - Aktualisiert - - -

Falls Du mal mehr Leistung schalten wolltest, da gibt es auch so was hier: https://www.amazon.de/Quimat-MOSFET-Upgrade-Erweiterungskarte-Hochstrom-Bett-Leistungsmodul/dp/B077HP7XX9/ref=sr_1_24_sspa?keywords=Ramps+1.4&qid=1572790734&sr=8-24-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzSUpPM1lXV0UyS1pMJ mVuY3J5cHRlZElkPUEwMTg0MTI1M0dVV1hPRERFVDFPVSZlbmN yeXB0ZWRBZElkPUEwNjM1MzIwMVAxNkpBMjlZUVpOSCZ3aWRnZ XROYW1lPXNwX210ZiZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05 vdExvZ0NsaWNrPXRydWU=

inka
03.11.2019, 15:43
ich würde schon lieber 4 einzelne in der nähe der motoren einbauen (wie der einbauort jetzt ist). Ich wusste garnicht, dass es sowas auch gibt, aber es gibt nichts was es nicht gibt :-)

inka
07.11.2019, 16:23
Solange ein Akku dran ist, lädt es ihn auf. Da muß schon eine Menge passieren, bis da die Spannung zu hoch wird. Bei einem Netzteil kann das schon mal anders sein. Da fließt rückwärts kein Strom rein, die Spannung kann also steigen. Es ist aber auch ein Kondensator drin. Wieviel der hilft, hängt nun wiederum von der Leitungslänge und von anderen Schaltungsteilen, die auch an dieser Versorgung angeschlossen sind ab.

MfG Klebwax
im umkehrschluss heisst es dann, "solange der akku dran ist" - stehen die treiberplatinen ständig unter spannung?

Moppi
07.11.2019, 16:36
Na ja, zumindest bei meiner Anwendung dürfte nichts in den Akku zurückfließen, weil ich vom Akku über Diode die Schaltung versorge.

Nach Schaltbild hängt die Versorgung der Motoren, also in unserm Fall der Akku, direkt an der DMOS Full Bridge. Dort direkt dran hängen auch die Motorspulen.



MfG

Klebwax
07.11.2019, 18:18
im umkehrschluss heisst es dann, "solange der akku dran ist" - stehen die treiberplatinen ständig unter spannung?

Ja. Zumindest solange das Gerät eingeschaltet ist. Wenn die Treiber keinen Strom in den Motor liefern sollen (er ist dann frei drehbar) schaltet man ENABLE ab. Wenn man noch weniger Strom verbrauchen will, benutzt man SLEEP. Dabei muß man immer berücksichtigen, daß der Motor dabei die Schritt bzw die Mikroschrittposition verliert.

Den praktischen Stromverbrauch eines Steppers mit Stromchopper zu bestimmen, ist nicht einfach. Der Chopper bildet zusammen mit der Induktivität der Motorspulen einen Schaltregler. Da reicht dann das Ohmsche Gesetz nicht mehr zur Beschreibung. Dazu kommt noch die Gegen-EMK, die von der Drehzahl abhängt. Insgesamt sind Schrittmotore nicht gerade für ihre Effizienz berühmt. Sie können dafür eine Sache gut: ohne externe Positionsmessung eine Position anfahren, Das hat sich aber relativiert. Sensoren sind so billig und die µC sind so schnell geworden, daß man selbst in billigen Druckern DC-Motore mit Getriebe und Sensor findet.

MfG Klebwax

inka
09.11.2019, 15:55
der kleinere akku ist da, also kann ich weiter experimentieren. Bei diesem



#include <AccelStepper.h>
#include <Wire.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <IRremote.h>
#include <Bounce2.h>


uint8_t RECV_PIN = 13; //13
uint8_t taste = 0;
uint8_t zaehler = 0;

uint8_t idx;

#define PIN2RESET 10



#define dirPin_VL 2
#define stepPin_VL 3
#define dirPin_HL 4
#define stepPin_HL 5
#define dirPin_VR 6
#define stepPin_VR 7
#define dirPin_HR 8
#define stepPin_HR 9

#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43

IRrecv irrecv(RECV_PIN);

decode_results results;

Bounce debouncer = Bounce();

enum stepper_e
{ stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX };


AccelStepper stepper[stepper_MAX]
{
AccelStepper(1, stepPin_VL, dirPin_VL),
AccelStepper(1, stepPin_HL, dirPin_HL),
AccelStepper(1, stepPin_VR, dirPin_VR),
AccelStepper(1, stepPin_HR, dirPin_HR)
};


void setup()
{
Serial1.begin(115200);
Serial.begin(115200);

Serial.println("code----//home/georg/Arduino/outdoor_robo/stepper/test_vier_stepper/mit_lib/infra_rot_pin_13/remote_vier_stepper_switch_1_enbl");

//pinMode(RECV_PIN, INPUT_PULLUP);

pinMode(PIN2RESET, INPUT);

debouncer.attach(RECV_PIN);
debouncer.interval(5); // interval in ms

irrecv.enableIRIn(); // Start the receiver

for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].setMaxSpeed(1000);
stepper[idx].setSpeed(800);
stepper[idx].setAcceleration(100);
}


digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

digitalWrite(PIN2RESET, HIGH);
}

void loop()
{

// Update the Bounce instance :
debouncer.update();

// Get the updated value :
zaehler = debouncer.read();

if (zaehler == 1)
{
zaehler = 0;
if (irrecv.decode(&results))
{
taste = results.value;
Serial.println(taste);
// delay(1000);
irrecv.resume(); // Receive the next value
}
// taste = 0;
tasten_abfrage();
//vorwaerts();

fahrt_ausfuehren();
}
}


/************************************************** *********/

void tasten_abfrage(void)
{
switch (taste)
{

case 151 ://taste 1 große FB
{
if (taste == 151 )
{
Serial.println("szenario_1");
Serial1.println("szenario_1");

//fahre szenario_1

delay (1000);

break;
}
}

case 103://taste 2 große FB
{
if (taste == 103)
{
Serial.println("szenario_2");
Serial1.println("szenario_2");

//fahre szenario_2

delay (1000);

break;
}
}

case 79://taste 3 große FB
{
if (taste == 79)
{
Serial.println("szenario_3");
Serial1.println("szenario_3");

//fahre szenario_3

delay (1000);

break;
}
}


case 207://taste 4 große FB
{
if (taste == 207)
{
Serial.println("szenario_4");
Serial1.println("szenario_4");

//fahre szenario_4

delay (1000);

break;
}
}


case 253://OK taste, motor stop
{
if (taste == 253)
{
alle_stepper_stop();

break;
}
}


case 61:// rotate rechts große FB
{
if (taste == 61)
{
rechts_drehen();

break;
}
}


case 221:// rotate links große FB
{
if (taste == 221)
{
links_drehen();

break;
}

}


case 157:// fahre vor große FB
{
if (taste == 157)
{
vorwaerts();

break;
}
}


case 87:// fahre rückwärts große FB
{
if (taste == 87)
{
rueckwaerts();

break;
}
}
}


}


/************************************************** *********/
void alle_stepper_stop(void)
{
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{

stepper[idx].stop();

}

digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
reboot();
}

/************************************************** *********/
void vorwaerts(void)
{

digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

for (idx = stepper_VL; idx < stepper_VR; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(-200);
}

for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(200);
}
}


/************************************************** ********/

void rueckwaerts(void)
{

digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);


for (idx = stepper_VL; idx < stepper_VR; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(200);
}

for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(-200);
}
}

/************************************************** *********/
void rechts_drehen(void)
{

digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

for (idx = stepper_VL; idx < stepper_VR; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(-200);
}

for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(-200);
}
}


/************************************************** ********/
void links_drehen(void)
{

digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

for (idx = stepper_VL; idx < stepper_VR; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(200);
}

for (idx = stepper_VR; idx < stepper_MAX; idx++)
{
stepper[idx].runSpeed();
stepper[idx].move(200);
}
}

/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/

boolean fahrt_fertig()
{

return stepper[stepper_VL].isRunning() && stepper[stepper_HL].isRunning() && stepper[stepper_VR].isRunning()
&& stepper[stepper_HR].isRunning();

}

/************************************************** **********/
void fahrt_ausfuehren()
{
// while ( ! fahrt_fertig() )
{
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].run();
// delay(1);
}
}
}

für eine fernbedienung, die ich im code mit bounce entprellt habe, stellte ich fest, dass bei einer "Vorwärts - STOP - Rückwärts" befehlsfolge die abgebrochene vorwärtsbewegung beim betätigen der rückwärtstaste erstmal zu ende ausgeführt wird bevor es rückwärts geht...
Ich verstehe es nicht, weil ich den gleichen code bereits bei den anderen, kleinere steppern - ohne dieses phänomen - verwendet habe. Hier scheint es mir so zu sein, dass nach einem stop-befehl die variablen nicht in den zustand versetzt werden, der nach RESET bzw. neustart des codes vorhanden ist. Kann das an der motortreibern liegen?
Ich konnte mir zunächst damit helfen, dass ich den arduino im STOP befehl mit diesem


#define PIN2RESET 10

void setup()

{

Serial.begin(115200);

Serial.println("code----//home/georg/Arduino/tools/reboot");

pinMode(PIN2RESET, INPUT);

delay(2000); //nur für test
}

void loop()

{

reboot();
// delay(2000); //nur für test
}

/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}

resette. Es funktioniert, ganz wohl ich mir aber nicht dabei...

Klebwax
09.11.2019, 18:14
Kann das an der motortreibern liegen?

Wenn du damit die Hardware Treiber Module meinst, nein. Die haben keine Variablen, merken sich nichts. Beim enablen/disablen kann es höchtens einen Ruckler um +- 1/2 Schritt geben, also so rund um 1° Drehung.

Es ist ein Software Problem.

MfG Klebwax

Moppi
10.11.2019, 06:02
Ich versuche mal ein wenig Licht in die Sache zu bringen. Da sind mir noch mehr Dinge aufgefallen, die ich nicht so recht in dem Code von Inka verstehe. Wie das Verwenden von runSpeed(). Das soll immer wieder aufgerufen werden (?), damit der Motor seine Schritte tut, allerdings ruft Inka danach immer wieder die move()-Methode auf? Die Verwendung von move(), setSpeed() usw. verstehe ich noch nicht so recht.

Aber zunächst mal was anderes:

die Klassenreferenz: http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html


zu: stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX
habe ich keine Werte gefunden, welche verbergen sich dahinter?






Übersetzung:


Sie können mehrere gleichzeitige Stepper verwenden, die sich alle mit unterschiedlichen Geschwindigkeiten und Beschleunigungen bewegen,
vorausgesetzt, Sie rufen ihre run () - Funktionen in ausreichend regelmäßigen Abständen auf.
Die aktuelle Position ist auf 0 und die Zielposition auf 0 eingestellt. Die Standardeinstellung für MaxSpeed und Acceleration ist 1.0.
Die Motorpins werden während des Konstruktors durch einen Aufruf von enableOutputs () in den OUTPUT-Modus initialisiert.




setEnablePin()
--------------
Legt die Aktivierungs-PIN-Nummer für Schritttreiber fest. 0xFF zeigt unbenutzt an (Standard). Andernfalls, wenn ein Pin gesetzt ist,
wird der Pin beim Aufruf von enableOutputs () eingeschaltet und beim Aufruf von disableOutputs () ausgeschaltet.


Der Ordnung halber würde ich den Enable-Pin über diese Methode, für alle 4988, festlegen. Auch wenn es, zumindest scheinbar, an
der LIB vorbei funktioniert.




stop()
------
Der Stepper soll unter Verwendung der aktuellen Geschwindigkeits- und
Beschleunigungsparameter so schnell wie möglich anhalten.




disableOutputs()
----------------
Deaktivieren Sie die Motor-Pin-Ausgänge, indem Sie alle auf LOW stellen. Abhängig vom Design Ihrer Elektronik kann dies
die Stromversorgung der Motorspulen unterbrechen, um Strom zu sparen. Dies ist nützlich, um Arduino-Energiesparmodi
zu unterstützen: Deaktivieren Sie die Ausgänge für den Ruhezustand und aktivieren Sie sie dann erneut mit enableOutputs(),
bevor Sie erneut einen Schritt ausführen. Wenn der Aktivierungs-Pin definiert ist, wird er in den OUTPUT-Modus
versetzt und der Pin auf deaktiviert gesetzt.


isRunning()
-----------
Überprüft, ob der Motor gerade läuft.



Hier habe ich Zweifel, wegen dem UND-Operator.


/************************************************** *********/


boolean fahrt_fertig()
{


return stepper[stepper_VL].isRunning() && stepper[stepper_HL].isRunning() && stepper[stepper_VR].isRunning()
&& stepper[stepper_HR].isRunning();


}

"1" und "0" ergibt normalerweise "0".
fahrt_fertig() gäbe FALSE, wenn nur 1 Motor nicht mehr läuft.
Wenn alle Ergebnisse von isRunning() zusammengeführt werden
sollen, würde ich das ändern in folgenden Code, mit dem ODER-Operator.


/************************************************** *********/


boolean fahrt_fertig()
{


return stepper[stepper_VL].isRunning() || stepper[stepper_HL].isRunning() || stepper[stepper_VR].isRunning()
|| stepper[stepper_HR].isRunning();


}

Dann gäbe fahrt_fertig() ein FALSE, wenn alle Motoren nicht mehr laufen.





Folgender Code, um die Stepper anzuhalten.


/************************************************** *********/
void alle_stepper_stop(void)
{
for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].stop();
stepper[idx].disableOutputs();
}


/*
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
reboot();
*/

}



stop() soll den Motor - so schnell wie möglich - anhalten.
disableOutputs() sollte den a4988 Motortreiber abschalten,
so dass der Motor sofort anhalten sollte.
Normalerweise erst stoppen, dann abschalten.


Später dann wieder anschalten enableOutputs() und den Motor bewegen.



MfG

- - - Aktualisiert - - -

Auch mal bitte prüfen, ob der Code der Fernbedienung ohne Verzögerung im Programm ankommt, ob von dort irgendwo die Verzögerung (vorwärts auf rückwärts) herrührt.

- - - Aktualisiert - - -


Beispiel:
stepper[index].setEnablePin(Pinnummer);
siehe auch: setPinsInverted()
stepper[index].setPinsInverted(false,false,true); //weil der Enable ein invertierender Eingang ist

inka
10.11.2019, 10:23
ich gebe ja zu, das ganze basiert auf anderen steppern und treibern (siehe anhang), auf einer anderen LIB (CustomStepper) und auf meiner naivität das ganze irgendwie auf die neue situation "anzupassen"...


zu: stepper_VL, stepper_HL, stepper_VR, stepper_HR, stepper_MAX
habe ich keine Werte gefunden, welche verbergen sich dahinter?

diese bezeichnungen beziehen sich auf die vier stepper (V_orne L_inks usw.) und im zusammenhang mit der variablen "idx" sollen diese in der schleife:

for (idx = stepper_VL; idx < stepper_MAX; idx++)
{
stepper[idx].run();
// delay(1);
} alle vier gleichzeitig in bewegung gesetzt werden, ohne diese schleife liefen die früher nacheinander an...
Ich versuch jetzt mal das ganze mit direkten anweisungen an die DIR und STEP pins der stepper zu realisieren, ohne LIB :-)

inka
10.11.2019, 17:10
so, dieser



//libraries
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <IRremote.h>
#include <Bounce2.h>


uint8_t RECV_PIN = 13;
uint8_t taste = 0;
uint8_t zaehler = 1;

//resett pin definieren
#define PIN2RESET 10


// DIR und STEP pins definieren
#define dirPin_VL 2
#define stepPin_VL 3
#define dirPin_HL 4
#define stepPin_HL 5
#define dirPin_VR 6
#define stepPin_VR 7
#define dirPin_HR 8
#define stepPin_HR 9

//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43

//definiere steps pro umdrehung:
#define stepsPerRevolution 200

//IR pin definieren
IRrecv irrecv(RECV_PIN);

decode_results results;

// debouncer instanz definieren
Bounce debouncer = Bounce();


void setup()
{

// deklariere pins als output:
pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);

Serial.begin(115200);

Serial.println("code----/home/georg/Arduino/outdoor_robo/stepper/test_vier_stepper/ohne_lib/remote_vier_stepper_switch_1_enbl_bounce");

//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);

// IR empfänger pin mit bounce verbinden
debouncer.attach(RECV_PIN);

// debounce interval in ms
debouncer.interval(5);

// starte IR receiver
irrecv.enableIRIn();

// deaktiviere enable pins:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}

void loop()
{

// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);


// Update the Bounce instance :
debouncer.update();

// Get the updated value :
zaehler = debouncer.read();

if (zaehler == 1)
{
zaehler = 0;
// taste = 0;
if (irrecv.decode(&results))
{
taste = results.value;
Serial.println(taste);
// delay(1000);
irrecv.resume(); // Receive the next value
}

}
tasten_abfrage();

}


/************************************************** *********/

void tasten_abfrage(void)
{
switch (taste)
{

case 151 ://taste 1 große FB
{
if (taste == 151 )
{
Serial.println("szenario_1");
Serial1.println("szenario_1");

//fahre szenario_1

delay (1000);

break;
}
}

case 103://taste 2 große FB
{
if (taste == 103)
{
Serial.println("szenario_2");
Serial1.println("szenario_2");

//fahre szenario_2

delay (1000);

break;
}
}

case 79://taste 3 große FB
{
if (taste == 79)
{
Serial.println("szenario_3");
Serial1.println("szenario_3");

//fahre szenario_3

delay (1000);

break;
}
}


case 207://taste 4 große FB
{
if (taste == 207)
{
Serial.println("szenario_4");
Serial1.println("szenario_4");

//fahre szenario_4

delay (1000);

break;
}
}


case 253://OK taste, motor stop
{
if (taste == 253)
{
alle_stepper_stop();

break;
}
}


case 61:// rotate rechts große FB
{
if (taste == 61)
{
rechts_drehen();

break;
}
}


case 221:// rotate links große FB
{
if (taste == 221)
{
links_drehen();

break;
}

}


case 157:// fahre vor große FB
{
if (taste == 157)
{
vorwaerts();

break;
}
}


case 87:// fahre rückwärts große FB
{
if (taste == 87)
{
rueckwaerts();

break;
}
}
}


}


/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
reboot();
}

/************************************************** *********/
void vorwaerts(void)
{

// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}
}


/************************************************** ********/

void rueckwaerts(void)
{

// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}
}

/************************************************** *********/
void rechts_drehen(void)
{

// enable pins aktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}

}


/************************************************** ********/
void links_drehen(void)
{

//enable pins aktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(2000);
}

}

/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/

/************************************************** **********/

kommt ohne eine stepper-lib aus, funktioniert soweit...
die erweiterungen / aufnahmen für die A4988 sowie der stärkere akku sind noch unterwegs, erst dann, mit der notwendigen einstellung der ströme zu den steppern kann ich sagen wie es weitergeht...

inka
14.11.2019, 08:55
wieder eine kleinigkeit:

34473

34474

34475

ich hoffe - auch wenn ich noch gar nicht weiss, ob das ding auch wirklich was wird - es damit etwas "outdoortauglicher" gemacht zu haben. Das ausdenken, entwerfen, drucken und montieren hat riesig spass gemacht...

Bei mir ist oft der weg das ziel :-)

Rabenauge
14.11.2019, 11:18
Geht mir immer genauso....dir kommt eine Idee.
Die reift einige Tage im Kopf, und dann setzt du dich an Blender (oder halt das bevorzugte CAD-Programm), und die Idee reift weiter, nimmt virtuell Form an.
Tage später (oder Stunden, oder Wochen) liegt die Idee fertig vor dir.

Ich liebe den 3D-Drucker.:)
Und mir gehts genauso: der Werdegang ist oft sogar spannender als das eigentliche Endergebnis....

Moppi
14.11.2019, 13:32
wieder eine kleinigkeit:

34473

34474

34475

ich hoffe - auch wenn ich noch gar nicht weiss, ob das ding auch wirklich was wird - es damit etwas "outdoortauglicher" gemacht zu haben. Das ausdenken, entwerfen, drucken und montieren hat riesig spass gemacht...

Bei mir ist oft der weg das ziel :-)


Inka, ich kann es zwar ahnen, was Du da gedruckt hast, aber bin mir nicht sicher, ob es das ist, was ich denke. Schreib doch einfach dabei, was es ist! Hmmm, sieht so aus, asl ob ein Bild seitenverkehrt ist. Kann das sein?

Hat riesig Spaß gemacht .. der Weg ist das Ziel. Bist Du schon am Ende? - Hoffentlich nicht! ;)


MfG

inka
14.11.2019, 14:05
es ist eine kappe für die vier leitungen zum schrittmotor - damit die nicht so schutzlos im freien herumhängen. Und seitenverkehrt nur insofern, dass auf dem linken rad die kappe schon drauf war, am rechten noch nicht. Oder umgekehrt... :-)

Und am ende bin ich noch lange nicht, ich wollte mir das warten auf teile etwas verkürzen... ;-)

btw (wir haben ja kein unterforum): Bei meinem 3D drucker ist der platz für die filamentspule etwas begrenzt. Hat schon jemand filament von einer grossen (1kg) auf eine kleinere (0,5kg) spule umgewickelt? Geht das überhaupt vernünftig?

Moppi
14.11.2019, 14:19
Dann sollten wir das jetzt so machen, dass wir die 3D-Drucker-Sachen unter Konstruktion/CAD rein stellen: https://www.roboternetz.de/community/forums/42-Konstruktion-CAD-Sketchup-und-Platinenlayout-Eagle-Fritzing-u-a

Vielleicht einen Thread mit dem Thema: 3D-Drucker - Hilfe/Probleme/Suche
Dort kann jeder sich dranhängen, wenn es um die Hardware von 3D-Druckern geht. Noch sind es nicht so viele, die dort was schreiben würden, denke ich, vielleicht wird später ein Unterforum draus.

Und vielleicht einen Thread mit dem Thema: 3D-Druck CAD/Slicer
Dort kann jeder sich dranhängen, wenn es dazu Fragen gibt.


Zuerst aber:

Umwickeln kannst Du das, wenn Du willst. Geht das venünftig? - Nein. Dabei wird später das Abwickeln etwas erschwert, dennoch funktioniert das trotzdem. Jedenfalls bei meinem Drucker bisher immer. Habe schon Filamentspulen gekauft, wo ein Rest aufgewickelt war, da ist das dann auch nicht anders, dass sich die Wicklungen hinterher etwas verheddern, durch Überkreuzen - liegt am Material.



Wer jetzt aufmerksam ist, wird bemerken (so wie ich jetzt gerade) dass 3D-Druck automatisch verlinkt wird, auf eine weitere Seite von Frank, unserm Forenbetreiber hier. Dort hat er wohl auch was für 3D-Drucker übrig (habe da noch nicht genau geschaut). Vielleicht hat er sich das dann jetzt so gedacht!?




MfG

Rabenauge
14.11.2019, 15:04
Du müsstest dir ne simple Vorrichtung bauen:
die Spender-Rolle sollte leicht gebremst werden (gerade PLA verhält sich wie ne Feder, das wickelt sich alleine teilweise ab), und die Empfänger-Rolle solltest du manuell oder auch elektrisch drehen. Wichtig ist, dass dein Filament immer _leicht_ unter Spannung steht, dann müsste das sich auch gut aufwickeln.
Entgegen der landläufigen Meinung ist es nämlich Wurst, wie "ordentlich" ein Fliament aufgewickelt ist- meine sind oft gar nicht so toll aufgewickelt.
Interessiert den Drucker überhaupt nicht.
Nur Knoten darf es natürlich nicht geben.
Manche Filamente neigen übrigens zum brechen, wenn sie auf zu dünne Durchmesser aufgerollt werden.....

inka
14.11.2019, 16:00
hat gut geklappt:
34476

ein drehteller (ich glaub von fondue), 10 minuten drehen und das wars...

Um ein video aufzunehmen hat die dritte hand gefehlt...

021aet04
15.11.2019, 07:56
Ich habe es schon mit der Drehbank umgespult. Hatte das Problem das eine Dickstelle im Filament war und ich den Druck nach über 40h abbrechen musste. Damit das nicht mehr passiert habe ich das Filament kontrolliert. Habe mir aber einen Sensor gebaut der das registrieren soll. Muss ich aber noch testen und optimieren.

MfG Hannes

Moppi
15.11.2019, 08:24
Mit wieviel Spannung muß das aufgewickelt werden?


MfG

021aet04
15.11.2019, 09:45
Das Material darf nicht locker sein, das ist die Hauptsache.

Was auch noch wichtig ist, ist das du keine Stelle hast mit einem "Berg" oder einem "Tal". Wenn das passiert kann es das Material beim Verarbeiten nachrutschen und sich das Material verzwicken.

MfG Hannes

inka
15.11.2019, 14:50
Mit wieviel Spannung muß das aufgewickelt werden?
MfG
34477
habe nicht so drauf geachtet, habe einfach mit der rechten hand gedreht, mit der linken die grosse spule etwas gebremst, also das filament ein bischen unter spannung gehalten und versucht das material auf der kleineren spule ein bischen zu verteilen. Besonders ist es nicht gelungen, der drucker druckt aber...

p.s. werden hier neuerdings alle fotos in "landscape" gedreht?

inka
16.11.2019, 16:40
hallo allerseits,

die adapterplatinen für die motortreiber A4988 sind nun endlich gekommen, eingebaut und das ganze funktioniert auch...

Die adapter haben auch die möglichkeit, die steppermotoren was die schrittweite betrifft (1 / 0.5, 0.25......) einzustellen und auch die potis auf den motortreibern sind gut zugänglich....

Ich weiss, dass man die einstellung der treiber/stepper mit einstellung der spannung zwischen masse und dem poti machen kann, habe aber auch schon gelesen, dass man den punkt, an dem die stepper stehen bleiben suchen kann und dann den punkt wählen kann, wo sie "geradeso" laufen...

Diese möglichkeit ist aber wahrscheinlich aus der ecke "3D-drucker" gekommen und dort auch gerechtfertigt, man braucht nicht unbedingt grosses drehmoment dort...

Alles, was bei der poti einstellung über diesen punkt hinausgeht, steigert das drehmoment, den strom, den die stepper ziehen, aber auch die temperatur. Die frage, die mich nun beschäftigt ist, wie warm dürfen die stepper bzw. die kühlkörper werden? Im netz findet man aussagen - 70° ist gut, 100°C ist eher zu viel....

Gibt es andere erfahrungswerte?

Moppi
16.11.2019, 18:19
Die Motoren dürfen, unter Last, deutlich warm werden. Schätzungsweise ~50°C. Wenn Du sie mit der Hand nicht mehr anfassen kannst, ist es zu viel. 100°C wären viel zu viel - nicht gut.
Die Kühlkörper geben sehr viel Wärme ab, wenn die Motoren richtig arbeiten müssen. Auch etwa 50 bis 60°C. Aber: die 4988 haben einen Schutz, werden sie zu heiß, sollten sie abschalten.


MfG

Klebwax
16.11.2019, 18:42
Die Motoren dürfen, unter Last, deutlich warm werden. Schätzungsweise ~50°C. Wenn Du sie mit der Hand nicht mehr anfassen kannst, ist es zu viel. 100°C wären viel zu viel - nicht gut.

Sehe ich auch so. Die Wicklung innen ist noch mal ein gutes Stück wärmer. Und so ab 180° gehen Lötstellen auf.

Aber alles, was du an Wärme produzierst, muß dein Akku leisten und geht dir an Akkukapazität für die wirklichen Funktionen verloren.

MfG Klebwax

inka
17.11.2019, 11:25
ein versuch mit steigung hab ich gemacht: https://youtu.be/zeQfXrpw3DI

steigungsweinkel ca 9°, keinerlei probleme...

inka
17.11.2019, 14:12
steigungswinkel verdoppelt, also ca. 18°, die stepper laufen bei beiden versuchen im halbschritt und mit einer verzögerung von 2ms zwischen HIGH und LOW...

https://youtu.be/nPnKT4-R_8o

es ist aber bei weitem nicht so aufregend, wie der "klatschi (https://www.roboternetz.de/community/threads/74213-GI-Guckis-Intelligenz?p=656428&viewfull=1#post656428)" vom Rumgucker, bei mir ist es egal, ob eine oma, ein auto oder ein hund vor die karre laufen, die kommen alle noch rechtzeitig weg :-)
Bei dem wackligen aufbau traue ich mich aber nicht die geschwindigkeit zu erhöhen, weil mir das dann vermutlich alles um die ohren fliegt...

korrektur:
---------------------------------------------------------------------------------
bei einer steigung von ca. 20°, im halbschritt und einem delay zwischen HIGH und LOW von 0.5ms, schafft er es auch und deutlich schneller:

https://youtu.be/t8sk6ldp5fI

Moppi
17.11.2019, 18:33
Musst jetzt nur aufpassen, bei den Microschritten verlierst Du Drehmoment. Immer im Hinterkopf behalten.


MfG

inka
18.11.2019, 11:15
diesmal ohne video dafür mit dem letzten



//libraries
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <IRremote.h>
#include <Bounce2.h>


uint8_t RECV_PIN = 13;
uint8_t taste = 0;
uint8_t zaehler = 1;

//resett pin definieren
#define PIN2RESET 10


// DIR und STEP pins definieren
#define dirPin_VL 2
#define stepPin_VL 3
#define dirPin_HL 4
#define stepPin_HL 5
#define dirPin_VR 6
#define stepPin_VR 7
#define dirPin_HR 8
#define stepPin_HR 9

//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43

//steps pro umdrehung definieren:
#define stepsPerRevolution 200

//IR pin definieren
IRrecv irrecv(RECV_PIN);

decode_results results;

// debouncer instanz definieren
Bounce debouncer = Bounce();


void setup()
{

//pins als output:
pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);

Serial.begin(115200);

//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);

// IR empfänger pin mit bounce verbinden
debouncer.attach(RECV_PIN);

// debounce interval in ms
debouncer.interval(5);

// starte IR receiver
irrecv.enableIRIn();

//enable pins deaktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}

void loop()
{
/*
// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
*/

// bounce instance updaten:
debouncer.update();

// neuen bounce wert holen :
zaehler = debouncer.read();

if (zaehler == 1)
{
zaehler = 0;
// taste = 0;
if (irrecv.decode(&results))
{
taste = results.value;
Serial.println(taste);
// delay(1000);
// nächsten IR-wert empfangen
irrecv.resume();
}

}
tasten_abfrage();

}


/************************************************** *********/

void tasten_abfrage(void)
{
switch (taste)
{

case 151 ://taste 1 große FB
{
if (taste == 151 )
{
Serial.println("szenario_1");
Serial1.println("szenario_1");

//fahre szenario_1

delay (1000);

break;
}
}

case 103://taste 2 große FB
{
if (taste == 103)
{
Serial.println("szenario_2");
Serial1.println("szenario_2");

//fahre szenario_2

delay (1000);

break;
}
}

case 79://taste 3 große FB
{
if (taste == 79)
{
Serial.println("szenario_3");
Serial1.println("szenario_3");

//fahre szenario_3

delay (1000);

break;
}
}


case 207://taste 4 große FB
{
if (taste == 207)
{
Serial.println("szenario_4");
Serial1.println("szenario_4");

//fahre szenario_4

delay (1000);

break;
}
}


case 253://OK taste, motor stop
{
if (taste == 253)
{
alle_stepper_stop();

break;
}
}


case 61:// rotate rechts große FB
{
if (taste == 61)
{
rechts_drehen();

break;
}
}


case 221:// rotate links große FB
{
if (taste == 221)
{
links_drehen();

break;
}

}


case 157:// fahre vor große FB
{
if (taste == 157)
{
vorwaerts();

break;
}
}


case 87:// fahre rückwärts große FB
{
if (taste == 87)
{
rueckwaerts();

break;
}
}
}


}


/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
reboot();
}

/************************************************** *********/
void vorwaerts(void)
{

// enable pins aktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(250);
}
}


/************************************************** ********/

void rueckwaerts(void)
{

// enable pins aktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}

/************************************************** *********/
void rechts_drehen(void)
{

// enable pins aktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}

}


/************************************************** ********/
void links_drehen(void)
{

//enable pins aktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}

}

/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/

/************************************************** **********/

der letzter stand ist: halbschritt und 2,5ms zwischen HIGH und LOW, damit fährt er 1m in ca 2sekunden. Das reicht erstmal, würde ich sagen. Damit schafft er auch eine 20° steigung, mehr konnte ich innen nicht testen und mehr haben wir hier kaum an der Elbe:-), ausser in der Sächsischen Schweiz, und da ist es dann doch zu steil und sandig...

Ich werde jetzt ein paar "szenarios" einprogrammieren und bei schönerem wetter ein paar bilder vom outdooreinsatz schicken....

Die bedienung ist erstmal mit IR, das geht draussen natürlich nur schlecht. Der nächste schritt ist WiFi, sprich der ESP32 kommt zusätzlich rein, die komunikation über I2C mit dem 2560 als motorsteuerung muss noch entwickelt werden und die bedienung über WiFi über smartphone geschrieben werden....
Dieser


// https://microcontrollerslab.com/esp32-web-server-arduino-led/#Displaying_HTML_web_server_with_ESP32

#include <Arduino.h>
#include <analogWrite.h>

#include <WiFi.h>
#include <WebServer.h>

double velo = 0;

const char* ssid = "ESP32-lok"; //PTCL-BB
const char* password = "12345678"; //5387c614
WiFiServer server(80);

String header;

String LED_ONE_STATE = "vorwaerts";
String LED_TWO_STATE = "aus";
String LED_THREE_STATE = " 0 ";
String LED_FOUR_STATE = "aus";

//String MOTOR_STATE = "off";
//String DIRECTION_STATE = "off";

const int GPIO_PIN_NUMBER_5 = 5;
const int GPIO_PIN_NUMBER_18 = 18;
const int GPIO_PIN_NUMBER_22 = 22;
const int GPIO_PIN_NUMBER_19 = 19;

//const int GPIO_PIN_NUMBER_9 = 9; //motor
//const int GPIO_PIN_NUMBER_10 = 10;//direction


IPAddress local_ip(192, 168, 1, 101);
IPAddress gateway(192, 168, 1, 101);
IPAddress subnet(255, 255, 255, 0);

void setup() {
Serial.begin(115200);
Serial.print("code----ESP_32/pico_lok/HTTP_AP_server_motor_control_8_buttons_velo");

pinMode(GPIO_PIN_NUMBER_5, OUTPUT);
pinMode(GPIO_PIN_NUMBER_18, OUTPUT);
pinMode(GPIO_PIN_NUMBER_22, OUTPUT);
pinMode(GPIO_PIN_NUMBER_19, OUTPUT);

// pinMode(GPIO_PIN_NUMBER_9, OUTPUT);
// pinMode(GPIO_PIN_NUMBER_10, OUTPUT);


digitalWrite(GPIO_PIN_NUMBER_5, LOW);
digitalWrite(GPIO_PIN_NUMBER_18, LOW);
digitalWrite(GPIO_PIN_NUMBER_22, LOW);
digitalWrite(GPIO_PIN_NUMBER_19, LOW);

// digitalWrite(GPIO_PIN_NUMBER_9, LOW);
// digitalWrite(GPIO_PIN_NUMBER_10, LOW);


Serial.print("Connecting to ");
Serial.println(ssid);

// WiFi.begin(WIFI_NAME, WIFI_PASSWORD);

WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_ip, gateway, subnet);

/*
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.println("Trying to connect to Wifi Network");
}
*/
Serial.println("");
Serial.println("Successfully connected to WiFi network");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}

void loop() {
WiFiClient client = server.available();
if (client)
{
Serial.println("New Client is requesting web page");
String current_data_line = "";
while (client.connected())
{
if (client.available())
{
char new_byte = client.read();
Serial.write(new_byte);
header += new_byte;
if (new_byte == '\n')
{

if (current_data_line.length() == 0)
{

client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();

// lok vorwärts/rückwärts
if (header.indexOf("LED1=ON") != -1)
{
Serial.println("GPIO5 LED is ON");
LED_ONE_STATE = "vorwaerts";
digitalWrite(GPIO_PIN_NUMBER_5, HIGH);
}
if (header.indexOf("LED1=OFF") != -1)
{
Serial.println("GPIO5 LED is OFF");
LED_ONE_STATE = "rueckwaerts";
digitalWrite(GPIO_PIN_NUMBER_5, LOW);
}
// lok an/aus
if (header.indexOf("LED2=ON") != -1)
{
Serial.println("GPIO18 LED is ON");
LED_TWO_STATE = "an";
analogWrite(GPIO_PIN_NUMBER_18, velo); //HIGH);
}
if (header.indexOf("LED2=OFF") != -1)
{
Serial.println("GPIO18 LED is OFF");
LED_TWO_STATE = "aus";
analogWrite(GPIO_PIN_NUMBER_18, LOW);
}
//lok schneller/langsammer
if (header.indexOf("LED3=ON") != -1)
{
Serial.println("GPIO22 LED is ON");
velo = velo + 5;
LED_THREE_STATE = velo; //"on";
//analogWrite(GPIO_PIN_NUMBER_22, velo);//HIGH
}
if (header.indexOf("LED3=OFF") != -1)
{
Serial.println("GPIO22 LED is OFF");
velo = velo - 5;
LED_THREE_STATE = velo; //"off";
//analogWrite(GPIO_PIN_NUMBER_22, velo); //LOW
}

if (header.indexOf("LED4=ON") != -1)
{
Serial.println("GPIO19 LED is ON");
LED_FOUR_STATE = "an";
digitalWrite(GPIO_PIN_NUMBER_19, HIGH);
}
if (header.indexOf("LED4=OFF") != -1)
{
Serial.println("GPIO19 LED is OFF");
LED_FOUR_STATE = "aus";
digitalWrite(GPIO_PIN_NUMBER_19, LOW);
}

client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: 2px solid #4CAF50;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 1px 1px; cursor: pointer; }");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
// Web Page Heading
client.println("</style></head>");
//client.println("<body><center><h1>ESP32 Web server LED controlling example</h1></center>");
//client.println("<center><h2>Web Server Example Microcontrollerslab.com</h2></center>" );
//client.println("<center><h2>Press on button to turn on led and off button to turn off LED</h3></center>");
client.println("<form><center>");

client.println("<p> richtung ist " + LED_ONE_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED1\" value=\"ON\" type=\"submit\">VORW</button>") ;
client.println("<button class=\"button\" name=\"LED1\" value=\"OFF\" type=\"submit\">RUECKW</button></center>");

client.println("<p>motor ist " + LED_TWO_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED2\" value=\"ON\" type=\"submit\">AN</button>");
client.println("<button class=\"button\" name=\"LED2\" value=\"OFF\" type=\"submit\">AUS</button></center>");

client.println("<p>geschwindigkeit ist " + LED_THREE_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED3\" value=\"ON\" type=\"submit\">SCHNELLER</button>");
client.println("<button class=\"button\" name=\"LED3\" value=\"OFF\" type=\"submit\">LANGSAMMER</button></center>");

client.println("<p>kamera ist " + LED_FOUR_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED4\" value=\"ON\" type=\"submit\">AN</button>");
client.println("<button class=\"button\" name=\"LED4\" value=\"OFF\" type=\"submit\">AUS</button></center>");


client.println("</center></form></body></html>");
client.println();
break;
}
else
{
current_data_line = "";
}
}
else if (new_byte != '\r')
{
current_data_line += new_byte;
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}

sollte umgeschrieben werde, war ursprünglich für die autonome TT - lok geschrieben, bzw. abgewandelt worden...

inka
19.11.2019, 10:18
vielleicht greife ich hier zu weit vor, aber warum eigentlich nicht. Der Mega 2560 soll ja als "motorbetreuer" dienen, evtl. bekommt er noch ein paar sensoren zur seite...
Für die kommunikation nach aussen (und innen) soll ein LOLIN ESP32 dienen, den hatte ich als "rest" aus dem projekt der autonomen TT-lok noch da. Das menü auf dem smartphone sah dort so aus:

34490
dies soll, da die bedienung des outdoor roboters ja viel umfangreicher sein wird durch so etwas
34491
ersetzt werden...

Die übernahme des AP-servers macht mir denke ich keine probleme, wie ich aber die (html?) programmierung des neuen bedienfeldes hinbekommen soll, da habe ich keinen blassen schimmer... Wer hilft?

Moppi
19.11.2019, 11:31
Wenn Du Hilfe beim HTML-Bedienfeld brauchst, kann ich das gerne für Dich übernehmen. Allerdings habe ich keinen ESP32, nur ein ESP-12E. Müsstest den Code dann auf dem ESP32 selbst zum Laufen bringen, wenn Du nicht ganz unbewandert bist, sollte das funktionieren.


Gruß

inka
19.11.2019, 12:26
also bitte nicht übernehmen, das war nicht der hintergrund meiner frage nach hilfe - ich möchte schliesslich verstehen, was da in dem code passiert... :-)

Die situation:

- auf dem ESP läuft ein webserver, der ist an sich kein problem, zumindest habe ich (halbwegs) verstanden was da abläuft...

- der webserver soll auf "tastendrücke" am smartphone reagieren und die werte, die jetzt die IR-fernbedienung (weiss nicht ob das so sinnvoll ist?) vom ESP über I2c an den arduino liefern...

- evtl. die IR fernbedienung nur um die werte, die jetzt vom smartphone kommen ergänzen, sodass beide bedienungen funktionieren?

- der arduino soll per switch() - wie jetzt auch schon - die vom ESP kommenden befehle umsetzen und die motoren steuern...

Die beiden sketches, so wie sie jetzt sind (die am arduino funktioniert ja bereits mit der IR fernbedienung) und die basis für den webserver (die ich teilweise übernehmen wollte) sind im vorletzten post enthalten. Meinst Du wir können so erstmal starten?

Moppi
19.11.2019, 12:54
Dann habe ich das in der Kürze Deiner Anfrage nicht vollständig verstanden, wie Du das jetzt weiter beschreibst.
Aber dennoch: das Tastenfeld der abgebildeten Fernbedienung kannst Du in eine HTML-Seite packen, die kannst Du per Webbrowser von jedem Gerät, dass einen hat, aufrufen.
Als zweites hast Du dann noch die Fernbedienung zum in die Hand nehmen, die ja sowieso schon funktioniert, wie Du sagst.
Das halte ich für am einfachsten, für jeden.

Dies habe ich noch nicht verstanden:

evtl. die IR fernbedienung nur um die werte, die jetzt vom smartphone kommen ergänzen, sodass beide bedienungen funktionieren?


MfG

- - - Aktualisiert - - -

Du kannst Deinen alten Code natürlich umstricken. Dann musst Du sagen, wobei Du genau Hilfe brauchst. Beim Quelltext für HTML? Oder noch was anderes?


MfG

- - - Aktualisiert - - -

Das Bild von der Fernbedienung: kannst Du mal eine ganz genaue Aufnahme direkt von oben machen? Dann kann das Bild bearbeitet werden, dass es sich möglichst gut komprimieren lässt und dann könnte das als Hintergrundbild verwendet werden. Darüber wird ein Raster mit Elementen gelegt, die beim Anklicken die Stelle hervorheben, die auf dem Bild angeklickt wurde. Wäre eine Möglichkeit die Bedienung in HTML bedienbar zu machen.

inka
19.11.2019, 13:05
das Tastenfeld der abgebildeten Fernbedienung kannst Du in eine HTML-Seite packen, die kannst Du per Webbrowser von jedem Gerät, dass einen hat, aufrufen.
das ist genau der punkt, wo ich hilfe bräuchte... vielleicht sollten wir uns erstmal auf den aufbau der webseite konzentrieren. Ich hab ja vor jahrzenten bereits ein bischen was mit HTML, PHP und CSS gemacht, aber das ist einerseits sicher überholt und auch bereits so gut wie vergessen. Ein paar begriffe und ihre bedeutung sind noch da, mehr ist es aber nicht...

das hier


while (client.connected())
{
if (client.available())
{
char new_byte = client.read();
Serial.write(new_byte);
header += new_byte;
if (new_byte == '\n')
{

if (current_data_line.length() == 0)
{

client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();

// lok vorwärts/rückwärts
if (header.indexOf("LED1=ON") != -1)
{
Serial.println("GPIO5 LED is ON");
LED_ONE_STATE = "vorwaerts";
digitalWrite(GPIO_PIN_NUMBER_5, HIGH);
}
if (header.indexOf("LED1=OFF") != -1)
{
Serial.println("GPIO5 LED is OFF");
LED_ONE_STATE = "rueckwaerts";
digitalWrite(GPIO_PIN_NUMBER_5, LOW);
}
// lok an/aus
if (header.indexOf("LED2=ON") != -1)
{
Serial.println("GPIO18 LED is ON");
LED_TWO_STATE = "an";
analogWrite(GPIO_PIN_NUMBER_18, velo); //HIGH);
}
if (header.indexOf("LED2=OFF") != -1)
{
Serial.println("GPIO18 LED is OFF");
LED_TWO_STATE = "aus";
analogWrite(GPIO_PIN_NUMBER_18, LOW);
}
//lok schneller/langsammer
if (header.indexOf("LED3=ON") != -1)
{
Serial.println("GPIO22 LED is ON");
velo = velo + 5;
LED_THREE_STATE = velo; //"on";
//analogWrite(GPIO_PIN_NUMBER_22, velo);//HIGH
}
if (header.indexOf("LED3=OFF") != -1)
{
Serial.println("GPIO22 LED is OFF");
velo = velo - 5;
LED_THREE_STATE = velo; //"off";
//analogWrite(GPIO_PIN_NUMBER_22, velo); //LOW
}

if (header.indexOf("LED4=ON") != -1)
{
Serial.println("GPIO19 LED is ON");
LED_FOUR_STATE = "an";
digitalWrite(GPIO_PIN_NUMBER_19, HIGH);
}
if (header.indexOf("LED4=OFF") != -1)
{
Serial.println("GPIO19 LED is OFF");
LED_FOUR_STATE = "aus";
digitalWrite(GPIO_PIN_NUMBER_19, LOW);
}

client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: 2px solid #4CAF50;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 1px 1px; cursor: pointer; }");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
// Web Page Heading
client.println("</style></head>");
//client.println("<body><center><h1>ESP32 Web server LED controlling example</h1></center>");
//client.println("<center><h2>Web Server Example Microcontrollerslab.com</h2></center>" );
//client.println("<center><h2>Press on button to turn on led and off button to turn off LED</h3></center>");
client.println("<form><center>");

client.println("<p> richtung ist " + LED_ONE_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED1\" value=\"ON\" type=\"submit\">VORW</button>") ;
client.println("<button class=\"button\" name=\"LED1\" value=\"OFF\" type=\"submit\">RUECKW</button></center>");

client.println("<p>motor ist " + LED_TWO_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED2\" value=\"ON\" type=\"submit\">AN</button>");
client.println("<button class=\"button\" name=\"LED2\" value=\"OFF\" type=\"submit\">AUS</button></center>");

client.println("<p>geschwindigkeit ist " + LED_THREE_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED3\" value=\"ON\" type=\"submit\">SCHNELLER</button>");
client.println("<button class=\"button\" name=\"LED3\" value=\"OFF\" type=\"submit\">LANGSAMMER</button></center>");

client.println("<p>kamera ist " + LED_FOUR_STATE + "</p>");
client.println("<button class=\"button\" name=\"LED4\" value=\"ON\" type=\"submit\">AN</button>");
client.println("<button class=\"button\" name=\"LED4\" value=\"OFF\" type=\"submit\">AUS</button></center>");


client.println("</center></form></body></html>");
client.println();
break;
}
else
{
current_data_line = "";
}
}
else if (new_byte != '\r')
{
current_data_line += new_byte;
}
}
}


ist das problem,


Du kannst Deinen alten Code natürlich umstricken. Dann musst Du sagen, wobei Du genau Hilfe brauchst. Beim Quelltext für HTML? Oder noch was anderes?
naja, dass, was jetzt bereits im arduino läuft - läuft ja. Zunächst ist das ja ausreichend. Es geht mir letztendlich darum , dass ich - je nach situation - den roboter per IR-fernbedienung oder smartphone steuen kann...

edit: foto hinzu...
34497

Moppi
19.11.2019, 15:28
Der Link (Anhang 34495 (https://www.roboternetz.de/community/attachment.php?attachmentid=34495)) funktioniert nicht.

Fehler:

Ungültige Angabe: Anhang
Wenn du einem normalen, gültigen Link im Forum gefolgt bist, wende dich bitte an den Webmaster (https://www.mikrocontroller-elektronik.de/kontakt/).

- - - Aktualisiert - - -

Ok, Bild ist jetzt da.

inka
19.11.2019, 15:34
ich hatte im nachinein auch probleme das bild darzustellen, keine ahnung was da war...

ich finde es toll, dass Du mir hilfst, würde aber sehr gerne an Deinen überlegungen teilhaben wollen - wenn's denn nicht zu viel verlangt ist :-) - also auch mit evtl. irrwegen, meinen dummen fragen usw...

Moppi
19.11.2019, 15:35
Na gut, wenn Du das alles nachvollziehen willst, musst Du selber ran, an den Code, aber mit Unterstützung / Hilfe.
Das Bild bearbeite ich mal und verpacke das in eine komprimierte Datei, JPEG oder so - was am wenigsten Platz benötigt.

Die Datei kann in das "Filesystem" auf dem nodeMCU geschrieben werden, damit belegt es keinen Programmspeicher. Allerdings kommt dann wieder zusätzlicher Programmcode, für SPIFF hinzu.
Oder zweitens, ich codiere die Dateigleich zu Base64 und diesen String kann man dann direkt in den Programmcode integrieren. Das wäre vielleicht zu Anfang die einfachste Methode.




MfG

inka
19.11.2019, 16:26
okay, das war ein bischen zu schnell für'n alten man :-(


Die Datei kann in das "Filesystem" auf dem nodeMCU geschrieben werden, damit belegt es keinen Programmspeicher. Allerdings kommt dann wieder zusätzlicher Programmcode, für SPIFF hinzu.
muss ich das manuell machen und nur einmal, oder macht das das programm? Und was ist SPIFF?




Oder zweitens, ich codiere die Datei gleich zu Base64 und diesen String kann man dann direkt in den Programmcode integrieren. Das wäre vielleicht zu Anfang die einfachste Methode.ok, die einfachste methode, aber bitte was ist Base64?

Du siehst schon, viele von den begriffen von damals haben nicht überlebt :-(...

Ich glaube wir müssen es etwas anders aufbauen. Mit beispielen. Und ich weiss nicht, ob Dir das nicht zu viel wird :-(

edit:
base64 (ungefähr =) open PGP - und PGP ist mir von früher her ein begriff
SPIFF -flash-speicher?

-----------------------
aber Du musst schon etwas langsammer machen :-)

Moppi
19.11.2019, 17:17
Das ist zunächst der erste Schritt:



Ich habe jetzt mal das Bild bearbeitet und verkleinert, dass es noch eine annehmbare Zahl an Details enthält, wenn das Bild nachher im Browser dargestellt wird, sollte der die Pixelübergänge weichzeichnen.
Hier ist erst einmal der String, wie der dann aussieht:


data:image/png;base64,iVBORw....AElFTkSuQmCC

Weil das 9KByte sind, hier als Textdatei: 34498

Base64 (https://de.wikipedia.org/wiki/Base64) ist eine Codierung, die Hex-Code in Zeichencode umwandelt (ganz einfach ausgedrückt). So kann der auch im Webseitencode transportiert werden. Damit kann man eine DATA-URL (https://de.wikipedia.org/wiki/Data-URL) erzeugen, direkt im Webseitencode, der Browser erkennt das und stellt die Grafik dann als solche dar, weil er das zuvor dekodiert. Man kann diesen String aber auch direkt im Browser, oben in der URL-Zeile, eingeben (reinkopieren), der Browser sollte dann das Bild darstellen (es ist in dem Moment eine Data-URL). Wenn Du es ausprobierst, wird Dir sicher alles klar.


MfG

- - - Aktualisiert - - -

SPIFF ist das File System, dass auf einem nodeMCU emuliert wird. Ein ESP-12E hat 1MByte Programmspeicher und 3MByte für SPIFFs (zusätzlicher Flash-Speicher für Dateien). In der Arduino-IDE kann man Dateien im Menü "Werkzeuge" mit "Sketch Data Upload" hochladen. So wie man den Programmcode in den Programmspeicher hochlädt. So, wie Du eine SD-Karte verwenden kannst, kannst Du auch diesen Speicher per SPIFFs verwenden. Wieviel der ESP32 hat, weiß ich nicht, habe noch keinen ESP32.

inka
19.11.2019, 17:42
Man kann diesen String aber auch direkt im Browser, oben in der URL-Zeile, eingeben (reinkopieren), der Browser sollte dann das Bild darstellen (es ist in dem Moment eine Data-URL). Wenn Du es ausprobierst, wird Dir sicher alles klar.


34499

war das so gemeint?

Moppi
19.11.2019, 18:25
Nein! Du hast den Kurzen aus dem Veranschaulichungsbeispiel genommen! :Haue

Du musst den langen String aus der Textdatei nehmen, nur der ist vollständig. :-b

- - - Aktualisiert - - -

Zweiter Schritt dann:

Wir bauen einfach eine Tabelle, wo die Grafik als Hintergrundbild dient.

inka
19.11.2019, 18:27
Nein! Du hast den Kurzen aus dem Veranschaulichungsbeispiel genommen! :Haue

Du musst den langen String aus der Textdatei nehmen, nur der ist vollständig. :-b

jaja, hau nur drauf...

das sieht aber schon besser aus jetzt:
34500
den zweck musst Du mir aber bei passender gelegenheit erklären...

Moppi
19.11.2019, 20:02
Ich habe aber gerade nochmal nachgesehen, statt Tabelle können wir wohl auch eine Image Map in HTML benutzen. Dafür sind diese Dinger da. Das würde die Sache erleichtern.

Also nehmen wir dann dieses Bild und erzeugen damit in HTML eine Map, also Karte, mit den Koordinaten, wo was angeklickt werden kann.

Wofür das oben gut ist? Du siehst, dass man diesen 9KByte langen String als Text kopieren kann und sich darin Dein Bild befindet.



MfG

- - - Aktualisiert - - -

Nächster Schritt



Ich habe schon mal eine Tabelle, als Rahmen, erstellt und das ganz einfach als HTM-Datei gespeichert.
Zuerst muss die Tabelle definiert werde, dann in der Tabelle drei Zeilen und jede Zeile enthält drei Zellen.
Die mittlere Zelle bekommt später als Inhalt die Image Map, also das Bild der Fernbedienung.
Die Tabelle dient als Rahmen um das Bild, damit die Fernbedienung dem Original nahe kommt.
Ich habe bei dem Bild zunächst alle Ränder abgeschnitten, damit wir Speicherplatz sparen.
Die Ränder sind mit der Tabelle wieder hinzugefügt. Belegen damit 928Byte, also knapp 1KByte, zusätzlich zum Bild.

Hier erstmal die Datei mit den Rohdaten: 34501
Die Datei ist als *.TXT gespeichert. Die Endung kann umbenannt werden von ".txt" in ".htm", um sie im Browser zu laden und anzuschauen.

Fragen so weit? Wir machen weiter, wenn nicht.



MfG

- - - Aktualisiert - - -

Zur Erläuterung des HTML-Codes


Die Tabelle ist so aufgebaut:




TABELLE
.......TABELLENZEILE
...................TABELLENZELLE|TABELLENZELLE|TAB ELLENZELLE
.......TABELLENZEILE
...................TABELLENZELLE|TABELLENZELLE|TAB ELLENZELLE
.......TABELLENZEILE
...................TABELLENZELLE|TABELLENZELLE|TAB ELLENZELLE



Die Tabelle hat also sechs Zellen, in drei Zeilen.


------------------------------------------------------------------


Die Tabelle ist definiert mit:

<div style='display:table;background:#000000;border-radius:2em'>


display:table ... DIV-Container als Tabelle
background ... #000000 = hexadezimale Notation für RGB (Rot/Grün/Blau) ergibt hier schwarz
border-radius ... damit die Ecken der Tabelle rund werden, die Zahl gibt den Durchmesser an


Maßeinheit: ich verwende immer "em", diese Maßeinheit ist skalierbar. 1em sind normalerweise 16 Pixel, aber nicht in jedem Browser, hängt mit der Basis-Schriftgröße zusammen; Pixel "px" wäre eine absolute Größe und ist unpraktisch, wir wollen später sehen, dass sich unsere HTML-Fernbedienung an die Größe Deines Smartphone-Bildschirms anpasst


------------------------------------------------------------------


Eine Tabellenzeile ist definiert mit:

<div style='display:table-row'>


display:table-row ... DIV-Container als Tabellenzeile


------------------------------------------------------------------


Eine Tabellenzelle ist definiert mit:



<div style='display:table-cell;width:3em;height:3em'>


display:table-cell ... DIV-Container als Tabellenzelle
width ... Breite einer Zelle
height ... Höhe einer Zelle

inka
19.11.2019, 21:09
oh, Moppi, Du bist mir viel zu schnell :-), morgen geht's weiter, wenn ich alles verstanden hab...
gruss inka

Moppi
19.11.2019, 21:36
Ich habe keine Zeit zu verlieren :)

Guck es Dir ruhig an. Dann kommt noch die Image Map, das ist nicht allzu schwer. Dann müssen wir sehen, dass der HTML-Code das macht, was er soll und dann muss der in Dein Programm eingebunden werden.

Ist schon spät heute.

MfG

Moppi
20.11.2019, 08:12
Hallo inka!

Ich habe da mal noch eine Versuchsdatei: 34503

Wieder Endung ".txt" in ".htm" umbenennen und mit dem Webbrowser laden.

Daran ist zu sehen, wie das mit der Image Map funktioniert.
Hier der Teil der Map:


<img width='170' height='372' usemap='#Remote' src='data:image/png;base64,iVBO...uQmCC'>
<map name='Remote'>
<area shape='circle' coords='84,26,22' href='..'>
</map>


Mit width und height wird die Breite und Höhe des Bildes angegeben. Usemap verweist auf die Map mit dem Namen "Remote".
Weil zu dem Bild eine "Karte" mit Koordinaten angegeben werden muss - der Bereich "area", wo sich eine Taste, auf dem Bild der Fernbedienung, befindet. Für die oberste Taste ist das die Position 84 Pixel von links und 26 Pixel von oben, mit einem Radius (weil die Tasten rund sind) von 22 Pixel. Angegeben wird das alles in "<area ...>". "shape='circle'" wird verwendet, weil wir einen Kreis, als Bereich, definieren. "src=..." ist die Quelle des Bildes für die Map, hier setzen wir den Base64-kodierten String unseres Bildes ein.

Und nun haben wir ein Problem, das mir nicht gefällt. Hätte ich ganz zu Anfang dran denken können, das zu überprüfen (obwohl ich schon einmal Image Maps verwendet habe, ist allerdings schon etwa 15 Jahre her): die Image Map arbeitet nur mit Pixel. Wir können keine Koordinaten verwenden, die einfach skaliert werden können, indem wir ein anderes Maß, als eben Pixel, verwenden. Falls das doch irgendwie machbar sein sollte, weiß ich noch nicht wie.
Das bedeutet, dass die Tabelle und das Bild - also die Fernbedienung in HTML - in Pixel definiert wird (was ich in der Beispieldatei schon gemacht habe). Sollte die Fernbedienung, in Pixel, breiter oder höher sein, als der Smartphone-Bildschirm, passt die dort nicht vollständig drauf und muss horizontal und/oder vertikal gescrollt werden. Natürlich kann man die Pixelmaße dann an seinen Smartphone- oder Tablet-Bildschirm anpassen, es bleibt aber eine feste Angabe.

Ich lass das erst einmal so stehen. Schau es Dir zunächst einmal an. Dann schauen wir weiter.

-------------

Gleich noch etwas weiter drüber nachgedacht: die Pixelangaben können nachher im Programm berechnet und in die HTML-Seite eingesetzt werden, basierend auf einer vorgegebenen Breite und Höhe (z.B. Displaygröße in Pixel v. Smartphone). Damit kann die Größe der HTML-Fernbedienung auch nachjustiert werden. Aber das jetzt erst einmal nur so nebenbei.




MfG

inka
20.11.2019, 12:23
Und nun haben wir ein Problem, das mir nicht gefällt. Hätte ich ganz zu Anfang dran denken können, das zu überprüfen (obwohl ich schon einmal Image Maps verwendet habe, ist allerdings schon etwa 15 Jahre her): die Image Map arbeitet nur mit Pixel. Wir können keine Koordinaten verwenden, die einfach skaliert werden können, indem wir ein anderes Maß, als eben Pixel, verwenden. Falls das doch irgendwie machbar sein sollte, weiß ich noch nicht wie.
Das bedeutet, dass die Tabelle und das Bild - also die Fernbedienung in HTML - in Pixel definiert wird (was ich in der Beispieldatei schon gemacht habe). Sollte die Fernbedienung, in Pixel, breiter oder höher sein, als der Smartphone-Bildschirm, passt die dort nicht vollständig drauf und muss horizontal und/oder vertikal gescrollt werden. Natürlich kann man die Pixelmaße dann an seinen Smartphone- oder Tablet-Bildschirm anpassen, es bleibt aber eine feste Angabe.

die darstellung auf dem smartphone sieht so aus:


34504
ich meine, es muss nicht sein, dass die html fernbedienung das ganze display ausfüllt, toll (und völlig ausreichend) wäre es, wenn es in etwa zentriert zum display wäre.

Die anderen sachen habe ich mir angeschaut, selber programmieren könnte ich es nicht, aber ich habe verstanden wo Du was und wie gemacht hast, müsste also in der lage sein kleine korrekturen selbst durchführen zu können. Toll erklärt!

Moppi
20.11.2019, 13:28
ich meine, es muss nicht sein, dass die html fernbedienung das ganze display ausfüllt, toll (und völlig ausreichend) wäre es, wenn es in etwa zentriert zum display wäre.

So etwas mache immer am Ende irgendwann. Manchmal werden ganze Entwürfe wieder verworfen, dann macht man nicht so viel Arbeit umsonst. Wenn das später so bleiben sollte, schauen wir, dass wir das zentriert bekommen. Oder wie auch immer. Berechnen müssen wir das im Programmcode neu. Jetzt passt es zwar, aber mit einem andern Gerät sieht das wieder anders aus. Aber die Berechnung können wir auch später einfügen.

Du kannst ja mal schauen, dass Du die Koordinaten für die anderen Tasten hinzufügst, da fehlen noch 16. Zurzeit feilen wir am Design und HTML-Layout. Deshalb Frage: Wie ist das jetzt überhaupt, ist das schon so in Ordnung oder fehlen noch zusätzliche Funktionen an der Fernbedienung in HTML? Gefällt Dir sonst irgendwas nicht? Oder willst Du lieber was anderes?



MfG

- - - Aktualisiert - - -

Ausgabe zentrieren


Ich habe etwas experimentiert. Und es hat funktioniert. Da es einfach war, hier direkt der neue HTML-Quelltext: 34505
Umbenennen der Datei kennst Du ja schon.

Noch ist das alles nicht so geordnet, sondern mehr zusammengeschmiert :)
Das macht aber nichts, weil ich mich so dem Endergebnis annähere.

Ich habe noch einen DIV-Container drumherum gesetzt:

<div style='width:100%;height:100%;display:flex;align-items:center;justify-content:center'>
Der bekommt als Eigenschaften die Breite von 100% (uns unbekannte Displaybreite) und die Höhe von 100% (uns unbekannte Displayhöhe).
In dem Container platzieren wir unser bisheriges HTML. Dann schließen wir den Container mit:

</div>

"display:flex;" sorgt dafür, dass der Browser Kenntnis erhält, wie er mit unserem Layout innerhalb des Containers und mit dem Container umgehen soll (Flex-Container)
"align-items:center;" zentriert alle Elemente (vertikal)
"justify-content:center;" zentriert alle Elemente (horizontal)



MfG

inka
20.11.2019, 15:13
hier die txt datei mit den koordinaten, auf dem smartphone kann man beim antippen den kreis der sich bildet sehen, 100%tig stimmt die lage nicht...
edit: dafür, dass man da mit dem finger "zielt" ist es m.e. nach genau genug :-)

das mit dem zentrieren klappt wunderbar am pc, da folgt die FB brav den aussenkanten des fensters, beim smartphone klappt es nicht, da muss man scrollen um die FB zu sehen...

34506

Moppi
20.11.2019, 16:00
Auf dem Smartphone musst Du jetzt scrollen? Ist merkwürdig. Was ist da für ein OS drauf?

inka
20.11.2019, 16:04
android 9

Moppi
20.11.2019, 16:08
Passt es horizontal oder vertikal nicht oder beides nicht?

inka
20.11.2019, 16:15
https://youtu.be/dlrAPK1ftPk

Moppi
20.11.2019, 16:37
In Deinem Beitrag wird was eingeblendet, was Du nicht hingeschrieben hast. Unter Deinem Namen wird "Getriebemotor zu Servo umbauen" verlinkt. Das ist echt irritierend!

- - - Aktualisiert - - -

Habs gesehen, Dein Smartphonebrowser gibt vor, der Anzeigebereich wäre größer als das Display. Interessant! Aber wozu?
Funktioniert dann nur nicht mit dem Zentrieren.

Hast Du Firefox auf dem Smartphone? Ich habe auf unserem Tablet mit Android Firefox installiert.


MfG

inka
20.11.2019, 16:45
In Deinem Beitrag wird was eingeblendet, was Du nicht hingeschrieben hast. Unter Deinem Namen wird "Getriebemotor zu Servo umbauen" verlinkt. Das ist echt irritierend!
in welchem beitrag?

Moppi
20.11.2019, 16:51
In Deinem Beitrag #126, habe das Bild angehängt von der Kamera, leider nicht so tolle Qualität, aber es ist zu erkennen.
Tja, das passiert wohl, wenn man die KI nicht unter Kontrolle hat! :)

Das war ja ein Thread von Dir, inka.

Edit: Neee, Irrtum, das war ein Thrad von HannoHupman!



MfG

inka
20.11.2019, 17:09
Tja, das passiert wohl, wenn man die KI nicht unter Kontrolle hat! :)
oder die eigene :-)

Das war ja ein Thread von Dir, inka.
was man schon so alles im leben gemacht hat... :-)

das ist mit den koordinaten? lassen wir sie so?

Du hast gefragt, ob ich noch was anderes wollte:
eigentlich nicht, die FB, so wie sie auf dem bild ist, ist ok, alles was man zuzsätzlich oder anders machen würde, würde auch ein neues bild erfordern - woher nehmen?

Moppi
20.11.2019, 17:38
Also das mit dem Zentrieren, das nehmen wir dann für das Erste wieder raus. Bis uns was einfällt.

Die Fernbedienung, war das erste Ziel. Du hast was von zusätzlichen Funktionen geschrieben. Welche denn? - Das Bild kann geändert werden.


MfG

- - - Aktualisiert - - -

Ich hätte gerne das Layout fertig, bevor wir das in Stücke zerhacken und in den Code übernehmen.

- - - Aktualisiert - - -

Ich habe etwas in Deinem Code gefunden, Inka: "<meta name='viewport' content='width=device-width, initial-scale=1'>"
Ich hab's in die Datei eingebaut, probier die mal: 34509

inka
20.11.2019, 17:48
Also das mit dem Zentrieren, das nehmen wir dann für das Erste wieder raus. Bis uns was einfällt.
siehe unten...


Die Fernbedienung, war das erste Ziel. Du hast was von zusätzlichen Funktionen geschrieben. Welche denn? - Das Bild kann geändert werden. Ich hätte gerne das Layout fertig, bevor wir das in Stücke zerhacken und in den Code übernehmen.
verstehe ich, bitte lass uns zusammen überlegen was sinnvoll für so einen roboter sein könnte... Ein tag denkpause?



Ich habe etwas in Deinem Code gefunden, Inka: "<meta name='viewport' content='width=device-width, initial-scale=1'>"
Ich hab's in die Datei eingebaut, probier die mal: 34509
das funktioniert jetzt auch auf demn smartphone einwandfrei!!!
was bedeutet das mit dem "in deinem code gefunden"? In welchem?

Moppi
20.11.2019, 17:57
In Deinem Code, wo die Lok-Steuerung per HTML abgewickelt wird. Ich habe nachgelesen, das soll irgendwie den Viewport auf dem Smartphone anpassen, aber nicht herausgefunden, wie und warum ganz genau. Ich nehme aber an, dass durch "width=device-width" die Breite des Ausgabebereichs an die Displaybreite angepasst wird. "initial-scale=1" hat was mit der Skalierung im Viewport zu tun. Keine Ahnung, wie genau das zusammenhängt. Funktioniert das Zentrieren jetzt einwandfrei horizontal und vertikal?

- - - Aktualisiert - - -

Gut, dann haben wir das jetzt so weit. Ein wenig Platz für Tasten ist ja noch. So viele kann man aber nicht hinzufügen, auf dem Smartphone willst Du das mit dem Finger ja auch noch treffen können und die Eingabe soll eindeutig sein. Aber Platz für 4 zusätzliche Tasten sehe ich. Und unten drunter noch eine Reihe mit 3 Tasten, sind zusammen 7 zusätzliche Tasten.

inka
21.11.2019, 09:04
moin Moppi,

Deine frage nach änderungen im bild der FB hat mich kalt erwischt - ich habe bilder aus meiner webseiten programmierzeit als etwas unveränderliches in erinnerung, hier stellt sich die frage wieviel aufwand eine veränderung / erweiterung des FB-bildes bedeutet? Denn - die IR-FB kann ich ja nicht erweitern...
Natürlich würde ich dann voll auf smartphone steuerung unsteigen - wie gesagt, es ist die frage des aufwands....

Mir sind folgende änderungen eingefallen:
- KEYES raus
- zeichen "<" und ">" als zeichen zum blättern (in evtl. zwei bildern?) im unteren bereich hinzu - wenn man selbst die bilder personalisieren könnte?
- speziell zu roboter ist mir nur "nordsuche" eingefallen
- die zeichen "*" und "#" machen in einer neu zu definierenden FB keinen sinn...

btw: die darstellung der "IR-fernbedienung_htm3.htm" ist auf dem smartphone in chrome, HTML-anzeige und firefox super zentriert, der aufbau im firefox dauert etwas...

Moppi
21.11.2019, 09:34
Die Veränderung des Bildes ist Minutensache.

Bitte erläutere mal, das verstehe ich noch nicht:

Mir sind folgende änderungen eingefallen:
- KEYES raus
- zeichen "<" und ">" als zeichen zum blättern (in evtl. zwei bildern?) im unteren bereich hinzu - wenn man selbst die bilder personalisieren könnte?


- - - Aktualisiert - - -

Willst Du beide Fernbedienungen verwenden, würde ich die Tasten nicht ändern und alles so lassen. Außer, bei der HTML-Version welche hinzufügen, die Du - meinetwegen zur Konfiguration oder so - selten verwendest und im Normalbetrieb nicht benötigst. So eine richtige Fernbedienung hat ja auch was, u.U. auch Vorteile.

Sonst lassen wir das zunächst so, wie es ist, sonst ufert das jetzt aus. Ich würde mich dann jetzt mal eher auf das Wichtige konzentrieren. Dann ändern wir das später eventuell. Ich habe schon geschaut, Dein alter Code kann so weit verwendet werden, so dass wir das zunächst einfach halten können, da steigst Du besser durch die Materie, als wenn jetzt noch hundert Sachen dazukommen, von denen viele neu für Dich, in der Programmierung, sind. Später wirst Du sehen, ob Du noch etwas anderes benötigst.

Dann ist Deine HTML-Bedienung nämlich schon so gut wie fertig.



MfG

inka
21.11.2019, 10:34
Sonst lassen wir das zunächst so, wie es ist, sonst ufert das jetzt aus. Ich würde mich dann jetzt mal eher auf das Wichtige konzentrieren. Dann ändern wir das später eventuell. Ich habe schon geschaut, Dein alter Code kann so weit verwendet werden, so dass wir das zunächst einfach halten können, da steigst Du besser durch die Materie, als wenn jetzt noch hundert Sachen dazukommen, von denen viele neu für Dich, in der Programmierung, sind. Später wirst Du sehen, ob Du noch etwas anderes benötigst.

Dann ist Deine HTML-Bedienung nämlich schon so gut wie fertig.

genau so machen wir's...

und wir sind dann bei teil2:
die HTML FB sendet die gleichen (kann man so und muss man - denke ich - so einstellen können) zeichen zum roboter, nur über WiFi und nicht per IR. Der ESP32 empfängt diese zeichen und muss sie zum arduino schicken, per I2c... Und damit betrete ich schon wieder neuland ...

inka
22.11.2019, 13:25
Wir werden sortieren müssen was inhaltlich zur Diskussion in diesem Thread gehört und was Verbesserungsvorschläge bezüglich der Darstellung betrifft.
Wenn es vermischt wird hat wirklich keiner etwas davon.


1. voschlag: alles was nach post 136 kommt löschen

2. vorschlag: nur noch beiträge zum thema "outdoor I"

3. vorschlag: keine diskussion zum verfahren im forum (z.b. zu *.zip, *.txt und *.htm dateien)

habe ich was vergessen?

Moppi
22.11.2019, 13:40
habe ich was vergessen?

Ja, irgendwie schon. Denn anscheinend haben wir die Forenregeln nicht beachtet:

HaWe schrieb:

wenn iihr das unter euch in privat-Mails hin und her macht, die sonst keiner liest, ist es ntl ok.
Aber dies ist ein öffentliches Forum, das auch anderen Mitgledern zugänglich und ...

Und deshalb haben wir das so zu machen, wie er das möchte. - Punkt.
Wenn nicht, wird hier so lange getrollt, bis der Thread endlich Ruhe findet.
Zur Erinnerung: es gibt schon einen mit sehr ähnlichem Thema der tot ist.
Jetzt ist dieser lebendig, jetzt gehts eben auf diesen Thread drauf. So, wie es in der Vergangenheit oft gelaufen ist. Da wird so lange drauf rum gehauen und der Inhalt umgebogen, bis keiner mehr Lust daran hat.
Man möge mal bei Wikipedia unter Troll schauen.



MfG

- - - Aktualisiert - - -

Ab Beitrag 136 gibt noch Inhalte die zur Sache beitragen. Wenn die weg sind, sind sie nicht wiederzuholen.

HaWe
22.11.2019, 13:44
@moppi:
ich trolle nicht, ich habe etliche rationale Argumente für die Klartext-Regelung genannt, denen du dich verschließt, und bezgl. der Lösung sind wir ja schon längst 1 Schritt weiter:
Ihr könnt die Anhänge hochladen, wenn es euch gefällt, oder auch Code Tags, und ich kann ebenfalls code in Code-Tags posten, da ich dann den Code per Zoom-Funktion auch wirklich zeitnah (edit: und groß genug) lesen kann.

inka
22.11.2019, 13:46
Ab Beitrag 136 gibt noch Inhalte die zur Sache beitragen. Wenn die weg sind, sind sie nicht wiederzuholen.
hast recht, aber die datei mit dem endergebnis der FB ist ja vorhanden. Man muss konsequent den HaWe-zopf abschneiden. Mir reichts jetzt langsam auch.

Moppi
22.11.2019, 13:59
Inka, hast Du quellcode3? Wenn nicht, die habe ich noch. Bloß die Erklärung nicht mehr dazu.


MfG

inka
22.11.2019, 14:30
Inka, hast Du quellcode3? Wenn nicht, die habe ich noch. Bloß die Erklärung nicht mehr dazu.MfG

nein Moppi, die erklärungen dazu habe ich auch nicht, ich denke es gibt schlimmeres :-)


@holomino:
ich hab jetzt mit diesem sketch:


void setup() {
// put your setup code here, to run once:

}

void loop() {
// put your main code here, to run repeatedly:

}

den roboter gestartet, das gleiche ergebnis, alle stepper rattern ca. 1 sekundelang... Ist es der arduino? Was anderes fält mir jetzt wirklich nicht ein...

HaWe
22.11.2019, 14:37
@holomino:
ich hab jetzt mit diesem sketch:


void setup() {
// put your setup code here, to run once:

}

void loop() {
// put your main code here, to run repeatedly:

}

den roboter gestartet, das gleiche ergebnis, alle stepper rattern ca. 1 sekundelang... Ist es der arduino? Was anderes fält mir jetzt wirklich nicht ein...

ich hatte dir dazu bereits eine Erklärung geliefert!

inka
22.11.2019, 15:00
ich hatte dir dazu bereits eine Erklärung geliefert!
fängst schon wieder an? Du hast eine vermutung geliefert, nicht mehr. Und die ausrufezeichen spare Dir bitte in zukunft...
Mich interessieren - sei bitte nicht böse - auch die ansichten und lösungen anderer user..
also troll dich...

HaWe
22.11.2019, 15:11
ich werde doch wohl noch darauf hinweisen dürfen, dass ich bereits eine Erklärung geliefert hatte, und wenn du weitere Erklärungen möchtest, ist das ntl ok - das ist kein Grund für dich, unverschämt zu werden.

Moppi
22.11.2019, 15:43
nein Moppi, die erklärungen dazu habe ich auch nicht, ich denke es gibt schlimmeres :-)


Du weißt nicht, wieviel Zeit ich mit der Suche verbracht habe. Also hier nochmal, der dann hoffentlich endlich funktionierende Quelltext (Dein Quelltext): 34524


Dann kannst Du Dich um diese Links "?LED1=OFF" kümmern. Bitte das "?" immer am Anfang hinschreiben.
Falls was unklar dazu ist, bitte fragen!


das gleiche ergebnis, alle Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) rattern ca. 1 sekundelang

Aber sie drehen nicht mehr in eine Richtung? Richtig oder falsch?



MfG

- - - Aktualisiert - - -

Noch eine Frage, inka:

Hast Du RESET und SLEEP miteinander verbunden?

- - - Aktualisiert - - -

Und: wo nimmst Du die Spannung für VDD an A4988 her?

inka
22.11.2019, 15:52
Du weißt nicht, wieviel Zeit ich mit der Suche verbracht habe. Also hier nochmal, der dann hoffentlich endlich funktionierende Quelltext.
es passt alles, im firefox, firefox (pc-darstellung) und auch in chrome auf dem smartphone, und auch auf dem pc auch in beiden browsern wird in x- und y- richtung zentriert... nochmals thx...


Dann kannst Du Dich um diese Links "?LED1=OFF" kümmern. Bitte das "?" immer am Anfang hinschreiben.
Falls was unklar dazu ist, bitte fragen! mache ich ab morgen...


Aber sie drehen nicht mehr in eine Richtung? Richtig oder falsch?
falsch, sie drehen sich, wenn man von vorne auf den stepper draufschaut drehen sie CCW


Noch eine Frage, inka: Hast Du RESET und SLEEP miteinander verbunden?
ja, die verbindung ist auf dem aufnahmeboard für die stepsticks draufgeätzt...


Und: wo nimmst Du die Spannung für VDD an A4988 her?

die 12V kommen aus dem akku und per step-up erzeuge ich 5V, mit denen wird auch alles andere (ausser arduino, der bekommt auch 12V) versorgt

Moppi
22.11.2019, 16:01
Lösungsvorschlag#1 (Voraussetzung: RESET und SLEEP miteinander verbunden): einen 5kOhm-Widerstand an ENABLE anschließen und mit VDD verbinden. Damit dieser PIN zunächst sicher auf HIGH liegt (ENABLE=HIGH, dann A4988 aus)

- - - Aktualisiert - - -

Kalte Lötstellen und Wackelkontakte ausgeschlossen?

- - - Aktualisiert - - -


per step-up erzeuge ich 5V

Die legst Du an VDD an. Dann liegt diese nicht 100%ige Gleichspannung auch am Sleep und am RESET an. Würde ich so nicht machen. Nimm mal, als Versuch, bitte die 5V vom Arduino-Board ab. Und versorge damit VDD.

inka
22.11.2019, 16:04
Lösungsvorschlag#1 (Voraussetzung: RESET und SLEEP miteinander verbunden): einen 5kOhm-Widerstand an ENABLE anschließen und mit VDD verbinden. Damit dieser PIN zunächst sicher auf HIGH liegt (ENABLE=HIGH, dann A4988 aus)
mache ich gleich morgen früh, jetzt muss ich mich noch um anderes kümmern :-)



Kalte Lötstellen und Wackelkontakte ausgeschlossen? ich denke, es sind vier identische baugruppen, hälst Du es wirklich für wahrscheinlich, dass bei allen der gleiche fehler auftritt? Gut - china produkte, aber sowas glaube ich einfach nicht...

Moppi
22.11.2019, 16:11
Für wahrscheinlicher halte ich jetzt, dass der Step-Up-Wandler Probleme macht.



per step-up erzeuge ich 5V

Die legst Du an VDD an. Dann liegt diese nicht 100%ige Gleichspannung auch am Sleep und am RESET an. Würde ich so nicht machen. Nimm mal, als Versuch, bitte die 5V vom Arduino-Board ab. Und versorge damit VDD.

- - - Aktualisiert - - -

Warum brauchst Du überhaupt einen Step-Up-Wandler? Hast Du so viele Baugruppen mit insgesamt so hohem Strom zu versorgen?

inka
22.11.2019, 16:19
Für wahrscheinlicher halte ich jetzt, dass der Step-Up-Wandler Probleme macht.
warum sollte er? Die frage (beim fliegensterben bei mir damals) hab ich schon gestellt, ob die paar milisekunden, die die 5V später anliegen als die 12V irgendwas ausmachen, wurde mir von irgendjemanden gesagt, macht nix, mache ich immer so :-)




Die legst Du an VDD an. Dann liegt diese nicht 100%ige Gleichspannung auch am Sleep und am RESET an. Würde ich so nicht machen. Nimm mal, als Versuch, bitte die 5V vom Arduino-Board ab. Und versorge damit VDD.
kein unterschied :-(


Warum brauchst Du überhaupt einen Step-Up-Wandler? Hast Du so viele Baugruppen mit insgesamt so hohem Strom zu versorgen? weil ich es schon immer so gemacht habe, und weil ich ganz zu anfang den 5V regler bei einem mega abgefackelt habe, da war einfach zu viel drauf...
Und wenn ich alles zusammenrechne, BT, IR, US, gyro...

Moppi
22.11.2019, 16:34
Kein Unterschied, wenn Du die 5V vom Arduino-Board abnimmst? Und der Step-Up ist aus dem Verbund raus? Oder noch immer mit drin? Wenn muss der ganz raus.
Wenn es dann immer noch so ist, versuche mal das mit den 5kOhm von ENABLE an VDD. Ich weiß, morgen. :)

Wenn auch das nicht helfen sollte, haben wir noch einen Joker. Mehr dazu morgen. Oder auch nicht, wenn es funktioniert.


MfG

inka
22.11.2019, 16:55
Kein Unterschied, wenn Du die 5V vom Arduino-Board abnimmst? Und der Step-Up ist aus dem Verbund raus? Oder noch immer mit drin? Wenn muss der ganz raus.
der stepp-up war ganz draussen, da hing nur noch das IR-modul dran...

Wenn es dann immer noch so ist, versuche mal das mit den 5kOhm von ENABLE an VDD. Ich weiß, morgen. :) in meinem alter muss man schon mit den kräften haushalten, und es war heute nicht ganz ohne, aber erfolgreich :-)


Wenn auch das nicht helfen sollte, haben wir noch einen Joker. Mehr dazu morgen. Oder auch nicht, wenn es funktioniert.
:-)

- - - Aktualisiert - - -


Wenn es dann immer noch so ist, versuche mal das mit den 5kOhm von ENABLE an VDD.

ENABLE VL pin eines der stepstick's ist bei mir mit pin 40 des arduino verbunden, diese widerstand zwischen enable und VDD (ist mit Vin bezeichnet) kommt zusätzlich dazu, oder? Ich will es bei einem stepper probieren, denn wenns funktioniert, dreht der halt nicht mit...

Moppi
22.11.2019, 19:03
der stepp-up war ganz draussen, da hing nur noch das IR-modul dran...

ganz weg nehmen, dass der elektrisch nichts mehr mit der übrigen Schaltung zu tun hat. GND am Eingang und Ausgang abklemmen und PLUS-Versorgung am Eingang und Ausgang abklemmen.

- - - Aktualisiert - - -

Dann alle Platinen für den A4988 abklemmen. Da wo die Leisten drauf sitzen, um das a4988 -Modul draufzustecken, alle komplett abklemmen von der Versorgung etc.
Nur erst mal ein A4988-Modul betreiben, ohne Step-Up.

Warum? Du hast 4 Module parallel angeschlossen, vielleicht tun die sich gegenseitig irgendwas, was auch immer. Jede dieser Steckplatinen, mit den Sockelleisten, hat einen Kondensator drauf sitzen, wenn das dem Bild entspricht. Mich wundert nämlich auch diese ~1sec. Ich habe immer nur einen A4988 benutzt, mit 100%iger Gleichspannung aus einem Akku und mit einem Spannungsregler (nicht Step-Up-Wandler) und ich hatte nie auch nur das geringste irgendwelcher Probleme, die Du jetzt hast.

Funktioniert es mit einem Modul (wider Erwarten), schließt Du ein zweites Modul an. Dann das dritte und dann das vierte Modul.

- - - Aktualisiert - - -


ENABLE VL pin eines der stepstick's ist bei mir mit pin 40 des arduino verbunden, diese widerstand zwischen enable und VDD (ist mit Vin bezeichnet) kommt zusätzlich dazu, oder? Ich will es bei einem Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) probieren, denn wenns funktioniert, dreht der halt nicht mit...

Der Widerstand existier so nicht. Der muss dann extra dran.
Und doch: wenn es funktioniert, sollte der trotzdem mit drehen, wenn er angesteuert wird. Weil wenn Arduino-Pin den ENABLE auf LOW (also 0V) zieht, hat der ENABLE-Pin LOW-Potential, trotz dem 5k-Widerstand (der soll nur sicher stellen, dass ein definierter Pegel anliegt - eben HIGH zu Beginn, wenn der Arduino noch durchstartet). So die Idee.

- - - Aktualisiert - - -

Tut mir leid, mir gefallen diese Platinen nicht. Da steht doch drauf: PLS USE 9V1A POWER. Nicht 12V2A oder gar 30V1.7A. Da sind sogar noch zusätzliche Widerstände drauf gelötet, neben dem Kondensator. Da steht dran 5V-GND-9V. Ich würde die Teile weglassen. Gefällt mir irgendwie nicht. Nicht, dass nachher vielleicht anfangen die Leisten zu schmelzen, weil Du 1.7A bei 12V drüber schickst. Außerdem, was machen die Widerstände, gibt es einen Schaltplan von der Platine?

inka
22.11.2019, 20:27
Moppi, gehe mal zu post 68, da ratterts auch schon, da waren die stepsticks noch ohne "motherboard" im betrieb...

Moppi
22.11.2019, 21:16
Ja, das war jetzt nicht primär deswegen, sondern vor allem wegen der Leistung. Weil 9V bei 1A ist nicht viel. Und viel mehr würde ich da vorsichtshalber dann auch nicht drüber gehen. Also nicht wundern, falls es mal nach Plastik riecht. Gerade beim 3D-Drucker, wie dem Anet A8, hat die Platine auch ein massives Wärmeproblem. Auch bei Übergangswiderständen an gelöteten Anschlussklemmen usw. Ist eben doch eine Menge Leistung.
Aber dennoch würden mich diese Widerstände auf der Platine intressieren. Im Netz konnte ich dazu nichts finden.


MfG

Moppi
23.11.2019, 07:51
Ich hätte noch Vorschläge zur Spannungsversorgung, auch wenn ich kein Experte auf dem Gebiet bin:


Den Step-Up-Wandler (vermutlich eher Step-Down) auf 6.8V bis 7.5V einstellen (wegen der Verlustleistung nachfolgender Spannungsregler).
Mit dieser Spannung den Arduino speisen (Versorgung: abs. Minimum 6V, empfohlen: 7V).
Geräte ohne eigenen Spannungsregler nicht direkt an Step-Up/Step-Down-Wandler anschließen, sondern Spannungsregler dazwischen schalten (mit Kondensatoren am Eingang und Ausgang, da gibts i.R. für jeden Regler eine Art "Standardbeschaltung" im Datenblatt) - ist nicht zwingend notwendig, Besonderheiten beachten.


(Anmerkungen durchaus erwünscht)


MfG

PS: für mehr Informationen zu DC/DC-Wandlern mal hier (https://www.all-electronics.de/befilterung-von-dcdc-wandlern/) schauen, da gibt es auch ein Bild zur Erklärung der Störungen, die auftreten können.

- - - Aktualisiert - - -

Für mehr Informationen zum A4988, Datenblatt: https://www.allegromicro.com/en/products/motor-drivers/brush-dc-motor-drivers/a4988

Holomino
23.11.2019, 10:32
Ich hab mir gestern mal so ein Schaltplan von einer A4988-Steckbrücke angeschaut. Da saß ein 100k-Widerstand gegen Masse an /Enabled.
Kann es sein, dass die Versorgungsspannung beim Einschalten sehr langsam steigt und sich die Brücken mehrfach über /Enabled resetten?
(Ein Pullup im Bereich 1k..4k7 wäre dann vielleicht eine Möglichkeit, die Treiber während des Einschaltens etwas stabiler zu deaktivieren)

inka
23.11.2019, 10:37
Den Step-Up-Wandler (vermutlich eher Step-Down) auf 6.8V bis 7.5V einstellen (wegen der Verlustleistung nachfolgender Spannungsregler).
Mit dieser Spannung den Arduino speisen (Versorgung: abs. Minimum 6V, empfohlen: 7V).
Geräte ohne eigenen Spannungsregler nicht direkt an Step-Up/Step-Down-Wandler anschließen, sondern Spannungsregler dazwischen schalten (mit Kondensatoren am Eingang und Ausgang, da gibts i.R. für jeden Regler eine Art "Standardbeschaltung" im Datenblatt) - ist nicht zwingend notwendig, Besonderheiten beachten.
wahrscheinlich zielführend, aber etwas kompliziert. Ich habe noch eine beobachtung gemacht: Das rattern kommt nicht vor, wenn der arduino am USB programmierkabel hängt, und er somit mit unabhängigen 5V versorgt wird.
Was wäre denn davon zu halten, an die 5V und GND pins einen kleinen lipo akku (ich sündige mal hier) mit 3.7V zu hängen und den vor dem einschalten des roboters mit seinen steppern, quai als "vorglühen" beim diesel :-) für 5 sekunden dazuzuschalten?


Für mehr Informationen zum A4988, Datenblatt: https://www.allegromicro.com/en/products/motor-drivers/brush-dc-motor-drivers/a4988
ich habe an dem 5ten extenderboard die widerstände ausgemessen:
R1 liegt zwischen 5V und dem gemeinsamen punkt der schiebeschalter zur einstellung der schrittweite, wert 5K
R2 liegt zwischen EN und dem minuspol (?) des grossen kondensators, wert 5K

Moppi
23.11.2019, 10:58
Morgen Inka,


ich habe an dem 5ten extenderboard die widerstände ausgemessen:
R1 liegt zwischen 5V und dem gemeinsamen punkt der schiebeschalter zur einstellung der schrittweite, wert 5K
R2 liegt zwischen EN und dem minuspol (?) des grossen kondensators, wert 5K

Ok, da habe ich nicht dran gedacht.
Danke!

Hast Du das mit dem Pull-Up-Widerstand, also die 5k von ENABLE nach +5V (Vdd) schon ausprobiert?

MfG

PS: noch etwas nebenbei: ich habe eine Versuchsschaltung aufgebaut. Die maximale Umdrehungszahl der NEMA17-Stepper mit 1.8°-Schritten, liegt etwa bei 400 bis 500U/min (irgendwo habe ich mal gelesen 450u/min). Bei einem Durchmesser des Rades von 9cm sind das etwa 28cm Umfang. Müssten etwa 7.56km/h sein. Gut Schrittgeschwindigkeit, mit so kleinen Rädern.

inka
23.11.2019, 11:04
Hast Du das mit dem Pull-Up-Widerstand, also die 5k von ENABLE nach +5V (Vdd) schon ausprobiert?

moin Moppi,

nein, habe ich noch nicht, der R grinst mich noch ganz schön frech an :-) - > passt es überhaupt noch mit dem "R2" am ENABLE pin?

Moppi
23.11.2019, 11:15
Das mit dem Pull-Up von Holomino habe ich noch nicht verstanden, wo soll der hin - der Widerstand? :)


passt es überhaupt noch mit dem "R2" am ENABLE pin?

Warum nicht? Wenn ENABLE dauernd auf HIGH liegt dürfte sich nix mehr drehen.
Dann mit dem Arduino nach dem Starten im Setup 2s Gedenkpause einlegen (s. Holominos Beitrag) und dann erst mit dem Programm fortfahren.

- - - Aktualisiert - - -

@inka
um Dich zu ärgern: bei meinem Versuchsaufbau funktioniert alles einwandfrei, obwohl ich keine Strippe gelötet habe, alles nur gesteckt. ;)

inka
23.11.2019, 11:19
@inka um Dich zu ärgern: bei meinem Versuchsaufbau funktioniert alles einwandfrei, obwohl ich keine Strippe gelötet habe, alles nur gesteckt. ;)
vier stepper? Oder von welchem aufbau sprichst Du? Bei mir ist ja auch alles gesteckt... Und ärgern? Ich freue mich für Dich :-)
nachmittags will ich es probieren:
- - - Aktualisiert - - -



Wenn es dann immer noch so ist, versuche mal das mit den 5kOhm von ENABLE an VDD.

ENABLE VL pin eines der stepstick's ist bei mir mit pin 40 des arduino verbunden, diese widerstand zwischen enable und VDD (ist mit Vin bezeichnet) kommt zusätzlich dazu, oder? Ich will es bei einem Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) probieren, denn wenns funktioniert, dreht der halt nicht mit...

Moppi
23.11.2019, 11:38
40 Stepper ... glaubst Du mir?

:)

Nein - einer! Reicht aus zum Ausprobieren.

- - - Aktualisiert - - -


wahrscheinlich zielführend, aber etwas kompliziert. Ich habe noch eine beobachtung gemacht: Das rattern kommt nicht vor, wenn der arduino am USB (http://www.rn-wissen.de/index.php/USB) programmierkabel hängt, und er somit mit unabhängigen 5V versorgt wird.

Wenn Du die 12V nimmst, dann hängen dort die Motoren dran und geben vermutlich Störungen auf die Versorgungsspannung drauf, das gelangt dann zum Arduino.

Klar kannst Du den Arduino extra mit Akku betreiben.

- - - Aktualisiert - - -

Du kannst aber auch was anderes noch versuchen, in diesem Fall. Nimm die 12V vom Akku , die auch an den Arduino gehen, verbinde die +12V mit einer Gleichrichterdiode und das andere Ende der Diode verbindest Du mit den Motoren. Also eine Diode in die Versorgungsspannung zu den Motoren. Vielleicht hilfts schon.

- - - Aktualisiert - - -

Sag mal, der Akku ist nicht vielleicht zu schwach, dass die Spannung einbricht, beim Einschalten des Gerätes?

inka
23.11.2019, 12:16
Klar kannst Du den Arduino extra mit Akku betreiben. kann der dann auch dauend an- und an den 5V und GND pins dranbleiben? Er hat ja nur 3.7V? Es ging ja auch nicht direkt darum den arduino damit zu betreiben, sondern zusätzlich zu der 12v versorgung quasi eine art "starthilfe" zu geben...


Du kannst aber auch was anderes noch versuchen, in diesem Fall. Nimm die 12V vom Akku , die auch an den Arduino gehen, verbinde die +12V mit einer Gleichrichterdiode und das andere Ende der Diode verbindest Du mit den Motoren. Also eine Diode in die Versorgungsspannung zu den Motoren. Vielleicht hilfts schon.
probiere ich auch noch...


Sag mal, der Akku ist nicht vielleicht zu schwach, dass die Spannung einbricht, beim Einschalten des Gerätes?
und wie stelle ich das fest? Ich hab nur die spannungsangabe von 10,6 - 12V und die 8Ah

dieser 5kOhm widerstand von ENABLE an VDD: zusätzlich zu der verbindung zum arduino pin (hier, einer von vier, die nr. 40) oder als ersatz? Wenn zusätzlich, könnte ich den widerstand auch auf der treiberplatine auflöten...

Moppi
23.11.2019, 12:48
Wenn zusätzlich, könnte ich den widerstand auch auf der treiberplatine auflöten...

Ja, könntest Du.

Was die Spannung angeht. Kannst Du doch messen. Du sagst doch, das dauert etwa eine Sekunde. Messgerät dran und dann Einschalten und beobachten.
Normal müsstest Du mir einem Oszilloskop messen, dann kannst Du genau sehen, was los ist. Wie hoch die Spannung ist und ob Störungen drauf sind.
Du kannst auch noch eine Diode zwischen "+" und "-" hängen, als Freilaufdiode, soll zwar nicht notwendig sein...


Ich würde mal die einfachste Möglichkeit versuchen und eine Gleichrichterdiode in die Plusleitung zu den Motoren reinhängen. Wenn das nichts nützt, eine zweite, gleiche Diode als Freilaufdiode.

Das Problem könnten auch Einschaltspitzen sein. Ich habe keine Ahnung, wieviel Strom kurzfristig gezogen wird, bei 4 Steppern. Theor., wenn ich an die bis 4A Spitze denke, die als Störung auftreten können, 4*4 sind 16A. Zwar sollen die Elkos hier gegensteuern, aber wer weiß. Und wenn es auch nur 2A sind, dann bist Du schon bei 8A. Wenn das beim Einschalten kurz passiert, bricht die Spannung am Akku ein. Wenn das sehr große Sprünge sind, kann es sein, dass der Spannungsregler vom Arduino das nicht hinbekommt. Dann hast Du so ein Phänomen. Oder, wenn die Störspitzen auf die Versorgung zurück gelangen, könnte auch das auch dazu führen. Noch schlimmer wird es in dem Fall, wenn die Störungen aller 4 Motoren zusammen kommen, das kann ganz heftig werden. Fest steht: beim Einschalten der Versorgungsspannung können die Stepper kurzfristig unter Strom stehen, das habe ich bei meinem Versuchsaufbau nämlich auch so.

Mehr fällt mir auch nicht ein.



MfG

inka
23.11.2019, 13:09
Ja, könntest Du. (5K zwischen ENABLE und VDD)
wahrscheinlich ein erfolgserlebnis, kann es noch nicht so beurteilen :-) der stepper an dem ich den widerstand aufgelötet habe rattert beim einschalten nicht, bewegt sich (natürlich?) aber auch nachher nicht, wenn die FB benutzt wird...

Moppi
23.11.2019, 13:27
Mal eine Bitte: guck mal hier! (https://www.conrad.de/de/p/conrad-energy-modellbau-akkupack-lipo-11-1-v-1000-mah-zellen-zahl-3-25-c-softcase-bec-1344136.html?WT.mc_id=google_pla&WT.srch=1&ef_id=EAIaIQobChMIvLSrm7SA5gIV1OFRCh1ixg3nEAQYAiAB EgL1LvD_BwE:G:s&gclid=EAIaIQobChMIvLSrm7SA5gIV1OFRCh1ixg3nEAQYAiAB EgL1LvD_BwE&hk=SEM&s_kwcid=AL!222!3!367270211652!!!g!!)

So ein 12V LiPo kostet 12 EUR. Ein Ladegerät hst Du doch. Der bringt bis 50A. Damit kannst Du deinen Roboter testen. Um auszuschließen, dass die Spannung einbricht.


aber auch nachher nicht, wenn die FB benutzt wird...

Dann mach aus den 5K , mal 10KOhm. Normalerweise sollte das funktionieren. Nimm mal bitte ein Messgerät, lege den ENABLE-Pin auf Masse (GND) - den Widerstand zwischen dem Pin und +5V drin lassen, und messe mal, an dem Pin die Spannung (nicht vergessen dabei den Ausgang des Arduino abzuklemmen). Dort müssen dann 0V anliegen. Ebenfalls, wenn der Arduino-Ausgang den Pin auf LOW (das sind beim Arduino 0V) schaltet. Ob der Arduino 0V schaltet, kann auch überprüft werden. Mein UNO machte das jedenfalls so, also der 328P.


MfG

- - - Aktualisiert - - -

Und natürlich auch schauen, dass nach Änderungen immer alles richtig verdrahtet ist. Nicht das Verbindungen vom Arduino zum Treiberboard vergessen wurde.

- - - Aktualisiert - - -


wahrscheinlich ein erfolgserlebnis

Jedenfalls war der Gedanke richtig.
Aber besser wärs, die Spannung vom Akku zu stabilisieren und zu entstören und genügend Strom zur Verfügung zu haben, beim Einschalten.

inka
23.11.2019, 13:47
Mal eine Bitte: guck mal hier! (http://www.roboternetz.de/tools/?view_co=1344136) muss ich das verstehen?



Dann mach aus den 5K , mal 10KOhm. Normalerweise sollte das funktionieren. das war's, danke :-)




Aber besser wärs, die Spannung vom Akku zu stabilisieren und zu entstören und genügend Strom zur Verfügung zu haben, beim Einschalten. das war das mit der diode von +12V zu den motoren, bzw. motortreibern. In der richtung muss sie ja auch leitend sein, denke ich... tut's eine schottky 1N5817? Und reicht eine? Die 12V leitung splittet sich erst später in 4 auf...

Moppi
23.11.2019, 13:55
muss ich das verstehen?

Ist ein Akku mit 12V und liefert bis 50A Strom. Muss ja nicht lange durchhalten, zum Probieren reicht es aus.
Oder hast Du was dagegen? - Weiß ja nicht! :)



tut's eine schottky 1N5817

weiß ich nicht, da bin ich zu wenig experte, ich nehme immer Gleichrichterdioden (sowas: https://www.reichelt.de/gleichrichterdiode-axial-7-x-4-5-semik-ska1-17-p247674.html?&trstct=pos_6) gibt es auch etwas kleiner, glaub ich. - Aber ja, nimm die. Habe gerade nachgeschaut, was Schottky ist. Diese Dinger nehme ich sonst auch.


Dann mach aus den 5K , mal 10KOhm. Normalerweise sollte das funktionieren.

-------------------------------
das war's, danke :-)

Funktioniert damit?



das war das mit der diode von +12V zu den motoren, bzw. motortreibern. In der richtung muss sie ja auch leitend sein, denke ich


So ist es.



MfG

inka
23.11.2019, 14:02
https://www.roboternetz.de/community/images/misc/quote_icon.png Zitat von Moppi https://www.roboternetz.de/community/images/buttons/viewpost-right.png (https://www.roboternetz.de/community/showthread.php?p=656737#post656737)
Mal eine Bitte: guck mal hier! (http://www.roboternetz.de/tools/?view_co=1344136)
muss ich das verstehen?

ich meine den link?



Dann mach aus den 5K , mal 10KOhm. Normalerweise sollte das funktionieren.

-------------------------------
das war's, danke :-) Funktioniert damit?
ja, ein kleiner vermutstropfen - der stepper, bei dem ich es mit dem 10K widerstand versuchsweise gemacht habe, steht dauernd unter spannung. Egal was im sketch für den enable-pin angegeben ist, also unabhängig ob HIGH oder LOW. Wie gesagt, wesentlich weniger schlimm, als das rattern...
Muss jetzt alle vier treiberplatinen mit dem widerstand nachrüsten - melde mich wieder :-)

Moppi
23.11.2019, 14:04
ich meine den link?

Ach! Ich habe einen Link von Conrad gehabt!


Hier noch einer: kostet dort 14 EUR bei Conrad zurzeit 12 EUR. (https://www.amazon.de/Conrad-energy-1000-ECO-LINE-LIPO-AKKU/dp/B0107XBMD8)



Wenn das mit dem Widerstand am ENABLE nicht funktioniert, dann lass den weg. Hat keinen Sinn dann.

inka
23.11.2019, 15:38
naja teilweise hats ja funktioniert, das nervende rattern war zumindest weg. Ich hab dann den fliegenden aufbau durch was solideres ersetzt:
34525
und ab dem moment hat's wieder gerattert!
Also, ich werde jetzt den kleinen "vorglüh-akku" einsetzen:
34526
vorgehen beim starten:
- taste drücken, damit wird eine schaltung aktiviert, die von dem akku aus ein RC-glied lädt
- wenn geladen geht eine LED an
- hauptschalter an
- arduino schaltet kleinen akku ab (RC-glied ladeerkennung)

mal sehen ob das geht... :-)

und bis dahin ist der kleine akku dran und es rattert nicht :-)

Moppi
23.11.2019, 16:55
Ich probiere das jetzt mit dem ENABLE aus. Ich hab ja den Aufbau vor mir liegen. Verstehe nicht, warum das nicht funktionieren soll, es sei denn, es gibt intern eine Beschaltung. Davon habe ich aber nichts gelesen.



MfG

- - - Aktualisiert - - -

Also mit 5k bzw. 4.7kOhm am ENABLE-Pin des A4988 funktioniert es, wie erwartet. Ohne Widerstand liegen dort vom Arduino her 5V oder 0V an. Mit Widerstand zwischen ENABLE und Vdd des A4988 liegen 5V oder 0.02V an und der Arduino kann diesen ENABLE-Pin auch steuern. Nur, wenn der Arduino-Ausgang noch nicht initialisiert ist, liegen am ENABLE-Pin (wie erwartet) auch keine 5V an, was normal ist und daran liegt, dass die Ausgänge des Arduino nach Neustart zunächst im hochohmigen Zustand sind. Somit bringt der 4.7k / 5k-Widerstand genau das, was er soll, nämlich für einen definierten Pegel sorgen, wenn der Arduino-Ausgang noch hochohmig ist.
Allerdings ändert dieser Widerstand am ENABLE nichts daran, dass der Motor beim Anschalten der Versorgungsspannung des Treibers kurzzeitig in Bewegung ist, also Strom fließt. Aber vermutlich liegt das Ganze ja sowieso an der Spannungsversorgung.

- - - Aktualisiert - - -

Du solltest unbedingt einen Schaltplan zeichnen, mit Arduino, A4988, div. Widerständen drin, Mäuseklavier etc. Sonst kann man wirklich nicht sagen, warum was bei Dir an der Schaltung nicht funktioniert.

- - - Aktualisiert - - -

Motor Geschwindigkeit steigern


Um den Motor auf Maximalgeschwindigkeit zu bringen, lasse ich im FULL-STEP-Modus diese Testschleife laufen:



int j=2000;
//-----------------------------------------------------------------------------
void loop() {


if(j>280)j--;
for(int i=0;i<3;i++){
digitalWrite(Step, LOW);
delayMicroseconds(j);
digitalWrite(Step, HIGH);
delayMicroseconds(j);
}


}

Sollte jetzt selbsterklärend für Dich sein, inka.






MfG

- - - Aktualisiert - - -


vorgehen beim starten:
- taste drücken, damit wird eine schaltung aktiviert, die von dem akku aus ein RC-glied lädt
- wenn geladen geht eine LED an
- hauptschalter an
- arduino schaltet kleinen akku ab (RC-glied ladeerkennung)


Dann kannst Du auch die Logikspannung der Platinen mit dem Arduino bereitstellen. Falls Du Angst hast, die vier A4988-Platinen würden zu viel Strom benötigen, kann man einen BC547B mit dem Arduino-Ausgang ansteuern. Dann nimmt man den BC547B in Open-Collector-Schaltung, verbindet VDD, des A4988, mit 5V und GND, des A4988, schaltet man über den Transistor. Das Schöne dabei: man kann auch einfach 2 BC547B parallel schalten, um auf insgesamt 200mA Max-Strom zu kommen, das reicht für die vier A4988 allemal aus (eigentlich sollten 100mA ausreichen). Der Effekt: Solange der Arduino hochohmige Ausgänge hat, schaltet der Transistor nicht durch und die A4988 bekommen keinen Strom. Wenn die ohne Logikspannung sind, bewegt sich der Motor nicht. So kann man auch immer die Logikspannung der Treiber mit dem Arduino abschalten und anschalten. - Das wäre mein Joker :) Zur Not wäre so auch jeder Treiber einzeln zuschaltbar, bloß bräuchte es dann vier Arduino-Ausgänge, allerdings kann dann der BC547B gespart werden, weil so viel Strom, wie ein A4988 benötigt, kann ein Arduino-Ausgang bereitstellen.

inka
23.11.2019, 17:07
Ich probiere das jetzt mit dem ENABLE aus. Ich hab ja den Aufbau vor mir liegen. Verstehe nicht, warum das nicht funktionieren soll, es sei denn, es gibt intern eine Beschaltung. Davon habe ich aber nichts gelesen.

ich hab jetzt sogar den arduino ausgetauscht, es rattert. Ich weiss langsam, welchen fehler ich gemacht habe, aber in den kleinen verhältnissen war das gar nicht anders möglich. Ich hab ja quasi ein kabelbaum, der läuft an den wänden entlang, schön aufgeräumt, um nicht noch mehr strippen und durcheinander in der kiste zu haben. So weit so gut, nur laufen dort die 12V leitungen (versorgung der motoren), die 5V leitungen (versorgung motortreiber, arduino...) und fast alle signalleitungen mit ihren paar mA alle schön parallel. Hätte es eigentlich wissen müssen , diese problematik war von 30 jahren mein täglich brot... Da helfen keine paar widerstände am leitungsende...

Ich muss es mit dem hilfsakku machen, sonst sehe ich kein land...


Also mit 5k bzw. 4.7kOhm am ENABLE-Pin des A4988 funktioniert es, wie erwartet. Ohne Widerstand liegen dort vom Arduino her 5V oder 0V an. Mit Widerstand zwischen ENABLE und Vdd des A4988 liegen 5V oder 0.02V an und der Arduino kann diesen ENABLE-Pin auch steuern. Nur, wenn der Arduino-Ausgang noch nicht initialisiert ist, liegen am ENABLE-Pin (wie erwartet) auch keine 5V an, was normal ist und daran liegt, dass die Ausgänge des Arduino nach Neustart zunächst im hochohmigen Zustand sind. Somit bringt der 4.7k / 5k-Widerstand genau das, was er soll, nämlich für einen definierten Pegel sorgen, wenn der Arduino-Ausgang noch hochohmig ist.
Allerdings ändert dieser Widerstand am ENABLE nichts daran, dass der Motor beim Anschalten der Versorgungsspannung des Treibers kurzzeitig in Bewegung ist, also Strom fließt. Aber vermutlich liegt das Ganze ja sowieso an der Spannungsversorgung.

hier verstehe ich auch, was Du da machst und misst, mit einem unterschied, Du hast alles schön frei auf dem tisch vor Dir liegen, bei mir ist alles etwas schwerer zugänglich :-( und dort auch schwer zu messen...


Um den Motor auf Maximalgeschwindigkeit zu bringen, lasse ich im FULL-STEP-Modus diese Testschleife laufen:



int j=2000;
//-----------------------------------------------------------------------------
void loop() {


if(j>280)j--;
for(int i=0;i<3;i++){
digitalWrite(Step, LOW);
delayMicroseconds(j);
digitalWrite(Step, HIGH);
delayMicroseconds(j);
}


}

Sollte jetzt selbsterklärend für Dich sein, inka.

ist es auch, klar...

Moppi
23.11.2019, 17:40
Schirmung ist die eine Sache, die Du nachholen könntest und das Trennen der Leitungen, wo Leistung drüber fließt und derer, wo Signale drüber laufen.
Aber trotzdem: ich glaube nicht so recht, dass dies die Probleme verursacht. Wenn Du die Spannung aus dem DC/DC-Konverter und alle Signale, sowie alle leistungsführenden Kabel alle schön gerade zusammengebunden über 30cm Länge nebeneinander her führst, kann es natürlich sein, dass Du Dir Störungen auf den Signalleitungen fabrizierst. Aber für mich sieht dies Problem genau nach dem aus, dass ich beim Hexapod auch habe/hatte und kenne, dass eben die Leistung des Akkus/Netzteils nicht ausreichend ist, mit einer 2000mAh Powerbank wird es dann ganz verrückt, dann treten solche Sachen während stärkerer Belastungen auf, dass eben die Elektronik verrückt spielt und die Motoren dann infolge am Zappeln sind. Du wirst wahrscheinlich die Verkabelung ändern müssen, wenn Du zukünftig von Problemen verschont bleiben willst. :(

Ist eben die Frage, ob Dir eine Bastelei ausreichend ist oder ob Du ein solides Projekt haben möchtest.

Holomino
23.11.2019, 18:05
Mal generell zum Aufbau:
- Versorgungsstrippen kurz (und dick), Motorleitungen lang (und ausreichend)
- Versorgung sternförmig von der Quelle weg
- Wenn was über eine Diode abgeblockt werden muss, dann tunlichst mit einem Kondensator dahinter. Damit Der nicht unendlich groß wird, empfielt es sich, den Zweig mit der geringsten Stromaufnahme abzublocken (wahrscheinlich also die wenigen mA vom Controller). Treiberbausteine über Dioden in der Versorgung abzublocken ist eher kontraproduktiv. Über die Freilaufdioden in den Treibern müssen Überspannungsimpulse der Motorinduktivitäten frei auf die Versorgung rückgekoppelt werden können.

Vielleicht macht es also Sinn, die ganze Elektronik in eine Ecke zu packen und nur die Motorleitungen über einen Kabelbaum zu verteilen.

Wegen der /Enabled-Leitung: Hast Du mal den Durchgang zwischen Eingang am Shield und Pin auf dem Treiberboard geprüft? Was ist denn noch auf diesem Shield? Ist da noch ein Regler drauf? Gibts dazu nen Schaltplan?

Moppi
23.11.2019, 18:18
Über die Freilaufdioden in den Treibern müssen Überspannungsimpulse der Motorinduktivitäten frei auf die Versorgung rückgekoppelt werden können.

Freilaufdioden schalten Gegen-EMK gegen Masse kurz, das ist doch gegeben. Selbst wenn die Plusleitung über eine Diode geführt wird.
Deshalb würden mich die Hintergründe dazu genauer interessieren, warum Überspannungsimpulse auf bspw. ein Netzteil rückgekoppelt werden müssen.


NUr so am Rande: wir hatten so was mal, dass Überspannung ins Stromnetz rückgekoppelt wurde, bei einem Fernseher (defekter Zeilentrafo oder was auch immer). Dabei ist die Sicherung des DVD-Players durchgegangen und die Stereoanlage hat gebrannt. Zum Glück war ich zu dem Zeitpunkt im Raum, weil ich fern gesehen habe.

MfG

inka
23.11.2019, 18:29
Mal generell zum Aufbau:
- Versorgungsstrippen kurz (und dick), Motorleitungen lang (und ausreichend)
- Versorgung sternförmig von der Quelle weg
das ist der letzter stand des aufbaus:
34527
die verbindungen basieren an den dupont litzen, also AWG30 schätze ich mal...



Wegen der /Enabled-Leitung: Hast Du mal den Durchgang zwischen Eingang am Shield und Pin auf dem Treiberboard geprüft? Was ist denn noch auf diesem Shield? Ist da noch ein Regler drauf? Gibts dazu nen Schaltplan?
meinst Du ob der A4988 kontakt zum extenderboard hat? Hat er...

das ist das einzige was an "unterlagen" zu finden war:
34528 34529


@Moppi:
Ist eben die Frage, ob Dir eine Bastelei ausreichend ist oder ob Du ein solides Projekt haben möchtest.

kennst Du die 20/80 regel?

Moppi
23.11.2019, 18:56
kennst Du die 20/80 regel?

Gehört: kann sein, kennen: nein

Klebwax
23.11.2019, 19:36
Aber trotzdem: ich glaube nicht so recht, dass dies die Probleme verursacht.

Das sehe ich auch so. Dazu nur mal ein paar Daumenwerte: Bei CMOS-Logik liegen die Schaltschwellen bei etwa 1/3 und 2/3 der Versorgung. Bei 5V bedeutet das, alles unter 1,6V ist eine 0, alles über 3,4V ist eine 1. Ein Signal von 1V mit einem Ripple von 100mV ist eine glatte 0. Selbst bei 200mV Ripple gilt das noch. Die oben erwänten 0,02V sind einfach 0. Am Ende zählt aber die Spannung, die am Modul anliegt und nicht der Wert, den die SW ausgibt. Daher sollte man sich alle Signale auf dem Scope anschauen. Bei mir läuft bei solchen Entwicklungen das Scope immer mit.

Und bevor man anfängt, eine Sache umzubauen, die eigentlich funktionieren sollte, ist es sinnvoll den wirklichen Fehler zu finden. Sonst macht man ihn beim Umbau noch einmal. Dazu einen Schaltplan erstellen und den Plan der Treibermodule mit einbeziehen. Der ist bei Pollolu zu finden. Nicht jeden Pullup/Pulldown muß man selbst setzen, an SLEEP z.B. ist schon einer drauf. Die Pullup/Pulldown sind keine analogen Teile, sie können Werte zwischen 0Ω (Achtung, Gefahr eines Kurzschluß beim Abrutschen mit dem Tastkopf) und 50kΩ haben. Sollte sich ein unterschiedliches Verhalten bei unterschiedlichen Werten ergeben, liegt ein anderer Fehler vor. Da die Pullup/Pulldown auf den Treiber wirken sollen, sollten sie auch nahe bei ihm sein. Das macht es schnellen (µs) Störungen schwerer an den Treiber zu kommen.

In einem der vorigen Posts war von 9V und 1A die Rede. Kleiner als 9V (eigentlich 8V nach Datenblatt) sollte die Versorgung nicht sein. Der Chip schaltet sich sonst wegen Unterspannung ab. Die Maximalspannung des Chips, und mehr ist auf dem Board ja nicht drauf, beträgt 35V. Und ein Netzteil mit weniger als 1A dürfte selbst bei kleinen Strangströmen Probleme haben.

Zu guter letzt: diese Module sind eigentlich keine Schrittmotortreiber, obwohl ich sie selbst so bezeichne. Es sind Eval bzw Breakouboards der A4988 Chips von Allegro (oder der DRV8825 Chips von TI) für Entwickler und Bastler. Sie machen SMD Chips steckbretttauglich. Ein industrieller Schrittmotortreibern sieht ganz anders aus. Wie aus dem Schaltplan ersichtlich, enthalten sie nur das Minimum an notwendiger externer Beschaltung. Man könnte auch sagen, sie enthalten schon das Minimum, um einem das Entwickeln zu erleichtern. Alle Daten gehen also aus dem Datenblatt des Chips hervor, die Pollolu Entwickler geben dazu noch zusätzlich Tips aus ihrer Praxis. So benutzen sie den Pullup von SLEEP auch für RST, indem sie beide Anschlüsse verbinden. Das spart den Anschluß eines eigenen Pullups. Wenn man aber SLEEP oder RST aktiv steuert, geht das natürlich nicht. Für das Verhalten dieser Boards ist also das Datenblatt die Bibel. Und ansonsten Messen statt vermuten.

MfG Klebwax

Moppi
23.11.2019, 21:58
an die 5V und GND pins einen kleinen lipo akku (ich sündige mal hier) mit 3.7V zu hängen und den vor dem einschalten des roboters mit seinen steppern, quai als "vorglühen" beim diesel :-) für 5 sekunden dazuzuschalten?

Ich habe es noch nicht verstanden. Erstmal soll man an die Arduino-Pins keine Spannung einspeisen. Die 5V oder 3.3V an der Stiftbuchsenleiste kommen doch von einem Spannungsregler oder nicht? Warum sollen dort am 5V-Pin 4V eingespeist werden? Was soll das ändern?


Hier mal eine Übersetzung aus dem Datenblatt eines mega2560:


Der Arduino Mega kann über den USB-Anschluss oder mit einem externen Netzteil betrieben werden.Die Stromquelle wird automatisch ausgewählt.
Externe (Nicht-USB-) Stromversorgung kann entweder von einem AC-zu-DC-Adapter (Wall-Wart) oder von einem anderen Gerät erfolgen.
Batterie. Der Adapter kann durch Einstecken eines 2,1 mm Mittelpositivsteckers in das Gerät angeschlossen werden.
an der Strombuchse des Boards. Leitungen von einer Batterie können in die Stiftleisten Gnd und Vin von
den POWER-Anschluss.
Das Board kann mit einer externen Versorgung von 6 bis 20 Volt betrieben werden. Bei Lieferung mit weniger als
7V, jedoch kann der 5V-Pin weniger als fünf Volt liefern und die Platine kann instabil sein.
Bei Verwendung von mehr als 12V kann der Spannungsregler überhitzen und die Platine beschädigen. Die
empfohlener Bereich ist 7 bis 12 Volt.




Übersetzt mit www.DeepL.com/Translator (http://www.DeepL.com/Translator)

Ich denke jetzt mal, dass Du "die Stiftleisten Gnd und Vin" vom Power-Anschluss meinst. Aber wieso mit 4V da dran? Vielleicht mag ein mega2560 auch mit 3.3V betrieben werden können - keine Ahnung jetzt.


...für 5 sekunden dazuzuschalten?

Mag vielleicht funktionieren, aber für die Arduino-Ausgänge gibts eine Definition, die müsste im Datenblatt stehen. Genannt hatte ich die auch schon, man muss sie nur kennen: bevor die Pins im Programm definiert sind, sind die im "Z3-State", also weder Eingang, noch Ausgang. Mit dem Wissen kann man seine Beschaltung logisch sicher gestalten. Und genau aus diesem Grund, falls das zu unsicher sein sollte, kann man mit einem Arduino-Pin Transistoren in Open-Collector-Schaltung als Treiber steuern. Dann hast Du genau den Effekt, dass erst der Arduino gestartet und vom Programm her initialisiert sein muss, bevor die A4988-Module überhaupt bestromt werden und die Motoren eine Chance hätten, zu drehen. Da sparst Du den ganzen merkwürdigen Klamauk mit "Vorglühtaste".

So, wie Du das aber beschreibst, dass das Motorchassis nur funktioniert, wenn der Arduino mit unabhängiger Spannungsquelle versorgt ist, dann müsste das doch auch immer so sein (getrennte Stromkreise oder wenigstens eine Entkopplung).
Und wenn das eher unerwünscht ist, dann muss dafür gesorgt werden, dass möglichst keine entgegengerichteten Ströme (falls so etwas überhaupt da ist) zurück zur Spannungsquelle fließen, weil die dann auch an dem Arduino-Spannungseingang ankommen. Eine Freilaufdiode, direkt am Abzweig zu den Motorversorgungen, könnte das verhindern. Wenn das nicht reicht, kann man eine Freilaufdiode auch am Arduino-Spannungseingang schalten, wenn das besser wäre. Zu hohe Spannungen sollten auch nicht zurückfließen können - meine Meinung, denn das käme auch am Arduino-Spannungseingang an. Man könnte eine Stromkreis-Entkopplung vornehmen (idee zwei getrennter Stromkreise); Diode in Plus zur Versorgung der Motoren, wäre eine Möglichkeit. Spannungseinbrüche haben wir auch schon besprochen. Deshalb noch mal, ich weiß dass das evtl. nervt: Die Spannungsquelle muss belastbar sein und Reserve nach oben haben, nicht zu knapp ausgelegt. Wenn dann die Spannungsquelle belastbar genug ist und massive Störungen auf der Versorgungsleitung am Arduino-Eingang ausgeschlossen sind und man vermutet, dass die Arduino-Ausgänge im hochohmigen Zustand zu Problemen führen, könnte man die Spannungsversorgung, der A4988, vom Arduino aus steuern oder Pull-Up-/Pull-Down-Widerstände einsetzen.


Wichtig:

Egal, ob der Arduino bereits im Betrieb ist oder nicht. Sobald der A4988, in der Beschaltung RESET+SLEEP verbunden und mit 5k-Ohm Pull-Up versehen - weil so ist die Schaltung hier und so habe ich sie nachgebaut, mit Spannung versorgt wird / an die Versorgung angeschlossen wird, dreht sich der angeschlossene Stepper, d.h. dort fließt kurzzeitig Strom durch die Spulen (schätzungsweise eine viertel Sekunde). Liegt vielleicht auch daran, was das Datenblatt beschreibt:

At power-on or reset, the translator sets the DACs and the phasecurrent polarity to the initial Home state (shown in Figures 9
through 13), and the current regulator to Mixed decay mode for
both phases.
Sollten Störungen durch die Motorspulen entstehen, die störend wirken, sind die also in jedem Fall da, wenn sie nicht wirkungsvoll unterdrückt wurden. Sollten die Störungen durch Einschaltstromspitzen der Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) entstehen, sind die, aus demselben Grund, auch da und nicht verschwunden (siehe 100µF-Elko, habe auch schon 220µF gesehen).


Gut, in Ordnung. Ich hatte das mit dem "vorglühen" noch nicht kapiert. Und jetzt doch wieder alle Gedanken dazu aufgeschrieben und verm. viel zu viel. :)





MfG

inka
24.11.2019, 09:33
moin,


Gehört: kann sein, kennen: nein
zunächst der einfachere teil (20/80 regel):

für's erreichen von 80% der gewollten/spezifizierten funktionalität eine gerätes braucht man 20% der gestellten mittel (geld, zeit...), für die restlichen 20% der funktionalität auch die restlichen 80% der mittel. Folglich muss man sich überlegen, wann man aufhört und zufrieden zu sein hat :-)

was die stromversorgung von einem arduino betrifft hier ein link (https://michaelsarduino.blogspot.com/2015/07/arduino-mit-strom-versorgen.html)...

weiteres im laufe des tages...

Moppi
24.11.2019, 10:10
Inka, das ist ein UNO, kein MEGA. Aber egal. Schau mal ins Datenblatt vom MEGA2560, wo die Pins für die Stromversorgung sind.

Ich verbuche dieses: "was die stromversorgung von einem arduino betrifft hier ein link (https://michaelsarduino.blogspot.com/2015/07/arduino-mit-strom-versorgen.html)..." mal unter 20/80-Regel ;)

:)

"weiteres im laufe des tages..."

Ich habe meinen Testschaltkreis abgebaut und alles brav weggeräumt.
Mal sehen, wie es weiter geht.


Übrigens habe ich da mal was gefunden. (https://www.amazon.de/gp/product/B077CZVZTJ) Ist nicht so teuer, auch nicht so genau sicherlich etc. Aber für 0815-Überprüfung der Leitungen könnte das doch ausreichend sein!?
Da ich noch keins habe, bestelle ich mal so ein Teil. Besser als gar nichts.



MfG

- - - Aktualisiert - - -

Da wir hier im Forum das Thema auch schon mehrfach hatten, habe ich nochmal einen nützlichen Beitrag auf github (https://github.com/Ardumower/ardumower/blob/master/Dokumentation/Motor%20Entstoerung/Motor%20EntstoerungREV20150531.pdf) rausgekramt. Sehr lesenswert, mit genauer Erklärung und vielen Bildern.

inka
24.11.2019, 10:13
Inka, das ist ein UNO, kein MEGA. Aber egal. Schau mal ins Datenblatt vom MEGA2560, wo die Pins für die Stromversorgung sind. klar ist es ein UNO, ich bin halt davon ausgegangen, dass die "grungsätzlichen" pins und anchlüsse - und dazu zähle ich auch die 5V und GND pins auch - identische funktionen haben. Vielleicht ein trugschluss, aber das mit dem kleinen 3,7V lipoakku da dran funktioniert, nachprüfbar :-)




Übrigens habe ich da mal was gefunden. (https://www.amazon.de/gp/product/B077CZVZTJ) Ist nicht so teuer, auch nicht so genau sicherlich etc. Aber für 0815-Überprüfung der Leitungen könnte das doch ausreichend sein!?
Da ich noch keins habe, bestelle ich mal so ein Teil. Besser als gar nichts.
was es heutzutage nicht alles schon gibt:-)? Ich habe mir mal für viel geld einen gebrauchten HAMEG HM203 angeschafft, kann damit nicht umgehen. Ziert nur mein arbeitsplatz und schindet eindruck, wenn's mal einer sieht :-(

EDIT:
ok, ich hab alles von @klebwaxs und von Dir gelesen, der versuch mit dem 3,7V am 5V pin war und ist dilettantisch, auch wenn es funktioniert hat....
Ich habe noch die 12V versorgung aus dem kabelbaum rausgenommen, bzw. an beiden seiten abgeklemmt und durch freiverdrahtung ersetzt, keine änderung, die stepper rattern. Also hätten wir auch diese "ursache" abgeräumt. Bleibt wirklich noch der akku und das zusammenbrechen der 12V und damit der 5V versorgung des arduino.
Ich glaube nicht, dass es mir gelingt mit einem vernünftigem aufwand das zusammenbrechen der spannung beim einschalten der stepper zu verhindern, der/die akkus sind da und sollten auch verwendet werden....
Würde es was bringen den einschaltvorgang in zwei stufen aufzuteilen? Schalter 1: 12V und 5V arduino, paar sekunden später schalter 2: stepper?

Moppi
24.11.2019, 11:39
Dazu hatte ich ganz viel geschrieben.
Um es einfach auszuprobieren:

1. nimm die Leitung vom Arduino zum ENABLE-Pin, am ENABLE-Pin, weg.
2. Verbinde den ENABLE-Pin mit GND.
3. Trenne die Verbindung von Vdd, des A4988, zu +5V.
4. Nimm die Leitung, die vom ENABLE-Pin weggenommen wurde und verbinde sie mit Vdd (Logikspannung) des A4988.
5. Nimm für jeden A4988 einen Arduino-Ausgang. Im MEGA-Datenblatt steht was von nur 40mA, das ist gut für EINEN A4988 (normal könnte man 4 Treiber damit versorgen, könnte aber zu knapp werden).

Jetzt kannst Du jeden A4988 extra einschalten, nachdem der Arduino gestartet ist. Solange der A4988 keine Logikspannung bekommt, gibt der Motor Ruhe.

A4988#1 anschalten - 2s Pause - A4988#2 anschalten - 2s Pause - A4988#3 anschalten - 2s Pause - A4988#4 anschalten

Pausen können dann verkürzt werden, bis die Probleme erneut auftreten, dann die Pausen wieder etwas verlängern.
Gilt natürlich alles nur, wenn es Einschaltspitzen sind, die den Akku zu sehr belasten, in welcher Form auch immer.

- - - Aktualisiert - - -

Wenn ich das richtig sehe, können die 12V für die Motorspannung ruhig von Anfang an am A4988 anliegen. Die DMOS-Bridge wird solange nicht gesteuert, wie keine Logikspannung am A4988 anliegt. Also bekommen auch die Motoren keinerlei Strom.

- - - Aktualisiert - - -

Man soll die Motorspannung nicht abklemmen, wenn der A4988 in Betrieb ist. Normal ist das kein Problem, wenn die Treiberstufe des A4988 keinen Strom zu den Motorwicklungen leitet, machst Du da aber einen Fehler im Programm, könntest Du den Treiber zerstören, wenn Du die Motorspannung nach der Logikspannung anlegst.

- - - Aktualisiert - - -

Falls Du einen Riesenelko (4700µF, 10000µF, 22000µF) hast, könntest Du auch den noch mit in die Versorgung hängen, vielleicht behebt es das Problem schon (wäre vielleicht weniger aufwendig).

Klebwax
24.11.2019, 12:51
Ich glaube nicht, dass es mir gelingt mit einem vernünftigem aufwand das zusammenbrechen der spannung beim einschalten der stepper zu verhindern,

Bist du sicher, daß die Spannung zusammenbricht oder ist es eine Vermutung?


..gebrauchten HAMEG HM203 angeschafft...

Ein analoges Scope hilft dir bei einmaligen Ereignissen wie deinem Startproblemen leider nicht wirklich. Da braucht man einen Speicher. Aber zum Überprüfen von Signalen geht das schon. Einfach den Trigger auf AUTO stellen. Die Zeitbasis wird auf einen Millisekundenwert eingestell. Dann sollten 2 Linien für die 2 Kanäle zu sehen sein. Jetzt den Eingang auf 2V/cm und den Masseclip an GND. Wenn man jetzt mit der Tastspitze an 5V geht, springt die Linie um 2,5cm, 5V halt, nach oben. Jetzt kann man ganz schnell alle Signale ansehen. Wenn die nicht entweder auch 5V oder 0V haben, muß man sich dieses Signal genauer ansehen. Wenn ich etwas länger beobachten will, klemme ich die Tastspitze fest. Zur Not löte ich ein krzes Drahtstück an den Anschluß und klemme da den Tastkopf an. So kann man auch zwei Signale gleichzeitig ansehen. Und dann mit Single-Step durchs Programm und schauen, ob die Signale dem entsprechen, was man meint programmiert zu haben.

MfG Klebwax

inka
24.11.2019, 15:31
Um es einfach auszuprobieren:

1. nimm die Leitung vom Arduino zum ENABLE-Pin, am ENABLE-Pin, weg.
2. Verbinde den ENABLE-Pin mit GND.
3. Trenne die Verbindung von Vdd, des A4988, zu +5V.
4. Nimm die Leitung, die vom ENABLE-Pin weggenommen wurde und verbinde sie mit Vdd (Logikspannung) des A4988.
5. Nimm für jeden A4988 einen Arduino-Ausgang. Im MEGA-Datenblatt steht was von nur 40mA, das ist gut für EINEN A4988 (normal könnte man 4 Treiber damit versorgen, könnte aber zu knapp werden).

Jetzt kannst Du jeden A4988 extra einschalten, nachdem der Arduino gestartet ist. Solange der A4988 keine Logikspannung bekommt, gibt der Motor Ruhe.
Der ENABLE-pin war mit arduino-pin 40 (beispiel) verbunden. Ich könnte also diese verbindung nutzen um den Vdd pin des A4988 mit arduino zu verbinden und mit dem befehl "digitalWrite (40,HIGH)" den A4988 einschalten.

- - - Aktualisiert - - -


Bist du sicher, daß die Spannung zusammenbricht oder ist es eine Vermutung?
ich hatte beim einschalten am 12V anschluss ein voltmeter hängen. Es zeigte beim einschalten sehr kurz 10V, dann ca.6 bis 7V und dann - nach dem rattern - 11V.

Moppi
24.11.2019, 17:21
Der ENABLE-pin war mit arduino-pin 40 (beispiel) verbunden. Ich könnte also diese verbindung nutzen um den Vdd pin des A4988 mit arduino zu verbinden und mit dem befehl "digitalWrite (40,HIGH)" den A4988 einschalten.


Hast Du richtig verstanden.



MfG

- - - Aktualisiert - - -

Ich habe mich nochmal mit der Batterie beschäftigt, weil manchmal bekommt man aus China Produkte, die nicht das halten, was sie versprechen. Ich habe mir jetzt eine 1-Stern-Bewertung angesehen:


Lieferung ist sehr schnell. Die batterie arbeitet richtig. Aber drei von sechs batterien ist nur ein dummy. ICH hoch zweifel, dass in die batterie 8 amps. Tun nicht overpay für müll.

Batterie kapazität ist über 1000-1200 mAh. Ist nicht in der lage, entladung zu mehr als 0, 6A (nicht 5A als verkäufer sagt). Die batterie aufgeladen ist in 2 stunden mit dem verkäufer ladegerät (500 mA).

Die produkt nicht spiel die beschreibung 8000mAh für 6 zellen 18650 von 2500mAh max in serie es der 2500mAh und nicht 8000mAh

Inka, prüfe bitte die Batterie/Akku, ob alle Zellen vorhanden sind und irgendwie auch, ob die die angegebene Kapazität hat.


Daten Deines Akkus:

Nennspannung: 12 V Eingangs spannung: 12,6 V
Ausgang spannung: 9 V-12,6 V
Batterie kapazität: 8000 mAh (8Ah)
Insgesamt gewicht: weniger als 300 gramm
Preis: 12 EUR inkl. Netzteil



Im Vergleich ein "richtiges" Li-Ion Akkupack, bei Conrad zu finden (Akkupack 3x 18650 Kabel Li-Ion 3.7 V 7800 mAh):


Zellen-Zahl: 3
Spannung: 3.7 V
Kapazität: 7800 mAh
Technologie: Li-Ion
Gewicht: 140 g
Preis: 50 EUR exkl. Netzteil



Wenn man damit auf 11.1V kommen möchte, muss man also 3 Packs davon nehmen, das sind dann 420g.
Wie kann dann der Akku, den Du gekauft hast, mit 12 bis 12.6V, 8000mAh, mehr als 120g weniger wiegen?

Im Vergleich würde ein LiPo_Akku mit 11.1V Nennspannung (voll geladen 12.6V) und 8000mAh ca. 65,-EUR kosten. Bei Conrad: 11.1V LiPo 5000mAh = 41,-EUR.



MfG

inka
25.11.2019, 11:12
hallo Moppi,

mit diesem


// DIR und STEP pins definieren
#define dirPin_HL 4
#define stepPin_HL 5


//start pin definieren
#define start_HL 42


//steps pro umdrehung definieren:
#define stepsPerRevolution 200


void setup()
{
//pins als output:

pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(start_HL, OUTPUT);

//richtung bestimmen
digitalWrite(dirPin_HL, HIGH);

Serial.begin(115200);

void loop()
{
delay(2000);
digitalWrite(start_HL, HIGH);
delay(2000);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_HL, HIGH);
delayMicroseconds(500);

digitalWrite(stepPin_HL, LOW);
delayMicroseconds(500);
}
}


wird der stepper HL aktiviert, alle 2 sec macht der jeweils eine sequenz in CW richtung, es rattert nicht, es scheint zu funktionieren. Jetzt muss ich die verdrahtung etwas ordentlicher machen und alle vier stepper anschliessen. Vielleicht auch in umgekehrter reihenfolge....

Mit den akkus beschäftige ich mich anschliessend, die machen eigentlich einen guten eindruck, das was man halt sehen kann. Das gewicht ist natürlich gering, 270gramm. Die spannung stimmt wohl auch mit den angaben überein, ob die kapazität stimmt? Wie soll ich das denn messen? Wenn das mit dem rattern nun weg sein sollte, lasse ich den roboter über meine wippe hin und her fahren. Bis die akkus leer sind...

Moppi
25.11.2019, 11:51
Mit den akkus beschäftige ich mich anschliessend, die machen eigentlich einen guten eindruck, das was man halt sehen kann.

Wenn, sehe ich auch eher das Problem, dass der Akku die Leistung nicht bringt. Da steht zwar 5000mA Dauerstrom, aber ich glaube das nicht. Wenn die Spannung auf 50% einbricht, wie Du gemessen hast. Und die Stepper ziehen doch nicht so viel Strom beim Einschalten, oder? Ich rechne da mal mit 250mA pro Motor. Das sind bei 4 Motoren 1A. Gut, lass es 1.5A, beim Einschalten, sein. Aber dass dort die Spannung schon so weit einbricht? Dann müssten die Akkus sehr schlechte Qualität haben bzw. mit max. 1A belastbar sein. Das sagt mein Bauch, da dies nicht meine Hauptbeschäftigung ist, kann der sich auch gewaltig irren. Eine Gegen-EMK von 4 bis 6V? Kann ich mir auch nicht so recht vorstellen. Aber rein theoretisch ergeben +12V vom Akku und -6V Gegen-EMK evtl. eben +6V zu dem Zeitpunkt, wo beides aufeinandertrifft, dann fällt die Elektronik aus und alles beginnt von vorn, bis sich das innerhalb 1sec aufgeschaukelt hat, dass es endlich stabil ist?

Du kannst natürlich die mA auch mal messen, die dort beim Einschalten vorhanden sind.



wird der Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) HL aktiviert, alle 2 sec macht der jeweils eine sequenz in CW richtung, es rattert nicht, es scheint zu funktionieren. Jetzt muss ich die verdrahtung etwas ordentlicher machen und alle vier Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) anschliessen. Vielleicht auch in umgekehrter reihenfolge....

was bedeutet "alle 2 sec macht der jeweils eine sequenz in CW richtung"?
und das " und alle vier Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) anschliessen. Vielleicht auch in umgekehrter reihenfolge...." verstehe ich auch nicht, Du schon, Du kennst Deine Technik und hast sie vor Dir.




MfG

- - - Aktualisiert - - -

was bedeutet "alle 2 sec macht der jeweils eine sequenz in CW richtung"?

Ok, habe mir den Code angesehen, das ist also Normalzustand. - Ist ja schon mal gut.

- - - Aktualisiert - - -

Andersum fährt das Teil auch mit den Akkus, ohne auszufallen. Wenn das Oszi funktioniert, kannst Du mal damit messen, Du musst rausfinden, was auf den Leitungen los ist, um späteren Problemen vorzubeugen.

inka
25.11.2019, 12:18
was bedeutet "alle 2 sec macht der jeweils eine sequenz in CW richtung"?
und das " und alle vier Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) anschliessen. Vielleicht auch in umgekehrter reihenfolge...." verstehe ich auch nicht, Du schon, Du kennst Deine Technik und hast sie vor Dir.

das erste ist nun klar - nach 2sec delay macht er ein paar steps - usw... das zweite bedeutet, erstmal vielleicht quick&dirty alle stepper verdrahten und erst dann aufräumen :.-)

EDIT:
quick&dirty verdrahtung fertig und es läuft!!!!!! :-) :-)

danke noch einmal für die letzte idee, so wie es jetzt ist soll es sein :-)

Moppi
25.11.2019, 14:35
Was mich jetzt vor allem interessiert, ist - natürlich - wie schnell hintereinander die A4988 zugeschaltet werden können, ohne, dass es Probleme gibt.
Wäre nett, wenn Du das noch ausprobieren/mitteilen könntest!

Später musst Du dran denken, wenn Du die Spannung der A4988 abschaltest, weil die anhalten sollen, dass dann das Haltedrehmoment weg ist. Die Treiber müssen immer aktiviert bleiben.



danke noch einmal für die letzte idee, so wie es jetzt ist soll es sein http://www.roboternetz.de/phpBB2/images/smiles/icon_biggrin.gif

War ganz schön anstrengend ;)

Und natürlich würden uns alle auch Messergebnisse der Leitungen interessieren, was die Störpegel angeht. Klebwax hatte doch geschrieben, wie Du mit Deinem Gerät messen kannst.

MfG

inka
25.11.2019, 15:02
Was mich jetzt vor allem interessiert, ist - natürlich - wie schnell hintereinander die A4988 zugeschaltet werden können, ohne, dass es Probleme gibt.
momentan schalte ich die motortreiber (alle auf einmal - zumindest in einem anweisungsblock "nacheinander" an) erst mit dem anschalten / auswählen der bewegung mit der FB ein. Aber auch wenn ich sie im setup() aktiviere, gibt es keinerlei probleme. Es macht kurz einmal klack und sie sind an.



//libraries
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <IRremote.h>
#include <Bounce2.h>


uint8_t RECV_PIN = 13;
uint8_t taste = 0;
uint8_t zaehler = 1;

//resett pin definieren
#define PIN2RESET 10


// DIR und STEP pins definieren
#define dirPin_VL 2
#define stepPin_VL 3
#define dirPin_HL 4
#define stepPin_HL 5
#define dirPin_VR 6
#define stepPin_VR 7
#define dirPin_HR 8
#define stepPin_HR 9

//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43

//steps pro umdrehung definieren:
#define stepsPerRevolution 200

//IR pin definieren
IRrecv irrecv(RECV_PIN);

decode_results results;

// debouncer instanz definieren
Bounce debouncer = Bounce();


void setup()
{

//pins als output:

pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(enbl_VL, OUTPUT); //<---
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(enbl_HL, OUTPUT); //<---
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(enbl_VR, OUTPUT); //<---
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
pinMode(enbl_HR, OUTPUT); //<---


Serial.begin(115200);

Serial.println("code----/home/georg/Arduino/outdoor_robo/stepper/test_vier_stepper/ohne_lib/remote_vier_stepper_switch_1_enbl_bounce");

//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);

// IR empfänger pin mit bounce verbinden
debouncer.attach(RECV_PIN);

// debounce interval in ms
debouncer.interval(5);

// starte IR receiver
irrecv.enableIRIn();

/*
//enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);
*/


//enable pins deaktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}

void loop()
{
/*
// aktiviere enable pins:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
*/

// bounce instance updaten:
debouncer.update();

// neuen bounce wert holen :
zaehler = debouncer.read();

if (zaehler == 1)
{
zaehler = 0;
// taste = 0;
if (irrecv.decode(&results))
{
taste = results.value;
Serial.println(taste);
// delay(1000);
// nächsten IR-wert empfangen
irrecv.resume();
}

}
tasten_abfrage();

}


/************************************************** *********/

void tasten_abfrage(void)
{
switch (taste)
{

case 151 ://taste 1 große FB
{
if (taste == 151 )
{
Serial.println("szenario_1");
Serial1.println("szenario_1");

//fahre szenario_1

delay (1000);

break;
}
}

case 103://taste 2 große FB
{
if (taste == 103)
{
Serial.println("szenario_2");
Serial1.println("szenario_2");

//fahre szenario_2

delay (1000);

break;
}
}

case 79://taste 3 große FB
{
if (taste == 79)
{
Serial.println("szenario_3");
Serial1.println("szenario_3");

//fahre szenario_3

delay (1000);

break;
}
}


case 207://taste 4 große FB
{
if (taste == 207)
{
Serial.println("szenario_4");
Serial1.println("szenario_4");

//fahre szenario_4

delay (1000);

break;
}
}


case 253://OK taste, motor stop
{
if (taste == 253)
{
alle_stepper_stop();

break;
}
}


case 61:// rotate rechts große FB
{
if (taste == 61)
{
rechts_drehen();

break;
}
}


case 221:// rotate links große FB
{
if (taste == 221)
{
links_drehen();

break;
}

}


case 157:// fahre vor große FB
{
if (taste == 157)
{
vorwaerts();

break;
}
}


case 87:// fahre rückwärts große FB
{
if (taste == 87)
{
rueckwaerts();

break;
}
}
}


}


/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
reboot();
}

/************************************************** *********/
void vorwaerts(void)
{

// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(250);
}
}


/************************************************** ********/

void rueckwaerts(void)
{

// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}

/************************************************** *********/
void rechts_drehen(void)
{

// enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}

}


/************************************************** ********/
void links_drehen(void)
{

//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}

}

/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/

/************************************************** **********/




Später musst Du dran denken, wenn Du die Spannung der A4988 abschaltest, weil die anhalten sollen, dass dann das Haltedrehmoment weg ist. Die Treiber müssen immer aktiviert bleiben.
warum? damit der roboter nicht wegrollt?


Und natürlich würden uns alle auch Messergebnisse der Leitungen interessieren, was die Störpegel angeht. Klebwax hatte doch geschrieben, wie Du mit Deinem Gerät messen kannst.
wird gemacht, allerdings wird in der verdrahtung erstmal aufgeräumt. :-)

Moppi
25.11.2019, 16:48
warum? damit der roboter nicht wegrollt?

Ja. Obwohl der so einfach nicht wegrollt, bei Schrittmotoren. Aber das wirst Du dann sehen. Nur dass Du Bescheid weißt.


momentan schalte ich die motortreiber (alle auf einmal - zumindest in einem anweisungsblock "nacheinander" an) erst mit dem anschalten / auswählen der bewegung mit der FB ein. Aber auch wenn ich sie im setup() aktiviere, gibt es keinerlei probleme. Es macht kurz einmal klack und sie sind an.

Gut. Dann war's wohl vor allem wichtig, dass der Arduino vor den Treibern "an" ist. Welche Wechselspiele die auch immer miteinander ausgefochten haben.
Dann könntest Du von vier benötigten Arduino-Ausgängen auf einen reduzieren. Kannst einen MOSFET nachschalten, weil ich beim andern Thema gerade dabei war. Ich weiß aber nicht, ob ein MOSFET so schnell schaltet, nicht dass es dadurch wieder zu Problemen kommt. Deshalb würde ich, weil ich weiß, dass das funktioniert, einen BC547B nehmen. Am Arduino-Ausgang einen 2.2k-Widerstand anschließen (oder 1k, oder 4.7k), an das andere Ende des Widerstands die Basis des Transistor anschließen, Emitter des Transistor an GND verbinden und den Kollektor mit GND der Logikspannung der vier A4988. Vdd der Logikspannung, der A4988, dann mit +5V verbinden.



MfG

Klebwax
25.11.2019, 17:44
Dann könntest Du von vier benötigten Arduino-Ausgängen auf einen reduzieren.

Ja, das geht so. Ein Logikausgang kann viele Logikeingänge treiben. Vier Eingänge an einem Ausgang sind kein Problem. Bei CMOS Bausteinen, die quasi keinen Eingangsstrom brauchen (beim A4988 typ. weniger als 1µA) können das auch 10 oder mehr sein. Alles andere bringt nur Probleme, die man nicht braucht.

MfG Klebwax

Moppi
25.11.2019, 17:46
Hallo inka,

für Deinen Code hätte ich einen Vorschlag, um den Ruck beim Anfahren zu reduzieren.

Der Codeteil, den ich meine:


/************************************************** ********/
void links_drehen(void)
{

//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}

}


könnte so geändert werden:


/************************************************** ********/
void links_drehen(void)
{

//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

for (int i = 0, j = 2000; i < stepsPerRevolution; i++) //"j = 2000": der Anfangswert für das Delay in Microsekunden
{
if (j > 500) j--; //"j > 500": der Endwert für das Delay in Microsekunden - bestimmt auch die Endgeschwindigkeit (mindestens 250 bis 300)
for (int z = 0; z < 3 && i < stepsPerRevolution; z++) //"z < 3": wieviele Schritte mit dem eingstellten Delay "j" gemacht werden sollen, bevor es reduziert wird
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(j);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(j);
i++;
}
}


}





Ist übertragbar auf die anderen Richtungen.

inka
26.11.2019, 13:27
danke für den vorschlag für die anfahrt-rampe....
ich habe inzwischen den akku gequält (https://www.youtube.com/watch?v=Y2s00jOWc-k)...

steigung ca. 10°, strecke, die gefahren wurde ca. 70cm in ca. 2sec, akku mit 8000mAh. Masse des roboters ca. 3kg.

Nach ca. 45 minuten haben die stepper angefangen etwas lauter zu "singen", nach ca. 55 minuten war schluss. Die motoren wurden zu keiner zeit mehr als handwarm.
gefahrener stil: 2sec pause / 2sec rauf / 2sec pause / 2sec (motor gebremst) runter. Daraus habe ich eine gefahrene strecke von 472,5m errechnet, also ca. 500m. Ich weiss nicht, wie das allgemein gesehen wird, ich habe, nachdem den akkus hier relativ wenig zugetraut wurde, nicht mit so viel gerechnet, bin also mit der kombination akku / stepper / ansteuerung zufrieden...

jetzt muss ich mich um die verdrahtung kümmern, habe dazu eine stiftleiste an die stepper-extention-platinen angebracht, um (eigentlich auch für später) die 5V, GND und evtl. auch die 12V an mehreren stellen zur verfügung zu haben...
34532
bedauerlich, dass es nur in ausnahmefällen so eine frei bestückbare zone auf den modulen gibt....

- - - Aktualisiert - - -
zu der stepperansteuerung:


Dann könntest Du von vier benötigten Arduino-Ausgängen auf einen reduzieren. macht das wirklich sinn? Bitte nicht als kritik auffassen, aber der mega hat do fast schon zu viele ausgänge, und ist es nicht eher von vorteil die motoren auch einzeln ansteuern zu können? Abgesehen davon, dass mir die phantasie fehlt wo ich die dazu erforderliche schaltung unterbringen sollte? Wieder ein platinchen mit notwendiger befestigung, dann doch lieber die flexible art mit vier letungen und vier arduino-ausgängen, oder?

Moppi
26.11.2019, 13:37
macht das wirklich sinn? Bitte nicht als kritik auffassen, aber der mega hat do fast schon zu viele ausgänge, und ist es nicht eher von vorteil die motoren auch einzeln ansteuern zu können?

Wenn Du zu viele Ausgänge hast und die belegen musst, dann lass es so, wie es ist. :) Ich achte nur, wenn später mal mehr und mehr dazu kommt, dass man I/O-Ports brauchen kann.
Die Dazu erforderliche Schaltung wäre ca. 1cm² groß, wenn überhaupt. Ich würde mir zutrauen, das längs zu verlöten, dass ein Schrumpfschlauch drüber passt, an das Ganze werden dann 3 Drähte angelötet und Schrumpfschlauch drüber. Aber man könnte auch ein Minigehäuse mit dem 3D-Drucker drucken, wo der Widerstand und der Transistor reinpassen, dazu noch schöne kleine Kabelführungen mit hineindrucken. Widerstand an Transistor löten, Kabel anlöten und alles ins Gehäuse einlegen, mit Klebstoff Deckel drauf kleben. Schönes Miniaturprojekt :) Kann man dann immer wieder so bauen und gebrauchen, wenn mal ein paar Milliampere fehlen.


MfG

inka
26.11.2019, 13:44
Wenn Du zu viele Ausgänge hast und die belegen musst, dann lass es so, wie es ist. :) Ich achte nur, wenn später mal mehr und mehr dazu kommt, dass man I/O-Ports brauchen kann. naja, zu viele könne es nie sein :-) aber ich dachte eher an die flexibilität bei der motoransteurung, ob man die wirklich braucht mal dahingestellt...



Die Dazu erforderliche Schaltung wäre ca. 1cm² groß, wenn überhaupt. Ich würde mir zutrauen, das längs zu verlöten, dass ein Schrumpfschlauch drüber passt, an das Ganze werden dann 3 Drähte angelötet und Schrumpfschlauch drüber. Aber man könnte auch ein Minigehäuse mit dem 3D-Drucker drucken, wo der Widerstand und der Transistor reinpassen, dazu noch schöne kleine Kabelführungen mit hineindrucken. Widerstand an Transistor löten, Kabel anlöten und alles ins Gehäuse einlegen, mit Klebstoff Deckel drauf kleben. Schönes Miniaturprojekt :) Kann man dann immer wieder so bauen und gebrauchen, wenn mal ein paar Milliampere fehlen. hast recht, wäre schon was als druckprojekt - eigentlich eine sache für so ein 3D-drucker-unterforum... :-)

Was hälst Du von dem stepper / akku test?

Moppi
26.11.2019, 13:56
Was hälst Du von dem Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) / akku test?

Scheint mir etwas wenig. Ich häte jetzt überschlagen auf 1000 bis 1500m getippt. Ohne zu wissen, was die Motoren wirklich verbrauchen. Daher kann ich mich auch irren.
Rechne das doch mal aus. Kannst eine Autoglühlampe 12V dran hängen (da steht ja drauf, wieviel Watt die hat). Dann ab und an messen und die Zeit erfassen, wie lange die Lampe leuchtet, bis 9V erreicht sind, die angegeben waren.

Das Problem bei Schrittmotoren ist, dass Du möglichst gleichbleibende Spannung brauchst, bis zum Schluss. Deswegen würde ich so etwas ohne LiPo nicht machen, wenn da der AKku leer ist, sind das etwa 1.5V weniger, als Anfangs, als er voll war. Aber wenn das für Dich ausreichend ist, wie es ist, auch gut.

Mal ne Frage: wie lange lädt der Akku denn, bis er voll ist? Daran kannst Du auch ungefähr sehen, wieviel Kapazität der wohl hat.

Aber jetzt kann man dann direkt Gewicht drauf stellen, wenn das Teil fährt und schauen, was passiert.



MfG

inka
26.11.2019, 14:20
Mal ne Frage: wie lange lädt der Akku denn, bis er voll ist? Daran kannst Du auch ungefähr sehen, wieviel Kapazität der wohl hat. ich habe nicht genau auf die uhr geschaut, aber so 1.5h schätzte ich...

- - - Aktualisiert - - -


Das Problem bei Schrittmotoren ist, dass Du möglichst gleichbleibende Spannung brauchst, bis zum Schluss. Deswegen würde ich so etwas ohne LiPo nicht machen, wenn da der AKku leer ist, sind das etwa 1.5V weniger, als Anfangs, als er voll war. Aber wenn das für Dich ausreichend ist, wie es ist, auch gut.

ich dachte später an sowas: (https://youtu.be/ebyBFszIjxk)https://youtu.be/ebyBFszIjxk

Moppi
26.11.2019, 15:54
Solarlader ... musst Du schauen, ob der Ladestrom hoch genug ist.


MfG

inka
26.11.2019, 16:01
Solarlader ... musst Du schauen, ob der Ladestrom hoch genug ist.
ich hatte das bereits so wie es in dem video ist auch realisiert :-)

Moppi
26.11.2019, 16:07
Und wie hoch ist denn der Ladestrom?

inka
26.11.2019, 16:15
siehe hier:

https://www.roboternetz.de/community/threads/62934-RP6-Projekt-induktive-Ladestation?p=614510&viewfull=1#post614510

Moppi
26.11.2019, 17:51
Hallo inka,


wenn Du das als nützlich ansiehst, warum nicht?


Auf jeden Fall sieht es ganz putzig aus, das in so ein Lauwerk einzubauen. :)
So musst Du die Solarzellen nicht oben drauf packen, sondern kannst das Teil
eben auch unten einbauen und oben noch was anderes drüber.
Wenn der Ladestrom bei 200mA liegt, dann brauchts nur ein paar Stunden,
bis so ein Akku halbwegs wieder geladen ist. ;)
Voll laden damit praktisch natürlich nicht in Erwägung zu ziehen.




MfG

inka
12.12.2019, 14:36
ein paar neuigkeiten gibt es:

die verdrahtung wurde geändert, die 12V leitungen wurden aus dem um das gehäuse herum laufenden kabelbaum entfernt, die stepper werden jetzt jeder für sich sternförmig versorgt Den hauptgrud sieht man im zweiten foto, die leitung wurde etwas zu warm...
34561 34562

der zweite dauertest wurde durchgeführt. Wieder eine steigung von ca. 10°, eine strecke von 80cm wurde rauf und runter gefahren, insgesamt 640mal hin und zurück. Diesmal habe ich die strecke nicht über die zeit geschätzt, sondern die runden gezählt. Die erreichte entfernung beträgt etwas mehr als 1 km...

Moppi
12.12.2019, 15:05
Dass Du nicht 5 bis 8A, bei 12V über so eine dünne Leitung...
Das hättest Du wissen müssen. ;)
Ist ja bald so weit, dann brennen wieder die Bäume. - Vielleicht auch Kabelbäume?

:Weihnacht

inka
12.12.2019, 15:51
ich hab ja gleich zu anfang geschrieben, dass die NEMA stepper neu für mich sind, die bisherigen waren etwas kleiner. Naja, richtig gebrannt hat's ja nicht :-)....
Was zu den 1000m? Platz für einen zweiten akku wäre zur not auch noch, aber erstmal reichts, jetzt muss ich mich um die FB kümmern...

Moppi
12.12.2019, 16:21
Was zu den 1000m?
Liegt in meiner Schätzung, was soll ich dazu sagen? - Kann hinkommen. Wie gesagt, hätte ich den Akku mal etwas genauer unter die Lupe genommen, mit einer 12V Glühlampe, nur um sicher zu gehen, welche Kapazität der hat. Auf ein paar mAh kommt es ja nicht an.


Gruß
:Weihnacht

inka
13.12.2019, 10:19
mit einer 12V Glühlampe, nur um sicher zu gehen, welche Kapazität der hat. Auf ein paar mAh kommt es ja nicht an.
wann wäre denn dann eine aussage über die kapazität des akku "wirklichkeitsnah" gewesen? Wie hell hätte die glühlampe noch leuchten müssen? So war der plötzliche ausfall der stepper sehr deutlich, finde ich, aber egal, jetzt gehts erstmal weiter...

Moppi
13.12.2019, 10:49
So war der plötzliche ausfall der Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) sehr deutlich, finde ich
Gibt es ja nichts dagegen einzuwenden. Wenn Du weißt, wieviel Strom durchschnittlich über die Zeit geflossen ist.
Die unterste Angabe für den Akku sind doch 9V? Ich würde den als "leer" betrachten, wenn er diese Spannung erreicht hat und dann abschalten. Es sei denn, die Motoren schalten vorher ab. Ist der Akku schon mit einer inneren Abschalteinrichtung versehen? Welchen Ladestrom liefert das Ladegerät und wie lange dauert es, bis der Akku von "leer" wieder aufgeladen ist? - Pi mal Daumen würde mir das auch ausreichen. Aber wenn Dir das so genügt, wie es ist, ist es auch in Ordnung.



MfG
:Weihnacht

inka
19.12.2019, 15:16
ich hab schon wieder ein problem mit BT, bzw. den seriellen schnittstellen:

für mein e-bike habe ich mir eine (als ersatz für die original - ausgefallene) bedienung über einen pro-mini arduino und smartphone gebaut. Und die funktioniert auch, mit soft-serial, weil der mini ja nicht mehr serielle schnittstellen hat....



#include "SoftwareSerial.h"
#include "Arduino.h"

//board "arduino pro or pro mini"
//processor Atmega 328P, 5V, 16mhz


uint8_t sensor = 6;
uint8_t LED = 13;
uint8_t sinus;
uint8_t helligkeit = 25;
uint8_t helligkeit_endzustand = 0;

uint8_t fadeschritte = 5;

long taste_neu = 0;
long taste_alt = 8;

#define rxPin 10 //8
#define txPin 11 //7

SoftwareSerial mySerial(rxPin, txPin); // RX, TX


void setup()
{
pinMode(LED, OUTPUT);
pinMode(sensor, OUTPUT);

Serial.begin(115200);

mySerial.begin(115200);
Serial.println("bluetooth übertragung!");
}

void loop()
{
while (mySerial.available())
{
taste_neu = mySerial.read();
// Serial.println(taste_neu);


if (taste_neu == 56 )
{
alles_auf_null();
}
else if (taste_neu == 57)
{
vorwaerts();
}

else if (taste_neu == 48)
{
plus();
}

else if (taste_neu == 49)
{
minus();
}

}

}




Jetzt versuche ich den code auf den Atmega 2560 umzustricken - ganz easy, würde man denken, blos es funktioniert nicht. Warum? Bin ich blind, oder blöd?



#include "Arduino.h"


uint8_t LED = 13;


long taste_neu = 0;
long taste_alt = 8;



void setup()
{
pinMode(LED, OUTPUT);

Serial.begin(115200);
Serial1.begin(115200);

Serial.println("bluetooth übertragung!");
}

void loop()
{
while (Serial1.available())
{
taste_neu = Serial1.read();
Serial.println(taste_neu);
/*

if (taste_neu == 56 )
{
alles_auf_null();
}
else if (taste_neu == 57)
{
vorwaerts();
}

else if (taste_neu == 48)
{
plus();
}

else if (taste_neu == 49)
{
minus();
}
*/
}

}

beim zweiten code ist die abfrage der tastenwerte auskommentiert, ich möchte die von der app generierten werte nur ausdrucken, es kommen aber nur nullen...

Moppi
19.12.2019, 20:15
Hast Du Dein Gerät mit den richtigen Pins für "Serial1" verbunden?

inka
19.12.2019, 22:11
Klar, mit rx1 und tx1. Es kommt ja auch was an, wenn ich die beiden Verbindungen tausche, kommt nix...

Moppi
19.12.2019, 23:01
Weil Du geschrieben hast: es kommen aber nur nullen...

inka
20.12.2019, 09:01
ich habe noch einmal getestet:

- der code für arduino mini bringt als ausdruck im seriellen monitor (beim druck auf eine taste auf dem smartphone) drei untereinander liegende zweistellige zahlen

- der code für mega2560 bringt als ausdruck 8 untereinander liegende nullen

- dies passiert auch bei einer änderung auf die 2te serielle schnittstelle, also TX2 /RX2

- ein tauschen der tx/rx anschlüsse hat zu folge, dass kein ausdruck erfolgt...

ich würde vermuten, dass der 2560 einen anderen datentyp braucht?

Moppi
20.12.2019, 09:45
Ich kann das nicht so recht verstehen, da steht nichts ungewöhnliches in loop().

Ich würde loop() mal ganz leer machen und dann einfach erst einmal so probieren,
was da überhaupt ankommt:



void loop(){
while (Serial1.available())Serial.write(Serial1.read());
}


Zwischen Serial.write() und Serial.print() sollte es geringfügige Unterschiede geben.
Arduino.cc sagt dazu:
Um Daten ohne Umwandlung in ihre Darstellung als Zeichen zu senden, verwende Serial.write() (https://www.arduino.cc/reference/de/language/functions/communication/serial/write).

Mit der kurzen Schleife oben siehst Du, welche Zeichen geschickt wurden,
wenn Du nichts siehst, dann wurden auch keine lesbaren Zeichen geschickt.
Kurz: write() gibt das aus, was geschickt wurde. Steuerzeichen, lesbare Zeichen oder was auch immer.


:Weihnacht

inka
20.12.2019, 16:50
danke Moppi,
aber da kommt einfach garnix an. Ich glaube ich lasse es und mache weiter mit der wifi fernbedienung...

Moppi
20.12.2019, 17:23
Da musst Du herausfinden, warum nichts ankommt. Nutzt nichts. Vielleicht ist auch die Platine kaputt.

Wenn du die Leitungen statt RX1 und TX1 mit RX2 und TX2 verbindest, kommt dann was an, auf Serial2 ?
Wenn ja, dann nochmal versuchen mit RX1 und TX1, kommt nichts an? Kabel vertauscht?



MfG
:Weihnacht

inka
20.12.2019, 18:41
Da musst Du herausfinden, warum nichts ankommt. Nutzt nichts. Vielleicht ist auch die Platine kaputt.
einen anderen atmega 2560 und eine andere BT-platine genommen - das gleiche ergebnis


Wenn du die Leitungen statt RX1 und TX1 mit RX2 und TX2 verbindest, kommt dann was an, auf Serial2 ?
Wenn ja, dann nochmal versuchen mit RX1 und TX1, kommt nichts an? Kabel vertauscht?

das hatte ich ja schon weiter oben getestet, auch mit dem kabeltauschen. Also entweder mache ich irgendwo noch einen fehler, oder - was kanns noch sein? - egal, ich sagte ja schon, ich hab ja noch die wifi alternative...

Moppi
20.12.2019, 19:19
Ich denke schon, dass Du irgendwo einen Fehler machst. Aber von Ferne kann man nicht beurteilen, wo das sein könnte.


Gruß
:Weihnacht

inka
21.12.2019, 09:51
Ich denke schon, dass Du irgendwo einen Fehler machst. Aber von Ferne kann man nicht beurteilen, wo das sein könnte
man sollte sich nie zu sicher sein, so nach dem motto, das hast du doch schon hundertmal gemacht... Ja, das BT-modul war nicht 100%tig richtig programmiert :-( , jetzt geht alles...

oberallgeier
21.12.2019, 12:36
man sollte sich nie zu sicher sein, so nach dem motto, das hast du doch schon hundertmal gemacht ..Wie wahr. (M)Ein bemerkenswerter Fall: Projekt Jugend forscht (http://https://www.roboternetz.de/community/threads/65596-Fragen-zu-Laserpointer-Leistung-Sichtbarkeit-Gef%C3%A4hrdungsgrad?p=604602&viewfull=1#post604602), ich hatte gecoacht, P*** hatte von vier nachmittags bis acht abends an einer Platine mit einigen Sensoren gesessen - nix ging - ausser einem Hilferuf an mich. Um acht war ich da und wir hatten gemeinsam drei weitere Stunden gesucht - periphere Sensoren, (Mutter)Platine etc. Schließlich stellte ich fest, dass die PullUps fürs I²C fehlen. Mit den restlichen Arbeiten war P*** noch ne gute Stunde dran. Sooo lang für einen total blödsinnigen Fehler.

Moppi
23.12.2019, 14:38
Hallo Inka,

kommst Du voran? Wie ist denn der Stand der Dinge?

MfG
:Weihnacht

inka
23.12.2019, 15:00
weihnachten naht :-) -- wenig zeit weil gäste kommen...

aber in kleinen schritten gehts voran - momentan versuche ich einen "200 steps per buttonklick" in eine dauerbewegung bei gleichzeitiger ständiger abfrage des tastenfeldes der bluetooth FB in der app umzuwandeln - wenn du nicht dranbleiben kannst, machst du eigentlich immer wieder die gleichen fehler :-)

inka
23.12.2019, 17:47
jetzt hänge ich's doch hier rein. Egal was ich mache, entweder es gibt nur kurze bewegungen (in der länge der definierten stepps per revolution), oder die erste angewählte richtung wird dauernd bedient und ich habe keine möglichkeit einzugreifen :-( --- Wer weiss rat warum das so ist?

danke...




// DIR und STEP pins definieren
#define dirPin_VL 6 //2
#define stepPin_VL 7 //3
#define dirPin_HL 8 //4
#define stepPin_HL 9 //5
#define dirPin_VR 2 //6
#define stepPin_VR 3 //7
#define dirPin_HR 4 //8
#define stepPin_HR 5 //9

//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43

//resett pin definieren
#define PIN2RESET 10


//steps pro umdrehung definieren:
#define stepsPerRevolution 200


uint8_t taste_neu = 1;
uint8_t taste_alt = 8;
uint8_t taste = 0;



void setup()
{
// pinMode(LED, OUTPUT);

//pins als output:

pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(enbl_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(enbl_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(enbl_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
pinMode(enbl_HR, OUTPUT);


//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);

Serial.begin(115200);
Serial1.begin(115200);
Serial.println("code----- /home/georg/Arduino/outdoor_robo/smartphone_steuerung/outdoor_FB_switch_bluetooth_1.ino");

Serial.println("bluetooth übertragung!");


//enable pins deaktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}

void loop()
{

while (Serial1.available())
{
taste = Serial1.read();
Serial.println(taste);
// taste_neu = taste;
tasten_abfrage();
}
}
/************************************************** *********/

void tasten_abfrage(void)
{

switch (taste)
{

case 100:// rotate rechts - FB quer smartphone
{

rechts_drehen();

break;
}


case 97:// rotate links - FB quer smartphone
{

links_drehen();

break;

}


case 116:// fahre vor - FB quer smartphone
{

vorwaerts();

break;
}


case 115:// fahre rückwärts - FB quer smartphone
{

rueckwaerts();

break;
}
}


}

/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
reboot();
}

/************************************************** *********/
void vorwaerts(void)
{

// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);



for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
tasten_abfrage();
}


/************************************************** ********/

void rueckwaerts(void)
{

// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);


for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
tasten_abfrage();
}

/************************************************** *********/
void rechts_drehen(void)
{

// enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);



for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
tasten_abfrage();
}


/************************************************** ********/

void links_drehen(void)
{

//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
tasten_abfrage();
}

/*
void links_drehen(void) //mit beschleunigung und sound
{

//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

//"j = 2000": der Anfangswert für das Delay in Microsekunden

for (int i = 0, j = 2000; i < stepsPerRevolution; i++)
{

//"j > 500": der Endwert für das Delay in Microsekunden - bestimmt auch die Endgeschwindigkeit (mindestens 250 bis 300)

if (j > 300) j--;
//"z < 3": wieviele Schritte mit dem eingstellten Delay "j" gemacht werden sollen, bevor es reduziert wird

for (int z = 0; z < 3 && i < stepsPerRevolution; z++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(j);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(j);
i++;
}
}
}
*/
/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/

/************************************************** **********/

Moppi
23.12.2019, 19:51
Zunächst mal, was mir zuerst, beim Überfliegen des Codes, auffällt und unvorhersehbar enden kann:

Du rufst in loop() die Funktion tasten_abfrage() auf.
In tasten_abfrage() rufst Du die Funktionen rechts_drehen(), links_drehen() usw. auf. In diesen Funktionen wiederum rufst du tasten_abfrage() erneut auf.
Es entsteht eine Rekursion, die zum Stapelüberlauf und damit zum Absturz führen kann.

Zuerst würde ich die Rekursion entfernen. Und dann den Code anders gestalten - dazu muss ich erst genauer schauen.



MfG
:Weihnacht

- - - Aktualisiert - - -

Dann mein Vorschlag zum weiteren Programmablauf:

zuerst vier Statusvariablen einführen, für die jeweiligen Richtungen:




uint8_t s_vor = 0;
uint8_t s_rueck = 0;
uint8_t s_links = 0;
uint8_t s_rechts = 0;


Dann nur in loop() die Funktion tasten_abfrage() aufrufen.

Dann habe ich hier für das Beispiel "vorwärts" den Code geändert:


/************************************************** *********/
void vorwaerts(void)
{
if(s_vor == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


s_vor = 1;
s_rueck = 0;
s_links = 0;
s_rechts = 0;
}
else{
weiter_vorwaerts();
}
}


void weiter_vorwaerts(void)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}


Zuerst wird der Status für die Richtung "vorwärts" abgefragt. Ist der "0", dann müssen die Enable-Pins aktiviert werden und die Richtung bestimmt.
Dann wird der Status für die Richtung auf "1" gesetzt, die Vorbereitungen müssen nicht mehr ausgeführt werden, einmal genügt.
Außerdem werden die Statusvariablen der anderen Richtungen auf "0" gesetzt.

Dadurch, dass die Statusvariable für "Vorwärts" auf "1" gesetzt wurde, wird in jedem weiteren Durchlauf nur noch die Funktion weiter_vorwaerts() aufgerufen,
wo der Schrittmotor tatsächlich bewegt wird. Und zwar hier im Beispiel nur einen Schritt.

In allen anderen Funktionen für die Richtungen muss identisch verfahren werden.

Falls die Fernbedienung nicht schnell genug "feuert", läuft der Motor nur sehr langsam , weil immer nur ein Schritt pro Durchlauf gemacht wird.
Um das zu ändern, müssen in einem Durchlauf mehr Schritte gemacht werden (die Schleife habe ich jetzt raus genommen).

Der Code kann noch weiter geändert werden, dass es "besser" funktioniert. Das würde jetzt aber alles auf einmal wohl etwas überfordern. Deshalb erst einmal so weit.



MfG

- - - Aktualisiert - - -

Ich habe des gesamten Code überarbeitet, schau es Dir mal an, Du solltest es durchschauen, was ich gemacht habe.
Ob das jetzt fehlerfrei ist, weiß ich nicht. Ich hoffe dass Du den Code so kompilieren kannst und dass er funktioniert:



// DIR und STEP pins definieren
#define dirPin_VL 6 //2
#define stepPin_VL 7 //3
#define dirPin_HL 8 //4
#define stepPin_HL 9 //5
#define dirPin_VR 2 //6
#define stepPin_VR 3 //7
#define dirPin_HR 4 //8
#define stepPin_HR 5 //9


//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43


//resett pin definieren
#define PIN2RESET 10




//steps pro umdrehung definieren:
#define stepsPerRevolution 200




uint8_t taste_neu = 1;
uint8_t taste_alt = 8;
uint8_t taste = 0;


uint8_t s_vor = 0;
uint8_t s_rueck = 0;
uint8_t s_links = 0;
uint8_t s_rechts = 0;
uint8_t StepsPerDirection = 0;


void setup()
{
// pinMode(LED, OUTPUT);


//pins als output:


pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(enbl_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(enbl_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(enbl_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
pinMode(enbl_HR, OUTPUT);




//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);


Serial.begin(115200);
Serial1.begin(115200);
Serial.println("code----- /home/georg/Arduino/outdoor_robo/smartphone_steuerung/outdoor_FB_switch_bluetooth_1.ino");


Serial.println("bluetooth übertragung!");




//enable pins deaktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);


//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}


void loop()
{
if (Serial1.available())
{
taste = Serial1.read();
Serial.println(taste);
// taste_neu = taste;
tasten_abfrage();
}


if ( StepsPerDirection > 0)
{
StepsPerDirection--;
richtung_abfrage();
}
}


/************************************************** *********/
void richtung_abfrage(void)
{
if (s_rechts == 1) rechts_drehen();
if (s_links == 1) links_drehen();
if (s_vor == 1) vorwaerts();
if (s_rueck == 1) rueckwaerts();
}


/************************************************** *********/
void tasten_abfrage(void)
{


switch (taste)
{


case 100:// rotate rechts - FB quer smartphone
{


StepsPerDirection = 200/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200 Schritte
rechts_drehen();


break;
}




case 97:// rotate links - FB quer smartphone
{


StepsPerDirection = 200/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200 Schritte
links_drehen();


break;


}




case 116:// fahre vor - FB quer smartphone
{


StepsPerDirection = 200/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200 Schritte
vorwaerts();


break;
}




case 115:// fahre rückwärts - FB quer smartphone
{


StepsPerDirection = 200/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200 Schritte
rueckwaerts();


break;
}
}




}


/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
reboot();
}


/************************************************** *********/
void vorwaerts(void)
{
if(s_vor == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


s_vor = 1;
s_rueck = 0;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}


/************************************************** ********/


void rueckwaerts(void)
{
if(s_rueck == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);


s_vor = 0;
s_rueck = 1;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}


/************************************************** *********/
void rechts_drehen(void)
{
if(s_rechts == 0)
{
// enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);


s_vor = 0;
s_rueck = 0;
s_links = 0;
s_rechts = 1;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}




/************************************************** ********/


void links_drehen(void)
{
if(s_links == 0)
{
//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


s_vor = 0;
s_rueck = 0;
s_links = 1;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}


/*
void links_drehen(void) //mit beschleunigung und sound
{


//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


//"j = 2000": der Anfangswert für das Delay in Microsekunden


for (int i = 0, j = 2000; i < stepsPerRevolution; i++)
{


//"j > 500": der Endwert für das Delay in Microsekunden - bestimmt auch die Endgeschwindigkeit (mindestens 250 bis 300)


if (j > 300) j--;
//"z < 3": wieviele Schritte mit dem eingstellten Delay "j" gemacht werden sollen, bevor es reduziert wird


for (int z = 0; z < 3 && i < stepsPerRevolution; z++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(j);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(j);
i++;
}
}
}
*/
/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/


/************************************************** **********/

inka
23.12.2019, 21:21
Zu viel des guten Moppi, danke...
Der Weihnachtsmann kommt ja erst morgen...
Frohe Weihnachten!

Moppi
23.12.2019, 21:40
Ja! Dann probiere es morgen aus!

Nein, ich denke, es war nicht zu viel, gerne wieder. :Weihnacht

Dir auch frohe Weihnachten!



MfG

inka
26.12.2019, 16:03
ich habe mir mal die beiden versionen des codes angeschaut und verglichen...

deine


// DIR und STEP pins definieren
#define dirPin_VL 6 //2
#define stepPin_VL 7 //3
#define dirPin_HL 8 //4
#define stepPin_HL 9 //5
#define dirPin_VR 2 //6
#define stepPin_VR 3 //7
#define dirPin_HR 4 //8
#define stepPin_HR 5 //9


//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43


//resett pin definieren
#define PIN2RESET 10




//steps pro umdrehung definieren:
#define stepsPerRevolution 200




uint8_t taste_neu = 1;
uint8_t taste_alt = 8;
uint8_t taste = 0;


uint8_t s_vor = 0;
uint8_t s_rueck = 0;
uint8_t s_links = 0;
uint8_t s_rechts = 0;
uint8_t StepsPerDirection = 0;


void setup()
{
// pinMode(LED, OUTPUT);


//pins als output:


pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(enbl_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(enbl_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(enbl_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
pinMode(enbl_HR, OUTPUT);




//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);


Serial.begin(115200);
Serial1.begin(115200);
Serial.println("code----- /home/georg/Arduino/outdoor_robo/smartphone_steuerung/outdoor_moppi_FB_switch_bluetooth_1");


Serial.println("bluetooth übertragung!");




//enable pins deaktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);


//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}


void loop()
{
if (Serial1.available())
{
taste = Serial1.read();
Serial.println(taste);
// taste_neu = taste;
tasten_abfrage();
}


if ( StepsPerDirection > 0)
{
StepsPerDirection--;
richtung_abfrage();
}
}


/************************************************** *********/
void richtung_abfrage(void)
{
if (s_rechts == 1) rechts_drehen();
if (s_links == 1) links_drehen();
if (s_vor == 1) vorwaerts();
if (s_rueck == 1) rueckwaerts();
}


/************************************************** *********/
void tasten_abfrage(void)
{


switch (taste)
{


case 100:// rotate rechts - FB quer smartphone
{


StepsPerDirection = 200/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200 Schritte
rechts_drehen();


break;
}




case 97:// rotate links - FB quer smartphone
{


StepsPerDirection = 200/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200 Schritte
links_drehen();


break;


}




case 116:// fahre vor - FB quer smartphone
{


StepsPerDirection = 200/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200 Schritte
vorwaerts();


break;
}




case 115:// fahre rückwärts - FB quer smartphone
{


StepsPerDirection = 200/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200 Schritte
rueckwaerts();


break;
}
}




}


/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
reboot();
}


/************************************************** *********/
void vorwaerts(void)
{
if(s_vor == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


s_vor = 1;
s_rueck = 0;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}


/************************************************** ********/


void rueckwaerts(void)
{
if(s_rueck == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);


s_vor = 0;
s_rueck = 1;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}

/************************************************** *********/
void rechts_drehen(void)
{
if(s_rechts == 0)
{
// enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);


s_vor = 0;
s_rueck = 0;
s_links = 0;
s_rechts = 1;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}




/************************************************** ********/


void links_drehen(void)
{
if(s_links == 0)
{
//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


s_vor = 0;
s_rueck = 0;
s_links = 1;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}


/*
void links_drehen(void) //mit beschleunigung und sound
{


//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


//"j = 2000": der Anfangswert für das Delay in Microsekunden


for (int i = 0, j = 2000; i < stepsPerRevolution; i++)
{


//"j > 500": der Endwert für das Delay in Microsekunden - bestimmt auch die Endgeschwindigkeit (mindestens 250 bis 300)


if (j > 300) j--;
//"z < 3": wieviele Schritte mit dem eingstellten Delay "j" gemacht werden sollen, bevor es reduziert wird


for (int z = 0; z < 3 && i < stepsPerRevolution; z++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(j);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(j);
i++;
}
}
}
*/
/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/


/************************************************** **********/


und die meine


//#include "Arduino.h"

//2019_12_21:

//bei linksdrehen ist das langsammere anfahren berücksichtigt / auskommentiert
//dauerbewegung beim einmal drücken (fernbedienung "quer" am smartphone) geht nicht

//uint8_t LED = 13;

// DIR und STEP pins definieren
#define dirPin_VL 6 //2
#define stepPin_VL 7 //3
#define dirPin_HL 8 //4
#define stepPin_HL 9 //5
#define dirPin_VR 2 //6
#define stepPin_VR 3 //7
#define dirPin_HR 4 //8
#define stepPin_HR 5 //9

//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43

//resett pin definieren
#define PIN2RESET 10


//steps pro umdrehung definieren:
#define stepsPerRevolution 1600


uint8_t taste_neu = 1;
uint8_t taste_alt = 8;
uint8_t taste = 0;



void setup()
{
// pinMode(LED, OUTPUT);

//pins als output:

pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(enbl_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(enbl_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(enbl_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
pinMode(enbl_HR, OUTPUT);


//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);

Serial.begin(115200);
Serial1.begin(115200);
Serial.println("code----- /home/georg/Arduino/outdoor_robo/smartphone_steuerung/outdoor_FB_switch_bluetooth_1.ino");

Serial.println("bluetooth übertragung!");


//enable pins deaktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);

//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}

void loop()
{

while (Serial1.available())
{
taste = Serial1.read();
Serial.println(taste);
// taste_neu = taste;
tasten_abfrage();
}
}
/************************************************** *********/

void tasten_abfrage(void)
{

switch (taste)
{

case 100:// rotate rechts - FB quer smartphone
{

rechts_drehen();

break;
}


case 97:// rotate links - FB quer smartphone
{

links_drehen();

break;

}


case 116:// fahre vor - FB quer smartphone
{

vorwaerts();

break;
}


case 115:// fahre rückwärts - FB quer smartphone
{

rueckwaerts();

break;
}
}


}

/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
reboot();
}

/************************************************** *********/
void vorwaerts(void)
{

// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);



for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
// tasten_abfrage();
}


/************************************************** ********/

void rueckwaerts(void)
{

// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);


for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
// tasten_abfrage();
}

/************************************************** *********/
void rechts_drehen(void)
{

// enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);



for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
// tasten_abfrage();
}


/************************************************** ********/

void links_drehen(void)
{

//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
// tasten_abfrage();
}

/*
void links_drehen(void) //mit beschleunigung und sound
{

//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

//"j = 2000": der Anfangswert für das Delay in Microsekunden

for (int i = 0, j = 2000; i < stepsPerRevolution; i++)
{

//"j > 500": der Endwert für das Delay in Microsekunden - bestimmt auch die Endgeschwindigkeit (mindestens 250 bis 300)

if (j > 300) j--;
//"z < 3": wieviele Schritte mit dem eingstellten Delay "j" gemacht werden sollen, bevor es reduziert wird

for (int z = 0; z < 3 && i < stepsPerRevolution; z++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(j);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(j);
i++;
}
}
}
*/
/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/

/************************************************** **********/


bei meiner version habe ich die rekursiv - aufrufe in den einzelnen bewegungsfunktionen rausgenommen - und - das ist bei mir in ein wenig in vergessenheit geraten - die stepper laufen mit mikrostepping, 1/8schritt, das bedeutet, dass ich die variable "StepsPerRevolution" auf 1600 anpassen muss. Dann laufen die stepper je nach befehl vom smartphone genau eine umdrehung.

Bei Deiner version verstehe ich einiges nicht. Dass Du in den einzelnen "richtungs"funktionen die richtungsdefinition nur einmal ablaufen lässt verstehe ich, auch den sinn der "s-* variablen" (vor, rück usw) ist klar.
Bei einer änderung der zeile " StepsPerDirection = 200/4;" in 200 dreht der stepper um 1/8 umdrehung, bei 200/4 war es 1/32 pro befehl vom smartphone. Wenn ich die zahl in 1600 ändere müsste doch der stepper eine ganze umdrehung machen er dreht sich aber nur um einen 1/24stel. Wie kommt das?

Moppi
26.12.2019, 16:43
Bei einer änderung der zeile " StepsPerDirection = 200/4;" in 200 dreht der Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) um 1/8 umdrehung, bei 200/4 war es 1/32 pro befehl vom smartphone. Wenn ich die zahl in 1600 ändere müsste doch der Stepper (http://www.rn-wissen.de/index.php/Schrittmotoren) eine ganze umdrehung machen er dreht sich aber nur um einen 1/24stel. Wie kommt das?

Die 200 sind auf Full Steps bezogen. Daran hatte ich schon gedacht, dass Du mit Microstepping arbeiten möchtest. Ich dachte, Du kannst das umrechnen, wenn Du einen anderen Step-Mode wählst. Wenn das bei 1/16tel sechszehn mal mehr Schritte pro Umdrehung sind, muss man die 200 mit 16 multiplizieren: 200*16/4,. Bei 1/8 wären das dann 200*8/4 (also: StepsPerDirection = 200*8/4;). Theoretisch wäre das also mit 1600 richtig. Dann wären 1600/4, wieder ein Viertel. Wie dann jetzt 1/24stel rauskommt, verstehe ich nicht an der Stelle. Ich hoffe natürlich, dass der Code so weit fehlerfrei war, das kann ich schlecht ausprobieren (das wäre immer meine Kontrolle hinterher). Aber ich will gerne noch mal schauen. Dann stell den Code hier noch mal rein, wie der bei Dir 1/24stel Umdrehung macht.

Habe gerade gesehen, oben steht der Code ...

Mal eine grundsätzliche Frage: funktionierte dass denn vom Prinzip, mit den Änderungen, die ich angebracht habe?

Dann entspräche dieser Code jetzt dem mit Mode 1/8 Step und das Rad müsste eine viertel Umdrehung machen, bis es steht:



// DIR und STEP pins definieren
#define dirPin_VL 6 //2
#define stepPin_VL 7 //3
#define dirPin_HL 8 //4
#define stepPin_HL 9 //5
#define dirPin_VR 2 //6
#define stepPin_VR 3 //7
#define dirPin_HR 4 //8
#define stepPin_HR 5 //9




//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43




//resett pin definieren
#define PIN2RESET 10








//steps pro umdrehung definieren:
#define stepsPerRevolution 200








uint8_t taste_neu = 1;
uint8_t taste_alt = 8;
uint8_t taste = 0;




uint8_t s_vor = 0;
uint8_t s_rueck = 0;
uint8_t s_links = 0;
uint8_t s_rechts = 0;
uint8_t StepsPerDirection = 0;




void setup()
{
// pinMode(LED, OUTPUT);




//pins als output:




pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(enbl_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(enbl_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(enbl_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
pinMode(enbl_HR, OUTPUT);








//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);




Serial.begin(115200);
Serial1.begin(115200);
Serial.println("code----- /home/georg/Arduino/outdoor_robo/smartphone_steuerung/outdoor_moppi_FB_switch_bluetooth_1");




Serial.println("bluetooth übertragung!");








//enable pins deaktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);




//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}




void loop()
{
if (Serial1.available())
{
taste = Serial1.read();
Serial.println(taste);
// taste_neu = taste;
tasten_abfrage();
}




if ( StepsPerDirection > 0)
{
StepsPerDirection--;
richtung_abfrage();
}
}




/************************************************** *********/
void richtung_abfrage(void)
{
if (s_rechts == 1) rechts_drehen();
if (s_links == 1) links_drehen();
if (s_vor == 1) vorwaerts();
if (s_rueck == 1) rueckwaerts();
}




/************************************************** *********/
void tasten_abfrage(void)
{




switch (taste)
{




case 100:// rotate rechts - FB quer smartphone
{




StepsPerDirection = 200*8/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200*8 Schritte
rechts_drehen();




break;
}








case 97:// rotate links - FB quer smartphone
{




StepsPerDirection = 200*8/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200*8 Schritte
links_drehen();




break;




}








case 116:// fahre vor - FB quer smartphone
{




StepsPerDirection = 200*8/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200*8 Schritte
vorwaerts();




break;
}








case 115:// fahre rückwärts - FB quer smartphone
{




StepsPerDirection = 200*8/4; //Nach 1/4 Radumdrehung Stillstand; weil pro Umdrehung = 200*8 Schritte
rueckwaerts();




break;
}
}








}




/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
reboot();
}




/************************************************** *********/
void vorwaerts(void)
{
if(s_vor == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);




//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);




s_vor = 1;
s_rueck = 0;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}




/************************************************** ********/




void rueckwaerts(void)
{
if(s_rueck == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);




//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);




s_vor = 0;
s_rueck = 1;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}


/************************************************** *********/
void rechts_drehen(void)
{
if(s_rechts == 0)
{
// enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);




//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);




s_vor = 0;
s_rueck = 0;
s_links = 0;
s_rechts = 1;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}








/************************************************** ********/




void links_drehen(void)
{
if(s_links == 0)
{
//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);




//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);




s_vor = 0;
s_rueck = 0;
s_links = 1;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}




/*
void links_drehen(void) //mit beschleunigung und sound
{




//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);




//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);




//"j = 2000": der Anfangswert für das Delay in Microsekunden




for (int i = 0, j = 2000; i < stepsPerRevolution; i++)
{




//"j > 500": der Endwert für das Delay in Microsekunden - bestimmt auch die Endgeschwindigkeit (mindestens 250 bis 300)




if (j > 300) j--;
//"z < 3": wieviele Schritte mit dem eingstellten Delay "j" gemacht werden sollen, bevor es reduziert wird




for (int z = 0; z < 3 && i < stepsPerRevolution; z++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(j);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(j);
i++;
}
}
}
*/
/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/




/************************************************** **********/



MfG





- - - Aktualisiert - - -

Außerdem kann man dann natrülich die "200*8" auch durch "StepsPerRevolution" ersetzen, wie hier, als Beispiel:




StepsPerDirection = StepsPerRevolution/4; //Nach 1/4 Radumdrehung Stillstand

inka
26.12.2019, 16:52
ich habe mir den code jetzt garnicht angeschaut, sondern copy/paste und geladen, ich muss 11x am smartphone drücken, bis die 360° erreicht sind...
und nun ist der akku leer, muss also ca. 2h warten...

edit:

das hier


void loop()
{

if (Serial1.available())
{
taste = Serial1.read();
Serial.println(taste);
// taste_neu = taste;
tasten_abfrage();
}

if ( StepsPerDirection > 0)
{
StepsPerDirection--;
richtung_abfrage();
}
}

was genau wird damit erreicht? hauptsächlich die zweite if-abfrage...

Moppi
26.12.2019, 17:26
Zur ersten if-Abfrage:
Du bist in der Funktion/Methode loop() innerhalb einer Schleife. Deshalb habe ich das ursprüngliche while von Dir entfernt und durch if ersetzt.

Die zweite if-Abfrage sorgt dafür, dass die Stepper so lange in die angeforderte Richtung gedreht werden, wie dies in StepsPerDirection vorgegeben ist. Hier habe ich gedacht, dass eine viertel Umdrehung ein guter Wert wäre. Denn wenn Du die Fernbedienung drückst, "feuert" die ja nicht 200mal pro Sekunde (oder wie lange eine Radumdrehung dauert), sondern weniger. Hier muss man dann passende Werte finden, dass die Handhabung angenehm wird. Wenn für Dich 1 Radumdrehung pro Tastendruck angenehm ist, kannst Du natürlich aus der viertel Umdrehung eine Ganze machen (also: StepsPerDirection = StepsPerRevolution).

Wenn Du 11 Mal Drücken musst, um eine Umdrehung zu erhalten, könnte man versuchsweise schreiben: StepsPerDirection = StepsPerRevolution*11;
Allerdings verstehe ich das mit den 11 Malen nicht, ich sehe darin keine Logik.


MfG

inka
26.12.2019, 17:42
Zur ersten if-Abfrage:
Du bist in der Funktion/Methode loop() innerhalb einer Schleife. Deshalb habe ich das ursprüngliche while von Dir entfernt und durch if ersetzt.
ok, die loop wird ja immer wieder durchlaufen, ist es aber nicht so, dass "if" nur einmal abgefragt wird und "while" so lange, bis ein bestimmtes ereignis eintrifft? Damit wollte ich erreichen, dass weitere anweisungen in der loop erst nach diesem ereignis ausgeführt werden...


Du die Fernbedienung drückst, "feuert" die ja nicht 200mal pro Sekunde (oder wie lange eine Radumdrehung dauert), sondern weniger. Hier muss man dann passende Werte finden, dass die Handhabung angenehm wird. Das eigentliche ziel war (und ist) einmal auf "vor" zu drücken und der roboter fährt so lange vorwärts, bis er einen andern befehl bekommt, oder halt ein anderer sensor meldet sich...


Wenn Du 11 Mal Drücken musst, um eine Umdrehung zu erhalten, könnte man versuchsweise schreiben: StepsPerDirection = StepsPerRevolution*11; Allerdings verstehe ich das mit den 11 Malen nicht, ich sehe darin keine Logik.
ich auch nicht...

Moppi
26.12.2019, 18:05
ist es aber nicht so, dass "if" nur einmal abgefragt wird und "while" so lange, bis ein bestimmtes ereignis eintrifft

Ja, wenn die Abfrage so formuliert ist.
"if" wird auch immer wieder geprüft (weil ja in "loop()"). Wenn dann ein Ereignis eingetreten ist, weil auf "Serial1" etwas "available" ist, wird das Ereignis abgearbeitet.


Damit wollte ich erreichen, dass weitere anweisungen in der loop erst nach diesem ereignis ausgeführt werden...
Passiert hier mit dem "if" genau so. Wenn keine Taste gedrückt wurde und also kein Ereignis vorhanden ist, bewegt sich auch kein Motor, es sei denn, die viertel oder ganze Umdrehung ist noch nicht fertig. Und wenn sich die Motoren in eine Richtung drehen, kannst Du eine andere Taste drücken und die Motoren bewegen sich praktisch sofort in die andere Richtung.

Also eigentlich sollte das Programm dann das tun, was Du beabsichtigt hast. Und wie gesagt, das "while" erübrigt sich, weil Du in "loop()" bist und dieser Code darin immer wieder abgearbeitet wird.

Daher macht



while(Serial1.available()){
...
}


im Grunde dasselbe, wie



loop(){
if(Serial1.available()){
...
}
}


Beides wird immer wieder abgearbeitet, wenn die Bedingungsprüfung für "Serial1.available()" positiv ausfällt.
Wenn diese Prüfung negativ ausfällt, stoppt "while" nicht den Programmablauf in "loop()", bis ein Ereignis eintritt, sondern nur, solange eines da ist.
Mit "if" passiert dasselbe. Nur dass es den Programmablauf nicht aufhält, solang Ereignisse vorhanden sind, sondern nur so lange, wie ein Ereignis abgearbeitet wird. Wenn beim nächsten Durchlauf in "loop()" festgestellt wird, dass immer noch oder wieder ein Ereignis vorhanden ist, wird das wieder abgearbeitet. Das geht dann so lange, bis kein Ereignis (also Zeichen auf Serial1) mehr vorhanden ist.


MfG

inka
26.12.2019, 18:33
Passiert hier mit dem "if" genau so. Wenn keine Taste gedrückt wurde und also kein Ereignis vorhanden ist, bewegt sich auch kein Motor, es sei denn, die viertel oder ganze Umdrehung ist noch nicht fertig. Und wenn sich die Motoren in eine Richtung drehen, kannst Du eine andere Taste drücken und die Motoren bewegen sich praktisch sofort in die andere Richtung.
Also eigentlich sollte das Programm dann das tun, was Du beabsichtigt hast. Und wie gesagt, das "while" erübrigt sich, weil Du in "loop()" bist und dieser Code darin immer wieder abgearbeitet wird.
das ist es ja - eben nicht. ich habe deine version von vorwärtes etwas geändert, von:

void vorwaerts(void)
{
if(s_vor == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);


//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);


s_vor = 1;
s_rueck = 0;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}

in:

void vorwaerts(void)
{
if (s_vor == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);

//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);

s_vor = 1;
s_rueck = 0;
s_links = 0;
s_rechts = 0;

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}
else

for (int i = 0; i < stepsPerRevolution; i++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}


so macht sie eine umdrehung pro signal vom smartphone, wie meine ursprüngliche auch :-)
allerdings muss ich am ende der umdrehung für die nächste wieder drücken...

Moppi
26.12.2019, 19:01
Du kannst es natürlich machen, wie Du es für richtig hältst. Ich verstehe Deine Intention, das sequentiell abarbeiten zu wollen. Das ist tendenziell für Beginner einfacher. Allerdings wirst Du später eventuell auf eine parallele Abarbeitung hinaus wollen oder müssen. Sequentielle Abarbeitung blockiert immer ein Programm und wird unübersichtlich, wenn man dies zu ändern versucht (indem man immer wieder kreuz und quer Funktionsaufrufe einstreut). Parallele Abarbeitung verfolgt dagegen den Ansatz, mehrere Aufgaben nebeneinander abzuarbeiten, übersichtlich und kontrolliert.

Ich schlage (leider hier nicht zum ersten Mal) vor, einen Programmablaufplan zu erstellen. Gerade, wenn man nicht so den Überblick hat, ist das eine tolle Sache! Den dafür sind die sogenannten PAPs da: optisch einen Überblick über den Programmablauf zu verschaffen. Da erkennt man auch Probleme in der Programmabarbeitung.

Ein Problem will ich noch bildhaft beschreiben, wenn Du die Programmierung in diesen Schleifen (for (int i = 0; i < stepsPerRevolution; i++)...) so aufrecht erhalten willst:

Sollte der Roboter eine dreiviertel Umdrehung am Abgrund stehen und er fährt vorwärts, kannst Du ihn mit keiner Taste stoppen. Weil er erst den Abgrund hinunterstürzt, bevor er auf eine weitere Taste reagiert.



MfG

inka
26.12.2019, 19:32
Lieber Moppi,
wir schreiben aneinander vorbei :-), es geht nicht um parallel oder seriell, auch das mit der einer Umdrehung pro Smartphonesignal ist doch nur eine Hausnummer, die jederzeit geändert werden kann...
Es geht um die Dauerbewegung nach nur einem Klick am Smartphone, das weiss ich nicht wie ich da hinkomme...
morgen geht's weiter...

Moppi
26.12.2019, 20:49
Dauerbewegung nach nur einem Klick

Wenn Du willst, dass das Teil immer vorwärts oder rückwärts ... fährt, dann geht das z.B. so:



// DIR und STEP pins definieren
#define dirPin_VL 6 //2
#define stepPin_VL 7 //3
#define dirPin_HL 8 //4
#define stepPin_HL 9 //5
#define dirPin_VR 2 //6
#define stepPin_VR 3 //7
#define dirPin_HR 4 //8
#define stepPin_HR 5 //9








//enable pins definieren
#define enbl_VL 40
#define enbl_HL 42
#define enbl_VR 41
#define enbl_HR 43








//resett pin definieren
#define PIN2RESET 10
















//steps pro umdrehung definieren:
#define stepsPerRevolution 200
















uint8_t taste_neu = 1;
uint8_t taste_alt = 8;
uint8_t taste = 0;








uint8_t s_vor = 0;
uint8_t s_rueck = 0;
uint8_t s_links = 0;
uint8_t s_rechts = 0;


void setup()
{
// pinMode(LED, OUTPUT);








//pins als output:








pinMode(dirPin_VL, OUTPUT);
pinMode(stepPin_VL, OUTPUT);
pinMode(enbl_VL, OUTPUT);
pinMode(dirPin_HL, OUTPUT);
pinMode(stepPin_HL, OUTPUT);
pinMode(enbl_HL, OUTPUT);
pinMode(dirPin_VR, OUTPUT);
pinMode(stepPin_VR, OUTPUT);
pinMode(enbl_VR, OUTPUT);
pinMode(dirPin_HR, OUTPUT);
pinMode(stepPin_HR, OUTPUT);
pinMode(enbl_HR, OUTPUT);
















//resett pin zustand definieren
pinMode(PIN2RESET, INPUT);








Serial.begin(115200);
Serial1.begin(115200);
Serial.println("code----- /home/georg/Arduino/outdoor_robo/smartphone_steuerung/outdoor_moppi_FB_switch_bluetooth_1");








Serial.println("bluetooth übertragung!");
















//enable pins deaktivieren:
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);








//resett pin aktivieren
digitalWrite(PIN2RESET, HIGH);
}








void loop()
{
if (Serial1.available())
{
taste = Serial1.read();
Serial.println(taste);
// taste_neu = taste;
tasten_abfrage();
}


richtung_abfrage();
}








/************************************************** *********/
void richtung_abfrage(void)
{
if (s_rechts == 1) rechts_drehen();
if (s_links == 1) links_drehen();
if (s_vor == 1) vorwaerts();
if (s_rueck == 1) rueckwaerts();
}








/************************************************** *********/
void tasten_abfrage(void)
{








switch (taste)
{








case 100:// rotate rechts - FB quer smartphone
{








rechts_drehen();








break;
}
















case 97:// rotate links - FB quer smartphone
{








links_drehen();








break;








}
















case 116:// fahre vor - FB quer smartphone
{








vorwaerts();








break;
}
















case 115:// fahre rückwärts - FB quer smartphone
{








rueckwaerts();








break;
}
}
















}








/************************************************** *********/
void alle_stepper_stop(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
reboot();
}








/************************************************** *********/
void vorwaerts(void)
{
if(s_vor == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);








//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);








s_vor = 1;
s_rueck = 0;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}








/************************************************** ********/








void rueckwaerts(void)
{
if(s_rueck == 0)
{
// enable pins aktivieren:
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);








//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);








s_vor = 0;
s_rueck = 1;
s_links = 0;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}




/************************************************** *********/
void rechts_drehen(void)
{
if(s_rechts == 0)
{
// enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);








//richtung bestimmen
digitalWrite(dirPin_VL, LOW);
digitalWrite(dirPin_HL, LOW);
digitalWrite(dirPin_VR, LOW);
digitalWrite(dirPin_HR, LOW);








s_vor = 0;
s_rueck = 0;
s_links = 0;
s_rechts = 1;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}
















/************************************************** ********/








void links_drehen(void)
{
if(s_links == 0)
{
//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);








//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);








s_vor = 0;
s_rueck = 0;
s_links = 1;
s_rechts = 0;
}
else{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(500);
}
}








/*
void links_drehen(void) //mit beschleunigung und sound
{








//enable pins aktivieren
digitalWrite(enbl_VL, HIGH);
digitalWrite(enbl_HL, HIGH);
digitalWrite(enbl_VR, HIGH);
digitalWrite(enbl_HR, HIGH);








//richtung bestimmen
digitalWrite(dirPin_VL, HIGH);
digitalWrite(dirPin_HL, HIGH);
digitalWrite(dirPin_VR, HIGH);
digitalWrite(dirPin_HR, HIGH);








//"j = 2000": der Anfangswert für das Delay in Microsekunden








for (int i = 0, j = 2000; i < stepsPerRevolution; i++)
{








//"j > 500": der Endwert für das Delay in Microsekunden - bestimmt auch die Endgeschwindigkeit (mindestens 250 bis 300)








if (j > 300) j--;
//"z < 3": wieviele Schritte mit dem eingstellten Delay "j" gemacht werden sollen, bevor es reduziert wird








for (int z = 0; z < 3 && i < stepsPerRevolution; z++)
{
digitalWrite(stepPin_VL, HIGH);
digitalWrite(stepPin_HL, HIGH);
digitalWrite(stepPin_VR, HIGH);
digitalWrite(stepPin_HR, HIGH);
delayMicroseconds(j);
digitalWrite(stepPin_VL, LOW);
digitalWrite(stepPin_HL, LOW);
digitalWrite(stepPin_VR, LOW);
digitalWrite(stepPin_HR, LOW);
delayMicroseconds(j);
i++;
}
}
}
*/
/************************************************** *********/
void reboot()
{
pinMode(PIN2RESET, OUTPUT);
digitalWrite(PIN2RESET, LOW);
delay(100);
}
/************************************************** *********/








/************************************************** **********/


Du hast da aber keinen Stop-Code drinnen, auf den Du reagieren kannst. Wenn der dann fährt, bleibt er nicht mehr stehen.
Allerdings ist der Code so angelegt, dass Du die Chance hast, eine Taste zu drücken, wenn er fährt, also auch eine Stop-Taste.
Die musst Du aber noch abfragen, weil noch nicht vorhanden!


MfG

- - - Aktualisiert - - -

Eine Funktion zum Anhalten des Fahrzeugs, auf den obigen Code zugeschnitten. Sollte aufgerufen werden, wenn eine Stop-Taste gedrückt wird.



/************************************************** *********/
void anhalten(void)
{
//enable pins deaktivieren
digitalWrite(enbl_VL, LOW);
digitalWrite(enbl_HL, LOW);
digitalWrite(enbl_VR, LOW);
digitalWrite(enbl_HR, LOW);
s_vor = 0;
s_rueck = 0;
s_links = 0;
s_rechts = 0;
}

inka
27.12.2019, 09:59
ich glaube nun verstanden zu haben, wie es geht, danke...
Jetzt werde ich die beiden methoden (IR und BT) als "quasi redundante" bedienmethoden unter einen hut bringen - beides ist mir nun geläufig, später kommt dann noch WiFi dazu - wer weiss was auf dem fremden planeten geht?

Moppi
27.12.2019, 10:18
Guten Morgen!

Ich will nochmals einen Vorschlag vertiefen.

Es ist tatsächlich die beste Lösung, zunächst einen Ablaufplan zu erstellen.
Noch ist so viel nicht im Programmcode drin. Jedenfalls nicht in diesem hier, wie eben besprochen.

Ein einfach zu handhabendes Programm, um PAPs zu erstellen, findet man hier zum Download: https://www.heise.de/download/product/papdesigner-51889
Bilder sagen mehr als Worte. Beispiel 1 und Beispiel 2 des Programms verdeutlichen, was ein PAp ist.

1. Zuerst muss ein neues Projekt angelegt werden (Projekt -> neues Projekt erstellen).
2. Daraufhin wird Start und Ende des PAP bereits vorgegeben.
3. Auf der rechten Seite hat man einige Symbole zur Auswahl. Diese genügen, um einen PAP zu erstellen.
4. Statt "Hauptprogramm 1" schreibt man z.B. "void loop()". Indem man den Schriftzug anklickt, öffnet man ein Menü, wo man den Text ändern kann.
5. Um zu verdeutlichen, dass es sich bei "loop()" um eine Funktion/Methode handelt, die immer wieder aufgerufen wird - also in einer Schleife abgearbeitet wird, kann man das Symbol für "Schleife" rechts anklicken und es anschließend mit der Maus zwischen "Start" und "Ende" platzieren.
6. Als Schleifenbedingung kann einfach "void loop()" eingetragen werden, damit klar ist, worum es sich bei der Schleife handelt.
7. Zwischen den Symbolen für Schleifenanfang und das Schleifenende können nun weitere Symbole platziert und beschriftet werden. Es gibt fünf weitere Symbole, mit denen ein kompletter Programmablauf beschrieben werden kann, indem die Symbole angeklickt, dann platziert und beschriftet werden. Außerdem kann man dann Verbindungen zwischen den Symbolen herstellen, wo auch Pfeile angetragen werden, so dass die Flußrichtung zu erkennen ist.
8. Um eine Verbindungslinie (Flußlinie) zwischen zwei Symbolen zu erstellen, klickt man zuerst das Symbol für "Verbindungspunkt bzw. Endpunkt einfügen" an. Danach klickt man ein Mal auf das Zielsymbol, dann bewegt man den Mauszeiger zum Symbol, von dem aus die Verbindung starten soll. Es erscheinen so kleine Vierecke mit Richtungsweisern in Grün, wenn man über ein Symbol fährt. Auf diese grünen Vierecke klickt man einmal drauf und es wird dann eine Verbindung in der gewünschten Richtung, zwischen den Symbolen gezogen. Man kann die Verbindungslinien noch beschriften, das ist z.B. bei Verzweigungen üblich, wo dann an jede Flußrichtung "ja" oder "nein" angetragen wird oder auch "wahr" oder "falsch", da eine Verzweigung durch eine Bedingungsprüfung erreicht wird (wie: "ist A > B ?").

Mit diesen wenigen Handgriffen kann man sich nun ziemlich schnell und einfach seinen PAP erstellen.

Welche Vorteile haben PAPs:

- beim Erstellen, muss der Programmablauf (Logik) reflektiert werden, was zu einem besseren Verständnis des Programms schon während des Zeichnens führt
- durch einfache und immer wiederkehrende Symbole wird eine Übersichtlichkeit und sehr gute Lesbarkeit erzeugt
- anhand des Diagrammflusses (Linien/Verbindungen zwischen den Symbolen) kann leicht nachvollzogen werden, was das Programm tut, es fallen Fehler auf und Fehlverhalten in der Programmlogik kann leicht erkannt werden
- einen PAP kann ein Programmierer in einen Programmcode übersetzen, wie C++
- bei einem gut angelegten PAP, der dann auch aus mehreren Teil-PAPs besteht, werden auch große oder "kompliziertere" Projekte übersichtlich und die Programmlogik im Einzelnen gut nachvollziehbar
- Fragen, wie: was tut dieser oder jener Programmteil (if .. while ..) können anhand eines PAP besser nachvollzogen werden, als man dies in Worten erklären kann.

Hält man sich beim Programmieren dann an den PAP, kann so gut wie nichts mehr schief gehen.




MfG

inka
27.12.2019, 13:33
da ich linux (ubuntu) verwende, kommt leider der pap-designer für mich nicht in frage, habe aber yEd installiert, mal sehen, wie ich damit zurechtkomme...
Ansonsten ist mir das mit den PAP's ja nicht neu, ist auch sinnvoll, klar...

Moppi
27.12.2019, 14:43
Schau mal hier (https://www.pcwelt.de/ratgeber/Windows-Programme-unter-Linux-157825.html), Wine ist ein Emulator. Ich habe vor Jahren mal gehört, das soll unter Linux gut funktionieren.


MfG

inka
27.12.2019, 14:56
wine kenne ich, seit jahren schon ein mehr oder weniger schlechter ersatz für echtes windows. Es ist bei linux so, entweder es gibt was vergleichbares an software, oder halt nicht und damit kann man leben (seit 12 jahren schon), es kostet aber nix...

Moppi
27.12.2019, 15:12
Als ich in den 90ern Linux installiert hatte, gab es nicht mal Treiber für Hardware, die ich brauchte. :) Deswegen bin ich dann bei Windows geblieben.
Ist aber jetzt ab vom Thema.

MfG

Searcher
28.12.2019, 07:34
Ein einfach zu handhabendes Programm, um PAPs zu erstellen, findet man hier zum Download: https://www.heise.de/download/product/papdesigner-51889

@Moppi: Danke. Super! DAS ist ja mal ein Tipp. Habe schon öfter versucht ein PAP mit Zeichenprogrammen zu erstellen. Auch mal mit Visio. Immer abgebrochen weil mir das dann zu umständlich war. Dieses Programm hab ich mir mal runtergeladen und kurz ausprobiert. Läuft sogar noch auf WINXP, kommt mir praktisch und auch wirklich einfach vor. Damit sollte ich diesmal vielleicht doch endlich mehr/bessere Dokumentation zu meinen Programmen schaffen.

@Inka: Ich mag zu sehen, was andere so basteln und lese eifrig mit.

Gruß
Searcher

inka
29.12.2019, 14:51
ich habe jetzt mal eine frage betreffend microstepping und wollte wissen, was ihr so drüber denkt...

Die extenderplatine für den steppertreiber hat ja einen 3poligen schiebeschalter on board, mit dem man - ohne strippen ziehen zu müssen - zwischen den verschiedenen microstep-modi umschalten kann. Allerdings ist sowas eher für den stationären betrieb gedacht, beim fahrenden roboter eher nicht gut machbar.
Die frage:
wäre es sinnvoll die schaltung von der extenderplatine zum arduino zu führen um dann vom smartphone auch "unterwegs" mal umschalten zu können? Alle motoren auf einmal, oder einzeln?

Moppi
29.12.2019, 15:01
Im Datenblatt steht, übersetzt mit goggle:


Beim Ändern der Stufe
Modus Die Änderung wird erst mit dem nächsten Schritt wirksam
Kante.
Wenn der Schrittmodus ohne Zurücksetzen des Übersetzers geändert wird, und absolut
Position muss beibehalten werden, es ist wichtig, die zu ändern
Schrittmodus an einer Schrittposition, die beiden Schrittmodi in gemeinsam ist
um fehlende Schritte zu vermeiden.

Die MAx-Geschwindigkeit, wie ich schon mal erwähnt habe, erreichst Du glaub ich nur im Full-Step-Mode.
Den Step-Mode musst Du dann bei allen Motoren gleichzeitig ändern. Sonst drehen die ja unterschiedlich schnell.

MfG