Neuling versteht Arduino-Sketch nicht ganz

Hallo

Ich habe schon recht viel gelesen, doch ganz klar, ich bin noch nicht so recht in der Materie eingearbeitet. Ich habe via Google oder auch hier im Forum nichts dergleichen gefunden was mir helfen könnte. Nun hoffe ich hier auf Unterstützung.

Ich habe vor einen Roboter zu steuern und ein paar Arduino Sketchs im Netz gefunden. Der Sender soll mit einem Arduino Pro Mini 16Mhz, einem Xbee Serie1 und unter anderem diesem Joystick Analog 2-axis Thumb Joystick with Select Button + Breakout Board : ID 512 : $5.95 : Adafruit Industries, Unique & fun DIY electronics and kits gesteuert werden.
Der Empfänger besteht aus einem Arduino Uno, Xbee Serie1 und einem Roboclaw 2x60A Motorcontroller.

Nun zur eigentlichen Frage. Ich verstehe im Sketch nicht so ganz, was beim Empfänger-Sketch in der Zeile für mappos3 resp. mappos4 geschieht. Am Roboclaw sind ja normale Motoren angeschlossen und keine Servos. Sind die Wertumwandlungen im Befehl map() nicht die Winkel vom Servo?

Im Sketch habe ich nur den Joystick Mittelklick (nehme ich an) mit der Übertragung dringelassen. das posarray[2] resp. posarray[3] sind die übertragenen Werte des Joysticks links/rechts resp. vorwärts/rückwärts. Hier mal der Sketch vom Sender: und Empfänger: (es geht um die rot markierten Zeilen)

Sendermodul:

int joybut = 11;
int joybutstate = 0;
int joybuttx;

void setup(){
pinMode(joybut, INPUT_PULLUP);
}

void loop(){
joybutstate=digitalRead(joybut);
if (joybutstate == LOW) {
joybuttx = 2;
}
if (joybutstate == HIGH) {
joybuttx = 1;
}

Serial.write(',');
Serial.write(joybuttx);

delay(25);

Empfängermodul:

#include <VarSpeedServo.h>

int mappos3;
int mappos4;
int posarray[8];
int i;

int servo3Pin = 9;
int servo4Pin = 10;
int joybut = 0;

VarSpeedServo servo3;
VarSpeedServo servo4;

void setup(){

Serial.begin(38400);

servo3.attach(servo3Pin);
servo4.attach(servo4Pin);
}

void loop(){

if(Serial.read() == ','){
while(Serial.available() >= 7){
for(i = 0; i < 8; i ++) {
posarray[i] = Serial.read();
}
}
}

joybut = posarray[0];

if(joybut==1){
mappos3 = map(posarray[2], 0, 180, 100, 80);
mappos4 = map(posarray[3], 0, 180, 100, 80);
}

if(joybut==2){
mappos3 = map(posarray[2], 0, 180, 100, 80);
mappos4 = map(posarray[3], 0, 180, 120, 60);
}
servo3.slowmove(mappos4, 20);
servo4.slowmove(mappos3, 20);

delay(10);
}

Ich hoffe es kann mir jemand Licht ins Dunkeln bringen.
Nebenbei noch, was bedeutet das “Serial.write(’,’);” für was steht das ‘,’?

Grüsse

Stef

Erstmal: Code immer in Code Tags </> posten, sonst gehen wesentliche Teile verloren (siehe oben).

Was der Code tun soll, kann ich Dir auch nicht sagen, IMO tut sich da überhaupt nichts. Wenn Du nichts sinnvolleres findest, wirst Du wohl alles selbst neu schreiben müssen.

Gleich mit DC Motoren zur Steuerung eines Robots anzufangen, das ist schon sehr sportlich. Ich würde eher mit einem kompletten Bausatz anfangen, der alles enthält bis hin zur Software. Hast Du schon einmal versucht, einen DC Motor in einer bestimmten Stellung anzuhalten? Falls nicht, dürfte das Dich die nächsten Wochen beschäftigen :-]

Was Serial.write(’,’) bedeuten soll, das steht im Empfänger Sketch.

stef308:
Am Roboclaw sind ja normale Motoren angeschlossen und keine Servos.

Roboclaw bietet verschiedene Möglichkeiten der Ansteuerung, auch als Servo. Du solltest Dir unbedingt "Pulse Ranges" in der Bedienungsanleitung ansehen und dann mittels µs steuern.

DrDiettrich:
Hast Du schon einmal versucht, einen DC Motor in einer bestimmten Stellung anzuhalten?

Scheint prinzipiell dafür gedacht, siehe "RC Mode with feedback for velocity or position control". Aber sportlich bleibt es dennoch :wink:

if(joybut==1){
mappos3 = map(posarray[2], 0, 180, 100, 80);
mappos4 = map(posarray[3], 0, 180, 100, 80);
}

map() ist eine Funktion die den Eingabewert (posarray[2]) in einen anderen Bereich mappt. Also ein Wert 0 wird 100; ein Wert 180 wird 80 und das gleiche mit anderen Werten dazwischen (aber auch außerhalb) Es ist eine Verhältnisrechnung.

zB wenn Du eine Spannung zwischen 0 und 3V hast, Du diese aber zwischen 0 und 100% als Percent Wert ausgeben willst benutzt Du map()
Analogwert = analogRead(analogpin); // Du bekommst Werte von 0 bis 613 für 0 bis 3,0V bei 5V Referenz (hoffe habe richtig gerechnet)
Prozent = map(Analogwert,0, 613, 0,100);

https://www.arduino.cc/reference/en/language/functions/math/map/

Grüße Uwe

Nebenbei noch, was bedeutet das "Serial.write(',');" für was steht das ','?

Nicht für einen Beistrich der ausgegeben werden soll?
Grüße Uwe

Erstmal: Code immer in Code Tags </> posten, sonst gehen wesentliche Teile verloren (siehe oben).

Merke ich mir, danke für den Hinweis!

Du solltest Dir unbedingt “Pulse Ranges” in der Bedienungsanleitung ansehen und dann mittels µs steuern.

Das sehe ich mir mal an. Ja die Roboclaws sollen DC Motoren wie einen Servo ansteuern können, habe ich auch gelesen, ich schaus mir mal an.

map() ist eine Funktion die den Eingabewert (posarray[2]) in einen anderen Bereich mappt. Also ein Wert 0 wird 100; ein Wert 180 wird 80 und das gleiche mit anderen Werten dazwischen (aber auch außerhalb) Es ist eine Verhältnisrechnung.

zB wenn Du eine Spannung zwischen 0 und 3V hast, Du diese aber zwischen 0 und 100% als Percent Wert ausgeben willst benutzt Du map()
Analogwert = analogRead(analogpin); // Du bekommst Werte von 0 bis 613 für 0 bis 3,0V bei 5V Referenz (hoffe habe richtig gerechnet)
Prozent = map(Analogwert,0, 613, 0,100);

Das habe ich auch so verstanden, aber ich begreife nicht wofür der Wert 100 und 80 der ausgegeben wird, steht? Das können ja unmöglich die Winkel der Servosteuerung sein…

Nebenbei noch, was bedeutet das “Serial.write(’,’);” für was steht das ‘,’?

Nicht für einen Beistrich der ausgegeben werden soll?

Doch, das stimmt glaube ich. Das gibt die Serial.write Werte getrennt weiter, stimmt das so? Wenn ja, danke für den Stupser :slight_smile:

stef308:
… aber ich begreife nicht wofür der Wert 100 und 80 der ausgegeben wird, steht?

Für die Richtung und die Geschwindigkeit: rückwärts < 90 < vorwärts

Die 80 steht für langsam rückwärts, 0 wäre volle Pulle. Die 100 steht für langsam vorwärts, 180 wäre volle Pulle.

Die Winkel entsprechen einer Impulszeit des Servosignals. Die Servobibliothek erlaubt auch die Angabe von Zeiten in µs. Da würde ich direkt die Zeiten aus der Bedienungsanleitung verwenden, weil die Zeiten dann genau passen und sich das besser abstufen läßt.

Ach so! Wo kann man denn das nachlesen? Weiss man das einfach oder gibt es da etwas? Also ich weiss es ja jetzt, aber für die Zukunft.
Super, vielen Dank! Dann schau ich das mal an.

aber für die Zukunft.

Hast du vor das wieder zu vergessen?
:o :o :o :o :o

Tipp:
Das Internet weiß fast alles!
Und dein Servo Antrieb funktioniert wie ein Seilwinden Servo
Also: Google(Seilwinden Servo Ansteuerung)
(das suche ich dir jetzt nicht)

stef308:
Wo kann man denn das nachlesen?

Bedienungsanleitung gepaart mit Erfahrung, um die Bedienungsanleitung zu verstehen.

Danke Euch beiden! Vergessen nicht, das weiss ich jetzt!
Wenn man manchmal nur nach den richtigen Dingen suchen würde...

Habs nochmals angeschaut und soweit verstanden. Etwas ist mir jedoch noch aufgefallen:

#include <VarSpeedServo.h>

int mappos3;
int mappos4;
int posarray[8];
int i;

int servo3Pin = 9;
int servo4Pin = 10;
int joybut = 0;

VarSpeedServo servo3;
VarSpeedServo servo4;

void setup(){

Serial.begin(38400);

servo3.attach(servo3Pin);
servo4.attach(servo4Pin);
}

void loop(){

if(Serial.read() == ','){
while(Serial.available() >= 7){
for(i = 0; i < 8; i ++) {
posarray[i] = Serial.read();
}
}
}

joybut = posarray[0];

if(joybut==1){
mappos3 = map(posarray[2], 0, 180, 100, 80);
mappos4 = map(posarray[3], 0, 180, 100, 80);
}

if(joybut==2){
mappos3 = map(posarray[2], 0, 180, 100, 80);
mappos4 = map(posarray[3], 0, 180, 120, 60);
}
servo3.slowmove(mappos4, 20);
servo4.slowmove(mappos3, 20);

delay(10);
}

Ganz unten in der Zeile “servo3.slowmove(mappos4, 20);” steht ja nochmals die Geschwindigkeit mit dem Wert 20 drin oder nicht? Was hat das für einen Zweck?

Und noch eine andere Frage die mich total durcheinander bringt.
Wenn ich am Gerät1 ein Input auf HIGH setze und sobald ein Signal kommt auf LOW an einen Output befehle, muss dann am angehängten Gerät2 der Input auf INPUT_PULLUP stehen, stimmt das so, damit er das Signal wahrnimmt?

Grüsse

Stef

P.S. @Tommy: Ich habs schon verstanden, aber dachte, weil ich den Sketch schon gepostet habe ganz oben mache ich den als Zitat nochmals rein - sorry…

Versuche mal den Unterschied zwischen [*quote] (Zitat) und [*code] (Quelltext) - ohne * - zu verstehen und korrigiere bitte Deinen Beitrag.

Gruß Tommy

stef308:
Ganz unten in der Zeile "servo3.slowmove(mappos4, 20);" steht ja nochmals die Geschwindigkeit mit dem Wert 20 drin oder nicht? Was hat das für einen Zweck?

Du nutzt eine Bibliothek, wo die Begrifflichkeiten nicht zur Nutzung durch den Treiber passen. Das kann irritieren.

Die Geschwindigkeit wird über die Servo-Position bestimmt, dementsprechend dürfte die Servo-Geschwindigkeit der Beschleunigung entsprechen.