LCD12864SPI

Bonjour,
Toujours pour le fun, je suis tombé sur un montage du type "Speedométre GPS" avec un affichage en gros caractéres sur un LCD 12864 et utilisation de la bibliothèque "openGLCD".

L'ennui c'est que le concepteur utilise un montage avec un câblage complet du LCD soit 20 liaisons !!!
J'avais réalisé il y a quelques temps une platine permettant une liaison du type SPI avec seulement 5 fils sur ce LCD et bien décidé à utiliser cette facilité je me suis lancé à la recherche d'une bibliothèque ad hoc. La librairie u8g fonctionne très bien mais je n'ai pas trouvé comment modifier le sketch pour l'utiliser. J'en ai finalement trouvé une "LCD12468SPI" qui fonctionne.

/*
LCD  Arduino
PIN1 = GND
PIN2 = 5V
RS(CS) = 8; 
RW(SID)= 9; 
EN(CLK) = 3;
PIN15 PSB = GND;
*/

#include "LCD12864RSPI.h"

void setup()
{
  LCDA.initialise();
  delay(100);
}

int i = 1;
void loop()
{
  LCDA.clear();
  delay(10);
  LCDA.printf(0, 0, "This is an integer %d, which will be incremented.", i);
  delay(1000);
  i++;
}

Il existe manifestement au moins deux librairies avec des variables du genre "Initialise" ou "initialise" et elles ne se parlent pas !!!!
j'ai tenté de l'implanter sur le code du speedometre et tout avait l'air d'aller bien jusqu'à la ligne 73 où je n'ai pas trouvé comment remplacer:

"GLCD.DrawBitmap(Number0, pos, 0);" par son équivalent avec "LCD12468SPI"

#include <math.h> //math library to use for round function
#include "TinyGPS.h" //GPS module library
#include <openGLCD.h> // LCD library
TinyGPS gps; //create a gps object

float fLat, fLong; //floats for longitude and latitude; will be used to determine whether the GPS data is up to date or not
unsigned long fix_age; // returns +- latitude/longitude in degrees

int digit1, digit2, digit3; //integers to hold the three digits making up the speed
int iSpeed; //integer to hold the speed value from the GPS module

void setup()
{
  Serial.begin(9600); //start the serial communication
  // initialise the library, non inverted writes pixels onto a clear screen
  GLCD.Init(NON_INVERTED);
}

void loop()
{
  while (Serial.available())
  {
    //incoming serial data from GPS
    int c = Serial.read();
    if (gps.encode(c))
    {
      // process new gps info here, in case you want to display more details   
    }
  }
  gps.f_get_position(&fLat, &fLong, &fix_age); //get longitude and latitude, used to find if data is up to date
  if (fix_age == TinyGPS::GPS_INVALID_AGE || fix_age > 2000)
  {
    //data was not updated for some time, assume that GPS connection is lost
    iSpeed = 0;
  }
  else
  {
    //GPS connection is up to date, get the speed information, and round it to closest integer value
    iSpeed = round(gps.f_speed_kmph()); // speed in km/h
  }

  //when not moving, the GPS module will still read some "speed" value, not necessarily zero
  //in that case assume the car is not moving; only display values greater than 2
  if (iSpeed == 1) iSpeed = 0;
 
  displaySpeed(iSpeed); //call function to display the speed, digit by digit
}


void displaySpeed(int iSpeed)
{
    //"simple" maths to extract each digit value
    digit1 = iSpeed / 100;
    iSpeed = iSpeed - (digit1 * 100);
    digit2 = iSpeed / 10;
    digit3 = iSpeed - (digit2 *10); 

    //display "blank" bitmap when necessary, instead of number zero
    if (digit2 == 0 && digit1 == 0) digit2 = -1; //digit 2 is blank
    if (digit1 == 0) digit1 = -1; //digit 1 is blank

    //call function to display each digit, at their required position
    drawDigit(digit1, 0);
    drawDigit(digit2, 45);
    drawDigit(digit3, 90);
}

void drawDigit(int digit, int pos)
{
  switch (digit)
  {
    case 0:
    GLCD.DrawBitmap(Number0, pos, 0);
    break;
    case 1:
    GLCD.DrawBitmap(Number1, pos, 0);
    break;
    case 2:
    GLCD.DrawBitmap(Number2, pos, 0);
    break;
    case 3:
    GLCD.DrawBitmap(Number3, pos, 0);
    break;
    case 4:
    GLCD.DrawBitmap(Number4, pos, 0);
    break;
    case 5:
    GLCD.DrawBitmap(Number5, pos, 0);
    break;
    case 6:
    GLCD.DrawBitmap(Number6, pos, 0);
    break;
    case 7:
    GLCD.DrawBitmap(Number7, pos, 0);
    break;
    case 8:
    GLCD.DrawBitmap(Number8, pos, 0);
    break;
    case 9:
    GLCD.DrawBitmap(Number9, pos, 0);
    break;
    default:
    GLCD.DrawBitmap(NumberBlank, pos, 0);
    break;
  }
}

Si quelqu'un a une idée j'en serais trés heureux bien sûr.
Merci.

Je n'arrive pas à trouver la bibliothèque LCD12864RSPI : peux-tu poster un lien ?

Bonjour Lesept,
En fait, j'ai trouvé deux exemples qui sont:

http://lcd12864r-arduino.blogspot.fr/...... Qui fonctionne chez moi !!
http://www.adeept.com/blog/lcd12864-spi-communication-for-arduino_b0028.html

Le second à l'air de sortir du premier bien que les termes soient sensiblement différents. Initialise au lieu initialise, LCDA.CLEAR au lieu de LCDA.clear !!!! Mystères de l'informatique (je plaisante)

Je pense que l'origine de l'affaire vient de Dfrobot avec son backpak SPI spécialement conçu pour le LCD 12864.

Lien forum Arduino :

http://forum.arduino.cc/index.php?topic=152045.0

Dépôts de Github:

Autres liens:

http://idea-dev-storage.de/spi-lcd-module-arduino/ .....Fonctionne chez moi !!!
LCD12864RSPI.h | searchcode

Voilou !!!
Je ne sais pas si tu vas trouver de quoi faire, mais il n'y a pas grand chose. Mais c'est intéressant de faire fonctionner cet écran sur 5 fils au lieu de 20. NON ?
Merci
Christian

Je vois que c'est compliqué. !!!
J'ai un peu ..... tout petit peu avancé et j'ai une librairie qui m'a l'air correcte.

class LCD12864RSPI {
	typedef unsigned char uchar;

public:
	LCD12864RSPI();
	
	void initialise(void);         /* Initialize the screen. */
	void delayns(void);            /* Delay dalayTime amount of microseconds. */
	
	void writeByte(int data);      /* Write byte data. */
	void writeCommand(int cmd);    /* Write command cmd into the screen. */
	void writeData(int data);      /* Write data data into the screen. */
	void moveCursor(int X, int Y); /* Move cursor to 0-based column X and 0-based row Y as the starting point of the next display. */

	void clear(void);			                    /* Clear the screen. */
	void clearRow(int Y);                           /* Clear the y-th row (y is 0-based) */
	void fillBlock(int X, int Y, uchar c, int len); /* Fill block starting from 0-based column X and 0-based row Y with the character c. The filled block is of length len.*/
	void clearBlock(int X, int Y, int length);      /* Clear the block starting from 0-based column X and 0-based row Y. The cleared block is of len byte long. */

	void printf(int X, int Y, char *fmt, ... );         /* Display formated string at 0-based column X and 0-based row Y. The formatted string should not be longer than 64 characters. */
	void displayString(int X,int Y,uchar *ptr,int dat); /* Display string ptr (with length len) at 0-based column X and 0-based row Y. */
	void displaySig(int M,int N,int sig);               /* Display a single character sig at 0-based column X and 0-based row Y. */
	void displayInteger(int X, int Y, int number);      /* Display integer number at 0-based column X and 0-based row Y. */
	
	void drawFullScreen(uchar *p);  /* Display the full screen using data from p. */
	void drawImage1(uchar img[]);   /* Display image */
	void drawImage2(uchar img[]);   /* Display image */

	int delayTime;    /* Delay time in microseconds. */
	int DEFAULTTIME;  /* Default delay time. */

	static const int latchPin = 8;
	static const int clockPin = 3; 
	static const int dataPin  = 9;

Avec cela je dois pouvoir afficher un gros chiffre avec "displayImage" ou "displayString"

Merci pour l'aide.

Je viens de trouver ça : tu devrais t'en inspirer car Nick Gammon est une pointure de chez pointure.Il implémente ton LCD en I2C ou en SPI. Je n'ai pas regardé en détail, car je n'ai pas le temps, mais je te laisse faire...

Bon, y'a peut-être un peu de taf à la clé...