Arduino Micro mouse "press", "move" und "release" oder Drag and drop

Hallo Leute, ich probiere schon eine “Drag and drop” funktion mit einen Encoder und Arduino zu emulieren.
Dafür habe ich einer Sketch modifiziert der ich gefunden habe. Der Original Sketch ist von Tim:
http://www.tim.id.au/limejuice/volume-control-with-arduino-leonardo/.

Alle Funktioniert mit eine Aussnahme und zwar, wenn ich damit einen Fader steuern möchte läuft es ganz gut aber wenn es um einer Drehe knopf geht, funktioniert es nur bis der cursor der “Press” Bereich verläst.

ich hab einer kleine Filmchen vorbereitet: - YouTube

Kann jemanden Helfen? hier ist mein Sketch (ich hab die relevante Bereich in Rot markiert):

#include <Mouse.h>

const int encoderA = 2;
const int encoderB = 3;

int position = 0;
int volume = 0;
int encoderState = LOW;
int encoderLastState = LOW;

[color=red]void raiseVolume()
  { position++;
  Mouse.press();
  Mouse.move(0, 10, 0);
  delay(10);
  Mouse.release();
  }

void lowerVolume()
  {
  if (position > 0)
    position--;
  Mouse.press();
  Mouse.move(0, -10, 0);
  delay(10);
  Mouse.release();
  }[/color]

void printStatus()
  {
  Serial.print("Position: ");
  Serial.print(position);
  Serial.print(", volume: ");
  Serial.print(volume);
  Serial.println("%");
  }

void setup()
  {
  pinMode(encoderA, INPUT);
  digitalWrite(encoderA, HIGH);
  pinMode(encoderB, INPUT);
  digitalWrite(encoderB, HIGH);
  Mouse.begin();
  Serial.begin(9600);
  }

void loop()
  {
  
  encoderState = digitalRead(encoderA);
  if (encoderLastState == LOW && encoderState == HIGH)
    {
    if (digitalRead(encoderB) == LOW)
      lowerVolume();
    else
      raiseVolume();
    
    
    printStatus();
    }
  encoderLastState = encoderState;
  
  
  
  }

Die Encoder Controls sind zum Drehen gedacht, nicht wie Schieberegler zum linearen Verschieben, und sie reagieren nicht auf Mausbewegungen außerhalb ihres Darstellungsbereichs (Control Window). Laß die Maus über dem Encoder Control kreisen, dann sollte es funktionieren.

Hi, Vielen dank für die Antwort und fröhes Fest;-))

die Virtuelle drehe Encoder auf dem Bildschirm, bewege ich normalerweise, genau wie die Virtuelle Fader, mit : Linke maus Taste gedruck halten und der maus nach unten oder nach oben bewegen. Das ist genau was ich auch mit dem "Arduino" Encoder simulieren möchte.

Ich muss heraus finden wie ich hinbekomme folgendes (es geht hier um der Physischer Encoder der ich an der Arduino angeschloßen habe):

  1. mousePress sobald eine Encoder bewegung erkannt werden
  2. mouseMove
  3. mouseRelease sobald es ekannt werden dass der Encoder länger als "xx" sekonden stehen bleibt.

in meinem code geht der Press und Release ohne auf bewegung Pause zuwarten los.....

Ich hoffe dass ich etwas klare jetzt beschrieben haben können...

Danke nochmal.

Angenommen wir teilen ein Encoder Control in 6 Segmente ein, dann muß sich der Mauszeiger von einem dieser Segmente in das nächste bewegen, das gibt dann etwa eine Kreisbewegung in 6 Schritten. Dazu kannst Du ein Array mit den relativen Koordinaten der Segmente benutzen, und einen Fixpunkt im Control, z.B. seinen Mittelpunkt, und den Index des Segments, in dem der Mauszeiger zuletzt stand (bei Release). In raiseVolume bewegst Du den Mauszeiger auf dieses Segement im Control, dann Press und Bewegung zum nächsten Segment, solange der Wert weiter erhöht wird. Zuletzt Release und aktuellen Segmentindex merken.

Alles am besten in eine Klasse packen, und lowerVolume() und raiseVolume dort als Methoden implementieren, z.B. als turnLeft() und turnRight(). Dann für jedes Encoder Control eine Instanz dieser Klasse erzeugen, mit den Bildschirmkoordinaten des Fixpunkts.

Hallo DrDiettrich,

vielen Dank für die Lösungansatz aber ich glaube dass ich mein Anlegen, vielleicht, nicht so gut beschrieben habe. Deine lösung, so wie ich es verstanden habe, geht in einer andere Richtung.

Ich möchte gerne bildschirm reglern über einer Hardware encoder bedienen so wie ich es bis jetzt mit einen Maus tue.

Mit dem Maus geht das durch Press (Klick and hold) und noch unten oder nach oben Ziehen (Drag and drop) wie beim “Windows” wenn man der Volumeregler bewegt.

Bei meine Software der Form der Regler ist völlig egal da solang der maus auf “Press” ist, lockt der Zeiger sich auf die sich unter befindende Regler und muss nicht der form der Bildschirmregler befolgen.

zurzeit in mein Code ist es so das der zeiger jede 10 Pixel (zeiger bewegung) wieder auf Release geht und fängt von vorn an also “Press”, 10 pixel “Move” und wieder “Release” und das Natürlich in einer Loop.

Was ich benötige ist wie folgend:

  1. mousePress sobald eine “mouseMove” (egal in welche Richtung) erkannt worden

  2. mouseRelease sobald einen Zeiger (mouseMove) Stillstand von über 2 sek. (als beispiel) erkannt worden.

Die unterschidliche Regler am Bildschirm selektiere ich über einen Touchscreen oder normale Maus. Der Arduino mit dem Encoder sollen dinnen als so eine art universal Regler der regelt der bildschirm regler der grade geklickt is.

Vielen Dank nochmal,

Tal

Mit "mouse capture" bekommst Du ein Problem beim Release, denn dann wird die Verbindung (capture) zum Control beendet. Beim nächsten Press steht die Maus nicht mehr auf dem Control, die nachfolgenden Messages gehen damit ins Leere (an das Fenster). Du müßtest also vor jedem Press den Mauszeiger auf das Control setzen, das die nachfolgenden Moves bekommen soll.

Das ist kein Problem. Ich muss den Zeiger sowieso immer vorher auf das Control setzen die ich bewegen möchte. Darum geht das auch. die Funkzion heißet, bei uns in der Audio branche, "touch and turn". es gibt einen Hardware regler und damit kann man unterschidliche controllern bewegen.

man klick an den gewünsche controller im bildschirm und man bewegt ihn mit dem Encoder.

man kann es auch mit dem Scroll funktion der Maus machen aber die ist total und genau und hat sprunge.
mit der "maus Ziehen" geht das viel besser mit dem nachteil das beim "maus Ziehen" mus mann den Zeiger auf Press setzten ansonst bewegt sich nur der Zeiger ohne was zu ändern.

gewünscht ist einfach eine Funktion wie beim Datei auf dem Desktop hin und her schieben....

Danke.

Dann sind wir uns doch offensichtlich einig. Vor jedem Press mußt Du den Mauzeiger auf das Control setzen, das geändert werden soll. Dazu muß der Arduino natürlich wissen, wo das Control im Fenster liegt, damit er den Mauszeiger dort hinbewegen kann.

Ja genau...

ich finde leider nicht heraus wie ich anduino sagen soll:

if "mouseMove" (egal in welche richtung)
dann "mousePress"...
if "mouseMove" stops für mehr als x secends
dann "mouseRelease"

hast du ein idee?

Danke.

talfish:
if "mouseMove" (egal in welche richtung)
dann "mousePress"...
if "mouseMove" stops für mehr als x secends
dann "mouseRelease"

Der Arduino kann Mausbewegungen simulieren, nicht wahrnehmen.

Das wird so nix. :frowning:

Erst mal brauchst Du die Mausposition, wenn Move nur relativ erfolgen kann. Die muß bei jedem Move aktualisiert werden. Ärgerlich dabei ist, daß der Benutzer den Mauszeiger auch mit seiner Maus verschieben kann. Dann brauchst Du die Positionen der Controls, um die Maus um das zum Encoder gehörige Control setzen zu können. Das könnte vereinfacht werden, wenn Du den Encodern und ihren Controls Mausknöpfe zuweist, und vor Press ein ButtonDown schickst, dann kann das GUI Programm die Maus selbst auf das Control setzen.

Im Code fragst Du ab, welcher Encoder bewegt wurde, merkst Dir den und schickst die entsprechenden Messages ab. Wenn der Encoder eine bestimmte Zeit unverändert bleibt, oder ein anderer bewegt wird, kannst Du Release schicken und ggf. auf den nächsten Encoder umschalten.

Noch einfacher wäre es für den Arduino, wenn der auch Keyboard Messages senden kann, die dann vom GUI Programm entsprechend interpretiert werden. Dann könntest Du auf die Mausbewegungen ganz verzichten, und alle Bedienungen in Zeichenfolgen codiert übertragen. Oder mit Processing direkt abfragen, was am Arduino bedient wurde, und entsprechend reagieren.

OK, ich glaube dass ich wieder falsh formuliert habe.....

wenn ich schreibe "mouseMove" heißt es : wenn ich der Encoder, der an der Arduino angeschloßen ist um der zeiger am bildschirm zu bewegen, bewege......

also auf eine neues;-))):

if "mouseMove" (sobald ich den Hardware Encoder drehe und einer "mouseMove" an der Arduino sende, egal in welche richtung)
dann "mousePress"...
if "mouseMove" (siehe oben) stops für mehr als x secends
dann "mouseRelease"

der Arduino muss nicht wissen wo der zeiger ist...... ich brige der zeiger dort hin wo ich was verändere möchte an den Biildschirm.

Zur Wartezeit siehe Debounce und StateChangeDetection Beispiele.