En tant que débutant j'ai une erreur que je ne comprends pas : "warning: invalid conversion from 'byte {aka unsigned char}' to 'byte* {aka unsigned char*}'
Cela survient dans une foinction apelée pour lire la temperature d'une sonde DS18D20
void readMeasuredTemperature (byte *temperature_cumulus, const byte adresse_sonde[]) {
byte data[2]; // données lues du capteur
sonde.reset();
sonde.select(adresse_sonde);
sonde.write(0xBE);
for (byte i = 0; i < 2; i++) {
data[i] = sonde.read();
}
temperature_cumulus = byte (((data[1] << 4) | data[0]) >> 4);
} //fin de la fonction de lecture de la temperature
À une époque, je faisais souvent ce genre de confusion, mais je connais une méthode pour ne plus me tromper : je fais attention aux noms des pointeurs.
Là, 'temperature_cumulus' est un nom trompeur : on pourrait croire qu'il désigne la température du cumulus. D'où l'affectation erronée de la ligne 9.
En réalité, cette variable est un pointeur vers la température du cumulus. Si je l'appelle (par exemple) 'pt_temperature_cumulus', je ne peux plus me tromper sur la nature de l'objet : c'est un pointeur, il faut utiliser l'opérateur * pour mettre une température dans la zone pointée.
En tant que débutant j'ai une erreur que je ne comprends pas : "warning: invalid conversion from 'byte {aka unsigned char}' to 'byte* {aka unsigned char*}'
Cela survient dans une foinction apelée pour lire la temperature d'une sonde DS18D20
void readMeasuredTemperature (byte *temperature_cumulus, const byte adresse_sonde[]) {
byte data[2]; // données lues du capteur
sonde.reset();
sonde.select(adresse_sonde);
sonde.write(0xBE);
for (byte i = 0; i < 2; i++) {
data[i] = sonde.read();
}
temperature_cumulus = byte (((data[1] << 4) | data[0]) >> 4);
} //fin de la fonction de lecture de la temperature
Si l'objectif est de récupérer la température du cumulus, on peut se simplifier la vie en décidant de représenter cet traitement par une fonction qui retourne la température.
byte readMeasuredTemperature(const byte probe_address[])
{
...
byte lo = sonde.read() >> 4;
byte hi = sonde.read() << 4;
return hi | lo;
}
au lieu de s'emmerder avec des pointeurs.
----
Un autre point à considérer, c'est que ce programme n'est pas écrit en C, mais en C++, comme le prouve l'appel de fonctions membres, exemple sonde.read()
Et en C++ on dispose du passage de paramètres, dont l'absence est un gros boulet traîné par les programmeurs C depuis l'antiquité de la programmation.
En parlant d'antiquité, à Rome, fais donc comme les romains, passe les paramètres par référence quand ils doivent être modifiés par la fonction appelée :
(mais la solution du retour par return est probablement préférable).
---
PS : la variable "sonde" est mal nommée, il s'agit plus probablement d'un bus 1-wire. Sur un bus, il peut y avoir plusieurs sondes ou autres périphériques.
Mal nommer les choses, c'est un moyen de se créer des emmerdements.
byte readMeasuredTemperature(const byte probe_address[])
{
...
byte lo = sonde.read() >> 4;
byte hi = sonde.read() << 4;
return hi | lo;
}
Alors je ne sais pas lequel de vous deux a raison (j'opte pour michelbillaud), mais le calcul de la t° va donner un résultat différent suivant le code employé.
- Edité par edgarjacobs 11 avril 2021 à 20:01:17
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
The resolution of the temperature sensor is user-configurable to 9, 10, 11, or 12 bits, corresponding to increments of 0.5°C, 0.25°C, 0.125°C, and 0.0625°C, respectively. The default resolution at power-up is 12-bit.
les deux premiers octets du "scratchpad" sont le LSB et le MSB de la température. Jusque là, lo et hi, ça correspond.
Après, est-ce que c'est pertinent de récupérer la température sur un octet, j'ai un doute.
Y aurait que moi je le récupérerais sur un entier 16 bits avec (hi << 8) | lo, ou sur un float en divisant par l'incrément correspondant à la résolution.
Bazarder les 4 bits de droite du MSB , ça ramène la précision à 1°C (16*0.0625) en 12 bits. Faut voir l'application. Problème à voir quand même avec les températures négatives, parce que si le résultat est dans un byte, il n'est pas signé. Il va faire chaud en dessous de 0.
- Edité par michelbillaud 11 avril 2021 à 21:36:13
Pour la température la précision de 1 degré est plus que suffisante car il s'agit de la température estimé d'un chauffe-eau.
S'emmerder avec des demi degrés et une précision sur 12 bits quand on sait que la variation de haut en bas est de plus de 10°C me semble du pur masochisme dans la quête de la perfection. Quand aux températures négatives dans un chauffe eau je l'imagine mal à moins qu'il soit déjà explosé grâce a l'anomalie dilatométrique dont l'eau, les semiconducteur et le plutonium ont le secret.
Mais je ne comprends toujours pas le pourquoi du warning de compilation.
Le domaine d'application, on n'en savait rien. Un chauffe eau dans un chalet resté en panne de chauffage par -20 dehors, ça peut démarrer assez bas quand on redémarre. Et ça serait ballot qu'il veuille pas démarrer justement parce qu'il trouve qu'il fait déjà 240 degrés.
Quitte à représenter sur 8 bits, autant que ça soit un octet signé.... Enfin bon, si tu as décidé qu'il n'y aurait que des températures positives, c'est toi qui vois.
Venons-en au vif du sujet:
> le pourquoi du warning de compilation
invalid conversion from 'byte {aka unsigned char}'
to 'byte* {aka unsigned char*}'
il suffit de lire, les petites étoiles ne sont pas là pour faire joli
temperature_cumulus est déclaré avec le type byte*, soit "pointeur de char non signé".
et l'expression
byte (((data[1] << 4) | data[0]) >> 4);
est de type "char non signé".
Non seulement c'est pas pareil, mais c'est pas raisonnable d'affecter un entier (petit ou grand, signé ou pas) dans un pointeur. Donc le compilateur le dit.
- Edité par michelbillaud 11 avril 2021 à 23:30:14
Comme j'apprends pour des raisons purement ludiques il y a plein de stupidités faites au cours du temps. Ce qui me "rejouit" plutôt car cea me permets d'apprendre.
En fait pour la temperature elle est constamment régulée entre 4 et 90 degrés. En principe le problème pourrait venir comme tu le dis en cas de panne électrique et -20 dehors mais dans ce cas il n'y a rien a faire car meme si je peux mettre un back-up pour le fonctionnement de la régulation il n'y a pas de possibilité de chauffer l'eau de toute façon voire non plus de transmettre les info à distance.
J''ai finalement implémenté la fonction avec un retour de temperature par la fonction mais pour des raisons purement éducatives je vais ressayer avec les pointeurs.
Par ailleurs j'ai découvert Tinkercad qui m'a permis de "simuler" bien d'erreurs mais il ne connait que tres peu de périphériques/libraries.
Existe-t-il d'autres simulateurs de ATmega328 ? et qui "connait les peripherique 1 wire ?
Pour des raisons éducatives, focalise-toi plutôt sur les manières correctes de faire les choses. Passe la variable par reference.
Faut reconnaître que les tutoriels n'aident pas trop. A les lire ceux qui les ont écrits s'imaginent qu'ils programment en C, donc ne disent pas un mot des références.
Comme je fais tout ca pour le divertissement pur je ne le fait que le soir.
J'ai un (petit) background d'electronique et programmation mais ca date de plus de 30 ans et depuis ma memoire "is fading" Ca resurgit de temps en temps avec des exclamation ques ce qu'on peut etre con, mais c'est ca aussi le fun.
Je suis à la recherche d'une reference écrite mais mais je trouve difficilement dans le sens que c'est très disparate en termes de qualité sur le WEB. Je suis preneur de conseils/recommendations.
Je reviens vers vous car j'ai des difficultés pour mettre en place une fonction en utilisant les pointeurs. J'ai compris (je le pense) le concept et en théorie son utilisation mais en pratique le compil n'est toujours pas content (gcc sous Arduino IDE).
Problème:
J'ai une variable de type array of bytes (byte addr[7];) que je dois peupler avec l'adresse d'un capteur 1 wire.
Pour des question de lisibilité du code (et d'apprentissage) je veux le faire dans une fonction séparé qui dois donc recevoir l'adresse ( un pointeur donc) de addr pour pouvoir la modifier ensuite. La fonction doit retourner le code d'erreur sur l'etat (present/type) de capteur) et donc je dois passer par un pointeur.
J'ai regarde la reference sur le carnet du maker. Quand je faitvtout ds setup ca marche bien mais par une fonction ext non.
j'ai essayé en plusieurs modalités (et au fil du temps j'ai compris qqs erreurs mais je n'arrive toujours pas a le faire correctement.
J'ai essaye de créer une variable pointeur vers addr et ca ne marche pas non plus.
Avez vous une reference qui traite de ce sujet (un cours) ou au moins des explications comment faire ?
La fonction doit retourner le code d'erreur sur l'etat (present/type) de capteur) et donc je dois passer par un pointeur.
Ah non ! Le code d'erreur doit être la valeur de retour de la fonction. C'est même « typique C » que d'avoir des fonctions qui réalisent plein de chose et retournent juste un code d'erreur. Exemple : la fonction 'scanf' fait de la saisie formatée au clavier, et retourne le nombre de données correctement saisies. Autre exemple : la fonction 'main'.
Si j'ai bien compris, tu as besoin de retourner un code d'erreur et de manipuler un tableau. Dans ce cas, le prototype de la fonction est quelque chose comme :
int fonction(type adresse_capteur, byte addr[7]);
Code d'erreur : c'est le 'int' retourné par la fonction (ou 'unsigned int', ou 'char', ou autre...)
Adresse du capteur : c'est un paramètre passé par valeur. (Je ne sais pas de quel type il est, aussi j'ai mis 'type'...)
Tableau à mettre à jour : pas besoin de gérer des pointeurs puisque c'est un tableau (tu te souviens qu'un tableau en paramètre d'une fonction est toujours passé par adresse ?)
Voila le code qui me compile pas et (désolé d'insiter) je voudrais comprendre pourqoui.
#include <OneWire.h>
// Defining digitalpins
#define pin_1_wire_bus A2 // Pin mesure temperature; pas d'autre disponible
//Defining resolution of the temperature readings un comment one of the four options
#define TEMPERATURE_PRECISION 0b00111111 //precision 10 bits implicite choice
//#define TEMPERATURE_PRECISION 0b00011111 //precision 9 bits temps de conversion 90 ms
//#define TEMPERATURE_PRECISION 0b01011111 //precision 11 bits temps de conversion 375 ms
//#define TEMPERATURE_PRECISION 0b01111111 //precision 12 bits temp de conversion 750 ms
//Variables retournés apres initialisation de la sonde de temperature
enum DS18B20_RCODES {
SENSOR_OK, // Lecture ok
NO_SENSOR_FOUND, // Pas de capteur
INVALID_ADDRESS, // Adresse reçue invalide
INVALID_SENSOR // Capteur invalide (pas un DS18B20)
};
// variables liés à la mesure de temperature
byte adresse_sonde[8];
bool sonde_temp_presente = false;
bool mesure_temperature_disponible = false;
byte temperature_cumulus;
OneWire sonde(pin_1_wire_bus); // definition de sonde comme objet OneWire
void setup() {
if (initialisesondetemperature (&adresse_sonde, TEMPERATURE_PRECISION)== SENSOR_OK) { //apeller l'initialisation de sonde de temp , qui doit modifier la variabke adresse sonde
sonde_temp_presente = true;
}
else {
sonde_temp_presente = false;
}
} //end setup
void loop() {
//routine de gestion de la temp a mettre dans la boucle de 1 sec.
if (sonde_temp_presente) { //On teste si la sonde est initialisée
if (!mesure_temperature_disponible) {
startMesureTemperature (adresse_sonde); // initier une nouvelle mesure si temp non deja lue
mesure_temperature_disponible = true; //signale que la temp est disponible au prochain cycle
}
else {
readMeasuredTemperature (&temperature_cumulus, adresse_sonde); //lecture de la temperature mesurée le cycle précedent et gestion
mesure_temperature_disponible = false; //signale que la temp mesuree a été lue
}
} //Fin du bloc avec sonde de temperature
} // Fin de loop
// Definition des fonctions
// Fonction d'initialisation de la sonde de temperature
byte initialisesondetemperature (byte *addr, byte precision) {
// Cherche sonde temperature
sonde.reset_search(); /* Recherche le prochain capteur 1-Wire disponible */
if (!sonde.search(addr)) { // Pas de capteur
return NO_SENSOR_FOUND;
}
if (OneWire::crc8(addr, 7) != addr[7]) { // Verifie que l'adresse est valide
return INVALID_ADDRESS;
}
if (addr[0] != 0x28) { // Verifie le type de capteur
return INVALID_SENSOR;
}
else {
sonde.reset();
sonde.select(addr);
sonde.write(0x4E);
sonde.write(0x00);
sonde.write(precision);
sonde.reset();
return SENSOR_OK;
}
}
//Fonction de demande de mesure de la temperature
void startMesureTemperature (const byte adresse_sonde[]) {
sonde.reset();
sonde.select(adresse_sonde);
sonde.write(0x44, 1);
}
//fin de la demande de lecture de temperature
//fonction de lecture de la temperature mesurée
void readMeasuredTemperature (*temperature_cumulus, const byte adresse_sonde) {
byte data[2]; // données lues du capteur
sonde.reset();
sonde.select(adresse_sonde);
sonde.write(0xBE);
for (byte i = 0; i < 2; i++) {
data[i] = sonde.read();
}
*temperature_cumulus = byte (((data[1] << 4) | data[0]) >> 4);
// if ((temperature_cumulus < T_LIMIT_LOW ) || (temperature_cumulus > T_LIMIT_UP)) {
// major failure tout arreter à implementer
// }
} //fin de la fonction de lecture de la temperature
Si vous avez des choses a me rocommander pour lire je suis preneur.
Voila le code qui me compile pas et (désolé d'insiter) je voudrais comprendre pourqoui.
Comment sais-tu qu'il ne compile pas ? Aurais-tu, mais vraiment à tout hasard, des messages qui pourraient, toujours à tout hasard, nous aider à débusquer le bug ???
Enfin, des fois que ton compilo ne sois pas muet …
Bon, je ne m'investit pas dans ton code (je ne suis pas un pro de l'embarqué), m ais bon le premier message d'erreur semble tout simplement dire que tu as donné l'adresse d'un tableau comme paramètre au lieu du «tableau».
Et non … on n'a pas un compilo dans la tête qui compile lorsqu'on lit … enfin pas comme ça.
Je dois vraiment apprendre a lire les messages des compilo
Donc mon problème est dans la définition de la fonction.
En effet je veux lui donner une adresse (pointeur vers un tableau) et je dois voir l'écriture de la fonction pour quelle attende un pointeur c'est ca ?
Je dois vraiment apprendre a lire les messages des compilo
lire … et comprendre surtout. Sans ça tu n'avanceras jamais.
BogdanGrigoriu a écrit:
[...]
Donc mon problème est dans la définition de la fonction.
[...]
Ptêt dans l'utilisation …
BogdanGrigoriu a écrit:
[...]
En effet je veux lui donner une adresse (pointeur vers un tableau) et je dois voir l'écriture de la fonction pour quelle attende un pointeur c'est ca ?
Non ce n'est pas ce que tu veux, en tout cas pas un pointeur vers un tableau … car c'est ce que tu fais et ce que la fonction attend est simplement un pointeur sur byte, ce qui sans rentrer trop dans les détails est simplement ton tableau. Les tableau que tu passes en paramètres sont «automatiquement» considérés comme un pointeur sur leur premier élément.
lui donner adresse_sonde, un tableau, et la fonction recevra un pointeur sur le premier élément du tableau …
warning: invalid conversion from 'byte to byte
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Si l'objectif est de récupérer la température du cumulus, on peut se simplifier la vie en décidant de représenter cet traitement par une fonction qui retourne la température.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent