Convert float to uint8_t for LCD function

Hi to all,

I’m having lots of problems to display the data coming from my mpu6050 sensor with my LCD.
The LCD is made by waveshare and it uses the HX8347D controller.

The function provided by the manufacturer (I guess) accepts a pointer to a string in this format:

const uint8_t *pchString

while the MPU650 function returns a float value.

If I try in this way:

Tft.lcd_display_string(60, 120, (const uint8_t *)mpu6050.getAngleX(), FONT_1608, WHITE);

I get this error:

TFT_display:42:70: error: invalid cast from type 'float' to type 'const uint8_t* {aka const unsigned char*}'

   Tft.lcd_display_string(60, 120, (const uint8_t *)mpu6050.getAngleX(), FONT_1608, WHITE);

This is my whole code:

#include <stdint.h>
#include <LCD.h>
#include <SPI.h>

#include <MPU6050_tockn.h>
#include <Wire.h>

MPU6050 mpu6050(Wire);

#define __AVR_ATmega32U4__

void setup()
{  
     Serial.begin(9600);
     Wire.begin();
     mpu6050.begin();
     mpu6050.calcGyroOffsets(true);
    SPI.setDataMode(SPI_MODE3);
    SPI.setBitOrder(MSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV4);
    SPI.begin();
    
    Tft.lcd_init();                                      // init TFT library
    Tft.lcd_display_string(60, 120, (const uint8_t *)"Calibrating the Sensor", FONT_1608, WHITE);
   }

void loop()
{
   


  Tft.lcd_clear_screen(BLUE);

  mpu6050.update();
  Serial.print("angleX : ");
  Serial.print(mpu6050.getAngleX());
  Serial.print("\tangleY : ");
  Serial.print(mpu6050.getAngleY());
  Serial.print("\tangleZ : ");
  Serial.println(mpu6050.getAngleZ());

  Tft.lcd_display_string(60, 120, (const uint8_t *)mpu6050.getAngleX(), FONT_1608, WHITE);
 
 
}

How can I correctly send the value to the lcd_display_string() function?

This should be the code used by the library where it is possible to find the lcd_display_string implementation: HX8347D.cpp

does getAngleX() return a pointer to a string (char* == uint8_t*) or a float?

maybe you should translate the value of getAngleX() to a string using sprintf() and pass the string to the lcd display routine

Use dtostrf - by default, floating point is disabled for sprintf.

getAngleX return just a float.

I tried to use dtostrf but it always displays the first value on the LCD and it never updates the values even if I can see them changing in the serial monitor.

void loop()
{
   


  Tft.lcd_clear_screen(BLUE);

  mpu6050.update();
  Serial.print("angleX : ");
  Serial.print(mpu6050.getAngleX());
  Serial.print("\tangleY : ");
  Serial.print(mpu6050.getAngleY());
  Serial.print("\tangleZ : ");
  Serial.println(mpu6050.getAngleZ());

  static float f_val = mpu6050.getAngleX();
  static char outstr[15];
  dtostrf(f_val,3, 2, outstr);
  
  Tft.lcd_display_string(60, 120, (const uint8_t *)outstr, FONT_1608, WHITE);

 delay(1000);
 
}

Moreover, the dtostrf function needs the second and the third parameter to correctly setup the decimal value, but I can receive values like 30.51 and 180.89, how should I handle them?

EDIT: if i print the value of Serial.println(outstr); I always get the same number.

Sorry, it works fine, the variable was declared as static.

It works, but is there any other smarter way to do that?

Doesn’t the display library have a function to print floats?

  char outstr[15];
  dtostrf( mpu6050.getAngleX(), 3, 2, outstr);

TheMemberFormerlyKnownAsAWOL:
Doesn’t the display library have a function to print floats?

  char outstr[15];

dtostrf( mpu6050.getAngleX(), 3, 2, outstr);

only integers:

//display a number at the specified position on lcd.
void TFT::lcd_display_num(uint16_t hwXpos,  //specify x position.
                          uint16_t hwYpos, //specify y position.
                          uint32_t chNum,  //a number is display.
                          uint8_t chLen,   //length ot the number
                          uint8_t chSize,  //specify the size of the number
                          uint16_t hwColor) //specify the color of the number
{         	
	uint8_t i;
	uint8_t chTemp, chShow = 0;

	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
		return;
	}
	
	for(i = 0; i < chLen; i ++) {
		chTemp = (chNum / _pow(10, chLen - i - 1)) % 10;
		if(chShow == 0 && i < (chLen - 1)) {
			if(chTemp == 0) {
				lcd_display_char(hwXpos + (chSize / 2) * i, hwYpos, ' ', chSize, hwColor);
				continue;
			} else {
				chShow = 1;
			}	 
		}
	 	lcd_display_char(hwXpos + (chSize / 2) * i, hwYpos, chTemp + '0', chSize, hwColor); 
	}
}

Post a GitHub link to the library.

Unfortunately, I only have the compressed file: https://www.waveshare.com/w/upload/5/5e/2.8inch_TFT_Touch_Shield_code.7z

However, this is the file that contains all the functions:

LCD.cpp

#include <LCD.h>
#include <SPI.h>

void TFT::lcd_init()
{
 __LCD_DC_OUT();
 __LCD_DC_SET();
 
 __LCD_CS_OUT();
    __LCD_CS_SET();

 __LCD_BKL_OUT();
    __LCD_BKL_OFF();

 
    lcd_clear_screen(WHITE);
 __LCD_BKL_ON();
}

//draw a point on the lcd with the specified color.
//hwXpos specify x position.
//hwYpos specify y position.
//hwColor color of the point.
void TFT::lcd_draw_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor) 
{
 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }
 
 lcd_set_cursor(hwXpos, hwYpos);
 lcd_write_byte(0x22, LCD_CMD);
    lcd_write_word(hwColor);
}

//display a char at the specified position on lcd.
void TFT::lcd_display_char(uint16_t hwXpos, //specify x position.
                         uint16_t hwYpos, //specify y position.
                         uint8_t chChr,   //a char is display.
                         uint8_t chSize,  //specify the size of the char
                         uint16_t hwColor) //specify the color of the char
{       
 uint8_t i, j, chTemp;
 uint16_t hwYpos0 = hwYpos, hwColorVal = 0;

 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }

   
    for (i = 0; i < chSize; i ++) {   
 if (FONT_1206 == chSize) {
 chTemp = pgm_read_byte(&c_chFont1206[chChr - 0x20][i]);  
 } else if (FONT_1608 == chSize) { 
 chTemp = pgm_read_byte(&c_chFont1608[chChr - 0x20][i]);
 }
 
        for (j = 0; j < 8; j ++) {
     if (chTemp & 0x80) {
 hwColorVal = hwColor;
 lcd_draw_point(hwXpos, hwYpos, hwColorVal);
     } 
 chTemp <<= 1;
 hwYpos ++;
 if ((hwYpos - hwYpos0) == chSize) {
 hwYpos = hwYpos0;
 hwXpos ++;
 break;
 }
 }   
    } 
}


//_pow
static uint32_t _pow(uint8_t m, uint8_t n)
{
 uint32_t result = 1;
 
 while(n --) result *= m;    
 return result;
}

//display a number at the specified position on lcd.
void TFT::lcd_display_num(uint16_t hwXpos,  //specify x position.
                          uint16_t hwYpos, //specify y position.
                          uint32_t chNum,  //a number is display.
                          uint8_t chLen,   //length ot the number
                          uint8_t chSize,  //specify the size of the number
                          uint16_t hwColor) //specify the color of the number
{         
 uint8_t i;
 uint8_t chTemp, chShow = 0;

 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }
 
 for(i = 0; i < chLen; i ++) {
 chTemp = (chNum / _pow(10, chLen - i - 1)) % 10;
 if(chShow == 0 && i < (chLen - 1)) {
 if(chTemp == 0) {
 lcd_display_char(hwXpos + (chSize / 2) * i, hwYpos, ' ', chSize, hwColor);
 continue;
 } else {
 chShow = 1;
 } 
 }
 lcd_display_char(hwXpos + (chSize / 2) * i, hwYpos, chTemp + '0', chSize, hwColor); 
 }
} 

//display a string at the specified position on lcd.
void TFT::lcd_display_string(uint16_t hwXpos, //specify x position.
                         uint16_t hwYpos,   //specify y position.
                         const uint8_t *pchString,  //a pointer to string
                         uint8_t chSize,    // the size of the string 
                         uint16_t hwColor)  // specify the color of the string 
{

 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }
 
    while (*pchString != '\0') {       
        if (hwXpos > (LCD_WIDTH - chSize / 2)) {
 hwXpos = 0;
 hwYpos += chSize;
 if (hwYpos > (LCD_HEIGHT - chSize)) {
 hwYpos = hwXpos = 0;
 lcd_clear_screen(0x00);
 }
 }
 
        lcd_display_char(hwXpos, hwYpos, (uint8_t)*pchString, chSize, hwColor);
        hwXpos += chSize / 2;
        pchString ++;
    } 
}

//draw a line at the specified position on lcd.
void TFT::lcd_draw_line(uint16_t hwXpos0, //specify x0 position.
                      uint16_t hwYpos0, //specify y0 position.
                      uint16_t hwXpos1, //specify x1 position.
                      uint16_t hwYpos1, //specify y1 position.
                      uint16_t hwColor) //specify the color of the line
{
 int x = hwXpos1 - hwXpos0;
    int y = hwYpos1 - hwYpos0;
    int dx = abs(x), sx = hwXpos0 < hwXpos1 ? 1 : -1;
    int dy = -abs(y), sy = hwYpos0 < hwYpos1 ? 1 : -1;
    int err = dx + dy, e2;

 if (hwXpos0 >= LCD_WIDTH || hwYpos0 >= LCD_HEIGHT || hwXpos1 >= LCD_WIDTH || hwYpos1 >= LCD_HEIGHT) {
 return;
 }
    
    for (;;){
        lcd_draw_point(hwXpos0, hwYpos0 , hwColor);
        e2 = 2 * err;
        if (e2 >= dy) {     
            if (hwXpos0 == hwXpos1) break;
            err += dy; hwXpos0 += sx;
        }
        if (e2 <= dx) {
            if (hwYpos0 == hwYpos1) break;
            err += dx; hwYpos0 += sy;
        }
    }
}

//draw a circle at the specified position on lcd.
void TFT::lcd_draw_circle(uint16_t hwXpos,  //specify x position.
                        uint16_t hwYpos,  //specify y position.
                        uint16_t hwRadius, //specify the radius of the circle.
                        uint16_t hwColor)  //specify the color of the circle.
{
 int x = -hwRadius, y = 0, err = 2 - 2 * hwRadius, e2;

 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }
 
    do {
        lcd_draw_point(hwXpos - x, hwYpos + y, hwColor);
        lcd_draw_point(hwXpos + x, hwYpos + y, hwColor);
        lcd_draw_point(hwXpos + x, hwYpos - y, hwColor);
        lcd_draw_point(hwXpos - x, hwYpos - y, hwColor);
        e2 = err;
        if (e2 <= y) {
            err += ++ y * 2 + 1;
            if(-x == y && e2 <= x) e2 = 0;
        }
        if(e2 > x) err += ++ x * 2 + 1;
    } while(x <= 0);
}

//fill a rectangle out at the specified position on lcd.
void TFT::lcd_fill_rect(uint16_t hwXpos,  //specify x position.
                   uint16_t hwYpos,  //specify y position.
                   uint16_t hwWidth, //specify the width of the rectangle.
                   uint16_t hwHeight, //specify the height of the rectangle.
                   uint16_t hwColor)  //specify the color of rectangle.
{
 uint16_t i, j;

 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }
 
 for(i = 0; i < hwHeight; i ++){
 for(j = 0; j < hwWidth; j ++){
 lcd_draw_point(hwXpos + j, hwYpos + i, hwColor);
 }
 }
}

//draw a vertical line at the specified position on lcd.
void TFT::lcd_draw_v_line(uint16_t hwXpos, //specify x position.
                        uint16_t hwYpos, //specify y position. 
                        uint16_t hwHeight, //specify the height of the vertical line.
                        uint16_t hwColor)  //specify the color of the vertical line.
{ 
 uint16_t i, y1 = min(hwYpos + hwHeight, LCD_HEIGHT - 1);

 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }
 
    for (i = hwYpos; i < y1; i ++) {
        lcd_draw_point(hwXpos, i, hwColor);
    }
}

//draw a horizonal line at the specified position on lcd.
void TFT::lcd_draw_h_line(uint16_t hwXpos, //specify x position.
                        uint16_t hwYpos,  //specify y position. 
                        uint16_t hwWidth, //specify the width of the horizonal line.
                        uint16_t hwColor) //specify the color of the horizonal line.
{ 
 uint16_t i, x1 = min(hwXpos + hwWidth, LCD_WIDTH - 1);

 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }
 
    for (i = hwXpos; i < x1; i ++) {
        lcd_draw_point(i, hwYpos, hwColor);
    }
}

void TFT::lcd_draw_rect(uint16_t hwXpos,  //specify x position.
                      uint16_t hwYpos,  //specify y position.
                      uint16_t hwWidth, //specify the width of the rectangle.
                      uint16_t hwHeight, //specify the height of the rectangle.
                      uint16_t hwColor)  //specify the color of rectangle.
{
 if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
 return;
 }

 lcd_draw_h_line(hwXpos, hwYpos, hwWidth, hwColor);
 lcd_draw_h_line(hwXpos, hwYpos + hwHeight, hwWidth, hwColor);
 lcd_draw_v_line(hwXpos, hwYpos, hwHeight, hwColor);
 lcd_draw_v_line(hwXpos + hwWidth, hwYpos, hwHeight + 1, hwColor);
}


TFT Tft = TFT();
/*********************************************************************************************************
  END FILE
*********************************************************************************************************/