Bonjour,
je rencontre un soucis innatendu. j'ai simplifié mon code afin d'isoler le problème. J'ai un écran LCD 4 lignes avec un encoder KY 040. l'encodeur est utilisé sans la librairie encoder.h car avec, l'encodeur ne répond pas correctement.
voici mon code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define CLK_PIN 10
#define DT_PIN 11
#define SW_PIN 9
int position = 51; // pour le test
int last_position = 0;
int n = 0;
LiquidCrystal_I2C lcd(0x27, 20, 4); // Adresse I2C, colonnes (20 pour un écran 4x20), lignes (4), SDA (A4), SCL (A5)
void setup() {
lcd.init();
lcd.backlight();
lcd.clear();
}
void loop() {
n = digitalRead(CLK_PIN);
if ((last_position == 0) && (n == HIGH)) {
if (digitalRead(DT_PIN) == LOW) {
position++;
} else {
position--;
}
}
last_position = n;
// test affichage
lcd.setCursor(0, 0);
//lcd.print(" position ");
lcd.print(position);
}
avec ce code, l'encodeur fonctionne parfaitement, aucun soucis, réactivité parfaite.
par contre dès que j'écris quelques chose sur la même ligne ou la ligne en dessous, ça ne fonctionne plus.
cette ligne //lcd.print(" position ");
passée en lcd.print(" position ");
fais que l'encodeur ne fonctionne plus. parfois l'encodeur fixe, parfois ça incrémente correctement, parfois ça fait l'inverse et souvent ça bloque, je n'ai plus aucune réactivité.
je ne comprends pas comment le fait d'écrire un mot peut faire planter mon encodeur. ça fait plusieurs jours que je planche dessus et que je ne trouve pas de la solution, je me permets de demander à la communauté en espérant que vos lanternes m'aiguillent .
Pourquoi afficher constamment sur le lcd même quand la valeur n'a pas changé ? Ca gaspille énormément de cycles, et c'est probablement la cause de ton problème. Mais le mieux est de gérer un encodeur rotatif par des interruptions.
j'avoue bidouiller souvent les arduinos, mais je suis clairement novice comparé à vous ^^
je découvre que je peux faire plusieurs "void xxx" pour les rappeler dans le loop ! je comprends mieux la notion de void setup aussi merci.
J'ai compris que j'affiche des infos en fixe et que je mets dans le loop celles qui ont besoin d'un refresh (via le loop) et aussi que ça sert à rien d'initialiser dans le loop !! (merde pu**iin de newBie ^^)
une question concernant ce code, si je veux que mon compteur commence à 50, je peux changer cette ligne lcd.setCursor(0, 1); lcd.print(F("POS: 50"));
mais ça reste pour l'affichage du départ, l'incrément part à 1 ce qui est logique. je n'arrive pas à donner à la variable encoderPosition un défaut de 50 pour que mon premier incrément soit 51.
c'est ce que j'ai fait, mais ça ne marche pas
désolé j'aurais du dire que j'avais testé ça. pour moi aussi en toute logique si j'initialise encoderPosition à 50 ça devrait incrémenter à 51 bhé non ça part toujours à 1
@J-M-L a pris la peine de mettre un lien vers la doc de la librairie Encoder. Il suffit de lire cette doc.
Il n'y a pas beaucoup à lire car il n'y que le constructeur et 2 méthodes, une pour lire la valeur de l'accumulateur et l'autre pour fixer sa valeur.
Basic Usage
Encoder myEnc(pin1, pin2);
Create an Encoder object, using 2 pins. You may create mulitple Encoder objects, where each uses its own 2 pins. The first pin should be capable of interrupts. If both pins have interrupt capability, both will be used for best performance. Encoder will also work in low performance polling mode if neither pin has interrupts.
myEnc.read();
Returns the accumulated position. This number can be positive or negative.
myEnc.write(newPosition);
Set the accumulated position to a new number.
@fdufnews oui désolé je n'avais pas creusé la doc constructeur.
@J-M-L Merci ta syntaxe est la bonne, ça fonctionne
Merci encore pour vos aides, je retourne sur mon projet initial. d'ailleurs y a un endroit où on peut présenter son projet pour montrer ses avancements et poser des éventuelles questions ?
bonjour à tous.
je rencontre un soucis de freeze sur mon projet. je m'en suis servi pour faire une étuve de ginger beer (grrrr ) mais au petit matin il semble bloqué.
je l'éteints et le rallume et oui clairement il était bloqué. lui ou la sonde, mais la sonde donnait 28° et était bloqué.
Après reboot, la sonde se remet à s'actualiser toute les secondes et il fait 21°. donc j'ai bien eu un blocage.
je vous repose le code utilisé. en espérant que vous ayez une idée car je sèche
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include <Encoder.h> // https://www.pjrc.com/teensy/td_libs_Encoder.html
#include <Toggle.h>
#include "max6675.h" // https://github.com/Dlloydev/Toggle
//création LCD
const uint8_t nbCols = 20;
const uint8_t nbRows = 4;
hd44780_I2Cexp lcd;
//config des pins
int relais = 2;
int thermoDO = 4;
int thermoCS = 5;
int thermoCLK = 6;
const byte encoderSWPin = 9;
Toggle encoderSwitch;
const byte encoderCLKPin = 10;
const byte encoderDTPin = 11;
//////
Encoder encoder(encoderDTPin, encoderCLKPin);
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
//config des variable
int tempRef;
int page = 1;
unsigned long previousMillis = 0; // Variable pour stocker le temps précédent
const unsigned long interval = 500; // pour pallier le delay qui fait planter l'encoder
bool encoderChanged() {
long newPosition = encoder.read() >> 2;
if (newPosition != tempRef) {
tempRef = newPosition;
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
encoderSwitch.begin(encoderSWPin);
//Serial.begin(9600);
pinMode(relais, OUTPUT);
int result = lcd.begin(nbCols, nbRows);
encoder.write(28 << 2);
intro();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
void intro() {
lcd.backlight();
lcd.clear();
delay(100);
lcd.setCursor(0, 0);
lcd.print(" / / Etuve Box / / ");
lcd.setCursor(4, 2);
lcd.print("V1 23/09/203 ");
lcd.setCursor(0, 1);
lcd.print(" by Yvan Bonnin ");
delay(100);
lcd.backlight();
lcd.clear();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mySwitch() {
encoderSwitch.poll();
if (encoderSwitch.onPress()) {
page++;
if (page == 3) { page = 1; }
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void myEncoder() {
if (encoderChanged()) {
lcd.setCursor(13, 1);
lcd.print(F(" ")); // on efface l'ancienne valeur
}
if (page == 1) {
lcd.setCursor(13, 1);
lcd.print(tempRef); // on met la nouvelle valeur
}
if (tempRef <= 9) { // symbole °
lcd.setCursor(14, 1);
lcd.print((char)223);
lcd.setCursor(15, 1);
lcd.print(" ");
} else { // symbole ° décalé de 1 en dessous de 10
lcd.setCursor(15, 1);
lcd.print((char)223);
}
if (tempRef <= 0 || tempRef >= 95) { // limite des températures acceptées
encoder.write(29 << 2);
}
lcd.setCursor(16, 1);
lcd.print("/ /");
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
mySwitch();
//Serial.println(tempRef);
if (page == 1) {
myEncoder();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// Lire la température en Celsius depuis le capteur MAX6675
double temperature = thermocouple.readCelsius();
// Formater la température avec une décimale
String formattedTemperature = String(temperature, 1);
lcd.setCursor(0, 0);
lcd.print(" / / Mode Etuve / / ");
lcd.setCursor(0, 1);
lcd.print("/ / Objectif ");
lcd.setCursor(0, 2);
lcd.print(" Temp Four : ");
lcd.print(formattedTemperature); // Afficher la température avec une décimale
lcd.write((char)223);
// Allumer ou éteindre la Lampe en fonction de la température
if (temperature <= tempRef - 1) {
digitalWrite(relais, LOW); // Allumer la Lampe
lcd.setCursor(0, 3);
lcd.print(" Lampe en chauffe ");
}
if (temperature >= tempRef) {
digitalWrite(relais, HIGH); // Éteindre la Lampe
lcd.setCursor(0, 3);
lcd.print(" ");
}
previousMillis = currentMillis;
}
} else {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// Lire la température en Celsius depuis le capteur MAX6675
double temperature = thermocouple.readCelsius();
// Formater la température avec une décimale
String formattedTemperature = String(temperature, 1);
lcd.setCursor(0, 0);
lcd.print(" Temperature check ");
lcd.setCursor(0, 1);
lcd.print("/ / / / / / / / / / ");
lcd.setCursor(0, 2);
lcd.print(" Temp Four : ");
lcd.print(formattedTemperature); // Afficher la température avec une décimale
lcd.write((char)223);
lcd.setCursor(0, 3);
lcd.print("/ / / / / / / / / / ");
digitalWrite(relais, HIGH); // Éteindre la Lampe
previousMillis = currentMillis;
}
}
}
Pas certain que ce soit la cause racine de ton problème mais, pourquoi faire ça
alors que print propose déjà le formatage des float.
Ceci devrait se comporter de la même manière et éviterait l'usage des String qui peut poser des problèmes d'occupation mémoire sur le long terme.
lcd.print(temperature, 1); // Afficher la température avec une décimale
A part, ça, le code semble propre.
Si le système était en exploitation il devait tourner sur la page 1 qui ne fait pas grand chose.
Il n'est pas impossible que le plantage ait été causé par une microcoupure ou un parasite sur le secteur.
Merci pour ton retour. le système est en cours d'utilisation. j'ai eu encore un freeze. j'ai l'impression que c'est au bout de 10h.
Comme c'est en utilisation dans mon four je ne peux pas changer le code, je ferai demain la correction.
je t'avoue je ne suis pas assez calé pour comprendre la subtilité que tu expliques, quand j'aurais le code avec l'arduino branché j'essaierai de mettre ça au clair en essayant de comprendre tout ça
String formattedTemperature = String(temperature, 1);
lcd.print(formattedTemperature); // Afficher la température avec une décimale
la première ligne alloue de la mémoire et fait le calcul pour transformer le nombre en chaîne formaté que vous affichez en suite.
si vous faites simplement
lcd.print(temperature, 1); // Afficher la température avec une décimale
la fonction print va simplement stopper l'affichage du nombre décimal après le premier chiffre. vous n'avez pas eu l'allocation intermédiaire dynamique de mémoire.
Si la mémoire est limitée (c'est souvent le cas sur des petits arduinos) on essaye d'être prudent sur tout ce qui en consomme pour rien