Go Down

Topic: Tableau et char* (Read 691 times) previous topic - next topic

Geeks

Bonjour,

Bon, maintenant que j'ai résolu un certain nombre de bug concernant le souci de binaire incomplet, j'ai un autre problème... Forcément !

Voila, j'ai un tableau de voies qui contient des int 0 à 180 en général. Pas de négatif (je dis au cas ou) !

J'ai donc initialisé:
Code: [Select]

#define SIZE_VOIES 10  //Nombre de voies
int voies[SIZE_VOIES];  //Initialise le tableau des voies


Dans mon code, le tableau se charge et j'arrive à créer ma trame sur une string:
Code: [Select]

String trame;  //Trame d'émission

//Boucler tant que toutes les voies ne sont pas créées
for(int i = 1; i <= (SIZE_VOIES); i++) {


//Créer la trame
trame += voies[i];

//Tant que l'on est pas sur la dernière voie
if(i <= (SIZE_VOIES-1)) {

trame += ",";  //Placer un séparateur
}
}


Ensuite, dans une autre portion de code, je cherche à faire afficher voie par voie sa valeur:
Code: [Select]

ecrireLcd(voies[3], 25);  //Ecrire
ecrireLcd(voies[4], 45);  //Ecrire


Et là ben je me prens un:
Quote

Telecommande_V10_final_001.ino: In function 'void affEcran()':
Telecommande_V10_final_001:326: error: invalid conversion from 'int' to 'const char*'
Telecommande_V10_final_001:326: error: initializing argument 1 of 'String::String(const char*)'


Donc un souci de conversion entre int et char* ! Je m'étais tenter à itoa() sans succès donc je bloque un peu la dessus. Pourquoi dans une string, comme en haut ça marche, surtout si je fais un truc comme ça:
Code: [Select]
ecrireLcd(trame, 21);  //Ecrire

Je voie pas pourquoi je peux pas non plus faire:
Code: [Select]

String test = voies[3];
ecrireLcd(test, 21);


Enfin, bref, on ne touche pas au tableau il est OK mais pour l'affichage, c'est une autre blague !

Merci pour votre aide.

fdufnews

D'abord une remarque
Code: [Select]
#define SIZE_VOIES 10  //Nombre de voies
int voies[SIZE_VOIES];  //Initialise le tableau des voies

.....
for(int i = 1; i <= (SIZE_VOIES); i++) {
//Créer la trame
trame += voies[i];
......

voies est créé avec 10 éléments (de 0 à 9) donc le for devrait être
Code: [Select]
for(int i = 0; i < (SIZE_VOIES); i++) {


//Créer la trame
trame += voies[i];


Quote
j'arrive à créer ma trame sur une string

ATTENTION bien faire la distinction entre string et String ce n'est pas la même chose.

Concernant ton problème d'affichage la fonction ecrireLcd();  attend en premier argument une chaine de caractères pourquoi ne pas lui en donner une en utilisant ça pour faire afficher trame par exemple : http://arduino.cc/en/Reference/StringToCharArray

Pour ton autre exemple 2 possibilités:
     faire une chaine avec l'int que tu veux afficher (itoa, sprintf il y a plusieurs solutions)
     écrire une fonction similaire à ecrireLcd() qui accepte en entrée un int.

skywodd

Bonjour,

Si ta valeur va de 0 à 180 exclusivement un byte (1 octet) suffit, pas la peine d'utiliser un int (2 octet) ;)
Ensuite dans ta boucle tu utilises une String, c'est une saloperie pas possible la String sur arduino ;)
Si c'est pour faire de l'affichage autant afficher directement à l'écran au lieu de passer par une string.

Sur cette partie de code :
Code: [Select]
//Créer la trame
trame += voies[i];

Quel est le type de la variable "voies" ?

-> Sans le code complet on ne peut pas te dire ou ce situe l'erreur ...

Ps: comme le fait remarquer fdufnews il y a aussi un problème d'indexage avec ta boucle.
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Geeks

Ok,  je comprends un peu en effet le coup du String !

Bon, trame est injecter sur un équipement radio au format série... En effet (Atduino : tx -> rx : Equipement)...
Donc la String part tel que !!

Ok pour l'idée de virer le int pour un byte. C'est vrai que ça serais une belle optimisation. Mais est-ce que ça restera compatible avec partie transmission sur tx -> rx et ensuite avec l'affichage sur mon écran ?

Bon, si je scrute les 800 lignes  :smiley-sad-blue: Ben oui, je ne fais pas que renvoyé des infos sur un récepteur... Je sait aussi travailler sur carte SD avec ce montage, je remarque que j'utilise ceci:
Code: [Select]

//Transmission de la trame sur le récepteur
Serial1.print(trame);


Donc, tu remarquera que trame est envoyé tel que.

Pour ce qui est de l'afficheur, je vais donner la série de code que j'ai employé. C'est orienté fonction car c'est assez souple pour ce que je veux faire et je ne m'en sent pas de créer des classes avec des fichiers de partout ! Pour moi une classe = son fichier. La on est obliger de faire un header, un autre fichier... Bref c'est (pour moi) le B***** !

Donc fonctions de l'afficheur:
Code: [Select]

/* FONCTION initLCD */
void initLcd() {

//Initialisation de l'écran par I2C
Wire.begin();  //Amorce la connection sur SDA et SCL
Wire.beginTransmission(adresseLcd); //Appelle l'écran LCD
Wire.write((byte)0x00);  //Assigne un null
Wire.write((byte)0x0C);  //Effacer l'écran
Wire.write((byte)0x13);  //Allume le rétro-éclairage
Wire.write((byte)0x04);  //Ne pas afficher le curseur
Wire.endTransmission();  //Ferme la connexion sur SDA et SCL
}

/* FONCTION ecrireLcd */
void ecrireLcd(String texte, int positionEcran) {

//Initialisation de l'écran par I2C
Wire.begin();  //Amorce la connection sur SDA et SCL
Wire.beginTransmission(adresseLcd); //Appelle l'écran LCD
Wire.write((byte)0x00);  //Assigne un null
Wire.write((byte)0x02);  //Placer le curseur
Wire.write(positionEcran);  //Sur l'écran
Wire.print(texte);  //Ecrire un texte
Wire.endTransmission();  //Ferme la connexion sur SDA et SCL
}

/* FONCTION ecrireLcdChar */
void ecrireLcdChar(char texte[32], int positionEcran) {

//Initialisation de l'écran par I2C
Wire.begin();  //Amorce la connection sur SDA et SCL
Wire.beginTransmission(adresseLcd); //Appelle l'écran LCD
Wire.write((byte)0x00);  //Assigne un null
Wire.write((byte)0x02);  //Placer le curseur
Wire.write(positionEcran);  //Sur l'écran
Wire.write(texte);  //Ecrire un texte
Wire.endTransmission();  //Ferme la connexion sur SDA et SCL
}

/* FONCTION clearLcd() */
void clearLcd() {

//Initialisation de l'écran par I2C
Wire.begin();  //Amorce la connection sur SDA et SCL
Wire.beginTransmission(adresseLcd); //Appelle l'écran LCD
Wire.write((byte)0x00);  //Assigne un null
Wire.write((byte)0x0C);  //Effacer l'écran
Wire.endTransmission();  //Ferme la connexion sur SDA et SCL
}

/* FONCTION clearCol() */
void clearCol(int col) {
//Effacer la colonne
Wire.begin();  //Amorce la connection sur SDA et SCL
Wire.beginTransmission(adresseLcd); //Appelle l'écran LCD
Wire.write((byte)0x00);  //Assigne un null
Wire.write((byte)0x02);  //Placer le curseur
Wire.write(col);  //Sur l'écran
Wire.write((byte)0x11);  //Effacer l'écran
Wire.endTransmission();  //Ferme la connexion sur SDA et SCL
}


J'avais prévenu...

Ça fonctionne parfaitement. Ouf ! Mais je pense que c'est difficilement incontournable autrement. J'ai essayer de synthétisé un maximum ainsi. J'aime pas trop taper 10 fois le même code... Ai-je dit une bêtise  :smiley-mr-green:

Voila, je pense maintenant travailler sur une petite optimisation (passage sur une boucle fort à un endroit ou je fais la même chose pour les voies 7 à 10. Mais j'aimerais résoudre ce problème. Merci.

Geeks

Bon, je viens en effet de modifier quelques petites choses.

Passage du int au byte sans problème.
Code: [Select]

//int voies[SIZE_VOIES];  //Initialise le tableau des voies
byte voies[SIZE_VOIES];  //Initialise le tableau des voies


Je garde !

Modifications au niveau de la boucle for, comme indiqué au dessus. A noter cependant que j'ai été obliger de rectifier d'autres valeurs du tableau mais je suis retomber sur mes pattes. 1 -> 0 / 2 -> 1 / 3 -> 2 / 4 -> 3 / 5 -> 4 / 6 -> 5 / 7 -> 6 / 8 -> 7 / 9 -> 8 / 10 -> 9 / ce qui donne maintenant :
Code: [Select]

//Initialiser la trame
trame = "";

//Boucler tant que toutes les voies ne sont pas créées
for(int i = 0; i < (SIZE_VOIES); i++) {


//Créer la trame
trame += voies[i];

//Tant que l'on est pas sur la dernière voie
if(i <= (SIZE_VOIES-2)) {

trame += ",";  //Placer un séparateur
}
}

//Transmission de la trame sur le récepteur
Serial1.print(trame);


Reste à solutionner le retrait du "String trame;" et l'affichage du tableau à la demande sur le LCD. J'obtient maintenant le message suivant:
Quote

Telecommande_V10_final_001.ino: In function 'void affEcran()':
Telecommande_V10_final_001:326: error: invalid conversion from 'byte' to 'const char*'
Telecommande_V10_final_001:326: error: initializing argument 1 of 'String::String(const char*)'


Donc j'ai bien quitté le mode int.

Merci pour votre aide.

skywodd

Remet ton int et fait ça :
Code: [Select]
trame += String(voies[i]);

Ça évitera l'erreur de compilation (normalement), mais les String ça reste une mauvaise idée ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Geeks

Effectivement, pour la trame ça fonctionne  8)

Mais par contre pour le phénomène plus bas, je vais cherché un moyen de m'affranchir du String.

On est pas au bout de nos peine mais j'y arriverais  XD

Go Up