DIY Spinner Controller

Discussion of keyboards, gamepads, joysticks and other input related peripherals.
User avatar
hellbent
Posts: 58
Joined: Tue Nov 09, 2021 9:19 pm
Has thanked: 22 times
Been thanked: 74 times
Contact:

DIY Spinner Controller

Unread post by hellbent »

here's a DIY spinner i made for arkanoid, etc. this was all code i grabbed from the web and a case from thingiverse so i can take literally no credit for any of it.

spinner outside.jpg
spinner outside.jpg (505.96 KiB) Viewed 8759 times
spinner inside.jpg
spinner inside.jpg (426.38 KiB) Viewed 8759 times

case was from thingiverse and i just mirrored it over one axis when printed so it could be held in the left hand and use my thumb on the fire button.

because the case is so small you have to get low profile arcade buttons, these were from focus attack

the rotary encoder was from amazon and was the most costly part. seems to be out of stock but i'm sure something similar is available. this one uses hall effect sensors and spins smoothly with no detentes.

spinner knob is a generic aluminum knob. i wanted bigger but settled on this one

micro controller can be any Arduino that utilizes the 32u4 processor as you NEED the native USB functionality. i used an adafruit itsy-bitsy i had already that was small enough to fit inside the case.

last was a spare USB A cable. this was an old apple iphone lightning cable that was busted. just snipped off the apple end and robert's your mothers’ brother.

code was from here. i didn't write it, just used and adapted it for my purposes. it details how to attach the encoder and buttons (i think its setup for 6 buttons if you want but obviously the case is too small for that many so i limited it down to just 2 for fire and player1/coin).

@h3llb3nt.bsky.social

User avatar
ntt
Posts: 72
Joined: Mon Feb 15, 2021 10:05 am
Has thanked: 76 times
Been thanked: 17 times

Re: DIY Spinner Controller

Unread post by ntt »

Great project, thanks for sharing!
User avatar
sonik
Posts: 91
Joined: Sun May 09, 2021 3:31 pm
Location: Brazil
Has thanked: 15 times
Been thanked: 17 times

Re: DIY Spinner Controller

Unread post by sonik »

Also check out Sorg's paddle/spinner code. It's interesting as it will work on mister as paddle and spinner.
User avatar
dennis808
Posts: 7
Joined: Thu Sep 30, 2021 9:44 am
Has thanked: 22 times
Been thanked: 1 time

Re: DIY Spinner Controller

Unread post by dennis808 »

I built exactly the same spinner, but have a really hard time getting it properly configured in different MiSTer cores/games, how much code did you change? Would you be willing to share the code?
User avatar
hellbent
Posts: 58
Joined: Tue Nov 09, 2021 9:19 pm
Has thanked: 22 times
Been thanked: 74 times
Contact:

Re: DIY Spinner Controller

Unread post by hellbent »

here is the code as i used it. it was tweaked for my button inputs.

Code: Select all

/*   Arcade Spinner v0.7
*    Copyright 2018 Joe W (jmtw000 a/t gmail.com)
*                   Craig B - Updated code for mouse movement modes(DROP, ACCM) and case statement for Button port bit validation
*    
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

#include "Mouse.h"
#include "Joystick.h"
                 
#define pinA 2   //The pins that the rotary encoder's A and B terminals are connected to.
#define pinB 3
#define maxBut 2  //The number of buttons you are using up to 10.

int lastButtonState[maxBut] = {1,1};

//The previous state of the AB pins
volatile int previousReading = 0;

//Keeps track of how much the encoder has been moved
volatile int rotPosition = 0;

volatile int rotMulti = 0;

//Create a Joystick object.
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
  maxBut, 0,             // Button Count, Hat Switch Count
  true, true, false,     // X, Y, but no Z Axis. We need at least two axes even though they're not used.
  false, false, false,   // No Rx, Ry, or Rz
  false, false,          // No rudder or throttle
  false, false, false);  // No accelerator, brake, or steering;

void setup() {
  //Serial.begin (9600);
  //pinMode(13, OUTPUT); //LED to see if mouse interrupt is working or not.
  PORTD = 0b00000011; //Digital pins D2, D3, D4, D6, and D12.
  PORTB = 0b11100000; //Digital pins D11, D10, D9 for buttons
  
  /* pin mapping for adafruit feather 32u4 to PORTX
  PORT D available HIGH 0b11001111 (pins D6, D12, X, D4, D1, D0, D2, D3)
  D6  06 PD7
  D12 12 PD6
      xx PD5
  D4  25 PD4 - SDcard no don't touch   
  D1  01 PD3 
  D0  00 PD2
  D2  02 PD1 - interrupt 1
  D3  03 PD0 - interrupt 0

  PORT B available HIGH (0b11101110) ( pins D11, D10, D9, X, D8, MISO, MOSI, SCK, X)
  D11 11 PB7
  D10 10 PB6
  D9  09 PB5
  D8  08 PB4 - LED onboard
 MISO 14 PB3
 MOSI 16 PB2
  SCK 15 PB1
      xx PB0 - not useable
  */
  
  //Set up the interrupt handler for the encoder's A and B terminals on digital pins 2 and 3 respectively. Both interrupts use the same handler.
  attachInterrupt(digitalPinToInterrupt(pinA), pinChange, CHANGE); 
  attachInterrupt(digitalPinToInterrupt(pinB), pinChange, CHANGE);

  //Start the mouse
  Mouse.begin();

  //Start the joystick
  Joystick.begin();
  
  //Center the X and Y axes on the joystick
  Joystick.setXAxis(511);
  Joystick.setYAxis(511);
}

//Interrupt handler
void pinChange() {

  //Set the currentReading variable to the current state of encoder terminals A and B which are conveniently located in bits 0 and 1 (digital pins 2 and 3) of PIND
  //This will give us a nice binary number, eg. 0b00000011, representing the current state of the two terminals.
  //You could do int currentReading = (digitalRead(pinA) << 1) | digitalRead(pinB); to get the same thing, but it would be much slower.
  int currentReading = PIND & 0b00000011;

  //Take the nice binary number we got last time there was an interrupt and shift it to the left by 2 then OR it with the current reading.
  //This will give us a nice binary number, eg. 0b00001100, representing the former and current state of the two encoder terminals.

  int combinedReading  = (previousReading << 2) | currentReading; 

  //Now that we know the previous and current state of the two terminals we can determine which direction the rotary encoder is turning.

  //Going to the right
  if(combinedReading == 0b0010 || 
     combinedReading == 0b1011 ||
     combinedReading == 0b1101 || 
     combinedReading == 0b0100) {
     rotPosition--;                   //update the position of the encoder
  }

  //Going to the left
  if(combinedReading == 0b0001 ||
     combinedReading == 0b0111 ||
     combinedReading == 0b1110 ||
     combinedReading == 0b1000) { 
     rotPosition++;                   //update the position of the encoder
  }
  //Serial.println("interrupt!");

  //Save the previous state of the A and B terminals for next time
  previousReading = currentReading;
}

void loop(){ 

  //If the encoder has moved 1 or more transitions move the mouse in the appropriate direction 
  //and update the rotPosition variable to reflect that we have moved the mouse. The mouse will move 1/2 
  //the number of pixels of the value currently in the rotPosition variable. We are using 1/2 (rotPosition>>1) because the total number 
  //of transitions(positions) on our encoder is 2400 which is way too high. 1200 positions is more than enough.
  
  if(rotPosition >= 1 || rotPosition <= -1) {
    rotMulti = rotPosition>> 1;                 //copy rotPosition/2 to a temporary variable in case there's an interrupt while we're moving the mouse 
    Mouse.move(rotMulti,0,0);
    rotPosition -= (rotMulti<< 1);              //adjust rotPosition to account for mouse movement
  }

  int currentButtonState;

  int button = 0;
  do {
    switch ( button ) {
      case 0:  //on digital pin 11, Arcade Button 0
        currentButtonState = (PINB & 0b10000000) >> 7; //logical AND the 8-bit pin reading with a mask to isolate the specific bit we're interested in and then shift it to the end of the byte
        break;
      case 1:  //on digital pin 10, Arcade Button 1
        currentButtonState = (PINB & 0b01000000) >> 6;
        break;
      default: //should never happen
        currentButtonState = 0b00000000;
        break;
      }
    //If the current state of the pin for each button is different than last time, update the joystick button state
    if(currentButtonState != lastButtonState[button])
      Joystick.setButton(button, !currentButtonState);
      
    //Save the last button state for each button for next time
    lastButtonState[button] = currentButtonState;

    ++button;
  } while (button < maxBut); 
}

@h3llb3nt.bsky.social

User avatar
aberu
Core Developer
Posts: 1192
Joined: Tue Jun 09, 2020 8:34 pm
Location: Longmont, CO
Has thanked: 247 times
Been thanked: 411 times
Contact:

Re: DIY Spinner Controller

Unread post by aberu »

I printed one of those cases out of Wood-filled PLA (https://www.amazon.com/dp/B0833X5NKB) awhile ago, but never put it all together. Good to see someone else finished one.

birdybro~
CraigB-spinner
Posts: 1
Joined: Fri Dec 24, 2021 3:22 pm

Re: DIY Spinner Controller

Unread post by CraigB-spinner »

Hellbent,

Did you look at the second name in the code list?
I spawned a github page at https://craigb-spinner.github.io/ for my Spinbox; hey no 3D printer.
Never thought about updating the code to support MiSTer FPGA as I was using a Pie and MAME.
Well the insanity arrived - in-MCU SpinSpeed adjustment without a '/' function. I didn't like the 300 to 500 clock cycles overhead.
I did it old school RISC process, yah division is really subtraction. 5-6 hours debugging a logic bug, yah forgot to do a step. One foot infront of the other, oops trip, splat...
The code should be uploaded to my github with adjustable spin rate from the device - loss of two digital pins sacrifice.
My understanding not all cores can handle the faster pulse rate.
Is that so?

Craig B

User avatar
hellbent
Posts: 58
Joined: Tue Nov 09, 2021 9:19 pm
Has thanked: 22 times
Been thanked: 74 times
Contact:

Re: DIY Spinner Controller

Unread post by hellbent »

i've only ever used it with arkanoid!

the sketch works great for me so kudos to your work on it with jmtw000

@h3llb3nt.bsky.social

Missus
Posts: 183
Joined: Fri Jan 27, 2023 12:45 am
Has thanked: 48 times
Been thanked: 43 times

Re: DIY Spinner Controller

Unread post by Missus »

i just built one too, works great.
thanks for the writeup and code folks!

MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

Hello,

I built one too, and it works very well with arkanoid.
However, I can't get it to work with some of the Jotego cores, for example puzzle loop 2 and forgotten world.
have you tried these games?

Thanks a lot

jca
Top Contributor
Posts: 1911
Joined: Wed May 27, 2020 1:59 pm
Has thanked: 145 times
Been thanked: 454 times

Re: DIY Spinner Controller

Unread post by jca »

Did you check the DIP settings?

User avatar
Alkadian
Top Contributor
Posts: 728
Joined: Thu May 28, 2020 9:55 am
Has thanked: 294 times
Been thanked: 119 times

Re: DIY Spinner Controller

Unread post by Alkadian »

MrChatouille wrote: Wed Mar 08, 2023 3:23 pm

Hello,

I built one too, and it works very well with arkanoid.
However, I can't get it to work with some of the Jotego cores, for example puzzle loop 2 and forgotten world.
have you tried these games?

Thanks a lot

See post here :mrgreen:

viewtopic.php?p=69693#p69693

MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

Hello,

I'd like to give you a little follow-up on this topic.
After much effort and trial and error, I finally got my version to work with more games (yeeeh)

I took some ideas from CraigB and merged it with Sorgelig's original code.

So far, the following games work:

  • Arkanoid (World)
  • Block Gal
  • Breakout (TTL) : enable spinner in controls
  • Crater Raider
  • Dark Planet
  • Demolition Derby
  • Discs of Tron
  • Forgotten Worlds
  • Kick
  • Kozmik Krooz'r
  • Midnight Resistance
  • Moonwar
  • Puzz Loop 2 : Enable Paddle in Service mode (System -> Operation)
  • Tron
  • Two Tigers (tron conversion)

And others with a bit of fiddling:

  • Block block (world) : use alternatives/block block (world 910910), must use Mouse Emulation
  • Super Breakout : Enable paddle in controls, must use paddle emulation
yuq1QpA.jpeg
yuq1QpA.jpeg (459.06 KiB) Viewed 2248 times

I plan to deliver the 3D files and the Arduino source code under an opensource license after cleaning up the code that needs it

MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

Hello Everyone,

As promised before, I cleaned up the code and published it on github, under opensource license.

I would be delighted and honored to see your various constructions if you would like to make one for yourself.

I am aware that the documentation is not yet perfect, do not hesitate to ask me your questions, I will try to answer them as well as possible.

Oh, and I forgot, here is the link to the repository : https://github.com/willoucom/Arduino_ArcadeSpinner

Have a great time building!

MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

Hello everyone,

I made a video demonstration of the product.

Have a nice day

DeKay
Posts: 34
Joined: Sun Apr 02, 2023 10:11 pm
Has thanked: 16 times
Been thanked: 25 times

Re: DIY Spinner Controller

Unread post by DeKay »

MrChatouille wrote: Tue Mar 21, 2023 1:51 pm

I'd like to give you a little follow-up on this topic.
After much effort and trial and error, I finally got my version to work with more games (yeeeh)

This looks very nice. I am wondering about the "feel" of this solution. One of the popular spinners out there has an additional weight to add inertia to the encoder. Another (if I remember correctly) uses a piece of felt to introduce some drag. Is there a spinner out there that you could compare yours to, or can you describe its feel?

Also, would this work in Mame as well?

MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

It will be difficult for me to describe the feel of the spinner but I will try to do my best.

There is no friction with the encoder since it uses a magnet to detect the rotation, with a simple flick it is easy to make it do several turns.

As far as I know, there was no weight on the original Arkanoid spinner but a mechanism using plastic gears, and I guess if the gears were not sufficiently greased, that it added a little "weight" to the rotation.
With a lot of modification, it may be possible to add a little friction and resistance, but I wouldn't know if that's a good or bad thing to do.
Another option would be to use a heavier knob, the one I'm using is plastic, but probably something in aluminum or steel would be better because it's heavier.

So far, not many people have tested the controller, but most of them found the feel excellent but a bit too sensitive (I added an option to change the sensitivity last week based on this feedback).

Swainy
Posts: 161
Joined: Sat May 22, 2021 9:07 am
Has thanked: 104 times
Been thanked: 17 times

Re: DIY Spinner Controller

Unread post by Swainy »

Here is the ultimate cost saving diy spinner:

Full credit must go to Andrew Major, checkout his GitHub page: https://github.com/dekkit/Strap-On-Mouse-Spinner

MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

I appreciate the commitment and ingenuity of such DIY

User avatar
Armakuni
Posts: 208
Joined: Fri Jan 13, 2023 10:37 am
Has thanked: 38 times
Been thanked: 33 times

Re: DIY Spinner Controller

Unread post by Armakuni »

MrChatouille wrote: Wed Apr 05, 2023 3:44 pm

It will be difficult for me to describe the feel of the spinner but I will try to do my best.

There is no friction with the encoder since it uses a magnet to detect the rotation, with a simple flick it is easy to make it do several turns.

As far as I know, there was no weight on the original Arkanoid spinner but a mechanism using plastic gears, and I guess if the gears were not sufficiently greased, that it added a little "weight" to the rotation.
With a lot of modification, it may be possible to add a little friction and resistance, but I wouldn't know if that's a good or bad thing to do.
Another option would be to use a heavier knob, the one I'm using is plastic, but probably something in aluminum or steel would be better because it's heavier.

So far, not many people have tested the controller, but most of them found the feel excellent but a bit too sensitive (I added an option to change the sensitivity last week based on this feedback).

I must thank you for this great project, i love the small footprint and the multiple modes

We just need someone to run a few off for users as spinners especially affordable ones are very thin on the ground for MiSTer.

Though I like the milk bottle top project too

capitaineflam25
Posts: 36
Joined: Mon Oct 10, 2022 6:56 pm
Has thanked: 34 times
Been thanked: 6 times

Re: DIY Spinner Controller

Unread post by capitaineflam25 »

MrChatouille wrote: Sat Mar 25, 2023 12:19 pm

Hello Everyone,

As promised before, I cleaned up the code and published it on github, under opensource license.

I would be delighted and honored to see your various constructions if you would like to make one for yourself.

I am aware that the documentation is not yet perfect, do not hesitate to ask me your questions, I will try to answer them as well as possible.

Oh, and I forgot, here is the link to the repository : https://github.com/willoucom/Arduino_ArcadeSpinner

Have a great time building!

Thanks a lot for sharing the code with us, i'll try to use it on my 3 buttons spinner.

capitaineflam25
Posts: 36
Joined: Mon Oct 10, 2022 6:56 pm
Has thanked: 34 times
Been thanked: 6 times

Re: DIY Spinner Controller

Unread post by capitaineflam25 »

I'm using MrChatouille code and it is working OK when in mr.Spinner mode.
I can also see that the mouse mode is OK (testing with Utility/Gamepad Input Test)

But unfortunately, in "Normal mode" or in "Paddle Emulation" mode, i have no input detection in MisterFPGA (if i plug it to a Windows computer, i can see the buttons and the changes on the paddle when testing with joy.cpl)

Any idea of what i am doing wrong ?

Attachments
spinner_issue_on_misterfpga.png
spinner_issue_on_misterfpga.png (19.1 KiB) Viewed 6350 times
MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

Unfortunately joy.cpl doesn't help much with this kind of devices.
I suggest you enable debug mode in the source code and then open the serial monitor to see if the buttons and spinner do anything

capitaineflam25
Posts: 36
Joined: Mon Oct 10, 2022 6:56 pm
Has thanked: 34 times
Been thanked: 6 times

Re: DIY Spinner Controller

Unread post by capitaineflam25 »

Thanks for your answer
joy.cpl was a first way to verify that everything works in default and paddle mode, and it is moving as expected (on a Windows computer :D )

But when plugged to mister in one of those 2 modes, i don't have any button or spinner input.

Do you confirm that i don't need any special configuration in mister.ini ?
Do you confirm that i should see something in any of the 4 modes in Mister Input Tester ? (The picture illustrate it when started in mouse mode)

Attachments
IMG_20230430_211844.jpg
IMG_20230430_211844.jpg (2.13 MiB) Viewed 6336 times
MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

In default mode you should have A B Select Start and the Spinner

mrspinner.png
mrspinner.png (181.05 KiB) Viewed 6329 times

Nothing to add to mister.ini but you must add the device in mister (system settings then Define joystick buttons)

capitaineflam25
Posts: 36
Joined: Mon Oct 10, 2022 6:56 pm
Has thanked: 34 times
Been thanked: 6 times

Re: DIY Spinner Controller

Unread post by capitaineflam25 »

Thanks a lot, it works after doing the joystick mapping in the main screen ! :D

I didn't do the mapping because it was asking first for the "Right" button and i didn't know what to do with the spinner...

I finally pressed any button to select the spinner, then press F12 to clear the assignement and then press SPACE for any irrelevant button.
Was it the simplest way to do the mapping ?

capitaineflam25
Posts: 36
Joined: Mon Oct 10, 2022 6:56 pm
Has thanked: 34 times
Been thanked: 6 times

Re: DIY Spinner Controller

Unread post by capitaineflam25 »

By the way, you can add Pong to your working list (using Paddle emulation)

A long time ago i was able to play Pop'n Bounce NeoGeo with a mouse, by setting paddle control with the dipswitch, but my first test with my spinner was a fail.
Anyone manage to get it to work?

MrChatouille
Posts: 18
Joined: Thu Jan 06, 2022 9:38 am
Location: France
Has thanked: 1 time
Been thanked: 11 times
Contact:

Re: DIY Spinner Controller

Unread post by MrChatouille »

For pop'n bounce, enter the dips settings, then soft dips, then pop'n bounce and enable paddle.
You can then play using the default spinner mode.

capitaineflam25
Posts: 36
Joined: Mon Oct 10, 2022 6:56 pm
Has thanked: 34 times
Been thanked: 6 times

Re: DIY Spinner Controller

Unread post by capitaineflam25 »

Works perfectly 👌

metalfacemark
Posts: 179
Joined: Mon Jan 04, 2021 12:04 pm
Has thanked: 22 times
Been thanked: 15 times

Re: DIY Spinner Controller

Unread post by metalfacemark »

hellbent wrote: Sun Nov 06, 2022 6:26 pm

here is the code as i used it. it was tweaked for my button inputs.

Code: Select all

/*   Arcade Spinner v0.7
*    Copyright 2018 Joe W (jmtw000 a/t gmail.com)
*                   Craig B - Updated code for mouse movement modes(DROP, ACCM) and case statement for Button port bit validation
*    
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

#include "Mouse.h"
#include "Joystick.h"
                 
#define pinA 2 //The pins that the rotary encoder's A and B terminals are connected to. #define pinB 3 #define maxBut 2 //The number of buttons you are using up to 10. int lastButtonState[maxBut] = {1,1}; //The previous state of the AB pins volatile int previousReading = 0; //Keeps track of how much the encoder has been moved volatile int rotPosition = 0; volatile int rotMulti = 0; //Create a Joystick object. Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD, maxBut, 0, // Button Count, Hat Switch Count true, true, false, // X, Y, but no Z Axis. We need at least two axes even though they're not used. false, false, false, // No Rx, Ry, or Rz false, false, // No rudder or throttle false, false, false); // No accelerator, brake, or steering; void setup() { //Serial.begin (9600); //pinMode(13, OUTPUT); //LED to see if mouse interrupt is working or not. PORTD = 0b00000011; //Digital pins D2, D3, D4, D6, and D12. PORTB = 0b11100000; //Digital pins D11, D10, D9 for buttons
/* pin mapping for adafruit feather 32u4 to PORTX PORT D available HIGH 0b11001111 (pins D6, D12, X, D4, D1, D0, D2, D3) D6 06 PD7 D12 12 PD6 xx PD5 D4 25 PD4 - SDcard no don't touch
D1 01 PD3 D0 00 PD2 D2 02 PD1 - interrupt 1 D3 03 PD0 - interrupt 0 PORT B available HIGH (0b11101110) ( pins D11, D10, D9, X, D8, MISO, MOSI, SCK, X) D11 11 PB7 D10 10 PB6 D9 09 PB5 D8 08 PB4 - LED onboard MISO 14 PB3 MOSI 16 PB2 SCK 15 PB1 xx PB0 - not useable */
//Set up the interrupt handler for the encoder's A and B terminals on digital pins 2 and 3 respectively. Both interrupts use the same handler. attachInterrupt(digitalPinToInterrupt(pinA), pinChange, CHANGE); attachInterrupt(digitalPinToInterrupt(pinB), pinChange, CHANGE); //Start the mouse Mouse.begin(); //Start the joystick Joystick.begin();
//Center the X and Y axes on the joystick Joystick.setXAxis(511); Joystick.setYAxis(511); } //Interrupt handler void pinChange() { //Set the currentReading variable to the current state of encoder terminals A and B which are conveniently located in bits 0 and 1 (digital pins 2 and 3) of PIND //This will give us a nice binary number, eg. 0b00000011, representing the current state of the two terminals. //You could do int currentReading = (digitalRead(pinA) << 1) | digitalRead(pinB); to get the same thing, but it would be much slower. int currentReading = PIND & 0b00000011; //Take the nice binary number we got last time there was an interrupt and shift it to the left by 2 then OR it with the current reading. //This will give us a nice binary number, eg. 0b00001100, representing the former and current state of the two encoder terminals. int combinedReading = (previousReading << 2) | currentReading; //Now that we know the previous and current state of the two terminals we can determine which direction the rotary encoder is turning. //Going to the right if(combinedReading == 0b0010 || combinedReading == 0b1011 || combinedReading == 0b1101 || combinedReading == 0b0100) { rotPosition--; //update the position of the encoder } //Going to the left if(combinedReading == 0b0001 || combinedReading == 0b0111 || combinedReading == 0b1110 || combinedReading == 0b1000) { rotPosition++; //update the position of the encoder } //Serial.println("interrupt!"); //Save the previous state of the A and B terminals for next time previousReading = currentReading; } void loop(){ //If the encoder has moved 1 or more transitions move the mouse in the appropriate direction //and update the rotPosition variable to reflect that we have moved the mouse. The mouse will move 1/2 //the number of pixels of the value currently in the rotPosition variable. We are using 1/2 (rotPosition>>1) because the total number //of transitions(positions) on our encoder is 2400 which is way too high. 1200 positions is more than enough.
if(rotPosition >= 1 || rotPosition <= -1) { rotMulti = rotPosition>> 1; //copy rotPosition/2 to a temporary variable in case there's an interrupt while we're moving the mouse Mouse.move(rotMulti,0,0); rotPosition -= (rotMulti<< 1); //adjust rotPosition to account for mouse movement } int currentButtonState; int button = 0; do { switch ( button ) { case 0: //on digital pin 11, Arcade Button 0 currentButtonState = (PINB & 0b10000000) >> 7; //logical AND the 8-bit pin reading with a mask to isolate the specific bit we're interested in and then shift it to the end of the byte break; case 1: //on digital pin 10, Arcade Button 1 currentButtonState = (PINB & 0b01000000) >> 6; break; default: //should never happen currentButtonState = 0b00000000; break; } //If the current state of the pin for each button is different than last time, update the joystick button state if(currentButtonState != lastButtonState[button]) Joystick.setButton(button, !currentButtonState);
//Save the last button state for each button for next time lastButtonState[button] = currentButtonState; ++button; } while (button < maxBut); }

Is this for mister.ini ? I have a spinner but i cant get it to register on the mister.

Post Reply