Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // A joystick with calibration function and/or some added buttons.
- // Using RC joystick gimbal (dual pot type) and Arduino Pro Micro(32u4)
- // User holds calibrate button for 2s to enter calmode. Stick is moved to extremes then cal button pressed again to exit and save.
- // Makes use of ArduinoJoystickLibrary by MHeironimus
- // https://github.com/MHeironimus/ArduinoJoystickLibrary
- // JC_Button library by Jack Christensen
- // https://github.com/JChristensen/JC_Button
- // and the default EEPROM library from Arduino
- // By: Daniel Spargo for Technology for Ageing and Disability QLD (TADQ)
- #include "Arduino.h"
- #include "Joystick.h"
- #include "EEPROM.h"
- #include "JC_Button.h"
- #include "FadeLed.h"
- #define xAxis A0
- #define yAxis A2
- #define UpButton 15
- #define DownButton 14
- #define LeftButton 16
- #define RightButton 10
- #define CalButton 9
- #define LEDpin 3
- #define RangeScaleFactor 0.85
- #define debounce 10
- //EEPROM addresses to be used
- int XcentaddH = 0, XcentaddL = 1;
- int YcentaddH = 2, YcentaddL = 3;
- int XrangeAdjaddH = 4, XrangeAdjaddL = 5;
- int YrangeAdjaddH = 6, YrangeAdjaddL = 7;
- //Various stick position vals
- int16_t xVal = 0,yVal = 0;
- int16_t xValAdj = 0,yValAdj = 0;
- int16_t Ycenter = 0,Xcenter = 0;
- int16_t Ymax = 0,Ymin = 0;
- int16_t Xmax = 0,Xmin = 0;
- int16_t YmaxAdj = 0, XmaxAdj = 0;
- int16_t Xrange = 0, Yrange = 0;
- int16_t XrangeAdj = 0, YrangeAdj = 0;
- //Flag for indicating status of calibration mode
- bool calmode = 0;
- // Create Joystick
- // Joystick(hidReportID,joystickType,buttonCount,hatSwitchCount,rest are axes enable-X_Y_Z_RX_RY_RZ)
- Joystick_ Joystick(0x04, JOYSTICK_TYPE_JOYSTICK, 4, 0,true,true,false,false,false,false,false,false,false,false,false);
- //Create Button Debouncer and Reader
- Button UpBtn(UpButton,debounce,true,true);
- Button DownBtn(DownButton,debounce,true,true);
- Button LeftBtn(LeftButton,debounce,true,true);
- Button RightBtn(RightButton,debounce,true,true);
- Button CalBtn(CalButton,debounce,true,true);
- //Create FadeLed
- FadeLed BreatheLED(LEDpin);
- void setup() {
- Joystick.begin();
- //Joystick.setYAxisRange(0,1023);
- //Joystick.setXAxisRange(0,1023);
- //Set params for LED
- BreatheLED.setTime(3000, true);
- BreatheLED.set(127);
- //INPUTS
- //Analog inputs from stick pots
- pinMode(xAxis, INPUT);
- pinMode(yAxis, INPUT);
- //Button inputs, set internal pullups
- UpBtn.begin();
- DownBtn.begin();
- LeftBtn.begin();
- RightBtn.begin();
- CalBtn.begin();
- //Get values from EEPROM and calculate max vals
- //Get high byte shift it left then append low byte
- Xcenter = EEPROM.read(XcentaddH);
- Xcenter = Xcenter<<8;
- Xcenter |= EEPROM.read(XcentaddL);
- Ycenter = EEPROM.read(YcentaddH);
- Ycenter = Ycenter<<8;
- Ycenter |= EEPROM.read(YcentaddL);
- XrangeAdj = EEPROM.read(XrangeAdjaddH);
- XrangeAdj = XrangeAdj<<8;
- XrangeAdj |= EEPROM.read(XrangeAdjaddL);
- YrangeAdj = EEPROM.read(YrangeAdjaddH);
- YrangeAdj = YrangeAdj<<8;
- YrangeAdj |= EEPROM.read(YrangeAdjaddL);
- //Max Value for axis is center + adjusted range
- XmaxAdj = Xcenter+XrangeAdj;
- YmaxAdj = Ycenter+YrangeAdj;
- }
- void loop() {
- //Read analog inputs
- xVal = analogRead(xAxis);
- yVal = analogRead(yAxis);
- //Read button inputs and set button or LED outputs
- Joystick.setButton(0,UpBtn.read());
- Joystick.setButton(1,DownBtn.read());
- Joystick.setButton(2,LeftBtn.read());
- Joystick.setButton(3,RightBtn.read());
- CalBtn.read();
- FadeLed::update();
- //Calibration button held for 2s? Enter calmode. Grab center vals.
- if(CalBtn.pressedFor(2000)&&(!calmode)){
- calmode = 1;
- Ycenter = yVal;
- Xcenter = xVal;
- BreatheLED.off();
- }
- //constantly update max/min axis vals while in calmode
- if(calmode){
- if(xVal>Xmax)Xmax=xVal;
- if(yVal>Ymax)Ymax=yVal;
- if(xVal<Xmin)Xmin=xVal;
- if(yVal<Ymin)Ymin=yVal;
- if(BreatheLED.done()){
- if(BreatheLED.get()){
- BreatheLED.off();
- }
- else{
- BreatheLED.on();
- }
- }
- }
- //If we are in calmode and a rising edge is detected from CalBtn then exit calmode and update EEPROM.
- if(CalBtn.wasPressed()&&calmode){
- calmode = false;
- if((Xmax-Xcenter)>=(Xcenter-Xmin)){ //Find X smallrange
- Xrange = Xcenter-Xmin;
- }
- if((Xmax-Xcenter)<=(Xcenter-Xmin)){
- Xrange = Xmax-Xcenter;
- }
- if((Ymax-Ycenter)>=(Ycenter-Ymin)){ //Find Y smallrange
- Yrange = Ycenter-Ymin;
- }
- if((Ymax-Ycenter)<=(Ycenter-Ymin)){
- Yrange = Ymax-Ycenter;
- }
- //Adjust smallranges by a bit
- XrangeAdj = round(Xrange*RangeScaleFactor);
- YrangeAdj = round(Yrange*RangeScaleFactor);
- //Use adjusted smallranges to calculate adjusted max vals
- XmaxAdj = Xcenter+XrangeAdj;
- YmaxAdj = Ycenter+YrangeAdj;
- //Store center and adjusted range values to EEPROM
- EEPROM.write(XcentaddH,Xcenter>>8);
- EEPROM.write(XcentaddL,Xcenter);
- EEPROM.write(YcentaddH,Ycenter>>8);
- EEPROM.write(YcentaddL,Ycenter);
- EEPROM.write(XrangeAdjaddH,XrangeAdj>>8);
- EEPROM.write(XrangeAdjaddL,XrangeAdj);
- EEPROM.write(YrangeAdjaddH,YrangeAdj>>8);
- EEPROM.write(YrangeAdjaddL,YrangeAdj);
- BreatheLED.stop();
- BreatheLED.set(50);
- }
- //Not in calmode? be a Joystick. Do Joystick things.
- if(!calmode){
- xVal = constrain(xVal, 0, 1023);
- yVal = constrain(yVal, 0, 1023);
- // Just ensuring center and max values that we send are in the expected range. Can swap 1023 and 0 to flip axes orientation.
- xValAdj = map(xVal,Xcenter,XmaxAdj, 511, 0);
- yValAdj = map(yVal,Ycenter,YmaxAdj, 511, 1023);
- //Send current stick positions
- Joystick.setXAxis(xValAdj);
- Joystick.setYAxis(yValAdj);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement