Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Albireo
Inlägg: 73
Blev medlem: 30 november 2019, 00:29:39

Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av Albireo »

Hej!
Försöker skriva en sträng (å - Bra gjort!) till en LCD I2C display med en Arduino.
(Men misslyckades!)

Skapade först ett program som skriver ut de svenska tecknen .: åäöÅÄÖ till LCD -displayen.
(Kanske går att lösa på ett smidigare sätt?)

Kod: Markera allt

/* 
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("å ä ö Å Ä Ö");

  lcd.setCursor(0,1);
  String message = "\01 \02 \03 \04 \05 \06 ";
  lcd.print(message); 
} /*--(end setup )---*/


void loop() {   /*----( LOOP: RUNS CONSTANTLY )----*/
}
Det fungerar (på ett sätt)
På första raden skrivs ASCII-tecknen ut för å ä ö Å Ä Ö (med Arduinos kod-tabell - liknar japanska :) )
På andra raden skrivs å ä ö Å Ä Ö ut. (som förväntat.)

Skapade ett nytt program där strängen skrivs ut till LCD-skärmen från en variabel.
Problemet uppstår när å i strängen skall bytas mot den skapade bokstaven å.
Här kommer detta försök till program .:

Kod: Markera allt

 /* I2C LCD with Arduino example code. More info: https://www.makerguides.com
       https://www.makerguides.com/character-i2c-lcd-arduino-tutorial/  */
    // Include the libraries:
    // LiquidCrystal_I2C.h: https://github.com/johnrickman/LiquidCrystal_I2C
    
    #include <Wire.h> // Library for I2C communication
    #include <LiquidCrystal_I2C.h> // Library for LCD
    // Wiring: SDA pin is connected to A4 and SCL pin to A5.
    // Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered)
    // LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4); // Change to (0x27,16,2) for 16x2 LCD.
    LiquidCrystal_I2C lcd = LiquidCrystal_I2C(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
    };
    
    
    // https://www.arduino.cc/en/Reference/VariableDeclaration
    // https://www.arduino.cc/reference/en/language/variables/data-types/string/
    char TextLCD[16] = "å - Bra gjort!";  // Variable type .: String
    int i = 0;
    
    void setup() {
      lcd.init();       // Initiate the LCD:
      lcd.backlight();  // Backlight ON:

      lcd.createChar(1, AwithRing);     //å
      lcd.createChar(2, AwithDots);     //ä
      lcd.createChar(3, OwithDots);     //ö
      lcd.createChar(4, BigAwithRing);  //Å
      lcd.createChar(5, BigAwithDots);  //Ä
      lcd.createChar(6, BigOwithDots);  //Ö
    }
    
    void loop() {
      i = 0;
      while (i < strlen(TextLCD))
      { lcd.setCursor(i, 0); // Pekare på .: Kolumn1 - Rad1
        char pointer = TextLCD[i++];

        if ( pointer = "å" ) {
            String replace(pointer, "/1");
        }
        
        lcd.print(pointer);
        // Serial.println(pointer);
        delay(500);
      }

      lcd.clear();
      // lcd.setCursor(0, 1); // Pekare på .: Kolumn1 - Rad2 
      // StringChar.TextLCD(1);
      // lcd.print(myChar);
      // lcd.print("Hello World!"); // Print the string "Hello World!" - Fungerarar!
      
      // lcd.setCursor(2, 1); //Set the cursor on the third column and the second row (counting starts at 0!).
      // lcd.print("LCD tutorial");
    }
Är detta svårt att lösa?
Användarvisningsbild
GeekJoan
Admin
Inlägg: 10642
Blev medlem: 26 maj 2003, 15:59:27
Ort: Solna

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av GeekJoan »

Här är en liknande kod som jag kör på denna: https://photos.app.goo.gl/EXXmvAdg8usoJpze7
Du borde kunna klura ut det.

Kod: Markera allt

// SDA -> Pin A4
// SCL -> Pin A5
// Pot -> Pin A0

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
#include <Arduino.h>
#include <TM1637Display.h>
LiquidCrystal_PCF8574 lcd(0x27);  // set the LCD address to 0x27 for a 16 chars and 2 line display


// Arduino pin numbers
#define CLK 2
#define DIO 3
TM1637Display display(CLK, DIO);
const int Pot = A0; 
int PotVal = 20;
int Sleep = 100;
int OldPotVal = 0;

void setup()
{
  pinMode(Pot, INPUT);
  lcd.begin(16, 2); // initialize the lcd
  lcd.setBacklight(255);
  Serial.begin(9600);

  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
};
  
  lcd.createChar(1, AwithRing);
  lcd.createChar(2, AwithDots);
  lcd.createChar(3, OwithDots);
  lcd.createChar(4, BigAwithRing);
  lcd.createChar(5, BigAwithDots);
  lcd.createChar(6, BigOwithDots);
  lcd.createChar(7, Minus);
  
   display.setBrightness(7, true);
}

void loop()
{
  OldPotVal = PotVal;
  PotVal = analogRead(A0);
  PotVal = map(PotVal, 0, 1023, 0, 12);
  
  if (PotVal == OldPotVal){
    delay(Sleep);
    }

  else {
  if (PotVal == 0){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Vi \02r h\02r!");
  lcd.setCursor(0,1);
  lcd.print("\06ppna och kom in!");
  display.showNumberDec(1, false);
  Serial.println(PotVal);
  }
  if (PotVal == 1){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Vi \02r p\01 lunch!");
  lcd.setCursor(0,1);
  lcd.print("\04ter kl 13:00");
  display.showNumberDec(2, false);
  Serial.println(PotVal);
  }
  if (PotVal == 2){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Tillf\02lligt ute");
  lcd.setCursor(0,1);
  lcd.print("kommer snart");
  display.showNumberDec(3, false);
  }
  if (PotVal == 3){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Vi har g\01tt f\03r");
  lcd.setCursor(0,1);
  lcd.print("dagen");
  display.showNumberDec(4, false);
  }
  if (PotVal == 4){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Ute p\01 service");
  lcd.setCursor(0,1);
  lcd.print("\04ter ca: 10:00");
  display.showNumberDec(10, false);
  }
  if (PotVal == 5){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Ute p\01 service");
  lcd.setCursor(0,1);
  lcd.print("\04ter ca: 11:00");
  display.showNumberDec(11, false);
  }
  if (PotVal == 6){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Ute p\01 service");
  lcd.setCursor(0,1);
  lcd.print("\04ter ca: 13:00");
  display.showNumberDec(13, false);
  }
  if (PotVal == 7){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Ute p\01 service");
  lcd.setCursor(0,1);
  lcd.print("\04ter ca: 14:00");
  display.showNumberDec(14, false);
  }
  if (PotVal == 8){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Ute p\01 service");
  lcd.setCursor(0,1);
  lcd.print("\04ter ca: 15:00");
  display.showNumberDec(15, false);
  }
  if (PotVal == 9){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Ute p\01 service");
  lcd.setCursor(0,1);
  lcd.print("\04ter ca: 16:00");
  display.showNumberDec(16, false);
  delay(Sleep);
  }
  if (PotVal == 10){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Ute p\01 service");
  lcd.setCursor(0,1);
  lcd.print("\04ter ca: 17:00");
  display.showNumberDec(17, false);
  }
  if (PotVal == 11){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("\05r i n\02r0heten");
  lcd.setCursor(0,1);
  lcd.print("Ring 0704\07l96170");
  display.showNumberDec(1961, false);
  }
}

} 
 

Användarvisningsbild
Xyzzy
Inlägg: 1222
Blev medlem: 30 januari 2004, 22:31:07
Ort: Uppsala, Sweden

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av Xyzzy »

Ändra:

Kod: Markera allt

if ( pointer = 'å' ) {
 String replace(pointer, "/1");
}
Till:

Kod: Markera allt

if ( pointer == 'å' ) {
  pointer = 1;
} 
Edit: div korrigering
Användarvisningsbild
Icecap
Inlägg: 26105
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av Icecap »

Som Xyzzy skriver är den rad fel! Med "if ( pointer = "å" )" GER du Pointer värdet "å" vilket per definition är TRUE (i C är allt annat än 0 TRUE).

Sedan anser jag att det även ska stå:
if (pointer == 'å')
då "å" motsvarar en STRÄNG som i detta fall består av "'å', noll".
Skillnaden är alltså " kontra ' där " innesluter en sträng och ' innesluter ett tecken.
Albireo
Inlägg: 73
Blev medlem: 30 november 2019, 00:29:39

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av Albireo »

Tack för Ert egaremang!
(Ska försöka beskriva vad som inträffade)

Har testat att ändra till

Kod: Markera allt

        if (pointer == 'å') {
          pointer = 1;
        } 
Detta genererar ett fel
if ( pointer == 'å' ) {
^~~~
(lyckades inte få "taket" att peka under första snutten i 'å'

_________________________________________________

Har även funderat över en lösning likt denna (men försår inte hur instruktionen replace fungerar)

Kod: Markera allt

    char TextLCD[16] = "å - Bra gjort!";  // Variable type .: String

    TextLCD.replace('å', 1);
    TextLCD.replace('ä', 2);
    TextLCD.replace('ö', 3);
    TextLCD.replace('Å', 4);
    TextLCD.replace('Ä', 5);
    TextLCD.replace('Ö', 6);
BJ
Inlägg: 8185
Blev medlem: 11 april 2007, 08:14:53
Ort: En_stad

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av BJ »

Jag vet inte vad felmeddelandet är, men det är
inte så att du har förväxlat ' bredvid Ä på tangentbordet
med en oskiftad fnutt mellan + och sudd-knappen?
Dom ser likadana ut i Linux mint med Geany eller Leafpad...
Albireo
Inlägg: 73
Blev medlem: 30 november 2019, 00:29:39

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av Albireo »

Använde först "snutten" till höger om "Å" på tangntbordet!
Sedan kopierades lösningen från koden ovan.
Blev ingen skillnad :? !

Nu ser en del av koden ut på följande sätt .:

Kod: Markera allt

    void loop() {
      i = 0;
        
      while (i < strlen(TextLCD))
      { lcd.setCursor(i, 0);    // Pekare på .: Kolumn1 - Rad1
        char pointer = TextLCD[i++];

        if ( pointer == 'å' ) {
           pointer = 1;
        }
        
        lcd.print(pointer);
        delay(500);
      }

      delay(1000);
      lcd.clear();
    }
BJ
Inlägg: 8185
Blev medlem: 11 april 2007, 08:14:53
Ort: En_stad

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av BJ »

Okej.
Vad skriver den som felmeddelande?
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av arvidb »

'å' är två bytes enligt UTF8: c3 a5. Tecknet ryms alltså inte i en char:

Kod: Markera allt

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	char c = 'å';

	printf("%c", c);

	return EXIT_SUCCESS;
}

Kod: Markera allt

$ gcc -Wall utf8-test.c -o utf8-test
utf8-test.c: In function 'main':
utf8-test.c:6:11: warning: multi-character character constant [-Wmultichar]
  char c = 'å';
           ^~~~
utf8-test.c:6:11: warning: overflow in conversion from 'int' to 'char' changes value from '50085' to '-91' [-Woverflow]
Oavsett så kanske ett första steg är att byta namn på variabeln "pointer" till något som inte är lika missvisande? :)
Albireo
Inlägg: 73
Blev medlem: 30 november 2019, 00:29:39

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av Albireo »

Detta fel skapas när programmet kompileras
if ( pointer == 'å' ) {
. . . . . . . . . . . . . . . . . . . . ^~~~ (ett försök att få "taket" att peka under första snutten i 'å'
Körs programmet ignoreras "if-satsen"
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av arvidb »

Men vad säger kompilatorn om vilket fel det är, det vill säga vad är själva felmeddelandet? Det där är ju bara platsen som det blir fel på.
BJ
Inlägg: 8185
Blev medlem: 11 april 2007, 08:14:53
Ort: En_stad

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av BJ »

arvidb:s svar hade jag inte tänkt på. :doh:
Albireo
Inlägg: 73
Blev medlem: 30 november 2019, 00:29:39

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av Albireo »

....\LCD-Test_write.ino:110:25: warning: multi-character character constant [-Wmultichar]

if ( pointer == 'å' ) {

^~~~

Sketch uses 2990 bytes (9%) of program storage space. Maximum is 32256 bytes.
Global variables use 310 bytes (15%) of dynamic memory, leaving 1738 bytes for local variables. Maximum is 2048 bytes.
______________________________________________________________________

Hela programmet!

Kod: Markera allt

/* I2C LCD with Arduino example code. More info: https://www.makerguides.com
       https://www.makerguides.com/character-i2c-lcd-arduino-tutorial/  */
    // Include the libraries:
    // LiquidCrystal_I2C.h: https://github.com/johnrickman/LiquidCrystal_I2C
    
    #include <Wire.h> // Library for I2C communication
    #include <LiquidCrystal_I2C.h> // Library for LCD
    // Wiring: SDA pin is connected to A4 and SCL pin to A5.
    // Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered)
    // LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4); // Change to (0x27,16,2) for 16x2 LCD.
    LiquidCrystal_I2C lcd = LiquidCrystal_I2C(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
    };
    

    // https://www.arduino.cc/en/Reference/VariableDeclaration
    // https://www.arduino.cc/reference/en/language/variables/data-types/string/
    char TextLCD[16] = "å - Bra gjort!";  // Variable type .: String

   /* 
    TextLCD.replace('å', 1);
    TextLCD.replace('ä', 2);
    TextLCD.replace('ö', 3);
    TextLCD.replace('Å', 4);
    TextLCD.replace('Ä', 5);
    TextLCD.replace('Ö', 6);
    */ 
    int i = 0;
    
    void setup() {
      lcd.init();       // Initiate the LCD:
      lcd.backlight();  // Backlight ON:

      lcd.createChar(1, AwithRing);     //å
      lcd.createChar(2, AwithDots);     //ä
      lcd.createChar(3, OwithDots);     //ö
      lcd.createChar(4, BigAwithRing);  //Å
      lcd.createChar(5, BigAwithDots);  //Ä
      lcd.createChar(6, BigOwithDots);  //Ö
    }
    
    void loop() {
      i = 0;
        
      while (i < strlen(TextLCD))
      { lcd.setCursor(i, 0);    // Pekare på .: Kolumn1 - Rad1
        char pointer = TextLCD[i++];

        if ( pointer == 'å' ) {
           pointer = 1;
        }
        
        lcd.print(pointer);
        delay(500);
      }

      delay(1000);
      lcd.clear();
    }
Är det raden .: char TextLCD[16] = "å - Bra gjort!"; som ska hanteras på annat sätt?
ex. String TextLCD = "å - Bra gjort!"; (ingen aning vad som skiljer)
Användarvisningsbild
Icecap
Inlägg: 26105
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av Icecap »

Det är inte alls ovanligt att det inte får finnas program-tecken över ASCII 128 i källkoden.
Lösningen är då att ange värdet i hex.
if ( pointer == 0x<vaddetnuär> ) {
guckrum
Inlägg: 1669
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Svenska tecken på LCD I2C display ( 2x16 ) - Arduino

Inlägg av guckrum »

Observera att kompilatorn ger en bra ledtråd i sitt felmeddelande. Läs felmeddelandena! (I din första post talade du bara om ATT det blev fel.) Felet är alltså att din editor representerar 'ä' med två bytes, kanske via UTF8-kodad unicode, medan din jämförelsesats i koden är på endast en char.
Skriv svar