0

XRAD'S MOUSY WHEEL
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

XRAD'S MOUSY WHEEL

by XRAD on Mon Feb 11, 2019 5:07 pm

I am tired getting logged out of my work computer. It is behind two locked doors and only I use it. I can't load a move mouse program either. So I built one of these! Nearly truly random 'x' and 'y' motion and an additional independent nearly random time function. I took a few lines of basic servo code and added a bunch of stuff including arduino's random seed using the ATSAMD21 pin 20 (well it could be pin 19...). This is a not pretty looking prototype enclosure. I am using a 12v power supply stepped to 5v 2.5A and a polplu 2808 mini power switch. Of course , the trinket M0 is capable of much more than this simple process, so I added 2 LEDs ;) . One is for the rotating servo and one for the linear servo. They are triggered HIGH when certain servo signal criteria are met.

The cool part about this program is that you can adjust servo travel at same time you are adjusting the 'random' position event. Soooo, if you do not like the linear travel (might be hitting the edge) or rotating travel limits, you can easily adjust them. The rotating servo housing slides vertically on to to end of the toothed rack. But, it is not rigidly fixed to the rack. this allows a bit of vertical play as the wheel rotates, or to make up for my poor housing measurements.

I really wanted to put the whole moving plate under a piece of 1/8th plexi, but the focal zone for my home and work mice is right beyond the sensor hole. More than a few mm's away, and no motion. Anyway, fun build and you can surely use this code for other cool projects /props.....Of course, this mouse box really is made to fit a G500s mouse, but a universal box (to work with most cheap standard sized work mice) could be easily constructed.

I love 'randomness,' so many of my codes incorporate this capability. If you look at my code, you can see that there is :
Code: Select all | TOGGLE FULL SIZE
//some storage for random #'s
long randomNumber;
long randomNumber1;

I ran into some strange servo behavior using the same memory for 'time' and the 'servos' but not for just the servos. Also, I could not use ((x>=y)&&(x<=z)) . Not sure why either. Maybe the loop and random generator are too fast? So I had to settle for on/off LEDs based on < or>. Adds a bit of color to the project. Press the momentary power on button and the wheel centers, and the LEDs light up. Center your pointer on the screen and drop mouse into the Mousy Wheel. 'Never' repeats same pattern !!

Final Code Here:
Code: Select all | TOGGLE FULL SIZE
/***************************************************
     ==========XRAD'S MousyWheel===========
  Tired of that log-off screen?? Can't load that move
  mouse program?  Build one of these! Random seed for
  motion and time delay, makes for a really 'almost
  completly random' event!! Do I smell a two hour lunch?
***************************************************/

#include <Servo.h>

#define LED 3  //PWM  for 'rotating' led
#define LED1 4  //PWM  for 'linear' led

//declare servo object
Servo servo1;//rotate
Servo servo2;//linear

//some storage for random #'s
long randomNumber; //for servos
long randomNumber1; //for time

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(LED1, OUTPUT); 
  digitalWrite(LED, HIGH);
  digitalWrite(LED1, HIGH);
  delay(50);
  servo1.attach (0);//rotate
  servo2.attach (2);//linear
  servo1.write(90);//mid rotator position to set baseline
  servo2.write(60);//mid slider position to set baseline
  randomSeed(analogRead(20));//some pin not used
  delay(5000); //place your mouse down on wheel
}

void loop() {

  //random servo position rotating
  randomNumber = random(30, 150); //random travel (servo min, servo max)
  int pos = randomNumber;
  servo1.write(pos);//move servo1 to new position
  delay(80);
   if (pos <= 90) { //midpoint
    digitalWrite(LED, LOW);
  }
   if (pos >= 91) {
    digitalWrite(LED, HIGH);
  }

  //random servo position linear
  randomNumber = random(10,120); //random travel (servo min, servo max)
  pos = randomNumber;
  servo2.write(pos);//move servo2 to new position
    if (pos <= 65) {  //midpoint
    digitalWrite(LED1, LOW);
  }
   if (pos >= 66) {
    digitalWrite(LED1, HIGH);
  }
 
  //random time delay
  randomNumber1 = random(1000, 5000);//delay in millisecs
  delay(randomNumber1);
}


IMG_3076.JPG
IMG_3076.JPG (210.93 KiB) Viewed 192 times
Last edited by XRAD on Mon Feb 11, 2019 6:33 pm, edited 12 times in total.

XRAD
 
Posts: 560
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S MOUSY WHEEL

by XRAD on Mon Feb 11, 2019 5:30 pm

some 'paint drying' vids:

https://www.youtube.com/watch?v=JMho3NSqtV8

https://www.youtube.com/watch?v=z8vvJaA ... e=youtu.be

IMG_3061.JPG
IMG_3061.JPG (247.96 KiB) Viewed 192 times


IMG_3062.JPG
IMG_3062.JPG (222.53 KiB) Viewed 192 times


IMG_3065.JPG
IMG_3065.JPG (224.86 KiB) Viewed 192 times

XRAD
 
Posts: 560
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S MOUSY WHEEL

by XRAD on Tue Feb 12, 2019 10:32 pm

Worked like a champ today!

smiley.jpg
smiley.jpg (6.52 KiB) Viewed 170 times

XRAD
 
Posts: 560
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S MOUSY WHEEL

by adafruit_support_bill on Wed Feb 13, 2019 6:59 am

Cool project! Thanks for posting.

adafruit_support_bill
 
Posts: 74965
Joined: Sat Feb 07, 2009 10:11 am

Re: XRAD'S MOUSY WHEEL

by XRAD on Mon Jun 03, 2019 10:20 pm

THX Bill! Sorry for late reply, just revisiting tonight. After running for a few months, my 2.5 amp power supply quit. This gave me the opportunity to reassess servo speed. So it took a few hours, but I came up with a sketch that is 'completely' random and has slow servo movement. This does not use angles or degrees or timers to limit servo speed. Just a few simple for( )'s. Generally, the key to slow servo motion is to have two points A and B, and the servo move from A to B with a delay, or through angles, or A to B with a timer.

My issue is that by choosing ONE random servo location between say 30 and 150 degrees, I only have one point to work with. So the first movement is fairly straightforward. The second movement becomes more challenging because you can't travel beyond the limits of servo travel. So you have to create a second point to go to (or leave from). Look through the code to see how it works out. I do get a jump once in a while at travel limits during reverse. But other than that it is really a cool idea (getting two points from one random servo point) implemented through an OK sketch....

I know there are several 'slow' servo libraries out there(many years old), but this approach is easier for the beginner and less math/code intense....

I am no code pro; there are definitely better ways to do this. Please feel free to add corrections, improvements, etc... This is good for slow servo random props!

Feeling the working code mental buzz right now!! :)


Code: Select all | TOGGLE FULL SIZE
/***************************************************
     ==========XRAD'S MousyWheel V2===========
  Tired of that log-off screen?? Can't load that move
  mouse program?  Build one of these! Random seed for
  motion and time delay, makes for a really 'almost
  completly random' event!! Do I smell a two hour lunch?

  This is the new SLOW servo sersion without using a
  servo 'timer.' It is blocking, but good for slow props!
  Work in progress......
  The servos have to actuate once to determine a
  lastPosServo, then they will operate slowly 99% of time
***************************************************/

#include <Servo.h>

#define LED 3  //PWM  for 'rotating' led
#define LED1 4  //PWM  for 'linear' led

int lastPosServo1; //save last servo position for next time
int lastPosServo2; //save last servo position for next time
 
#define DELAYTIME 15

//declare servo object
Servo servo1;//rotate
Servo servo2;//linear

//some storage for random #'s
long randomNumber; //for servos
long randomNumber1; //for time

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(LED1, OUTPUT);
  digitalWrite(LED, HIGH);
  digitalWrite(LED1, HIGH);
  delay(50);
  servo1.attach (0);//rotate
  servo2.attach (2);//linear
  servo1.write(90);//mid rotator position to set baseline
  servo2.write(60);//mid slider position to set baseline
  randomSeed(analogRead(20));//some pin not used
  delay(5000); //place your mouse down on wheel
}

void loop() {

  //random servo position rotating
  randomNumber = random(30, 150); //random travel (servo min, servo max)
  int pos = randomNumber;

  if (lastPosServo1 < 90) {
    for (int i = lastPosServo1; i < (pos ); i++) {
      servo1.write(i);
      if (pos  > 150) {
        pos  = 150;
      }
      if (pos < 30) {
        pos = 30;
      }
      delay(DELAYTIME);
    }
  }
 
  else if (lastPosServo1 > 90) {
    for (int i = lastPosServo1; i > (pos ); i--) {
      servo1.write(i);
      if (pos  > 150) {
        pos  = 150;
      }
      if (pos < 30) {
        pos = 30;
      }
      delay(DELAYTIME);
    }
  }
  lastPosServo1 = pos  ;

  if (pos <= 90) { //midpoint
    digitalWrite(LED, LOW);
  }
  if (pos >= 91) {
    digitalWrite(LED, HIGH);
  }


 
  //random servo position linear midpoint=60
  randomNumber = random(10, 120); //random travel (servo min, servo max)
  pos  = randomNumber;

  if (lastPosServo2 < 65) {
    for (int i = lastPosServo2; i < (pos ); i++) {
      servo2.write(i);
      if (pos  > 120) {
        pos  = 120;
      }
      if (pos < 10) {
        pos = 10;
      }
      delay(DELAYTIME);
    }
  }
 
  else if (lastPosServo2 > 65) {
    for (int i = lastPosServo2; i > (pos ); i--) {
      servo2.write(i);
      if (pos  > 120) {
        pos  = 120;
      }
      if (pos < 10) {
        pos = 10;
      }
      delay(DELAYTIME);
    }
  }
  lastPosServo2 = pos  ;


  if (pos <= 65) {  //midpoint
    digitalWrite(LED1, LOW);
  }
  if (pos >= 66) {
    digitalWrite(LED1, HIGH);
  }

  //random time delay
  randomNumber1 = random(1000, 5000);//delay in millisecs
  delay(randomNumber1);
}

XRAD
 
Posts: 560
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S MOUSY WHEEL

by XRAD on Tue Jun 04, 2019 7:03 pm

I tried a few variants of the above code in this sketch. Only issues is when the servo 'limits' are exceeded (such as current pos + new pos > 150 ) then I get a bit of a jump. I need a way to set limits to new pos + current pos without getting a jump.... All three variants of servo positioning in the code produce relatively the same result, so I know that I need a new approach.

Works great on trinket M0. Note that the servo pins are a bit different as tested on my teesy board...

Code: Select all | TOGGLE FULL SIZE
/***************************************************
     ==========XRAD'S MousyWheel V2===========
  Tired of that log-off screen?? Can't load that move
  mouse program?  Build one of these! Random seed for
  motion and time delay, makes for a really 'almost
  completly random' event!! Do I smell a two hour lunch?

  This is the new SLOW servo sersion without using a
  servo 'timer.' It is blocking, but good for slow props!
  Work in progress......
  The servos have to actuate once to determine a
  lastPosServo, then they will operate slowly 99% of time
***************************************************/

#include <Servo.h>

#define LED 3  //PWM  for 'rotating' led
#define LED1 4  //PWM  for 'linear' led

int lastPosServo1; //save last servo position for next time
int lastPosServo2; //save last servo position for next time

#define DELAYTIME 15

//declare servo object
Servo servo1;//rotate
Servo servo2;//linear

//some storage for random #'s
long randomNumber1; //for servos
long randomNumber2; //for servos
long randomNumber; //for time

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(LED1, OUTPUT);
  digitalWrite(LED, HIGH);
  digitalWrite(LED1, HIGH);
  delay(50);
  servo1.attach (5);//rotate
  servo2.attach (6);//linear
  servo1.write(90);//mid rotator position to set baseline
  servo2.write(60);//mid slider position to set baseline
  randomSeed(analogRead(20));//some pin not used
  delay(5000); //place your mouse down on wheel

  //lastPosServo1 = random(30, 150); //random travel (servo min, servo max)
  // lastPosServo2 = random(30, 150); //random travel (servo min, servo max)
}

void loop() {

  //random servo position rotating
  randomNumber1 = random(30, 150); //random travel (servo min, servo max)

  int posA = randomNumber1;

  if (lastPosServo1 < 90) {
    for (int i = lastPosServo1; i < (posA ); i++) {
      if (i < 150) {
        servo1.write(i);
        delay(DELAYTIME);
      }
    }
  }
  else if (lastPosServo1 > 90) {
    for (int i = lastPosServo1; i > (posA ); i--) {
      if ( i > 30) {
        servo1.write(i);
        delay(DELAYTIME);
      }
    }
  }
 
  lastPosServo1 = posA  ;

  if (posA <= 90) { //midpoint
    digitalWrite(LED, LOW);
  }
  if (posA >= 91) {
    digitalWrite(LED, HIGH);
  }



  //random servo position linear midpoint=60
  randomNumber2 = random(30, 150); //random travel (servo min, servo max)

  int posB  = randomNumber2;

  if (lastPosServo2 < 90) {
    for (int i = lastPosServo2; i < (posB ); i++) {
      servo2.write(i);
      delay(DELAYTIME);
    }
  }
  else if (lastPosServo2 > 90) {
    for (int i = lastPosServo2; i > (posB ); i--) {
      servo2.write(i);
      delay(DELAYTIME);
    }
  }
  lastPosServo2 = posB  ;

  if (posB <= 90) {  //midpoint
    digitalWrite(LED1, LOW);
  }
  if (posB >= 91) {
    digitalWrite(LED1, HIGH);
  }

  //random time delay
  randomNumber  = random(1000, 2000);//delay in millisecs
  //delay(randomNumber );
}

XRAD
 
Posts: 560
Joined: Sat Nov 19, 2016 3:28 pm

Please be positive and constructive with your questions and comments.