ISO help with a gear shift indicator.

Hi all, I have already browsed the forums and unfortunately I couldn't find a way to use any other code for help. I am very new to this, and this is my first project. What I am attempting to do is use a 3 way joystick as a gear shifter. I am using the 3 way joystick and an Adafruit 1.44" 128x128 TFT display to show the gears. I am currently trying to use the Y-axis value over 950 to show an up-shift and one under 150 to show a downshift (not coded yet as I don't know how). I can display the first gear, as seen below, but I don't know how to "stack" or add onto it so that it does not just override the first one. Here is the code:

// Arduino pin numbers
const int SW_pin = 3; // input for detecting whether the joystick/button is pressed
const int X_pin = A0; // analog pin connected to X output
const int Y_pin = A1; // analog pin connected to Y output
int val0 = 0; //variable to store the value read of a0
int val1 = 0; //variable to store the value read of a1

#include <Adafruit_GFX.h>         // Core graphics library
#include <Adafruit_ST7735.h>      // Hardware-specific library
#include <SdFat.h>                // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h>    // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
#define USE_SD_CARD
#define SD_CS    4 // SD card select pin
#define TFT_CS  10 // TFT select pin
#define TFT_DC   8 // TFT display/command pin
#define TFT_RST  9 // Or set to -1 and connect to Arduino RESET pin
#if defined(USE_SD_CARD)
  SdFat                SD;         // SD card filesystem
  Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
#else
  // SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
  #if defined(__SAMD51__) || defined(NRF52840_XXAA)
    Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
      PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
  #else
    #if (SPI_INTERFACES_COUNT == 1)
      Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
    #else
      Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
    #endif
  #endif
  Adafruit_SPIFlash    flash(&flashTransport);
  FatFileSystem        filesys;
  Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif

Adafruit_ST7735      tft    = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Image       img;        // An image loaded into RAM
int32_t              width  = 0, // BMP image dimensions
                     height = 0;



void setup() {
  pinMode(SW_pin, INPUT);      //setup SW input
  digitalWrite(SW_pin, HIGH);  //reading button state:1=not pressed,0=pressed
  Serial.begin(9600);          //Seput serical connection for print out to console
  #if !defined(ESP32)
  while(!Serial);       // Wait for Serial Monitor before continuing
#endif

  tft.initR(INITR_144GREENTAB); // Initialize screen

  // The Adafruit_ImageReader constructor call (above, before setup())
  // accepts an uninitialized SdFat or FatFileSystem object. This MUST
  // BE INITIALIZED before using any of the image reader functions!
  Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
  // SD card is pretty straightforward, a single call...
  if(!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
    Serial.println(F("SD begin() failed"));
    for(;;); // Fatal error, do not continue
  }
#else
  // SPI or QSPI flash requires two steps, one to access the bare flash
  // memory itself, then the second to access the filesystem within...
  if(!flash.begin()) {
    Serial.println(F("flash begin() failed"));
    for(;;);
  }
  if(!filesys.begin(&flash)) {
    Serial.println(F("filesys begin() failed"));
    for(;;);
  }
#endif
  Serial.println(F("OK!"));
 tft.fillScreen(ST7735_BLACK);
 ImageReturnCode stat; // Status from image-reading functions

}
     //print out values
void loop() {
  Serial.print("Switch:  ");
  Serial.print(digitalRead(SW_pin));
  Serial.print("\n");
  Serial.print("X-axis: ");
  Serial.print(analogRead(X_pin));
  Serial.print("\n");
  Serial.print("Y-axis: ");
  Serial.println(analogRead(Y_pin));
  Serial.print("\n\n");
  delay(2000);
  
ImageReturnCode stat; // Status from image-reading functions

 val0 = analogRead(X_pin);    // read the input a0 pin
  val1 = analogRead(Y_pin);    // read the input a1 pin


if (val1 > 1000)
{
Serial.print(F("Loading 1stgear.bmp to screen..."));
  stat = reader.drawBMP("/1stgear.bmp", tft, 0, 0);
  reader.printStatus(stat);   // How'd we do?
}
if (val1>900)
{
Serial.print(F("Loading 2ndgear.bmp to screen...."));
  stat = reader.drawBMP("/2ndgear.bmp", tft, 0, 0); 
   reader.printStatus(stat); //how'd we do??

  }    

}

Thanks in advance!

Seems like a tremendously ambitious first project. I would sugest you work through some/all of the TFT examples that come with the library to understand how they work.

I would then spend a good amount of time understanding the 3-axis joystick and make sure you know how that is working, just using Serial.print() statements without the TFT. After you get a good understanding, start building your project by combine the code as simply as possible and, once it is working, add to it and make it more complex.

Also, +1 karma for actually putting your code inside code tags on your first post.

I'd go even further than that. Ditch the tft for now. They are complicated for beginners and eat RAM like chocolate truffles. See if you can print on the serial monitor what gear your in when it shifts.

-jim lee

One thing I learned playing with this stuff is to work in parts as both previous posts say. I sometimes make a project folder and end up with loads of small sketches testing just "this" or "that" before I bolt them together.

The only danger though, is that it's a temptation to code small sketches with loads of delay()s in them, since that probably doesn't matter too much in an individual test sketch. But then when you come to integrate, those delay()s stomp on each other.

So right from the start, if there's any timing to do (and I'll wager 99% of Arduino sketches have some) do it delay()-lessly with millis()-type thinking.

Thanks for all of your input guys, I will use your recommendations as far as not using the TFT at this moment. I still do not understand how to recognize how many times that the joystick has been pulled in a certain direction. Any help with this would be much appreciated.

slowmo46:
Thanks for all of your input guys, I will use your recommendations as far as not using the TFT at this moment. I still do not understand how to recognize how many times that the joystick has been pulled in a certain direction. Any help with this would be much appreciated.

What is your definition of "pulled in a certain direction"? Does it mean, for example, the X axis reading is above 950 and then not? Or simply just above 950?

You will need to remember the previous reading much like the StateChangeDetection example (File->Examples->02.Digital->StateChangeDetection) but with your analog value. Your "upshift" will happen when the joystick transitions to above 950, not whether or not is is currently above 950.

Apply the same logic for the downshift (<150) portion.

blh64:
What is your definition of "pulled in a certain direction"? Does it mean, for example, the X axis reading is above 950 and then not? Or simply just above 950?

Yes, I mean whenever it is above 950, and then it is not.

I am currently looking at the example you provided, It's just a lot to take in.

In the variables there is "int buttonPushCounter = 0; // counter for the number of button presses" Can I make change this into a "int joystickPushCounter = 0"?

Thanks

slowmo46:
In the variables there is "int buttonPushCounter = 0; // counter for the number of button presses"

The counter in the state change example isn't the "mainstream" of the example, it's just a way of showing that it works. You wouldn't need that.

But your equivalents of their states high and low would be over and under your thresholds.