Generate line graph using LiquidCrystal createChar() and nested for loops

Hi guys,

I'm new to Arduino, plus to programming in general, but I'm finding due to the excellent resources available that I'm coming along nicely. Thanks for that!

The purpose of the below function is to generate a character for the LCD resembling a line graph. My plan is to have a couple of these side by side to generate a horizontal temperature graph. This code compiles and run's successfully, outputting the expected result:

00000
00000
00001
00010
00100
01000
10000
00000

Unfortunately the only way I have found to make this work is use the string data type, but obviously I need this array to be of bytes to pass into createChar(). Would somebody mind pointing me in the right direction?

Thanks,
Ash

void displayGraph()
{
  String firstSegment[8];
  int displayTemp[5];
  String binary;
  int count = 7;

  displayTemp[0] = 1;
  displayTemp[1] = 2;
  displayTemp[2] = 3;
  displayTemp[3] = 4;
  displayTemp[4] = 5;


  // Loop through the height of the character
  for(int l=0; l<8; l++)
  {
    // Loop through the width of the character
    for (int m=0; m<5; m++)
    {
      // If a pixel is necessary
      if (count == displayTemp[m])
      {
        // Append a 1 to the byte
        binary += 1;
      }
      else
      {
        // Append a 0 to the byte
        binary += 0;
      }
    }
    count--;
    
    // Add byte to array
    firstSegment[l] = binary;
    
    // Reset byte
    binary = "";
    
  }

  // Print byte array to serial
  for(int n=0; n<8; n++)
  {
    Serial.println(firstSegment[n]);
  }

}

You do not want Strings. You want bytes. You do not append a 0 or 1 to the String. You use bitSet() or bitWrite() to set the appropriate bit.

Thanks Paul,

That got me moving in the right direction! Unfortunately I've now run across what I think is a logical issue...

The below code is showing the correct character, but it seems to be flipped both horizontally and vertically.. Could this be an issue with the way I have stored the bits in the byte? MSB/LSB?

Thanks,
Ash

void displayGraph()
{
  byte firstSegment[8];
  int displayTemp[5];
  byte binary;

  displayTemp[0] = 2;
  displayTemp[1] = 3;
  displayTemp[2] = 3;
  displayTemp[3] = 5;
  displayTemp[4] = 6;

  // Loop through the height of the character
  for(int l=0; l<8; l++)
  {
    // Loop through the width of the character
    for (int m=0; m<5; m++)
    {
      // If a pixel is necessary
      if (l == displayTemp[m])
      {
        bitSet(binary,m);
      }
    }

    firstSegment[l] = binary;

    
    // Reset byte
    bitClear(binary,0);
    bitClear(binary,1);
    bitClear(binary,2);
    bitClear(binary,3);
    bitClear(binary,4);
    bitClear(binary,5);
    bitClear(binary,6);
    bitClear(binary,7);
    
  }

  lcd.createChar(0, firstSegment);
  lcd.setCursor(0,1);
  lcd.write(byte(0));

}
    bitClear(binary,0);
    bitClear(binary,1);
    bitClear(binary,2);
    bitClear(binary,3);
    bitClear(binary,4);
    bitClear(binary,5);
    bitClear(binary,6);
    bitClear(binary,7);

Instead of all this, isn't:

binary = 0;

simpler?

Could this be an issue with the way I have stored the bits in the byte?

Yes. Perhaps you need to use 7-m in the bitSet() function call, instead of m. That should flip the data about one axis at least.

Thanks Paul,

With a little tinkering, plus your advice, the following function is now working perfectly for me:

void displayGraphSegment(int pos, int first, int last)
{
  byte binary;
  byte segment[8];
  
  // Loop through the height of the first character
  for(int l=0; l<8; l++)
  {
    // Loop through the width of the character
    for (int m=first; m<=last; m++)
    {
      // If a pixel is necessary
      if (l < displayTemp[m])
      {
        bitSet(binary,4-m);
      }
    }
    segment[7-l] = binary;
    
    // Reset byte
    binary = 0;
  }
  
  lcd.createChar(pos, segment);
  lcd.setCursor(7+pos,0);
  lcd.write(byte(pos));
}

Thanks again for all your help!