Close

I got it centered

A project log for The analog joystick adventure

Taking the analog joystick into the digital world

talofer99talofer99 02/25/2020 at 08:560 Comments

After many adventures I finally manged to get a proper readings from the analog. 

at first I tried to work it out using a 555 IC in monostable configuration and to read the result using the pulsein command.

My first big task was to find the right circuit, I had one major hardware limitation, and that is the 100K vcc connected potentiometer.

The second most important limitation I had was that I wanted the total of both the High and Low period to be as short and possible, yet leaving me enough scale on the High part.

After searching and few trials and errors, I ended up with this circuit.

Down there between the wires there is a 555 IC, one of the oldest most used IC till today. The setup is monostable, and the output is red by the Arduino using the pulsein command.

What you are seeing in the serial monitor is the pulsein result of both the High and Low square wave length of time in microseconds. The potentiometer, valued at 100K ohm, will control the length of the HIGH period. As you can see when I move it, the High period changes. Running from 6 to about 50, which gives more than enough scale to work with. 

After running the test with a potentiometer it was time to connect the joy stick and see if I get proper results.

Now at this stage I was getting unstable reads, mainly from the scroller on the side.

After a conversation with my friend Ofer, that pointed out that the 555 and analog are both using a voltage divider and why won’t I go back to analog. I did. I first took an 100K ohm resistor and working with voltage dividing formula to calculate the value of the variant resistor I was able to get some reasonable values. Link for this post in the description. Out of this value I could see the possibility of calculate, at some accuracy, what is the position of the x & y of the joystick. Now that worked well with the x & y, but when tested on the side scroller, I find it to get thrown out of balance at the edge of the scroller

My first guess was that unlike the x&y this one seem to have to full range of the potentiometer and its due to the none linear change in resistance.

I added another 100K ohm resistor, so the diving id done between 100K to 100K + potentiometer resistance value. It gave much better result across the board. The last step was to decide what will be the edges of all the x& y in value, I add to trim thing up a bit, 


I still have to deiced what to do with it now, I originally thought of moving some thing physically,  but in the last few days I'm thinking of maybe using esp and serve a html game out of it, using the joystick as the game controller. 

This is how the setting file in the video looks like 

#define BUT_TRIGGER 14 //1110
#define BUT_TRIG_R  11 //1011
#define BUT_TRIG_C  7  //0111
#define BUT_TRIG_L  13 //1101
#define BUT_UP      0  //0000
#define BUT_DOWN    8  //1000
#define BUT_LEFT    12 //1100
#define BUT_RIGHT   4  //0100

#define MAX_X1 190
#define MIN_X1 110

#define MAX_Y1 185 
#define MIN_Y1 105

#define MAX_Y2 184 
#define MIN_Y2 104

and this is the main code 




#include "joyStickSettings.h"

#define BUT_A1_PIN 4
#define BUT_A2_PIN 5
#define BUT_B1_PIN 6
#define BUT_B2_PIN 7

#define JOY1_X A8
#define JOY1_Y A9
#define JOY2_Y A10

int joy1_x,joy1_y,joy2_y;

// include the library header
#include <openGLCD.h>


int getAnalogPosition(byte analogChannel) {
  int analogValue = analogRead(analogChannel);
  return (102300) / analogValue - 100;
}


void setup()
{
  Serial.begin(115200);
  Serial.println("System started");
  pinMode(BUT_A1_PIN, INPUT);
  pinMode(BUT_A2_PIN, INPUT);
  pinMode(BUT_B1_PIN, INPUT);
  pinMode(BUT_B2_PIN, INPUT);

  // Initialize the GLCD
  GLCD.Init();
  // Select the font for the default text area
  GLCD.SelectFont(Callibri10);
  GLCD.print("-JOYSTICK TEST-");


}

void loop()
{
  //read buttons
  byte butState = 128;
  butState |= digitalRead(BUT_A1_PIN);
  butState |= digitalRead(BUT_A2_PIN) << 1;
  butState |= digitalRead(BUT_B1_PIN) << 2;
  butState |= digitalRead(BUT_B2_PIN) << 3;

  // read analog
  joy1_x = constrain(getAnalogPosition(JOY1_X),MIN_X1,MAX_X1);
  joy1_y = constrain(getAnalogPosition(JOY1_Y),MIN_Y1,MAX_Y1);
  joy2_y = constrain(getAnalogPosition(JOY2_Y),MIN_Y2,MAX_Y2);
  

  GLCD.CursorTo(0, 2);
  GLCD.print(butState, BIN);
  GLCD.print(" ");
  switch (butState - 128) {
    case BUT_TRIGGER:
      GLCD.print("TRIGGER");
      break;
    case BUT_TRIG_R:
      GLCD.print("R-TRIG");
      break;
    case BUT_TRIG_C:
      GLCD.print("C-TRIG");
      break;
    case BUT_TRIG_L:
      GLCD.print("L-TRIG");
      break;
    case BUT_UP:
      GLCD.print("UP");
      break;
    case BUT_DOWN:
      GLCD.print("DOWN");
      break;
    case BUT_LEFT:
      GLCD.print("LEFT");
      break;
    case BUT_RIGHT:
      GLCD.print("RIGHT");
      break;
      default :
      GLCD.print("        ");
  }


  GLCD.print("    ");
  // print X1
  GLCD.CursorTo(0, 3);
  GLCD.print("Joy1_X : ");
  GLCD.print(map(joy1_x,MIN_X1,MAX_X1,0,100));
  GLCD.print("  ");
  // print Y1
  GLCD.CursorTo(0, 4);
  GLCD.print("Joy1_Y : ");
  GLCD.print(map(joy1_y,MIN_Y1,MAX_Y1,0,100));
  GLCD.print("  ");
  
  GLCD.CursorTo(0, 5);
  GLCD.print("Joy2_Y : ");
  GLCD.print(map(joy2_y,MIN_Y2,MAX_Y2,0,100));
  GLCD.print("  ");
}

Discussions