Joystick Logik klappt nicht :-(

Experimentiere gerade ein wenig mit einem Joystick zur motorsteuerung.

Dieser hier !

Verstehe aber nicht so richtig die logic hinter dem maping :o

Bei Stop habe ich X=339 Y=350

Bei vorwärts X=339 Y=674 Da sollte doch sein fs = (map(joystick[0], 339, 674, 0, 255)); forward(fs);

Rückwärts X=339 Y=1 dementsprechend ... bs = (map(joystick[0], 339, 1, 0, 255)); backward(bs);

Links X=0 Y=350 ls = (map(joystick[1], 0, 350, 0, 255)); turnleft(ls);

Rechts X=674 Y=350 rs = (map(joystick[1], 350, 674, 10, 255)); turnright(rs);

Aber irgendwie funktioniert das ganze nicht. Die Motoren laufen in irgendeine Richtung. Wo liegt mein denkfehler ?? :(

Wieso glauben alle wir könnten hellsehen?

Da ich Dir garantiere, daß wir es nicht können, brauchen wir von Dir den GESAMTEN Sketch, den Schaltplan und die benutzten Teile (Arduino, Motortreiber und Motor).

Grüße Uwe

Hallo Uwe,

vieles ist im Link untergebracht (auch wenn das erneute posten hier sinnvoller gewesen wäre).

Der Schaltplan von dem Ding fehlt aber und das ist hier das Problem!
Die Werte bei einem Stop (ich gehe mal davon aus, dass es sich hier um die Mittelstellung handelt im unbetätigten Zustand) sind dann schon einmal fehlerhaft.

Erwartet werden sollten hier Werte für Y = 511 und X = 511. Abweichungen der Werte um mehrere 10er Stellen sind hier durchaus üblich. Die verbauten Potis und der Hebel haben einen sehr kurzen Weg und fahren nicht 100% in Nullstellung(Mittelstellung).

Für die map-Befehle müsstest du dann entsprechend das ganze so anpacken

Y-Achse
int val_y = map(raw_y, 0, 1023, -256, 255);

X-Achse
int val_x = map(raw_x, 0, 1023, -256, 255);

Fällt der Wert von val_y auf <= 0, so sollte der Motor Rückwärts, andern falls Vorwärts fahren.
if(raw_y < 0) rw((val_y*(-1))-1);
else fw(val_y);

hi,

wenn man allerdings nicht von datenblattwerten ausgeht, sondern von den real gemessenen, würde ich das map von 0 bis 675 statt von 0 bis 1023 machen...

gruß stefan

sschultewolter: Hallo Uwe,

vieles ist im Link untergebracht (auch wenn das erneute posten hier sinnvoller gewesen wäre).

Er umschreibt den Link auf die Seite mit "Dieser hier !". Dadurch habe ich angenommen, daß er sich nur auf das Foto auf der Seite bezieht. Natürlich kann er auch den Sketch der Seite verwenden, aber dann sollte er es auch explizit schreiben.

Zum Rätselraten habe ich keine Lust. ;) ;)

Grüße Uwe

uwefed: Wieso glauben alle wir könnten hellsehen? Da ich Dir garantiere, daß wir es nicht können ...

Hallo Uwe! Ich erwarte nicht von dir das Du in die Zukunft schauen kannst. Wobei das natürlich schon nicht schlecht wäre. Allein schon wegen der Lottozahlen von nächster Woche :-)

uwefed: Natürlich kann er auch den Sketch der Seite verwenden, aber dann sollte er es auch explizit schreiben.

Zum Rätselraten habe ich keine Lust. ;) ;) Grüße Uwe

Ich wollte einfach einen doppelpost vermeiden. Außer dem geht es mir erstmal darum die logik mit dem joystick zu verstehen. Daher die frage mit dem mapping.

sschultewolter:
Hallo Uwe,

vieles ist im Link untergebracht (auch wenn das erneute posten hier sinnvoller gewesen wäre).

Der Schaltplan von dem Ding fehlt aber und das ist hier das Problem!
Die Werte bei einem Stop (ich gehe mal davon aus, dass es sich hier um die Mittelstellung handelt im unbetätigten Zustand) sind dann schon einmal fehlerhaft.

Erwartet werden sollten hier Werte für Y = 511 und X = 511. Abweichungen der Werte um mehrere 10er Stellen sind hier durchaus üblich. Die verbauten Potis und der Hebel haben einen sehr kurzen Weg und fahren nicht 100% in Nullstellung(Mittelstellung).

Für die map-Befehle müsstest du dann entsprechend das ganze so anpacken

Y-Achse
int val_y = map(raw_y, 0, 1023, -256, 255);

X-Achse
int val_x = map(raw_x, 0, 1023, -256, 255);

Fällt der Wert von val_y auf <= 0, so sollte der Motor Rückwärts, andern falls Vorwärts fahren.
if(raw_y < 0) rw((val_y*(-1))-1);
else fw(val_y);

sschultewolter: Erwartet werden sollten hier Werte für Y = 511 und X = 511. Abweichungen der Werte um mehrere 10er Stellen sind hier durchaus üblich. Die verbauten Potis und der Hebel haben einen sehr kurzen Weg und fahren nicht 100% in Nullstellung(Mittelstellung).

Für die map-Befehle müsstest du dann entsprechend das ganze so anpacken

Y-Achse int val_y = map(raw_y, 0, 1023, -256, 255);

X-Achse int val_x = map(raw_x, 0, 1023, -256, 255);

Ich verstehe was du meinst ! 0-1023 Wert was das poti liefert und -256 - 255 was das skript interpretiert. Richtig?

Nun messe ich allerdings 0-674 ! Wäre dann nicht logisch map(raw_y, 0, 674, -256, 255) !?

Eisebaer: hi,

wenn man allerdings nicht von datenblattwerten ausgeht, sondern von den real gemessenen, würde ich das map von 0 bis 675 statt von 0 bis 1023 machen...

gruß stefan

Danke Stefan ... Das war jetzt mein Gedanke ...

Also Vorwärts fs = (map(joystick[0], 339, 674, -256, 255)); forward(fs);

Rückwärts bs = (map(joystick[0], 339, 1, -256, 255)); backward(bs);

Links ls = (map(joystick[1], 0, 350, -256, 255)); turnleft(ls);

Rechts rs = (map(joystick[1], 350, 674, -256, 255)); turnright(rs);

Stefan, wie kommst du auf die Werte deutlich unterhalb von dem Maximalausschlag (1023)?

Böse falle 8)

Habe gerade festgestellt das sich die werte laufend verändern. Und siehe da eine kalte Lötstelle auf dem Joystickshield. Da waren weniger als 5Volt welches meine abwechenden Werte ausmachte. Nachgelötet und jetzt sind dort 5Volt und 1023 als maximalwert sind vorhanden. ;)

Danke für die Hilfe !!

Jetzt läuft es mit dem Joystick ;)

Youtube

hi,

Stefan, wie kommst du auf die Werte deutlich unterhalb von dem Maximalausschlag (1023)?

das sind die werte, die er im ersten post angegeben hat...

gruß stefan

Da hab ich seine Werte schon nicht verstanden, da das Shield auch nur einen einfachen PS2 üblichen Joystick verwendet.

Aber hat sich ja rausgestellt, dass da was nicht ordentich gelötet war.

hi,

ich hab' zwar den PS2-joystick zuhause, aber noch nie für was artfremdes verwendet. deshalb dachte ich, die werte sind "normal".

gruß stefan

Ich hab das ganze mal handlich verpackt und funktioniert auch schon mal recht gut :slight_smile:

Nun lass ich mir unteranderem die x und y Position vom joystick im Display anzeigen. Leider bleibt mir da immer die vierte stelle hängen. Es muss doch möglich sein das zu unterdrücken … !?

Hier gut zu sehen !

Ein lcd.clear sorgt bei mir nur für flackernde anzeige :roll_eyes:
Hat da vielleicht jemand ein Lösungsansatz für mich :wink:

// NRF24L01 Remote control - Last update: AndreasVan 2015-03-24 Version 1.31
// NRF24L01 connected to Arduino Uno
// Transmit analog values from joystick to the receiver using RF24 library
// Receive 2 floats (current from the motors) from Explorer Controller Board

// LiquidCrystal
// LCD RS pin to digital pin 0 
// LCD Enable pin to digital pin 1
// LCD Backlight pin 3
// LCD D4 pin to digital pin 4
// LCD D5 pin to digital pin 5
// LCD D6 pin to digital pin 6
// LCD D7 pin to digital pin 7
// LCD R/W pin to ground

// 1 - GND
// 2 - VCC 3.3V !!! NOT 5V
// 3 - CE to Arduino pin 9
// 4 - CSN to Arduino pin 10
// 5 - SCK to Arduino pin 13
// 6 - MOSI to Arduino pin 11
// 7 - MISO to Arduino pin 12
// 8 - UNUSED
   
// Default Button Pins: 
// Up - pin 2
// Right - pin 3
// Down - pin 4
// Left - pin 5
// - 
// Analog Joystick module
// GND to Arduino GND
// VCC to Arduino +5V
// X Pot to Arduino A0
// Y Pot to Arduino A1

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
#include <Bounce2.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x27  // Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

int n = 1;
LiquidCrystal_I2C	lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
RF24 radio(9,10);

const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

int joystick[3];
float current[4];

const int z = 2;
int roverState = LOW;         // the current state of the output pin

Bounce bouncer = Bounce();

long previousMillis = 0;
long interval = 25;

void setup(){
  pinMode(z, INPUT);
  radio.begin();
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  radio.startListening();
  lcd.begin (20,4);
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();                  
  lcd.clear();
  lcd.print("   Startup Remote ");
  lcd.setCursor(0, 1);
  lcd.print("    Version 1.31  ");
  delay(1000);
  lcd.clear();
  lcd.print("   Rover 5 active  ");
  lcd.setCursor(3,3);
  lcd.print("M1=");
  lcd.setCursor(11,3);
  lcd.print("M2=");

}

void loop(){
  joystick[0] = analogRead(A1);
  joystick[1] = analogRead(A0);
  joystick[2] = roverState;
  lcd.setCursor(3,2);
  lcd.print("X=");
  lcd.print(joystick[0]);
  lcd.setCursor(11,2); 
  lcd.print("Y=");
  lcd.print(joystick[1]);

  if ( bouncer.update() ) {
    if ( bouncer.read() == HIGH) {
      if ( roverState == LOW ) {
        roverState = HIGH;
      } 
      else {
        roverState = LOW;
      }
    }
  }

  if ( radio.available() )
  {
    unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    
    // Dump the payloads until we've gotten everything
    bool done = false;
    while (!done)
    {
      // Fetch the payload, and see if this was the last one.
      done = radio.read( &current, sizeof(current) );

    }
  }

    lcd.setCursor(6,3);
    lcd.print(current[0]);
    lcd.setCursor(14,3);
    lcd.print(current[2]);
    radio.stopListening();
    bool ok = radio.write( &joystick, sizeof(joystick) );
    radio.startListening();  

  }
}

Hallo, anstelle Löschen überschreibst Du mit Leerzeichen. Also: 1234 456_ 9___ 7654

Hier mein Geheimtipp zur formatieten Ausgabe von anderen schlauen Menschen im Forum.

Jetzt muss ich mir nur überlegen wie ich die Leerzeichen in die ausgabe vom Joystick integrieren kann :art:

Moin,

ich habe auch mal einen Joystick ausgewerten und damit vier Motoren angesteuert. Mien Tipp: In der Nullstellung des Joysticks solltest Du einen toten Bereich legen, in dem dann elles als Nullstellung angesehen wird. Das gleiche würde ich dann bei den maximalen Ausschlägen genauso machen. Das stellt dann eine Art Hysterese dar. Brauch auch nicht viel sein, ein paar Bitwerte langen da schon.

Damit umgehst Du das "bitflattern" von den analogen Eingängen. Zudem kann ich mir nicht vorstellen, dass die Nullstellung vom Joystick immer den gleichen Wert hat. Oder später, wenn der Joystick dann schon ein paar Jahr alt ist, immer noch so leichtgängig ist wie in seinen jungen Jahren.

Bei meiner Joystick-Auswertung hat dass auf jeden Fall viel bewirgt.

Viele Grüße Christian

Nochmal zu den Leerzeichen: Andere freundliche Mitglieder des Forums haben mich zu diesem Code angeleitet (Quelle):

void StarteMusikWiedergabe(int nummer) {
  char track[9] = { 0 };
  strcat_P(track, PSTR("t000"));
  if (nummer < 10) {
    itoa(nummer, track + 3, 10);
  }
  else if (nummer < 100) {
    itoa(nummer, track + 2, 10);
  }
  else {
    itoa(nummer, track + 1, 10);
  }
  strcat_P(track, PSTR(".mp3"));
  debugPrint(F("Musik beginnt mit Datei: "));
  debugPrintln(track);
  musicPlayer.startPlayingFile(track); // Lied beginnt
}

Da I2C auch mal Fehler produziert, steht dann möglicherweise Schrott auf dem Display und wird nicht gelöscht. Daher beschreibe ich immer eine ganze Zeile einschließlich festem Text und Leerzeichen.