Plantage du programme

Bonjour,

J’ai créé un simple programme pour la régulation en chauffage d’une enceinte.

Que j’ai mis en route, arrêter remis etc… ( je n’est plus la date de lancement, 2mois max):

Il tourne sur un Arduino Mega 2560 avec un module relais et un ds18b20;

#include "EEPROM.h"
#include <Encoder.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
Encoder myEnc(2, 3);
LiquidCrystal_I2C lcd(0x3F, 20, 2);
OneWire oneWire(7);
DallasTemperature sensorsint(& oneWire);
DallasTemperature sensorsext(& oneWire);
DeviceAddress sensorDeviceAddress;
int a = 80;
float consigne;
float temperature = 20;
float temperatureExt = 20;
float hysteresy = 0.25; 
byte resistance = 9;
byte bp = 6;
byte etatbp;
unsigned long previousMillis = 0;
const long interval = 5000;
void setup()
{
	consigne = EEPROM.read(a);
	myEnc.write(consigne);
	pinMode(bp, INPUT);
	pinMode(resistance, OUTPUT);
	lcd.init();
	lcd.backlight();
	Serial.begin(9600);
	sensorsint.begin();
	sensorsint.getAddress(sensorDeviceAddress, 0);
	sensorsint.setResolution(sensorDeviceAddress, 11);
}

float oldPosition = -999;

void loop()
{
	unsigned long currentMillis = millis();
	etatbp = digitalRead(bp);
	float newPosition = myEnc.read();

	if (currentMillis - previousMillis >= interval)
	{
		sensorsint.requestTemperatures();
		temperature = sensorsint.getTempCByIndex(0);
		previousMillis = currentMillis;
	}

	consigne = newPosition/8;

	if (etatbp == 0)
	{
		EEPROM.write(a, newPosition);
		delay(100);
	}

	if (temperatureExt < consigne + 1)
	{
		if (temperature >= consigne + hysteresy)
		{
			digitalWrite(resistance, 0);
			lcd.setCursor(5, 1);
			lcd.print("off");
		}
		if (temperature <= consigne - hysteresy)
		{
			digitalWrite(resistance, 1);
			lcd.setCursor(5, 1); 
			lcd.print("on ");
		}
	}

	lcd.setCursor(0, 0); 
	lcd.print("B:");
	lcd.print(temperature);
	lcd.print("  ");
	lcd.setCursor(0, 1); 
	lcd.print(consigne);
	lcd.print("  ");
	delay(10);
}

Mais hier il a “planter” il est rester bloquer avec la fonction résistance en 1 avec l’affichage une t° erroné sur le lcd (19° affiché au lieu de 34° mesuré ) …

J’ai débranché le 5V et rebranché et tout est rentré dans l’ordre

Je soupçonne le “mills” qui est arrivé a bout …

Une idée ?

Par avance merci.

Bonjour,

Ce n’est pas du à un débordement de millis() car le test utilisé
if (currentMillis - previousMillis >= interval)gère le débordement sans problème.

Dépassement de capacité de l’EEPROM ?

lesept: Dépassement de capacité de l'EEPROM ?

Bonsoir

Vous parlez de l'appuie sur le bouton ? j'ai du l'utiliser une dizaine de fois maximun.

Ou vous parliez d'autre chose ?

Merci

Un code qui plante sans raison ça fait penser à un dépassement d’indice de tableau (mais je n’en vois pas dans ton code) ou à un problème mémoire : voyant que tu écris dans l’EEPROM je me demande si c’est un problème de ce côté là…

J4l13n: Vous parlez de l'appuie sur le bouton ? j'ai du l'utiliser une dizaine de fois maximun.

Oui mais tel que le code est écrit, si tu tiens le bouton 1s tu fais 10 écritures

    if (etatbp == 0)
    {
        EEPROM.write(a, newPosition);
        delay(100);
    }

Même si ce n'est sans doute pas ça la raison de ton problème, ce serait bien d'attendre le relâché du bouton pour continuer

    if (etatbp == 0)
    {
        EEPROM.write(a, newPosition);
        while(digitalRead(bp)){};
    }

fdufnews: Même si ce n'est sans doute pas ça la raison de ton problème, ce serait bien d'attendre le relâché du bouton pour continuer

  if (etatbp == 0)
    {
        EEPROM.write(a, newPosition);
        while(digitalRead(bp)){};
    }

Bonjour,

Ah super merci :)

Y a t-il un moyen de relancer l'Arduino pour qu'il reboot toutes les 5min ?

Cordialement

Oui, il suffit d'appeler une fonction reset lorsque millis atteint les cinq minutes, soit 5*60*1000ul

On trouve plusieurs possibilités pour cette fonction reset, Google "arduino software reset", en voici une

void(* resetFunc) (void) = 0;//declare reset function at address 0
...
resetFunc(); //call reset

J4l13n: Y a t-il un moyen de relancer l'Arduino pour qu'il reboot toutes les 5min ?

Il y a moyen de le faire mais je dirais que c'est une mauvaise solution car elle ne cherche pas à résoudre le problème.

Tu pourrais déjà prévoir une sécurité, si la résistance est allumé depuis un certain temps et que la température ne change pas alors faire un reset. Cela pourrait couvrir un problème lié à la lecture des capteurs de température, mais causé par quoi??

Comment est réalisée ton installation? Est-ce que les capteurs de température sont éloignés? Si oui, peut-être blinder les connexions. Est-ce qu'une perturbation secteur pourrait avoir causé ce problème?

Si c'est vraiment un problème logiciel, mais il est tellement simple qui je ne vois pas trop où il pourrait-y avoir un problème, tu pourrais activer le watchdog. Et dans loop tu le réactiverait périodiquement.

.

Bonjour,

Il y a plusieurs choses qui m'interpellent dans ton programme:

 consigne = EEPROM.read(a);
...
 consigne = newPosition/8;
...
 EEPROM.write(a, newPosition);
  • read() et write() écrivent uniquement un octet alors que les float font 4 ocets. Ca marche peut être de manière bancale pour des entiers inférieurs à 255, mais c'est incorrect. Il faut utiliser put() et get() qui présentent en plus l'avantage d'écrire effectivement que si la valeur à écrire est différente de celle qui est dans l'EEPROM

  • tu écris une chose et tu lis autre chose. Tu écris newPosition qui vaut 8*consigne et tu relis consigne.

J4l13n: Y a t-il un moyen de relancer l'Arduino pour qu'il reboot toutes les 5min ?

il y a un moyen "un peu plus propre" c'est de mettre un watchdog

la lib wire est susceptible de bloquer le programme a cause d'un mauvais contact ou des parasites

rjnc38: il y a un moyen "un peu plus propre" c'est de mettre un watchdog

la lib wire est susceptible de bloquer le programme a cause d'un mauvais contact ou des parasites

Bonjour

la lib "Wire" , vous pensez au ds18b20 ?

Cordialement

non celle de l'I2C

rjnc38:
il y a un moyen “un peu plus propre” c’est de mettre un watchdog

la lib wire est susceptible de bloquer le programme a cause d’un mauvais contact ou des parasites

huuuum si il a planter le watchdog peut faire le taf ?

Donc j’integre ce code dans le skecth :

#include <avr/wdt.h> // watchdog


void setup(){
     wdt_enable(WDTO_8S); // watchdog fixé à a 8s (maxi possible)

    }


void loop(){
     wdt_reset(); // watchdog démarré on le raz a chaque passage sinon reboot ...

    }

void reboot() {
       while(1);
     }

Donc si le raz “wdt_reset()” du watchdog n’est pas effectué au bout du temps impartit (8secondes) l’arduino redemarre ? c’est ça ?

Merci

oui c’est cela
l’enable plutôt en fin de setup au cas ou il dure plus de 8s

Merci je vais updater le sketch