Pages: [1]   Go Down
Author Topic: Arduino + LCD Smartie - Affichage non compréhensible  (Read 1935 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour à tous,

J'aurais besoin d'une aide pour faire fonctionner correctement le logiciel LCD Smartie en liaison usb avec une carte arduino MEGA.

Pour l'affichage, j'utilise un afficheur 4 x 20 équipé d'un contrôleur HD44780 câblé en 4 bits.

Le code utilisé est le suivant :

Code:
// include the library code:
#include <LiquidCrystal.h>

// these constants won't change.  But you can change the size of
// your LCD using them:
const int numRows = 4;
const int numCols = 20;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 10, 5, 4, 3, 2);
// RS, RW, Enable, 4,5,6,7 (Refer to the back of your LCD for details)


void setup() {
  Serial.begin(19200);
  // set up the LCD's number of rows and columns:
  lcd.begin(numRows, numCols);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("**LCD  SMARTIE**");
  lcd.setCursor(0,1);
  lcd.print("on Arduino");
}

byte serial_getch(){
 
  int incoming; 
  while (Serial.available()==0){}
// read the incoming byte:
  incoming = Serial.read();

  return (byte) (incoming &0xff);
}

void loop(){

  byte rxbyte;
  byte temp;

  rxbyte = serial_getch();

  if (rxbyte == 254) //Matrix Orbital uses 254 prefix for commands
  {
    switch (serial_getch())
    {
    case 66: //backlight on (at previously set brightness)
      // not implemented

      break;
    case 70: //backlight off
      // not implemented
      break;
    case 71:  //set cursor position
      temp = (serial_getch() - 1);  //get column byte
      switch (serial_getch())  //get row byte
      {
        //line 1 is already set up
      case 2:
        temp += 0x40;
        break;
      case 3:
        temp += 0x14;
        break;
      case 4:
        temp += 0x54;
        break;
      default:
        break;
      }
      lcd.command(0b10000000 + temp);
      break;
    case 72:  //cursor home (reset display position)
      lcd.command(2);
      break;
    case 74:  //show underline cursor
      lcd.command(0b00001110);
      break;
    case 75:  //underline cursor off
    case 84:  //block cursor off
      lcd.command(0b00001100);
      break;
    case 76:  //move cursor left
      lcd.command(16);
      break;
    case 77:  //move cursor right
      lcd.command(20);
      break;
    case 78:  //define custom char
      lcd.command(64 + (serial_getch() * 8));  //get+set char address
      for (temp = 7; temp != 0; temp--)
      {
        lcd.print(serial_getch()); //get each pattern byte
      }
      break;
    case 83:  //show blinking block cursor
      lcd.command(0b00001111);
      break;
    case 86:  //GPO OFF
      //implement later
      break;
    case 87:  //GPO ON
      /*temp = serial_getch();
        if (temp == 1)
        {
        GPO1 = GPO_ON;
        }*/
      break;
    case 88:  //clear display, cursor home
      lcd.command(1);
      break;
    case 152: //set and remember (doesn't save value, though)
    case 153: //set backlight brightness
      //not implemented
      break;

      //these commands ignored (no parameters)
    case 35: //read serial number
    case 36: //read version number
    case 55: //read module type
    case 59: //exit flow-control mode
    case 65: //auto transmit keypresses
    case 96: //auto-repeat mode off (keypad)
    case 67: //auto line-wrap on
    case 68: //auto line-wrap off
    case 81: //auto scroll on
    case 82: //auto scroll off
    case 104: //init horiz bar graph
    case 109: //init med size digits
    case 115: //init narrow vert bar graph
    case 118: //init wide vert bar graph
      break;
    default:
      //all other commands ignored and parameter byte discarded
      temp = serial_getch();  //dump the command code
      break;
    }
    return;
  } //END OF COMMAND HANDLER

  //change accented char to plain, detect and change descenders
  //NB descenders only work on 5x10 displays. This lookup table works
  //  with my DEM-20845 (Display Elektronik GmbH) LCD using KS0066 chip.
  switch (rxbyte)
  {
    //chars that have direct equivalent in LCD charmap
    /* case 0x67: //g
      rxbyte = 0xE7;
      break;
      case 0x6A: //j
      rxbyte = 0xEA;
      break;
      case 0x70: //p
      rxbyte = 0xF0;
      break;
      case 0x71: //q
      rxbyte = 0xF1;
      break;
      case 0x79: //y
      rxbyte = 0xF9;
      break;
     */  case 0xE4: //ASCII "a" umlaut
    rxbyte = 0xE1;
    break;
  case 0xF1: //ASCII "n" tilde
    rxbyte = 0xEE;
    break;
  case 0xF6: //ASCII "o" umlaut
    rxbyte = 0xEF; //was wrong in v0.86
    break;
  case 0xFC: //ASCII "u" umlaut
    rxbyte = 0xF5;
    break;

    //accented -> plain equivalent
    //and misc symbol translation
  case 0xA3: //sterling (pounds)
    rxbyte = 0xED;
    break;
    /* case 0xB0: //degrees symbol
      rxbyte = 0xDF;
      break;
     */  case 0xB5: //mu
    rxbyte = 0xE4;
    break;
  case 0xC0: //"A" variants
  case 0xC1:
  case 0xC2:
  case 0xC3:
  case 0xC4:
  case 0xC5:
    rxbyte = 0x41;
    break;
  case 0xC8: //"E" variants
  case 0xC9:
  case 0xCA:
  case 0xCB:
    rxbyte = 0x45;
    break;
  case 0xCC: //"I" variants
  case 0xCD:
  case 0xCE:
  case 0xCF:
    rxbyte = 0x49;
    break;
  case 0xD1: //"N" tilde -> plain "N"
    rxbyte = 0x43;
    break;
  case 0xD2: //"O" variants
  case 0xD3:
  case 0xD4:
  case 0xD5:
  case 0xD6:
  case 0xD8:
    rxbyte = 0x4F;
    break;
  case 0xD9: //"U" variants
  case 0xDA:
  case 0xDB:
  case 0xDC:
    rxbyte = 0x55;
    break;
  case 0xDD: //"Y" acute -> "Y"
    rxbyte = 0x59;
    break;
    /* case 0xDF: //beta  //mucks up LCDSmartie's degree symbol??
      rxbyte = 0xE2;
      break;
     */  case 0xE0: //"a" variants except umlaut
  case 0xE1:
  case 0xE2:
  case 0xE3:
  case 0xE5:
    rxbyte = 0x61;
    break;
  case 0xE7: //"c" cedilla -> "c"
    rxbyte = 0x63;
    break;
  case 0xE8: //"e" variants
  case 0xE9:
  case 0xEA:
  case 0xEB:
    rxbyte = 0x65;
    break;
  case 0xEC: //"i" variants
  case 0xED:
  case 0xEE:
  case 0xEF:
    rxbyte = 0x69;
    break;
  case 0xF2: //"o" variants except umlaut
  case 0xF3:
  case 0xF4:
  case 0xF5:
  case 0xF8:
    rxbyte = 0x6F;
    break;
  case 0xF7: //division symbol
    rxbyte = 0xFD;
    break;
  case 0xF9: //"u" variants except umlaut
  case 0xFA:
  case 0xFB:
    rxbyte = 0x75;
    break;
  default:
    break;
  }

  lcd.print(rxbyte);  //otherwise a plain char so we print it to lcd
  return;


}


Le problème est que je reçois bien des informations sur l'afficheur mais elles sont sous forme numériques. Je n'ai que des chiffres et aucune lettre.

Le code utilisé est issue d'exemples sur internet et il fonctionne.

Je ne vois pas où le problème se pose.

Merci d'avance pour votre aide
Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Es tu sûr de ton câblage de l'écran LCD sur l'Arduino ?
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Normalement oui.

Le texte dans la partie setup s'affiche correctement, j'en déduis que le câblage est bon à moins qu'il y ai une subtilité avec la réception par le port série.

D'ailleurs l'affichage suit une logique. Les espaces sont représentés par le chiffre 32 et les autres lettres par d'autres chiffres.

J'ai fais le test en écrivant qu'un caractère sur LCD Smartie.

« Last Edit: April 14, 2012, 08:59:08 am by ChefChaudard » Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ca voudrait dire que tu reçoit les caractères à afficher non pas directement en octets représentant leur code ASCII, mais un flux d'octet lui même reconvertit en chaine ASCII
En gros pour afficher le caractère "A" tu devrais recevoir un octet de valeur 65 mais tu reçoit les caractères "6" et "5".

Peut être est-ce un problème de configuration du logiciel LCD Smartie ?
Ou bien est-tu sur que le code Arduino que tu as récupéré correspond bien à la version courante du protocole utilisé par LCD Smartie ?
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C'est exactement le problème que je rencontre. Effectivement le A apparait sous le caractère 65.

J'utilise le plugin matrix.dll qui permet d'envoyer les informations à l'arduino par l'USB.

Cela dit lorsque je change de protocole, c'est le même problème.

Les infos retenues ont été prises ici http://www.milesburton.com/LCD_Smartie_Powered_By_Arduino_Liquid_Crystal_library
et ici pour le paramétrage du logiciel http://waihung.net/lcd-smartie-through-arduino/

Pour moi, j'ai les bonnes versions comme pour l'exemple.

Le seul changement que j'ai fais et la vitesse de transmission. Elle est à 19200 au lieu de 9600.

Je sens qu'il y a une subtilité avec le code arduino. A tout hasard j'ai essayé avec un IDE 018 et c'est le même résultat

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai trouvé une solution. J'ai trouvé un autre code.

Par contre par curiosité, j'aimerais comprendre ce qui n'allait pas

Voici le nouveau code :

Code:
/*
 arduino-matrixorbital.ino
 A software emulator for Matrix Orbital character display commands on Arduino.
 
 V1.5 28/12/2011
 Added fixes by yosoyzenitram, prettified code a little and added all Matrix Obrital commands for display model LK204-25.
 
 V1.0 6/2/2010
 Coded by giannoug <giannoug@gmail.com>
 Based on code by nuelectronics <http://www.nuelectronics.com/>
 
 You can use whatever screen size you want, but you will
 have to make proper adjustments to both this file and at
 LCDSmartie's configuration menu or whatever program you
 might use.
 
 Matrix Orbital LK204-25 manual (for command reference):
 http://www.matrixorbital.ca/manuals/LK_Series/LK204-25/LVK204-25%20%28Rev1.3%29.pdf
 
 The circuit (make sure to power the LCD):
 * LCD RS pin to digital pin 12
 * LCD E pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD Ve pin (contrast) to digital pin 6
 
 */

#include <LiquidCrystal.h>

// You can define your own pins here.
#define RS 2
#define E  22
#define D4 23
#define D5 24
#define D6 25
#define D7 26
#define BR 6

#define VERSION 1

#define GPO1 8 // Not yet implemented. (pg. 18 of the manual)

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

void setup() {
  Serial.begin(19200); // Default baudrate.
  lcd.begin(20, 4); // Change this for other screen sizes.

  analogWrite(BR, 0); // Set maximum brightness.

  lcd.print("Arduino");
  lcd.setCursor(1, 1);
  lcd.print("Matrix Orbital!");
}

void loop() {
  byte rxbyte = serial_getch(); // Command
  byte temp; // Parameter

  if (rxbyte == 254) {
    switch (serial_getch()) {
    case 71: // Set cursor position (2 parameters, column, row)
      lcd.setCursor(serial_getch() - 1, serial_getch() - 1);
      break;
    case 72: // Cursor home (doesn't clear the screen!)
      //lcd.home();
      lcd.setCursor(0,0);
      break;
    case 74: // Underline cursor on
      lcd.cursor();
      break;
    case 75: // Underline cursor off
      lcd.noCursor();
      break;
    case 83: // Block cursor on
      lcd.blink();
      break;
    case 84: // Block cursor off
      lcd.noBlink();
      break;
    case 76: // Move cursor left
      lcd.command(16);
      break;
    case 77: // Move cursor right
      lcd.command(20);
      break;
    case 78: // Define custom character (2 parameters, id, data)
      lcd.command(64 + (serial_getch() * 8));
      for (temp = 7; temp != 0; temp--) {
        lcd.print(serial_getch());
      }
      break;
      //case 35: // Read serial number
      //case 36: // Read version number
    case 54: // Read version number
      Serial.print(VERSION);
      break;
    case 55: // Read module type
      Serial.print(9); // 9 for LK204-25
      break;
    case 80: // Set contrast (1 parameter, contrast)
      analogWrite(BR, 0xFF-serial_getch());
      break;
    case 81: // Auto scroll on
      lcd.autoscroll();
      break;
    case 82: // Auto scroll off
      lcd.noAutoscroll();
      break;
    case 86: // General Purpose Output off (1 parameter, number)
      //temp = serial_getch();
      //if (temp == 1) {
      //  digitalWrite(GPO1, LOW);
      //}
      break;
    case 87: // General Purpose Output on (1 parameter, number)
      //temp = serial_getch();
      //if (temp == 0) {
      //  digitalWrite(GPO1, HIGH);
      //}
      break;
    case 88: // Clear screen
      lcd.clear();
      break;
    case 35: // Place large number
    case 38: // Poll key presses
    case 51: // Change I2C slave address (1 parameter, address)
    case 57: // Change baud rate (1 parameter, baud rate)
    case 59: // Exit flow-control mode
    case 61: // Place vertical bar (2 parameters, column, length)
    case 64: // Change the startup screen
    case 65: // Auto transmit keypresses on
    case 67: // Auto line wrap on
    case 68: // Auto line wrap off
    case 66: // Backlight on (1 parameter, minutes)
    case 69: // Clear key buffer
    case 70: // Backlight off
    case 79: // Auto transmit keypress off
    case 85: // Set debounce time (1 paramater, time)
    case 96: // Auto repeat mode off
    case 152: // Set and save brightness (1 parameter, brightness)
    case 153: // Set backlight brightness (1 parameter, brightness)
    case 104: // Initialize horizontal bar
    case 109: // Initialize medium number
    case 110: // Initialize lange numbers
    case 111: // Place medium numbers
    case 115: // Initialize narrow vertical bar
    case 118: // Initialize wide vertical bar
    case 124: // Place horizontal bar graph (4 parameters, column, row, direction, length)
    case 126: // Set auto repeat mode (1 parameter, mode)
    case 145: // Set and save contrast (1 parameter, contrast)
    case 160: // Transmission protocol select (1 parameter, protocol)
    case 192: // Load custom characters (1 parameter, bank)
    case 164: // Setting a non-standart baudrate (1 parameter, speed)
    case 193: // Save custom character (3 parameters, bank, id, data)
    case 194: // Save startup screen custom characters (2 parameters, id, data)
    case 195: // Set startup GPO state (2 parameters, number, state)
    case 200: // Dallas 1-Wire
      switch (serial_getch()) {
      case 1: // Dallas 1-Wire transaction (6 parameters, flags, send, bits, receive, bits, data)
      case 2: // Search for a 1-Wire device
      default:
        break;
      }
      break;
    case 213: // Assign keypad codes
    default:
      /* All other commands are ignored
       and parameter byte is discarded. */
      temp = serial_getch();
      break;
    }
    return; // Stop and start again.
  }

  // Otherwise its a plain char so we print it to the LCD.
  lcd.write(rxbyte);
}

/*
 * Waits for a byte to be available, reads and returns it.
 */
byte serial_getch() {
  while (Serial.available() == 0);

  return Serial.read();
}


Les caractères apparaisent
Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Je viens de monter la manip et le problème est là
Code:
 lcd.print((char)rxbyte);  //otherwise a plain char so we print it to lcd

Le sketch a été développé pour une version différente de l'IDE Arduino dans lequel la bibliothèque "Print" dont dérive "LiquidCrystal" avait une version différente de la fonction print()

Dans la version précédante print( byte ) était équivalente de print(char )
Alors que dans l'IDE 1.0, print( byte ) est devenu équivalent de print( int )
Donc le nouveau comportement est d'afficher la valeur de rxbyte plutot que le caractère représenté.

En ajoutant un cast (char)rxbyte on force l'affichage de rxbyte comme le caractère qu'il représente plutot que comme sa valeur (ie le code ASCII)

EDIT: Je viens de voir le nouveau code que tu as trouvé. Il utilise .write au lieu de .print
Or dans le code de Print.cpp, on trouve que print(char c) effectue un write(c)
C'est pour cela que le nouveau code marche aussi
« Last Edit: April 14, 2012, 12:00:17 pm by barbudor » Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci beaucoup pour cette réponse.

Naïvement, j'ai voulu intégrer cette fonctionnalité dans mon projet mais ça ne fonctionne pas.

Je suis entrain de réaliser un boitier de PC évolué. Il comporte entre autre un écran LCD permettant de paramétrer la tour, d'afficher les températures, les commandes de ventilateurs, etc. Toute cette partie est gérée par l'arduino.

Je suis tombé par hasard sur LCD Smartie et je me suis dis que ce serait une bonne idée de renvoyer également des informations systèmes en plus des autres.

Je pensais mettre tout le code servant à afficher les données du PC dans un switch case ou une condition if mais il s'avère que le programme ne reconnait plus les codes ainsi et plante à la compilation. Lorsque je fais un jeu de taquin de programmation, le programme ne dépasse plus le setup.

De plus je m’aperçois que la synchronisation série n'est pas robuste. Si je ferme LCD Smartie et que je le ré-ouvre, il y a de forte chance que le programme s'arrête au Setup.

Si je redémarre l'arduino, ca me fait bien souvent la même chose.

A priori, la meilleur solution est de mettre une carte arduino dédié à un LCD et alimentée par le port USB pour est synchronisé avec les signaux.

Je vais faire quelques tests en ce sens.

Merci encore pour ton aide !
Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Je suis pas sur de comprendre mais il me semble que tu veux utiliser l'écran de 2 manières différentes dans le temps :
1) gérer les menus de l'application pour laquelle tu utilises un Arduino à l'origine
2) quand il ne sert pas pour l'usage ci-dessus, tu veux l'utiliser avec LCDSmartie

Si c'est çà, çà devrait pouvoir marcher.
Il faut que tu gère 2 cas dans ta loop et que tu fasse attention en passant d'un mode à l'autre.
Notamment quand tu reviens au mode Smartie, il faut
- vider le buffer série pour ignorer ce qui traine dedans qui est probablement incomplet
- te re-synchroniser sur l'affichage d'une nouvelle page. Peut être attendre la suite d'octets 254 (préfixe de commande) et 88 (commande effacement d'écran)

Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oui c'est ca. Afficher soit les informations issues de la carte arduino soit les informations issues du PC. J'ai mis le code dans une fonction if et à la compilation ça me mettais que des éléments n'était pas définis.

Après je t'avouerais que je maitrise pas du tout le code qui permet de faire l'affichage du PC et que les commandes utilisés sont assez obscures pour moi.

Je comprends pas que mettre tout le code de la fonction loop dans une fonction switch ou if génère des erreurs de compilation et que des commandes ne soient pas reconnues car non déclarées
Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ça sent les accolades fermantes manquantes.
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Pages: [1]   Go Up
Jump to: