Go Down

Topic: Special Characters on LCD 16x2 using byte array (Read 138 times) previous topic - next topic

apexapex

Hi all,

I tried to create Thai characters on regular LCD 16x2 which is possible using this website https://omerk.github.io/lcdchargen/ and createChar function. Unfortunately, some Thai words are a combination of many Thai characters at a same position (at most 4 characters). I am looking for the method that can combine byte arrays of Thai characters into one byte array for displaying all necessary characters at once. Following is my approach, but no luck.

Code: [Select]

byte nornuChar[8] = {
  0b00000,
  0b00000,
  0b00000,
  0b11010,
  0b01011,
  0b01111,
  0b00000,
  0b00000
};

byte sara_eeChar[8] = {
  0b00001,
  0b00111,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

byte* combinedChar(byte char1[], byte char2[]){
  static byte resChar[8];
  for(byte x=0; x<8; ++x){
    resChar[x]=char1[x]|char2[x]; //try to use OR bitwise operator to combine them
  }
  return resChar;
}

void setup()
{
  byte testChar = combinedChar(nornuChar, sara_eeChar);
  lcd.createChar(0, testChar);
  lcd.begin(16, 2);
  lcd.write((uint8_t)0);
}


But it doesn't work.
Could any one help me, please?
Thanks in advance.

Apex.

bperrybap

#1
Mar 19, 2017, 05:48 pm Last Edit: Mar 19, 2017, 05:50 pm by bperrybap
You haven't shown us all the code you are using or your code is incomplete.
The code you have shown us is incomplete and what you have shown us will not build a sketch.
(missing loop() , library includes and the lcd object declaration & definition)
Also, since it is incomplete, we can't tell which library you are using.
But here are some things that you must keep in mind:
You must call begin() before you do anything else to the LCD.
If you are not using my hd44780 lcd library package you must call home(), clear() or setCursor(col,row)
after you call createChar() but before you call write()
since other libraries leave the lcd module in CGRAM mode and you need to get the display back into DDRAM mode before you can send characters to the display.

You may want to start with a simpler piece of example code that ensures that a simple custom character works.
The code you have now will not work even with a simple custom character.

If you want to use my hd44780 library package it can be installed using the library manager.
You can read more about it here:
https://github.com/duinoWitchery/hd44780

There are several i/o classes that are included along with examples. The hd44780 i/o class you choose will depend on the hardware interface to your lcd. hd44780_pinIO is the i/o class when using arduino pins to directly control the LCD.

--- bill

apexapex

Hi Bill,

thank you for replying.

Indeed, my code here is not complete. But I use the code from this website https://omerk.github.io/lcdchargen/, which works just fine. I assume that they use the LiquidCrystal library reference.

But my main target is to find out how can I make a function with 2 byte array arguments that can return byte array in Arduino. Is it possible or some workarounds?

For instance:
Code: [Select]

byte nornuChar[8] = {
  0b00000,
  0b00000,
  0b00000,
  0b11010,
  0b01011,
  0b01111,
  0b00000,
  0b00000
};

byte sara_eeChar[8] = {
  0b00001,
  0b00111,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

can be combined into: (maybe with OR bitwise operator)
Code: [Select]

byte newChar[8] = {
  0b00001,
  0b00111,
  0b00000,
  0b11010,
  0b01011,
  0b01111,
  0b00000,
  0b00000
};


Thank you!

Apex

bperrybap

Of course you can do what you are wanting to do, it just a matter of getting your code correct.

However, the example code on lcdchargen as well as the LiquidCrystal example here:
https://www.arduino.cc/en/Reference/LiquidCrystalCreateChar
is are depending on some hidden behaviors and IMO are not good examples of how to use the API.

1)
You cannot reliably send commands to the LCD until you have properly initialized it.
This is absolutely an issue when using 4 bit mode.
The LCD powers up in 8 bit mode. If you attempt to send it commands prior to initializing it to 4 bit mode the commands will not work properly.

The LiquidCrystal library will not initialize the LCD, which is what puts it into 4 bit mode, until you call init() or begin().
The constructor for LiquidCrystal will call init() for you but will put initialized the lcd and library for 16x1 mode.

The sketch code call to begin() will re-initalized the lcd  and set the LCD and library to the geometry you pass in.

2)
The sketch code is depending on the LCD being initialized *before* you call begin().
While this will work with the LiquidCrystal library, it will not work with other LCD libraries like ones that use i2c.
It is best to not depend on this extra initialization behavior and to not attempt to talk to the lcd until after begin() is called.
That way the sketch code will work with any LCD using a LiquidCrystal API compatible library - including ones that use i2c.

3)
The sketch code is depending on re-initialization done by begin() to flip the LCD from CGRAM mode (which was set by createChar()) back to DDRAM mode.
While this can be used in this type of simple example sketch, usually this cannot be done in a real sketch as it may not be desirable to reset/re-initalize the entire lcd just to program a custom character.


My recommendation is to do that things that I mentioned in response #1.

--- bill

apexapex

I understand. Thanks a lot for your reply!

Apex

Go Up