Aurea 5 hybrid: interfaces met de buitenunit en thermostaat

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Op het forum zie je veel duscussies over de matige werking van de Aurea warmtepomp m.n. het onbekende en onverwachte regelgedrag. Aangezien ik belangstelling heb om deze WP aan te schaffen, zou ik graag met de techneuten onder elkaar, erachter zien te komen hoe het technisch ontwerp in elkaar steekt. Dus geen discussies over het regeldrag van de individuele gevallen maar puur bedoeld om kennis uit te wisselen mbt de technische implementatie. Mogelijk kan met die kennis de controlbox incl Anna en plugwise vervangen worden door een oplossing zoals bv https://diyless.com/product/esp8266-opentherm-gateway.
Vragen:
1: Hoe is de interface tussen de controlbox en de buitenunit geimplementeerd? Via een relais aan/uit aansturing of digitale powerline-interface?
2: Hoe meet de controlbox de buitentemperatuur? Rechtstreeks via de buiteninit, of misschien via het internet?
3: Hoe worden de aanvoer en retourtemperatuur gemeten, via de CV-ketel of mogelijk via de buitenunit?
4: Gesteld dat je een aan-uit CV-ketel hebt: zijn dan de aanvoer- en retourtemperatuur ook zichtbaar?
5: De foto van de controlbox geeft onvoldoende inzicht welke componenten deze bevat, kan iemand de typenummers van de IC's noteren? Is het huidige ontwerp mogelijk gebaseerd op de welbekende Opentherm-gateway (Schelte Bron) :) ?

[ Voor 126% gewijzigd door Freeckje op 02-12-2023 11:27 ]

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • mhr-zip
  • Registratie: Januari 2001
  • Nu online
Volgens mij praat de thermostaat opentherm met de controlbox, waarna de controlbox er iets van maakt.

Probleem in mijn ogen zit in die controlbox en niet in de thermostaat. En ja, met de thermostaat manipuleren kan je hem misschien iets meer laten doen wat jij wil ipv dat hij een eigen leven lijdt.


(Kan de retoursensor niet op je aanvoerleiding, maar dan een paar meter verder dat je wel verschil meet, maar dat hij niet steeds uit springt).

Zijn vijftig was nog schoon. Drinkwaterkaart.nl Drinkwaterspots


Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Helemaal mee eens, mijn gedachte is om de gevraagde aanvoertemperatuur te laten afhangen van de actuele aanvoertemp. Dus de gevraagde aanvoer-temp zolang mogelijk binnen de 5 graden houden.
De Anna heeft zijn eigen regelstrategie die negeer je hiermee.

Wat de controlbox nog meer doet weet ik niet, maar met bovenstaande los je m.i. de belangrijkste klacht op n.l. het niet of te laat opstarten of te vroeg stoppen van de WP.

"(Kan de retoursensor niet op je aanvoerleiding, maar dan een paar meter verder dat je wel verschil meet, maar dat hij niet steeds uit springt)."
Ik heb zelf geen Aurea, dus ik snap niet precies wat je bedoelt... Worden de aanvoer en retourtemperaturen dan niet door je CV gemeten, of krijg je die van de WP zelf? Zie mijn vragenlijstje.

[ Voor 30% gewijzigd door Freeckje op 04-12-2023 16:17 ]

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
"(Kan de retoursensor niet op je aanvoerleiding, maar dan een paar meter verder dat je wel verschil meet, maar dat hij niet steeds uit springt)."
Als deze sensoren zich in de wp bevinden, dan verstoor je daarmee mogelijk de regeling cq de vermogenstoevoer van de compressor!?

De controlbox regelt toch op het verschil tussen gevraagde (via Anna) en geleverde aanvoertemperatuur? De controlbox zet de Wp aan of uit...Dat staat toch los van de retoursensor?

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • JJvdB
  • Registratie: December 2022
  • Laatst online: 07-10-2024
dit zou m.i. ook de oplossing kunnen zijn. Het binnen 5 graden houden van het verschil tussen gevraagde temp en geleverde temp. Enige dat je dan niet kun beinvloeden is het <5gr buitentemp setpoint. Dat is wel door sommigen opgelost door manipulatie buitenvoeler. Echter, weet niet of dat de regelstrategie van de warmtepomp zelf (compressor, expansieventiel, etc) (negatief) beinvloedt.

Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Ik heb geen idee wie de <5gr buitentemp-regel echt aanstuurt, de WP zelf intern , of de Controlbox.
Heb jij een idee hoe dat zit?
Zie parameters op je display die persee door de WP aangeleverd worden? Bv de retour- en aanvoertemperatuur.. of komt die data van de CV via de OT-kabel?
Is er een vorm van digitale communicatie tussen de Wp en Controlbox, en welke standaard gebruiken ze daarvoor?

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Ik bedacht me later dat toen ik het hydraulisch schema van de installatie bekeek, dat de aanvoertemperatuur waarschijnlijk niet door CV via OT wordt aangeleverd omdat dat circuit in WP-bedrijf door een keerklep losstaat van de WP-aanvoer.

Kan jij obv wat je op de printplaat van de controlbox ziet qua componenten en de layout, uitmaken of er een vorm van digitale communicatie is tussen de Controlbox en de WP is?

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


  • JJvdB
  • Registratie: December 2022
  • Laatst online: 07-10-2024
controlbox bepaalt keuze voor WP of Ketel op basis van een aantal parameters zoals buitentemp, verschil setpoit en aanvoer voor bepaalde tijd en geeft dus signaal aan ketel of warmtepomp. Signaal moet dus digtaal zijn om die info van de warmtepomp te verkrijgen.

  • JJvdB
  • Registratie: December 2022
  • Laatst online: 07-10-2024
kan een foto maken van controlbox maar die staat ook in manual. Misschien niet duidelijk genoeg:
https://atlanticclimate.nl/download/2946/

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Die foto is onduidelijk. Ik zou op die foto op basis van de componenten eventueel kunnen ontwaren of er digitale communicatie is.
Qua bekabeling tussen wp en controlbox (los van 220volt en aarde) zie je maar 1 ader lopen. Is het dan toch power line- of draadloze communicatie, geen idee.
Mijn hoop was dat die ene ader een relaisaansturing was die de wp alleen maar aan- of uitzet. Als er sprake is van digitale communicatie wordt het vervangen van de controlbox door een eigen controller een onhaalbare zaak.

Blijft over of om de Anna te vervangen door een eigenbouw thermostaat, of er een gateway tussen te zetten die de gevraagde aanvoertemperatuur overneemt van de Anna.
En tevens die buitensensor te beinvloeden. (Kan ook eventueel door een programmeerbare weerstand ;) )

Het blijft klooien in de marge ben ik bang. En als je tevreden bent hoe de wp het nu doet, gewoon laten draaien.

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Antwoord van Aurea:
"De warmtepomp wordt via een eigen modulerend protocol aangestuurd door de controlbox. Via de protocol wordt ook de aanvoer- en retourtemperatuur (via de sensoren van het buitendeel) uitgelezen en OT teruggekoppeld van de controlbox naar Anna zodat die in de metingen zichtbaar zijn."
Vertrouwende u hiermee voldoende te hebben geïnformeerd.
Met vriendelijke groeten – Best regards,
Simon Reijmes
Aftersales Engineer - Groupe Atlantic Nederland
T: +31 (0) 318 544 705 / +31 (0) 318 544 691"
service.nl@groupe-atlantic.com / sreijmes@groupe-atlantic.com

Helder verhaal: Daar kom je dus niet eenvoudig tussen. Blijft over het geleidelijk aansturen van de gevraagde aanvoertemperatuur van het cv-water. En beinvloeden buitentemperatuur sensor.

DRAADJE wat mij betreft gesloten.

[ Voor 6% gewijzigd door Freeckje op 15-12-2023 16:27 ]

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • +3 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Ik zou een poging willen maken dit draadje weer op te pakken.

Sinds een week heb ik een 2de hands Aurea in gebruik en laat ik voorzichtig zeggen: er is ruimte voor verbetering bij de besturing zoals velen al hebben opgemerkt.

Ik doe al jarenlang simpele elektronica dingen, waaronder Arduino en zo, maar een expert ben ik absoluut niet (om te verwachtingen wat te temperen 8) ).

De besturing in de cotrol box is op basis van twee ouderwetse maar doodnormale microcontrollers, nl. de Atmel Atmega8L uit 2003 op 8 MHz en met 8 kB flash geheugen. Dit is een zwakkere broeder van degene die in een van de eerste Arduino’s zit (Atmega 168 met 16k flash geheugen en tot max. 20 MHz). Ze lijken pin compatibel, dus bv. met de Arduino IDE een alternatief programma maken, dat in een Atmega 168 of 328 zetten en vervolgens de chip(s) in de control box omwisselen lijkt geen enkel probleem. Dan kan de rest van de control box gewoon worden gebruikt. Nog mooier is natuurlijk iets met ESPhome en Over-The-Air updates.

Ik heb de printplaat gedeeltelijk gereversed engineered. Als ik een keer tijd heb, zal ik m'n schetsje in een schema omzetten, maar vooralsnog gaat het om de communicatie. Observaties:
  • De aansluitingen gemarkeerd met Smile en Anna, en die bij ‘emergency’ zijn 1-op-1 doorverbonden zonder verbinding met de rest van de elektronica.
  • De communicatie met buitenunit verloopt via de ‘N’ en ‘S’ draden die naar twee afzonderlijke optocouplers gaan (zal wel voor veiligheid zijn)
  • De N-draad lijkt de verbinding van de buitenunit naar de control box. Deze komt op pin 27 van de linker MCU (IC 1) terecht
  • De S-draad lijkt zend-draad van de control box naar de buitenunit. Deze komt van pin 26 van de linker MCU
  • De rechter MCU (IC2) is via een dubbele optocoupler met de Opentherm in- en uitgang verbonden. Hier is pin 11 de zender en 5 de ontvanger
  • Beide MCU communiceren met elkaar via pin 2 --> 3, en 3 --> 2. Dit loopt langs de soldeerpads PAD1, PAD2, resp. PAD3 is de ‘0’ (of massa).
  • De reset knop geeft een reset signaal naar beide microcontroller (pin 1)
  • Verder zitten beide MCU’s met pin 25 aan elkaar
  • IC1 neemt is ook aangesloten op de schakelaar en bestuurt de LED en vermoedelijk ook nog 1 of meerdere relais. Dat stuk heb ik verder niet in detail uitgezocht
  • Dus IC2 lijkt primair de Opentherm communicatie te doen, en IC2 de rest
Nu de communicatielijnen bekend zijn, is de volgende stap om te gaan kijken wat voor signalen daar zijn. Ik heb m’n eenvoudige logic analyser (Labnation Smartscope) aangesloten en ben eens gaan kijken.

Afbeeldingslocatie: https://tweakers.net/i/UAER6hskZ86RP7cl4qIlrcT2wW0=/800x/filters:strip_exif()/f/image/EbRwKvycpn1GUpgMfklEc1NH.png?f=fotoalbum_large

Dat gaf meteen een mooi beeld:

Afbeeldingslocatie: https://tweakers.net/i/5uvamkA6ChLp3trXSOzcXRnfOT0=/800x/filters:strip_exif()/f/image/lbyHENxgufNIMKc4XoKUrRGx.png?f=fotoalbum_large
Kanaal 0 (IC 1 Pin 3, IC2 pin 2) en 1 (IC 1 Pin 2, IC2 pin 3: Communicatie tussen beide MCU’s
Kanaal 2: Pin 25 van beide MCU’s
Kanaal 3: IC1, pin 27: Signaal uit buitenunit
Kanaal 4: IC1, pin 26: Signaal naar buitenunit
Kanaal 5 en 6: Opentherm in en uit. Voorlopig niet interessant.
Dus de MCU wisselen iedere 5 s data uit. De buitenunit praat een stuk meer dan de control box. Er lijkt geen communicatie op de pinnen 25.

Hier een detail van de communicatie tussen de MCU’s:
Afbeeldingslocatie: https://tweakers.net/i/JcrmzSlDqDft2mVwTYLberUUCDc=/800x/filters:strip_exif()/f/image/7I6o2jXzO0YsOkpU0c81CkdW.png?f=fotoalbum_large
En van communicatie met buitenunit (3 & 4) en met Opentherm (5 en 6):
Afbeeldingslocatie: https://tweakers.net/i/Qmi2iGynR4sLkaJWYA-nztGgoHI=/800x/filters:strip_exif()/f/image/PYgmejysppIEfXvmPnUoOZI8.png?f=fotoalbum_large
Meest interessant is wat de control box naar de buitenunit stuurt. Hier is een compleet ‘gesprekje’ van 433 mS:
Afbeeldingslocatie: https://tweakers.net/i/1I6y1bpEU71jwkPwTn_bEB2VNSQ=/800x/filters:strip_exif()/f/image/58io4Qz8erOESmkEzyR3EmYQ.png?f=fotoalbum_large
Het lijkt erop dat de buitenunit (3) begint, en dat de control box dan antwoord. Dit antwoord wordt 1-op-1 teruggestuurd door de buitenunit. Daarna volgt een kleine pauze, en komt de buitenunit met data. Hierin zullen de water- en buitentemperaturen zitten.
Aanzetten van UART of serieel op kanaal 5 en 6 leverde voor mij niets bruikbaars op.

Nu komen we wel aan de grenzen van mijn kennis 😉

Op basis van de pulsgrootte van 1.6 ms heb ik afgeschat dat de baudrate wel eens 590 bit/s zou kunnen zijn. Gek getal, want dat wordt normaal niet gebruikt en ontstaat ook niet door 8 MHz steeds door 2 te delen.
Vervolgens heb ik een CH340 printje (serieel naar USB) met kanaal 4 verbonden. Met 590 baud, 7 databits en 1 stopbit kreeg ik ‘data’ binnen in de vorm van een repeterend ‘ZaJ i] R M’ terwijl de buitenunit uit stond. Ging die aan, dan veranderde alleen de laatste letter ‘M’ naar 6b, %e of nog iets anders(?!). Er leek een goede relatie tussen die code en het opgenomen vermogen. Dus ik vermoed dat het laatste deel van het signaal de vermogensvraag naar de buitenunit is. Eigenlijk is dat het enige dat ons interesseert.

Hier houdt mijn huidige kennis helaas op. Als iemand weet hoe dit verder te analyseren houd ik me aanbevolen!

Het ziet er naar uit dat alleen het uitgaande signaal hoeft worden gemanipuleerd op het moment dat de buitenunit aangeeft klaar voor ontvangst te zijn. Het zijn maar kleine bursts aan data, dus iemand met verstand van zaken heeft waarschijnlijk zo achterhaald, hoe dit protocol in elkaar steekt.

Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
WackoH schreef op maandag 16 december 2024 @ 14:35:
Ik zou een poging willen maken dit draadje weer op te pakken.

Sinds een week heb ik een 2de hands Aurea in gebruik en laat ik voorzichtig zeggen: er is ruimte voor verbetering bij de besturing zoals velen al hebben opgemerkt.

Ik doe al jarenlang simpele elektronica dingen, waaronder Arduino en zo, maar een expert ben ik absoluut niet (om te verwachtingen wat te temperen 8) ).

De besturing in de cotrol box is op basis van twee ouderwetse maar doodnormale microcontrollers, nl. de Atmel Atmega8L uit 2003 op 8 MHz en met 8 kB flash geheugen. Dit is een zwakkere broeder van degene die in een van de eerste Arduino’s zit (Atmega 168 met 16k flash geheugen en tot max. 20 MHz). Ze lijken pin compatibel, dus bv. met de Arduino IDE een alternatief programma maken, dat in een Atmega 168 of 328 zetten en vervolgens de chip(s) in de control box omwisselen lijkt geen enkel probleem. Dan kan de rest van de control box gewoon worden gebruikt. Nog mooier is natuurlijk iets met ESPhome en Over-The-Air updates.

Ik heb de printplaat gedeeltelijk gereversed engineered. Als ik een keer tijd heb, zal ik m'n schetsje in een schema omzetten, maar vooralsnog gaat het om de communicatie. Observaties:
  • De aansluitingen gemarkeerd met Smile en Anna, en die bij ‘emergency’ zijn 1-op-1 doorverbonden zonder verbinding met de rest van de elektronica.
  • De communicatie met buitenunit verloopt via de ‘N’ en ‘S’ draden die naar twee afzonderlijke optocouplers gaan (zal wel voor veiligheid zijn)
  • De N-draad lijkt de verbinding van de buitenunit naar de control box. Deze komt op pin 27 van de linker MCU (IC 1) terecht
  • De S-draad lijkt zend-draad van de control box naar de buitenunit. Deze komt van pin 26 van de linker MCU
  • De rechter MCU (IC2) is via een dubbele optocoupler met de Opentherm in- en uitgang verbonden. Hier is pin 11 de zender en 5 de ontvanger
  • Beide MCU communiceren met elkaar via pin 2 --> 3, en 3 --> 2. Dit loopt langs de soldeerpads PAD1, PAD2, resp. PAD3 is de ‘0’ (of massa).
  • De reset knop geeft een reset signaal naar beide microcontroller (pin 1)
  • Verder zitten beide MCU’s met pin 25 aan elkaar
  • IC1 neemt is ook aangesloten op de schakelaar en bestuurt de LED en vermoedelijk ook nog 1 of meerdere relais. Dat stuk heb ik verder niet in detail uitgezocht
  • Dus IC2 lijkt primair de Opentherm communicatie te doen, en IC2 de rest
Nu de communicatielijnen bekend zijn, is de volgende stap om te gaan kijken wat voor signalen daar zijn. Ik heb m’n eenvoudige logic analyser (Labnation Smartscope) aangesloten en ben eens gaan kijken.

[Afbeelding]

Dat gaf meteen een mooi beeld:

[Afbeelding]
Kanaal 0 (IC 1 Pin 3, IC2 pin 2) en 1 (IC 1 Pin 2, IC2 pin 3: Communicatie tussen beide MCU’s
Kanaal 2: Pin 25 van beide MCU’s
Kanaal 3: IC1, pin 27: Signaal uit buitenunit
Kanaal 4: IC1, pin 26: Signaal naar buitenunit
Kanaal 5 en 6: Opentherm in en uit. Voorlopig niet interessant.
Dus de MCU wisselen iedere 5 s data uit. De buitenunit praat een stuk meer dan de control box. Er lijkt geen communicatie op de pinnen 25.

Hier een detail van de communicatie tussen de MCU’s:
[Afbeelding]
En van communicatie met buitenunit (3 & 4) en met Opentherm (5 en 6):
[Afbeelding]
Meest interessant is wat de control box naar de buitenunit stuurt. Hier is een compleet ‘gesprekje’ van 433 mS:
[Afbeelding]
Het lijkt erop dat de buitenunit (3) begint, en dat de control box dan antwoord. Dit antwoord wordt 1-op-1 teruggestuurd door de buitenunit. Daarna volgt een kleine pauze, en komt de buitenunit met data. Hierin zullen de water- en buitentemperaturen zitten.
Aanzetten van UART of serieel op kanaal 5 en 6 leverde voor mij niets bruikbaars op.

Nu komen we wel aan de grenzen van mijn kennis 😉

Op basis van de pulsgrootte van 1.6 ms heb ik afgeschat dat de baudrate wel eens 590 bit/s zou kunnen zijn. Gek getal, want dat wordt normaal niet gebruikt en ontstaat ook niet door 8 MHz steeds door 2 te delen.
Vervolgens heb ik een CH340 printje (serieel naar USB) met kanaal 4 verbonden. Met 590 baud, 7 databits en 1 stopbit kreeg ik ‘data’ binnen in de vorm van een repeterend ‘ZaJ i] R M’ terwijl de buitenunit uit stond. Ging die aan, dan veranderde alleen de laatste letter ‘M’ naar 6b, %e of nog iets anders(?!). Er leek een goede relatie tussen die code en het opgenomen vermogen. Dus ik vermoed dat het laatste deel van het signaal de vermogensvraag naar de buitenunit is. Eigenlijk is dat het enige dat ons interesseert.

Hier houdt mijn huidige kennis helaas op. Als iemand weet hoe dit verder te analyseren houd ik me aanbevolen!

Het ziet er naar uit dat alleen het uitgaande signaal hoeft worden gemanipuleerd op het moment dat de buitenunit aangeeft klaar voor ontvangst te zijn. Het zijn maar kleine bursts aan data, dus iemand met verstand van zaken heeft waarschijnlijk zo achterhaald, hoe dit protocol in elkaar steekt.
Leuk dat je onderwerp weer oppikt en er zoveel energie insteekt. Ik heb sinds begin dit jaar een Quatt aangeschaft, en ben daar tevreden over. Ook daar lopen discussies over uitlezen en aansturen van de wp. De communicatie loopt over een standaard modbus protocol en is inmiddels gedecodeerd.
Vraag: uit het eerdere antwoord van de importeur is sprake van powerline communicatie. Zie je componenten die dat verzorgen via de 220 Vac lijn? Tsja, en als dat vervolgens een proprietry protocol is.....dan kan dat decoderen een lastige klus worden.

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • +1 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
In het bericht van de importeur/leverancier zie ik geen vermelding naar 'powerline communicatie'.

Dat stukje heb ik wel uitgezocht maar is hier niet relevant omdat er optocouplers (2x H11D1 om precies te zijn) tussen dat deel, en het laagspanningsdeel met de mirocontrollers zitten,

Hier op hoofdlijnen hoe de print is onderverdeeld (tot hoever ik het heb uitgezocht). In de groene ovalen de optocouplers die hoogspanning (of 18V in geval van OpenTherm) van de rest scheiden):
Afbeeldingslocatie: https://tweakers.net/i/L4me7XQ7a4HFmnLn6TbhyX5aSjM=/800x/filters:strip_exif()/f/image/1eXgMeAOP1sG8b7b6hYFn8hB.png?f=fotoalbum_large

Rond de chips is het gewoon 5V en hele lage snelheid. Niets spannends.

Overigens zag ik dat de normale, uitgebreide, uitvoering van de buitenunit ook Modbus heeft. Dus best een kans dat deze communicatie dat ook is. Wat waarom zouden ze speciaal voor deze toepassing iets nieuws bedenken?

Modbus RTU is volgens Wikipedia de meest gebruikte seriele implementatie van Modbus. Iedere byte (8 bits) zou moeten bestaan uit 11 bits:
  • 1 start bit
  • 8 bit data/message, least significant bit sent first
  • 1 bit parity
  • 1 stop bit
Ga ik dat maar eens proberen :*)

Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Ja, niet letterlijk maar wel: "De warmtepomp wordt via een eigen modulerend protocol aangestuurd door de controlbox." Jij noemt dat "hoogspanningcommunicatie". Dat is powerline communicatie...daar draait het nu juist wel om, om dat uit te vogelen. Die modbus aansluiting is bedoeld voor een handbedieningsunit.

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
De communicatie naar de buitenunit geeft mooie consistente data als ik de logic analyser op meest gebruikte '8N1' instel (dus 8 bits, geen parity en 1 stopbit) Er worden dan berichten met 8 en 12 bytes zichtbaar (de ene laat ik in decimaal zien, de andere in hexadecimaal):
Afbeeldingslocatie: https://tweakers.net/i/yeWMB5leceY2_V7Hc835vC2mQ7g=/800x/filters:strip_exif()/f/image/8lvXZw5wcRWW3vnkDnHTAaXg.png?f=fotoalbum_large
Afbeeldingslocatie: https://tweakers.net/i/ROdct-GymgBH0bjBg-qa0V914FQ=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/JmmG8iAXdxDGwGPIIDqj7O6U.png?f=user_large
ASCI is het helaas niet want die omzetting geeft onzin (vandaar dat de directe aansluiting op een UART-naar-USB geen goede resultaten gaf).

De data vanuit de buitenunit bevat gegevens die we elders kunnen zien zoals drie temperaturen. Helaas gaat decoderen van die data niet zo makkelijk vanwege die langere start-puls aan het begin. Ik zou hiervoor de decoder moeten aanpassen.

We bedoelen natuurlijk hetzelfde maar 'Powerline communicatie' klinkt nogal intimiderend. Strikt genomen klopt het ook niet helemaal omdat er namelijk omdat de communicatie deels over een eigen draad (gemerkt 'S' = signal?) loopt. De andere loopt over de nul ('N'). De hardware implementatie van de communicaitie is verder ook niet relevant.

Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
WackoH schreef op dinsdag 17 december 2024 @ 10:42:
De communicatie naar de buitenunit geeft mooie consistente data als ik de logic analyser op meest gebruikte '8N1' instel (dus 8 bits, geen parity en 1 stopbit) Er worden dan berichten met 8 en 12 bytes zichtbaar (de ene laat ik in decimaal zien, de andere in hexadecimaal):
[Afbeelding]
[Afbeelding]
ASCI is het helaas niet want die omzetting geeft onzin (vandaar dat de directe aansluiting op een UART-naar-USB geen goede resultaten gaf).

De data vanuit de buitenunit bevat gegevens die we elders kunnen zien zoals drie temperaturen. Helaas gaat decoderen van die data niet zo makkelijk vanwege die langere start-puls aan het begin. Ik zou hiervoor de decoder moeten aanpassen.

We bedoelen natuurlijk hetzelfde maar 'Powerline communicatie' klinkt nogal intimiderend. Strikt genomen klopt het ook niet helemaal omdat er namelijk omdat de communicatie deels over een eigen draad (gemerkt 'S' = signal?) loopt. De andere loopt over de nul ('N'). De hardware implementatie van de communicaitie is verder ook niet relevant.
Het kon zijn dat die powerline communicatie op een standaard gebaseerd was en dat je op basis daarvan de data zou kunnen decoderen. Maar Aurea heeft de data versleuteld. Ik kan je hiermee helaas niet verder helpen aangezien ik deze wp niet heb.

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Snap ik, verwaht ik ook niet en geeft niet

Ik kan met niet voorstellen dat de data is versleuteld. Waarom zouden ze dat doen? Erg spannend voor derden is de communicatie niet.

Mooiste zou zijn om het protocol te snappen zodat gericht opdrachten naar de buitenunit kunnen worden verstuurd.
Maar als dat niet lukt, is een alternatief wellicht sequenties kopieren waarbij de WP de gewenste dingen deed en die via een Arduino of zo 'afspelen' wanneer nodig.
Volgens week ga ik eens wat bouwen om ik de data in een computer te krijg zodat ik meer data heb om te vergelijken.

Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Misschien heb je hier nog wat aan:
https://github.com/aerona-chofu-ashp/modbus

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • Candymirror
  • Registratie: November 2003
  • Laatst online: 15:37
@WackoH Ik ben niet volledig thuis in alle atmega varianten, maar volgens mij valt serieel en modbus af. Volgens mij ben je voor modbus een onderliggende seriele poort nodig. aangezien de rx/tx poorten van de atmega8 al in gebruik zijn voor de onderlinge communicatie tussen beide atmega's, blijft er dan alleen nog softserial over en die kan voor rx alleen op pd2 of pd3 (pin 4 of 5) bij een atmega8.

Wellicht is het het 1-wire protocol of een variant hiervan. Je zou het eens door sigrok kunnen proberen te halen.

Als laatste zou er nog gekeken kunnen worden of het flash lock bit staat op de atmega, grote kans van wel, maar niet geschoten altijd mis. Staat het lock bit niet, dan zou dump door een disasembler gegooid kunnen worden.

BTW ik heb deze warmtepomp gisteren via marktplaats kunnen overnemen voor een leuk bedrag. Zodra die bij mij aangesloten is en draait zal ik ook eens kijken of er wat valt te ontdekken.

[ Voor 11% gewijzigd door Candymirror op 07-01-2025 22:44 ]


Acties:
  • +2 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
@Candymirror Leuk dat je hier ook meen aan de gang wilt gaan!
Uitlezen van de code heb ik overwogen, maar wat ik er over heb gelezen is het disassambeleren niet eenvoudig.
In de tussentijd ben ik een stuk verder gekomen, maar nog net niet tot het punt dat ik de warmtepomp kan aansturen.
Op dit moment ben ik in het buitenland (vandaar de rare tijd van reageren; het is hier ochtend). Later deze week reis ik terug en zal ik uitgebreider reageren. Maar misschien herken je de protocol opzet.

Even uit m'n hoofd:
  • De communicatie vindt plaats met ~560 bps en is geen ModBus
  • Iedere 500 ms initieert de warmtepomp (WP) communicatie dmv een puls van ~8ms.
  • Daarop reageert de controlbox met een bericht van een aantal bytes die vrijwel instantaan door de WP worden herhaalt
  • Na de 9 tot 12 bytes van de controlbox volgen nog een aantal bytes die de WP zendt (en die de controlbox niet direct herhaalt).
  • De communicatie duurt ruim 400 ms, gevolgd door een pauze om de 500ms vol te maken.
  • De controlbox zendt repeterend vier verschillende berichten
  • Er lijken maar vier bytes te veranderen in een van de vier berichten
  • Het eerste byte is een aan/uit signaal (draait de WP dan is deze '1', anders '0')
  • De tweede lijkt de vermogensvraag te zijn: Deze varieert tussen de 1 (opgenomen elektrisch vermogen ~240W) en 12 (~1800W)
  • Van de 3de en 4de bytes weet ik niet wat die doen. Ik hoop niet dat dat een checksum of zo is.
Met een Arduino Mega2560 ben ik bezig een 'Proof of concept' te maken om te kijken of ik de WP met die eerste twee bytes aan kan sturen.

Hiervoor heb ik een aftap op het het signaal van de ontvangende optocoupler naar de linker ATMega gemaakt, en heb het signaalpad van de naar de zendende optocoupler onderbroken zodat ik daar zelf een signaal op kan zetten.

Ik ben al eind met de code maar heb het helaas voor mijn vertrek nog niet kunnen testen.

Als dit gaat, is volgende stap om het om te zetten naar ESPhome. Mijn is uiteindelijk doel is om via Home Assistant de WP aan te sturen zoals ik dat wil, gebruik makend van de info die via de Plugwise integratie binnenkomt. Voor de info vanuit de WP (watertemperaturen en buitentemperatuur) blijf ik dan de controlbox gebruiken. Ik kan eenvoudig voorkomen dat de CV aan gaat door deze op alleen sanitair warm water te zetten.

Acties:
  • +1 Henk 'm!

  • dingo35
  • Registratie: Februari 2008
  • Laatst online: 17:01
Die laatste zin maakt dat je oplossingsrichting voor de meesten van ons niet bruikbaar is; bij mijn Nefit ketels kun je alleen de tapwater voorziening uitzetten, niet het CV gedeelte.

Terwijl dat nu juist is wat de meesten hier willen: ook bij lage buitentemperaturen op de WP stoken ipv de CVketel.

Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Die laatste zin was meer een losse opmerking die ook niet echt werkt; het voorkomt weliswaar dat de CV gaan verwarmen maar de hybride box zet de buitenunit wel een uur uit.

Voorkomen dat de buitenunit op een lage buitentemperatuur uit gaat is het makkelijkste te voorkomen door de externe temperatuursensor van de buitenunit in het deel boven de compressor te leggen.

Dat heb ik nu ruim twee weken geleden gedaan en de unit gaat niet meer op buitentemperatuur uit. Bij -2oC vannacht is de buitenunit blijven draaien. De defrosts lijken er niet onder te lijden:
Afbeeldingslocatie: https://tweakers.net/i/2wGv2KG9pBa5iJnfEt_U6dk2wwc=/800x/filters:strip_exif()/f/image/aCUrGdSzIxN5VdVWcbHSJh4z.png?f=fotoalbum_large
Ik heb weer thuis en heb nu bij drie defrosts gekeken. Die lijken gewoon prima op het juiste moment te komen, dus als de verdamper begint dicht te slibben met ijs (rijp),

Maar dat 'delta_T 5oC'-probleem blijft.
De unit heeft twee weken gedraaid met een aanvoertemperatuur installing van 35oC (wat dan in het echt 31oC wordt :? ). Maar toen ik er 1 graad bij deed (dus 36oC) schakelde de hybride box een paar defrosts later toch de buiteunit uit. :X

Nieuwere iteraties van de software in de hybride box lijken wel beter. Dus eigenlijk zou Atlantic chips met geupdate software met de wensen van hun klanten tegen onkosten beschikbaar moeten stellen, want zij hebben een halfbakken product geleverd.

Er zijn verschillende oplossingsrichtingen. Eerst maar het proof-of-principle voor elkaar krijgen.

Acties:
  • 0 Henk 'm!

  • wybe-V
  • Registratie: Augustus 2023
  • Laatst online: 14:12
dingo35 schreef op zaterdag 11 januari 2025 @ 09:45:
Die laatste zin maakt dat je oplossingsrichting voor de meesten van ons niet bruikbaar is; bij mijn Nefit ketels kun je alleen de tapwater voorziening uitzetten, niet het CV gedeelte.

Terwijl dat nu juist is wat de meesten hier willen: ook bij lage buitentemperaturen op de WP stoken ipv de CVketel.
Ik heb de cv kachel niet aan gesloten op de controle box maar de eigen thermostaat terug gezet zodat ik zel kan bepalen af ik bepaal af ik de cv aan wil zetten

Acties:
  • +1 Henk 'm!

  • mhr-zip
  • Registratie: Januari 2001
  • Nu online
wybe-V schreef op zaterdag 11 januari 2025 @ 14:55:
[...]

Ik heb de cv kachel niet aan gesloten op de controle box maar de eigen thermostaat terug gezet zodat ik zel kan bepalen af ik bepaal af ik de cv aan wil zetten
Hier heb ik een paar vragen over als het mag.
- Je hebt geen CV aangesloten op je controlbox. Werkt de WP dan gewoon, of heb je iets moeten omzeilen?

-Op een gegeven moment gaat de controlbox de CV aan proberen te sturen, wat niet gaat. Wat gebeurt er dan? X tijd niks en dat dat de WP weer bijschakelt of?

Zijn vijftig was nog schoon. Drinkwaterkaart.nl Drinkwaterspots


Acties:
  • 0 Henk 'm!

  • wybe-V
  • Registratie: Augustus 2023
  • Laatst online: 14:12
mhr-zip schreef op zaterdag 11 januari 2025 @ 16:55:
[...]


Hier heb ik een paar vragen over als het mag.
- Je hebt geen CV aangesloten op je controlbox. Werkt de WP dan gewoon, of heb je iets moeten omzeilen?

-Op een gegeven moment gaat de controlbox de CV aan proberen te sturen, wat niet gaat. Wat gebeurt er dan? X tijd niks en dat dat de WP weer bijschakelt of?
Heb de CV-uitgang van de controle box vast gesoldeerd op het reset knopje van de controle box
Als de wp wil overschakelen naar de cv wordt er een reset gegeven en gaat de wp weer starten voor 20 min op ca 700watt
Mogelijk komt na deze reset de delta-T wel binnen de 5 graden en gaat de wp hierna naar een hoger vermogen

Acties:
  • +4 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Ik had nog belooft met meer info over de werking van de control box te komen. Bij deze een lange post...

Inleiding

Het hybride warmtepomp systeem Aurea van Atlantic bestaat uit verschillende delen:
  • Een Chofu AEYC-0643XU buitenunit met versimpelde (elektrische) aansluitingen ten opzichte van de basis versie. Dit is een al wat ouder model maar ‘made in Japan’. Dus wellicht niet de stilste en meest efficiënte, maar betrouwbaar en zonder kinderziekten.
  • Een control box besturing unit die Atlantic vermoedelijk zelf heeft (laten) ontwikkelen. Dit is veruit de zwakste schakel in het systeem door wat onhandige ontwerpkeuzes, en lijdend voorwerp van dit topic.
  • Een Plugwise Anna thermostaat met Smile gateway. Wat mij betreft een typische ‘slimme thermostaat’ die voor het doel voldoet.
  • Installatiemateriaal met terugslagkleppen, vuilfilter, etc. De charme van dit systeem is de de relatief eenvoudige installatie. Installatie kostte me in m’n eentje een weekend.

Werking van de control box

Hardware
De control box bevat een printplaat met twee oude en eenvoudige Atmel microcontrollers waarop het controle systeem is gebaseerd. De een (IC1) doet de communicatie met de buitenunit, de ander (IC2) het Opentherm stuk. Ze communiceren ook met elkaar om data tussen Opentherm en buitenunit uit te wisselen. Ik heb al eerder het een en ander over de hardware geschreven en foto’s gepost. Zie hier en hier.
Lang verhaal kort. In de basis voldoet de hardware prima, het is alleen een verouderde en te simpele basis want er is geen software update mogelijk zonder chips te wisselen, en bv. dip switches om de gebruiker keuzes over gedrag van de warmtepomp te laten maken, zijn er niet (met uitzondering van aan/uit of Opentherm thermostaat).
De aansluiting waarmee communicatie met de buitenunit verloopt is apart. Je zou iets van RS485 als hardware met ModBus als protocol verwachten (dat ondersteunt de buitenunit ook in de standaarduitvoering!). Het is echter een combinatie van stroomvoorziening vanuit de buitenunit naar de control box en communicatie.
Fysiek is de verbinding met vier draden: Fase, Nul, Signaal en Aarde. Fase en nul voorzien de unit van stroom, en via een wat bijzondere manier (rood en zwart banaan chassisdeel op de printplaat voor een USB adapter) ook de Smile gateway en Anna thermostaat. De communicatie verloopt via de nul- (van buitenunit naar control box) en signaaldraad (control box naar buitenunit). Wat hier precies gebeurt heb ik verder niet bekeken, anders dan dat een multimeter aangaf dat spanningen enkele tientalen volt heen en weer sprongen. Daarom durfde ik m’n eenvoudige USB oscilloscoop met max. +/- 35V hier niet op aan te sluiten.
Dat was ook niet nodig want de Atmel microcontrollers werken op 5V en de omzetting naar deze spanning zit natuurlijk gewoon op de printplaat. Ik heb van dat deel een schema gemaakt. Helaas nog steeds in potlood-uitvoering dus ik zal het hier nog niet posten. Hieronder voor de volledigheid nog wel een keer de foto van de print:

Afbeeldingslocatie: https://tweakers.net/i/L4me7XQ7a4HFmnLn6TbhyX5aSjM=/800x/filters:strip_exif()/f/image/1eXgMeAOP1sG8b7b6hYFn8hB.png?f=fotoalbum_large

De signalen van en naar de buitenunit worden met behulp van twee optocouplers (H11D1) gescheiden van netspanning. Degene met het signaal van de buitenunit (OK1) is via een 4.7 kOhm weerstand (R9) met IC1 verbonden, en dat IC stuurt zo’n opdrachten via een 1 kOhm weerstand (R14), een BC547 transistor (T2) en een 330 Ohm weesrtand (R10) naar de andere optocoupler (OK2).
Hier een overzicht van de aansluitingen op de microcontrollers:

PinIC1IC2
1ResetReset
2IC2 pin3IC1 pin3
3IC2 pin2IC1 pin2
4NCNC
5NCOpentherm in
6NCNC
7VCCVCC
8GNDGND
9X-talX-tal
10X-talX-tal
11NCOpentherm uit
12NCNC
13NCGND
14LED 1NC
15NCNC
16Relais 1Relais 1
17NCNC
18Schakelaar-LEDNC
19NCNC
20SchakelaarVCC
21SchakelaarVCC
22GNDNC
23SchakelaarNC
24NCNC
25IC2 25IC1 25
26WP in (OK2)NC
27WP uit (OK1)Schakelaar-LED
28NCNC

Primair van belang zijn pin 26 en 27 van IC1 die bij resp. weerstand R14 (1 kOhm) en R9 (4.7 kOhm) zijn af te tappen omdat hiermee de communicatie met de buitenunit verloopt. Primair heb ik me hier op gericht om het protocol in kaart te gaan brengen. De communicatie tussen beide IC’s verloopt langs PAD1 (IC1 pin 3 naar IC2 pin 2) , PAD2 (pin 2 → 3) en PAD3 (GND).
Software
De software van de control box zit ‘geflashed’ in beide microcontrollers. In beginsel kan dit worden uitgelezen. Maar dat lijkt me een tamelijk kansloze missie. Het lock bit kan actief zijn waardoor uitlezen wordt geblokkeerd. Maar als uitlezen wel mogelijk, is doorgronden en aanpassen van het programma vermoedelijk erg moeilijk. We weten bv. al niet welke ontwikkelsoftware is gebruikt (logisch zou de ontwikkelsoftware van Atmel, nog onderdeel van Microchip, zijn). Gezien de taken (vier communicatielijnen managen) van deze relatief zwakke chips (ze draaien maar op 8 MHz en hebben slechts 8 kB flash geheugen, 512 bytes EEPROM en 1 kB RAM) is er ook een kans dat er complexe low level code is gebruikt.
Protocol
Ik heb dus wel de communicatie met een eenvoudige logic analyser bekeken. Dat geeft dit overzichtsbeeld. Signaal 1 en 2 is de communicatie tussen beide microcontroller. Die sturen dus iedere 5 s een bericht van een paar bytes. Er lijkt verder geen bijzonder afstemming te zijn.
Signaal 3 is de communicatie van de buitenunit (warmtepomp, WP) naar control box, en 4 is die in omgekeerde richting. Dit is op basis van een wat geavanceerder protocol:
Afbeeldingslocatie: https://tweakers.net/i/_Z-rMg2qvqCgj986WqhMZb-5yow=/800x/filters:strip_exif()/f/image/9TvyoRO4EzOiPWgWOvTs8dvV.png?f=fotoalbum_large
Hier nog wat verder ingezoomd:

Afbeeldingslocatie: https://tweakers.net/i/z8cAtbdOWyO7FZdzDjOXHQopzUk=/800x/filters:strip_exif()/f/image/YZOgW3HneltPu36lXDJXpZ7E.png?f=fotoalbum_large
En nog wat verder (nu met 5 en 6 de inter-IC communicatie):
Afbeeldingslocatie: https://tweakers.net/i/fwjshKGWvYw-ONBocSpxz0Pe2jE=/800x/filters:strip_exif()/f/image/oYLuftB0db72eF41dugr1IUA.png?f=fotoalbum_large
Protocol opbouw
Dit is wat ik tot dusverre weet over dat protocol:

  • Bits duren 1.5 ms. Dat betekent dat de communicatie op een ongebruikelijke 666 bps verloopt.
  • Nemen we de control box (CB) als centrale eenheid dan is CB naar de warmtepomp (WP) ‘transmit (Tx), en WP → CB ‘receive’ (Rx).
  • Uitgangspositie is dat beide datalijnen laag zijn.
  • CB maakt Tx hoog
  • WP reageert hier op door Rx hoog te maken
  • 8 ms later begint de CB op Tx te zenden, dit wordt vrijwel direct door de WP op Rx teruggestuurd, wellicht om controle mogelijk te maken.
  • De opbouw van het bericht van CB naar WP is voor zover ik kan nagaan als volgt:
  • ◦ Eerste byte is altijd 19 hexadecimaal (25 in decimaal),
  • ◦ Tweede is een volgnummer (0, 1, 2, of 3).
  • ◦ Derde byte is de lengte van het totale bericht van de CB: Resp. 8, 12, 8 en 8 bytes
  • ◦ Dan volgt de inhoud van 3 of 7 bytes
  • ◦ Als laatste vermoedelijk twee bytes met een checksum
  • Als de CB na 8 of 12 bytes klaar is, gaat de BU door met zenden op de Rx waarbij zaken als temperatuur aan- en afvoer en buitentemperatuur overgedragen zullen worden. Dit gebeurt overigens niet als de checksum van de CB communicatie niet klopt!
  • De opbouw van het bericht van WP naar CB is:
  • ◦ Byte 1: Startnummer (91 in hexadecimaal, dus 145 in decimaal)
  • ◦ Byte 2: Volgnummer (achtereenvolgens 1, 0, 2 en 3)
  • ◦ Byte 3: Lengte met resp. 13, 12, 18 en 20 bytes
  • ◦ Inhoud van 8, 7, 13 en 15 bytes
  • ◦ Laatste twee bytes vermoedelijk weer de checksum
  • ◦ Als laatste nog een byte met ‘0’(die niet meetelt voor de lengte
  • Vervolgens stuurt de CB weer het eerste bericht.
  • De pauze tussen de berichten is steeds 98~100 ms. Omdat de berichten verschillende lengtes hebben, betekent dit dat de start niet met een vast interval is. Het lijkt er meer op dat de CB steeds wacht op een hoog worden van de Rx en dan na 8 ms gaat zenden.
Ik heb niet gevonden waar dit soort communicatie nu vandaan komt, behalve dat het lijkt op het RFC 916: Reliable Asynchronous Transfer Protocol (RATP) wat terug gaat tot tenminste 1984(!).
Protocol inhoud
Dan de inhoud. Dit zijn voorbeelden van de vier berichten die de CB heeft verstuurt. In blauw en rood getallen die ik heb zie veranderen. In decimaal is het:
Afbeeldingslocatie: https://tweakers.net/i/xbiUEsP0hhfd3hpN1UMrXMc9_SA=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/Pd2fXTcWymE4PSIbHCa0qNr4.png?f=user_large

Het 4de en 5de byte van bericht ‘2’ zijn cruciaal. Byte 4 is 0 (uit) of 1 (aan) en byte 5 geeft het gevraagde vermogen, vermoedelijk tussen 0 en 12. Het is een lineaire lijn:
Afbeeldingslocatie: https://tweakers.net/i/xlknbl1HlPYk_VbgEJIn5LgYv7E=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/A0SVg9KKzc4hPFZnC2LUOCoq.png?f=user_large

Verder heb ik tot dusverre geen andere getallen van CB naar WP gezien. Dat betekent dat de WP aansturen best eenvoudig is; alleen deze twee bytes hoeven te worden aangepast.

De WP stuurt meer terug. In decimaal:
Afbeeldingslocatie: https://tweakers.net/i/08jzdCXNa4IbxzRjzR0_ahzl_go=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/IPo4qBY0XBNfl12ouDHWmSFK.png?f=user_large
Ook hier weer in blauw getallen die veranderden. Dat zijn er dus best veel en vooralsnog heb ik geen idee wat het is. Het zijn geen voor de hand liggende getallen die bv. een watertemperatuur vertegenwoordigen.

Lastig tot dusverre is dat het me niet is gelukt te achterhalen hoe de checksum wordt berekend. Ideeën zijn welkom!
Alternatieve aansturing
Wat ik nu heb gedaan is een Arduino Mega2560 koppelen aan de communicatie tussen CB en WP. Het signaal vanaf de de WP wordt afgetapt, dat naar de WP heb ik onderbroken door 1 kant van R14 los te halen en hier voed ik een seriële uitgang van de Arduino op in.

Wat het programma nu op hoofdlijnen doet:
  • Tenminste 80 ms wachten nadat WP Rx laag heeft gemaakt, tot deze 7.7 ms hoog is geweest (dit komt nauw)
  • Dan beginnen met het versturen van het eerste bericht. Dit heb ik gewoon gekopieerd zoals ik het heb opgevangen
  • Vervolgens weer 80 ms bij Rx is laag wachten tot Rx 7.7 ms hoog is geworden. Dan tweede bericht sturen
  • Zelfde bij derde bericht, behalve dat ik hier bytes 4 en 5 vervang door aan/uit en het gewenste vermogen. Op dit moment kan ik dat lokaal met een rotary decoder instellen en aflezen met een OLED schermpje. Ik maak een voorselectie tussen 0 en 10 en activeer die dan door de draaiknop in te drukken.
  • Als laatste het 4de bericht.
Verder heb ik al voorbereid om tegelijkertijd op een andere seriële poort Rx uit te lezen. Maar hier doe ik nog even niets mee.

Hoe verder?

Doel 1 is bereikt: Ik kan zelf beslissen met hoeveel vermogen de warmtepomp werkt. Alleen zal de CB nu nog wel de CV aan gaan sturen. Dan heb ik in mijn geval voorkomen door deze op alleen sanitair te zetten.

Uiteindelijk is een soort ‘man-in-the-middle’ nodig die de berichten over en weer ontvangt, daar waar nodig aanpast en doorstuurt
Verder ontrafelen van het protocol tussen CB en WP gaat echter nog best wat moeite kosten: Wat is wat en hoe wordt die checksum berekend.

Makkelijker kan zijn om die andere communicatie te manipuleren, nl. die tussen beide microcontrollers. Hier komt de interessant info als watertemperatuur en wellicht ook de buitentemperatuur voorbij. We weten op dit moment echter niet welke van de twee beslist of de CV of de WP wordt gebruikt.
Afluisteren van de communicatie is eenvoudig. Toen ik de print er toch uit had, heb ik alvast pinnen in de pads gesoldeerd. Maar ingrijpen op de communicatie vereist doorkrassen van printsporen.
De communicatie zelf lijkt een heel stuk eenvoudiger. In detail heb ik er nog niet naar gekeken. Maar iedere 5 s gaan er van het ene IC een paar bytes naar de ander, en een paar tienden later de andere kant. Zo op het eerste gezicht veel eenvoudiger dan wat er naar de WP gaat.

Wordt vervolgd...

Acties:
  • 0 Henk 'm!

  • Freeckje
  • Registratie: Juni 2019
  • Laatst online: 17:15
Prima werk hoor, ik had het bijltje er al lang bij neergegooid...
Ik zou als ik jou was, na het decoderen van het communicatie protocol met de buitenunit, die controlbox met aanverwante kastjes, vervangen door een esp32 , met een opentherm master en slave interface. Heb ik zelf als opentherm gateway in gebruik.

NH, vrijstaand huis 70m2 bg vvw/40m2 boven radiatoren, Gas 2023:1500m3, Quatt 4kw, TS:DIY-Arduino, 6400 Wp panelen/SolarEdge.


Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Ik heb nog naar de communicatie tussen de microcontrollers gekeken door eerst met een logic analyzer verbonden met Pad 1 en 2 op de printplaat de bit tijdsduur te vinden, en vervolgens met een serieel naar USB omzetter te zien of ik logica in de getallen kon ontdekken.

De communicatie is, zoals al voor de hand lag, een stuk eenvoudiger.

Een bit duurt ~100us wat dus betekent dat de communicatie op een standaard 9600 bps werkt.

De berichten die over en weer worden gestuurd bevatten grotendeels dezelfde informatie en zijn steeds 12 bytes lang. De laatste byte is de checksum. Deze is de rest van de som van de voorgaande 11 bytes gedeeld door 256.

Ik heb de functie van de 12 bytes voor een redelijk deel kunnen achterhalen. Verdere suggesties zijn welkom:
  1. Doeltemperatuur vanuit thermostaat. Wordt 240 op pad 2 als de WP uit moet (door te lage buitentemperatuur bv.)
  2. ? Meestal 20, maar ook 23 gezien
  3. ? Meestal 179, maar 77 als het 2de byte 23 is
  4. Reserve?, want altijd 0
  5. Reserve?, want altijd 0
  6. Vermoedelijk temperatuur setpoint naar WP (want paar oC lager dan byte 1 zoals we in de praktijk ook zien. Deze wordt op Pad 2 0 als de WP uit gaat
  7. ? 0 en 14 gezien. Is er een link met byte 11 want als byte 6 0 wordt, wordt byte 11 vaak 1
  8. WP: Aanvoer temperatuur
  9. WP: Retour temperatuur
  10. WP: Buitentemperatuur
  11. ? Wordt 1 als byte 7 0 is
  12. Checksum
Byte 1 op Pad 2 wordt 240 als de WP uit moet, op Pad 1 blijft die de doeltemperatuur aangeven. Dus vermoedelijk loopt via Pad 1 de communicatie van IC2 (OT) naar IC1 (WP), en via Pad 2 die in omgekeerde richting.

De microcontroller voor de WP (IC1) lijkt de WP uit te zetten, en de OT microcontroller (IC2) daarvan via getal '240' (F0 in hex) 'op de hoogte te stellen'. Vermoedelijk zit in IC1 dan ook die 'delta 5oC' check op aanvoer en retour.

Als gevolg hiervan zal het via ingrijpen in de relatief eenvoudige commnicatie tussen IC1 en IC2 niet lukken om het vervelende gedrag van de control box te voorkomen.

Acties:
  • +2 Henk 'm!

  • maanlander69
  • Registratie: December 2023
  • Laatst online: 16:45
Protocol CB <-> buitenunit:
De laatste 2 bytes corresponderen met CRC-CCITT (0xFFFF).

Voorbeeld 1:
25 3 8 178 2 0 193 154 (dec)
omzetten naar
19 03 08 B2 02 00 C1 9A (hex)

https://www.lammertbies.nl/nl/comm/info/crc-calculation
Als je bericht 19 03 08 B2 02 00 invult in de calculator (invoer type hex aanvinken) geeft dit C1 9A als uitkomst.

Voorbeeld 2:
Werking als boven
25 1 12 0 0 0 0 0 0 0 170 53 (dec)
19 01 0C 00 00 00 00 00 00 00 AA 35 (hex)

[ Voor 5% gewijzigd door maanlander69 op 01-02-2025 16:11 ]


Acties:
  • +4 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Bedankt! Het klopt idd.

Ik ben nu deze opzet aan het testen:
Afbeeldingslocatie: https://tweakers.net/i/Whh3yrdri-KhTv1mDyWspS80Na4=/800x/filters:strip_exif()/f/image/DOAPVBtoT2fP2VM4ITPRR1GQ.png?f=fotoalbum_large
  • Aftappen van de output van de OT microcontroller om daaruit het aanvoer setpoint te halen (op basis van wat Anna thermostaat vraagt)
  • Afvangen van de communicatie van WP naar de OT microcontroller voor aanvoer, retour temperatuur en buitentemperatuur.
  • Aangepast bericht van WP naar OT microcontroller maken zodat CV en warmtepomp niet tegelijk gaan werken, maar ook dat de CV het van de warmtepomp overneemt bij een bepaalde buitentemperatuur (-2 in mijn geval)
  • Aangepast bericht van control box naar buitenunit maken met een vermogensvraag op basis van een PID regelaar die met de gewenste temperatuur en gemeten aanvoer temperatuur wordt gevoed.
Maar nu we weten hoe de checksum wordt bepaald, zijn we weer een stapje verder om de warmtepomp MCU door een eigen controller te vervangen. Dan hoeft er niet meer aan de print gesoldeerd te worden.

Een eigen Atmel ATmega328P zou kunnen want de MCU zit gelukking in een voetje en die is pin compatibel.

Omdat van de 28 pinnen maar 11 voor signaaloverdracht gebruikt, waaronder een 2 voor LEDS (kan worden gemist) en 1 voor een relais, is ook een mogelijkheid om een ESP32 te nemen en die jumpers met dupont connectoren te verbinden. Zo komen over-the-air updates en verdere integrate in Home Assistant in bereik.

Maar dan moeten we wel gaan snappen wat er precies in de communicatie tussen buitenunit en control box zit.

Acties:
  • +2 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Met dat laatste maak ik ook stapjes.

Metingen die in handleidingen van Atlantic en Chofu worden genoemd als waardes die display van buitenunit kan laten zien (en dus ook worden doorgegeven?!) zijn:
Afbeeldingslocatie: https://tweakers.net/i/UGFENRzvncbKNPaj1sNrKua5itg=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/ZKezjjFdoYvkPiVzcoKhd0iR.png?f=user_large

Op basis van het bovenstaande lijkt het me waarschijnlijk dat het setpoint naar de buitenunit (1~10) naar een werkfrequentie voor de compressor (d1) wordt vertaald.

Als ik naar data kijk, correleert bv. het 4de byte van het 4de bericht van de buitenunit heel sterk met het vermogen dat ik extern heb gemeten (correlatiecoefficient 0.99!) --> zal dus wel d3 zijn.
Als ik hier het verbruik van de besturing (~10W) en fan & pomp (~60 W) vanaf haal
De relatie (trendlijn) is: P_compressor [W] = 15 * (M4B3) - 350
(M = Message, B = Byte, 1ste byte is Byte 0. )
De hellingscoefficient (15) wijst in de richting van hexadecimaal (grondgetal 16).
Kan ook goed zijn dat zowel byte 3 als 4 het vermogen representeren. Alleen als ik dat omzet naar decimaal en deel door 16, kom ik wel een paar onderd watt te hoog uit .
Dus nog genoeg te doen

Acties:
  • +2 Henk 'm!

  • Grannetia
  • Registratie: Februari 2025
  • Laatst online: 02-06 14:43
Wauw!
Ik ben hard op zoek naar een manier om deze warmtepomp te laten doen wat ik wil, ipv wat de regeling zelf wil 😅. Stuit ik ineens op dit toch wel zeer actuele en interessante draadje.
Momenteel werk ik met een home assistant scripts geïnspireerd op deze https://community.home-as...tpump-controller/795111/2 om de warmtevraag van Anna zo te manipuleren dat de warmtepomp aan blijft en niet de ketel het niet te pas en te onpas overneemt. Voor mijn woonsituatie is de 5kw warmtepomp misschien iets aan de kleine kant, waardoor het echt een uitdaging is om de gewenste aanvoer te halen binnen de door de regeling gestelde tijd. Zeker aangezien de regeling ook nog bij een lage aanvoer temperatuur, het eerste kwartier blijft hangen rond 600watt :? Ik had in home assistant inmiddels een scriptje gemaakt om de maximale gevraagde aanvoer bij te stellen tot maximaal 4,5° boven de huidige aanvoer. Dit had tot gevolg dat Anna helemaal geen warmtevraag meer kon plaatsen wanneer mijn aanvoer te laag was na een lange tussenpauze in de warmtevraag (ik werk met een buffervat dat ik na een warmtevraag oplaad en leegtrek alvorens een nieuwe warmtevraag te plaatsen. Dit om mooie lange runs te krijgen). Enfin, hier ook weer iets voor verzonnen, de regeling mag nu zn gang gaan gedurende de eerste 15minuten en pas daarna ga ik de maximale aanvoer aanpassen. Ik verwacht begin volgende week de OpenTherm gateway om daarmee de gevraagde aanvoer temperatuur te kunnen manipuleren ipv deze te begrenzen door middel van de maximale waarde aan te passen.
Echter wat jij aan het doen bent is wel echt next level. Althans voor mij in ieder geval. Super tof dat je dit doet en je bevindingen deelt. Als je er werkelijk in slaagd om een programma te maken welke op een chip te schrijven is die gewoon in de bestaande socket kan worden geprikt, hoop ik dat je deze ook wil delen :)
Thank you and keep the good work up _/-\o_

Acties:
  • +5 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Ik heb meer tijd geinvesteerd om het protocol van de Chofu unit (warmtepomp) naar de conrtolbox verder te snappen. Hervoor heb ik data tijdens een defrost, met de buitentemperatuursensor in warm water, en tusen twee bevroren loempia's (moest toch wat om de temperatuur negatief te krijgen...). Hierdoor ben ik aardig opgeschoten. Eerst even een samenvatting van de basis:

De Chofu en control box communiceren via een Universal Asynchronous Receiver/Transmitter-protocol dat op enkele tientallen volts loopt. Hoeveel weet ik niet precies.
In de control box wordt dit naar 0~5 V omgezet. Dat heb ik afgetapt.

Een paar berichten eerder heb ik beschreven hoe de communicatie wordt geinitieerd. De Control box is blijkbaar zo geprogrammeerd dat die direct (in de praktijk na 8 ms) weer begin te zenden als de Chofu heeft aangegeven daar klaar voor te zijn (100 ms wachttijd).

Het blijkt echter niet nodig om op een puls vanuit de Chofu te wachten; de controller kan gewoon gaan zenden en de Chofu begin dan terug te sturen, mits de wachttijd van 100 ms wordt overschreden. Het interval tussen de berichten hoeft ook niet constant te zijn en lijkt naast het minimum van 100ms, ook rustig 50ms of langer te mogen zijn.
Positief gevolg is dat een puls-detectie niet nodig is. Gewoon iedere 600 ms een bericht sturen werkt ook,

Daarna verloopt de communicatie dus net als 'buiten' via een 'Universal Asynchronous Receiver/Transmitter' (UART) protocol met 666 bps (1.5 ms per bit), 8N1: 1 start bit, 8 data bits, geen parity en 1 stop bit.

Visuele opbouw van een bericht:
Afbeeldingslocatie: https://tweakers.net/i/0kGMkmeu9KWi2mPZEqF_Gjs-cs4=/800x/filters:strip_exif()/f/image/ayZ2M7vBIZ8ocWgBDDaGGW3m.png?f=fotoalbum_large


UnitIndentificatieBericht nummer Data lengtePayload
Chofu0x910x00~0x038, 12, 8 & 8 bytes incl. checksum3, 7, 3 & 3 bytes
Control box0x190x00~0x0312, 13, 18, 20 bytes, incl. checksum, inclusief 'stop 0'7, 8, 13 & 15 bytes

Checksum methode: CRC-CCITT (0xFFFF), aka CRC-16/IBM-3740 met poly 0x1021 en init 0xFFFF

Nu is wat ik toe nu heb kunnen bevestigen of vermoeden over de communicatie.
  • Die uit de controlbox is eenvoudig: Slechts 2 bytes (en 2 checksum bytes natuurlijk) heb ik zien veranderen.
  • Er komt echt een zee van dat uit de Chofu waarvan ik ~1/3 (de meest nuttige ook) vrijwel zeker weet. De codering hieronder is: Identifier (19 of 91), bericht nummer (0~3) en byte nummer in bericht (1st byte is '0'):
Control box to Chofu
19-0,3? 0x00, no change observed
19-0,4? 0x00, no change observed
19-0,5? 0x00, no change observed
19-1,3? 0x00, no change observed
19-1,4? 0x00, no change observed
19-1,5? 0x00, no change observed
19-1,6? 0x00, no change observed
19-1,7? 0x00, no change observed
19-1,8? 0x00, no change observed
19-1,9? 0x00, no change observed
19-2,3Compressor Off(0) - On(1)
19-2,4Compressor speed setpoint (0x00~0x0A)
19-2,5? 0x00, no change observed
19-3,3? 0xB2, no change observed
19-3,4? 0x02, no change observed
19-3,5? 0x00, no change observed


Chofu to controlbox
91-0,30x0D, no change observed
91-0,40x07, no change observed
91-0,50x04, no change observed
91-0,60x2F, no change observed
91-0,70x5A, no change observed
91-0,80xCE, no change observed
91-0,90xE1, no change observed
91-1,3??Mode of operation ? 0x40 = defrost, 0x50 = normal operation?
91-1,4Indicates defrost ongoing (0x00 Normal, 0x01 defrost)
91-1,5? 0x00, no change observed
91-1,6? 0x00, no change observed
91-1,7? 0x00, no change observed
91-1,8? 0x00, no change observed
91-1,9?Possibly compressor on (0x8A) and off (0x00). Is ~1 s ahaead of actual power registration
91-1,10??Possibly fan speed
91-2,3Return temperature Low byte
91-2,4Return temperature High byte
91-2,5Supply temperature Low byte
91-2,6Supply temperature High byte
91-2,7Outside temperature Low byte
91-2,8Outside temperature high byte
91-2,9Switch for alternating data (Either 0x00 or 0x01)
91-2,10Alternating data
91-2,11Alternating data. Probably defrost sensor (at bottom of evaporator)
91-2,12Alternating data. Possibly discharge temperature compressor
91-2,13Alternating data
91-2,14Alternating data. Possibly discharge temperature compressor
91-2,15Alternating data. Some relation with compressor
91-3,3?? Possibly LSB of pump speed?
91-3,4?? Possibly MSB of pump speed?
91-3,5Probably pump speed (hex2dec x10)
91-3,6?? Gas temperature or pressure??
91-3,7Has some relation with mode of unit.
91-3,80x00 or 0x01. Indicates defrost or switch for something?
91-3,9Compressor speed in % or Hz, conversion Hex2Dec
91-3,10Compressor power uptake in Watt, conversion (Hex2Dec*256/10)
91-3,110x02, no change observed
91-3,120x00, no change observed
91-3,130x18, no change observed
91-3,140x00, no change observed
91-3,150x00, no change observed
91-3,160x00, no change observed
91-3,170x00, no change observed


De instelling van het vermogen via vermoedelijk het toerentaal van compressor (in Hz of %) is niet triviaal. De Chofu heeft een eigen willetje...
Na opstart altijd 20 a 30 minuten zijn alleen stand 2 (~400 W) of 3 (~650W) mogelijk. Daarna kon ik tot stand 7 gaan, maar het laatste stap was maar ~100 W extra (iets is maximaal?) Ook wilde stand 1 (240W) niet, terwijl ik dat eerder 100% zeker heb gezien. Kan zijn dat de buitentemperatuur een rol speelt.

Temperaturen (voor zover tot nu heb gezien) worden als 2 bytes in ‘little endian’ notatie doorgegeven. Omrekening met 1 formule zodat negatieve temperatuur (in ieder geval relevant voor buitentemperatuur) correct wordt weergegeven, kan als volgt:
T [oC] = ((MSB*256)+LSB)-(65536*IF(MSB=255;1;0)))/10

Ergens zal ook ruimte zijn voor communicatie van foutmeldingen. Maar gelukkig heb ik die (nog) niet. Misschien ga ik die later eens induceren door foutmeldingen die in de handleidingen worden genoemd in relatie tot bv. temperatuur sensoren, op te roepen door bv. stekkertjes los te halen. Maar dat is ook wel wat griezelig want ik wil geen schade veroorzaken natuurlijk.

[ Voor 10% gewijzigd door WackoH op 06-02-2025 20:27 ]


Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Voro de aardigheid wat grafieken.

Vermogen en temperatuur tijdens een defrost:
Afbeeldingslocatie: https://tweakers.net/i/rxX0LfxVn-Ogp6gWymqNQMvNfZM=/800x/filters:strip_exif()/f/image/oSqh9SnfF2GPOLmPU7xEZECt.png?f=fotoalbum_large

Negatieve temperaturen:
Afbeeldingslocatie: https://tweakers.net/i/Yc_bqckseqp78OE3aJJsQ3-IAIY=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/BjRUc0uNap65066J7Hsxpdnc.png?f=user_large

Dan die gekke 'alternating data'. Byte 91-2,9 flipt steeds tussen '0' (2 berichten lang) en '1' (1 bericht lang). Vooral bij '0' laten bytes 91-2,10~15 data zien die wellicht ook iets met de gas temperaturen te maken heeft want ze veranderen tijdens de defrost. Maar wat het precies is...
Afbeeldingslocatie: https://tweakers.net/i/aXaFDQXJ7EfR3mIxOJSe6qDS1CI=/800x/filters:strip_exif()/f/image/yiRK0x7qJgbW7DEno3dsifo0.png?f=fotoalbum_large

Acties:
  • +1 Henk 'm!

  • Marc001
  • Registratie: Augustus 2022
  • Laatst online: 06-06 14:07
Hoop werk!
Tja en die loempia's.... _O-

Interessant om te lezen dat die 20min startup na lange stilstand dus een hard gegeven zijn.

Dat is wel vervelend omdat je eigenlijk meteen naar hogere vermogens wil.
Zal dit te maken hebben dat er minimaal een bepaalde gasdruk / temperatuur nodig is voordat hogere vermogens van de compressor gevraagd mogen worden.... om zo componenten van de Chofu te beschermen.

Acties:
  • 0 Henk 'm!

  • Azbest
  • Registratie: April 2000
  • Laatst online: 21-05 20:01
Dit is best wel een knap staaltje reverse engineering. Ik heb ook zo'n onding thuis en vroeg me in de eerste week al af of die controlbox ook kan vliegen. Ik probeer nu met een arduino op elektronisch niveau de boel te hacken. Huidige status is om met een digitale potentiometer de temperatuur te beïnvloeden.

Ondertussen zijn er ook gedachten om gewoon een VFD te pakken en de pomp en de fan rechtstreeks aan te sturen met een arduino. Punt is alleen dat ik te weinig weet van warmtepompen om zelf een programma te maken.

Acties:
  • +5 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Ik heb in het begin een keer met een hamer in m'n hand gestaan om die controlbox van de muur te meppen... Gelukkig ben ik daarvoor behandeld (bij wijze van spreken dan ;) ) en heb die wraakgevoelens kunnen ombuigen naar een drang tot vreedzaam reverse engineeren...

Direct aansturen van fan of compressor is kansloos. En gelukking ook absoluut onnodig!
Die Chofy unit is prima en laat 'm maar lekker zijn (haar?) ding doen.

Beter de aansturing overnemen. Zo blijven defrosts en vorst- en andere beveiligingen gewoon functioneren.

De simpelste Arduino op 8 MHz (is op basis van zelfde microcontroller als in de controlbox...) doet dat met gemak! Het enige wat je moet doen is de juiste weerstand op de print aan 1 kant loshalen, en daar een (soft) serial van een Arduino op aansluiten, Dat is op mijn print (rev 1.00) R14 (1 kOhm). Dat doe je dan aan de kant van de pin 26 van de microcontroller zodat je via die R14 je Arduino op T2 aan kunt sluiten.

Je moet dan steeds vier berichten achter elkaar op 666 bps (met 100 ms tussenpozen maar dat komt niet kritisch kwam ik recent achter, en standaard 8N1 met je Arduino versturen.

Deze berichten bevatten dan:
byte data0[] = { 0x19, 0x0, 0x8, 0x0, 0x0, 0x0, 0xd9, 0xb5 };
byte data1[] = { 0x19, 0x1, 0x0c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x35 };
byte data2[] = { 0x19, 0x2, 0x8, 0x1, 0x1, 0x0, 0x99, 0x37 };
byte data3[] = { 0x19, 0x3, 0x8, 0xb2, 0x2, 0x0, 0xc1, 0x9a }

Het enige wat je moet doen om de Chofu te bedienen zijn bytes 4 en 5 van data 2 wijzigen (staan hierboven op 1 en 1;dat betekent 'aan' op stand '1' = ~240W, en de checksum (bytes 7 en 8) overeenkomstig aanpaasen.
Byte 4 is dus 0 (uit) of 1 (aan), bytes 5 is stad 0~10 waarbij stand 1 ~240 Watt is. Ruim 600 watt krijg je op stand 3.
Die bijborende checksum voor byte 7 en 8 staat hieronder als resp. checksum1[] en checksum2[] )

byte checksum1[] = { 0x9d, 0x99, 0xcc, 0xff, 0x66, 0x55, 0x00, 0x33, 0x23, 0x10, 0x45 };
byte checksum2[] = { 0x36, 0x37, 0x64, 0x55, 0xc2, 0xf3, 0xa0, 0x91, 0xaf, 0x9e, 0xcd };

Je kunt de checksum ook berekenen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void calculate_CRC_CCITT_Checksum(uint8_t *data, uint8_t length, uint16_t *checksum) {
    uint16_t crc = 0xFFFF; // Initial value
    for (uint8_t i = 0; i < length; i++) {
        crc ^= (uint16_t)data[i] << 8;
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 0x8000) {
                crc = (crc << 1) ^ 0x1021;
            } else {
                crc <<= 1;
            }
        }
    }
    *checksum = crc;
}


Ik heb een rotary switch als input op de Arduino gebruikt om de stand te selecteren. Maar dat kan natuurlijk op verschillende anderen manieren.

PS; De controlbox raakt hiervan wel een beetje in de stress want de signalen die van Chofu komen zijn niet meer in overeenstemming met wat er wordt heengestuurd. Maar 'who cares' 8) Het enige effect is dat je niet altijd meer de aanvoer en retour watertemperatuur met de Plugwise app kunt uitlezen.

Ik ga ook kijken wat ik met een ESP8266 of EPS32 kan doen zodat de unit ook via wifi is aan te sturen,

[ Voor 7% gewijzigd door WackoH op 14-02-2025 01:27 ]


Acties:
  • 0 Henk 'm!

  • wybe-V
  • Registratie: Augustus 2023
  • Laatst online: 14:12
https://durocan.com/downloads/?v=1a13105b7e4e
Dit vond ik nog op internet oa over de buiten unit
Staat ook nog een document bij met software
Mogelijk kan dit helpen voor aanpassen van de controle box 🤗

Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Bedankt. Ik heb de documenten doorgekeken maar helaas niet iets gevonden wat direct nuttig was.

Acties:
  • 0 Henk 'm!

  • P1 modubus
  • Registratie: Maart 2023
  • Laatst online: 11:42
Goedendag allen, heb de WP geïnstalleerd, deed zeker niet wat ik wilde, nadien meer info gezocht en ben zodoende ook bij jullie uitgekomen, zag ook bij de wp documentatie een modbus aansluiting, daar kon ik nog iets mee, maar het verhaal wat er verder werd geschreven kon ik het niet meer goed volgen, nu ik de wp een beetje begrijp heb ik op mijn kennis een oplossing gezocht, zover mogelijk bij het ordinaal gebleven.
De bijpas zo ingeregeld, bij normale flow van de installatie, dat deze op een delta T van 5 grd C draait, de cv ketel een Calenta ace 28C nog niet op de smile aangesloten, zal dit nog wel proberen na hier eerder het verhaal gehoord te hebben dat dit enkele malen geprobeerd moet worden. verder heb ik de weerstand van de buitenunit met 85 Mega-ohm kortgesloten( wel geschakeld)
zal dit nog wel aanpassen gaf bij een 11 grd buiten temperatuur 17 grd aan dat is voor mij te veel het moet ook rendabel blijven een COP van 2-2.5 moet het zeker hebben anders is bij mij het stoken op gas een goedkopere optie, maar dat de pomp blijft lopen dat stoort ook mag rustig tot o grd C uit blijven, zodoende zal ik wel op een weerstand van 200 M-ohm uitkomen bij vorst, voor de COP van 2.5 moet ik nog achterhalen, als dit ook bij 0-1 grd zit dan kan ik de 200 -ohm vast aansluiten, anders maak ik een schakeling dat deze waarde kortsluit met de buitentemperatuurweerstand.
Bij mij draait deze nu rustig en moduleert prima, zie plaatje. Heb vloerverwarming die zoals hier eerder geschreven moeilijk is te regelen zodat de binnen temperatuur mooi constant blijft, hier is het zo sla de vloer niet koud is, is het altijd aangenaam ook tussen de 18-21 grd, bij 22- 23 grd kan de vloer uit dan blijft het toch aangenaam.
Heb reeds gemaild naar de fabrikant WP als Plugwise, het regelgedrag dus het algoritme is geheim wordt niet vrijgegeven, maar het wordt steeds duidelijker dat het om zeer veel berekeningen en data gaat, te veel verschil in gewenst en gemeten ruimtetemperatuur gaat de ketel stoken, zal zeker een berekening zijn van de gewenste watertemperatuur.
Hier koelt het niet veel af dus het verschil is niet groot dat helpt zeker.
de wp loopt tot nu toe goed en constant. tot zover weer.

Acties:
  • 0 Henk 'm!

  • Marc001
  • Registratie: Augustus 2022
  • Laatst online: 06-06 14:07
@WackoH

Als jij via je Arduino na lange stilstand (meer dan 3 uur) de Chofu wil opstarten met meer dan 600W.
Is dit dan mogelijk? Of word je dan begrenst op die 600W?

Kortom is de 600W een begrenzing van de Controlbox of de begrenzing van de Chofu zelf?

Dank je.

Acties:
  • 0 Henk 'm!

  • P1 modubus
  • Registratie: Maart 2023
  • Laatst online: 11:42
De WarmtePomp is geen cv ketel die op elk moment aan en uit kan, een cv ketel start ook niet maximaal, een WP past het beste bij een vloerverwarming, het gaat allemaal iets rustiger aan toe, ook de ruimtetemperatuur laat je ook niet ver uit elkaar lopen, ik stook meestal niet meer na 20.00 uur, laat de binnen temperatuur middags iets oplopen, bij een buitentemperatuur >11 grd hoef morgens nog niet te stoken.
Heb ook gezien dat de WP, nadat de bypass is ingeregeld, ook op modulerend ongeveer op een Dt van 5 grd draait.
Heb een beeldplaatje geüpload, maar zie in deze niet terug, ben hier nieuw, kan me iemand schrijven hoe dit moet?

Tot nu gaat het een heel stuk beter, is wel jammer dat je er een studie van moet maken, de ketel koppelen Opentherm is nog niet gelukt,

Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Het is na stilstand van meerdere uren een begrenzing van de Chofu zelf

Toevallig gisteren nog gezien toen de buitenunit vanwege het warme langere tijd had had uitgestaan.

Ik weet niet bij welke tijdsduur van stilstand het omslagpunt ligt, en of de controlbox ook nog een beperking oplegt.

Het kan zijn dat de buitentemperatuur ook een rol speelt. Zo zag ik bij +10 wel weer dat de buiteunit op stand 1 (~240W) wil draaien, wat rond de 0oC niet ging (dan was het minimum stand 2, ~450W)

Acties:
  • 0 Henk 'm!

  • Marc001
  • Registratie: Augustus 2022
  • Laatst online: 06-06 14:07
P1 modubus schreef op maandag 24 februari 2025 @ 11:44:
De WarmtePomp is geen cv ketel die op elk moment aan en uit kan, een cv ketel start ook niet maximaal, een WP past het beste bij een vloerverwarming, het gaat allemaal iets rustiger aan toe, ook de ruimtetemperatuur laat je ook niet ver uit elkaar lopen, ik stook meestal niet meer na 20.00 uur, laat de binnen temperatuur middags iets oplopen, bij een buitentemperatuur >11 grd hoef morgens nog niet te stoken.
Heb ook gezien dat de WP, nadat de bypass is ingeregeld, ook op modulerend ongeveer op een Dt van 5 grd draait.
Heb een beeldplaatje geüpload, maar zie in deze niet terug, ben hier nieuw, kan me iemand schrijven hoe dit moet?

Tot nu gaat het een heel stuk beter, is wel jammer dat je er een studie van moet maken, de ketel koppelen Opentherm is nog niet gelukt,
Dat klopt niet helemaal, de Chofu kan wel degelijk in één keer vanuit stilstand naar zijn max van 2200W.
Dit is ook duidelijk te zien in homewizard en plugwise.

Echter wil hij niet naar vol vermogen bij langere stilstand, dan blijft hij hangen op 20min 600W.

Vooral na opstart in de nacht of een warme dag (WP uit) en einde dag wordt het kouder (WP aan).
Er wordt dan gestart met 600W 20min.
Ondertussen bouwt de Anna de setpoints op, gevolg is dat de WP niet kan bijbenen (blijft hangen op 600W).
Waardoor de ControlBox de opdracht aan de CV geeft.

Overigens is de bypass puur voor de vorst periodes.
Niet om je delta T naar 5 graden te krijgen.
Je verspilt onnodig opgewekte warmte van de WP rechtstreeks naar de retour.
Dat sommigen dit doen, kan, maar het is beter je systeem waterzijdig in te regelen.

@WackoH Thx :)

Acties:
  • 0 Henk 'm!

  • P1 modubus
  • Registratie: Maart 2023
  • Laatst online: 11:42
Afbeeldingslocatie: https://tweakers.net/i/XDCJcX4k2B2yr6v0T3lgOcGj-ek=/fit-in/4920x3264/filters:max_bytes(3145728):no_upscale():strip_icc():strip_exif()/f/image/OqMhFHmeuOrnENtlDyIRy1nQ.jpg?f=user_large
Het is zeker niet alleen voor de vorst periode, het is zeker dat je de installatie goed inregelt, als je op volle capaciteit1600 Watt draait met een Dt van 5-6 grd dan boet je zeker niet in, koelmachines draaien meestal met een Dt van 6 grd ook Remeha, alles draait perfect ook als het hydraulisch minder wordt dan zorgt de bypass voor geen geruis en een perfecte Dt, zag ook dan modulerend perfect gaat Dt blijft goed, de warmtepomp doet dit perfect, en gaat ook minder aan uit, tijdens het schrijven is de WP zelfs pas na 25 minuten van 600 Watt naar 1200 Watt gegaan 1ste opstart vandaag, wist niet dat dit alleen bij een grotere stilstand gebeurd.
Weet niet of het plaatje zichtbaar wordt, zie dit dadelijk.

Acties:
  • 0 Henk 'm!

  • P1 modubus
  • Registratie: Maart 2023
  • Laatst online: 11:42
Afbeeldingslocatie: https://tweakers.net/i/pfqm98QsDxp8G7H7G1S4MkLm6s8=/fit-in/4920x3264/filters:max_bytes(3145728):no_upscale():strip_icc():strip_exif()/f/image/29H5xCUM4cINXqja3BICrkBu.jpg?f=user_large
Zie nu het plaatje nu in deellast, je kunt de temperaturen erbij zien, ook de retour van de installatie, ook de Dt, vermogen in Amp en Watt meterstand is voor je niet interessant die gegevens komen van een goedgekeurde E-tussenmeter .

Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Die geregelde bypass is een mooie concept om de nukken van de combinatie warmtepomp en controlbox te omzeilen. Maar je moet het eigenlijk niet willen.

Met die extra bypass (intern is er ook al eentje) wordt een deel van het verwarmde water weer terug naar de warmtepomp gestuurd. Zo til je temperatuur van de aanvoer en retour omhoog. Hogere watertemperaturen betekenen volgens mij per definitie dat het rendement (COP) lager wordt.
Nu gaat het hier maar om een paar graden en voornamelijk tijdens de start dus verder geen ramp, maar verschil maakt het wel.

Verder lijkt me een delta_T van 5oC geen wet, maar een handige vuistregel. Het water gaat met een vast debiet rond (tenminste, ik heb nog niet gevonden dat de pomp bij deze unit actief wordt gemoduleerd, maar kan dat ook niet uitsluiten), terwijl de warmtepomp een sterk wisselende hoeveelheid warmte toevoegt. Dus dit betekent dan weer per definitie dat de delta_T tussen aanvoer en retour sterk varieert. Bijvoorbeeld in mijn geval tussen de 1oC bij minimum en 5oC bij maximum vermogen. Wat de aanvoer/retourtemperatuur dan wordt hangt af van het warmteafgifte systeem. Radiatoren geven minder efficient warmte af dan een vloerverwarming, dus in het eerste geval liggen de temperaturen hoger.

Ik zie geen enkele reden (behalve in het Aurea geval :X ) waarom je bewust het hele systeem minder efficient zou moeten gaan laten werken door de warmtepomp kort te sluiten om zo een delta_T van 5oC te bereiken. Het betektent daarnaast ook dat de verdeling door de rest van de installatie verstoort raakt omdat je daar nu wisselende hoeveelheden water heen gaat sturen.


Over de wisellend vermogen gesproken: Ik zie overigens duidelijk dat bij een vast uitsturing naar de Chofu, het opgenomen vermogen sterk afhangt van de retour/aanvoertemperatuur (hogere temperaturen --> hoger vermogen). Het gaat om tientallen procenten verschil. De reden lijkt me dat het meer moeite (groter drukverschil) kost om het koelmiddel een hogere tempeatuur op te laten wekken zodat de compressor meer vermogen op gaat nemen als die met een bepaald toerental draait.

Acties:
  • 0 Henk 'm!

  • P1 modubus
  • Registratie: Maart 2023
  • Laatst online: 11:42
Het is misschien een misverstand, de bypass is de meegeleverde bypass niet een extra, deze wordt ook niet steeds bijgeregeld, deze heb ik vast ingesteld zoals in de bijschrijving summier beschreven staat, alleen ik heb de mogelijkheid benut van een secuur systeem, om een dt van 5-6 grd te krijgen, bij een ingeregelde cv installatie dat hydraulisch bijna altijd het zelfde is of meer flow, je ziet ook aan de retour van de cv installatie maar weinig verschil, 1/2 grd C,
Ook werd er in dit platform eerder geschreven dat als het Dt te groot wordt dat dan de cv ketel in bedrijf komt,
Het is aan jullie hoe jullie het willen, maar nu ik iets meer van het systeem begrijp en zie hoe het bij mij functioneert ben ik best tevreden met weinig aanpassingen, gisteren 5.5 Kwh verbruikt, WP bijna aaneen stuk verwarmd, met een hoge piek tijdens het installeren van de CV ketel via opentherm, rest perfect gedraaid, zie plaatje
Afbeeldingslocatie: https://tweakers.net/i/7PYwKCnTYMWM-yRoPbGuB5xc40Q=/800x/filters:strip_icc():strip_exif()/f/image/L6HeYDI4x6RfrQO0C7b3pHUz.jpg?f=fotoalbum_large
Het is ook gelukt om deze te koppelen helaas geeft de ketel dan een storing geen ruimteopnemer aangesloten, zal met Remeha telefoneren of hier een oplossing voor is, anders laat ik de Remeha standalone werken, niet aangesloten op de Plugwise regeling, deze kan ik via de app als nodig laten bijstoken, thermostaat naast de ketel hangen, laat dan Plugwise aan mijn regeling aangeven dat er warmte gevraagd wordt, via een Digitale ingang.
Nogmaals de koelsystemen zijn uitgelegd met een Dt van 6 grd een CV ketel met een Dt van 20 grd, als je een Dt van 5-6 grd hebt bij een maximaal vermogen dan werkt het perfect, is de flow over de unit niet te hoog en te laag, is de Dt te hoog heb een te kleine flow, is de Dt te klein is de flow te hoog,
Zie dan dat de WP het zelf ook perfect aanpast in deelvermogens.
Misschien was ik iets te onduidelijk maar de eerder plaatjes gaven de installatie goed weer er is niets meer of extra's toegevoegd. tot zover

Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Ik had inderdaad de indruk dat je de bypass actief bijregelde naar een delta_T van 5oC. Maar goed om te horen dat je het met de basisspullen goed hebt gekregen! Mooi werk.

Verder schijnen er meerdere software veries te zijn. Maar dat is lastig te achterhalen omdat de enige aanwijzing het stickertje op de microntrollers in de controlbox is. Bij mij staat er bijvoorbeeld Tesla2_M op

Acties:
  • 0 Henk 'm!

  • P1 modubus
  • Registratie: Maart 2023
  • Laatst online: 11:42
Na overleg met Remeha kan het probleem, het missen van een ruimteopnemer opgelost worden, ben alleen nog het twijfelen en of ik het aansluit, de thermostaat heb ik nu opgehangen naast de ketel en is via de app benaderbaar en te bedienen.
Eenmaal was de WP gestopt en wilde zomaar zonder verklaring de CV ketel laten stoken, dus laat ik het voorlopig zo.
Ook heb ik nu na een koude nacht de schakeling aangezet dat de buitentemperatuur 6 grd hoger maakt voor de WP, normaal neemt deze 7 watt op, bij 4 grd C wordt dit 54 Watt, dan laat de WP de circulatiepomp onnodig lopen, Ik zal naar 200 Mohm (nog uitproberen na montage kijk ik dit na op de WP zelf) gaan in de winter voor 4 grd verhogen van de buitentemperatuur, dit heeft 2 voordelen
1/ de circulatiepomp gaat niet onnodig draaien, bij 0 grd C pas;
2/ de WP blijft werken tot het rendement zodanig wordt dat het niet meer loont, dit kan ik met een schakeling automatisch laten gebeuren.

Alleen heb ik gemerkt dat de regeling bij mij niet aan of uit gaat via een rooster vannacht ging deze pas om 23.30 uur uit, heb zeker 3 tijden gezet 20.00, 22.00, 23.30 uur op nacht 18.00 grd staan.
Handmatig bediening en weergave denk ik op de Anna beter is dan de online versie,.
Afbeeldingslocatie: https://tweakers.net/i/IPK8UntVMy3dsvg95WHpwUkGQcI=/x800/filters:strip_icc():strip_exif()/f/image/Lq0gpibo9A5bnjNZNS6hj17b.jpg?f=fotoalbum_large
Afbeeldingslocatie: https://tweakers.net/i/dDV0b1Bc2jw_3mUwn5yrBB7fNUQ=/x800/filters:strip_icc():strip_exif()/f/image/p0Xm4uXw25e0Y9L6Jx8X9X1A.jpg?f=fotoalbum_large
Zie de verschillen in de een is het volgens rooster en op de Anna is dit niet,
Ik vind het zelf leuk om iets te achterhalen zeker in de Meet&Regel techniek, maar vindt het jammer dat er ook geen eenvoudige rechtstreekse regeling bij kan, dit zal de WP beter verkoopbaar maken, zelf vind ik het, het beste apparaat voor mijn situatie, dat gun ik zeker iedereen.

Acties:
  • +2 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Hallo,

Het is misschien wel aardig om te zien hoe eenvoudig de Chofu warmtepomp kan worden aangestuurd.
Ik gebruik hiervoor een Arduino Diecimila met een rotary encoder.

In de controlbox heb ik 1 kant van weerstand R14 losgehaald (deze kant is bewust zodat de uitgang van de microcontroller door R14 beschermd blijft), en in een (groen) draadje met aan beide zijden een een DuPont connector gesoldeerd. De andere kant heb ik via een 1 kOhm weerstand met pin 2 van de Diecimila verbonden.
Verder heb ik aan de losse kant van weerstand R14 een draadje met een contra DuPont connector gesoldeerd. Zo kan ik de oorspronkelijke situatie herstellen door deze twee connectoren in elkaar te schuiven:
Afbeeldingslocatie: https://tweakers.net/i/cM2yZN5e1kkKeKjPh1aGVzXT1PQ=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/BvD1xgame5eiuxTR6SZNKVFa.png?f=user_large

Daarnaast heb ik een min (of aarde) verbinding via PAD3 gemaakt door daar een connector in te solderen, en die met een GND van de Diecimila te verbinden. (De onderstaand foto is van voordat ik de verbinding heb gemaakt):

Afbeeldingslocatie: https://tweakers.net/i/8IqNuBhqSqBq0kIS_cOeFxA6eHU=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/IYZBYPSPQmIZWluRUEloCVkw.png?f=user_large

Dit is met versie 1.00 van de print en natuurlijk allemaal op eigen risico. Houd er rekening mee dat een foute verbinding (met name bij PAD 1 en 2, deze zijn zonder beschermende weerstanden met de beide microcontrollers verbonden), tot schade kan leiden.

Dit is de code:
Arduino:
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
/* 
Simple way to control the power setting of a Chofu AEYC-0643XU-CH heatpump with an Arduino
The power is set with a rotary switch and send via one-way serial communication at 666 bps to the heatpump, using the hardware of Atantic Aurea controlbox.
Lift the side of resistor R14 that is connected to the base of T2, and connect the output pin (default is pin 2) of the Arduino  via a 1 kOhm resistor to the base of T2.
Version 1.0, JHN 02-03-2025 */

#include "SoftwareSerialTX.h"
#include <string.h>

// Use a SoftwareSerialTX on Pin 2
SoftwareSerialTX txOnly(2);

//Define variables and constants
int PowerSetpoint;                                // Setpoint to heat pump  warmtepomp wordt gestuurd
int PowerStages = 9;                              // Number of useful steps in heatpump setpoint
// For rotary decoder
int pinCLK = 10;                                  // CLK of rotary encoder
int pinDT = 9;                                    // DT of  rotary encoder
int pinSwitch = 8;                                // Push button of rotary encoder to confirm setting
int encoderPosCount = 0;                          // Count position rotary encoder
int pinCLKLast;                                   // for rotary encoder
int aVal;                                         // for rotary encoder
bool bCW;                                         // Boolean Clockwise for rotary encoder
bool btnPressed = false;                          // Button of rotary switch pressed?
bool currentState = LOW;
const int LEDPin = 13;                            // Pin to activate LED
int TelegramCount = 0;                            // Follow-up number telegrams
volatile unsigned long Interval = 0;              // Time since last telegram
// Telegram timing 
unsigned long currentMicros = 0;                  // Storage current micro seconds
unsigned long previousMicros = 0;                 // Tracks the last pulse start time
const unsigned long SendInterval = 600000;        // Interval between pulses in microseconds 
byte data0[] = { 0x19, 0x0, 0x8, 0x0, 0x0, 0x0, 0xd9, 0xb5 };                             // Array of hexadecimal bytes for 1st message (last two butes are checksum)
byte data1[] = { 0x19, 0x1, 0x0c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x35 };        // Array of hexadecimal bytes for 2nd message (last two butes are checksum)
byte data2[] = { 0x19, 0x2, 0x8, 0x1, 0x1, 0x0, 0x99, 0x37 };                             // Array of hexadecimal bytes for 3rd message. This is the message to change bytes 4 (on/off) and 5 (power setpoint), and bytes 7 and 8 (checksum)
byte data3[] = { 0x19, 0x3, 0x8, 0xb2, 0x2, 0x0, 0xc1, 0x9a };                            // Array of hexadecimal bytes for 4th message (last two butes are checksum)
byte checksum1[] = { 0x9d, 0x99, 0xcc, 0xff, 0x66, 0x55, 0x00, 0x33, 0x23, 0x10, 0x45 };  //Array of 1st byte of checksum of 3rd message. First byte of the array is for 'off' and output '0', 2nd byte is for 'on' and putput '1' etc.
byte checksum2[] = { 0x36, 0x37, 0x64, 0x55, 0xc2, 0xf3, 0xa0, 0x91, 0xaf, 0x9e, 0xcd };  //Array of 2nd byte of presumed checksum. First byte of the array is for 'off' and output '0', 2nd byte is for 'on' and putput '1' etc.

void setup() {
  pinMode(LEDPin, OUTPUT);                        // Set the pulse pin as an output    

  // Rotary Encoder Setup
  pinMode(pinCLK, INPUT);
  pinMode(pinDT, INPUT);
  pinMode(pinSwitch, INPUT_PULLUP);
  pinCLKLast = digitalRead(pinCLK);               // Read Pin CLK, current pin state corresponds to latest position
  
  // Serial Setup
  Serial.begin(115200);                           // Start the Serial Monitor for debugging (Serial port 0)
  txOnly.begin(666);                              // Set-up software serial baurdrate for sending info to heat pump at 666 baud (pin 2)
  Serial.println("Setup complete...");
 }

void loop() {
// Send telegram
  currentMicros = micros();
  if (currentMicros - previousMicros >= SendInterval) {       // Start a new pulse if 500,000 µs have elapsed
    previousMicros = currentMicros;
    digitalWrite(LEDPin, HIGH);
        switch (TelegramCount) {
          case 0:                                             // Send message 0 (no changes)
            sendTelegram(data0, sizeof(data0), "Telegram 0");
            break;
          case 1:                                             // Send message 1 (no changes)
            sendTelegram(data1, sizeof(data1), "Telegram 1");
            break;
          case 2:                                             // Send and modify message 2 after modifiyng bytes 4, 5,7 and 8 according to the selected power setting
            if (PowerSetpoint > 0) {
              data2[3] = 0x1;
            } else {
              data2[3] = 0x0;
            }
            data2[4] = PowerSetpoint;
            data2[6] = checksum1[PowerSetpoint];
            data2[7] = checksum2[PowerSetpoint];
            sendTelegram(data2, sizeof(data2), "Telegram 2");
            break;
          case 3:                                             // Send message 3 (no changes)
            sendTelegram(data3, sizeof(data3), "Telegram 3");
            break;
          default:
            Serial.println("Invalid TelegramCount value");
            break;
        }
        TelegramCount = (TelegramCount + 1) % 4;              // Cycle through 0-3
        digitalWrite(LEDPin, LOW);
  }

// Check rotary encoder
   processRotaryEncoder();
}
////// End of main loop //////

// Below are the subroutines
void sendTelegram(byte *data, size_t size, const char *name) {
  for (size_t i = 0; i < size; i++) {
    txOnly.write(data[i]);
    if (i < size - 1) {
      }
  }
}

void processRotaryEncoder() {                                 // Read rotary decoder and write to screen
  int aVal = digitalRead(pinCLK);                
  if (aVal != pinCLKLast) {                                   // Knog is being turned
    // Determine direction of rotation by reading pin B
    bCW = (digitalRead(pinDT) != aVal);                       // This means that Pin A changed first --> clockwise rotation 
    encoderPosCount += bCW ? 1 : -1;                          // Otherwise Pin Bchanged first so counterclockwise rotation
    encoderPosCount = constrain(encoderPosCount, 0, PowerStages);
  }
  pinCLKLast = aVal;

  if (digitalRead(pinSwitch) == LOW && !btnPressed) {         // Button is pressed 
    btnPressed = true;
  } else if (digitalRead(pinSwitch) == HIGH && btnPressed) {  // Button is released 
    btnPressed = false;
    PowerSetpoint = encoderPosCount;
  }
}

Acties:
  • 0 Henk 'm!

  • wybe-V
  • Registratie: Augustus 2023
  • Laatst online: 14:12
Mooi om te zie dat je dit lukt en dat het werkt om op deze wijze de WP aan sturen
Ik zelf zou dit ook wil willen proberen en het aanpassen van de print is geen probleem maar met de Arduino Diecimila heb ik totaal geen ervaring
Is het misschien 🤔 een optie om dit als compleet setje aan te bieden tegen betaling en een extra vergoeding voor ontwikkeling
Dit alles natuurlijk wil op eigen risico 🤗😇🤔

Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Oh, die Arduino Deicimila (een echte uit Italie, geen Chinese kloon) heb ik alleen maar voor de aardigheid genoemd. Ik heb het even nagekeken: Die heb ik in april 2008(!!) voor $33.50 bij Adafruit gekocht. Die is al lang niet meer verkrijgbaar

Welke microcontrollers je gebruikt is niet kritisch. Die van het Amerikaanse Atmel (tegenwoordig MicroChip) vormden de basis voor het Arduino ecosysteem (In de controlbox zitten trouwens twee ATmega8's, de lichtere versie van de ATmega168 in de Diecimila). Ik gebruik overigens voor het complexere programma een Arduino op basis van een ATmega2560 omdat die vier hardware seriele poorten heeft.

Tegenwoordig zijn microcontroller van het Chinese Espressif populair (ESP8266 en ESP32) omdat die wifi aan boord hebben en krachtiger zijn. Die hebben echter als nadeel dat ze met 3.3 V (ipv 5 zoals de bovnegenoemde Atmels) op de in en uitgangen werken. Ik denk dat die nog steeds de WP aan kunnen sturen want transistor T2 zit er tussen om de stroom naar optocoupler OK2 te versterken, maar inlezen van de data vereist een spanningsomzetter (kan een eenvoudige spanningsdeler met weerstanden zijn omdat de snelheden laag zijn).

Het beste installeer je de Arduino IDE want daarmee kun tientallen meer of minder complexe bordjes programmeren, en zoekt een courant microcontroller bordje, bv. de Arduino Uno. Het programmeren stelt echt niets voor. Ik was eerlijk niet van plan om geprogrammeerde bordjes rond te gaan sturen ;)

Acties:
  • +4 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Het stookseizoen zit er bijna op. De warmtepomp heeft het grootste deel van de tijd prima gedraaid en vrijwel zonder gasverbruik (de laatste maanden helemaal niets). Maar dat ging niet vanzelf...

Sinds december heb ik flink wat tijd besteed om eerst te snappen hoe de communicatie tussen de buitenunit en de controlbox verloopt, en de communicatie tussen de microcontroller in de controlbox.

Ik had al snel een simpel programma in Arduino IDE dat ik op de bovengenoemde Diecimila draaide. Hiermee kon ik de snelheid (vermogen) van de Chofu buitenunit d.m.v. een rotary decoder instellen.

Vervolgens heb ik nagedacht wel kant ik op zou gaan. Er zijn namelijk verschillende richtingen:
  1. De communicatie van en naar de warmtepomp met een eigen microcontroller afhandelen die het setpoint voor de aanvoertemperatuur via wifi van bv. Home Assistant krijgt. De elektronica van de controlbox dient alleen als hardware interface van en naar de warmtepomp.
  2. Op een eigen microcontroller bordje zowel de OpenTherm communicatie als man-in-the-middle tussen ketel en thermostaat, als die met de warmtepomp afhandelen, en de controlbox alleen als hardware interface voor beide protocollen gebruiken.
  3. Op zo’n manier in de communicatie naar de warmtepomp en tussen de microcontrollers in de controlbox ingrijpen dat de normale kamerthermostaat (Plugwise Smile + Anna) blijft werken, en bediening op afstand mogelijk is.
Optie 1 zou relatief makkelijk zijn, maar is voor mijn idee te kwetsbaar voor problemen met bv. Home Assistant; verwarming moet niet afhankelijk zijn van wifi etc. Optie 2 is de mooiste want dan geen last meer van de nukken van de controlbox. Er zijn meerdere Arduino IDE OpenTherm libraries die geschikt zijn voor verschillende microcontroller bordjes. (bv. https://reference.arduino...e/en/libraries/opentherm/). Maar om het niet al te complex te maken heb ik uiteindelijk optie 3 uitgewerkt.

Het concept heb ik in een eerdere post al uitgelegd. Hieronder staat een variant van de code zoals ik die nu op een Arduino Mega met een Atmel Mega2560 microcontroller gebruik. Het verschil met mijn eigenlijke code is dat ik alle schrijfacties naar een LCD met allerlei variabelen van warmtepomp en OpenTherm, eruit heb gehaald om de code compacter te houden en in plaats daarvan verschillende schrijfopdrachten naar de seriële poort gedaan (normaal gebruik ik die alleen voor foutmeldingen en troubleshooten). De code compileert, maar ik heb ‘m niet in het echt getest. Verder heb ik het gedrag op basis van buitentemperatuur (met name bij < -2.0oC alsnog CV inschakelen) bij gebrek aan juiste condities op het juiste moment, niet in de praktijk kunnen testen.
Tenslotte: Ik ben geen doorgewinterde programmeur, dus ik vergeef me als sommige zaken niet volgens het boekje zijn gedaan O-)

Een paar algemene opmerkingen.
  • Er wordt niets gedaan met foutmeldingen vanuit de warmtepomp. Dat kan de controlbox volgens de handleiding wel. Maar ik had geen zin om te proberen te achterhalen hoe dat allemaal is gedecodeerd. Het wordt vanzelf koud als er een probleem is...
  • De code gebruik nu 7 standen van warmtepomp. Stand 8 geeft maar een klein beetje meer vermogensopname. De COP daalt met toenemend vermogen dus begrenzen tot 6 standen (als dat genoeg warmte voor het huis oplevert) geeft een beter rendement.
  • De PID regelaar regelt conservatief als de afwijking tussen setpoint en aanvoertemperatuur minder dan 1oC is, en anders agressief. Dit voorkomt een overshoot omdat de Anna de gevraagde aanvoertemperatuur slechts binnen 0.2oC rond de gewenste kamertemperatuur regelt (in mijn geval tenminste).
  • De optimale PID parameters zullen van de karakteristiek van je eigen systeemm afhangen
  • Als er conservatief wordt geregeld, verandert het setpoint voor de WP niet sneller dan eens per 7 min. Dit op snel op en afschakelen van het vermogen te voorkomen
  • Mijn programma heeft een watchdog timer op basis van een interrupt. Die heb ik er hier uitgelaten omdat die hardware specifiek is
Al deze instellingen zijn natuurlijk wijzigen.

Hier de code voor de besturing:
code:
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
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
/* 
Alternative control for the Atlantic Aurea heat pump, which based on the Chofu AEYC-0643XU-AT unit.
This is a sketch to control the power setting of a heat pump with an Arduino ATMega2560 and to modify communication inside the controlbox using 3 of the 4 hardware serial ports of this board. 
The original code shows various useful information like temperatures etc. on a 480*320 TFT LCD. This has been removed here to keep the code more compact.
Version 0.1Beta, JHN 19-03-2025 */

#include <QuickPID.h>                                   // Library for PID controller, see for documentation: https://github.com/Dlloydev/QuickPID

//Define variables and constants
  // General
  String MessageString = "";

  // For heat pump
  const uint8_t SpeedStages = 7;                        // Number of speed stages to be used (7 --> ~1400 W max)
  uint8_t SpeedSetpoint = 0;                            // Speed setpoint sent to heatpump   // const uint8_t MinTempSetpoint = 25;
  uint8_t TargetTemperatureThermostat = 20;             // Target temperature as requested by the thermostat   
  const float MinTemp4HP = -2;                          // Outside temperatute below wich heat pump should stop working and CV should start
  uint16_t TelegramCount = 0;                           // Follow-up number of telegrams
  // Variables to track timings
  uint32_t Interval = 0;                                // Time since last telegram
  uint32_t currentMillis = 0;                           // Check timing for sending messages
  uint32_t LastSpeedSetpointChange = 0;                 // Keep track when last time speedsetpint has been changed in milliseconds
  uint32_t SpeedSetpointHysteresis = 420000;            // Allow a change in speedsetpoint only once per 7 minutes (when using slow PID parameter set)
  // Cycle time check
  uint32_t previousCycleMicros = 0;                     // To store the time of the last cycle start
  uint32_t currentCycleMicros = 0;                      // To store the time of the current cycle start
  uint32_t cycleTime = 0;                               // To store the calculated cycle time
  uint16_t cycleCounter = 0;                            // Counter to track cycles
  const uint16_t displayInterval = 10000;               // Display cycle time every 10000 cycles
  uint8_t lcdUpdateStep = 0;                            // Variable to spread writing to screen over multiple steps
  // Receive and send inter MCU data 
  const uint32_t McuMessageWaitTime = 200;              // Waiting time between receiving message on Pad 1 (Serial 1) and sending on pad 2 (serial 2) in ms
  uint32_t McuMessageOneReceived = 0;                   // Tie last message send in ms
  bool dataMcu2Send = false;
  uint32_t PreviousMessageSerial2Sent = 0;   
  uint32_t MessageSerial2Interval = 10000;              // Maximum interval for sending message on serial 2 (to avoid that communication stops)
  const uint8_t DataMcuLength = 12;                     // Length of each transmission between MCU's
  uint8_t dataArrayOT_IC1_IC2[DataMcuLength] = {0};     // Array to store the incoming 12 bytes for OT IC1 to IC2.
  uint8_t dataArrayOT_IC2_IC1[DataMcuLength] = {0};     // Array to store the incoming 12 bytes for OT IC2 to IC1.
  uint8_t dataArrayOT_IC1_IC2_Old[DataMcuLength] = {0}; // Array to store the previous incoming 12 bytes for OT IC1 to IC2.
  uint8_t dataArrayOT_IC2_IC1_Old[DataMcuLength] = {0}; // Array to store the previous incoming 12 bytes for OT IC2 to IC1.  
  uint16_t ChecksumMCU = 0;                             // Checksum for communication between MCU's
// Variables for communication with heat pump
  uint8_t CB_HPlength = 0;                              // Length of communcation CB to HP
  uint16_t ChecksumCBHP = 0;                            // Checksum for communication of heat pump with control box
  uint8_t ChecksumCBHPfalseCount = 0;                   // Counter for number of times that the checksum did not match. After certain number of mismatches, message will be send to the serial port
  uint8_t data0[] = { 0x19, 0x0, 0x8, 0x0, 0x0, 0x0, 0xd9, 0xb5 };                       // Array of hexadecimal bytes
  uint8_t data1[] = { 0x19, 0x1, 0x0c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x35 };  // Array of hexadecimal bytes
  uint8_t data2[] = { 0x19, 0x2, 0x8, 0x1, 0x1, 0x0, 0x99, 0x37 };                       // Array of hexadecimal bytes. This is the one to change bytes 4 (on/off) and 5 (setpoint), and 7 and 8 (high and low bytes of the CRC CCITT checksum)
  uint8_t data3[] = { 0x19, 0x3, 0x8, 0xb2, 0x2, 0x0, 0xc1, 0x9a };                      // Array of hexadecimal bytes

// Variables for sending messages to heat pump
bool IncomingMessageEnded = 0;                          // Last message start time in milliseconds
volatile uint32_t PreviousMessageSent = 0;              // Time when prveious message was sent in milliseconds
volatile bool IsReceiving = false;                      // Tracks if message is being received from heat pump to block sending next message to heat pump
const uint32_t SendTimeout = 2000;                      // Time in milliseconds to wait before considering the communication ended
const uint32_t SendDelay = 99;                          // Delay in milliseconds before sending information to heatpump
const uint32_t MinMessageSendInterval  = 300;           // Minimum interval in millis between sending messages when no reply is received
volatile uint32_t previousMessageInEnded = 0;

// Definitions for reading and checking heat pump data
  // Prepare array for storing data from heatpump
    const uint8_t StartByte = 0x91;                     // First byte must be 145 (0x91)
    const uint8_t Rows = 4;                            // Number of rows in heat pump data array 
    const uint8_t Cols = 80;                            // Number of columns in heat pump data array 
    uint8_t numChars = 0;                               // Number of characters to be written to screen
    uint8_t dataHeatPumpTemp[Cols][Rows] = {0};         // Array to store of four messages from heatpump before checksum check
    uint8_t dataHeatPump[Cols][Rows] = {0};             // Array to store of four messages from heatpump after checksum is correct
    uint8_t dataHeatPumpOld[Cols][Rows] = {0};          // Array to store previous data of four messages so that screen is only updayted when needed
    uint8_t extractedRow[Cols];                         // 1D array to store the row  
    const uint8_t ValidLengths[] = {13, 14, 19, 21};    // Lengths 12, 13, 18 & 20   (12+1), (13+1), (18+1), (20+1)
    uint16_t value;                                     // Temporarily storage of datapoint from array
    float valuefloat;
    uint8_t Length = 0;
    float T_supply =0;                                  // Supply water temperature by heatpump
    float T_return =0;                                  // Return water temperature to heatpump
    float T_outside =0;                                 // Outside temperature measured on heatpump
  // State variables for non-blocking serial reading
    enum SerialState {  Wait_Start,                     // Waiting for the start of a serial message  
                        Read_Header,                    // Reading the header of the message  
                        Read_Payload,                   // Reading the main data (payload)  
                        Read_End                        // Reading the end of the message  
                        };                              // Enumeration type, which helps in defining different states of serial communication
    SerialState state = Wait_Start;                     // Make waiting to start the default
    uint8_t ID = 0;
    uint8_t msgLength = 0;
    uint8_t DataLength = 0;
    uint8_t buffer[Cols] = {0};                         // Temporary buffer for incoming data
    uint8_t index = 0;
    int8_t NegT = 0;                                    // Store if temperature is negative (value of 255 in MSB)
  // For PID controller 
    float TemperaturePIDsetpoint = 20;                  // Desired supply temperature
    const float TemperaturePIDsetpointMax = 37;         // Maximum temperature setpoint
    float TemperaturePIDinput = 0;                      // Current suppy temperature (feedback from the sensor in the heatpump)
    float TemperaturePIDoutput = 0;                     // Heat pump control signal
    float TemperaturePIDoutputRounded = 0;              // Heater control signal, rounded off
    // PID tuning parameter. Default values were Kp = 2.0, Ki = 5.0, Kd = 1.0
    uint8_t PIDParameterSet = 0;                        // Keep track of whcih PID parameters set is being used so that new parameter or only written when required
    float Sensitivity = 3;                              // Sensitivity (ratio) between the slow and fast PID settings. Optionally make this chnageable via rotary encoder
    float PIDParameterThreshold = 1;                    // Threshold for switch between fast (agressive) and slow (conservative) PID parameters
    float T_GapPIDParameterSwitch = 0;                  // Gap between the setpoint and actual temperature, used to determine which set PID parameters to use 
    const float Kp0 = 0.02, Ki0 = 0.008, Kd0 = 0.01;// 
    float Kp = Kp0, Ki = Ki0, Kd = Kd0;// 
// Create PID object
  QuickPID myPID(&TemperaturePIDinput, &TemperaturePIDoutput, &TemperaturePIDsetpoint, Kp, Ki, Kd, /* OPTIONS */
                myPID.pMode::pOnError,                   /* pOnError, pOnMeas, pOnErrorMeas */
                myPID.dMode::dOnMeas,                    /* dOnError, dOnMeas */
                myPID.iAwMode::iAwCondition,             /* iAwCondition, iAwClamp, iAwOff */
                myPID.Action::direct);                   /* direct, reverse */

void setup() {
// Serial Setup
  Serial.begin(115200);                                   // Start the Serial Monitor for debugging on terminal (Serial port 0)
  Serial1.begin(9600);                                    // Start serial port 1 for receiving messages from OT MCU to HP MCU (RX1, 9600 bps)
  Serial2.begin(9600);                                    // Start serial port 2 to receive messages from HP MCU and send modified message to OT MCU (RX2 pin & TX2 9600 bps)
  Serial3.begin(666);                                     // Start serial port 3 for sending an receiving info to heat pump at 666 baud (RX3 and TX3)
  Serial1.setTimeout(100);                                // Changes the timeout for readBytes() and other blocking serial read functions (readString(), readBytesUntil(), etc.).
  Serial2.setTimeout(100);
// For QuickPID
  myPID.SetOutputLimits(0, 99);                           // Set to max 99% to have max. 4 digits ('99.9')
  myPID.SetSampleTimeUs(5000000);                         // Sample time of PID controller in microseconds. Made slower than default because of relatively slow temperature changes and heat pump response to save processing time.
  myPID.SetTunings(Kp, Ki, Kd);
  myPID.SetMode(myPID.Control::automatic);                // Set PID controller in automatic, i.e. input (PV) is perdiodically compared with setpoint (SP) and control variable (CV) is adjusted 

  Serial.println("Setup complete.");
}

//////////////// Main loop ////////////
void loop() {
  currentMillis = millis();                                 // get curent millis (ms) for sending message to heat pump
  currentCycleMicros = micros();                            // Capture the current time (in us) to calculate the cycle time of the loop
  cycleCounter++;                                           // Increment the cycle counter
  
// Check for incoming data on Serial 1 (Pad 1 from MCU 2), 2 (Pad 2 from MCU 1) and Serial 3 (data from heat pump)
readSerialMessageHP();                                      // Call this function continuously to check for data on the incoming serial port from the heat pump
if (Serial1.available() >= DataMcuLength) {                 // Check whether the serial buffer connected to Pad 1 contains DataMcuLength (12) bytes or more  
  Serial.print("Serial1.available()"); Serial.println(Serial1.available()); 
  readSerialMessageMCU(1);                                  // When so, jump to subroutine to read the bytes or clear the buffer
  McuMessageOneReceived = currentMillis;                    // Set timestamp after receiving message on pad 1 (from MCU 2 to 1)
  dataMcu2Send = true;                                      // Set flag to send message on serial port 2
  TemperaturePIDsetpoint = 1 + 0.85 * dataArrayOT_IC2_IC1[0];// Scale the setpoint from the thermostat (0, and 30~40oC) to 25~37oC
  if (TemperaturePIDsetpoint > TemperaturePIDsetpointMax){
    TemperaturePIDsetpoint = TemperaturePIDsetpointMax;
    }
  }
if (Serial2.available() >= DataMcuLength) {                 // Check whether the serial buffer connected to Pad 2 contains DataMcuLength (12) bytes or more 
  Serial.print("Serial2.available()"); Serial.println(Serial2.available()); 
  readSerialMessageMCU(2);                                  // When so, jump to subrotuine to read the bytes or clear the buffer
  }

// Write modified message from MCU 1 to 2 on serial 2, McuMessageWaitTime (default 200 ms) after receiving message on serial 1 
if ((((currentMillis - McuMessageOneReceived) >= McuMessageWaitTime) && dataMcu2Send == true) || ((currentMillis-PreviousMessageSerial2Sent) > MessageSerial2Interval))  {
  Serial2.write(dataArrayOT_IC1_IC2, sizeof(dataArrayOT_IC1_IC2));    // Write array to serial port 2
  PreviousMessageSerial2Sent = currentMillis;
  dataMcu2Send = false;
  }

// Send the next message to the heat pump 100 ms after the previous incoming message has ended, or after 1000 ms without sending anything. Use the periodic sending also to update the screen
  currentMillis = millis();                                 // get curent millis (ms) for sending message to heat pump
    if ((( (currentMillis - previousMessageInEnded >= SendDelay)  &&  (!IsReceiving))  || ( currentMillis - previousMessageInEnded >= SendTimeout )) && (currentMillis - PreviousMessageSent >= ( MinMessageSendInterval ))) 
      {
      switch (TelegramCount) {
        case 0:
          Serial3.write(data0, sizeof(data0));
          break;
        case 1:
          Serial3.write(data1, sizeof(data1));
          break;
        case 2:
          SpeedSetpoint = (int)round( TemperaturePIDoutput / (100 / SpeedStages )) ;    // Scale the PID controller output from 0~100% to 0~8 speed setpoints, and convert from double to rounded integer
          if (SpeedSetpoint == 0) {
            data2[3] = 0x0;
            data2[4] = 0x0;
            } else {
              if ((PIDParameterSet == 0) && (currentMillis - LastSpeedSetpointChange > SpeedSetpointHysteresis)) { // Add hysteresis when slow PID parameter set is active
                data2[3] = 0x1;
                data2[4] = SpeedSetpoint;                 // Write calculate speed setpoint in array  
                LastSpeedSetpointChange = currentMillis;
                } else {
                  if ((PIDParameterSet > 0) && (currentMillis - LastSpeedSetpointChange > SpeedSetpointHysteresis/5)) 
                    { // Hysteresis 1/5 of default when fast PID parameter set is active to allow for fast respons
                    data2[3] = 0x1;
                    data2[4] = SpeedSetpoint;             // Write calculate speed setpoint in array  
                    }
                  }
              } 
          CB_HPlength = sizeof(data2);
          calculate_CRC_CCITT_Checksum(data2, CB_HPlength-2, &ChecksumCBHP);  
          data2[6] = (ChecksumCBHP >> 8) & 0xFF;          // Replace byte 6 with checksum High Byte
          data2[7] = ChecksumCBHP & 0xFF;                 // Replace byte 7 with checksum Low Byte
          Serial3.write(data2, sizeof(data2));
          break;
        case 3:
          Serial3.write(data3, sizeof(data3));
          break;
        default:
          Serial.print("Invalid TelegramCount value:  ");Serial.println(TelegramCount); 
          break;
        }
//        Serial.print("Message ");Serial.print(TelegramCount);Serial.println(" sent!");  // Confirm that message has bene sent
        TelegramCount = (TelegramCount + 1) % 4;          // Cycle through 0-3
        PreviousMessageSent = millis();
      }

   if (cycleCounter >= displayInterval) {
        if (previousCycleMicros != 0) {
          cycleTime = ( currentCycleMicros - previousCycleMicros ) / displayInterval;  // Time difference between cycles
          previousCycleMicros = currentCycleMicros;           // Update the previous cycle time
      cycleCounter = 0;                                   // Reset the cycle counter
      } else {
        previousCycleMicros = currentCycleMicros;
      }
    switch (lcdUpdateStep) {
      case 0:                                             // Print the cycle time etc. The timing for sneding message to the heatpump wil be oof when the cycle time is too long (> ~50 ms)
        Serial.println("Cycle time "+String(cycleTime)+" ms");
      break;
      case 1:                                             // Print PID settings
      break;
      case 2:                                             // Compresor speed 91-3,9
        if (dataHeatPump[9][3] != dataHeatPumpOld[9][3]) {  // Data has changed?
          Serial.print("Speed setpoint: "); Serial.println(dataHeatPump[9][3]);
          }
      break;
      case 3:                                             // Compresor power 91-3,10
        if (dataHeatPump[10][3] != dataHeatPumpOld[10][3]) {
          MessageString = String((25.6 * dataHeatPump[10][3]),0);
          Serial.print("Compressor power: "); Serial.println(MessageString);
          dataHeatPumpOld[10][3] = dataHeatPump[10][3];
          }
        // Compressor mode 91-1,3
        if (dataHeatPump[3][1] != dataHeatPumpOld[3][1]) {
          Serial.print("Compressor mode: "); Serial.println(dataHeatPump[3][1]);
          dataHeatPumpOld[3][1] = dataHeatPump[3][1];
          }
        // Defrost?   91-1,4
        if (dataHeatPump[4][1] != dataHeatPumpOld[4][1]) {
          Serial.print("Defrost ongoing? "); Serial.println(dataHeatPump[4][1]);
          dataHeatPumpOld[4][1] = dataHeatPump[4][1];
          }
      break;
      case 4:
        // ?Data? 91-3,5
        if (dataHeatPump[5][3] != dataHeatPumpOld[5][3]) {
          Serial.print("Generic info "); Serial.println(dataHeatPump[5][3]);
          dataHeatPumpOld[5][3] = dataHeatPump[5][3];
          } 
      break;
      case 5:                                             // Temperatures
        // Supply temperature   91-2,3~4
        if (dataHeatPump[3][2] != dataHeatPumpOld[3][2]) {
          value = dataHeatPump[4][2];                             // MSB of temperature; previous byte is the MSB
          T_supply = (((value*256+dataHeatPump[3][2])-(65536*((value == 255) ? 1 : 0)))/10.0);  // Do the conversion to temperature in such a way that also negative temperature can be shown
          TemperaturePIDinput = T_supply;                       // Make the input the PID controller equal to the current supply water temperature   
          MessageString = String(T_supply,1);
          Serial.print("Supply temperature "); Serial.println(MessageString);
          dataHeatPumpOld[3][2] = dataHeatPump[3][2];
        }
        // Return temperature 91-2,5~6
        if (dataHeatPump[5][2] != dataHeatPumpOld[5][2]) {
          value = dataHeatPump[6][2];               // MSB of temperature; previous byte is the MSB
          T_return = (((value*256+dataHeatPump[5][2])-(65536*((value == 255) ? 1 : 0)))/10.0);  // Do the conversion to temperature in such a way that also negative temperature can be shown
          MessageString = String(T_return,1);
          Serial.print("Return temperature "); Serial.println(MessageString);
          dataHeatPumpOld[5][2] = dataHeatPump[5][2];
        }
        break;
      case 6:
        // Outside temperature 282 91-2,7~8
        if (dataHeatPump[7][2] != dataHeatPumpOld[7][2]) {  
          value = dataHeatPump[8][2];               // MSB of temperature; previous byte is the MSB
          T_outside = (((value*256+dataHeatPump[7][2])-(65536*((value == 255) ? 1 : 0)))/10.0);  // Do the conversion to temperature in such a way that also negative temperature can be shown
          MessageString = String(T_outside,1);
          Serial.print("Outside temperature "); Serial.println(MessageString);
          }
 
      break;
      case 7:                                             // Do PID calculation
        // Evaluate PID calculation    
        T_GapPIDParameterSwitch = abs(TemperaturePIDsetpoint - TemperaturePIDinput);    // Check the gap between the temperature setpoint adn the actual temperature
        if ((T_GapPIDParameterSwitch < PIDParameterThreshold) && (PIDParameterSet = 1)) { // If the gap is smaller than the threshold and the PID controller is currently using the fast set, then
          Kp = Kp0; Ki = Ki0; Kd = Kd0;                       // Choose slow (conservative) settings
          myPID.SetTunings(Kp, Ki, Kd);                       // Write a new set of control parameter
          PIDParameterSet = 0;                                // Set parameter to default default (low) settings
          } else {
            if (PIDParameterSet = 1) {                          // Gap larger than threshold but slow parameters are used, then 
              Kp = Sensitivity*Kp0;                           // Choose fast or aggressive settings by larger gap
              Ki = Sensitivity*Ki0; 
              Kd = Sensitivity*Kd0;
              myPID.SetTunings(Kp, Ki, Kd);                   // Write a new set of control parameter
              PIDParameterSet = 1;                            // Set parameter to default default (low) settings
              }
            }
          break;
      case 8:                                             // Print inter MCU communication 
      break;
      case 9:
        TemperaturePIDoutputRounded = round(TemperaturePIDoutput*10.0)/10.0;
    }
    lcdUpdateStep = (lcdUpdateStep + 1) % 10;  // Cycle through screen updates
  }
}////////////// End of main loop  //////////////////////////

////////  Below are the subroutines //////////////////////
void readSerialMessageMCU(uint8_t MCU) {
uint8_t TempMcuData[DataMcuLength] = {0};
uint8_t TemperatureCategory;  // Variable to categorize temperature
  ////// Inter MCU communication
    switch (MCU) {
      case 1:          // 1. Communication IC2 (OT) to IC1 (HP): This communication is via PAD 1 and therefore used at serial 1. Check if enough data has arrived in the serial buffer and read it
        // for (int i = 0; i < DataMcuLength; i++) {
        //   TempMcuData[i] = Serial1.read();                 // Read the bytes into the array
        // }
        Serial1.readBytes(TempMcuData, DataMcuLength);        // Clean way of reading fixed number of bytes into array. Beware: Blocks execution until all bytes arrive or timeout (default timeout is 1000ms).
        calculateMCUChecksum(TempMcuData, DataMcuLength, ChecksumMCU);// Calculate and check the checksum by determining the sum of the first 11 bytes and taken modules 256
        if (ChecksumMCU == TempMcuData[DataMcuLength-1]) { // Check if the checksum matches
          // for (int i = 0; i < DataMcuLength; i++) {
          //   dataArrayOT_IC2_IC1[i] = TempMcuData[i];          
          //   }
          memcpy(dataArrayOT_IC2_IC1, TempMcuData, DataMcuLength); // Checksum OK so copy temp array to permanent array, cleaner and faster code than a loop  
          ChecksumMCU = false;                                // Make checksum false as start value for next time  
          } else {                                            // Checksum incorrect because communication possibly halfway received. 
              clearSerialBuffer(Serial1);                     // Clears the read buffer of serial 1 if the checksu was wrong to make a fresh start
              Serial.println("Serial buffer 1 cleared");
            }
      break;
      case 2:         // 2. Communication IC1 (HP) to IC2 (OT): This communication is via PAD 2 and therefore used at serial 2. Check if enough data has arrived in the serial buffer, read it, modify when required and resend
        Serial2.readBytes(TempMcuData, DataMcuLength);      // Clean way of reading fixed number of bytes into array. Beware: Blocks execution until all bytes arrive or timeout (default timeout is 1000ms).
        calculateMCUChecksum(TempMcuData, DataMcuLength, ChecksumMCU);// Calculate and check the checksum by determining the sum of the first 11 bytes and taken modules 256
        if (ChecksumMCU == TempMcuData[DataMcuLength-1]) { // Check if the checksum matches
          memcpy(dataArrayOT_IC1_IC2, TempMcuData, DataMcuLength); // Cleaner and faster code than a loop
          ChecksumMCU = false;                            // Make checksum false as start value for next time
          if (T_outside < MinTemp4HP) {
            TemperatureCategory = 0;                             // Too cold for heat pump, switch on cental heating
            } else if (T_outside < 4) {
              TemperatureCategory = 1;  // Below 4°C             // Prevent that controlbox starts CV 
              } else if (SpeedSetpoint == 0) {
                TemperatureCategory = 2;                         // SpeedSetpoint is zero
                } else {
                  TemperatureCategory = 3;                       // In all other cases use the temperature setpoint for water as read from Plugwise Anna via MCU2
                  }                 
          switch (TemperatureCategory) {
            case 0:                                     // Heat pump is not running because it is too cold so central heating should be started
              dataArrayOT_IC1_IC2[0] = 0xf0;
              break;
            case 1:                                     // Below 4°C but heat pump can run, adjust values to prevent central heating activation
              dataArrayOT_IC1_IC2[0] = dataArrayOT_IC2_IC1[0];
              dataArrayOT_IC1_IC2[9] = 0x04;
              dataArrayOT_IC1_IC2[4] = 0;               // Write 0's to force MCU2 to transfer HP temperature to OpenTherm 
              dataArrayOT_IC1_IC2[5] = 0;
              dataArrayOT_IC1_IC2[6] = 0;
              dataArrayOT_IC1_IC2[10] = 0;
              break;
              case 2:                                     // Heat pump is not running (Speedsetpoint  is zero), then let central heating boiler temperatures go to OpenTherm
              break;
              case 3:                                     // In all other cases use the temperature setpoint for water as read from Plugwise Anna via MCU2
                dataArrayOT_IC1_IC2[0] = dataArrayOT_IC2_IC1[0];
                dataArrayOT_IC1_IC2[4] = 0;             // Write 0's to force MCU2 to transfer HP temperature to OpenTherm 
                dataArrayOT_IC1_IC2[5] = 0;
                dataArrayOT_IC1_IC2[6] = 0;
                dataArrayOT_IC1_IC2[10] = 0; 
              break;
            }
            dataArrayOT_IC1_IC2[7] = round(T_supply);     // Write the actual outside temperature in the array. Will not work for temperatures below zero because array is 8 bits unsigned!
            dataArrayOT_IC1_IC2[8] = round(T_return);     //
            dataArrayOT_IC1_IC2[9] = round(T_outside);    // Write the actual outside temperature in the array. Will not wok for temperatures below zero because array is 8 bits unsigned!
            // Serial.print("T_supply: ");Serial.print(T_supply)     
            // Serial.print("T_return: ");Serial.print(T_return)
            // Serial.print("T_outside: ");Serial.print(T_outside)       
            calculateMCUChecksum(dataArrayOT_IC1_IC2, DataMcuLength, ChecksumMCU);// Recalculate the checksum
            dataArrayOT_IC1_IC2[11] = round(ChecksumMCU); // Replace old checksum value with new calculated one
            } else {                                      // Checksum incorrect because communication possibly halfway received. 
              clearSerialBuffer(Serial2);                 // Clears the read buffer of serial 2 if the checksu was wrong to make a fresh start
              Serial.println("Serial buffer 2 cleared");
              }
      break; 
    }
  }

void clearSerialBuffer(HardwareSerial &serialPort) {  
  while (serialPort.available() > 0) {
    serialPort.read();                                  // Read and discard the data in the buffer
  }
}

void calculateMCUChecksum(uint8_t dataArray[], int Length, unsigned int &checksum) {  // Calculate the checksum by determining the sum of the first 11 bytes and then take modules 256
  checksum = 0; // Initialize the checksum
      if (Length <= 1) {    // Ensure length is valid
        checksum = 0;
        return;
    }
    // Calculate the checksum for the first (Length-1) bytes in the specified row
    for (int i = 0; i < Length - 1; i++) {
        checksum += dataArray[i];
    }
    checksum %= 256;                                        // Modulus 256 to keep it in a single byte
}

// Function to calculate the CRC-CCITT (0xFFFF) checksum for the communication to and from the heat pump
void calculate_CRC_CCITT_Checksum(uint8_t *data, uint8_t Length, uint16_t *checksum) {
    uint16_t crc = 0xFFFF; // Initial value
    for (uint8_t i = 0; i < Length; i++) {
        crc ^= (uint16_t)data[i] << 8;
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 0x8000) {
                crc = (crc << 1) ^ 0x1021;
            } else {
                crc <<= 1;
            }
        }
    }
    *checksum = crc;
}

// Function that reads the serial data coming from the heat pump
void readSerialMessageHP() {
    while (Serial3.available()) {  // Check if data is available on Serial3
      IsReceiving = true;
      uint8_t byteReceived = Serial3.read();
       // Serial.print(String(byteReceived,DEC)+" ");
      IsReceiving = true;
        switch (state) {
            case Wait_Start:                            // Code to wait for the start character
                if (byteReceived == StartByte) {
                    state = Read_Header;
                    index = 0;
                    IncomingMessageEnded = false; // Reset if any other byte is received to indicate
                }
                break;
            case Read_Header:                           // Code to process header bytes
                if (index == 0) {
                    ID = byteReceived;
                    if (ID > 3) {  // ID must be 0-3
                        Serial.println("Invalid ID, resetting...");
                        state = Wait_Start;
                        return;
                    }
                } else if (index == 1) {
                    msgLength = byteReceived+1;
                    if (!IsValidLength(msgLength)) {
                        Serial.println("Invalid Length! Resetting...");
                        state = Wait_Start;  // Reset
                        return;
                    }
                    DataLength = msgLength - 3;  // Exclude first 3 bytes and last byte
                    index = 0;
                    state = Read_Payload;
                }
                index++;
                break;

            case Read_Payload:                          // Code to process data payload
                buffer[index++] = byteReceived;
                if (index >= DataLength) {
                    state = Read_End;
                }
                break;

            case Read_End:                              // Code to check that last byte of message corresponds to '0'
                if (byteReceived == 0) {  // Ensure last byte is 0
                    StoreMessage(ID, DataLength, buffer);
                    IncomingMessageEnded = true;                          // If the end of the incoming message is reached, set the infication boolean
                    previousMessageInEnded = millis();                    // Set timestamp after receiving end of incoming message             
                } else {
                    Serial.println("Warning: Last byte is not 0! Resetting...");
                }
                IsReceiving = false;
                state = Wait_Start;                                     // Reset for next message
                break;
                default:
                Serial.println("Error in readSerialMessageHP state"); 
                break;
        }
    }
}

// Function to check if the Length is valid
bool IsValidLength(uint8_t Length) {
    for (uint8_t i = 0; i < sizeof(ValidLengths) / sizeof(ValidLengths[0]); i++) {
        if (Length == ValidLengths[i]) return true;
    }
    return false;
}

// Function to store messages in separate arrays based on ID
void StoreMessage(uint8_t ID, uint8_t DataLength, uint8_t *message) {
    for (uint8_t i = 0; i < (DataLength); i++) {
      dataHeatPumpTemp[i+2][ID] = message[i];
      }
    dataHeatPumpTemp[0][ID] = StartByte;
    dataHeatPumpTemp[1][ID] = ID;
    dataHeatPumpTemp[2][ID] = DataLength+2; // 12, 13, 18, 20
     for (int j = 0; j < DataLength+2; j++) {                                  // Copy row 
       extractedRow[j] = dataHeatPumpTemp[j][ID];  
       } 
    calculate_CRC_CCITT_Checksum(extractedRow, DataLength+2, &ChecksumCBHP);   // Calculate checksum, including the two checksum bytes --> result will be zero if mesage has been sent error free
    if (ChecksumCBHP == 0) {                                                   // Check that result is indeed zero
      memcpy(dataHeatPump[ID], dataHeatPumpTemp[ID], Cols * sizeof(uint8_t));  // Transfer the temporarily array to the permanent array
      ChecksumCBHPfalseCount = 0; 
      Serial.println("Checksum heat pump data received not OK");               // Print a message if there is an error     
      } else {
        ChecksumCBHPfalseCount++;                                              // Increase counter for false checksums. Nog actie bedebken als threshold wordt bereikt
        Serial.print("Checksum error! ");                                      // Print a message if there is an error
        Serial.print("Now ");Serial.print(ChecksumCBHPfalseCount);Serial.print(" Checksum errors (of max 10) counted!");
        }
}
Verder heb ik een eenvoudige quick & dirty control box simulator van slechts 30 [edit: 55 regels. Ik heb simulate van MCU communicatie ook toegevoegd (met iets meer onderling verschil dan in het echt, nl. 480 vs. 200 ms] om het programma offline op de hardware te kunnen testen:
code:
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
/* Test program for serial communication related to Atlantic Aurea 
Hardware connections:
  Serial connections:
    Serial port 0: Monitoring and troubleshooting to USB port
    Serial port 1 (Orange): Connect Pin 19 (Rx1) to Pad 1: Receiving messages from OT MCU to HP MCU (9600 bps). This to extract thermostat setpoint     
    Serial port 2 (Brown/white): Connect Pin 16 & 17 (Tx2 (brown)& Rx2(white)) to Pad 2. Receive messages from HP MCU and send modified message to OT MCU (9600 bps)
    Serial port 3 (Connect: Pin 14 & optionally 15 (Tx3 & Rx3) (Green): Send messages with requested power to heatpump and optionally receive messages from HP for monitoring purposes and  (666 bps)
*/

//Define variables and constants
// Make pulse 
const uint32_t MessageSerialMCUInterval = 4200;                   // Interval for mesages send in between MCU (add delay for sending othr data)
uint32_t currentMillis = 0;                                       // Check timing for sending messages
uint32_t PreviousMessageSerial1Sent = 0;                        
bool SendSerial2 = false;

// Variables to receive inter MCU data
byte dataArrayOT_IC2_IC1[] = {44,20,154,0,0,33,14,32,29,8,0,78};  // Array for testing communication picked up at Pad 1 on PCB
byte dataArrayOT_IC1_IC2[] = {37,20,154,0,0,33,14,32,29,2,0,65};  // Array for testing communication picked up at Pad 2 on PCB

// Example of data send from heatpump to control box
byte dataHeatPump0[] = {25,0,8,0,0,0,217,181,         145,0,12,13,7,4,47,90,206,225,230,223,0};                       // Length 12
byte dataHeatPump1[] = {25,1,12,0,0,0,0,0,0,0,170,53, 145,1,13,80,0,0,0,0,0,138,82,164,39,0};                         // Length 13
byte dataHeatPump2[] = {25,2,8,1,5,0,85,243,          145,2,18,18,1,253,0,49,0,1,0,2,0,0,38,216,23,240,0};            // Length 18 
byte dataHeatPump3[] = {25,3,8,178,2,0,193,154,       145,3,20,120,81,168,151,21,0,83,53,2,0,24,0,0,0,0,233,241,0};   // Length 20

void setup() {
  // Serial Setup
  Serial1.begin(9600);                          // Start serial port 1 for receiving messages from OT MCU to HP MCU (9600 bps)
  Serial2.begin(9600);                          // Start serial port 2 to receive messages from HP MCU and send modified message to OT MCU (9600 bps)
  Serial3.begin(666);                           // Start serial port 3 for sending an receiving info to heat pump at 666 baud (pin 16)
  Serial.println("Setup complete.");
}

void loop() {
currentMillis = millis();                                 // get curent millis (ms) for sending message in between MCU's
if (currentMillis-PreviousMessageSerial1Sent > MessageSerialMCUInterval)  {
  Serial1.write(dataArrayOT_IC1_IC2, sizeof(dataArrayOT_IC1_IC2));    // Write array to serial port 1
  PreviousMessageSerial1Sent = currentMillis;
    SendSerial2 = true;
  }

Serial3.write(dataHeatPump0,sizeof(dataHeatPump0));
  delay(412);
if (SendSerial2)  {
  Serial2.write(dataArrayOT_IC1_IC2, sizeof(dataArrayOT_IC1_IC2));    // Write array to serial port 2
  SendSerial2 = false;
  }
Serial3.write(dataHeatPump1, sizeof(dataHeatPump1));
  delay(487);
Serial3.write(dataHeatPump2,sizeof(dataHeatPump2));
  delay(502);
Serial3.write(dataHeatPump3,sizeof(dataHeatPump3));
  delay(531);
}
Aan de hardware kant zij verder ook nog verbeteringen denkbaar. De belangrijkste die medetweakers ook noemden zijn:
  • Een of twee relais gebruiken die in onbekrachtigde toestand de oorspronkelijke situatie herstellen
  • De communicatie op de print aftappen door met tussenvoetjes bij de IC’s te werken. Zo zijn wijzigingen op de print niet nodig (in het geval van optie 1 en 2 hoeft dat zelfs niet want dan kunnen de microcontrollers worden verwijderd!)
  • Toevoegen van een flowmeter om de COP te kunnen berekenen.
Hier een foto van het display in actie:
Afbeeldingslocatie: https://tweakers.net/i/QVjuhsPtOvuC092J7equWxoUkYo=/fit-in/4000x4000/filters:no_upscale():strip_exif()/f/image/tvweTsHtszUAzBnsC4jTvDuO.png?f=user_large

Dan nog de potlood schets van het relevante deel van de print (ik was van plan dit netjes met een tool uit te tekenen, maar had geen zin in de leercurve voor deze ene keer). Het stukje rechts op de print waar twee relais zitten, ontbreekt grotendeels want dat stuk had ik niet nodig:
Afbeeldingslocatie: https://tweakers.net/i/dU6KFKlv9QK5qPFLWjJcedqjv7w=/800x/filters:strip_exif()/f/image/MWWyT4eD3krjkFZABO6jWFGs.png?f=fotoalbum_large

En tenslotte waar het om gaat: Een paar mooie trends (ik log alles wel in Home Assistant; thermostaat stond op 20.5oC, en om 23:40 naar 19.5oC):

Doeltemperatuur woonkamer:
Afbeeldingslocatie: https://tweakers.net/i/dXq3sVgUk88o8ymAP1ftfgNosNk=/800x/filters:strip_exif()/f/image/o33kg9Nbk2hzM9e3ygilorbt.png?f=fotoalbum_large

Doeltemperatuur aanvoer:
Afbeeldingslocatie: https://tweakers.net/i/fpGVuSzudTbODd3czC12k8V-bE0=/800x/filters:strip_exif()/f/image/e4fXSxCSp9M4QovmMbljWpZy.png?f=fotoalbum_large

Opgenomen vermogen:
Afbeeldingslocatie: https://tweakers.net/i/GBAQCzZJLZpGzMrs1JB4RerxR8c=/800x/filters:strip_exif()/f/image/ern13HxnZb9lQfXIyhbekOPI.png?f=fotoalbum_large

Temperatuur aanvoer (als de WP uit is, wordt afwisseld ook de CV (sanitair water) aanvoer getoond):
Afbeeldingslocatie: https://tweakers.net/i/8tcLfl8o8b13JuRwGO2Dl4Yzjqw=/800x/filters:strip_exif()/f/image/XTcfu14f6bBibsNbBkxfxJRF.png?f=fotoalbum_large

Temperatuur return (idem):
Afbeeldingslocatie: https://tweakers.net/i/uA5elUtVPR_qY4sLjBCz8c2YuJI=/800x/filters:strip_exif()/f/image/lZD2qqK3exCX3Qjnrw5LlvSI.png?f=fotoalbum_large

Het is hoogste tijd voor andere projecten :P

[ Voor 102% gewijzigd door WackoH op 21-03-2025 23:19 ]


Acties:
  • 0 Henk 'm!

  • Grannetia
  • Registratie: Februari 2025
  • Laatst online: 02-06 14:43
Ha Jacco,
ik zat nog eens aandachtig naar je programma te kijken. Grote klasse weer hoor! Ik vroeg mij alleen nog af: is het juist opgemerkt dat niet alleen de communicatie bij R14 van de controlbox moet worden onderbroken, maar ook de communicatie van de aurea mcu naar de ot mcu bij pad 1? Zo ja, mag ik dan vragen hoe/waar je dat gedaan hebt? en heb je verder nog weerstanden moeten toevoegen om de communicatie aan alle kanten te laten slagen?
Bedankt weer! en veel plezier met de volgende uitdaging :D

edit: Misschien moet pad 2 ook wel ontkoppelt, anders zal de ot mcu mogelijk tegenstrijdige berichten ontvangen. Is het niet?

[ Voor 11% gewijzigd door Grannetia op 23-03-2025 16:14 . Reden: aangepaste veronderstelling ]


Acties:
  • +1 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Klopt. Schematisch heb ik het hier weergegeven: WackoH in "Aurea 5 hybrid: interfaces met de buitenunit en thermostaat"

- R14 van1 kOhm tussen IC4 (microcontroller voor de warmtepomp) en T2 heb ik aan de bovenkant losgemaakt.
- Op het vrijgekomen gaatje heb ik TX3 van de ATmega2560 via een nieuwe 1kOhm weerstand (op T2 dus) aangesloten
- Via het losse pootje van R14 kan ik eventueel uitlezen wat IC4 naar de warmtepomp zou willen sturen. De weerstand beschermt IC dan tegen bv. per ongeluk kortsluiting maken

Het is inderdaad essentieel om de verbinding tussen IC4 en IC2 die langs Pad 2 loopt, te onderbreken als je hier een nieuw signaal op in wilt voeden, want anders bestaat het risico dat de uitgang van IC4 kapot gaat. Dat zou niet best zijn.
Ik heb dat gedaan door het printspoor tussen IC4 en Pad 2 door te snijden (alternatief is via met ene tussenvoetje werken, of het betreffende pootje uit het voetje te houden en er een draadje aan te solderen). Vervolgens heb ik op het printspoor tussen IC4 en de onderbreking een draadje gesoldeerd. Zo ook in pad2.
Enerzijds kan ik zo de oorspronkelijke situatie herstellen door beide draadjes te verbinden. Maar ik heb nu de uitgang van IC4 via een 1kOhm weerstand met de RX2, en Pad 2 met TX2 van de ATmega2560, verbonden.

Hieronder nog twee foto's die het hopelijk wat duidelijker te maken. Ja, heeft hoog prototype gehalte ;) Het handige van het breadboardje is dat ik gemakkelijk een logic analyzer en serial naar USB omzetter aan kan sluiten.

Afbeeldingslocatie: https://tweakers.net/i/I_B_zfzmjbPuGQBL9RqnMwRmVoE=/800x/filters:strip_exif()/f/image/qYRkPxgyHymeLfNggw7cWBkq.png?f=fotoalbum_largeAfbeeldingslocatie: https://tweakers.net/i/o5UnfJiDEsRCFz3W54rSJgbbLmI=/800x/filters:strip_exif()/f/image/7xstdfhBjIqKUuG6ZsashCFF.png?f=fotoalbum_large


PS: In eerdere berichten en code heb ik het over IC1 (WP / HP). Dat is op printplaat echter IC4.

[ Voor 4% gewijzigd door WackoH op 25-03-2025 00:10 ]


Acties:
  • 0 Henk 'm!

  • P1 modubus
  • Registratie: Maart 2023
  • Laatst online: 11:42
Goedendag De Flowmeter is geïnstalleerd. eenmaal even kunnen meten was toen 10.9 ltr/min

Afbeeldingslocatie: https://tweakers.net/i/PoPL6ss04Hy9UF7XD2S_uWcJDzk=/fit-in/4920x3264/filters:max_bytes(3145728):no_upscale():strip_icc():strip_exif()/f/image/VvZdwj3qKEjUBnPAJT9IPne7.jpg?f=user_large


Plaatje is ook klaar nu moet de WP nog draaien, helaas na het installeren van de flowmeter gaf de Anna weer niet thuis kreeg geen verbinding met de Smile, weer alles opnieuw geïnstalleerd na aantal malen geprobeerd te hebben weer contact, nu gaf deze weer geen stookwens naar de WP, kamer temp. 23 grd gevraagd, weer verlaagd na tijdje weer verhoogd en zo gelaten, cv ketel maar even handmatig aangezet Vanmorgen was het warm, gezien dat de WP om 23.05 uur inkwam en niet meer uitgegaan was, 22 grd kamer. Namiddag weer aangezet de Anna vragend gezet 23 grd. maar komt niet in wel 22 grd. in de kamer, testfase natuurlijk, wil het middags hoger stoken i.v.m. zonne-energie, avonds uit omdat de vloer opgewarmd is, kan normaal WP uit tot volgende dag, middags dan weer het zelfde verhaal,
het moet toch kunnen zonder veel aanpassingen dit geregeld te krijgen, ben wel meet en regel man maar kan niet zoals hierboven de print met software aanpassen.

Vind optie 3 ook het beste alles zoveel mogelijk origineel laten, de echtgenote moet ook simpel verder kunnen mocht ik plotseling wegvallen, alles zo gemaakt dat het dan naar de originele status gaat,

De buitentemperatuur beïnvloeding van 4 grd, is schakelend gemaakt zodat de WP de circulatiepomp niet onnodig laat draaien, en bij lage buitentemperatuur toch inkomt, maar niet bevriezen kan, bij hogere buitentemperatuur dit weer normaal zet, dan is dat toch overbodig en werkt alles normaal

De vraag aan de cv Ketel doorgezet naar de testknop dit kan ook gemonitord worden met telwerk en tijd als dit nodig zou zijn, kan ook nog gestart worden zonder cv ketel vraag, maar moet wel vanuit de Smile warmte gevraagd worden, helaas is dit nu niet het geval.

Net weer een mail naar Plugwise gestuurd, hop een een positief bericht, de Anna/ Smile is een mooi systeem als het werkt, alleen is dit niet vaak het geval, in het begin deed als het prima, maar nu een en al problemen, jammer toch begrijp niet dat het niet eenvoudig geregeld kan worden, en jullie er zoveel aan moeten passen zodat de WP naar wens draait.

Heeft iemand de originele uitgebreide printplaat getest of geïnstalleerd met modbus aansluiting.?
Weet niet wat er dan nodig aan aanpassingen nodig zijn en of dit nu nog kan.
Heb reeds de hamer klaar liggen.

Acties:
  • 0 Henk 'm!

  • WackoH
  • Registratie: November 2012
  • Laatst online: 13:45
Haha, herkenbaar :*)

Zelf heb ik de aanschaf van een flowmeter toch even geparkeerd. Ik ben namelijk vooral in de relative COP geïnteresseerd. Dus of de COP beter is bij lagere vermogens dan bij hogere. Als ik er van uit ga dat het debiet nauwelijks verandert, kan ik een aanname over het debiet doen en constant houden. Dan hoef ik alleen met de gemeten temperaturen en vermogen te werken.

Ik heb die berekening aan de software toegevoegd en met 9 kg/min krijg ik ene relatische waarde (niet perse de juiste) dat komt redelijk goed overeen met de kleine 11 die jij hebt gemeten) heb ik realistische COP waardes van bv. 4.0.

Wat me bij Plugwise opvalt, is dat de Opentherm communicatie tussen controlbox en ketel na inschakelen vaak niet goed op gang komt. Wat ik doen is de Homewizard Heatlink die in de lijn zit, even aanzetten. Die strijkt dan op de een van andere manier de rimpels glad en de communicatie is daarna goed. Misschien helpt een keertje reset in de controlbox drukken ook wel.
Pagina: 1