Page 8 sur 34

Re: chauffage PID

Publié : 10 nov. 2017, 18:54
par jackslayter
Merci je viens de voir mon erreur

Re: chauffage PID

Publié : 25 nov. 2017, 11:57
par ogulf
Je viens ENFIN de comprendre pourquoi, lorsque je passais mon interrupteur virtuel en "Off", mon radiateur chauffait quand même....
Je pense qu'il y a une petite erreur dans la fonction "compute(pid)" sur la séquence suivante :

Code : Tout sélectionner

Variable du script Lua :
pid['OnOff'] = 'Présence' -- Nom de l'interrupteur virtuel de mise en parche oui/non
pid['cycle'] = 10	-- temps en minute d'un cycle PID

function compute(pid)
	< code >

	-- à chaque cycle
	if ( time.min%pid['cycle'] == 0 ) then
		< code >

		-- si l'on veut chauffer
		if ( otherdevices[pid['OnOff']] == 'On' ) then
			< code >
		end

	-- toutes les 15 minutes, si on ne veut pas chauffer
	elseif ( otherdevices[pid['OnOff']] == 'Off' and time.min%15 == 0 ) then
		< code >
	end
Lorsque time.min est un multiple de pid['cycle'] et un multiple de 15, alors on ne rentre jamais dans le "si on ne veut pas chauffer".

Chez moi le cycle est fixé à 5 minutes, du coup le premier test est satisfait toutes les 5 minutes, en particulier toutes les 15 minutes, même si je suis en otherdevices[pid['OnOff']] == 'Off'.

Dans l'exemple que tu fournis, avec un cycle à 10 minutes, le radiateur ne reçoit jamais d'ordre "Off" à time.min=0 ou 30 puisque la première condition est satisfaite (0%10=0 et 30%10=0).
Dans ce cas précis, l'ordre Off est envoyé toutes les 1/2h (hh:15 et hh:45) et non tous les 1/4h.
Dans mon cas, aucun ordre n'était envoyé :-(


Il y a plusieurs solutions pour corriger, chacun adoptera la sienne, mais je pense qu'il conviendra d'en reporter une dans ton fichier modules.lua pour ceux qui le découvriraient seulement maintenant ;)
Ou toute autre solution différente, bien entendu !
Je vous en propose 3.

Solution 1 :

Code : Tout sélectionner

function compute(pid)
	< code >

	-- à chaque cycle
	if ( time.min%pid['cycle'] == 0 ) then
		< code >

		-- si l'on veut chauffer
		if ( otherdevices[pid['OnOff']] == 'On' ) then
			< code >
		end
	end

	-- toutes les 15 minutes, si on ne veut pas chauffer
	if ( otherdevices[pid['OnOff']] == 'Off' and time.min%15 == 0 ) then
		< code >
	end
Solution 2 :

Code : Tout sélectionner

function compute(pid)
	< code >

	-- à chaque cycle, si l'on veut chauffer
	if ( time.min%pid['cycle'] == 0 and otherdevices[pid['OnOff']] == 'On') then
		< code >

	-- toutes les 15 minutes, si on ne veut pas chauffer
	elseif ( otherdevices[pid['OnOff']] == 'Off' and time.min%15 == 0 ) then
		< code >
	end
Solution 3 :
Choisir le cycle et la fréquence pour ne pas chauffer tels que PPCM > 60
Par exemple : cycle = 7 et off toutes les 15 minutes car PPCM(7,15)=105
Par exemple : cycle = 7 et off toutes les 10 minutes car PPCM(7,10)=70

nb : PPCM = Plus Petit Commun Multiple, cf le Web pour ceux que ça intéresse :D

La solution 2 a l'avantage d'être plus lisible, et permet en plus de s'affranchir d'un IF THEN END qui avait pour seule condition otherdevices[pid['OnOff']] == 'On' : cette condition est remontée dans le test principal.
C'est cette solution que j'ai adoptée.

==========================================

J'ai apporté une autre modification à l'ordre de chauffe quand commande = 100%.
En effet, inutile de prévoir un "OFF AFTER Cycle + 20 secondes" puisqu'un nouvel ordre va arriver au prochain cycle... J'ai constaté que ça perturbait le fonctionnement pour la bonne et simple raison qu'au cycle d'après si on avait encore 100%, alors le radiateur recevait un Off au bout de 20 secondes...

Exemple avec cycle = 10 minutes

HH.00:00 : supposons que le calcul donne "commande = 100", le radiateur reçoit "ON" à HH:00:00 et "OFF AFFTER 620", càd "OFF" à HH:10:20
HH:10:00 : supposons à nouveau "commande = 100", le radiateur reçoit "ON" à HH:10:00 et "OFF AFFTER 620", càd "OFF" à HH:20:20
HH:10:20 : le radiateur reçoit le OFF envoyé à HH:00:00
Et ainsi de suite tant qu'on calcule 100%.
Donc 20 secondes de chauffe au lieu des 10 minutes attendues !

Avant modif :

Code : Tout sélectionner

	-- action sur l'élément chauffant
	if heatTime > 0 then
		log(pid['zone']..' : Temp='..temp..', Consigne='..consigne..', Chauffage pendant '..string(round(heatTime/60,0))..' minutes')
		commandArray[1] = {[pid['radiateur']] = marche}
		commandArray[2] = {[pid['radiateur']] = arret..' AFTER '..heatTime}
	else
		log(pid['zone']..' : Temp='..temp..', Consigne='..consigne..', Pas de chauffage dans les '..pid['cycle']..' prochaines minutes')
		commandArray[pid['radiateur']]=arret
	end
Après modif :

Code : Tout sélectionner

	-- action sur l'élément chauffant
	if heatTime > 0 then
		log(pid['zone']..' : Temp='..temp..', Consigne='..consigne..', Chauffage pendant '..string(round(heatTime/60,0))..' minutes')
		commandArray[1] = {[pid['radiateur']] = marche}
		if commande < 100 then
		    commandArray[2] = {[pid['radiateur']] = eco..' AFTER '..heatTime}
		end
	else
		log(pid['zone']..' : Temp='..temp..', Consigne='..consigne..', Pas de chauffage dans les '..pid['cycle']..' prochaines minutes')
		commandArray[pid['radiateur']]=arret
	end
==========================================

Au final, j'ai adopté ce script plutôt que le précédent (ne pas m'en vouloir !).
Avec ces modifications il est très lisible et beaucoup plus facile à implémenter.
Seul bémol : la maintenance de modules.lua nécessite une connexion de type putty/ssh, mais en dehors de mon réseau local le proxy de mon employeur m'en empêche ^_^

Re: chauffage PID

Publié : 25 nov. 2017, 14:04
par vil1driver
Merci de ton retour

ne pas rentrer dans la condition 'si on ne veut pas chauffer' n'est pas le problème normalement puisque l'on ne rentre pas non plus dans celle 'si l'on veut chauffer'

ton chauffage aurait du se couper de lui même après la durée de chauffe calculée et ne plus se relancer.

la condition 'si on ne veut pas chauffer' permet simplement de renvoyer régulièrement la commande Off par sécurité (pour systèmes sans retour d'état), mais ce n'est pas elle qui stop la chauffe.

mais tu as raison, autant faire en sorte d'y rentrer,
j'opte pour la solution 1

la solution 2 empêchant la relève cyclique des températures (même si pid['OnOff'] == 'Off') ce qui ne convient pas
c'est d'ailleurs ce que je faisais initialement avant de séparer les premières conditions pour les raisons citées, ce qui à mené à ce bug.
merci de l'avoir relevé.

concernant "OFF AFTER Cycle + 20 secondes", je ne rencontre aucun problème ici,
AFTER étant annulé par tout autre commande,
tu peux avoir plusieurs cycles 100% consécutifs sans interruption.

c'est étrange le comportement que tu décris :?

Re: chauffage PID

Publié : 25 nov. 2017, 16:33
par ogulf
Mon chauffage ne se coupait pas car dans le cas 100% je n'envoie pas le "OFF AFTER"...
Et un planning mal paramétré a passé le mode en Off sur un chauffage dont le dernier ordre était... chauffe sans condition !



En toute franchise, j'avoue que le coup du "AFTER 620" je n'en suis pas très sûr...
Pourtant j'avais bien un pb de chauffe sur plusieurs calculs "commande = 100" consécutifs.

Maintenant, pour ma défense, j'utilise le protocole X2D avec le dongle RFP1000 et le plugin adéquat (peut-être qu'un jour je me ferai un RFLink en 868 puisque depuis la R47 ce dernier sait gérer les ordres X2D ; mais en attendant je fais avec ce que j'ai ^_^).

Tous mes cycles étant sur 5 minutes... pour gérer 5 zones... Il est possible, je dis bien "possible", que le RFP1000 saturait en recevant 5 ordres X2D dans la même seconde (quelque soit l'ordre) et que les derniers ordres n'étaient tout simplement pas "envoyés" par le RFP1000... et donc pas reçus par les radiateurs !

Du coup en restant sur 5 zones et un cycle de 5 minutes, je crée un décalage avec une nouvelle entrée pid['decalage'] qui va de 0 à 4 (en fait les différentes valeurs du modulo 5) et depuis cette adaptation (plus les modifs déjà évoquées) mes radiateurs reçoivent bien tous les ordres. J'ai donc un ordre toutes les minutes, mais sur des zones différentes à chaque fois tant que je n'ai pas bouclé le cycle.
Il faudrait que je remette en fonction le "AFTER" sans condition pour voir.
Mais j'ai peur de la WAF répression si demain matin la SdB est à 16°C !! :lol: :lol:

Et si un jour je dois gérer une sixième zone, alors j'aurai des cycles de 6 minutes et je pourrai facilement traiter cette zone ajoutée avec le décalage supplémentaire "5" (ce qui fait bien 6 décalages : les 0 à 4 déja existants plus celui rajouté).



ps : j'ai vu pour la solution 2... J'ai dû sortir l'alimentation des 4 dernières valeurs... en les conditionnant par le cycle...
Du coup je confirme : la solution 1 est à privilégier du coup ;)

Re: chauffage PID

Publié : 03 déc. 2017, 14:53
par Cissou
Salut,

intéressant comme mode de pilotage,
une seule question reste dans mon esprit, au niveau de la consommation électrique ?
plus intéressant que l’hystérésis ?

Re: chauffage PID

Publié : 11 déc. 2017, 10:57
par jackslayter
bon cela fait 3 jours que ton script est en test et je dois dire que c'est pas mal, grâce à toi je gagne de l'argent en tout cas des kWh.
par contre comment ce rapprocher au max de la consigne ? je suis à -0.3 mais si je pouvais être à -0.1 ça serai super.
merci

Re: chauffage PID

Publié : 11 déc. 2017, 11:11
par vil1driver
Merci de ton retour

Un petit log aurait été un plus ;)

Essai d'augmenter Kp et Ki de 20 chacun
Il est possible que dans un premier temps ça dépasse la consigne

Re: chauffage PID

Publié : 11 déc. 2017, 11:43
par jackslayter
le log
4.png
4.png (86.47 Kio) Consulté 7864 fois
ok pour Kp et Ki de 20, je test

Re: chauffage PID

Publié : 11 déc. 2017, 17:44
par ogulf
Même phénomène chez moi.
Mais comme j'ai une jolie approche, pas trop "agressive", j'ai solutionné en mettant une consigne à 2 dixièmes de plus, et j'ai donc "la bonne" température :-)

Re: chauffage PID

Publié : 11 déc. 2017, 18:36
par jackslayter
Augmenter le kp et ki ma permis d'arriver à la consigne