Help on If Statement For TFT Display

I am creating a project that allows me to see which gear I am in on my motorcycle. The below code works but the only issue is that the menu repeats through gears. I want menu to stop at Gear 1 and not go to gear 6 if I press gear down again. Vise versa on the up gear as well. Want menu to stop at Gear 6 and not cycle to Gear 1 if I press Gear up. Any help on my if statement would be appreciated

//Setup TFT Display
#define _Digole_Serial_UART_
#include <DigoleSerial.h>
DigoleSerialDisp tftDisplay(&Serial, 9600);

//Hall Effect Sensor Pin Declaration
const int gearUp = 3;
const int gearDown = 4;

int gearUpValue = 0;
int gearDownValue = 0;

int currentGear = 0;
const int gearPos = 6;
String gearArray[gearPos];

String temp;
char currentPrintOut[11];

//Hall Sensor Boolean Setup
bool upLastState = HIGH;
bool downLastState = HIGH;

void setup() {

  //Setup Hall Effect Sensors
  pinMode(gearUp, INPUT_PULLUP);   //Remove _PULLUP when final sensors are in place
  pinMode(gearDown, INPUT_PULLUP); //Remove _PULLUP when final sensors are in placedra

  gearArray[0] = "1st   Gear ";
  gearArray[1] = "2nd Gear ";
  gearArray[2] = "3rd Gear ";
  gearArray[3] = "4th Gear ";
  gearArray[4] = "5th Gear ";
  gearArray[5] = "6th Gear ";

  //TFT Setup
  tftDisplay.begin();
  tftDisplay.displayStartScreen(0);
  tftDisplay.clearScreen();
  tftDisplay.setRotation(45);
  //tftDisplay.drawBitmap256(80, 10, 150, 150, Bike);
  delay(50);
  tftDisplay.clearScreen();
  tftDisplay.setRotation(45);
  tftDisplay.setColor(223);
  tftDisplay.setPrintPos(8, 0);
  tftDisplay.print("Gear Indicator (Yamaha R6)" );
  tftDisplay.drawLine(50, 20, 280, 20);
  tftDisplay.setFont(8);
  tftDisplay.setPrintPos(0, 17);
  tftDisplay.print("Drive Safely");
  tftDisplay.setColor(239);
  tftDisplay.drawCircle(160, 120, 75, 0);
  //tftDisplay.drawFrame(85,80,150,80);

  //Setup Draw Window
  // tftDisplay.setDrawWindow(15,3,280,20);
  gearChanged();

}

void loop() {

  //Hall Sensors
  if (digitalRead(gearUp) != upLastState) {
    upLastState = !upLastState;

    if (!upLastState) {
      if (currentGear < gearPos - 1) {
        currentGear++;
      } else {
        currentGear = 0;
      }
      gearChanged();
    }
  }

  if (digitalRead(gearDown) != downLastState) {
    downLastState = !downLastState;

    if (!downLastState) {
      if (currentGear > 0) {
        currentGear--;
      } else {
        currentGear = gearPos - 1;
      }
      gearChanged();
    }
  }

  delay(50);
}

void gearChanged() {
  tftDisplay.setColor(255);
  tftDisplay.setFont(120);
  tftDisplay.setPrintPos(15, 3);

  temp = String (gearArray[currentGear]);
  temp.toCharArray(currentPrintOut, 11);
  tftDisplay.print(currentPrintOut);
}

First, welcome to the Forum and really nice to see a first-timer use code tags!

Second, it will be difficult for us to help without knowing what’s in Bike.h, since that is likely a non-standard header.

Third, if you do use a downloadable, non-standard header, it’s useful to give the URL in the source file, like:

#include <Adafruit_GFX.h>     	// https://github.com/adafruit/Adafruit-GFX-Library
#include "Bike.h"               // ??

That way someone who might not have it installed can at least find it.

Finally, you might consider changing from the String class to using C strings (note lower case ‘s’). They are generally less wasteful. You can find a short intro here.

Thanks for the message, I removed the #include Bike.h from the program. It is just the HEX data for a 256k bitmap for the startup screen. The Bike.h header has nothing to do with the main program.

Thanks

      if (currentGear < gearPos - 1) {
        currentGear++;
      } else {
        currentGear = 0;
      }

This doesn’t make sense. If you can’t shift up out of 6th gear, the transmission does NOT go into the 0th gear. It STAYS in 6th.

      if (currentGear > 0) {
        currentGear--;
      } else {
        currentGear = gearPos - 1;
      }

If you can’t shift down out of 1st gear, the transmission does NOT go into top gear. It stays in first gear.

If your code matched reality, it would probably behave more like you want it to.

Understood! The problem is if I'm in first gear then go into neutral. If I go back to 1st gear the hall sensor will register the move and display 6th gear. I need the display to remain in 1st Gear until the upGear hall sensor is sensed.

If I go back to 1st gear the hall sensor will register the move and display 6th gear.

Which hall effect sensor? The one for up-shifting or the one for down-shifting?

You need to post some kind of diagram to explain the hardware setup.

I have two hall sensors. Up shift is on pin 3 and downshift is on pin 4. The sensors are working and the sketch I posted works. The problem is with the "if" statement. Think of upshift and downshift as a push button. When you press the up button the menu screen goes 1st gear, 2nd gear, 3rd gear, 4th gear, 5th gear, 6th gear, 1st gear, 2nd gear. I want it to stop at 6th gear regardless if I keep pressing the up button. The same goes with the down button. 6th,5th,4th,3rd,2nd,1st,6th,5th. I want the menu to stop at 1st gear regardless if I keep pressing the down button.

Hope this helps explain a little better.

Untested…

    if (!upLastState) {
      if (currentGear < gearPos - 1) {
        currentGear++;
        if (currentGear > 6)              // New code
           currentGear = 6;  
      } else {
        currentGear = 0;
      }
      gearChanged();
    }
// ...more code...

    if (!downLastState) {
      if (currentGear > 0) {
        currentGear--;
        if (currentGear < 1)              // New code
           currentGear = 1;  
      } else {
        currentGear = gearPos - 1;
      }
      gearChanged();
    }

I tried the code that you summited but does not work. The menu does not change with the new code.

We have not seen your code since you changed it to C string. You need to repost the modified code.

Is there a tutorial or post on how to convert my String to a C string?

I already sent you a link. Go study that and get rid of the String class. That link is pretty clear on how to do it, and it also presents a number of the string functions you can use to manipulate a C string.

Good evening, I converted my Strings to Cstrings. How do I display the array with each press of the button? The tutorial shows how to copy, concatenate, and determine length. I’m just not sure how to display the array via the gearChanged function.

//Setup TFT Display
#define _Digole_Serial_UART_
#include <DigoleSerial.h>
DigoleSerialDisp tftDisplay(&Serial, 9600);

//Hall Effect Sensor Pin Declaration
const int gearUp = 3;
const int gearDown = 4;

int gearUpValue = 0;
int gearDownValue = 0;

int currentGear = 0;
const int gearPos = 6;

char gear1[10] = "1st  Gear";
char gear2[9] = "2nd Gear";
char gear3[9] = "3rd Gear";
char gear4[9] = "4th Gear";
char gear5[9] = "5th Gear";
char gear6[9] = "6th Gear";

int temp;
char currentPrintOut[11];

//Hall Sensor Boolean Setup
bool upLastState = HIGH;
bool downLastState = HIGH;

void setup() {

  //Setup Hall Effect Sensors
  pinMode(gearUp, INPUT_PULLUP);   //Remove _PULLUP when final sensors are in place
  pinMode(gearDown, INPUT_PULLUP); //Remove _PULLUP when final sensors are in placedra


  //TFT Setup
  tftDisplay.begin();
  tftDisplay.displayStartScreen(0);
  tftDisplay.clearScreen();
  tftDisplay.setRotation(45);
  //tftDisplay.drawBitmap256(80, 10, 150, 150, Bike);
  delay(50);
  tftDisplay.clearScreen();
  tftDisplay.setRotation(45);
  tftDisplay.setColor(223);
  tftDisplay.setPrintPos(8, 0);
  tftDisplay.print("Gear Indicator (Yamaha R6)" );
  tftDisplay.drawLine(50, 20, 280, 20);
  tftDisplay.setFont(8);
  tftDisplay.setPrintPos(0, 17);
  tftDisplay.print("Drive Safely");
  tftDisplay.setColor(239);
  tftDisplay.drawCircle(160, 120, 75, 0);
  //tftDisplay.drawFrame(85,80,150,80);

  //Setup Draw Window
  // tftDisplay.setDrawWindow(15,3,280,20);
  gearChanged();

}

void loop() {

  //Hall Sensors
  if (digitalRead(gearUp) != upLastState) {
    upLastState = !upLastState;

    if (!upLastState) {
      if (currentGear < gearPos - 1) {
        currentGear++;
      } else {
        currentGear = 0;
      }
      gearChanged();
    }
  }


  if (digitalRead(gearDown) != downLastState) {
    downLastState = !downLastState;

    if (!downLastState) {
      if (currentGear > 0) {
        currentGear--;
        if (currentGear < 1) {           // New code
          currentGear = 1;
        } else {
          currentGear = gearPos - 1;
        }
        gearChanged();
      }
    }

    delay(50);
  }
}
void gearChanged() {
  tftDisplay.setColor(255);
  tftDisplay.setFont(120);
  tftDisplay.setPrintPos(15, 3);

  //temp = char (gearArray[currentGear]);
  //temp.toCharArray(currentPrintOut, 11);
  tftDisplay.print(currentPrintOut);
}

Same as before:

tftDisplay.print("Drive Safely and put it in ");

  • tftDisplay.print(gear1);*

Ok makes sense, but how will it scroll to gear2, gear3, etc....

Either by using the logic you write, or perhaps rethinking your data and start using arrays.

EconJack, I want to thank you for your help with this project. I was able to rethink my if/else statement and get the results that I was looking for. Thanks for making me re-think my project and not giving me an easy out.

Regards,

Brian W.

As I understand it, the gears on a bike are 1, neutral, 2,3,4,5,6 . You want ‘neutral’ to be ‘gear 0’.

so:

if( /* gear up is sensed */) {
  switch(gear) {
  case 0: gear = 2; break;
  case 1: gear = 0; break;
  case 6: break;
  default: gear ++; break;
  }
}

if( /*gear down is sensed */) {
  switch(gear) {
  case 0: gear = 1; break;
  case 1: break;
  case 2: gear = 0; break;
  default: gear --; break;
  }
}

if you want to be clever about it,

if(/*gear up or gear down is sensed*/) {
  if(gear < 2) gear = 1 - gear;
  if(/*gear up*/ && gear < 6) gear++;
  if(/*gear down */ && gear > 0) gear --;
  if(gear < 2) gear = 1 - gear;
}

but I really wouldn’t recommend this second method - it’s a bit opaque. Actually - they are both a bit opaque. Either will do.