Displaying variable on TFT

1st Arduino project, beyond the very basic intros, and no coding experience before this endeavor, so I’m sure I’m just not searching the right things/way to figure this out.

The project - replacing gauges in my truck with Arduino+TFT display. As a starter, I’m working strictly on single fuel gauge functionality, and eventually including dual fuel gauges (2 separate fuel tanks in truck), voltage gauge, coolant temp gauge, and GPS driven speedometer. Yeah…I’m already realizing I’m in for a bit of a steep learning curve here, lol.

The setup - Genuine Arduino Mega 2560, Seeed Studio 2.8" touchscreen sheild V1.0, aftermarket universal style fuel sender. Sender is connected to Analog pin 9 through a voltage divider circuit running roughly 1.5VDC-4.95VDC, and I get appropriate numbers from the serial monitor when cycling the sender. I’m not currently utilizing the touch features of the screen, though I may in the future. RIght now it’s strictly a display device. I did find out how to modify the TFT.h file to get the display to function on the Mega board, and am writing static text to it currently.

The problem - how the heck do I get the value read from the Analog pin to display on the screen? I’ve spent the last couple of days searching the forums here and on Adafruit, as well as various other sites found on Google. I’ve spent hours looking at other’s code to try and figure this out, but not being a coder before this, I’m finding it difficult to determine which parts of the code are relevant to what I’m attempting to do, and I think I may be confusing myself/WAY overthinking it, lol. It seems like it should be a simple thing…

This is my current code. I started with the Draw Text example sketch, and modified it for my use. dTankPin is the variable I set for the driver’s side fuel tank, with dLevel being the variable set to store the reading I get from the sender. I set static text lines for Tank - D, Tank - P (driver and passenger side fuel tanks), Volts, and C/T (coolant temp), then MPH for the future GPS speedometer. The commented out lines in there are just static values I added to initially set font size to fit the screen, but that I want to replace with the dynamic values i get from reading the various sensors.

That part I’m good with, but I can’t figure out how to get a value read from the analog pins to display as numbers on the screen. I’m not looking to be spoon fed the answers, but if I could maybe get some guidance on what functions I’m missing, or what I should be searching for to figure this out?

// Draw Texts - Demonstrate drawChar and drawString
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library 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
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#include <stdint.h>
#include <TouchScreen.h> 
#include <TFT.h>

#ifdef SEEEDUINO
  #define YP A2   // must be an analog pin, use "An" notation!
  #define XM A1   // must be an analog pin, use "An" notation!
  #define YM 14   // can be a digital pin, this is A0
  #define XP 17   // can be a digital pin, this is A3 
#endif

#ifdef MEGA
  #define YP A2   // must be an analog pin, use "An" notation!
  #define XM A1   // must be an analog pin, use "An" notation!
  #define YM 54   // can be a digital pin, this is A0
  #define XP 57   // can be a digital pin, this is A3 
#endif 

int dTankPin = A9; //driver's side tank sender pin
int dLevel = 0;     //variable to store the value from sender

void setup()
{
  Serial.begin(9600);
Tft.init();  //init TFT library

  Tft.drawString("Tank-D",0,0,3,CYAN);
  //Tft.drawString("25%",150,0,3, RED);
  Tft.drawString("Tank-P",0,30,3,CYAN);
  //Tft.drawString("100%",150,30,3, GREEN);
  Tft.drawString("Volts",0,60,3, WHITE);
  //Tft.drawString("13.0",150,60,3, YELLOW);
  Tft.drawString("C/T",0,90,3, WHITE);
  //Tft.drawString("195*",150,90,3, GREEN);
  Tft.drawString("MPH",60,140,5, BLUE);
  //Tft.drawString("53",10,190,15, BLUE);
  
    
}

void loop()
{
 
 dLevel = analogRead(dTankPin);  //read the value from the sender
 Serial.println( dLevel, DEC); // print the value from sender to screen
 

}

Do you mean something like this using itoa() to convert the number to a C String so it can be printed on the screen

Personally I’m also a fan of sprintf(), but would make the overall code size a bit bigger

// Draw Texts - Demonstrate drawChar and drawString
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library 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
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#include <stdint.h>
#include <TouchScreen.h> 
#include <TFT.h>

#ifdef SEEEDUINO
  #define YP A2   // must be an analog pin, use "An" notation!
  #define XM A1   // must be an analog pin, use "An" notation!
  #define YM 14   // can be a digital pin, this is A0
  #define XP 17   // can be a digital pin, this is A3 
#endif

#ifdef MEGA
  #define YP A2   // must be an analog pin, use "An" notation!
  #define XM A1   // must be an analog pin, use "An" notation!
  #define YM 54   // can be a digital pin, this is A0
  #define XP 57   // can be a digital pin, this is A3 
#endif 

int dTankPin = A9; //driver's side tank sender pin
int dLevel = 0;     //variable to store the value from sender

void setup()
{
  Serial.begin(9600);
Tft.init();  //init TFT library

  Tft.drawString("Tank-D",0,0,3,CYAN);
  //Tft.drawString("25%",150,0,3, RED);
  Tft.drawString("Tank-P",0,30,3,CYAN);
  //Tft.drawString("100%",150,30,3, GREEN);
  Tft.drawString("Volts",0,60,3, WHITE);
  //Tft.drawString("13.0",150,60,3, YELLOW);
  Tft.drawString("C/T",0,90,3, WHITE);
  //Tft.drawString("195*",150,90,3, GREEN);
  Tft.drawString("MPH",60,140,5, BLUE);
  //Tft.drawString("53",10,190,15, BLUE);
  
    
}

void loop()
{

 dLevel = analogRead(dTankPin);  //read the value from the sender
 Serial.println( dLevel, DEC); // print the value from sender to screen


showTank();
delay(500);// wait 1/2 sec so that its not continuously updating 
}

void showTank()
{
 char str[10];
itoa(str,dLevel,10);
Tft.drawString(str,150,0,3, RED);
}

rogerClark: Do you mean something like this using itoa() to convert the number to a C String so it can be printed on the screen

Personally I'm also a fan of sprintf(), but would make the overall code size a bit bigger

Honestly, I don't have a clue what I need, lol. I'm getting the itoa converting the value to a string that drawString can then handle, but not quite understanding how it's getting the value. I'll spend some time with the man pages for itoa and sprintf this afternoon...thanks! That is what I was looking for though - kind of a nudge in the direction I needed to go, I still enjoy the challenge of figuring out how to get there :)

Well, your code didn’t work. I forgot what the error was, but it didn’t compile…I think it was something to do with not correctly converting an integer to character. Quite by accident, I stumbled on the following code, and got it to compile, and display something on the screen, though it’s coming out as two character gibberish.

So I still have work to do, but at least I feel like I’m making progress at this point :slight_smile:

//Draft code by urbex for displaying output from various automotive
//gauges.  
//
//Latest revision 8/17/2014

#include <stdint.h>
#include <TouchScreen.h> 
#include <TFT.h>

#ifdef MEGA
  #define YP A2   // must be an analog pin, use "An" notation!
  #define XM A1   // must be an analog pin, use "An" notation!
  #define YM 54   // can be a digital pin, this is A0
  #define XP 57   // can be a digital pin, this is A3 
#endif 

int dTankPin = A9; //driver's side tank sender pin
int dLevel = 0;     //variable to store the value from sender

void setup()
{
  Serial.begin(9600);
Tft.init();  //init TFT library

  Tft.drawString("Tank-D",0,0,3,CYAN);
  //Tft.drawString("25%",150,0,3, RED);
  Tft.drawString("Tank-P",0,30,3,CYAN);
  //Tft.drawString("100%",150,30,3, GREEN);
  Tft.drawString("Volts",0,60,3, WHITE);
  //Tft.drawString("13.0",150,60,3, YELLOW);
  Tft.drawString("C/T",0,90,3, WHITE);
  //Tft.drawString("195*",150,90,3, GREEN);
  Tft.drawString("MPH",60,140,5, BLUE);
  //Tft.drawString("53",10,190,15, BLUE);
  
    
}

void loop()
{

  char str[5];
    
    str[0] = analogRead(dTankPin);
  
 Tft.drawString(str,150,0,3, RED);
delay(1000);
 Tft.drawString(str,150,0,3, BLACK);

}

Use int instead of char fro storing the value from analogRead().

Also when your using arrays and a function that is looking for a string, you need to use pointers.

Try drawChar instead of drawString, like Tft.drawChar(str[0],0,160,1,CYAN);

Ah-ha! I was attempting to use drawChar earlier, but kept getting errors on converting int to char...but I wasn't adding the [0] after str, like this - Tft.drawChar(str, 150,0,3, RED); Once I did it your way, the gibberish turned to single character letters and numbers, like it was going through a progression of a font (a,b,c,d,e, etc followed by capital letters, numbers, then symbols).

I have changed the code to the following (only changing the section within void loop ()

void loop()
{

  int flevel = analogRead(A9);
    flevel = map(flevel, 0, 1023, 0, 100);

  char str[0];
    str[0] = flevel;
    
 Tft.drawChar(str[0],150,0,3, RED);
delay(1000);
 Tft.drawString(str,150,0,3, BLACK);
  
}

I think my issue now may be within the mapping function? The behavior of the sensor seems to be working OK, just the displayed output is still wrong (I'm hoping for a readout of 0-100, to indicate fill percentage of the fuel tank).

char str[0]; basically your not making an array, it should be atleast char str[1].

Try this instead.

void loop()
{
  int flevel = map(analogRead(A9), 0, 1023, 0, 100);

  Tft.drawChar(flevel,150,0,3, RED);
  delay(1000);
  Tft.drawChar(flevel,150,0,3, BLACK);

}

Another ah-ha moment! I knew I was over complicating that analogRead mapping, I just didn't realize how to simplify it. Thanks!

Darn thing is still displaying characters instead of numbers (yeah...I know, technically a number IS a character... :P).

Here's a YouTube video of what it's doing. https://www.youtube.com/watch?v=Fm4cWBZawaE (make sure your speakers aren't cranked up...there's no audio in the video until the last bit when my ham radio picks up signal, and it's a bit loud).

It seems to be displaying ascii characters.

Test this to see if the screen shows 123, and if it does, simply replace [u]123[/u] with map(analogRead(A9), 0, 1023, 0, 100);

void loop()
{
  char str[4];
  *str = 123;
Tft.drawString(str,0,160,1,CYAN);
}

Nope., and changing the 123 to any other number changes the displayed character to whatever ASCII character is associated with that number (*str = 1 changes it to a ? mark, 124 is a pipe, etc).

I'm looking at the reference page for char, and it says a number will translate to the ASCII character, and literal characters need to be in single quotes and strings need to be double quotes. So using

*str = '123';

works, but only displays the number 3. Using double quotes gives me an error on compile - "invalid conversion from 'const char*' to 'char'

Sorry my code didn't quite work, I don't have your hardware or display library to test it on ;-)

have you tried this

void loop()
{
  char str[4]="123";
  Serial.print(str);
Tft.drawString(str,0,160,1,CYAN);
  delay(1000);

}

Like Roger, I don't have your hardware either, so I can't do any actual tests.

Your best bet would be to use sprintf().

void loop()
{
  char str[4]; // you dont need to constantly remake the array, so this line can be put before setup()
  sprintf(str, "%d", analogRead(A9)); // converts the numerical value to a string and stores it in the array.

  Tft.drawString(str,0,160,1,CYAN); // print the array.
}

No worries guys, I’m not getting upset over it :slight_smile: Well, frustrated a bit, as I’m looking at so many examples online that should work without issue, and half the time I can’t even get the stuff to compile, but I know that’s not either of your fault’s :slight_smile: I do appreciate the help, and that said, both of your latest examples worked a charm!

HazardsMind got numbers on my screen, and now I just need to go back through my prior notes and pull up the code for averaging these readings, and I’m thinking I may break it up into units of 10 for reads, instead of 1-100 with single increments. I can see the update flickers driving me bonkers eventually, lol.

I know i have those code snippets around here somewhere, and I’ll dive back into it tomorrow :slight_smile: