In dit topic een voorbeeld hoe een warmtepomp, in dit geval een Ecolution Combi50 van Inventum, geregeld kan worden door middel van het meten van temperaturen en energieverbruik. De metingen worden gedaan mbv een “Arduino Ethernet” microcomputer en makkelijk verkrijgbare sensoren. Het doel van de regeling is het voorkomen van “bevriezing “van de warmtepomp waardoor deze in storing (AP3/AP4) gaat. Gedurende deze tijd, vaak 40 minuten, staat de warmtepomp warme lucht uit de woning naar buiten te blazen wat ten koste gaat van het rendement.
Zeer veel informatie over de warmtepomp kan gevonden worden op: Ervaringen, tips etc. ventiline/inventum warmtepomp
De regeling zoals hier beschreven draait al geruime tijd bij mij thuis met zo goed als geen problemen. Problemen ontstaan momenteel alleen bij harde wind waardoor de tegendruk op de uitlaat van de warmtepomp te groot wordt en de luchtstroming langs de condensor van de WP te klein.
Voor de metingen aan en het regelen van de warmtepomp is er geen enkele fysieke aanpassing aan de warmtepomp gedaan. Sensoren zijn mbv tiraps op de diverse leidingen aangebracht.
Een korte beschrijving van het systeem is niet mogelijk omdat er meerdere onderdelen bij betrokken zijn.
De verschillende onderdelen:
Menu 0_0: 0 ventilatie volume WP-bedrijf 18 (=180 m3/h)
Menu 0_1: 5 ventilatie stand 1 10
Menu 0_1: 6 ventilatie stand 2 21
Menu 0_1: 7 ventilatie stand 3 28
Deze instellingen werken voor mijn woning, voor andere woningen moeten deze empirisch worden vastgesteld.
De intentie van dit systeem om zoveel mogelijk warmte uit de warmtepomp te krijgen zonder dat de CV daar aan bijdraagt. Daarom is de WP op een separate thermostaat aangesloten. (CV staat niet als slaaf van de WP). De CV heeft dan ook een eigen thermostaat die naar gelang een halve tot een hele graad lager staat ingesteld dan die van de WP.
De regeling stuurt op een tweetal temperaturen die gemeten worden in de WP namelijk Koudgas (0,75 °C) en Uitblaaslucht (4,25 °C)
Ook deze waardes zijn in de praktijk vastgesteld. Door het observeren van de grafieken van de diverse gegevens in de database. Deze waardes gelden voor mijn woning. Andere WP-systemen en woningen zullen andere waardes hebben.
Bovenstaande temperaturen geven een goede indicatie of een AP3/AP4 situatie van WP aanstaande is. Over het algemeen is het verhogen van het ventilatievolume de oplossing. Dat is precies wat de Arduino regeling doet.

De stroomsensor ACS712-5A is aangesloten op de NUL- ader, zodat alle stroom die door de Ecolution gaat hier gemeten kan worden.
Bij de verschillende relais staat de ruststand van de relais vermeld. NO is Normally Open (R1 en R3). NC is Normally Closed (R2).
Om geen enkele verandering aan de Ecolution aan te brengen is mbv een extra perilexstekker en wandcontactdoos (WCD) een tussenstuk gemaakt waarin de relais e.d. zijn aangebracht onder de extra WCD. Dus de extra perilex stekker steekt in de originele WCD en de perilexstekker van de Ecolution steekt weer in de extra WCD. Het voordeel van deze ietwat omslachtige werkwijze is dat het altijd mogelijk is de Ecolution direct op de originele WCD aan te sluiten.
https://store.arduino.cc/arduino-ethernet-rev3-without-poe
https://store.arduino.cc/arduino-usb-2-serial-micro.
De laatste dient als stroomvoorziening is makkelijk om de Arduino te programmeren


b. DS18B20 temperatuursensoren
De waterdichte versie worden gebruikt voor temperatuurmetingen in natte/vochtige ruimtes in de Ecolution, zoals koudgas en uitblaaslucht.
Dit type sensor gebruikt het onewire protocol waardoor er maximaal 127 sensoren op de (digitale) inputpoort van de Arduino kunnen worden aangesloten.
Alle sensoren zijn met 3,3V voeding aangesloten, dus GEEN parasitaire voeding.
https://create.arduino.cc...sensor-and-arduino-9cc806
In totaal zijn er 8 sensoren van dit type geplaatst:
- Aanvoer en retour circulerend water WP (2)
- Aanvoer en retour circulerend water CV (2)
- Aanvoer koud water naar boiler WP (1)
- Aangezogen en uitgeblazen ventilatielucht WP (2), waterdichte versie!
- Koudgas van het koelsysteem in de WP (1), waterdichte versie!
De gewone DS18B20 zijn aan het leidingwerk buiten de WP en CV op de leidingen bevestigd mbv tiraps en warmtepasta.
Voor het echte meet en regel werk zijn in principe alleen de sensoren op de koudgas en de uitgeblazen lucht nodig. Maar voor beter inzicht in de werking van het gehele verwarmingssysteem geven de overige sensoren zeer veel informatie. Mbv deze extra sensoren is de bedrijfstoestand van de WP te herleiden. (A1 ventilatie; A2 CV-bedrijf; A3 Boiler-bedrijf).


c. DHT22 temperatuur/luchtvochtigheidsensor
Deze sensor hangt naast het aanzuigpunt in badkamer en meet de vochtigheid en temperatuur in de badkamer. Adhv de gemeten vochtigheid wordt relais R3 gestuurd.

In eerste instantie hing de sensor in het afzuigpunt van de badkamer, maar dat resulteerde in een defecte sensor omdat meegezogen stof en vuil zich in de sensor ophoopte en zorgde voor continue 100% vochtigheid.
Een ander probleem is dat wanneer de warmtepomp niet als verwarming dienst doet het ventiltievolume relatief laag is en daardoor de badkamer vochtiger blijft door drogende handdoeken. De WP bleef zeer lang in de hoogste ventilatiestand staan zonder duidelijk toegevoegde waarde. Daarom is een schakelaar toegevoegd waarmee de software routine uitgeschakeld kan worden. https://www.arduino.cc/en/Tutorial/Button
De DHT22 en extra relais (R3) zijn niet noodzakelijk voor de werking het meet en regelsysteem, maar tijdens het stookseizoen wel makkelijk.
d. ACS712-5A stroomsensor (Hall-sensor) en LM404 externe referentiespanning
Deze sensor is aangesloten op de nul van de perilex, op deze manier meet je altijd het gehele stroomverbruik van de Ecolution. Let op dat er wel een 5A exemplaar wordt gebruikt, met ACS712 voor grotere vermogens moet er in het Arduino programma een waarde (mVperAmp) worden aangepast. Deze staan in het betreffende datasheet vermeld. YouTube: Stroom Meten met Arduino DEEL 1
Voor een wat nauwkeurigere meting, tov de fluctuerende referentiespanning van 5V, van is een externe stabiele referentiespanning (LM4040) aangesloten. https://www.hobbyelectron...ltage-reference-breakout/
Gebruik de 4,096V referentiespanning die dit bordje geeft. De Arduino heeft een meetnauwkeurigheid van 1024 stappen. Deze link geeft meer duidelijkheid. http://henrysbench.capnfa...ltage-reference-tutorial/
Mocht je nog nauwkeuriger willen meten kijk dan: YouTube: Stroom Meten met Arduino DEEL 2


DIT IS BELANGRIJK,vergeten kan het opblazen van de Arduino tot gevolg hebben!
Indien er geen gebruik wordt gemaakt van een externe referentiespanning, dan de constante “const float Vref” aanpassen van 4,096 naar 5,0.
In de sectie void setup() de regel “analogReference(EXTERNAL);” verwijderen.
e. Relais
https://www.hobbyelectron...ule-2-kanaals-5v/#reviews]
Dit relais is voorzien van opto-koppeling om de 230V los te koppelen van de Arduino. Een ander type relais kan anders reageren op de output van de digitale poorten van de Arduino en dat geeft verwarrende resultaten.

De 3 relais zijn aangesloten op:
R1: Tussen de L3 en L2 fase van de perilex
R2: In de L2 fase van de perilex
R3: Tussen de L3 en L1 fase (puls relais)
NB. L1/L2/L3 zijn geen fase in de zin van een 400V installaties, maar alleen de aanduiding op de Perilex stekkers en wandcontactdozen.
De L3 fase van de perilex is de fase waar constant 230V op staat en is stand 1 van de Ecolution fan. Als de fan in stand 2 staat, dan staan L3 en L2 met elkaar in verbinding. Tot slot staan bij stand 3 van de fan L3 en L1 met elkaar in verbinding. Met relais (R3) is het mogelijk om een puls van 1 seconde te geven zodat de timer van de Ecolution start en gedurende, in mijn geval, 30 minuten de fan in hoge ventilatiestand staat.
Zoals vermeld kan relais (R3) vervallen bij het weglaten van de DHT22 sensor.
f. Aansluiten van de sensoren.
De software van de Arduino schrijft/leest specifieke poorten. Hier een lijst met aansluitingen op de Arduino waarop de verschillende componenten zijn aangesloten.
Arduino
Setup:
Initialiseren van sensoren en ophalen van de laatst bekende totaal verbruikte vermogen van de WP uit de database.
Hoofdroutine:
Regelt de interval van data verzamelen. Er is geen klok nodig in het programma, de timing is gebaseerd op de klokfrequentie van de Arduino. Dataopslag krijgt automatisch een timestamp (ts) mee bij het toevoegen van data in de database. De metingen hebben een interval van 1 minuut.
De hoofdroutine is onderverdeeld in de volgende subroutines:
- Uitlezen van de DS18B20 temperatuursensoren. Om de programmacode eenvoudig en kort te houden worden de temperaturen van de sensoren in een array gezet en naar de database geschreven. De MAC-adressen van de sensoren staan ook in een array om controle te houden over de volgorde waarin de sensoren worden uitgelezen. wat ook de volgorde is waarin de data naar de database wordt geschreven.
De resolutie van de DS18B20 staat standaard op 12 bit. Om aanpassing mogelijk te maken is een routine , in Setup, toegevoegd.
- Routine ter voorkoming van het bevriezen van de warmtepomp met daarin het aansturen van de verschillende relais. Adhv de temperaturen van het koudgas en uitgeblazen ventilatielucht worden de verschillende relais gestuurd waardoor de WP harder of zachter draait.
- Badkamer routine meet en regelt de vochtigheid. Eventueel kan deze routine uitgeschakeld worden dmv een schakelaar. Indien de vochtigheid van de badkamer boven de 96% komt krijgt WP een puls van 1 seconde waardoor de timer van de fan ingeschakeld word. Als de timer start wordt de routine ter voorkoming van bevriezen gestaakt (reset).
- Meten van het actuele vermogen en sommatie van totaal verbruikte vermogen.
Het totaal verbruikte vermogen wordt in de database opgeslagen en bij een eventuele herstart van de Arduino zal deze weer uitgelezen worden uit de database zodat de registratie van het verbruikte vermogen correct blijft. De opslag van het totaal verbruikte vermogen zou ook in eeprom kunnen maar gezien de frequente metingen zou de eeprom vrij snel de geest kunnen geven.
- Bedrijfsmodus warmtepomp bepalen adhv diverse vlaggen en een virtuele stand van de perilexschakelaar. Mbv de diverse vlaggen wordt hier de stand van de Perilex bepaald. Een stand 4 is toegevoegd om aan te geven dat de WP in “anti-vries” stand staat.
- Gegevens naar database schrijven. Zie link onder punt 7.
Het programma (sketch) van de Arduino. In de sketch is veel commentaar aangebracht zodat de werking duidelijk zou moeten zijn. Een punt van aandacht is dat het programma strikt voor een 16-bits processor is geschreven. Bij gebruik van een 32-bits processor kunnen er mogelijk vreemde resultaten optreden.
https://www.tweaking4all....duino-ethernet-data-push/
https://www.tweaking4all....duino-ethernet-data-pull/
Om de tabel, voor dit systeem, in de database aan te maken de volgende SQL code:
De Arduino schrijft alle meetgegevens naar de database, hiervoor wordt op de hostingsite een PHP programma (add_data.php) aangeroepen dat de data ontvangt en wegschrijft naar de database.
Hier de generieke module dbconnect.php met daarin de inloggegevens voor de database:
Indien de Arduino (her)start wordt in de setup sectie van de computer de laatste data met totaal verbruikte energie uit de database opgehaald. Hiervoor is nog een apart klein PHP-bestandje (kwhdata.php) aangemaakt op de hostingsite. Dit programmatje maakt eenvoudig weg een webpagina met alleen de gewenste data. Deze data wordt serieel ingelezen en omgezet in een bruikbare waarde.
Zeer veel informatie over de warmtepomp kan gevonden worden op: Ervaringen, tips etc. ventiline/inventum warmtepomp
De regeling zoals hier beschreven draait al geruime tijd bij mij thuis met zo goed als geen problemen. Problemen ontstaan momenteel alleen bij harde wind waardoor de tegendruk op de uitlaat van de warmtepomp te groot wordt en de luchtstroming langs de condensor van de WP te klein.
Voor de metingen aan en het regelen van de warmtepomp is er geen enkele fysieke aanpassing aan de warmtepomp gedaan. Sensoren zijn mbv tiraps op de diverse leidingen aangebracht.
Een korte beschrijving van het systeem is niet mogelijk omdat er meerdere onderdelen bij betrokken zijn.
De verschillende onderdelen:
- Warmtepomp instellingen
- Elektrotechnische aanpassing tussen Perilex wandcontactdoos en Perilex stekker van de warmtepomp
- Hardware voor meten van temperaturen en energieverbruik
- Arduino Ethernet microcomputer met USB2Serial module
- DS18B20 temperatuur sensor
- DHT22 vochtigheidssensor (en temperatuur)
- ACS712-5A Hall-stroomsensor met LM4040 stabiele externe spanningsreferentie
- Relais
- Aansluiten van de sensoren
- Software voor meten en regelen
- Opslaan van meetgegevens in een (externe) database
Instellingen van de warmtepomp
Voor de werking van het meet- en regelsysteem zoals hier beschreven zijn de volgende waardes in de Ecolution ingesteld.Menu 0_0: 0 ventilatie volume WP-bedrijf 18 (=180 m3/h)
Menu 0_1: 5 ventilatie stand 1 10
Menu 0_1: 6 ventilatie stand 2 21
Menu 0_1: 7 ventilatie stand 3 28
Deze instellingen werken voor mijn woning, voor andere woningen moeten deze empirisch worden vastgesteld.
De intentie van dit systeem om zoveel mogelijk warmte uit de warmtepomp te krijgen zonder dat de CV daar aan bijdraagt. Daarom is de WP op een separate thermostaat aangesloten. (CV staat niet als slaaf van de WP). De CV heeft dan ook een eigen thermostaat die naar gelang een halve tot een hele graad lager staat ingesteld dan die van de WP.
De regeling stuurt op een tweetal temperaturen die gemeten worden in de WP namelijk Koudgas (0,75 °C) en Uitblaaslucht (4,25 °C)
Ook deze waardes zijn in de praktijk vastgesteld. Door het observeren van de grafieken van de diverse gegevens in de database. Deze waardes gelden voor mijn woning. Andere WP-systemen en woningen zullen andere waardes hebben.
Bovenstaande temperaturen geven een goede indicatie of een AP3/AP4 situatie van WP aanstaande is. Over het algemeen is het verhogen van het ventilatievolume de oplossing. Dat is precies wat de Arduino regeling doet.
Elektrotechnische aanpassing
Dit is het onderdeel met het grootste risico, er staat 230V op de aansluitingen. Hieronder staat het schema zoals het bij mij thuis is aangesloten en dient alleen als voorbeeld. Voor iedere andere situatie moet iedereen zelf uitzoeken/controleren of het veilig en verantwoord is om aanpassingen te maken en is geheel op eigen risico.
De stroomsensor ACS712-5A is aangesloten op de NUL- ader, zodat alle stroom die door de Ecolution gaat hier gemeten kan worden.
Bij de verschillende relais staat de ruststand van de relais vermeld. NO is Normally Open (R1 en R3). NC is Normally Closed (R2).
Om geen enkele verandering aan de Ecolution aan te brengen is mbv een extra perilexstekker en wandcontactdoos (WCD) een tussenstuk gemaakt waarin de relais e.d. zijn aangebracht onder de extra WCD. Dus de extra perilex stekker steekt in de originele WCD en de perilexstekker van de Ecolution steekt weer in de extra WCD. Het voordeel van deze ietwat omslachtige werkwijze is dat het altijd mogelijk is de Ecolution direct op de originele WCD aan te sluiten.
Hardware voor meten van temperaturen en energieverbruik
a. Arduino Ethernet microcomputer met USB2Serial modulehttps://store.arduino.cc/arduino-ethernet-rev3-without-poe
https://store.arduino.cc/arduino-usb-2-serial-micro.
De laatste dient als stroomvoorziening is makkelijk om de Arduino te programmeren


b. DS18B20 temperatuursensoren
De waterdichte versie worden gebruikt voor temperatuurmetingen in natte/vochtige ruimtes in de Ecolution, zoals koudgas en uitblaaslucht.
Dit type sensor gebruikt het onewire protocol waardoor er maximaal 127 sensoren op de (digitale) inputpoort van de Arduino kunnen worden aangesloten.
Alle sensoren zijn met 3,3V voeding aangesloten, dus GEEN parasitaire voeding.
https://create.arduino.cc...sensor-and-arduino-9cc806
In totaal zijn er 8 sensoren van dit type geplaatst:
- Aanvoer en retour circulerend water WP (2)
- Aanvoer en retour circulerend water CV (2)
- Aanvoer koud water naar boiler WP (1)
- Aangezogen en uitgeblazen ventilatielucht WP (2), waterdichte versie!
- Koudgas van het koelsysteem in de WP (1), waterdichte versie!
De gewone DS18B20 zijn aan het leidingwerk buiten de WP en CV op de leidingen bevestigd mbv tiraps en warmtepasta.
Voor het echte meet en regel werk zijn in principe alleen de sensoren op de koudgas en de uitgeblazen lucht nodig. Maar voor beter inzicht in de werking van het gehele verwarmingssysteem geven de overige sensoren zeer veel informatie. Mbv deze extra sensoren is de bedrijfstoestand van de WP te herleiden. (A1 ventilatie; A2 CV-bedrijf; A3 Boiler-bedrijf).


c. DHT22 temperatuur/luchtvochtigheidsensor
Deze sensor hangt naast het aanzuigpunt in badkamer en meet de vochtigheid en temperatuur in de badkamer. Adhv de gemeten vochtigheid wordt relais R3 gestuurd.

In eerste instantie hing de sensor in het afzuigpunt van de badkamer, maar dat resulteerde in een defecte sensor omdat meegezogen stof en vuil zich in de sensor ophoopte en zorgde voor continue 100% vochtigheid.
Een ander probleem is dat wanneer de warmtepomp niet als verwarming dienst doet het ventiltievolume relatief laag is en daardoor de badkamer vochtiger blijft door drogende handdoeken. De WP bleef zeer lang in de hoogste ventilatiestand staan zonder duidelijk toegevoegde waarde. Daarom is een schakelaar toegevoegd waarmee de software routine uitgeschakeld kan worden. https://www.arduino.cc/en/Tutorial/Button
De DHT22 en extra relais (R3) zijn niet noodzakelijk voor de werking het meet en regelsysteem, maar tijdens het stookseizoen wel makkelijk.
d. ACS712-5A stroomsensor (Hall-sensor) en LM404 externe referentiespanning
Deze sensor is aangesloten op de nul van de perilex, op deze manier meet je altijd het gehele stroomverbruik van de Ecolution. Let op dat er wel een 5A exemplaar wordt gebruikt, met ACS712 voor grotere vermogens moet er in het Arduino programma een waarde (mVperAmp) worden aangepast. Deze staan in het betreffende datasheet vermeld. YouTube: Stroom Meten met Arduino DEEL 1
Voor een wat nauwkeurigere meting, tov de fluctuerende referentiespanning van 5V, van is een externe stabiele referentiespanning (LM4040) aangesloten. https://www.hobbyelectron...ltage-reference-breakout/
Gebruik de 4,096V referentiespanning die dit bordje geeft. De Arduino heeft een meetnauwkeurigheid van 1024 stappen. Deze link geeft meer duidelijkheid. http://henrysbench.capnfa...ltage-reference-tutorial/
Mocht je nog nauwkeuriger willen meten kijk dan: YouTube: Stroom Meten met Arduino DEEL 2


DIT IS BELANGRIJK,vergeten kan het opblazen van de Arduino tot gevolg hebben!
Indien er geen gebruik wordt gemaakt van een externe referentiespanning, dan de constante “const float Vref” aanpassen van 4,096 naar 5,0.
In de sectie void setup() de regel “analogReference(EXTERNAL);” verwijderen.
e. Relais
https://www.hobbyelectron...ule-2-kanaals-5v/#reviews]
Dit relais is voorzien van opto-koppeling om de 230V los te koppelen van de Arduino. Een ander type relais kan anders reageren op de output van de digitale poorten van de Arduino en dat geeft verwarrende resultaten.

De 3 relais zijn aangesloten op:
R1: Tussen de L3 en L2 fase van de perilex
R2: In de L2 fase van de perilex
R3: Tussen de L3 en L1 fase (puls relais)
NB. L1/L2/L3 zijn geen fase in de zin van een 400V installaties, maar alleen de aanduiding op de Perilex stekkers en wandcontactdozen.
De L3 fase van de perilex is de fase waar constant 230V op staat en is stand 1 van de Ecolution fan. Als de fan in stand 2 staat, dan staan L3 en L2 met elkaar in verbinding. Tot slot staan bij stand 3 van de fan L3 en L1 met elkaar in verbinding. Met relais (R3) is het mogelijk om een puls van 1 seconde te geven zodat de timer van de Ecolution start en gedurende, in mijn geval, 30 minuten de fan in hoge ventilatiestand staat.
Zoals vermeld kan relais (R3) vervallen bij het weglaten van de DHT22 sensor.
f. Aansluiten van de sensoren.
De software van de Arduino schrijft/leest specifieke poorten. Hier een lijst met aansluitingen op de Arduino waarop de verschillende componenten zijn aangesloten.
Arduino
Sensor | Arduino pin | Voeding |
---|---|---|
DS18B20 | digitaal 9 | 3,3V |
DHT22 | digitaal 6 | 5V |
Relais 1 | digitaal 7 | 5V |
Relais 2 | digitaal 5 | 5V |
Relais 3 | digitaal 8 | 5V |
LM4040 | AREF | 5V |
ACS712 | analoog A0 | 5V |
Schakelaar | digitaal 2 | 5V |
Software voor meten en regelen
Het programma voor de Arduino is een lineair programma dat, na de setup, de verschillende functies achter elkaar doorloopt in een eindeloze lus.Setup:
Initialiseren van sensoren en ophalen van de laatst bekende totaal verbruikte vermogen van de WP uit de database.
Hoofdroutine:
Regelt de interval van data verzamelen. Er is geen klok nodig in het programma, de timing is gebaseerd op de klokfrequentie van de Arduino. Dataopslag krijgt automatisch een timestamp (ts) mee bij het toevoegen van data in de database. De metingen hebben een interval van 1 minuut.
De hoofdroutine is onderverdeeld in de volgende subroutines:
- Uitlezen van de DS18B20 temperatuursensoren. Om de programmacode eenvoudig en kort te houden worden de temperaturen van de sensoren in een array gezet en naar de database geschreven. De MAC-adressen van de sensoren staan ook in een array om controle te houden over de volgorde waarin de sensoren worden uitgelezen. wat ook de volgorde is waarin de data naar de database wordt geschreven.
De resolutie van de DS18B20 staat standaard op 12 bit. Om aanpassing mogelijk te maken is een routine , in Setup, toegevoegd.
- Routine ter voorkoming van het bevriezen van de warmtepomp met daarin het aansturen van de verschillende relais. Adhv de temperaturen van het koudgas en uitgeblazen ventilatielucht worden de verschillende relais gestuurd waardoor de WP harder of zachter draait.
- Badkamer routine meet en regelt de vochtigheid. Eventueel kan deze routine uitgeschakeld worden dmv een schakelaar. Indien de vochtigheid van de badkamer boven de 96% komt krijgt WP een puls van 1 seconde waardoor de timer van de fan ingeschakeld word. Als de timer start wordt de routine ter voorkoming van bevriezen gestaakt (reset).
- Meten van het actuele vermogen en sommatie van totaal verbruikte vermogen.
Het totaal verbruikte vermogen wordt in de database opgeslagen en bij een eventuele herstart van de Arduino zal deze weer uitgelezen worden uit de database zodat de registratie van het verbruikte vermogen correct blijft. De opslag van het totaal verbruikte vermogen zou ook in eeprom kunnen maar gezien de frequente metingen zou de eeprom vrij snel de geest kunnen geven.
- Bedrijfsmodus warmtepomp bepalen adhv diverse vlaggen en een virtuele stand van de perilexschakelaar. Mbv de diverse vlaggen wordt hier de stand van de Perilex bepaald. Een stand 4 is toegevoegd om aan te geven dat de WP in “anti-vries” stand staat.
- Gegevens naar database schrijven. Zie link onder punt 7.
Het programma (sketch) van de Arduino. In de sketch is veel commentaar aangebracht zodat de werking duidelijk zou moeten zijn. Een punt van aandacht is dat het programma strikt voor een 16-bits processor is geschreven. Bij gebruik van een 32-bits processor kunnen er mogelijk vreemde resultaten optreden.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
| #include <SPI.h> //serial interface library #include <Ethernet.h> //ethernet library #include <OneWire.h> //one-wire library #include <DHT.h> //DHT sensor library #define ONE_WIRE_BUS_PIN 9 //DS18B20 data pin 9 (digitaal) #define relaisL1Pin 5 //relais(R2) in L1 fase Perilex #define relaisL2Pin 7 //relais(R1) tussen L3 & L2 fase Perilex #define pulseL1Pin 8 //relais(R3) tussen L3 & L1 fase Perilex timer puls ventilatie #define ISNAN(X) (!((X)==(X))) //check output DHT22 op numerieke waarde (NAN = Not A Number) #define DHTPIN 6 //DHT22 data pin 6 (digitaal) #define DHTTYPE DHT22 //type vochtigheidssensor DHT22 #define schakelaar 2 //schakelaar DHT22-routine pin 2 (digitaal) #define stroomSensor A0 //ACS712 data pin A0 (analoog) //#define DEBUG //als alles werkt deze regel veranderen in opmerking! OneWire oneWire(ONE_WIRE_BUS_PIN); //initialiseer communicatie oneWire met DS18B20 DHT dht(DHTPIN, DHTTYPE); //initialiseer DHT22 sensor voor standaard 16mhz Arduino //***** ethernet settings byte macAdress[] = {0x90, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}; //MAC-adres Arduino Ethernet EthernetClient client; //start ethernet client char serverName[] = "my.hosting.site.nl"; //IP-adres/name dataserver char kwhserver[] = "www.your_web_hosting.nl"; //webpagina met totaal verbruikt vermogen //***** constanten voor hoofdroutine const unsigned int dataInterval = 60000; //tijd tussen datapunten (10000 = 10 seconds) //***** constanten voor anti-bevriezingsroutine const byte antiPendel = 15; //min aantal cycli (minuten) fan aan/uit (stand 1/2) const float lowOut = 4.25; //ondergrens uitblaas temperatuur const float lowGas = 0.5; //ondergrens koudgas temperatuur //***** constanten voor vochtigheidsmetingroutine const byte humHigh = 96; //bovengrens vochtigheid badkamer const byte lastPulse = 90; //wachtijd tot volgende puls fan stand 3 //***** constanten voor DS18B20 temperaturen const byte numSensors = 8; //aantal DS18B20 sensoren const byte sensorArray[numSensors][8] = { //array met MAC-adressen DS18B20 {0x28, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}, //0 CVin {0x28, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}, //1 CVuit {0x28, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}, //2 WPin {0x28, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}, //3 WPuit {0x28, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}, //4 water {0x28, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}, //5 aanzuig {0x28, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}, //6 uitblaas {0x28, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX} //7 koudgas }; //***** constanten voor ACS712 stroommeten const byte mVperAmp = 185; //milivolt per Ampere ACS712-5A const byte Vac = 230; //netspanning (V) const byte stroomOffset = 8; //correctie voor 0 meting ACS-712 const float Vref = 4.096; //referentie spanning (V), extern! const float rms = 0.707107; //omrekeningsfactor om Prms te berekenen (1/sqrt(2)) //***** variabelen voor hoofdroutine unsigned long previousMillis; unsigned long currentMillis; //***** variabelen voor DS18B20 temperatuurmeten float temparray[numSensors]; //array met temperaturen DS18B20 sensoren byte data[12]; //array met temepratuur data uit DS18B20 //***** variabelen voor anti-bevriezingsroutine boolean wpFanSt2 = false; //vlag relaisbediening WP fan (stand 2) float uitblaas = 0; //temperatuur uitgeblazen lucht WP float koudgas = 0; //temperatuur koudgas WP byte PerilexSt = 1; //stand perilexschakelaar keuken (virtueel) byte countFanSt2 = 0; //telt cycli fan stand 2 byte countFanSt1 = 0; //telt cycli fan stand 1 //***** variabelen voor DHT22 vochtigheidsmeting boolean dehumidify = false; //vlag fan hoogste toeren voor badkamer boolean wpFanSt3 = false; //vlag ventilatie timer WP (stand 3) byte countFanSt3 = 0; //telt cycli dehumify aan (30 minuten) (stand 3) float dht22Hum = 0; //luchtvochtigheid DHT22 float dht22Temp = 0; //temperatuur DHT22 //***** variabelen voor ACS712 stroommeten unsigned long startMillis; unsigned long stopMillis; unsigned long duration; float kWh = 0; //kilowattuur float kWhTot = 0; //kilowattuur sommatie float Vrms = 0; //Vout_stroom rms float Arms = 0; //amperage rms float Prms = 0; //vermogen rms void setup() { Ethernet.begin(macAdress); //initialiseer ethernet #ifdef DEBUG //only use serial when debugging Serial.begin(9600); //initialiseer serial output #endif analogReference(EXTERNAL); //gebruik externe referentie spanning pinMode(stroomSensor, INPUT); //analog data pin is input pinMode(schakelaar, INPUT); //datapin schakelaar op input //Initiliseer relais pinMode(relaisL1Pin, OUTPUT); //relais-pinnen als output digitalWrite(relaisL1Pin, HIGH); pinMode(relaisL2Pin, OUTPUT); digitalWrite(relaisL2Pin, HIGH); pinMode(pulseL1Pin, OUTPUT); digitalWrite(pulseL1Pin, HIGH); //***** instellen resolutie DS18B20 for (byte i = 0; i < numSensors; i++) { oneWire.reset(); oneWire.select(sensorArray[i]); oneWire.write(0x4E); oneWire.write(0); oneWire.write(0); oneWire.write(0x7F); //0x7F = 12 bit, 0x5F = 11 bit, 0x3F = 10 bit; 0x1F = 9 bit oneWire.write(0x48); } delay(750); //vertraging om DS18B20 ROM te schrijven. //***** einde instellen DS18B20 dht.begin(); //initialiseer DHT22 kWhTot = strTofloat(connectAndRead()); //haal totaal verbuikte energie op uit database startMillis = millis(); //start tijdmeting energieverbruik } void loop() { //***** hoofdroutine 1 x per minuut (cyclus) uitvoeren currentMillis = millis(); //huidige tijd if ((unsigned long)(currentMillis - previousMillis) >= dataInterval) { //rollover no problem if (client.connect(serverName, 80)) { //alleen met verbinding routines uitvoeren //***** routine uitlezen DS18B20 for (byte i = 0; i < numSensors; i++) { oneWire.reset(); //start conversie in niet parasiet modus oneWire.select(sensorArray[i]); oneWire.write(0x44, 0); //0 = sensor met aparte voeding, 1 = sensor met parsitaire voeding oneWire.reset(); //selecteer bepaalde DS18B20 oneWire.select(sensorArray[i]); oneWire.write(0xBE); // Read Scratchpad for (byte i = 0; i < 9; i++) {data[i] = oneWire.read();} //lees sensor data //converteer data naar temperatuur en sla temp.(ยบC) op in array temparray[i] = ((data[1] << 8) | data[0]) / 16.0; } //***** einde routine uitlezen DS18B20 //***** routine voorkom bevriezen WP (relais) uitblaas = temparray[6]; //maak temperatuur uitgeblazen lucht inzichtelijk koudgas = temparray[7]; //maak temperatuur koudgas inzichtelijk if (!wpFanSt2) { //indien fan in stand 1 (perilex) if (countFanSt1 < antiPendel) {countFanSt1++;} //verhoog aantal minuten fan uit, voorkom pendelen else if (uitblaas <= lowOut || koudgas <= lowGas) { //antipendel en 1 van de temperaturen te laag, fan stand 2 digitalWrite(relaisL1Pin, LOW); //L1 relais open, actief (voorkom problemen) delay(12); //reactietijd relais < 10ms. digitalWrite(relaisL2Pin, LOW); //L2 relais dicht, actief wpFanSt2 = true; //vlag fan stand countFanSt1 = 0; //reset teller (stand 1) } } else { //indien fan in stand 2 (perilex) if (countFanSt2 < antiPendel) {countFanSt2++;} //aantal minuten fan stand 2, voorkom pendelen else if (uitblaas > (lowOut + 0.5) && koudgas > (lowGas + 0.25)) { //fan minimum tijd aan, beide temperaturen ok, fan stand 1 digitalWrite(relaisL2Pin, HIGH); //L2 relais open, inactief delay(12); //reactietijd relais < 10ms. digitalWrite(relaisL1Pin, HIGH); //L1 relais dicht, inactief wpFanSt2 = false; //vlag fan stand1 countFanSt2 = 0; //reset teller (stand 2) } } //***** einde relais routine WP //***** relais routine reguleren vochtigheid badkamer (DHT22 & relais) dht22Hum = dht.readHumidity(); //lees humidity DHT22 sensor dht22Temp = dht.readTemperature(); //lees temperatuur DHT22 sensor if(ISNAN(dht22Hum) | ISNAN(dht22Temp)) { //check op numerieke output DHT22 dht22Hum = 0; //vul 0 in voor database dht22Temp = 0; } if (!digitalRead(schakelaar)) { //automatische regeling ingeschakeld? if (dehumidify) { if (countFanSt3 >= lastPulse) { //is laatste puls meer dan 1,5 uur geleden? dehumidify = false; //reset vlag fan hoogste stand countFanSt3 = 0; //reset teller (stand 3) } else { countFanSt3++; if (countFanSt3 == 30) {wpFanSt3 = false;} //30 minuten fan stand 3 } } else if (dht22Hum >= humHigh) { //indien vochtigheid >=96%, fan stand 3 dehumidify = true; //vlag fan hoogste stand wpFanSt3 = true; //vlag timer WP if (wpFanSt2) { //indien CV-antivries bedrijf stop deze routine wpFanSt2 = false; //vlag fan lage toeren countFanSt1 = 0; //reset teller (stand 1) countFanSt2 = 0; //reset teller (stand 2) digitalWrite(relaisL2Pin, HIGH); delay(12); //reactietijd relais < 10ms. } digitalWrite(pulseL1Pin, LOW); //start puls op L1 (stand 3) delay(1000); //1 sec. vertraging voor puls digitalWrite(pulseL1Pin, HIGH); //einde puls } } //***** einde relais routine badkamer //***** routine meting energieverbruik Vrms = getVpp() / 2.0 * rms; //bereken mV adh input waarde ACS712 Arms = Vrms * 1000.0 / mVperAmp; //berekend gemiddeld Amperage Prms = (Arms * Vac) - stroomOffset; stopMillis = millis(); duration = stopMillis - startMillis; startMillis = stopMillis; kWh = Prms * duration / 60 / 60 / 1000000.0; kWhTot += kWh; //***** einde routine meting energieverbruik //***** routine bepaal virtuele stand perilexschakelaar en bedrijfsstand WP if (wpFanSt3 && wpFanSt2) {PerilexSt = 4;} //dehumidify en CV-antivries else if (wpFanSt3) {PerilexSt = 3;} //dehumidify en CV else if (wpFanSt2) {PerilexSt = 2;} //CV-antivries else {PerilexSt = 1;} //CV of boiler //***** einde routine perilexschakelaar //***** schrijf data naar database client.print("GET http://www.your_web_hosting.nl/php//add_data.php?"); for (byte i = 1; i < numSensors + 1; i++) { if (i > 1) {client.print("&");} //ampersand toevoegen na eerste sensor client.print("tempsensor"); client.print(i); client.print("="); client.print(temparray[i - 1], 3); //opslag temp sensor 1 in temparray(0), etc. } client.print("&fanhighlow="); //stand perilex client.print(PerilexSt); client.print("&humidity="); //humidity DHT22 client.print(dht22_hum, 1); client.print("&temperature="); //temperature DHT22 client.print(dht22_tmp, 1); client.print("&prms="); //actueel vermogen (Watt client.print(Prms, 0); client.print("&kwhtot="); //totaal verbruikt vermogen (kWh) client.print(kWhTot, 3); client.println(" HTTP/1.1"); //spatie voor HTTP moet! client.print("Host: "); client.println(server); client.println("Connection: close"); //data verzonden, sluit database client.println(); client.println(); client.stop(); #ifdef DEBUG //only use serial when debugging Serial.print("koudgas = "); Serial.print(koudgas, 3); Serial.print(" uitblaas = \t"); Serial.println(uitblaas, 3); #endif previousMillis = currentMillis; //starttijd volgende cyclus van 1 minuut } } else {Ethernet.maintain();} } //***** einde hoofdroutine //***** functie bepaal inputvoltage ACS712 (AC-meting) float getVpp() { float result; int readValue; //data van sensor int maxValue = 0; //max. gemeten waarde int minValue = 1024; //min. gemeten waarde unsigned long start_time = millis(); while ((millis() - start_time) < 1000) { //meting gedurende 1 seconde readValue = analogRead(stroomSensor); if (readValue > maxValue) {maxValue = readValue;} //opslag max. waarde sensor if (readValue < minValue) {minValue = readValue;} //opslag min. waarde sensor } result = ((maxValue - minValue) * Vref) / 1024.0; //Vref = 4.096V if (result < 0) {result = 0.0;} return result; } //***** functie verbind met webpage met laatste data total vermogen verbruikt String connectAndRead() { Ethernet.begin(macAdress); if (client.connect(kwhserver, 80)) { client.print("GET http://www.your_web_hosting.nl/php/kwhdata.php"); return readPage(); } } //***** functie lees webpagina, sla alles op tussen '<' en '>' String readPage() { boolean startRead = false; //bezig met lezen? byte stringPos = 0; //string index teller char inString[9]; //string voor serial data memset(&inString, 0, 9); //clear inString memory while (true) { if (client.available()) { char c = client.read(); if (c == '<' ) {startRead = true;} //'<' begining character, start reading else if (startRead) { if (c != '>') { //'>' ending character, stop reading inString[stringPos] = c; stringPos ++; } else { //ready, disconnect startRead = false; client.stop(); client.flush(); return inString; } } } } } //***** functie coverteer string naar decimaal getal float strTofloat(String str) { char carray[str.length() + 1]; //determine size of array str.toCharArray(carray, sizeof(carray)); //put str into an array return atof(carray); } |
(Externe) Database
Het beschreven systeem slaat alle meetgegevens op in een MYSQL database op een hostingsite, in een tabel genaamd “temperature”. De Arduino en PHP routines voor het opslaan en teruglezen van data naar/uit een database komen van de onderstaande site.https://www.tweaking4all....duino-ethernet-data-push/
https://www.tweaking4all....duino-ethernet-data-pull/
Om de tabel, voor dit systeem, in de database aan te maken de volgende SQL code:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| CREATE TABLE `yourhostingsite`.`temperature` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'unique ID', `event` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Event Date and Time', `cvin` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `cvuit` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `wpin` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `wpuit` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `wtw` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `wpzuig` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `wpblaas` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `koudgas` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `fanhighlow` VARCHAR( 4 ) NOT NULL COMMENT 'Stand perilex', `humidity` VARCHAR( 7 ) NOT NULL COMMENT '(%)', `temperature` VARCHAR( 7 ) NOT NULL COMMENT '(ºC)', `prms` VARCHAR( 7 ) NOT NULL COMMENT '(W)', `kwhtot` VARCHAR( 9 ) NOT NULL COMMENT '(kWh)', INDEX ( `event` ) ) ENGINE = InnoDB; |
De Arduino schrijft alle meetgegevens naar de database, hiervoor wordt op de hostingsite een PHP programma (add_data.php) aangeroepen dat de data ontvangt en wegschrijft naar de database.
PHP:
1
2
3
4
5
6
| include("dbconnect.php"); //Connect to MySQL if ($mysqli->connect_error > 0) {die('Unable to connect to database [' . $mysqli->connect_error . ']');} //Prepare the SQL statement $SQL = "INSERT INTO yourhostingsite.temperature (cvin ,cvuit ,wpin ,wpuit ,wtw ,wpblaas ,koudgas ,wpzuig ,fanhighlow ,humidity ,temperature ,prms ,kwhtot) VALUES ('".$_GET["tempsensor1"]."', '".$_GET["tempsensor2"]."', '".$_GET["tempsensor3"]."', '".$_GET["tempsensor4"]."', '".$_GET["tempsensor5"]."', '".$_GET["tempsensor6"]."', '".$_GET["tempsensor7"]."', '".$_GET["tempsensor8"]."', '".$_GET["fanhighlow"]."', '".$_GET["humidity"]."', '".$_GET["temperature"]."', '".$_GET["prms"]."', '".$_GET["kwhtot"]."')"; $mysqli->query($SQL); //Execute SQL statement $mysqli->close() |
Hier de generieke module dbconnect.php met daarin de inloggegevens voor de database:
PHP:
1
2
3
4
5
6
7
| $DBServer = 'localhost'; $DBUser = 'USERNAME'; $DBPass = 'WACHTWOORD'; $DBName = 'NAAM VAN DE DATABASE'; $mysqli = new mysqli($DBServer, $DBUser, $DBPass, $DBName); // check connection if ($mysqli->connect_error > 0) {die('Unable to connect to database [' . $mysqli->connect_error . ']');} |
Indien de Arduino (her)start wordt in de setup sectie van de computer de laatste data met totaal verbruikte energie uit de database opgehaald. Hiervoor is nog een apart klein PHP-bestandje (kwhdata.php) aangemaakt op de hostingsite. Dit programmatje maakt eenvoudig weg een webpagina met alleen de gewenste data. Deze data wordt serieel ingelezen en omgezet in een bruikbare waarde.
PHP:
1
2
3
4
5
| include("dbconnect.php"); $result = $mysqli->query("SELECT id as LATEST, kwhtot FROM temperature ORDER BY id DESC LIMIT 1"); if ($mysqli_connect_errno) {exit;} echo "<".mysqli_fetch_array($result)['kwhtot'].">"; $mysqli->close(); |
[ Voor 200% gewijzigd door Zonnevis op 24-11-2018 08:27 . Reden: php aangepast naar MYSQLI, sketch Arduino geoptimaliseerd en correctie berekening energieverbruik ]
3000Wp & 2600Wp & 1020Wp