Aller au contenu


Photo
- - - - -

Réaliser une bibliothèque pour Arduino.


  • Veuillez vous connecter pour répondre
24 réponses à ce sujet

#1 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 17 mars 2016 - 11:06

Bonjour chers Robonautes,

Il y a des lustres que je cherche vainement à me créer une (des) bibliothèque qui serait acceptée par l’I.D.E. Naturellement, j’ai recherché sur la toile les informations indispensables.

Parmi les meilleurs didacticiels que j’ai parcouru, (Meilleur n’a qu’un sens restreint à mes appréciations personnelles bien entendu et n’obère en rien la qualité de tous les autres.) j’ai suivi pas à pas le didacticiel de Mr Philippe-RX. Les explications me sont globalement très accessibles, et ça va sans dire, j’ai proposé au compilateur les éléments concernés.

Le compilateur refuse le code et me signale une erreur dans son langage qui pour moi reste incompréhensible :

Morse/Morse.h:4:22: fatal error: WProgram.h: No such file or directory

 #include "WProgram.h"

Je dois certainement passer à coté d’un détail important, mais je ne trouve pas.

Avez-vous une idée à me soumettre S.V.P ?

Merci d’avance pour d’éventuelles réponses en espérant ne pas avoir alourdi le forum par un sujet qui n’est pas directement lié à la robotique : Nulentout.



#2 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 17 mars 2016 - 01:28

Salut !

De mémoire, WProgram est l'ancien nom des bibliothèques Arduino ; il faut utiliser Arduino.h désormais. Par ailleurs, #include "nomHeader" indique que le fichier .h est dans le même dossier que ton fichier source. Comme tu inclues les fichiers standards d'Arduino (fournis avec l'IDE normalement), il faut utiliser #include <Arduino.h> pour que le compilateur cherche au bon endroit.

(source : http://stackoverflow.com/questions/21593/what-is-the-difference-between-include-filename-and-include-filename)
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#3 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 17 mars 2016 - 04:08

Tout est dit !

 

Si tu veux un exemple de bibliothèque Arduino, regarde dans le zip de cette page : http://www.robot-maker.com/forum/topic/6535-bibliotheques-arduino/?p=42570&fromsearch=1#entry42570


Mon site internet : http://ferdinandpiette.com/


#4 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 20 mars 2016 - 09:29

Merci pour ces informations précieuses les copains, je vais aller "fouiller" sur ces liens.

 

Après différents essais, et grâce à vos suggestions et informations, c'est fait, un premier canevas de bibliothèque fonctionne.

Maintenant je vais tenter de créer une vraie bibliothèque. (Pour un afficheur LCD TG12864H3-05A).

 

Problème en partie RÉSOLU, c'est déjà très bien ...

 

J'ai malgré tout des problèmes latents :

la directive

#include <Arduino.h> est acceptée.

MAIS utiliser delay(100); par exemple "plante le programme".

 

et
#include <EEPROM.h>

provoque un message d'erreurs. Pourtant je crois avoir compris qu'avec les délimiteurs < et > le compilateur devrait trouver le dossiers;

 

Gnarf gnarf gnarf, m'en veut ce compilateur !

Aurriez-vous une idée les copains ?

 

Autre interrogation : Quelle est l'utilité intrinsèque des déclarations Private et Public ?



#5 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 29 mars 2016 - 08:30

Bonjour les amis,

Les deux problèmes cités sont résolus :

Mon répertoire pour Arduino était <! ARDUINO>. Comme j'avais un doute, maintenant j'ai réinstallé dans <ARDUINO>.

Surtout, je suis passé de la version 1.6.1 à la version 1.6.8 de l'IDE.

Maintenant, tout rentre dans l'ordre sauf que :

Le compilateur n'aime plus du tout ma procédure d'affichage de texte. Il me fait le message d'erreur suivant :
warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
à chaque appel du type LCD.Affiche_TEXTE("  BONjour ...");

Les caractères ordinaires sont correctement affichés, par contre les caractères spéciaux comme certains accentués ne sont plus traités correctement.

Vous avez une idée  s'il vous plait ?



#6 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 29 mars 2016 - 12:14

Salut,

 


J'ai malgré tout des problèmes latents :

la directive

#include <Arduino.h> est acceptée.

MAIS utiliser delay(100); par exemple "plante le programme".

Et si tu mettais ton code ici ? Sinon, on risque pas de pouvoir te répondre ;)

 

 

#include <EEPROM.h>

provoque un message d'erreurs. Pourtant je crois avoir compris qu'avec les délimiteurs < et > le compilateur devrait trouver le dossiers;

 

Gnarf gnarf gnarf, m'en veut ce compilateur !

Aurriez-vous une idée les copains ?

Pareil, file nous le code et dis nous quels sont les messages d'erreurs !

Les délimiteurs <> permettent de rechercher la bibliothèque dans les dossiers d'installation de ton compilateur directement (bibliothèques de bases).

Les délimiteurs "" quand à eux permettent de rechercher un fichier directement dans le dossier de ton projet.

 

 

Autre interrogation : Quelle est l'utilité intrinsèque des déclarations Private et Public ?

Lorsque tu déclares une classe, tu peux déclarer des attributs (variables) et des méthodes (fonctions) publiques ou privés (ou protégés aussi).

Lorsque tu déclares un attribut publique, tu peux y accéder en dehors de l'objet. S'il est privé, tu ne peux y accéder que dans une méthode intrinsèque à l'objet.

La bonne pratique impose de définir tous les attributs en privé afin que l'utilisateur de la bibliothèque ne puisse pas modifié les valeurs des variables à sa guise sans passer par une méthode prévu à cet effet. C'est ce que l'on appelle : respecter l'encapsulation.

 

Petit exemple basique :

#include <stdio>

class MaClasse {
    private:
        int monAttribut;        // monAttribut est privé
    public:
        MaClass(int);
        ~MaClass();
        int getMonAttribut();
        void setMonAttribut(int);
        void afficher();
};

MaClass::MaClass(int valeur) {
    std::cout << "Création d'une nouvelle instance de MaClass" << std::endl;
    this->setMonAttribut(value);
}

MaClass::~MaClass() {}

int MaClass::getMonAttribut() {
    // J'accède à monAttribut car je suis dans une méthode de la classe MaClass
    return this->monAttribut;
}

void MaClass::setMonAttribut(int value) {
    // J'accède à monAttribut car je suis dans une méthode de la classe MaClass
    this->monAttribut = value;
}

void main(void) {
    MaClass monObjet(42);
    int valeur;
    valeur = monObjet.getMonAttribut();    // Ok, ça fonctionne
    //valeur = monObjet.monAttribut;    // Erreur de compilation car monAttribut est privé
    std::cout << "La valeur de 'monAttribut' de monObjet est " << valeur << std::endl;
}

 

Le compilateur n'aime plus du tout ma procédure d'affichage de texte. Il me fait le message d'erreur suivant :

warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
à chaque appel du type LCD.Affiche_TEXTE("  BONjour ...");

Les caractères ordinaires sont correctement affichés, par contre les caractères spéciaux comme certains accentués ne sont plus traités correctement.

Vous avez une idée  s'il vous plait ?

Pareil, met nous le code pour que l'on puisse comprendre le problème.

Mais à vu de nez, c'est tout à fait normal.

Le compilateur interprète " BONjour ..." comme un pointeur constant sur chaine de caractère alors que ta fonction doit surement attendre autre chose (un objet string ?).

La conversion est possible, mais le compilateur t’avertis que maintenant, chaque caractère est codé sur un 'char', c'est à dire sur 8bits. Pour décoder et afficher le caractère, c'est donc la table ASCII qui sera utilisé.

Et dans la table ASCII, il n'y a que 128 caractères possibles (ou 256 (2^8) pour la table ASCII étendue), donc pas les caractères spéciaux.


Mon site internet : http://ferdinandpiette.com/


#7 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 30 mars 2016 - 10:25

Bonjour les Copains.

Le code ASCII est un "ami" depuis plus de 50 ans, je connais assez bien.

En fait, on peut y loger des caractères spéciaux.

Par exemple pour les codes 126 et 127 qui restent libres.

Et puis quand on réalise une table de caractère, on peut "tricher".

Par exemple je me passe plus facilement du \ que du é, du ^ que du à.

Le problème vient de la façon dont sont "récupérés" ces codes, elle varie semble t'il d'une version à l'autre du compilateur.

Je vais revoir et analyser tout ça.

Quoi qu'il en soit, merci pour ta réponse, c'est toujours une piste à explorer.



#8 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 30 mars 2016 - 02:57

Tu nous fais voir ton code ?


Mon site internet : http://ferdinandpiette.com/


#9 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 30 mars 2016 - 06:00

Oui, si tu le désires je la posterai, mais la bibliothèque est assez conséquente et je ne sais pas mettre des balises.

En fait, entre ton message et celui-ci j'ai résolu tous mes problèmes, tout fonctionne correctement.

1) Je suis passé sur conseil d'internautes à la version 1.7.9 de l'IDE.

2) Il suffit d'ajouter aussi un #include <EEPROM.h> dans le programme.ino qui utilise ma bibliothèque et tout fonctionne parfaitement.

naturellement si par curiosité tu désires voir le code, ce sera avec plaisir.

Quoi qu'il en soit, entre tous les conseils et idées que j'ai obtenu ici et sur le site français d'Arduino, la solution a fini par émerger.

Je tiens donc à tous vous remercier.



#10 Jan

Jan

    Webmaster

  • Membres
  • PipPipPipPipPip
  • 4 747 messages
  • Gender:Male
  • Location:Rhône Alpes

Posté 30 mars 2016 - 07:08

Oui n'hésites pas à poster ta solution ici ça pourra en aider beaucoup qui passeront par là.

 

Si les balises "code" ne sont pas bien insérées nous modifierons ton message pour le rendre plus lisible.

 

Tu peux également mettre un fichier txt attaché à ton message...



#11 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 31 mars 2016 - 10:18

Bonjour tout le monde,

Voici le code actuel de ma bibliothèque :

/* Bibliothèque personnelle de FE6AAE pour l'afficheurLCD  ST7565 LCD à rétroéclairage tricolore.
   cette bibliothèque a été développée et mise au point avec la version 1.7.9 de l'IDE.
   Le choix de l'ordre des identificateurs pour les broches n'est pas innocent :
      • La LED Arduino 13 est laissée "libre utilisateur".
      • Sept broches consécutives seront dédiées à l'afficheur "juste en dessous" de LED 13 donc de 6 à 12.
      • Les trois broches voisines 9, 10 et 11 permettent de faire de la PWM pour pouvoir moduler les couleurs.     
   ATTENTION : Il faudra impérativement déclarer #include <EEPROM.h> dans le programme utilisateur.   */

#ifndef PERSO_ST7565_h  // Si LCD_ST7565 n'est pas défini,
#define PERSO_ST7565_h  // On le défini ici.

#include <Arduino.h> // Uniquement déclaré ici car .ccp utilise LCD_ST7565_h donc toutes ses déclarations.
#include <EEPROM.h>

class PERSO_ST7565{

 private :
 // CS est placée directement sur GND ce qui économise une déclaration et une E/S.
 byte RST, A0, SCLK, Retro_Bleu, Retro_Rouge, Retro_Vert, SID; // Identificateurs pour désigner les broches  
 // Déclarer les variables réservées pour la bibliothèque :
 boolean SURbrillance;
 byte Colonne, Secteur; // Positionsur l'écran du prochain "octet vertical" qui sera "écrit".
 byte OCTET, BIT, PAGE;
 byte PosX, PosY; // Coordonnées d'écriture d'un texte.
 int PTR; // Pointeur dans la MEMOIRE;
 int PTR_ASCII;
 byte MEMOIRE[1024];
    
 public :
 // Constructeur : Créer une instance matérielle de l'afficheur personnalisée : 
 PERSO_ST7565(byte broche_RST, byte broche_A0, byte broche_SCLK, byte Retro_eclairage_Bleu, byte Retro_eclairage_Rouge, byte Retro_eclairage_Vert, byte broche_SID);
   
 // Déclarer les procédures et les fonctions de la bibliothèque :
 void Envoyer_une_COMMANDE(byte OCTET);
 void Envoyer_une_DONNEE(byte OCTET);
 void Envoyer_un_octet(byte OCTET, boolean commande);
 void Contraste(byte Contraste);
 void Afficheur_en_veille();
 void Afficheur_en_service();
 void Surbrillance(boolean);
 void Remplir_et_affiche_Ecran(byte OCTET);
 void Effacer_Ecran();
 void Afficher_MEMOIRE();
 void Blancking_Ecran();
 void Positionne_curseur(byte X, byte Y);
 void Impose_PAGE(byte Page);
 void Impose_COLONNE(byte COLONNE);
 void MAJ_PTR();
 void Inverser_ecran();
 //================================== Instructions GRAPHIQUES ====================================
 void PIXEL(int X, int Y, boolean Allume);
 void LIGNE(int x, int y, int X, int Y,boolean Allume);
 void RECTANGLE_plein(int x, int y, int X, int Y,boolean Allume);
 void CADRE(int x, int y, int X, int Y,boolean Allume);
 void Trace_un_point(int X, int Y, int R, int Angle, boolean Allume);
 void CERCLE(int X, int Y, int R, boolean Allume);
 void ARC(int X, int Y, int R, int Angle_debut, int Angle_fin, boolean Allume);
 void ELLIPSE(int X, int Y, int RX, int RY, boolean Allume);
 //================================= Instructions TEXTUELLES ====================================
 void Decale_ECRAN();
 void Decale_MEMOIRE();
 void Caractere(byte ASCII, boolean Allume);
 void Affiche_TEXTE(char TEXTE[]);
 void Affiche_NOMBRE(float VALEUR, byte Virgule);
 void CRLF();
 void HOME();
 void CURSEUR(byte X, byte Y);
 };
    
#endif // Fin du "if".

Ainsi que le développement :

/* Bibliothèque personnelle (FE6AAE) pour l'afficheur LCD ST7565 */

#include "PERSO_ST7565.h"

// Ci-dessous : Les commandes "utilisateur" reconnues par l'électronique de l'afficheur.
#define Contraste_Dynamique B10000001 // Passer en mode de contraste dynamique. Doit être
																			// suivi de la valeur entre 32 et 41. (0 à 63 dans la doc.)
#define Vertical_Normal    B11001000  // Balayage vertical normal.  (Haut vers Bas)
#define Vertical_Inverse   B11000000  // Balayage vertical inversé. (Bas vers Haut)
#define Horizontal_Normal  B10100000  // Balayage horizontal normal.  (Gauche vers Droite)
#define Horizontal_Inverse B10100001  // Balayage horizontal inversé. (Droite vers Gauche)
#define Allume_Tout        B10100101  // Allume tous les points.
#define Retour_mode_normal B10100100  // Retour au mode normal.
#define Ecran_Normal       B10100110  // Écriture "noire" sur fond clair". (Si afficheur de type "positif".)
#define Ecran_Inverse      B10100111  // Inverse l'état de l'intégralité de l'écran.

PERSO_ST7565::PERSO_ST7565(byte broche_RST, byte broche_A0, byte broche_SCLK, byte Retro_eclairage_Bleu, byte Retro_eclairage_Rouge, byte Retro_eclairage_Vert, byte broche_SID) {
	RST=broche_RST;
	A0=broche_A0;
	SCLK=broche_SCLK;
	Retro_Bleu=Retro_eclairage_Bleu;
	Retro_Rouge=Retro_eclairage_Rouge;
	Retro_Vert=Retro_eclairage_Vert;
	SID=broche_SID;
  pinMode(SID, OUTPUT); pinMode(SCLK, OUTPUT); digitalWrite(SCLK, LOW);
  pinMode(RST, OUTPUT); digitalWrite(RST, LOW);
// Attention : Un delay(100); placé ici bloque le programme !
// >>> Donc les instructions qui suivent servent de "délai".
  pinMode(A0, OUTPUT); // État sans importance donc pas d'initialisation.
	pinMode(Retro_Bleu, OUTPUT);
  pinMode(Retro_Vert, OUTPUT);
  pinMode(Retro_Rouge, OUTPUT);
// >>> Fin du "délai".   
  digitalWrite(RST, HIGH);
  // Initialisations matérielles :
  Envoyer_une_COMMANDE(B10100010); // Configuration du cycle de service soit 1/7.  (Ou 1/9 si B10100011 fonction de l'écran LCD physique.)
  Envoyer_une_COMMANDE(Horizontal_Normal);
  Envoyer_une_COMMANDE(Vertical_Normal);
  Envoyer_une_COMMANDE(B00100011); // Diviseur de résistances internes Rb/Ra = 3. (0 à 7)
  Envoyer_une_COMMANDE(B00101111); // COMMANDE de puissance interne sur tous les blocs.
  Envoyer_une_COMMANDE(Contraste_Dynamique); // Passer en mode de contraste dynamique. Doit être suivi de :
  Envoyer_une_COMMANDE(42); // 42 : Bon compromis entre luminosoté constante et traces parasites faibles.
  Afficheur_en_service(); Effacer_Ecran(); Surbrillance(0);}
  
void PERSO_ST7565::Envoyer_une_COMMANDE(byte OCTET) {Envoyer_un_octet(OCTET, true);}
void PERSO_ST7565::Envoyer_un_octet(byte huitbits, boolean commande) { // Envoiyer l'octet poids fort en premier.
  // Ci-dessous passer en mode COMMANDE ou en mode DONNEE pour les octets qui suivent.
  if (commande) digitalWrite(A0, LOW); else digitalWrite(A0, HIGH);
  //------------------ Envoyer les huit BITs dans l'ordre -----------------
  for(byte I = 8; I > 0; I--) {
    digitalWrite(SID, bitRead(huitbits,I-1)); // Place le BIT sur la ligne SID.
    digitalWrite(SCLK, HIGH); 
    digitalWrite(SCLK, LOW);}}
  //----------------------------------------------------------------------- 
  
void PERSO_ST7565::Envoyer_une_DONNEE(byte OCTET) {
  MAJ_PTR(); MEMOIRE[PTR] = OCTET; Envoyer_un_octet(OCTET, false);
  // Ci-dessous Incrémente Colonne car l'afficheur incrémente automatiquement son "curseur" interne. 
  Colonne++; // Car "Envoyer_un_octet" incrémente automatiquement "curseur" de l'afficheur.
  if (Colonne > 127) {Colonne = 0; if (Secteur < 7) Secteur++;
      Positionne_curseur(Colonne, Secteur); MAJ_PTR(); } }
  
void PERSO_ST7565::Contraste(byte Contraste) { // Je conseille entre 27 (Noir) et 50 (Maxi) en décimal.
  Envoyer_une_COMMANDE(B10000001); // Passer en mode de contraste dynamique suivi de :
  Envoyer_une_COMMANDE(Contraste);} // Contraste dynamique compris entre 0 et 63 hexadécimal.
  
void PERSO_ST7565::Afficheur_en_veille() {
  Envoyer_une_COMMANDE(B10101110); // Display OFF.
  digitalWrite(Retro_Bleu, HIGH);
  digitalWrite(Retro_Vert, HIGH);
  digitalWrite(Retro_Rouge, HIGH);}
  
void PERSO_ST7565::Afficheur_en_service() {
  Envoyer_une_COMMANDE(B10101111); // Display ON.
  digitalWrite(Retro_Bleu, LOW); // Allumé si LOW.
  digitalWrite(Retro_Vert, LOW); // Allumé si LOW.
  digitalWrite(Retro_Rouge, LOW);} // Allumé si LOW.
  
void PERSO_ST7565::Surbrillance(boolean Etat) {SURbrillance = Etat;}
	
void PERSO_ST7565::Remplir_et_affiche_Ecran(byte OCTET) {// Laisse inchangé Secteur et Colonne;
  for(int I=0; I<1024; I++) MEMOIRE[I]=OCTET; Afficher_MEMOIRE();} 
void PERSO_ST7565::Effacer_Ecran() {Remplir_et_affiche_Ecran(0);}
void PERSO_ST7565::Blancking_Ecran() {Remplir_et_affiche_Ecran(255);}
	
void PERSO_ST7565::Afficher_MEMOIRE() {// Laisse inchangé Secteur et Colonne;
  int PTRmem = 0;
  int SAV_Secteur; SAV_Secteur = Secteur;
  int SAV_Colonne; SAV_Colonne = Colonne;
  for (PAGE=0; PAGE<8; PAGE++) {
       Impose_PAGE(PAGE);
       for(byte I = 0; I<128; I++){
           Impose_COLONNE(I); OCTET=MEMOIRE[PTRmem]; Envoyer_une_DONNEE(OCTET); PTRmem++;} }
  Secteur = SAV_Secteur; Colonne = SAV_Colonne; Positionne_curseur(Colonne, Secteur);}
  
void PERSO_ST7565::Positionne_curseur(byte X, byte Y) {Impose_COLONNE(X); Impose_PAGE(Y);}

void PERSO_ST7565::Impose_PAGE(byte Page) {// Valeurs 0 à 7.
  Secteur = Page; 
  MAJ_PTR(); // Mise à jour du pointeur dans la MEMOIRE;
  if (Page < 4) Page = Page + 4; else Page = Page - 4;
  Envoyer_une_COMMANDE(B10110000 | Page);} // Imposer la PAGE.
  
void PERSO_ST7565::Impose_COLONNE(byte COLONNE) {// Valeurs 0 à 127.
  byte Octet;
  Colonne = COLONNE; 
  MAJ_PTR(); // Mise à jour du pointeur dans la MEMOIRE;
  COLONNE++; if(COLONNE > 128) COLONNE = 128; // Talonnera à droite de l'écran.
  Octet = COLONNE >> 4; Envoyer_une_COMMANDE(B00010000 | Octet);
  Octet = COLONNE & B00001111; Envoyer_une_COMMANDE(B00000000 | Octet);}

void PERSO_ST7565::MAJ_PTR() {PTR = (Secteur * 128) + Colonne;} // Mise à jour du pointeur dans la MEMOIRE;
	 
void PERSO_ST7565::Inverser_ecran(){
  for(int I=0; I<1024; I++) {OCTET = MEMOIRE[I]; OCTET = OCTET ^ 255; MEMOIRE[I]=OCTET;}
  Afficher_MEMOIRE();}
	
//================================== Instructions GRAPHIQUES ====================================
	
void PERSO_ST7565::PIXEL(int X, int Y, boolean Allume) {//X = 0 à 127, Y = 0 à 63 vers le bas.
  if((X<0) || (X>127) || (Y<0) || (Y>63)) return;
  Impose_COLONNE(X); PAGE = byte(Y/8); Impose_PAGE(PAGE);
  PTR = X + (PAGE * 128); OCTET = MEMOIRE[PTR]; BIT = Y - (PAGE*8);
  bitWrite(OCTET,BIT,Allume);
  MEMOIRE[PTR] = OCTET; Envoyer_une_DONNEE(OCTET); }
  
void PERSO_ST7565::LIGNE(int x, int y, int X, int Y,boolean Allume) {
  byte K;
  int DeltaX, DeltaY, Prov; 
  float J, Delta;
  // =============== Traite un trait vertical. (Éviter une ivision par zéro.) ===============
  if (X==x) { // Traite un trait vertical. (Éviter une ivision par zéro.)  
     if (y > Y) {Prov = y; y = Y; Y = Prov;} //Inverse les bornes pour les avoir croissantes.
     for(y; y < Y+1; y++) PIXEL(X, y, Allume); return;}
  // ========================== calcule la valeur du sélecteur K ============================
  K=0; if (X > x) K++; if (Y > y) K = K+2;
   DeltaX = abs(X-x); DeltaY = abs(Y-y);
  if (DeltaX > DeltaY) K = K+4;
  // ============================ Traite les tracés "rétrogrades ============================
  if ((K<2) || (K==4) || (K==6)) {Prov = x; x=X; X=Prov; Prov = y; y=Y; Y=Prov;}
  if (DeltaX > DeltaY) // Faire varier X et calculer Y.
      {Delta = float (Y-y)/ float (X-x);
      J=y;  for(x; x<(X+1); x++) {PIXEL(x,int(J),Allume); J = J + Delta;} }
  else // Faire varier Y et calculer X.
     {Delta = float (X-x)/ float (Y-y);
      J=x;  for(y; y<(Y+1); y++) {PIXEL(int(J),y,Allume); J = J + Delta;} } }
      	
void PERSO_ST7565::RECTANGLE_plein(int x, int y, int X, int Y,boolean Allume) {
  int Prov;
  if (X<x) {Prov = x; x=X; X=Prov;}
  for(int I=x; I<X+1; I++) LIGNE(I, y, I, Y,Allume);}

void PERSO_ST7565::CADRE(int x, int y, int X, int Y,boolean Allume) {
  LIGNE(x, y, X, y,Allume); LIGNE(x, Y, X, Y,Allume);
  LIGNE(x, y, x, Y,Allume); LIGNE(X, y, X, Y,Allume);}
  
void PERSO_ST7565::Trace_un_point(int X, int Y, int R, int Angle, boolean Allume) {
  int x,y;  float Alpha;
  Alpha=Angle*PI/180; x=int(X+(R * sin(Alpha)));
  y=int(Y-(R * cos(Alpha))); PIXEL(x, y, Allume);}

void PERSO_ST7565::CERCLE(int X, int Y, int R, boolean Allume) {ARC(X, Y, R, 0, 359, Allume);}  
  
void PERSO_ST7565::ARC(int X, int Y, int R, int Angle_debut, int Angle_fin, boolean Allume) {
  // La gestion hors écran est correcte. le tracé est effectué tous les degrés donc, plus le
  //   rayon devient grand plus les pixels sont séparés.
  Angle_debut = abs(Angle_debut); Angle_fin = abs(Angle_fin); // Pare des angles négatifs.
  int Angle; Angle = Angle_fin; // Pour le tracé rétrograde.
  if (Angle_debut < Angle_fin)
     for (Angle=Angle_debut; Angle < Angle_fin+1; Angle++)
          Trace_un_point(X,Y,R,Angle,Allume);
  else for (int I=Angle_fin; I != Angle_debut-1; I--)
           {if (Angle<0) Angle = 360 - Angle; if (I<0) I = 360 - I;
            Trace_un_point(X,Y,R,Angle,Allume); Angle--;} }
            
void PERSO_ST7565::ELLIPSE(int X, int Y, int RX, int RY, boolean Allume) {
  int x,y; int Angle;
  float Alpha;
  for (Angle=0; Angle<360; Angle++)
      {Alpha=Angle*PI/180; x=int(X+(RX * cos(Alpha)));
       y=int(Y+(RY * sin(Alpha))); PIXEL(x, y, Allume);} }
       
//================================= Instructions TEXTUELLES ====================================
  
void PERSO_ST7565::Decale_ECRAN() {Decale_MEMOIRE(); Afficher_MEMOIRE();}
   
void PERSO_ST7565::Decale_MEMOIRE() {
  int PTR_source, PTR_cible;
  PTR_cible = 0; PTR_source = 128;
  for(PTR_source; PTR_source < 1024; PTR_source++)
     {MEMOIRE[PTR_cible] = MEMOIRE[PTR_source]; PTR_cible++;} // Monte tout le bas d'une ligne de texte.
  while (PTR_cible < 1024) {MEMOIRE[PTR_cible] = 0; PTR_cible++;} }
    	
void PERSO_ST7565::Caractere(byte ASCII, boolean Allume) { // Laisse PTR sur le prochain Octet de MEMOIRE après de caractère.
  byte ligne;
  boolean BIT;
  // Pointer le premier "octet colonne" du cractère dans l'EEPROM.
  PTR_ASCII = 543 + (ASCII-32) * 5; // Correction pour ASCII il faut enlever 32.
  // Balayer horizontalement de la gauche vers la droite.
  for(byte Colne = 6; Colne >0; Colne--)
     {// Balayer verticalement du haut vers le bas
      for(ligne = 0; ligne < 8; ligne++)
          {if (Colne > 1) BIT = bitRead(EEPROM.read(PTR_ASCII),ligne); else BIT=0;
          if (SURbrillance) BIT = !BIT;
          PIXEL(PosX, (PosY +ligne), BIT);} PosX++; PTR_ASCII++;} }
          
void PERSO_ST7565::Affiche_TEXTE(char TEXTE[21]) { // 21 caractères au maximum sur une ligne.
  byte I, Code_ASCII;                // Laisse PTR sur le prochain Octet de MEMOIRE.
  I=0;
  while (TEXTE[I] != 0) {
    Code_ASCII = TEXTE[I]; 
    if (Code_ASCII != 0)
       {if ((Code_ASCII == 194) || (Code_ASCII == 195))
           {I++; Code_ASCII = TEXTE[I]; if (Code_ASCII == 169) Code_ASCII = 92; // Traite le é.
                                        if (Code_ASCII == 168) Code_ASCII = 96; // Traite le è.
                                        if (Code_ASCII == 160) Code_ASCII = 94; // Traite le à.
                                        if (Code_ASCII == 181) Code_ASCII = 126; // Traite le µ
                                        if (Code_ASCII == 167) Code_ASCII = 127;} // Traite le ç.
        else  Code_ASCII; 
        Caractere(Code_ASCII,SURbrillance); if (PosX>127) CRLF(); I++;} } }
        	
void PERSO_ST7565::Affiche_NOMBRE(float VALEUR, byte Virgule) { // Virgule = 0, 1 ou 2 Nb caractères après la virgule.
  char texte[21]; byte I;
  String Converti = String (VALEUR); Converti.toCharArray(texte,21);
  // Gérer les chiffres affichés derriére la virgule.
  I=1; while (texte[I] != '.') I++; // Recherche le point.
  if (Virgule > 2) Virgule = 2; if (Virgule > 0) I = ++I + Virgule; texte[I] = 0;
  Affiche_TEXTE(texte);}        	

void PERSO_ST7565::CRLF() {PosX = 0; if(PosY < 55) PosY = PosY+8; else Decale_ECRAN();}

void PERSO_ST7565::HOME() {PosX = 0; PosY = 0;}
	
void PERSO_ST7565::CURSEUR(byte X, byte Y) {PosX = X; PosY = Y;}	


#12 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 31 mars 2016 - 10:23

ATTENTION :

la bibliothèque présentée ci-avant suppose que la table pour générer les caractères se trouve gravée dans la partie haute de l'EEPROM.

Dans ce but il faut au préalable invoquer le programme :

/* Petit programme pour stocker la police de caractères dans l'EEPROM de l'ATmega328.
   Créer le tableau complet fonctionne car la taille reste inférieure à 512 octets. 
   La table sera placée en haut de l'EEPROM pour laisser tout le bas disponible soit
   pour un LOGO, soit pour des textes etc. 1023 - 480 = 543. */

#include <Adafruit_ssd1306syp.h>
#include <EEPROM.h>

// Variables du programme.
byte OCTET, Ligne, Colonne;
int PTR;
  
byte TABLE_ASCII[480] =  {B00000000, B00000000, B00000000, B00000000, B00000000, // ESPACE
                          B00000000, B00000000, B01001111, B00000000, B00000000, // !
                          B00000000, B00000011, B00000000, B00000011, B00000000, // "
                          B00010100, B00111110, B00010100, B00111110, B00010100, // #
                          B00100100, B00101010, B01111111, B00101010, B00010010, // $
                          B00100011, B00010011, B00001000, B01100100, B01100010, // %
                          B00110110, B01001001, B01010101, B00100010, B01010000, // &
                          B00000000, B00000101, B00000011, B00000000, B00000000, // '
                          B00000000, B00011100, B00100010, B01000001, B00000000, // (
                          B00000000, B01000001, B00100010, B00011100, B00000000, // )                          
                          B00010100, B00001000, B00111110, B00001000, B00010100, // *                          
                          B00001000, B00001000, B00111110, B00001000, B00001000, // +                          
                          B00000000, B01010000, B00110000, B00000000, B00000000, // ,
                          B00001000, B00001000, B00001000, B00001000, B00001000, // -                          
                          B00000000, B01100000, B01100000, B00000000, B00000000, // .
                          B00100000, B00010000, B00001000, B00000100, B00000010, // /
                          
                          B00111110, B01010001, B01001001, B01000101, B00111110, // 0
                          B00000000, B01000010, B01111111, B01000000, B00000000, // 1
                          B01000010, B01100001, B01010001, B01001001, B01000110, // 2
                          B00100001, B01000001, B01000101, B01001011, B00110001, // 3
                          B00011000, B00010100, B00010010, B01111111, B00010000, // 4
                          B00100111, B01000101, B01000101, B01000101, B00111001, // 5
                          B00111100, B01001010, B01001001, B01001001, B00110000, // 6
                          B00000001, B01110001, B00001001, B00000101, B00000011, // 7
                          B00110110, B01001001, B01001001, B01001001, B00110110, // 8
                          B00000110, B01001001, B01001001, B00101001, B00011110, // 9
                          B00000000, B00110110, B00110110, B00000000, B00000000, // :
                          B00000000, B01010110, B00110110, B00000000, B00000000, // ;
                          B00001000, B00010100, B00100010, B01000001, B00000000, // <
                          B00010100, B00010100, B00010100, B00010100, B00010100, // =
                          B00000000, B01000001, B00100010, B00010100, B00001000, // >
                          B00000010, B00000001, B01010001, B00001001, B00000110, // ?
                          
                          B00110010, B01001001, B01111001, B01000001, B00111110, // @                          
                          B01111100, B00010010, B00010001, B00010010, B01111100, // A
                          B01111111, B01001001, B01001001, B01001001, B00110110, // B 
                          B00111110, B01000001, B01000001, B01000001, B00100010, // C
                          B01111111, B01000001, B01000001, B01000001, B00111100, // D
                          B01111111, B01001001, B01001001, B01001001, B01000001, // E
                          B01111111, B00001001, B00001001, B00001001, B00000001, // F
                          B00111110, B01000001, B01001001, B01001001, B01111010, // G
                          B01111111, B00001000, B00001000, B00001000, B01111111, // H
                          B00000000, B01000001, B01111111, B01000001, B00000000, // I
                          B00100000, B01000000, B01000001, B00111111, B00000001, // J
                          B01111111, B00001000, B00010100, B00100010, B01000001, // K
                          B01111111, B01000000, B01000000, B01000000, B01000000, // L
                          B01111111, B00000010, B00001100, B00000010, B01111111, // M
                          B01111111, B00000100, B00001000, B00010000, B01111111, // N
                          B00111110, B01000001, B01000001, B01000001, B00111110, // O
                          
                          B01111111, B00001001, B00001001, B00001001, B00000110, // P
                          B00111110, B01000001, B01010001, B00100001, B01011110, // Q
                          B01111111, B00001001, B00011001, B00101001, B01000110, // R
                          B01000110, B01001001, B01001001, B01001001, B00110001, // S
                          B00000001, B00000001, B01111111, B00000001, B00000001, // T
                          B00111111, B01000000, B01000000, B01000000, B00111111, // U
                          B00011111, B00100000, B01000000, B00100000, B00011111, // V
                          B00111111, B01000000, B00111000, B01000000, B00111111, // W
                          B01100011, B00010100, B00001000, B00010100, B01100011, // X
                          B00000111, B00001000, B01110000, B00001000, B00000111, // Y
                          B01100001, B01010001, B01001001, B01000101, B01000011, // Z
                          B00000000, B01111111, B01000001, B01000001, B00000000, // [
                          B00111000, B01010100, B01010110, B01010101, B00011000, // é >>>>>> Non standard.
                          B00000000, B01000001, B01000001, B01111111, B00000000, // ]
                          B00100000, B01010101, B01010110, B01010100, B01111000, // à >>>>>> Non standard.
                          B10000000, B10000000, B10000000, B10000000, B10000000, // _
                          
                          B00111000, B01010101, B01010110, B01010100, B00011000, // è >>>>>> Non standard.
                          B00100000, B01010100, B01010100, B01010100, B01111000, // a
                          B01111111, B01000100, B01000100, B01000100, B00111000, // b
                          B00111000, B01000100, B01000100, B01000100, B00101000, // c
                          B00111000, B01000100, B01000100, B01000100, B01111111, // d
                          B00111000, B01010100, B01010100, B01010100, B00011000, // e
                          B00001000, B01111110, B00001001, B00000001, B00000010, // f
                          B00011000, B10100100, B10100100, B10100100, B01111100, // g
                          B01111111, B00001000, B00000100, B00000100, B01111000, // h
                          B00000000, B01000100, B01111101, B01000000, B00000000, // i
                          B01000000, B10000000, B10000100, B01111101, B00000100, // j
                          B01111111, B00010000, B00101000, B01000100, B00000000, // k
                          B00000000, B01000001, B01111111, B01000000, B00000000, // l
                          B01111100, B00000100, B00011000, B00000100, B01111000, // m
                          B01111100, B00001000, B00000100, B00000100, B01111000, // n
                          B00111000, B01000100, B01000100, B01000100, B00111000, // o
                          
                          B11111100, B00100100, B00100100, B00100100, B00011000, // p
                          B00011000, B00100100, B00100100, B00100100, B11111100, // q
                          B01111100, B00001000, B00000100, B00000100, B00001000, // r
                          B01001000, B01010100, B01010100, B01010100, B00100100, // s
                          B00000100, B00111111, B01000100, B01000100, B00100000, // t
                          B00111100, B01000000, B01000000, B00100000, B01111100, // u
                          B00011100, B00100000, B01000000, B00100000, B00011100, // v
                          B00111100, B01000000, B00110000, B01000000, B00111100, // w
                          B01000100, B00101000, B00010000, B00101000, B01000100, // x
                          B00011100, B10100000, B10100000, B10100000, B01111100, // y
                          B01000100, B01100100, B01010100, B01001100, B01000100, // z                          
                          B00000000, B00001000, B00110110, B01000001, B00000000, // {
                          B00000000, B00000000, B01111111, B00000000, B00000000, // |
                          B00000000, B01000001, B00110110, B00001000, B00000000, // }
                          B11111111, B00010000, B00010000, B00001000, B00011111, // µ >>>>>> Non standard.
                          B00011100, B10100010, B01100010, B00100010, B00010100 }; // ç >>>> Non standard.
  
void setup() { }

void loop() {
  // ==================== Ecriture des octets dans l'EEPROM. ====================
  PTR = 0;           // Début de la table en EEPROM : 543 d'où le + à cette valeur ci-dessous;
  while (PTR < 480) {EEPROM.write(PTR + 543,TABLE_ASCII[PTR]); PTR++;}
  // ==================== Confirmation de la fin du traitement. =================
  INFINI: goto INFINI; }


#13 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 31 mars 2016 - 11:03

Ha, j'oubliais,

Par exemple, ci-dessous une minuscule application qui transforme l'une des entrées analogiques d'Arduino UNO en un simple voltmètre analogique.

cette application utilise à la fois les possibilités graphiques et textuelles. Fondamentalement, c'est pour montrer l'avantage qu'il y a à pouvoir

positionner à des coordonnées quelconques un texte, et pas forcément sur des "lignes entières" en hauteur.

Cette faculté est mise à contribution pour les caractères 0 à 5 affichez en des positions "libres".

 

FCFkfWS0yXa_Vm%C3%A8tre-Analigique.JPG



#14 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 211 messages
  • Gender:Male
  • Location:Autriche

Posté 31 mars 2016 - 01:24

Salut !

Joli boulot ! J'aurais sûrement fait plein de choses différemment, mais si ça marche, c'est l'essentiel.

Par contre :

(...)
void setup() { }

void loop() {
// ==================== Ecriture des octets dans l'EEPROM. ====================
PTR = 0; // Début de la table en EEPROM : 543 d'où le + à cette valeur ci-dessous;
while (PTR < 480) {EEPROM.write(PTR + 543,TABLE_ASCII[PTR]); PTR++;}
// ==================== Confirmation de la fin du traitement. =================
INFINI: goto INFINI; }

La fonction loop est faite pour être répétée (elle est appelée tant que l'arduino est alimentée). La fonction setup s'exécute une seule fois, puis c'est la fonction loop qui se répète. Tu peux donc écrire dans l'EEPROM dans setup, puis avoir une loop vide (ou qui affiche quelques tests sur l'écriture dans l'EEPROM).
Le goto n'est pas nécessaire, et mieux vaut ne pas prendre le réflexe de l'utiliser : c++ dispose de suffisamment de structures de contrôle pour qu'il n'y ait pas besoin de sauter sauvagement d'un point à un autre (plus de détails : http://stackoverflow.com/questions/3517726/what-is-wrong-with-using-goto).
En fait, ici, tu forces loop à ne pas boucler avec ton goto, alors que tu peux facilement le laisser boucler avec d'autres organisation de programmation : mettre l'écriture EEPROM dans setup (meilleure solution à mon avis), mettre une condition et un flag pour n'écriture que la première fois qu'on passe par loop, faire l'écriture à chaque tour de loop (PTR mis à zéro dans setup(), la condition de ton while passe dans un if(), le while devient la fonction loop()).
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#15 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 31 mars 2016 - 02:11

Haaaa le goto ... il en aura fait couler de l'encre.

 

Oui, effectivement je pouvais faire une boucle principale vide et placer mon code dans setup.

 

C'est uniquement une façon "personnelle" de voir les choses.

Je m'explique :

Psychologiquement, pour Môamôa setup doit initialiser des configuration, et la boucle principale faire le travail qui motive le programme.

Donc, j'ai opté pour placer le code dans loop.

 

Comme je ne veux faire qu'une seule  fois le travail, j'enlise la boucle de base dans la sous-boucle INFINI: goto INFINI;

Cette écriture est pour moi un "STOP !" que j'utilise souvent lors de la mise au point des programmes, quand je veux "suspendre à un point précis".

 

Si le goto était interdit par la loi, je pourrais écrire une ligne du genre while (true) {}; qui aboutirait à un comportement identique, mais franchement, sur un coup d'œil rapide c'est moins lisible à mon sens qu'INFINI: goto INFINI;

 

En fait, tout ça n'est que compromis, avec en filigrane le mental de chacun.

Merci pour ton propos, c'est toujours utile d'avoir à se remettre en question, il en émerge toujours du positif ...



#16 fansa336

fansa336

    Nouveau membre

  • Membres
  • 5 messages

Posté 25 juillet 2016 - 09:13

Salut Nulentout :-)

 

d'abord bravo pour ton  travail, j'ai du mal à tout comprendre mais perso on voit que tu sait coder.

 

Si tu le permet je souhaiterais savoir si tu pourrais poster un exemple de programme .ino, car j'ai fait l'acquisition du même afficheur mais la bibliothèque de ladyada ne me permet pas de faire certaines choses.

 

à l'heure ou j'écrit ce message je suis en train de décoder toutes les fonctions que tu apporte en comparaison à celle de adafruit.

 

et surtout merci de faire partager tes connaissance, cela permet d'aider les curieux x).



#17 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 26 juillet 2016 - 07:14

Bonjour fansa336, bonjour les Arduinautes,

Oui, avec plaisir.

Par exemple voici le croquis qui émule le petit volt-mètre analogique :

/* EXEMPLE d'utilisation de la bibliothèque qui transforme Arduino en Voltmètre.

   Cette application met en evidence l'utilité de pouvoir positionner n'importe
   où sur l'écran l'écriture d'un caractère ou d'un texte.                          */

#include <PERSO_ST7565.h>

// Dans l'ordre : RST, A0, SCLK, Bleu, Rouge, Vert, SID :
PERSO_ST7565 LCD = PERSO_ST7565(6,7,8,9,10,11,12);

// Constantes et variables du programme.
#define N 400 // Nombre de mesures pour faire une moyenne.
int savANGLE;
int ANGLE;
float Tension_lue, N_Tensions_lues; // Valeur cumulée.
byte Vcurseur, Hcurseur;

void setup() {
  LCD.Afficheur_en_service(); LCD.Effacer_Ecran();
  Trace_le_cadran(); ANGLE=90;} // Valeur quelconque pour tracer l'aiguille au RESET.
  
void loop() {
  N_mesures_sur_Ai(0); // mesure la tension sur A0.
  if (Tension_lue < 250) ANGLE = map(Tension_lue, 0, 250, 322, 359);
                    else ANGLE = map(Tension_lue, 250, 500, 0, 38);
  if (ANGLE != savANGLE) {
     Aiguille(savANGLE, 61,0);
     Aiguille(ANGLE, 61,1); savANGLE = ANGLE;
     LCD.CURSEUR(66,0); LCD.Affiche_NOMBRE(Tension_lue/100,2); } }

void Trace_le_cadran() {
  LCD.LIGNE(19,27,24,32,1); // Graduation 0.
  LCD.LIGNE(36,19,39,24,1); // Graduation 1.
  LCD.LIGNE(54,15,54,19,1); // Graduation 2.
  LCD.LIGNE(73,15,72,19,1); // Graduation 3.
  LCD.LIGNE(91,19,89,24,1); // Graduation 4.
  LCD.LIGNE(107,27,102,31,1); // Graduation 5.
  LCD.ARC(64, 82, 63, 322, 38,1);
  LCD.ARC(63, 82, 63, 322, 38,1); // Deuxieme arc pour obtenir une continuite.
  LCD.CURSEUR(40,0); LCD.Affiche_TEXTE("V = ");
  LCD.CURSEUR(17,17); LCD.Affiche_TEXTE("0");
  LCD.CURSEUR(33,10); LCD.Affiche_TEXTE("1");
  LCD.CURSEUR(52,7); LCD.Affiche_TEXTE("2");
  LCD.CURSEUR(70,8); LCD.Affiche_TEXTE("3");
  LCD.CURSEUR(89,12); LCD.Affiche_TEXTE("4");
  LCD.CURSEUR(107,18); LCD.Affiche_TEXTE("5");}
  
void Aiguille(int Angle, int R, boolean Allume) {
  int x,y;  float Alpha;
  Alpha=Angle*PI/180; x=int(64+(R * sin(Alpha)));
  y=int(82-(R * cos(Alpha)));
  LCD.LIGNE(x, y, 64, 82, Allume);}

void N_mesures_sur_Ai(byte ENTREE) { 
  N_Tensions_lues = 0;
  for (int I = 0; I < (N) ; I++) 
       {Tension_lue = analogRead(ENTREE); // Mesure analogique [0 à  1023].
       N_Tensions_lues = N_Tensions_lues + Tension_lue; }
  Tension_lue = N_Tensions_lues / N;
  Tension_lue = map(Tension_lue, 0, 1023, 0, 500); } // Tension en volts * 1000.

Je te propose aussi l'un de mes programmes de base qui servait à tester les fonctionnalités de ma bibliothèque :

/* Programme initial pour tester la bibliothèque personnelle de l'afficheur ST7565.
   Cette version loge la table des caractères en mémoire FLASH de programme.
   Avant cette transition : 10208 (31%) 1181 (57%)
   Après cette transition : 10638 (32%) 1181 (57%) Il y a bien augentation de 430 octet
   du programme ce qui correspond à l'introduction de la table de caractères. */

#include <PERSO_ST7565.h>

#define Retro_Bleu 9
#define Retro_Rouge 10
#define Retro_Vert 11

// variables du programme :
byte TMP_etoile;

// Dans l'ordre : RST, A0, SCLK, Bleu, Rouge, Vert, SID :
PERSO_ST7565 LCD = PERSO_ST7565(6,7,8,Retro_Bleu,Retro_Rouge,Retro_Vert,12);

void setup()   {}

void loop() {
  LCD.LIGNE(-10, -10, 137, 73, 1);
  LCD.RECTANGLE_plein(30, 30, 60, 35,1);
  LCD.CADRE(5, 4, 122, 59,1);
  LCD.CERCLE(50, 25, 20, 1);
  LCD.CERCLE(50, 25, 0, 1);
  LCD.ARC(-50, -50, 100, 0, 180, 1);
  LCD.ARC(64, 50, 40, 330, +30, 1);
  LCD.ELLIPSE(64,32,60,30,1);
  LCD.ELLIPSE(0, 0, 60, 30, 1);
  delay(1000);
  LCD.Decale_MEMOIRE();
  LCD.Afficher_MEMOIRE();   
  delay(1000); 
  LCD.Remplir_et_affiche_Ecran(128);
  LCD.Decale_ECRAN();
  delay(2000);
  LCD.Effacer_Ecran(); LCD.Positionne_curseur(64,3);
  LCD.Envoyer_une_DONNEE(255); LCD.Envoyer_une_DONNEE(B01010101); LCD.Envoyer_une_DONNEE(B10101010);
  LCD.CURSEUR(30,40);
  LCD.Affiche_TEXTE("BONjour ...");
  LCD.Inverser_ecran();
  LCD.Surbrillance(1);
  LCD.Affiche_NOMBRE(PI, 7);
  LCD.CURSEUR(20,48);
  LCD.Affiche_TEXTE("Texte très long pour engendrer des passages à la ligne intempestif et 'prévus' dans ce programme.");
  delay(4000); LCD.Effacer_Ecran(); LCD.Inverser_ecran();
  while (true) // Ciel_nocturne:
        {TMP_etoile++;
        if (TMP_etoile>100) {TMP_etoile = 0;
            digitalWrite(Retro_Bleu, random(2));
            digitalWrite(Retro_Vert, random(2));
            digitalWrite(Retro_Rouge, random(2));}
        LCD.PIXEL(random(127),random(63),0); delay(30);
        // Ci-dessous on efface cent fois plus que l'on allume.
        for (byte i=0; i<100; i++) {LCD.PIXEL(random(127),random(63),1);} } }


#18 fansa336

fansa336

    Nouveau membre

  • Membres
  • 5 messages

Posté 27 juillet 2016 - 07:16

Bonjour Nulentout,

 

merçi pour ton exemple du voltmètre cela m'intéresse encore plus,

 

néanmoins après avoir retranscrit ton code j'obtient ceci lors de la  compilation

 

sketch\voltm_tre.ino.cpp.o: In function `Trace_le_cadran()':
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:33: undefined reference to `PERSO_ST7565::LIGNE(int, int, int, int, bool)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:34: undefined reference to `PERSO_ST7565::LIGNE(int, int, int, int, bool)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:35: undefined reference to `PERSO_ST7565::LIGNE(int, int, int, int, bool)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:36: undefined reference to `PERSO_ST7565::LIGNE(int, int, int, int, bool)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:37: undefined reference to `PERSO_ST7565::LIGNE(int, int, int, int, bool)'
 
sketch\voltm_tre.ino.cpp.o:C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:39: more undefined references to `PERSO_ST7565::LIGNE(int, int, int, int, bool)' follow
 
sketch\voltm_tre.ino.cpp.o: In function `Trace_le_cadran()':
 
C:\Users\Adrien\Desktop\voltm_tre/voltm_tre.ino:40: undefined reference to `PERSO_ST7565::ARC(int, int, int, int, int, bool)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:41: undefined reference to `PERSO_ST7565::ARC(int, int, int, int, int, bool)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:42: undefined reference to `PERSO_ST7565::CURSEUR(unsigned char, unsigned char)'
 
C:\Users\*****n\Desktop\voltm_tre/voltm_tre.ino:42: undefined reference to `PERSO_ST7565::Affiche_TEXTE(char*)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:43: undefined reference to `PERSO_ST7565::CURSEUR(unsigned char, unsigned char)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:43: undefined reference to `PERSO_ST7565::Affiche_TEXTE(char*)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:44: undefined reference to `PERSO_ST7565::CURSEUR(unsigned char, unsigned char)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:44: undefined reference to `PERSO_ST7565::Affiche_TEXTE(char*)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:45: undefined reference to `PERSO_ST7565::CURSEUR(unsigned char, unsigned char)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:45: undefined reference to `PERSO_ST7565::Affiche_TEXTE(char*)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:46: undefined reference to `PERSO_ST7565::CURSEUR(unsigned char, unsigned char)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:46: undefined reference to `PERSO_ST7565::Affiche_TEXTE(char*)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:47: undefined reference to `PERSO_ST7565::CURSEUR(unsigned char, unsigned char)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:47: undefined reference to `PERSO_ST7565::Affiche_TEXTE(char*)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:48: undefined reference to `PERSO_ST7565::CURSEUR(unsigned char, unsigned char)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:48: undefined reference to `PERSO_ST7565::Affiche_TEXTE(char*)'
 
sketch\voltm_tre.ino.cpp.o: In function `setup':
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:20: undefined reference to `PERSO_ST7565::Afficheur_en_service()'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:20: undefined reference to `PERSO_ST7565::Effacer_Ecran()'
 
sketch\voltm_tre.ino.cpp.o: In function `Aiguille(int, int, bool)':
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:54: undefined reference to `PERSO_ST7565::LIGNE(int, int, int, int, bool)'
 
sketch\voltm_tre.ino.cpp.o: In function `loop':
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:30: undefined reference to `PERSO_ST7565::CURSEUR(unsigned char, unsigned char)'
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:30: undefined reference to `PERSO_ST7565::Affiche_NOMBRE(float, unsigned char)'
 
sketch\voltm_tre.ino.cpp.o: In function `__static_initialization_and_destruction_0':
 
C:\Users\*****\Desktop\voltm_tre/voltm_tre.ino:9: undefined reference to `PERSO_ST7565::PERSO_ST7565(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
 
collect2.exe: error: ld returned 1 exit status
 
exit status 1
Error compiling for board Arduino Nano.
 
J'ai récupéré le code de ta bibliothèque et créée un fichier .h avec codeblocks
avec le même nom de fichier
 
peux-tu m'aider a comprendre ce qui ne vas pas ?
 
et merçi de m'avoir répondu :-)


#19 Nulentout

Nulentout

    Membre occasionnel

  • Membres
  • Pip
  • 82 messages
  • Gender:Male

Posté 28 juillet 2016 - 01:44

OUPS, l'est pas content le compilateur !

Il importe de savoir que j'ai pas mal galéré, jusqu'à ce que j'utilise la vertion 1.7.9 du compilateur, c'est peut être l'origine de ton problème.

Je suppose que tu as déclaré la bibliothèque dans l'IDE naturellement.

Si d'autres copains ont des idées, n'hésitez surtout pas à venir aider fansa336.



#20 fansa336

fansa336

    Nouveau membre

  • Membres
  • 5 messages

Posté 29 juillet 2016 - 11:24

Ah d'accord je vais tester avec la 1.7.9 mais je crois que j'ai mal créé la bibliothèque => le fichier PERSO_ST7565.h ne contient que la première partie de ta bibliothèque, je ne sais pas quoi faire de ta partie developpement




0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users