LCD Printing ASCII

Hello, I have a 20 x 4 I2C LCD and I'm trying to output a uint8_t value as it is but the LCD prints the ASCII character instead. Is there any way to get around this?

Here's the code:

  lcd.setCursor(0, 0);
  lcd.print("R:"); lcd.print(r); lcd.print(" ");
  lcd.print("G:"); lcd.print(g); lcd.print(" ");
  lcd.print("B:"); lcd.print(b); lcd.print(" ");
  lcd.print(" ");

If r, g and b are declared as uint8_t and you want them printed as numbers, you could try lcd.print((uint16_t)r);, etc.

Thank you, I tried this but the LCD continues to print random ASCII characters. The LCD successfully print's the 'hello world' script and any letters within quotations but my variables come out as gibberish.

That's the problem with trying to diagnose a problem from a code snippet; it rarely works.

Is your variable is a pointer? please post full code

#include <Wire.h>
#include "Adafruit_TCS34725.h"
#include "LCDIC2.h"

/* Connect SCL    to analog 5
   Connect SDA    to analog 4
   Connect VDD    to 3.3V DC
   Connect GROUND to common ground */

/* Initialise with specific int time and gain values */
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_240MS, TCS34725_GAIN_16X);
LCDIC2 lcd(0x27, 20, 4);

const int buttonPin = 2;  // the number of the pushbutton pin
int buttonState = 0;

//Defining some global variables
uint16_t rMa, gMa, bMa, cMa, rMi, gMi, bMi, cMi;
uint16_t rA, gA, bA, cA;

//Light source white point chromaticity coordinates values found on the following data sheet: https://www.farnell.com/datasheets/3195184.pdf
//Has a CCT of 6000k
float Xn_c = 0.313;
float Yn_c = 0.337;
float Zn_c = 1.0 - Xn_c - Yn_c;

//Normalised tristimulus white point values: https://www.opticsthewebsite.com/CIE1931
float Xn = Xn_c / Yn_c;
float Yn = 1.0;
float Zn = 1.0 - Xn_c - Yn_c;

// float Xn = 0.948;
// float Yn = 1;
// float Zn = 1.073;

//Function AveRGBValue has the sensor take 25 readings then average them out

void AveRGBValue(uint16_t *rAve, uint16_t *gAve, uint16_t *bAve, uint16_t *cAve) {
  uint32_t count = 25;
  uint32_t rT, gT, bT, cT;
  uint16_t r, g, b, c;

  rT = gT = bT = cT = 0;

  for (int i=0; i< count; i++) {

    tcs.getRawData(&r, &g, &b, &c);
  
    rT += r; 
    gT += g;
    bT += b;
    cT += c;
  }

  *rAve = rT / count; 
  *gAve = gT / count;
  *bAve = bT / count;
  *cAve = cT / count;

}

/* Function turning raw sensor values to RGB values from 0-255 
Max values are white RGB values, min are black RGB values*/

void rawTOrgb(uint8_t *r,uint8_t *g,uint8_t *b, uint16_t *RedMax, uint16_t *GreenMax, uint16_t *BlueMax, uint16_t *RedMin, uint16_t *GreenMin, uint16_t *BlueMin) {

  uint16_t red_M, green_M, blue_M;
  uint16_t red, green, blue, clear;

  // tcs.getRawData(&red, &green, &blue, &clear);
  AveRGBValue(&rA, &gA, &bA, &cA);
  uint32_t sum = cA;

  // Avoid divide by zero errors ... if clear = 0 return black
  if (cA == 0) {
    *r = *g = *b = 0;
    return;
  }

  red_M = map(rA, *RedMin, *RedMax, 0, 65535);
  green_M = map(gA, *GreenMin, *GreenMax, 0, 65535);
  blue_M = map(bA, *BlueMin, *BlueMax, 0, 65535);

  *r = ((uint32_t) red_M << 8) / sum;
  *g = ((uint32_t) green_M << 8) / sum;
  *b = ((uint32_t) blue_M << 8) / sum;

}

void TwoPointCalibrate(uint16_t *RedMax, uint16_t *GreenMax, uint16_t *BlueMax, uint16_t *ClearMax, uint16_t *RedMin, uint16_t *GreenMin, uint16_t *BlueMin, uint16_t *ClearMin) {

  uint16_t r,g,b,c;

  //Calibration begins
  //Calibrate for white
 
  lcd.print("Place white object");
  lcd.setCursor(0, 1);
  lcd.print("in front of sensor");
  lcd.setCursor(0, 2);
  lcd.print("then press a button:");

  //Waiting for user go ahead
  while (buttonState == LOW) {
    // Do Nothing, wait for button press
    buttonState = digitalRead(buttonPin);
  }
  //Collecting white RGB values

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Calibrating...");

  AveRGBValue(&rA, &gA, &bA, &cA);
  *RedMax = rA;
  *GreenMax = gA;
  *BlueMax = bA;
  *ClearMax = cA;

  Serial.print("R: "); Serial.print(*RedMax); Serial.print(" ");
  Serial.print("G: "); Serial.print(*GreenMax); Serial.print(" ");
  Serial.print("B: "); Serial.print(*BlueMax); Serial.print(" ");
  Serial.print("C: "); Serial.print(*ClearMax); Serial.print(" ");
  Serial.println(" ");

  //Calibrate for black
  lcd.clear();
  lcd.print("Place black object");
  lcd.setCursor(0, 1);
  lcd.print("in front of sensor");
  lcd.setCursor(0, 2);
  lcd.print("then press a button:");

  // Removes serial data so program will wait until it recieves user input, will change this out once I have a button

    //Waiting for user go ahead
  while (buttonState == LOW) {
    // Do Nothing, wait for press of button
    buttonState = digitalRead(buttonPin);
  }
  //Collecting white RGB values

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Calibrating...");
  // while(Serial.available() > 0) {
  //   char t = Serial.read();
  // }
  // while (Serial.available() == 0 ) {
  //   // Do Nothing
  // }

  // lcd.clear();


  //Collecting Black RGB values

  AveRGBValue(&rA, &gA, &bA, &cA); 
  *RedMin = rA;
  *GreenMin = gA;
  *BlueMin = bA;
  *ClearMin = cA;


  Serial.print("R: "); Serial.print(*RedMin); Serial.print(" ");
  Serial.print("G: "); Serial.print(*GreenMin); Serial.print(" ");
  Serial.print("B: "); Serial.print(*BlueMin); Serial.print(" ");
  Serial.print("C: "); Serial.print(*ClearMin); Serial.print(" ");
  Serial.println(" ");
}

/*Colour is evaluated through the CIElab system as a higher a* value was an indication of better masticatory performance 

deltaE and l*,a*,b* values have a highly linear relationship, so gums with the same deltaE value will have the same LAB values and will be visually the same*/

void RGBtoCIElab(float *X, float *Y, float *Z, float *CIEL, float *CIEa, float *CIEb, float *DeltaE) {

  //Converting the RGB values to XYZ trimstimulus counterparts

  float fracX, fracY, fracZ;
  float Fx, Fy, Fz;
  float x, y, z, R, G, B;
  uint8_t r, g, b;
  float dL, da, db;

  float OriL = 75.10;
  float Oria = -1.36;
  float Orib = -36.00;


  rawTOrgb(&r, &g, &b, &rMa, &gMa, &bMa, &rMi, &gMi, &bMi);

  lcd.setCursor(0, 0);
  lcd.print("R:"); lcd.print((r); lcd.print(" ");
  lcd.print("G:"); lcd.print(g); lcd.print(" ");
  lcd.print("B:"); lcd.print(b); lcd.print(" ");
  lcd.print(" ");

  float RAv = r;
  float GAv = g;
  float BAv = b;

  // turning the 0-255 values to 0-1

  R = RAv / 255.0;
  G = GAv / 255.0;
  B = BAv / 255.0;


  //Continuity check

  Serial.print("value between 0 - 1 R: "); Serial.print(R); Serial.print(" ");
  Serial.print("G: "); Serial.print(G); Serial.print(" ");
  Serial.print("B: "); Serial.print(B); Serial.print(" ");
  Serial.println(" ");

  // Using the RGB to XYZ matrix calculation found in the manufacturer datasheet to find the XYZ trimstimulus values

  // Manufacturer given
  // *X = (-0.14282F * R) + (1.54924F * G) + (-0.95641F * B);
  // *Y = (-0.32466F * R) + (1.57837F * G) + (-0.73191F * B);
  // *Z = (-0.68202F * R) + (0.77073F * G) + (0.56332F * B);

  //Matlab Calc #1
  // *X = (1.8057F *R) + (-1.8763F * G) + (0.3264F * B);
  // *Y = (0.9311F *R) + (-0.3753F * G) + (0.1306F * B);
  // *Z = (0.0846F *R) + (-4.0028F * G) + (1.7191F * B);

  //D65 2 degree standard observer matrix
  *X = (0.412453 * R) + (0.35758 * G) + (0.180423 * B);
  *Y = (0.212671 * R) + (0.715160 * G) + (0.072169 * B);
  *Z = (0.019334 * R) + (0.119193 * G) + (0.950227 * B);

  Serial.print("Tristimulus Values --- X: "); Serial.print(*X); Serial.print(" ");
  Serial.print("Y: "); Serial.print(*Y); Serial.print(" ");
  Serial.print("Z: "); Serial.print(*Z); Serial.print(" ");
  Serial.println(" ");

  // Converting the XYZ trimstimulus values to xyz chromacities values
  
  float Total = *X + *Y + *Z;
  x = *X / Total;
  y = *Y / Total;
  z = *Z / Total;

  lcd.setCursor(0, 1);
  lcd.print("X:"); lcd.print(x); lcd.print(" ");
  lcd.print("Y:"); lcd.print(y); lcd.print(" ");
  lcd.print("Z:"); lcd.print(z); lcd.print(" ");
  lcd.print(" ");

  // Going from CIExyz to CIELab

  fracX = *X/Xn;
  fracY = *Y/Yn;
  fracZ = *Z/Zn;

  // if (fracY > 0.008856) {
  //   *CIEL = pow( 116.0 * (fracY), 0.33333) - 16.0;
  //   *CIEa = 500 * (pow(fracX, 0.3333) - pow(fracY, 0.3333));
  //   *CIEb = 200 * (pow(fracY, 0.3333) - pow(fracZ, 0.3333));
  // }
  // else {
  //   *CIEL = 903.3 * fracY;
  //   *CIEa = 500 * (pow(fracX, 0.3333) - pow(fracY, 0.3333));
  //   *CIEb = 200 * (pow(fracY, 0.3333) - pow(fracZ, 0.3333));  
  // }

  if (fracX > 0.008856) {
    Fx = pow(fracX, 0.3333);
  } 
  else {
    Fx = ((7.787)*(fracX)) + (0.1379);
  }

  if (fracY > 0.008856) {
    Fy = pow(fracY, 0.3333);    
  }
  else {
    Fy = ((7.787)*(fracY)) + (0.1379);
  } 

  if (fracZ > 0.008856) {
    Fz = pow(fracZ, 0.3333);
  }
  else {
    Fz = ((7.787)*(fracZ)) + (0.1379);
  }


  *CIEL = (116.0 * Fy) - 16.0;
  *CIEa = 500.0 * (Fx - Fy);
  *CIEb = 200.0 * (Fy - Fz);

  // Calculating the colour difference

  dL = *CIEL - OriL;
  da = *CIEa - Oria;
  db = *CIEb - Orib;

  *DeltaE = pow( (pow(dL,2) + pow(da,2) + pow(db,2) ), 0.5);

}

void setup(void) {

  Serial.begin(9600);
  pinMode(buttonPin, INPUT);

  Serial.println("");

    if (tcs.begin() & lcd.begin()) {
    lcd.print("Found sensor");
    delay(5000);
    lcd.clear();
  } 
  else {
    lcd.print("No TCS34725 found ... check your connections");
    while (1);
  }

  TwoPointCalibrate(&rMa, &gMa, &bMa, &cMa, &rMi, &gMi, &bMi, &cMi);
  
}

void loop(void) {

  float X, Y, Z;
  float CIEL, CIEa, CIEb, dE;

  RGBtoCIElab(&X, &Y, &Z, &CIEL, &CIEa, &CIEb, &dE);

  lcd.setCursor(0, 2);
  lcd.print("L:"); lcd.print(CIEL); lcd.print(" ");
  lcd.print("a:"); lcd.print(CIEa); lcd.print(" ");
  lcd.print("b:"); lcd.print(CIEb); lcd.print(" ");
  lcd.setCursor(0, 3);
  lcd.print("dE:"); lcd.print(dE); lcd.print(" ");
  lcd.print(" ");
  delay(5000);

  lcd.clear();
}

The code is quite long and messy sorry, but here it is

Do the numbers print correctly on the serial print() screen?

And there's your problem right there. An odd ball library, where the class is not based on the Print class, and where its print methods only know how to print a glyph (I'm assuming that means a character, but the library is completely silent on that - and indeed, on everything else), or a String. There is no support for printing numbers.

Do yourself a favour and pick another library.

Yes, I used to have RGB, xyz and CIELAB values printing to the serial and they'd show up correctly

And that worked because Serial is derived from Print, and so behaves as you'd expect it to when printing numbers.

I see thank you! Is there a specific library I should be looking for?

Then cut the code down till it still exhibits the problem. Minimal verifiable example.

The process of doing this can be very helpful.

Check to see what chip you have on your LCD's I2C interface, and pick one compatible with it.