Go Down

Topic: I2C LCD 2x16 - Svenska tecken - hur? (Read 15674 times) previous topic - next topic

Albireo1

Hej!
Har just börjat fördjupa mig i Arduino och köpte en LCD-display. (I2C)
Men vad är bästa / enklaste sättet att få svenska tecken?
UTF-8? eller ....
(Har jag köpt fel display från Tyskland (Kina)?)

Albireo1

Har lyckats (med hjälp av några länkar) skapa åäöÅÄÖ på LCD I2C Displayen på följande sätt .:
Code: [Select]
/*
https://forum.arduino.cc/index.php?topic=224615.0
YourDuino.com Example Software Sketch
16 character 2 line I2C Display
Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

/* -----( Declare Constants )----- */

/* -----( Declare objects )-----   */
// set the LCD address to 0x27 for a 16 chars 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);


byte AwithRing[8] = {
  B00100,
  B01010,
  B01110,
  B00001,
  B01111,
  B10001,
  B01111,
};

byte AwithDots[8] = {
  B01010,
  B00000,
  B01110,
  B00001,
  B01111,
  B10001,
  B01111,
};
 
byte OwithDots[8] = {
  B01010,
  B00000,
  B01110,
  B10001,
  B10001,
  B10001,
  B01110,
};

byte BigAwithRing[8] = {
  0b00100,
  0b01010,
  0b01110,
  0b10001,
  0b11111,
  0b10001,
  0b10001,
  0b00000
};

byte BigAwithDots[8] = {
  0b01010,
  0b00000,
  0b01110,
  0b10001,
  0b11111,
  0b10001,
  0b10001,
  0b00000
};

byte BigOwithDots[8] = {
  0b01010,
  0b01110,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b01110,
  0b00000
};

/*
byte Minus[8] = {
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b11111,
  0b00000,
  0b00000,
  0b00000
};
*/

/*----( SETUP: RUNS ONCE )----*/
void setup() {
  Serial.begin(115200);  // Used to type in characters
  lcd.init();
  lcd.backlight();

//-------- Write characters on the display ------------------
  lcd.createChar(1, AwithRing); //å
  lcd.createChar(2, AwithDots); //ä
  lcd.createChar(3, OwithDots); //ö
  lcd.createChar(4, BigAwithRing); //Å
  lcd.createChar(5, BigAwithDots); //Ä
  lcd.createChar(6, BigOwithDots); //Ö


// Display. (Set Serial Monitor option to "No Line Ending")
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("å ä ö Å Ä Ö");

/*
String message = "å ä ö";
message.replace('å', char(1));
message.replace('ä', byte(2));
message.replace('ö', byte(3));
*/
  lcd.setCursor(0,1);
  String message = "\01 \02 \03 \04 \05 \06 ";
  lcd.print(message);
} /*--(end setup )---*/


void loop() {   /*----( LOOP: RUNS CONSTANTLY )----*/
}


Resultatet är positivt! Men är väldigt opraktiskt om text som ska visas på LCD-skärmen finns som textformat i en fil, eller lagras i en variabel i läsbart format.
Att skriva Såja skulle bli på följande sätt .:
Code: [Select]
String message = "S\01ja";
  lcd.print(message);


Då behövs en konvertering. Finns det redan?

Albireo1

Tillslut lyckades jag få ihop ett program som kan visa åäö på displayen enligt mitt önskemål .:
Code: [Select]
/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

/* -----( Declare Constants )----- */
byte AwithRing[8] = {  //å
  B00100,
  B01010,
  B01110,
  B00001,
  B01111,
  B10001,
  B01111,
};

byte AwithDots[8] = {  //ä
  B01010,
  B00000,
  B01110,
  B00001,
  B01111,
  B10001,
  B01111,
};
  
byte OwithDots[8] = {  //ö
  B01010,
  B00000,
  B01110,
  B10001,
  B10001,
  B10001,
  B01110,
};

byte BigAwithRing[8] = {  //Å
  0b00100,
  0b01010,
  0b01110,
  0b10001,
  0b11111,
  0b10001,
  0b10001,
  0b00000
};

byte BigAwithDots[8] = {  //Ä
  0b01010,
  0b00000,
  0b01110,
  0b10001,
  0b11111,
  0b10001,
  0b10001,
  0b00000
};

byte BigOwithDots[8] = {  //Ö
  0b01010,
  0b01110,
  0b10001,
  0b10001,
  0b10001,
  0b10001,
  0b01110,
  0b00000
};
    
/*
byte Minus[8] = {
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b11111,
  0b00000,
  0b00000,
  0b00000
};
*/


/* -----( Declare objects )-----   */
// set the LCD address to 0x27 for a 16 chars 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

// String message = "åäö - ÅÄÖ - öäå";
String message = "å -What I want!";
char TextLCD[30] = "";

/*----( SETUP: RUNS ONCE )----*/
void setup() {
  Serial.begin(115200);  // Used to type in characters
  lcd.init();
  
  //-------- Write characters on the display ------------------
  lcd.createChar(1, AwithRing);     //å
  lcd.createChar(2, AwithDots);     //ä
  lcd.createChar(3, OwithDots);     //ö
  lcd.createChar(4, BigAwithRing);  //Å
  lcd.createChar(5, BigAwithDots);  //Ä
  lcd.createChar(6, BigOwithDots);  //Ö

  message.replace("å", "\1");
  message.replace("ä", "\2");
  message.replace("ö", "\3");
  message.replace("Å", "\4");
  message.replace("Ä", "\5");
  message.replace("Ö", "\6");

  message.toCharArray(TextLCD, 30);

  lcd.backlight();
} /*--(end setup )---*/


void loop() {   /*----( LOOP: RUNS CONSTANTLY )----*/
  int pos = 0;

  while (pos < strlen(TextLCD)) {
    lcd.setCursor(pos, 0);    // pos & col
    lcd.print(TextLCD[pos]);

    delay(500);
    pos += 1;  // Nästa tecken
    
  }
  delay (1000);
  lcd.clear();
  delay (1000);
}

noiasca

hope you don't mind if I write in English:

if you try my Noiasca LCD Library, you can write your own converter and print out the characters without the need of an additional buffer. A simple

lcd.print("Å å Ä ä Ö ö");

will do the job.

example Sketch:
Code: [Select]

/*******************************************************************************
   Convert Swedish
   Swedish Characters for standard HD44780 LCD

   Define your own converter for handling of special characters
   including UTF-8 two byte characters

   Important: You have to chose the proper hardware interface in the sketch!

   by noiasca
   2020-09-18
 *******************************************************************************/
#include <NoiascaLiquidCrystal.h>      // download library from https://werner.rothschopf.net/202003_arduino_liquid_crystal_umlaute.htm

const byte cols = 16;                  // columns/characters per row
const byte rows = 2;                   // how many rows
const byte addr = 0x3F;                // set the LCD address for I2C to 0x3F or 0x27
const byte rs = 8;
//const byte rw = 255;                 // set to 255 if not used - for future use
const byte en = 9;
const byte d4 = 4;
const byte d5 = 5;
const byte d6 = 6;
const byte d7 = 7;
const byte bl = 10;                    // set to 255 if not used

// this example callback converter maps Swedish UTF-8 characters into custom characters
uint8_t cbConverter (uint32_t &special, uint8_t &value)
{
  uint8_t outputMode = NOPRINT;                  // assume not printable character
  if ((value & 0b11000000) == 0b11000000)        // if we receive a UTF8 multi byte character, it will be indicated in the two MSB of the first byte
  {
    special = value;                             // just store the byte as special character for the next call
  }
  else if (special > 0)                          // if there is a special character stored
  {
    if (special == 0xC3)                         // check if the first byte fits
    { //                                         // map value based on the second byte to another character in the ROM. 0 - 7 are the custom characters
      switch (value)
      {
        case 0x84: value = 6; break;             // Ä
        case 0x85: value = 5; break;             // Å
        case 0x96: value = 7; break;             // Ö
        case 0xA4: value = 0xE1; break;          // ä
        case 0xA5: value = 4; break;             // å
        case 0xB6: value = 0xEF; break;          // ö
      }
    }
    special = 0;                                 // delete special (in any cas)
    outputMode = PRINT;                          // we have a printable character in value
  }
  else                                           // print in any case
  {
    outputMode = PRINT;
  }
  return outputMode;                             // return if printable or not
}

// activate the needed lines according to your LCD hardware
//#include <NoiascaHW/lcd_4bit.h>        // parallel interface, 4bit
//LiquidCrystal_4bit lcd(rs, en, d4, d5, d6, d7, bl, cols, rows, cbConverter);  // create lcd object parallel 4bit

#include <NoiascaHW/lcd_i2c.h>         // I2C
LiquidCrystal_I2C lcd(addr, cols, rows, cbConverter);       // create lcd object I2C

//#include <NoiascaHW/lcd_spi.h>        // SPI
//LiquidCrystal_SPI lcd(0x40, cols, rows, csPin, cbConverter);  // create lcd object SPI

// define custom characters which are not available in the LCD ROM
const uint8_t small_a_ring_above []  = {0b00100, 0b01010, 0b01110, 0b00001, 0b01111, 0b10001, 0b01111, 0}; // å
const uint8_t capital_a_ring_above[] = {0b00100, 0b01010, 0b01110, 0b10001, 0b11111, 0b10001, 0b10001, 0}; // Å
const uint8_t capital_a_diareses[]   = {0b01010, 0b00000, 0b01110, 0b10001, 0b11111, 0b10001, 0b10001, 0}; // Ä
//const uint8_t capital_a_diareses[] = {0b10001, 0b01110, 0b10001, 0b10001, 0b11111, 0b10001, 0b10001, 0}; // Ä - Variant
const uint8_t captial_o_diareses[]   = {0b01010, 0b01110, 0b10001, 0b10001, 0b10001, 0b10001, 0b01110, 0}; // Ö
//const uint8_t capital_o_diareses[] = {0b10001, 0b01110, 0b10001, 0b10001, 0b10001, 0b10001, 0b01110, 0}; // Ö - Variant

void setup()
{
  // SPI.begin();                      // start the SPI bus - activate if needed for the display
  Wire.begin();                        // start the I2C bus - activate if needed for the display

  lcd.begin();                         // initialize the lcd
  lcd.backlight();

  lcd.createChar(4, small_a_ring_above);   // å
  lcd.createChar(5, capital_a_ring_above); // Å
  lcd.createChar(6, capital_a_diareses);   // Ä
  lcd.createChar(7, captial_o_diareses);   // Ö

  lcd.setCursor(0, 0);
  lcd.print("Swedish - Hallå");
  lcd.setCursor(0, 1);
  lcd.print("Å å Ä ä Ö ö");
}

void loop()
{}


This works fine for LCD with HD44780 A00 ROM.

As alternative, consider to buy a display with SPLC780D1 chip and 003A ROM. The displays with 003A ROM have native support of most European Languages.
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

Go Up