News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Soldering oven with Positron and Nextion

Started by Frizie, Aug 01, 2024, 06:43 PM

Previous topic - Next topic

Frizie

I know Les is not a big fan of the Nextion HMI touch panels  :'( , but I have successfully made several projects with it.
The YouTube video here shows how I use the Nextion HMI to operate a SMD soldering oven.
I made the project a few years ago, but I have only just made a video of it (my first video ever  :P )
It is programmed in an (old) PIC18F242 with, of course, Positron PIC Basic  ;D

The soldering oven is a second-hand combi microwave/hot air oven from Whirlpool.
I removed the original control, as well as the microwave part.
The end result of the easy SMD soldering is always 100%, as can be seen at the end of the YouTube video  8)

The project did not have a touchscreen for the first year, but a PLED 16x2 display and the operation was done with Bluetooth via my smartphone.
This turned out to be inconvenient, I had to keep turning on my smartphone to solder SMD prints and every now and then the connection dropped out  ::)

About 3 years ago I got to know the Nextion HMIs through projects at work and then I converted the soldering oven: Bluetooth out, Nextion in.
No regrets so far  :D

Here is the link to the Youtube video: https://www.youtube.com
Special attention to the Nextion control.
Ohm sweet Ohm | www.picbasic.nl

keytapper

Can you make some french fries  ;D ?
Ignorance comes with a cost

top204

#2
That is an excellent video Frizie, and well done my friend.

It is always very rewarding when I see the compilers used for a very good purpose by a competent user. It shows to me that my time on them is not wasted when others get enjoyment from them. :-)

A look at you board and circuit would be good. Did you create a PID for the temperature gradients?

I tried the Nextion displays about 10 years ago (wow! where has the time gone?), and I found them rather slow and unresponsive, and the maximum Baud rate for them was 9600, so they were actually very unresponsive. I also found them rather expensive. However, that situation may have changed now, because I have not looked at them in a long, long time.

A follow on from keytapper... Can I have a piece of pizza with those fries please? Extra mushrooms and no chilly. :-)

Best regards
Les

charliecoutas

Very impressive Frizie.
Charlie

Dompie

Dutch: WAUW Frits wat een gaaf project. Geweldig.

Johan

Frizie

#5
Below is the program for the soldering oven.
The program is already about 3 years old and was one of the first programs I wrote for a Nextion HMI.
I would not do it this way anymore, I do it in a much nicer way these days  ;D

Unfortunately I do not have a schematic  :(
I drew the PCB off the cuff for a Bluetooth module at the time and it is therefore not optimally drawn for Nextion.

The soldering oven is actually only a small HMI project compared to what I make for work.
At work I make a lot of machine controls for the industry with PIC, Positron and often a Nextion HMI.
Unfortunately my boss does not allow me to show work projects because of our competitors  ::)

I will hopefully take a picture of the PCB today and post it here, for this I have to open the soldering oven first.
Unfortunately for most of you, the program is in Dutch  :-[

(* Compiler V4.0.2.1
MCLR via C en R netwerk
           PIC18F242:                  +--v--+
                             MCLR/Vpp >[     ]<>B.7/PGD
                              AN0/A.0<>[     ]<>B.6/PGC
                              AN1/A.1<>[     ]<>B.5/PGM
                              AN2/A.2<>[     ]<>B.4
                              AN3/A.3<>[     ]<>B.3/CCP2*
                                  A.4<>[     ]<>B.2/INT2
                              AN5/A.5<>[     ]<>B.1/INT1
                                  GND >[     ]<>B.0/INT0
                                  OSC >[     ]< +5V
                              A.6/OSC <[     ]< GND
                                  C.0<>[     ]< C.7/RX UART: Nextion HMI (Human Machine Interface)
                            *CCP2/C.1<>[     ]> C.6/TX UART: Nextion HMI (Human Machine Interface)
                             CCP1/C.2<>[     ]<>C.5
                                  C.3<>[     ]<>C.4
                                       +-----+
www.picbasic.nl / Frits Kieftenbelt, Raalte, Netherlands (Frizie*)


DEVICE = 18F242
CONFIG_START
  OSC     = HS                ;HS oscillator
  OSCS    = OFF               ;Oscillator system clock switch option is disabled (main oscillator is source)
  PWRT    = ON                ;PWRT enabled
  BOR     = OFF               ;Brown-out Reset disabled
  BORV    = 20                ;VBOR set to 2.0V
  WDT     = OFF               ;WDT disabled (control is placed on the SWDTEN bit)
  WDTPS   = 128               ;1:128
  CCP2MUX = OFF               ;CCP2 input/output is multiplexed with RB3
  STVR    = ON                ;Stack Full/Underflow will cause RESET
  LVP     = OFF               ;Low Voltage ICSP disabled
  DEBUG   = OFF               ;Background Debugger disabled. RB6 and RB7 configured as general purpose I/O pins.
  CP0     = OFF               ;Block 0 (000200-001FFFh) not code protected
  CP1     = OFF               ;Block 1 (002000-003FFFh) not code protected
  CPB     = OFF               ;Boot Block (000000-0001FFh) not code protected
  CPD     = OFF               ;Data EEPROM not code protected
  WRT0    = OFF               ;Block 0 (000200-001FFFh) not write protected
  WRT1    = OFF               ;Block 1 (002000-003FFFh) not write protected
  WRTC    = OFF               ;Configuration registers (300000-3000FFh) not write protected
  WRTB    = OFF               ;Boot Block (000000-0001FFh) not write protected
  WRTD    = OFF               ;Data EEPROM not write protected
  EBTR0   = OFF               ;Block 0 (000200-001FFFh) not protected from Table Reads executed in other blocks
  EBTR1   = OFF               ;Block 1 (002000-003FFFh) not protected from Table Reads executed in other blocks
  EBTRB   = OFF               ;Boot Block (000000-0001FFh) not protected from Table Reads executed in other blocks
CONFIG_END

'DECLARE OPTIMISER_LEVEL = 0                             

DECLARE ALL_DIGITAL   = TRUE  ;Alle ingangen digitaal
'ECLARE XTAL          = 22    ;Kristal 22.1184 MHz  (40 = 44MHz: Kristal 11.0592 x 4xPLL)
DECLARE XTAL          = 20
DECLARE HSERIAL_BAUD  = 4800  ;4800 vanwege 20MHz kristal ipv. 22.1184MHz '9600 '115200
DECLARE HSERIAL_RCSTA = %10010000 ' Enable continuous receive
DECLARE HSERIAL_TXSTA = %00100000 ' Enable transmit and asynchronous mode  '%00100100 ' Enable transmit and asynchronous mode, highspeed (BRGH) (Zie DECLARE HSERIAL_TXSTA Proton Help)


'ON_INTERRUPT GOTO InterruptAfhandeling staat verderop, net onder CLEAR


;Algemene constanten
SYMBOL AntiDender     = 200   ;mSec: Wachttijd tegen contactdender van de deurschakelaar
SYMBOL BuzzerTijd     = 400   ;mSec: Tijd dat buzzer klinkt tijdens opstart van programma
SYMBOL Graad          = 223   ;223 is de ASCII code voor het 'graad' karakter



;Fabrieksinstellingen
SYMBOL FabrLampTijd   = 40    ;BYTE: De time-out tijd in seconden voor de lamp in het compartiment | Als de deur open blijft staan (of bij wachten op print inleggen / print gereed met deur dicht), dan zal de lamp na deze time-out tijd uitgaan
SYMBOL FabrLosseBits  = %0000000010110111    ;Fabrieksinstelling voor de losse bits (aliases)
SYMBOL FabrThermostaat= 70    ;WORD: Thermostaat-instelling in graad Celsius
SYMBOL FabrTaal       = 2     ;BYTE: Taal (0=Engels, 2=Nederlands) - (1=Duits, maar niet aanwezig in soldeer-oven)
SYMBOL FabrTempFinish = 90    ;BYTE: Temperatuur die aangeeft dat de PCB gereed wordt gemeldt (PCB is afgekoeld)
SYMBOL FabrTempPlace  = 40    ;BYTE: Temperatuur die aangeeft wanneer de PCB in de oven geplaatst kan worden als voor oven voorwarmen is gekozen
SYMBOL FabrOvershBack = 4     ;BYTE: Overshoottemperatuur in graden Celsius voor de achterste verwarming
SYMBOL FabrOvershTop  = 2     ;BYTE: Overshoottemperatuur in graden Celsius voor de bovenste verwarming



;Proces states
SYMBOL OvenStandBy    = 0
SYMBOL Opwarmen       = 1
SYMBOL PrintInleggen  = 2
SYMBOL Solderen       = 3
SYMBOL Afkoelen       = 4
SYMBOL PrintKlaar     = 5



SYMBOL MaxThermo    = 275     ;Maximaal in te stellen temperatuur in graden Celsius
'YMBOL MinThermo    = 40      ;Minimaal in te stellen temperatuur in graden Celsius
SYMBOL PIC_versie   = 100     ;Versienummer dat in het HMI scherm "pgGeneral" wordt weergegeven.  Als volgt opgeven: 100 is op de HMI "V1.0",  101 is op de HMI "V1.1",  400 is op de HMI "V4.0",  401 is op de HMI "V4.1",  410 is op de HMI "V4.10",  1234 is op de HMI "V12.34"



;Logische constanten (Alfabetische volgorde)
SYMBOL DICHT        = 0
SYMBOL FALSE        = 0       ;Niet waar
SYMBOL HOOG         = 1       ;Hoog signaal
SYMBOL INVISIBLE    = 0       ;Component niet zichtbaar op Nextion HMI
SYMBOL LAAG         = 0       ;Laag signaal
SYMBOL NietOK       = 0       ;Iets is niet OK
SYMBOL OK           = 1       ;Iets is OK
SYMBOL OPEN         = 1
SYMBOL PRESSED      = 1       ;HMI toets ingedrukt
SYMBOL RELEASED     = 0       ;HMI toets losgelaten
SYMBOL TRUE         = 1       ;Waar
SYMBOL VISIBLE      = 1       ;Component zichtbaar op Nextion HMI



'WWWWWWWWWWWWWWWWWWWWWWW AANPASSEN
;Berichten en foutmeldnummers voor het display in de HMI
;Numerieke volgorde --> Hoe hoger het foutnummer, hoe hoger de prioriteit van het bericht, een bericht met bijv. foutnummer 108 zal dus wel verschijnen als foutnummer 107 er al staat, andersom blijft 108 staan en zal 107 niet verschijnen als deze fout later ontstaat
;Dit wordt bereikt door elk bericht zo op te stellen: IF DisplayTekst < ERR_TempSens THEN DisplayTekst = ERR_TempSens
;Zorg ervoor dat onderstaande foutnummers overeenkomen met de foutnummers in de HMI (te vinden in 'sub0' in 'pgHome')
SYMBOL LCD_Normaal    = 0     ;Bericht: Normale weergave    (Berichten-display op HMI onzichtbaar)
SYMBOL LCD_StandBy    = 10    ;Bericht: Oven stand-by
SYMBOL LCD_PlaatsPCB  = 11    ;Bericht: Print in oven plaatsen
SYMBOL LCD_Opwarmen   = 12    ;Bericht: Oven opwarmen     
SYMBOL LCD_Solderen   = 13    ;Bericht: Print solderen
SYMBOL LCD_Afkoelen   = 14    ;Bericht: Print afkoelen
SYMBOL LCD_PCB_Gereed = 15    ;Bericht: Print gereed
SYMBOL ERR_DeurIsOpen = 16    ;Bericht: Deur is open!       (De deur is geopend)
SYMBOL ERR_ErrorMessg = 100   ;Program: Gereserveerd
SYMBOL ERR_DeurSluiten= 101   ;Error: Deur sluiten!         (Deur wordt geopend terwijl temperatuur al behoorlijk hoog is)
SYMBOL ERR_DeurOpenen = 102   ;Error: Deur openen om af te koelen (meer een waarschuwing dan een error)
SYMBOL ERR_OverTemp   = 103   ;Error: Temperatuur te hoog!  (Temperatuur in compartiment is veel hoger dan ingesteld)



;EEPROM adresnamen (Alfabetische volgorde)
;Let op: Adressen bij EDATA aaneengesloten houden (dus geen nummers overslaan, maar beginnen vanaf 0 en aaneengesloten doornummeren. Een WORD neemt 2 adressen in, een BYTE neemt 1 adres in.)
;Een WORD wordt opgeslagen in 2 BYTE geheugenplaatsen van de interne EEPROM van de PIC, vandaar dat steeds 1 adres moet worden overgeslagen
;WORDS
SYMBOL EE_LampTijd    = 0 '+1 ;WORD: Bevat de time-out tijd in seconden voor de lamp in het compartiment
SYMBOL EE_LosseBits   = 2 '+3 ;WORD: EEPROM adres bevat losse BIT instellingen voor bit aliases, op dit EEPROM adres kunnen zo 16 losse bits worden opgeslagen voor diverse instellingen
SYMBOL EE_TempFinish  = 4 '+5 ;WORD: Bevat de temperatuur instelling van PCB gereed
SYMBOL EE_TempPlace   = 6 '+7 ;WORD: Bevat de temperatuur instelling van PCB plaatsen
SYMBOL EE_Thermostaat = 8 '+9 ;WORD: EEPROM adres bevat de thermostaat instelling
SYMBOL EE_OvershBack  = 10'+11;WORD: Bevat de overshoot temperatuur van heating back
SYMBOL EE_OvershTop   = 12'+13;WORD: Bevat de overshoot temperatuur van heating top
SYMBOL EE_NEW3        = 14'+15;WORD: EEPROM adres bevat
SYMBOL EE_NEW2        = 16'+17;WORD: EEPROM adres bevat
SYMBOL EE_NEW1        = 18'+19;WORD: EEPROM adres bevat

;BYTES
SYMBOL EE_Taal        = 2    ;Bevat de taal-instelling (0=Engels, 2=Nederlands)
'LET OP BIJ HERNUMMERING: EDATA AANPASSEN!

;EDATA WORDS
EDATA WORD FabrLampTijd       
EDATA WORD %0000000110110111  ;Data van losse bits
EDATA WORD FabrTempFinish     
EDATA WORD FabrTempPlace     
EDATA WORD FabrThermostaat   
EDATA WORD FabrOvershBack     
EDATA WORD FabrOvershTop     
EDATA WORD $FFFF              ;14+15
EDATA WORD $FFFF              ;16+17
EDATA WORD $FFFF              ;18+19
;EDATA BYTES
EDATA FabrTaal               



;Namen van HMI vensters Nextion touchscreen (zelfde volgorde aanhouden als in de HMI)
SYMBOL pgOpstart     = 0
SYMBOL pgHome        = 1
SYMBOL pgMenu        = 2
SYMBOL pgNumeric     = 3
SYMBOL pgSettings    = 4
SYMBOL pgVar         = 5


;*** OP VOLGORDE ZETTEN VAN id NUMMERS IN HET NEXTION SCHERM IS MOGELIJK DOOR DE ITEMS TE SELECTEREN, DEZE TE KOPIEEREN, TE WISSEN EN WEER TE PLAKKEN, HIERDOOR WORDEN ZE WEER ONDERAAN DE LIJST GEZET
;*** DE VOLGORDE VAN SELECTEREN MAAKT UIT, ALS JE SELECTEERT MET DE MUIS DAN VAN ONDER NAAR BOVEN SELECTEREN, DAN WORDT HET id VAN DE ITEMS (VAN BIJV. CHECKBOXES) VAN BOVEN NAAR ONDER VAN LAAG NAAR HOOG GENUMMERD
;Namen en ID van ==pgHome== venster == Plaatsen in volgorde van opkomst op de HMI
;Toetsen (buttons) zover mogelijk onderin de lijst, zodat deze zo hoog mogelijk geplaatst worden op het HMI scherm (bring to top), anders kans op slecht werkende HMI touchtoetsen
SYMBOL Home_bUp      = 16     ;Button temperatuur up
SYMBOL Home_bDn      = 17     ;Button temperatuur down
SYMBOL Home_btTop    = 18     ;Dual-button 'Heating top'
SYMBOL Home_btBack   = 19     ;Dual-button 'Heating back'
SYMBOL Home_btLamp   = 20     ;Dual-button 'Lamp'
SYMBOL Home_bTurnPlt = 23     ;Button 'Turn plateau'



;Namen en ID van ==pgMenu== venster
SYMBOL Menu_rEn  = 11         ;RadioButton 'English'
SYMBOL Menu_rNe  = 12         ;RadioButton 'Nederlands'
SYMBOL Menu_c0   = 15         ;Aanklik (linker) checkbox regel 0 van het 'Settings' menu
SYMBOL Menu_c1   = 16         ;Aanklik (linker) checkbox regel 1 van het 'Settings' menu
SYMBOL Menu_c2   = 17         ;Aanklik (linker) checkbox regel 2 van het 'Settings' menu
SYMBOL Menu_c3   = 18         ;Aanklik (linker) checkbox regel 3 van het 'Settings' menu
SYMBOL Menu_c4   = 19         ;Aanklik (linker) checkbox regel 4 van het 'Settings' menu
SYMBOL Menu_c5   = 20         ;Aanklik (linker) checkbox regel 5 van het 'Settings' menu
SYMBOL Menu_c6   = 21         ;Aanklik (linker) checkbox regel 6 van het 'Settings' menu



;Namen en ID van ==pgNumeriek== venster
SYMBOL Num_1     = 1          ;Button '1'
SYMBOL Num_2     = 2          ;Button '2'
SYMBOL Num_3     = 3          ;Button '3'
SYMBOL Num_4     = 4          ;Button '4'
SYMBOL Num_5     = 5          ;Button '5'
SYMBOL Num_6     = 6          ;Button '6'
SYMBOL Num_7     = 7          ;Button '7'
SYMBOL Num_8     = 8          ;Button '8'
SYMBOL Num_9     = 9          ;Button '9'
SYMBOL Num_0     = 10         ;Button '0'
SYMBOL Num_Min   = 11         ;Button '-'
SYMBOL Num_Pnt   = 12         ;Button '.'
SYMBOL Num_Enter = 13         ;Button '<-|'(Enter toets)
SYMBOL Num_Del   = 14         ;Button '<-' (Delete cijfer)
'YMBOL Num_Terug = 15 DOET NIET MEE        ;Button '<-' (Terug/cancel toets)



;Namen en ID van ==pgSettings== venster
SYMBOL Sett_i0   = 5          ;Invoerveld
SYMBOL Sett_i1   = 21         ;Invoerveld
SYMBOL Sett_i2   = 22         ;Invoerveld
SYMBOL Sett_i3   = 23         ;Invoerveld
SYMBOL Sett_i4   = 24         ;Invoerveld
                 


;Talen (Numerieke volgorde)
SYMBOL Engels       = 0       
SYMBOL Duits        = 1       
SYMBOL Nederlands   = 2       



;Overige programmanamen (Alfabetische volgorde)
SYMBOL TelDn        = 0
SYMBOL TelUp        = 1
SYMBOL TimeOutTijd1 = 20      ;ms:   Time-out tijd voor de eerste seriele UART ingangspoort, waarop de Nextion HMI zit aangesloten
'YMBOL WeergaveTemp = 100     ;MAX 255!  Aantal geeft aan om de hoeveel metingen de temperatuurweergave op het display moet worden gedaan



;Namen van globale interruptregisters
SYMBOL GIE     = INTCON.7     ;Global Interrupt Enable Bit:   1 = Enable alle unmasked interrupts / Disable alle interrupts
SYMBOL PEIE    = INTCON.6     ;Peripheral Interrupt Enable:   1 = Enable alle unmasked peripheral interrupts / Disable alle peripheral interrupts
SYMBOL TMR1IF  = PIR1.0       ;TMR1 Overflow Interrupt Flag
SYMBOL TMR1IE  = PIE1.0       ;TMR1 Overflow Interrupt Enable



;Namen van USART
SYMBOL TXEN    = TXSTA.5      ;Transmit Enable Bit:           1 = Enabled / 0 = Disabled
SYMBOL SYNC    = TXSTA.4      ;USART Mode Select Bit:         1 = Synchroon mode / 0 = Asynchroon mode
SYMBOL SPEN    = RCSTA.7      ;Serial Port Enable Bit:        1 = Enabled / 0 = Disabled   (C.7 en C.6 zijn seriele poortpinnen bij enabling)
SYMBOL CREN    = RCSTA.4      ;Continu Receive Enable:        1 = Enabled / 0 = Disabled
SYMBOL FERR    = RCSTA.2      ;Framing ERRor Bit:             1 = Framing error (can be updated by reading RCREG register and receive next valid byte) / 0 = Geen framing error
SYMBOL OERR    = RCSTA.1      ;Overrun ERRor Bit:             1 = Overrun error (can be cleared by clearing bit CREN) / 0 = Geen overrun error
SYMBOL RCIE    = PIE1.5       ;ReCeive Interrupt Enable Bit:  1 = Enabled / 0 = Disabled
SYMBOL TXIE    = PIE1.4       ;Transmit Interrupt Enable Bit: 1 = Enabled / 0 = Disabled
SYMBOL RCIF    = PIR1.5       ;ReCeive Interrupt Flag Bit:    1 = USART receive  buffer is vol  / 0 = USART receive buffer is leeg
SYMBOL TXIF    = PIR1.4       ;Transmit Interrupt Flag Bit:   1 = USART transmit buffer is leeg / 0 = USART transmit buffer is vol



;Namen van het TMR1 register
;TMR1 wordt in dit programma gebruikt voor timing functies
SYMBOL TMR1ON  = T1CON.0      ;TMR1 On/Off control         (0 = TMR1 teller of timer stop / 1 = TMR1 teller of timer ingeschakeld)
SYMBOL TMR1CS  = T1CON.1      ;TMR1 Clock Source select    (0 = Interne klok (Fosc/4) / 1 = Externe klok (PORTC.0, puls van LAAG naar HOOG)
SYMBOL NOT_T1SYNC = T1CON.2   ;TMR1 external clock input SYNChronization select (0 = Synchronize externe klok input / 1 = Niet synchronizeren)
SYMBOL T1OSCEN = T1CON.3      ;TMR1 OSCillator ENable      (0 = Tweede oscillator input PORTC.1(T1OSI) uitgeschakeld / 1 = Tweede oscillator input ingeschakeld, wordt gebruikt voor o.a. 32.768kHz kristal als TMR1 een RTC wordt)
SYMBOL T1CKPS0 = T1CON.4      ;TMR1 PreScaler Select bit-0
SYMBOL T1CKPS1 = T1CON.5      ;TMR1 PreScaler Select bit-1
SYMBOL RD16    = T1CON.7      ;16-bit ReaD/write mode enable (0 =  / 1 = TMR1 waarden worden in een buffer geplaatst om een tussentijdse roll-over te voorkomen)



;Poortnamen
SYMBOL Nuldoorgang  = PORTA.3 ;Nuldoorgangdetectie (230V) (via optocoupler HCPL-354 (AC-input) en 4x33k weerstanden in serie aan de 230V lamp uitgang(!), 10k pull-up, detectie is dus alleen actief als lamp brandt!) om relais precies op de nuldoorgang in- en uit te schakelen (ter voorkoming van vonken)
SYMBOL LED_PCB      = PORTA.2 ;Gele LED op 70101-A PCB (LAAG = LED aan)
SYMBOL LED_front    = PORTA.1
SYMBOL AN0          = PORTA.0 ;Temperatuur sensor
'YMBOL Display      = PORTB.7 ;D7
'YMBOL Display      = PORTB.6 ;D6
'YMBOL Display      = PORTB.5 ;D5
'YMBOL Display      = PORTB.4 ;D4
'YMBOL Display      = PORTB.3 ;RS (bruin)
'YMBOL Display      = PORTB.2 ;EN (geel)
SYMBOL Toets        = PORTB.1 ;De PCB toets
SYMBOL Deur         = PORTB.0 ;Deurschakelaar van de oven
SYMBOL RX           = PORTC.7 ;Zit aan RX van Nextion HMI  (of ESP8266 Wifi module)
SYMBOL TX           = PORTC.6 ;Zit aan TX van Nextion HMI  (of ESP8266 Wifi module)
SYMBOL Lamp         = LATC.5  ;Voor de verlichting van het proces
SYMBOL PlateauMotor = LATC.4
SYMBOL HeatingBack  = LATC.3  ;Verwarmings element aan achterzijde (Let op de naam: 'HeatingBack' is de poort, 'btBackEN' is een bit-variabele)
SYMBOL BuzzerOpPCB  = LATC.2  ;CCP1 (HPWM uitgang)
SYMBOL HeatingTop   = LATC.1  ;Verwarmings element aan bovenzijde
SYMBOL Ventilator   = LATC.0



;         76543210
PORTA  = %00000100            ;PORTA poorten laag, behalve PORTA.2 (HOOG = LED_PCB uit bij opstart)
PORTB  = %00000000            ;PORTB poorten laag
'ORTC  = %11000000            ;PORTC poorten laag, behalve de communicatie kanalen (let op met ESP8266: 3,3V!)
PORTC  = %00000000            ;PORTC poorten laag (HMI)
LATA   = %00000100            ;LATA  poorten laag, behalve LATA.2 (HOOG = LED_PCB uit bij opstart)
LATB   = %00000000            ;LATB  poorten laag
'ATC   = %11000000            ;LATC  poorten laag, behalve de communicatie kanalen (let op met ESP8266: 3,3V!)
LATC   = %00000000            ;LATC  poorten laag (HMI)
TRISA  = %11111001            ;
TRISB  = %11111111            ;
'RISC  = %10000000            ;ESP8266(?)
TRISC  = %11000000            ;HMI

ADCON1 = %10001110            ;Alleen AN0 als analoge ingang (voor de temperatuur)



;Variabelen declareren
;WORD ========================
DIM Gemiddelde      AS WORD   ;Gemiddelde van de gemeten temperatuur, dit om een zenuwachtig 7-segments display te voorkomen en alleen het gemiddelde van het laatste aantal metingen te tonen
DIM HMI_Value       AS WORD   ;Bevat een ontvangen waarde die is ingegeven op het numerieke toetsenbord van de HMI
DIM InvoerBreedte   AS WORD   ;Beperkt de invoer van het numerieke toetsenbord van de HMI tot een opgegeven maximum aantal cijfers brede invoermogelijkheid
DIM LampTijd        AS WORD   ;Time out tijd van de lamp in het compartiment | Als de deur open blijft staan (of bij wachten op print inleggen / print gereed met deur dicht), dan zal de lamp na deze time-out tijd uitgaan
DIM LampTimer       AS WORD   ;Houd bij hoelang de lamp brandt nadat de deur werd geopend
DIM LosseBits       AS WORD   ;Wordt gebruikt om te verdelen in 16 losse bits om (max.16) aliases op te kunnen slaan in EEPROM
DIM LosseBitsX      AS WORD   ;Vergelijkingsvariabele
DIM MaxInvoer       AS WORD   ;Maximale invoer waarde bij het ingeven van een getal in het numerieke toetsenbord van de HMI
DIM MinInvoer       AS WORD   ;Minimale invoer waarde bij het ingeven van een getal in het numerieke toetsenbord van de HMI
DIM NumInvoer       AS WORD   ;Het invoerveld van het numerieke toetsenbord van de HMI
DIM PinCode         AS WORD   ;Pincode dat is ingegeven in het pgGeneral menu (via toets 'Status') 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW REM AANPASSEN
DIM Temperatuur     AS WORD   ;De uit de NTC gemeten en berekende temperatuur naar graden Celsius
DIM TemperatuurX    AS WORD   ;Vergelijkingsvariabele
DIM TempFinish      AS WORD   ;Temperatuursinstelling waarbij de print als gereed wordt gemeldt
DIM TempPlace       AS WORD   ;Temperatuursinstelling waarbij de print in de oven gelegd moet worden
DIM TempSamples     AS WORD   ;MAX 64: (Constante werkt niet goed, vandaar WORD) Een te hoog aantal geeft een te trage reactie, een snelle Temperatuur stijging in de oven wordt dan te traag waargenomen door het te hoge Gemiddelde, daarom de Waarde laag houden
DIM TempSensor      AS WORD   ;De ingelezen analoge 10-bits waarde van de NTC van de temperatuurssensor
DIM TempVerderGaan  AS WORD   ;Celsius: Als deze temperatuur tijdens solderen nog niet is bereikt, dan wordt bij het sluiten van de deur verder gegaan met solderen, is de temperatuur w l bereikt, dan wordt met sluiten van de deur verder gegaan met afkoelen
DIM Thermostaat     AS WORD   ;Thermostaatinstelling uitgelezen vanuit het EEPROM geheugen
DIM ToetsTimer      AS WORD   ;Houdt bij hoe lang een toets op de HMI wordt vastgehouden voordat het in autorepeat gaat (voor o.a. automatisch verlagen/ophogen van de thermostaat-instelling) 'WWWWWWWWWWWWWWWWWWWWWWWWWW GEBRUIKT???
DIM WD1             AS WORD   ;Word Dummy 1
DIM WD2             AS WORD   ;Word Dummy 2

;BYTE ========================
DIM BuzzerTimer     AS BYTE   ;Wordt gebruikt voor de lengte van duur van piepen van de buzzer (per 1/10 sec., dus 10 = 1 seconde)
DIM DisplayTekst    AS BYTE   ;Aan de hand van de waarde wordt een melding op het display weergegeven (tijdens bedrijf)
DIM DisplayTekstX   AS BYTE   ;Vergelijkingsvariabele of 'DisplayTekst' gewijzigd is
DIM Dump            AS BYTE   ;'Dump' is een prullenbak, data wordt meteen weggooid (niet vervangen door een 'BD' variabele, omdat 'Dump' in interrupt routines kan zitten)
DIM EE_Opslag       AS BYTE   ;Hierin wordt een EEPROM adres tijdelijk opgeslagen om na het ingeven van een waarde in het numerieke toetsenbord, de ingevoerde data op te slaan op het in 'EE_Opslag' opgegeven EEPROM adres
DIM HMI_ActivePage  AS BYTE   ;Bevat het actuele paginanummer die nu op het Nextion HMI wordt getoond
DIM HMI_ActivePageX AS BYTE   ;Vergelijkingsvariabele
DIM HMI_CompID      AS BYTE   ;
DIM HMI_Event       AS BYTE   ;
DIM HMI_Numeric     AS BYTE   ;Bevat een ID nummer van het numerieke invoerveld op de HMI waarin een waarde is ingesteld/gewijzigd (ID-nummer: eerste cijfer is menu-nummer, tweede het invoerveldnummer, dus als 'HMI_Numeric' 14 is, dan is het afkomstig uit menu 1, het 4e invoerveld
DIM HMI_OntvangType AS BYTE   ;Bevat de code waaruit is af te leiden waar uit de HMI dit bericht afkomstig is
DIM HMI_Page        AS BYTE
DIM MinThermo       AS BYTE   ;Minimaal in te stellen temperatuur in graden Celsius (= variabel, want is mede afhankelijk van de ingestelde "Print gereed" temperatuur)
DIM Ontvangst1      AS BYTE   ;Bevat de ontvangen data vanuit UART (de HMI code van Nextion van het soort data die erna te verwachten is op de RX pin van de PIC)
DIM OvershootBack   AS BYTE   ;Bevat de overshoot-temperatuurswaarde voor de achterste verwarming
DIM OvershootTop    AS BYTE   ;Bevat de overshoot-temperatuurswaarde voor de bovenste verwarming
DIM ProcesState     AS BYTE   ;Houd bij in welk proces de oven zit (standby, opwarmen, afkoelen, enz.)
DIM ReturnPag       AS BYTE   ;Bevat het HMI pagina nummer waarnaartoe gesprongen moet worden als op de ENTER toets van het numerieke toetsenbord wordt gedrukt
DIM SecondeTimer    AS BYTE   ;Creeert een seconde in het hoofdprogramma
DIM StatusCode      AS BYTE   ;Afhankelijk van de ingevoerde pincode wordt de status van de HMI ingesteld (om diverse menu's voor klanten verborgen te houden), bij een bepaalde pincode kan 'StatusCode' naar 1 gaan (meerdere menu's kunnen zichtbaar worden), bij een andere pincode kan 'StatusCode' 2 worden voor nog meer menu's, enz.
DIM StringTeller    AS BYTE   ;Teller houdt bij welk element van de string geschreven wordt
DIM Taal            AS BYTE   ;Bevat het ingestelde Taal nummer (0=Engels, 1=Duits, 2=Nederlands, enz.)
DIM TempOpslaanTmr  AS BYTE   ;Timer die ervoor zorgt dat de temperatuurinstelling wordt opgeslagen in EEPROM als de instelling een aantal seconden niet is gewijzigd
DIM Volume          AS BYTE   ;Volume van de buzzer (in te stellen in de HMI). Bij openen van de deur tijdens het soldeerproces zal de buzzer altijd op maximaal volume piepen
DIM VU_Percentage   AS BYTE   ;Waarde hierin geeft via een VU-meter het verloop van solderen weer
DIM VU_PercentageX  AS BYTE   ;Vergelijkingsvariabele, als 'VU_Percentage' van waarde is veranderd, dan de waarde verzenden naar HMI
DIM BD1             AS BYTE   ;Byte Dummy 1

;BIT =========================
DIM btLamp          AS BIT    ;TRUE dan brandt de 230V lamp in het compartiment
DIM btLampX         AS BIT    ;Vergelijkingsvariabele
DIM Buzzer          AS BIT    ;Dit bit houdt bij of de buzzer op het moment aan is of niet
DIM DeurMoetOpen    AS BIT    ;TRUE als deur open gedaan moet worden om de zojuist geslodeerde print (sneller) te laten afkoelen
DIM DeurSituatie    AS BIT    ;'DeurSituatie' onthoudt of afkoelen is afgerond met de deur open of met de deur dicht
DIM DeurToestand    AS BIT    ;OPEN of DICHT, deurpoort ingelezen en aan dit bit doorgegeven voor verdere verwerking van het deursignaal (tevens een antidendertijd inschakelen als de deur van toestand veranderd)
DIM HeatingBackX    AS BIT    ;Vergelijkingsvariabele
DIM HeatingTopX     AS BIT    ;Vergelijkingsvariabele
DIM NogSolderen     AS BIT    ;Als de deur open is in proces 'Solderen', en dit bit is TRUE, dan moet de print nog gesoldeerd worden, is dit bit FALSE, dan is de print al gesoldeerd en mag deze afkoelen
DIM Veranderd       AS BIT    ;Dit bit onthoud tijdens instellen van de thermostaat of de toets is bedient (voor het veranderen van de instelling met 1 graad Celsius)
DIM VisVUbalk       AS BIT    ;TRUE dan wordt de VU-balk op 'pgHome' zichtbaar (visible)
DIM VisVUbalkX      AS BIT    ;Vergelijkingsvariabele
DIM WisDataVanHMI   AS BIT
DIM WisInvoer       AS BIT    ;TRUE, dan het invoerveld van het numerieke toetsenbord wissen (op 0 zetten), hier betreft het een nieuwe waarde die ingevoerd gaat worden, de oude (vorige) waarde dus gaan uitwissen
DIM ID1             AS BIT    ;bIt Dummy 1


;Aliases van WORD 'LosseBits', deze bits worden in EEPROM opgeslagen als een parametermenu wordt afgesloten en ingelezen tijdens initialiseren
;LET OP! Bij rangschikken op alfabetische volgorde ook de constante 'FabrLosseBits' AANPASSEN! (in de lijst "Algemene constanten")
; 5432109876543210
;%0000000010110111  << Kopieeren naar 'FabrLosseBits'
DIM btBackEN        AS LosseBits.0  ;TRUE dan is de top  heating door de gebruiker ingeschakeld (Enabled)
DIM btTopEN         AS LosseBits.1  ;TRUE dan is de back heating door de gebruiker ingeschakeld (Enabled)
DIM LampOpwarmenEN  AS LosseBits.2  ;TRUE dan is checkbox 0 van menu 'Settings' aangevinkt, TRUE als lamp moet branden tijdens opwarmen
DIM LampAfkoelenEN  AS LosseBits.3  ;TRUE dan is checkbox 1 van menu 'Settings' aangevinkt, TRUE als lamp moet branden tijdens afkoelen
DIM FanAfkoelenEN   AS LosseBits.4  ;TRUE dan is checkbox 2 van menu 'Settings' aangevinkt, TRUE als ventilator moet blijven draaien tijdens afkoelen
DIM PlateauEN       AS LosseBits.5  ;TRUE dan is checkbox 3 van menu 'Settings' aangevinkt, TRUE als plateau moet draaien
DIM PauzeerEN       AS LosseBits.6  ;TRUE dan is checkbox 4 van menu 'Settings' aangevinkt
DIM BuzzerEN        AS LosseBits.7  ;TRUE dan is checkbox 5 van menu 'Settings' aangevinkt
DIM BuzzerAfkoelEN  AS LosseBits.8  ;TRUE dan is checkbox 6 van menu 'Settings' aangevinkt, TRUE als buzzer signaaltoon moet geven als oven klaar is met solderen en deur geopend moet worden om af te koelen
'enz.                               ;...
DIM Var15           AS LosseBits.15 ;Reserve



DELAYMS 250                   ;Stabilisatie signalen/display
DECLARE PORTB_PULLUPS ON      ;On-chip pull-up weerstanden actief
REMINDERS OFF
CLEAR                         ;Wis alle RAM geheugen
REMINDERS ON



'test: interrupt na poortinstellingen (ivm. hoog of laag opstarten
ON_INTERRUPT GOTO InterruptAfhandeling ;Zorg er altijd voor dat de ON_INTERRUPT GOTO regel vrijwel de eerste actieve programmaregel is (dus heel hoog in het programma plaatsen)

CLS
PRINT AT 1, 1, "Soldeer oven", AT 2, 1, "Stand alone V1.0" ;WWWWWWWWWWWWWWWW Weergave ook afhankelijk van taalinstelling

TempSamples = 6               ;MAX 64: (Constante werkt niet goed, vandaar WORD) Een te hoog aantal geeft een te trage reactie, een snelle temperatuur stijging in de oven wordt dan te traag waargenomen door het te hoog gemiddelde, daarom de waarde laag houden
Volume      = 31              ;Buzzer volume

HPWM 1, Volume, 2000          ;Buzzer (15 = zacht volume)
DELAYMS BuzzerTijd
HPWM 1, 0, 2000

Initialiseren()               ;Ga de EEPROM waarden naar RAM geheugen schrijven

FOR BD1 = 0 TO 100            ;Tijd voor zichtbaar houden opstartscherm, maar houdt de deurschakelaar in de gaten ivm. met de verlichting
  DELAYMS 60                  ;Tijd voor zichtbaar houden opstartscherm  (60ms x 100 = 6 seconden)
  Lamp  = Deur                ;Als tijdens wachten de deur wordt geopend, dan de verlichting aanzetten (en uitzetten als de deur weer wordt dicht gedaan)
NEXT
IF Deur = OPEN THEN LampTimer = 5 ;Voorkomt dat de lamp even UIT knippert bij het binnengaan van 'Main' als de lamp al aan was door een geopende deur

FOR BD1 = 1 TO 15
  TemperatuurMeten()          ;Ga het gemiddelde opbouwen zodat bij opstart meteen de juiste temperatuur weergave op de HMI wordt getoond
NEXT

GOTO Main                     ;Spring over de subroutines



;=============================
;======== PROCEDURES =========
;=============================
;Procedure om Nextion HMI naar opgegeven pagina te gaan of de huidige pagina te verversen
PROC HMIpag(HMI_Pagina AS BYTE)                                                 ;Laat de HMI naar de opgegeven pagina gaan of ververs de huidige pagina als de HMI zich al op de betreffende pagina bevindt
  DIM  PagString AS STRING * 2                                                  ;Declareer een stringvariabele voor 2 karakters (max. "99" HMI pagina's)
  REMINDERS OFF                                                                 ;Zet een hinderlijke hintmelding van de compiler even uit voor de STRN/STR$ bewerking
  STRN PagString = STR$(DEC HMI_Pagina)                                         ;Zet BYTE variabele 'HMI_Pagina' om naar stringvariabele 'PagString' voor HMI
  REMINDERS ON                                                                  ;Hints weer aan
  HSEROUT1 ["dp=", PagString, 0xFF, 0xFF, 0xFF]                                 ;Verzend via UART1 de opdracht naar de HMI  (Voorbeeld: dp=1 = pgHome)
ENDPROC



;Procedure waarde als tekst sturen naar Nextion HMI componenten
PROC HMItxt(HMI_Component AS STRING * 8, HMI_Value AS WORD)                     ;Stringlengte bepaald de maximale lengte die de naam van het HMI component mag hebben
  HSEROUT1 [HMI_Component, ".txt=", 34, DEC HMI_Value, 34, 0xFF, 0xFF, 0xFF]    ;Verzend via UART1 de opdracht naar de HMI  (34 is ASCII voor het aanhalingsteken)
ENDPROC



;Procedure waarde als integer sturen naar Nextion HMI componenten
PROC HMIval(HMI_Component AS STRING * 20, HMI_Value AS LONG)                    ;LONG i.v.m. grote waarde in geval van de urenteller / Stringlengte bepaald de maximale lengte die de naam van het HMI component mag hebben
  HSEROUT1 [HMI_Component, ".val=", DEC HMI_Value, 0xFF, 0xFF, 0xFF]            ;Verzend via UART1 de opdracht naar de HMI
ENDPROC



;Procedure Visible/Unvisible voor Nextion HMI componenten (HMI_Visible: 1 = visible / 0 = invisible)
PROC HMIvis(HMI_Component AS STRING * 8, HMI_Visible AS BIT)                   ;Stringlengte bepaald de maximale lengte die de naam van het HMI component mag hebben
  HSEROUT1 ["vis ", HMI_Component, 44, DEC HMI_Visible, 0xFF, 0xFF, 0xFF]       ;Verzend via UART1 de opdracht naar de HMI  (44 is ASCII voor het , teken)
ENDPROC



;Procedure die een in 'Breedte' opgegeven getal (1 t/m 4), resulteert in respectievelijk 1, 10, 100, 1000.  Wordt gebruikt om het maximum aantal cijfers van het numerieke invoerveld te beperken
PROC MaxAantalCijfers(Breedte AS BYTE)
  DIM BDX AS BYTE = 1                   ;Declareer locale BYTE variabele 'BDX' en geef deze startwaarde 1 mee
  InvoerBreedte   = 1                   ;Geef globale variabele 'InvoerBreedte' startwaarde 1 mee
  WHILE BDX < Breedte                   ;Zolang lus nog niet opgegeven aantal is doorlopen, dan...
    INC BDX                             ;'BDX' met 1 verhogen
    InvoerBreedte = InvoerBreedte * 10  ;Resulteert in respectievelijk 10, 100, 1000
  WEND
ENDPROC



;Procedure berekent uit thermostaat-instelling, wat de temperatuur is dat beslist of na openen en weer sluiten van de deur tijdens solderen verder moet gegaan met proces 'Solderen' of moet worden overgegaan op proces 'Afkoelen'
PROC VerderGaan(ThermosTemp AS WORD)    ;Als deze temperatuur tijdens solderen nog niet is bereikt, dan wordt bij het sluiten van de deur verder gegaan met solderen, is de temperatuur w l bereikt, dan wordt met sluiten van de deur verder gegaan met afkoelen
  ThermosTemp    = ThermosTemp * 10
  TempVerderGaan = ThermosTemp / 13 
ENDPROC



;Procedure voor het instellen van de thermostaat
PROC ThermostaatInst(Thermostaat AS WORD, GoUp AS BIT), WORD
  DIM InstelVrijgave AS BIT             ;Declareer bit 'InstelVrijgave' voor deze procedure
  InstelVrijgave   = FALSE              ;Reset 'InstelVrijgave'
  IF GoUp          = TRUE       THEN    ;Als de thermostaat naar omhoog moet worden ingesteld, dan...
    IF Thermostaat < MaxThermo  THEN InstelVrijgave = TRUE  ;Als thermostaat nog niet op maximum is ingesteld, dan...
  ELSE                                  ;...anders... (moet de thermostaat naar omlaag worden ingesteld)
    IF Thermostaat > MinThermo  THEN InstelVrijgave = TRUE  ;Als thermostaat nog niet op minimum is ingesteld, dan...
  ENDIF
 
  IF InstelVrijgave   = TRUE    THEN    ;Als de thermostaat gewijzigd mag worden, dan... (betekent dat deze nog niet aan zijn minimum of maximimum limiet zit)
    IF HMI_Event      = PRESSED THEN    ;Als de "thermostaat UP" of "thermostaat DN" toets (nog steeds) is bedient, dan...
      WisDataVanHMI   = FALSE           ;De zojuist ontvangen 'HMI_Page' en 'HMI_Component' niet wissen want de "thermostaat UP" of "thermostaat DN" toets wordt (nog steeds) vastgehouden
      IF Veranderd    = FALSE   THEN    ;Als de thermostaat nog niet met 1 graad Celsius is veranderd, dan...
        IF GoUp       = TRUE    THEN    ;Als de thermostaat naar omhoog moet worden ingesteld, dan...
          INC Thermostaat               ;Verhoog thermostaatinstelling met 1 graad Celsius
        ELSE                            ;...anders... (moet de thermostaat naar omlaag worden ingesteld)
          DEC Thermostaat               ;Verlaag thermostaatinstelling met 1 graad Celsius
        ENDIF
        HMItxt("tst", Thermostaat)      ;Geef aan de HMI de gewijzigde thermostaat stand door
        Veranderd     = TRUE            ;Onthoud dat de thermostaat met 1 graad Celsius is veranderd
        FOR BD1       = 1 TO 12         ;12x50ms=600ms vertraging tussen thermostaat veranderen met +1 of +5. Met de FOR-NEXT is de tijd in stukken gehakt om snel +1 tippen ook mogelijk te maken
          DELAYMS 50                    ;Lusvertraging voor de FOR-NEXT lus
          IF HMI_Event    = RELEASED THEN ;Wordt tijdens uitvoering van de FOR-NEXT (tijd)lus de "thermostaat UP" of "thermostaat DN" toets losgelaten, dan...
            WisDataVanHMI = TRUE        ;Toets is binnen de "+1" tijd losgelaten
            Veranderd     = FALSE       ;De "thermostaat UP" of "thermostaat DN" toets is losgelaten dus de volgende keer mag weer +1 erbij geteld worden
            BREAK                       ;Verlaat de FOR-NEXT lus
          ENDIF
        NEXT

      ELSE                                  ;...anders... (is 'Veranderd' TRUE dus is +1 al gebeurt, wordt de toets dus langer vastgehouden, dan...)
        IF ToetsTimer     = FALSE   THEN    ;Als de toetstimer nog niet loopt, dan...
          ToetsTimer      = 3               ;Deze vertraging bepaalt de snelheid van het automatisch veranderen per 5 van de thermostaat instelling
          IF HMI_Event    = PRESSED THEN    ;Check nog een keer extra of de "thermostaat UP" of "thermostaat DN" toets nog steeds is ingedrukt (om doorschieten te voorkomen als de toets is losgelaten)
            IF GoUp       = TRUE    THEN    ;Als de thermostaat naar omhoog moet worden ingesteld, dan... 
              Thermostaat = Thermostaat + 5 ;Thermostaat verhogen met 5
            ELSE                            ;...anders... (moet de thermostaat naar omlaag worden ingesteld)
              IF Thermostaat // 5 = 0 THEN Thermostaat = Thermostaat - 5  ;Thermostaat verlagen met 5 (alleen als het cijfer eindigt op 0 of 5, anders verlaagt ie 5 teveel en kan ie onder 0 komen)
            ENDIF

            Thermostaat   = Thermostaat / 5 ;- Afronden naar 5
            Thermostaat   = Thermostaat * 5 ;/

            HMItxt("tst", Thermostaat)      ;Geef aan de HMI de actuele stand van de thermostaat door
          ENDIF
        ENDIF
      ENDIF
    ENDIF
  ENDIF
  IF HMI_Event = RELEASED THEN Veranderd = FALSE  ;De "thermostaat UP" of "thermostaat DN" toets is losgelaten dus de volgende keer mag weer per 1 veranderd worden
  RESULT       = Thermostaat                      ;Stuur als resultaat de nieuwe thermostaat instelling retour vanuit deze procedure   
ENDPROC



;=============================
;======= SUBROUTINES =========
;=============================

SUB AllesUit
  IF Ventilator  = HOOG THEN  ;Als de ventilator nog draait, dan... (door dit af te vragen wordt het uitzetten incl. nuldoorgangsdetectie maar 1x uitgevoerd)
    NuldoorgangDetectie()
    Ventilator   = LAAG       ;Ventilator uit
    HeatingBack  = LAAG       ;Achterste verwarming uit
    HeatingTop   = LAAG       ;Bovenste verwarming uit
    PlateauMotor = LAAG       ;Stopt de plateau met draaien
  ENDIF
ENDSUB



SUB Initialiseren
  LampTijd      = EREAD EE_LampTijd
  Taal          = EREAD EE_Taal         ;Vanuit EEPROM de taal-instelling inlezen
  LosseBits     = EREAD EE_LosseBits    ;Vanuit EEPROM de losse bits inlezen waarin diverse checkbox instellingen staan   
  TempPlace     = EREAD EE_TempPlace
  TempFinish    = EREAD EE_TempFinish
  Thermostaat   = EREAD EE_Thermostaat  ;Vanuit EEPROM de thermostaat-instelling inlezen
  OvershootTop  = EREAD EE_OvershTop
  OvershootBack = EREAD EE_OvershBack

  LosseBitsX    = LosseBits             ;Vergelijkingsbit updaten

  MinThermo     = TempFinish + 10       ;De minimaal mogelijk in te stellen thermostaat temperatuur is 10 graden hoger dan de ingestelde "Print gereed" temperatuur
  IF Thermostaat< MinThermo THEN        ;Als de thermostaat lager staat ingesteld dan volgens 'MinThermo' mag, dan... (Dit kan gebeuren als de thermostaat laag staat ingesteld en de insteltemperatuur van 'MinThermo' wordt in het menu hoger gezet dan de thermostaat)
    Thermostaat = MinThermo             ;Maak in dat geval de thermostaat temperatuur gelijk aan wat minimaal mag
    EWRITE EE_Thermostaat, [Thermostaat] ;Ook de thermostaat waarde in de EEPROM aanpassen
  ENDIF
 
  HMIval("pgSettings.vs", PIC_versie)
  HMIval("pgVar.Taal",    Taal)         ;Zend ingestelde taal naar de HMI (naar 'pgVar', omdat de taal van belang is op elke HMI pagina om de gewenste taal weer te geven)

  VerderGaan(Thermostaat)               ;Als deze temperatuur tijdens solderen nog niet is bereikt, dan wordt bij het sluiten van de deur verder gegaan met solderen, is de temperatuur w l bereikt, dan wordt met sluiten van de deur verder gegaan met afkoelen
ENDSUB



SUB NuldoorgangDetectie
  ;De nuldoorgangs detectie werkt bij de stand-alone versie in sommige proces-states enorm vertragend, daarom uitgeschakeld
(*  IF Lamp = HOOG THEN         ;De nuldoorgangs detectie werkt alleen als de 230V lamp brandt (de optocoupler van de detectie zit over de 230V uitgang van de lamp en is dus uit als het apparaat in rust is (dit komt de optocoupler levensduur ten goede))
    REPEAT : UNTIL Nuldoorgang = HOOG
    REPEAT : UNTIL Nuldoorgang = LAAG
    DELAYUS 7500 '8400 << top relais ok, bck relais niet '7600 << meer vonken '7800 << redelijk '8200 '8000 << redelijk voor beide relais '8800 << goed voor top relais '9900 << vonkt fel '9300 << vonkt  ;Nog 8100uSec wachten tot aan volgende nuldoorgang
  ENDIF  *)
ENDSUB



SUB ProgressBar                         ;VU-balk berekenen
  IF     ProcesState = Opwarmen THEN
    VU_Percentage    = (20 * Temperatuur) / TempPlace
   
  ELSEIF ProcesState = Solderen THEN
    VU_Percentage    = (50 * Temperatuur) / Thermostaat
 
  ELSEIF ProcesState = Afkoelen THEN
    IF Temperatuur   < Thermostaat THEN                     ;Alleen als de temperatuur lager is dan de ingestelde temperatuur, dan...
     'VU_Percentage  = 50  + ((50 * (Temperatuur - TempFinish)) / (50 - (Thermostaat - TempFinish)))  ;De formule
      BD1            = Temperatuur - TempFinish             ;Haal eerst de "temperatuur print gereed" van de actuele temperatuur
      WD1            = 50  * BD1
      BD1            = WD1 / (Thermostaat - TempFinish)     ;Gemeten temperatuur (- temp. print gereed) delen door de ingestelde thermostaat temperatuur (- temp. print gereed)
      VU_Percentage  = 50  - BD1                            ;Inverteren (want hoe LAGER de temperatuur, hoe HOGER de VU-meter uit moet slaan)
      VU_Percentage  = 50  + VU_Percentage                  ;Verplaatsen naar de tweede helft van de VU-meter (50% ... 100% uitslag)
    ELSE                                                    ;...anders... (is er een overshoot van de temperatuur)
      VU_Percentage  = 50                                   ;De VU-meter op 50% houden (tot de temperatuur lager dan de ingestelde temperatuur wordt, ter voorkoming dat de VU-meter eerst weer terug gaat lopen (veroorzaakt door de overshoot van de temperatuur))
    ENDIF
  ENDIF
ENDSUB


;=============================
;====== HOOFDPROGRAMMA =======
;=============================

Main:

;===== TMR1 instellingen =====
PEIE    = 0                   ;0: Peripheral interrupts uit
GIE     = 0                   ;0: Globale interrupts uit

TMR1CS  = 0                   ;0: TMR1 op interne klok (Fosc/4) want TMR1 wordt gebruikt voor de timing functies in dit programma
RD16    = 0                   ;0: 16-bit ReaD/write mode uitgeschakeld
T1CKPS0 = 1                   ;-: 11: Prescaler op 1:8 TMR1 PreScaler Select
T1CKPS1 = 1                   ;/
TMR1H   = 0                   ;0: Reset TMR1 (Altijd eerst TMR1H opgeven, daarna TMR1L)
TMR1L   = 0                   ;0: Reset TMR1
TMR1IE  = 1                   ;1: Enable TMR1 overflow interrupt
T1OSCEN = 0                   ;0: TMR1 OSCillator ENable uitschakelen (1 = Oscillator ingeschakeld, gebruiken als een tweede (32.768kHz) kristal op PORTC.0(T1OSO) en PORTC.1(T1OSI) wordt aangesloten voor bijv. een RTC)
TMR1ON  = 1                   ;1: TMR1 On/Off control (0 = TMR1 teller of timer stop / 1 = TMR1 teller of timer ingeschakeld)

GIE     = 1                   ;1: Enable Global Interrupts (nodig voor timers, USART)
PEIE    = 1                   ;1: Enable alle peripheral interrupts (nodig voor o.a. TMR1)
RCIE    = 1                   ;1: Enable de USART receive interrupt (voor HSERIN)



VisVUbalk    = INVISIBLE      ;Bij opstart geen VU-balk zichtbaar
DisplayTekst = LCD_Normaal    ;Start met geen displaymeldingen
HMIpag(pgHome)                ;Spring naar het 'pgHome' scherm

DO
  CLRWDT                      ;Clear Watch Dog Timer
 

;=========== LAMP ============
  IF LampTimer > 1 THEN       ;Als 'LampTimer' loopt, dan... (is de tijd nog niet voorbij)
    btLamp     = HOOG         ;De lamp aanzetten
  ELSEIF LampTimer = 1 THEN   ;...anders... als de timeout tijd van de Lamp voorbij is, dan...
    btLamp     = LAAG         ;De lamp uitzetten
    LampTimer  = 0            ;'LampTimer' uitzetten
  ENDIF
  Lamp = btLamp               ;Lamp in compartiment aanzetten volgens niveau van 'btLamp  '


;========== BUZZER =========== (Moet v  r een eventuele lusvertraging staan, anders is de 'BuzzerTimer' al niet meer gelijk aan 'BuzzerTijd')
  IF DeurMoetOpen = TRUE  THEN BuzzerTimer = FALSE ;Buzzertimer weer uitzetten in geval van als de print moet afkoelen, anders dan blijft de buzzer niet continu piepen (met hoog volume)
  IF BuzzerTimer  > 1     THEN                    ;Als de 'BuzzerTimer' groter is dan 1, dan... (betekent het dat de buzzer aan moet zijn)
    IF Buzzer     = FALSE THEN                    ;Als de buzzer nog niet aanstaat, dan...
      IF BuzzerEN = TRUE  THEN HPWM 1, Volume, 2000 ;Buzzer aanzetten (maar alleen als dit is aangevinkt op de HMI)
      Buzzer      = TRUE                          ;Buzzer staat aan
    ENDIF
  ELSEIF BuzzerTimer = 1  THEN                    ;...anders, als 'BuzzerTimer' = 1, dan... (is de tijd van de buzzer voorbij)
    HPWM 1, 0, 2000                               ;Buzzer uitzetten
    Buzzer        = FALSE                         ;Buzzer is uitgezet
    BuzzerTimer   = FALSE                         ;Zet de buzzertimer uit (anders blijft ie deze code continu uitvoeren)
  ENDIF


;======= SECONDE PULS ========
  IF SecondeTimer = 0     THEN                    ;Als er weer een seconde voorbij is, dan...
    SecondeTimer  = 10                            ;Zet 'SecondeTimer' weer op 10/10 (maakt 1 seconde)
    LED_PCB       = ~LED_PCB                      ;LED op PCB met seconde ritme laten knipperen
    TemperatuurMeten()                            ;Ga temperatuur in het compartiment meten en reken om naar graden Celsius
   
    IF LampTimer      > 0 THEN DEC LampTimer      ;Zolang 'LampTimer' groter is dan 0, deze verlagen met 1
    IF TempOpslaanTmr > 0 THEN DEC TempOpslaanTmr ;Verlaag 'TempOpslaanTmr' elke seconde tot deze op 0 staat
    IF TempOpslaanTmr = 1 THEN                    ;Als 'TempOpslaanTmr' op 1 seconde staat (thermostaat-instelling is blijkbaar al een aantal seconden niet gewijzigd), dan...
      EWRITE EE_Thermostaat, [Thermostaat]        ;De thermostaatinstelling opslaan in EEPROM
      VerderGaan(Thermostaat)                     ;Als deze temperatuur tijdens solderen nog niet is bereikt, dan wordt bij het sluiten van de deur verder gegaan met solderen, is de temperatuur w l bereikt, dan wordt met sluiten van de deur verder gegaan met afkoelen
    ENDIF
  ENDIF



;=============================
;==== HMI DISPLAY MELDING ====
;=============================
  IF DisplayTekst     != DisplayTekstX  THEN      ;Als tekst van het displayschermpje een andere tekst heeft gekregen, dan...
    IF HMI_ActivePage != pgHome         THEN      ;Als het huidige HMI scherm, niet het 'pgHome' scherm is, dan...
      IF DisplayTekst  > ERR_ErrorMessg THEN      ;Als het bericht een foutmelding (error-bericht) betreft, dan... (vanuit elk menu naar het hoofdmenu springen om de foutmelding te tonen)
        HMIpag(pgHome)                            ;Schakel de HMI over naar het 'pgHome' scherm
        BuzzerTimer    = 20                       ;Geef de buzzertimer een tijd op, waardoor de buzzer deze tijd zal gaan piepen 20 = 2 seconden
      ENDIF
    ENDIF
  ENDIF



;=============================
;=== HMI EENMALIG UITVOER ====                    ;HMI instructies die eenmalig moeten worden uitgevoerd zodra het getoonde HMI venster zich opent
;=============================
  IF HMI_ActivePage != HMI_ActivePageX THEN       ;Als er van venster is gewisseld, dan...

    SELECT HMI_ActivePage                         ;Kijk welk HMI venster nu actief is (alfabetische volgorde)
;=============================
    CASE pgHome
      HMIval("btBack", btBackEN)                  ;Geef aan de HMI door of "Heating back" is enabled of niet
      HMIval("btTop",  btTopEN)                   ;Geef aan de HMI door of "Heating top" is enabled of niet
      HMItxt("tmp",    Temperatuur)               ;De temperatuurwaarde naar de HMI zenden (ook bij "HMI eenmalige uitvoer" geplaatst, anders zou "---" op het display blijven staan, en de temperatuur pas verschijnen als deze een graad is veranderd)
      HMItxt("tst",    Thermostaat)               ;Huidige thermostaatinstelling op HMI weergeven
      btLampX        = ~btLamp                    ;\
      DisplayTekstX  = ~DisplayTekst              ; |
      HeatingBackX   = ~HeatingBack               ; |
      HeatingTopX    = ~HeatingTop                ; |- Door de vergelijkingsbit ongelijk aan het origineel te maken zullen deze bits meteen worden afgehandeld in '=== HMI CONTINU UITVOER ==='
      VisVUbalkX     = ~VisVUbalk                 ; |
      VU_PercentageX = ~VU_Percentage             ;/
     
     
;=============================
    CASE pgMenu
      HMIval("c0", LampOpwarmenEN)                ;\
      HMIval("c1", LampAfkoelenEN)                ; |
      HMIval("c2", FanAfkoelenEN)                 ; |
      HMIval("c3", PlateauEN)                     ; |-Stel de checkboxes in op de waarden die ze moeten hebben
      HMIval("c4", PauzeerEN)                     ; |
      HMIval("c5", BuzzerEN)                      ; |
      HMIval("c6", BuzzerAfkoelEN)                ;/


;=============================
    CASE pgNumeric
      HMItxt("InvLCD", NumInvoer)                 ;Zet huidige waarde in het numerieke invoerveld
      HMItxt("tMax",   MaxInvoer)                 ;Geef waarde door voor 'a value between ...' op 'pgNumeric', wordt tevens gebruikt om error te creeeren als daadwerkelijk een te hoge waarde wordt ingevoerd
      HMItxt("tMin",   MinInvoer)                 ;Geef waarde door voor 'a value between ...' op 'pgNumeric', wordt tevens gebruikt om error te creeeren als daadwerkelijk een te lage waarde wordt ingevoerd


;=============================
    CASE pgSettings
      Initialiseren()                             ;Ga (eventueel gewijzigde) EEPROM waarden inlezen
      HMItxt("i0", LampTijd)                      ;Geef de huidige ingestelde tijd door aan de HMI zodat deze het kan tonen in het "Settings" menu
      HMItxt("i1", TempPlace)                     ;Geef de huidige ingestelde temperatuur door aan de HMI zodat deze het kan tonen in het "Settings" menu
      HMItxt("i2", TempFinish)                    ;Geef de huidige ingestelde temperatuur door aan de HMI zodat deze het kan tonen in het "Settings" menu
      HMItxt("i3", OvershootTop)                  ;Geef de huidige ingestelde temperatuur door aan de HMI zodat deze het kan tonen in het "Settings" menu
      HMItxt("i4", OvershootBack)                 ;Geef de huidige ingestelde temperatuur door aan de HMI zodat deze het kan tonen in het "Settings" menu


    ENDSELECT
    HMI_ActivePageX = HMI_ActivePage              ;Vergelijkingsvariabele weer gelijk maken aan huidig scherm
  ENDIF




;=============================
;==== HMI CONTINU UITVOER ====                    ;HMI instructies die bij een getoond venster continu moeten worden uitgevoerd
;=============================
  SELECT HMI_ActivePage                           ;Kijk welk HMI venster nu actief is

;=============================
  CASE pgHome                                     ;Instructies die continu uitgevoerd moeten worden als "pgHome" voor staat:
    IF btLamp      != btLampX      THEN           ;Als de lamp in het compartiment aan of uit is gezet, dan...
      HMIval("btLamp", btLamp)                    ;Geef aan de HMI door of "Lamp" brandt of niet
      btLampX       = btLamp                      ;Vergelijksvariabele updaten
    ENDIF
   
    IF HeatingBack != HeatingBackX THEN           ;Als de achterste heating aan of uit is gegaan, dan...
      HMIvis("p1",    HeatingBack)                ;Het symbool boven de "Heating back" toets zichtbaar of onzichtbaar maken (afhankelijk of heating back resp. aan of uit is)
      HeatingBackX  = HeatingBack                 ;Vergelijksvariabele updaten
    ENDIF

    IF HeatingTop  != HeatingTopX  THEN           ;Als de bovenste heating aan of uit is gegaan, dan...
      HMIvis("p0",    HeatingTop)                 ;Het symbool boven de "Heating top" toets zichtbaar of onzichtbaar maken (afhankelijk of heating top resp. aan of uit is)
      HeatingTopX   = HeatingTop                  ;Vergelijksvariabele updaten
    ENDIF

    IF Temperatuur != TemperatuurX THEN           ;Als de gemeten temperatuur in het compartiment is gewijzigd, dan...
      HMItxt("tmp",   Temperatuur)                ;De nieuwe temperatuurwaarde naar de HMI zenden
      TemperatuurX  = Temperatuur                 ;Vergelijkingsvariabele updaten
    ENDIF

    IF VisVUbalk   != VisVUbalkX   THEN           ;Als de VU-balk visualiteit status is veranderd, dan...
      IF VisVUbalk  = VISIBLE      THEN           ;Als de VU-balk zichtbaar moet zijn, dan...
        HMIvis("bTn", INVISIBLE)                  ;Maak de (eventueel zichtbare) "Turn plateau" toets onzichtbaar
        HMIvis("j0",  VISIBLE)                    ;Maak VU-balk zichtbaar
        HMIvis("tz0", PauzeerEN)                  ;Maak het eerste gele markering streepje boven de VU-balk zichtbaar, maar alleen als pauzering is enabled
        HMIvis("tz1", VISIBLE)                    ;Maak het tweede gele markering streepje boven de VU-balk zichtbaar
      ELSE
        HMIvis("bTn", VISIBLE)                    ;Maak de "Turn plateau" toets zichtbaar
        HMIvis("j0",  INVISIBLE)                  ;Maak VU-balk onzichtbaar
        HMIvis("tz0", INVISIBLE)                  ;Maak het eerste gele markering streepje boven de VU-balk onzichtbaar
        HMIvis("tz1", INVISIBLE)                  ;Maak het tweede gele markering streepje boven de VU-balk onzichtbaar
      ENDIF
      VisVUbalkX    = VisVUbalk                   ;Vergelijksvariabele updaten
    ENDIF 

    Progressbar()

    IF VU_Percentage != VU_PercentageX THEN       ;Als de VU stand is veranderd, dan...
      HMIval("j0",      VU_Percentage)            ;Verzendt de nieuwe VU stand naar de VU-meter op de HMI
      VU_PercentageX  = VU_Percentage             ;Vergelijkingsvariabele updaten
    ENDIF             
   
    IF DisplayTekst  != DisplayTekstX  THEN
      DisplayTekstX   = DisplayTekst
      HMIval("tekst",  DisplayTekst)              ;Laat de HMI de bij de waarde van 'DisplayTekst' behorende tekst in het venstertje weergeven
      HSEROUT1 ["click sub0,1", 0xFF, 0xFF, 0xFF] ;Klik op Hotspot 'sub0'. ('sub0' in de HMI is een Hotspot, dat gebruikt wordt als subroutine. 'sub0' bevat alle meldingen voor het meldings-display in 'pgHome')
    ENDIF
 
  ENDSELECT




;=============================
;======== HMI INVOER =========
;=============================
  IF HMI_Page > 0 THEN
    WisDataVanHMI = TRUE                          ;Normaal na elke verwerking van de HMI opdracht, deze opdracht meteen wissen (= default)
    SELECT HMI_Page                               ;Voer afhankelijk van het nu getoonde HMI venster de bijbehorende opdrachten uit
;=============================
    CASE pgHome                                   ;Als 'pgHome' op het HMI venster wordt weergegeven, dan...

      SELECT HMI_CompID
      CASE Home_bUp                               ;'Home_bUp' is de "thermostaat UP" toets van de HMI
        Thermostaat    = ThermostaatInst(Thermostaat, TelUp) ;Ga de thermostaat hoger instellen
        TempOpslaanTmr = 5                        ;Zet de timer die ervoor zorgt dat de temperatuurinstelling wordt opgeslagen in EEPROM in op 5 seconden

      CASE Home_bDn                               ;'Home_bDn' is de "thermostaat DOWN" toets van de HMI
        Thermostaat    = ThermostaatInst(Thermostaat, TelDn) ;Ga de thermostaat lager instellen
        TempOpslaanTmr = 5                        ;Zet de timer die ervoor zorgt dat de temperatuurinstelling wordt opgeslagen in EEPROM in op 5 seconden

      CASE Home_btBack
        btBackEN       = ~btBackEN

      CASE Home_btLamp
        IF ProcesState = Solderen THEN            ;Als het proces 'Solderen' bezig is, dan... (lamp kan niet uitgezet worden tijdens solderen)
          HMIval("btLamp", TRUE)                  ;Bij een druk op de btLamp toets op de HMI zet de HMI de toets zelf uit, deze toets dus meteen weer aanzetten
        ELSE                                      ;...anders... (is een ander proces bezig)
          btLamp       = ~btLamp                  ;Toggle de lamp
          IF ProcesState = OvenStandBy THEN       ;Als in proces 'OvenStandBy' de lamp met de toets werd aangezet, dan...
            LampTimer  = 300                      ;Deze alsnog na 5 minuten uitzetten
          ELSE                                    ;...anders...
            LampTimer  = LampTijd                 ;Time-out starten met de tijd die is ingesteld op de HMI
          ENDIF
         
          IF btLamp    = LAAG THEN LampTimer = FALSE ;Als de lamp handmatig wordt uitgeschakeld, dan een eventueel lopende lamptimer (weer) uitzetten
        ENDIF

      CASE Home_btTop
        btTopEN        = ~btTopEN
       
      CASE Home_bTurnPlt
        PlateauMotor   = HMI_Event                  ;Wordt de 'Turn plateau' toets ingedrukt, dan het plateau verdraaien / Bij loslaten stoppen

      ENDSELECT


;=============================
    CASE pgMenu
     
      SELECT HMI_CompID       
      CASE Menu_c0                                ;Checkbox verlichting tijdens opwarmen
        LampOpwarmenEN  = ~LampOpwarmenEN
         
      CASE Menu_c1                                ;Checkbox verlichting tijdens afkoelen
        LampAfkoelenEN  = ~LampAfkoelenEN
       
      CASE Menu_c2                                ;Checkbox ventilator tijdens afkoelen
        FanAfkoelenEN   = ~FanAfkoelenEN
        IF ProcesState  = Afkoelen THEN Ventilator = FanAfkoelenEN  ;Pas de fansituatie meteen aan (alleen tijdens proces afkoelen, anders zou bij uit- of aanvinken van de checkbox de fan gaan draaien (of juist niet) in overige states)
       
      CASE Menu_c3                                ;Checkbox plateau laten draaien
        PlateauEN       = ~PlateauEN
        IF ProcesState  > OvenStandBy AND ProcesState < PrintKlaar THEN PlateauMotor = PlateauEN  ;Pas de motorsituatie meteen aan (alleen tijdens proces, anders zou bij aanvinken van de checkbox de motor gaan draaien in standby of printklaar states)
       
      CASE Menu_c4                                ;Checkbox pauzeer na voorverwarmen om een PCB in te leggen
        PauzeerEN       = ~PauzeerEN
       
      CASE Menu_c5                                ;Checkbox signaaltoon geven (buzzer)
        BuzzerEN        = ~BuzzerEN
       
      CASE Menu_c6                                ;Checkbox signaaltoon geven als oven klaar is met solderen en deur geopend moet worden om af te koelen (buzzer)
        BuzzerAfkoelEN  = ~BuzzerAfkoelEN

      CASE Menu_rEn                               ;Als radiobutton Engels wordt geselecteerd, dan...
       ;Zorg ervoor dat checkboxes op dezelfde pagina als waar de radiobuttons van taalinstelling staan, in de HMI op GLOBAL staan, zodat bij taalwisseling de vinkjes blijven staan
        Taal = Engels                             ;Taal naar Engels
        EWRITE EE_Taal, [Taal]                    ;Sla de ingestelde taal ook op in de interne EEPROM
        HMIval("pgVar.Taal", Taal)                ;Zend ingestelde taal naar de 'pgVar' pagina van de HMI
        HMIpag(HMI_Page)                          ;Ververs de pagina, dit is nodig in geval er een andere taal wordt gekozen
 
      CASE Menu_rNe                               ;Als radiobutton Nederlands wordt geselecteerd, dan...
        Taal = Nederlands                         ;Taal naar Nederlands
        EWRITE EE_Taal, [Taal]                    ;Sla de ingestelde taal ook op in de interne EEPROM
        HMIval("pgVar.Taal", Taal)                ;Zend ingestelde taal naar de 'pgVar' pagina van de HMI
        HMIpag(HMI_Page)                          ;Ververs de pagina, dit is nodig in geval er een andere taal wordt gekozen
 
      END SELECT


;=============================
    CASE pgNumeric                                ;Numeriek toetsenbord
      ;ATTENTIE: Doordat 'NumInvoer' (in EWRITE EE_Opslag, [NumInvoer]) een WORD variabele betreft, moeten de variabelen voor de invoervelden ALTIJD van het type WORD zijn, ook al zou een waarde nooit groter dan 255 ingevoerd worden!  Anders EEPROM overlap problemen!

      SELECT HMI_CompID
      CASE Num_1 TO Num_0                         ;Toetsen '1' t/m '9' en toets '0' (met 'HMI_CompID' waarde 10)
        IF WisInvoer = TRUE THEN                  ;Als het invoerveld gewist moet worden, dan... (betreft het een nieuwe waarde die ingevoerd gaat worden, de oude (vorige) waarde dus uitwissen)
          NumInvoer  = 0                          ;Wis invoerveld door deze op 0 te zetten
          WisInvoer  = FALSE                      ;Wissen is gebeurt, in deze sessie dus niet meer doen
          HMIvis("tMinMax", INVISIBLE)            ;Maak het rode vak weer onzichtbaar
        ENDIF
        IF NumInvoer < InvoerBreedte THEN         ;'InvoerBreedte' beperkt de invoer tot opgegeven maximum aantal cijfers brede invoermogelijkheid
          NumInvoer  = NumInvoer * 10             ;Eerst x10 doen, waardoor het rechtercijfer een 0 zal worden
          IF HMI_CompID != Num_0 THEN NumInvoer = NumInvoer + HMI_CompID ;Als het niet toets '0' is (met HMI ID waarde 10) dat werd ingevoerd (dus is het een toets uit '1' t/m '9'), dan dit getal bij de huidige waarde optellen
        ENDIF
        HMItxt("InvLCD", NumInvoer)

      CASE Num_Del                                ;Button '<-' (Delete cijfer)
        NumInvoer    = NumInvoer / 10             ;Door door 10 te delen verdwijnt het rechter cijfer van de waarde dat in het invoerveld staat
        IF WisInvoer = TRUE THEN
          WisInvoer  = FALSE                      ;Een oude (vorige) waarde is door de DEL toets (10x) kleiner gemaakt, mogelijk wordt een oude (vorige) waarde verbeterd, ga het invoerveld nu niet meer wissen als er een numerieke toets wordt bedient
          HMIvis("tMinMax", INVISIBLE)            ;Maak het rode vak weer onzichtbaar
        ENDIF
        HMItxt("InvLCD", NumInvoer)
       
      CASE Num_Enter                              ;Button '<-|'(Enter toets)
        IF NumInvoer  < MinInvoer THEN            ;Als er een te kleine waarde wordt ingevoerd, dan...
          HMIval("tekst",  10)                    ;Laat de HMI de errortekst voor te klein getal ingevoerd in het rode invoervenstertje weergeven
          HSEROUT1 ["click sub0,1", 0xFF, 0xFF, 0xFF] ;Klik op Hotspot 'sub0'. ('sub0' in de HMI is een Hotspot, dat gebruikt wordt als subroutine. 'sub0' bevat de error meldingen voor het invoer-display in 'pgNumeric')
          BuzzerTimer = 10                        ;Buzzertijd opgeven, waardoor de buzzer verderop zal worden aangestuurd
          WisInvoer   = TRUE                      ;Foutieve waarde ingevoerd, wis zodadelijk de waarde zodra een numerieke toets wordt bedient
        ELSEIF NumInvoer > MaxInvoer THEN         ;...anders, als er een te grote waarde wordt ingevoerd, dan...
          HMIval("tekst",  11)                    ;Laat de HMI de errortekst voor te groot getal ingevoerd in het rode invoervenstertje weergeven
          HSEROUT1 ["click sub0,1", 0xFF, 0xFF, 0xFF] ;Klik op Hotspot 'sub0'. ('sub0' in de HMI is een Hotspot, dat gebruikt wordt als subroutine. 'sub0' bevat de error meldingen voor het invoer-display in 'pgNumeric')
          BuzzerTimer = 10                        ;Buzzertijd opgeven, waardoor de buzzer verderop zal worden aangestuurd
          WisInvoer   = TRUE                      ;Foutieve waarde ingevoerd, wis zodadelijk de waarde zodra een numerieke toets wordt bedient
        ELSE                                      ;...anders... (is een acceptuele waarde ingevoerd)
          EWRITE EE_Opslag, [NumInvoer]           ;Sla de nieuwe waarde (in 'NumInvoer') op, op het via 'EE_Opslag' doorgekregen EEPROM adres
          Initialiseren()                         ;Zet de huidige (gewijzigde) waarde(n) ook over naar bijbehorende RAM variabelen
          HMIpag(ReturnPag)                       ;Spring naar de pagina die bij het binnengaan van 'pgNumeric' werd opgegeven
        ENDIF

     'CASE Num_Min                                ;Button '-'
     'CASE Num_Pnt                                ;Button '.'
      ENDSELECT
     

;=============================
    CASE pgSettings                               ;Pagina instellingen

      WisInvoer = TRUE
      MinInvoer = 0                               ;Default waarde numeriek invoerveld
      MaxInvoer = 9999                            ;Default waarde numeriek invoerveld
      ReturnPag = HMI_Page                        ;Default pagina (en staat hier dus op 'pgSettings') waarna naartoe wordt gesprongen nadat op ENTER van het numerieke toetsenbord wordt gedrukt

      SELECT HMI_CompID
      CASE Sett_i0                                ;Een klik op het invoerveld 'i0' in 'Settings'
        MaxAantalCijfers(3)                       ;Maximum aantal in te voeren cijfers in het numerieke invoerveld
        MinInvoer = 5                             ;BYTE: Minimum op te geven aantal seconden voor de lamp time-out
        MaxInvoer = 250                           ;BYTE: Maximum op te geven aantal seconden voor de lamp time-out
        NumInvoer = LampTijd                      ;Geef de huidige ingestelde tijd door aan de HMI zodat deze het kan tonen in het invoerveld van het numerieke toetsenbord
        EE_Opslag = EE_LampTijd                   ;Geef aan 'EE_Opslag' door op welk EEPROM adres de zodadelijk in te geven waarde moet worden opgeslagen
        ReturnPag = pgHome                        ;Uitzondering: deze springt na ENTER van het numerieke toetsenbord naar 'pgHome'
     
      CASE Sett_i1
        MaxAantalCijfers(3)                       ;Maximum aantal in te voeren cijfers in het numerieke invoerveld
        MinInvoer = 40                            ;BYTE: Minimum op te geven temperatuur voor PCB in oven plaatsen
        MaxInvoer = 140                           ;BYTE: Maximum op te geven temperatuur voor PCB in oven plaatsen
        NumInvoer = TempPlace                     ;Geef de huidige ingestelde temperatuur door aan de HMI zodat deze het kan tonen in het invoerveld van het numerieke toetsenbord
        EE_Opslag = EE_TempPlace                  ;Geef aan 'EE_Opslag' door op welk EEPROM adres de zodadelijk in te geven waarde moet worden opgeslagen
       
      CASE Sett_i2
        MaxAantalCijfers(3)                       ;Maximum aantal in te voeren cijfers in het numerieke invoerveld
        MinInvoer = 30                            ;BYTE: Minimum op te geven temperatuur voor PCB finished
        MaxInvoer = 130                           ;BYTE: Maximum op te geven temperatuur voor PCB finished
        NumInvoer = TempFinish                    ;Geef de huidige ingestelde temperatuur door aan de HMI zodat deze het kan tonen in het invoerveld van het numerieke toetsenbord
        EE_Opslag = EE_TempFinish                 ;Geef aan 'EE_Opslag' door op welk EEPROM adres de zodadelijk in te geven waarde moet worden opgeslagen
     
      CASE Sett_i3
        MaxAantalCijfers(2)                       ;Maximum aantal in te voeren cijfers in het numerieke invoerveld
        MaxInvoer = 20                            ;BYTE: Maximum op te geven overshoot temperatuur voor de bovenste verwarming
        NumInvoer = OvershootTop                  ;Geef de huidige ingestelde temperatuur door aan de HMI zodat deze het kan tonen in het invoerveld van het numerieke toetsenbord
        EE_Opslag = EE_OvershTop                  ;Geef aan 'EE_Opslag' door op welk EEPROM adres de zodadelijk in te geven waarde moet worden opgeslagen
     
      CASE Sett_i4
        MaxAantalCijfers(2)                       ;Maximum aantal in te voeren cijfers in het numerieke invoerveld
        MaxInvoer = 20                            ;BYTE: Maximum op te geven overshoot temperatuur voor de achterste verwarming
        NumInvoer = OvershootBack                 ;Geef de huidige ingestelde temperatuur door aan de HMI zodat deze het kan tonen in het invoerveld van het numerieke toetsenbord
        EE_Opslag = EE_OvershBack                 ;Geef aan 'EE_Opslag' door op welk EEPROM adres de zodadelijk in te geven waarde moet worden opgeslagen
       
      END SELECT
     
    ENDSELECT
     

;=== Opslaan stand van radiobuttons, checkboxes en dual toetsen in EEPROM:
    IF LosseBits != LosseBitsX THEN               ;'btTopEN', 'btTopEN', 'LampOpwarmenEN', enz. zijn aliases (bits) van WORD 'LosseBits'. Dus als   n van deze bits is gewijzigd, dan...
      EWRITE EE_LosseBits, [LosseBits]            ;Dit opslaan in EEPROM
      LosseBitsX = LosseBits                      ;Vergelijkingsvariabele updaten
    ENDIF

    IF WisDataVanHMI = TRUE THEN                  ;Als de data (na verwerking van een HMI opdracht) gewist mag worden, dan...
      CLEAR HMI_CompID                            ;- De ontvangen en zojuist uitgevoerde HMI opdracht wissen
      CLEAR HMI_Page                              ;/
    ENDIF
  ENDIF
 
 

;=============================
;==== PROCES AFHANDELING =====
;=============================
  ;BELANGRIJK DAT DIT VIA BIT 'DeurToestand' GEBEURT, DIT VOORKOMT EEN HOOP NARIGHEID (Dan als steeds rechtstreeks naar poort 'Deur' wordt gevraagd)
  IF DeurToestand <> Deur THEN                    ;Als deur open of dicht gedaan wordt, dan... (verandering van toestand van de deur)
    DELAYMS AntiDender                            ;Vertragingstijd inzetten tegen contactdender van de deurschakelaar
    DeurToestand     = Deur                       ;Maak na de antidendertijd de deurtoestand weer actueel aan de deur situatie

    ;Onderstaande routine wordt maar 1x per deuractie ingesteld
    IF DeurToestand  = OPEN THEN                  ;Als de deur wordt geopend, dan...
      LampTimer      = LampTijd                   ;Lamptimer instellen op zijn op de HMI ingestelde tijd
     
      SELECT ProcesState
      CASE Solderen
        IF Temperatuur <= TempVerderGaan THEN HPWM 1, 127, 2000  ;Als de temperatuur nog niet heel erg hoog is, dan de buzzer aanzetten (als de temperatuur w l heel hoog is, wordt er vanuit gegaan dat men de print wil laten afkoelen, dan dus geen buzzer)
     
      CASE Afkoelen
        IF LampAfkoelenEN = TRUE THEN LampTimer = FALSE  ;Dit zorgt ervoor dat de lamp een minimale tijd blijft doorbranden, ook als in de HMI 'VerlichtingKoel' op uitgeschakeld staat     
        DeurMoetOpen = FALSE                      ;Na openen van de deur mag dit controlebit naar FALSE
        HPWM 1, 0, 2000                           ;Buzzer van waarschuwing "deur openen om af te koelen" uitzetten
 
      CASE OvenStandBy
        ProcesState  = Opwarmen                   ;Voor stand-alone is dit er bijgekomen (Vanuit stand-by is de boel op te starten door de deur open en dicht te doen)
        VisVUbalk    = INVISIBLE                  ;Maak de VU-balk onzichtbaar (invisible), waardoor de "Turn plateau" toets zichtbaar wordt
     
      CASE ELSE
        VisVUbalk    = INVISIBLE                  ;Maak de VU-balk onzichtbaar (invisible), waardoor de "Turn plateau" toets zichtbaar wordt     
      ENDSELECT     


    ELSE                                          ;...anders... (is de deur dicht)
      IF HMI_ActivePage != pgHome   THEN HMIpag(pgHome)       ;Als het huidige HMI scherm, niet het 'pgHome' scherm is, dan naar het 'pgHome' scherm springen
      IF ProcesState != OvenStandBy THEN VisVUbalk = VISIBLE  ;Maak de VU-balk zichtbaar (visible)

      SELECT ProcesState
      CASE Opwarmen
        btLamp       = LampOpwarmenEN             ;Verlichting tijdens opwarmen instellen volgens de instelling in de HMI
        LampTimer    = FALSE                      ;Anders kans dat een lopende timer alsnog de lamp uit gaat zetten
     
      CASE Solderen
        HPWM 1, 0, 2000                           ;Buzzer deur open tijdens solderen uitzetten

      CASE Afkoelen
        btLamp       = LampAfkoelenEN             ;Verlichting tijdens afkoelen wel of niet continu laten branden volgens de instelling in de HMI
        IF LampAfkoelenEN = TRUE THEN   
          LampTimer  = FALSE                      ;'LampTimer' uitzetten als 'verlichting tijdens afkoelen' is aangevinkt, anders kans dat een lopende timer alsnog de lamp uit gaat zetten
        ELSE                             
          LampTimer  = LampTijd                   ;Dit zorgt ervoor dat de lamp een minimale tijd blijft doorbranden, ook als in de HMI 'VerlichtingKoel' op uitgeschakeld staat
        ENDIF

      CASE OvenStandBy
        btLamp       = LAAG                       ;Lamp uitzetten als oven standby is
        HPWM 1, 0, 2000                           ;Buzzer uit
      ENDSELECT
    ENDIF
  ENDIF



  SELECT ProcesState
    CASE Opwarmen
      IF DeurToestand = DICHT THEN
        IF Temperatuur < TempPlace THEN   ;Als de oven nog niet op (voorverwarm)temperatuur is, dan...
          DisplayTekst= LCD_Opwarmen      ;Plaats tekst op het display van de HMI
          Ventilator  = HOOG              ;Ventilator aan
          HeatingBack = HOOG              ;Achterste verwarming aan (bij opwarmen gaan beide verwarmings aan, ongeacht de instelling van de 'Heating top' en 'Heating back' op de HMI)
          HeatingTop  = HOOG              ;Bovenste verwarming aan       
          PlateauMotor= PlateauEN         ;Laat plateaumotor draaien als de HMI hierop is ingesteld
          VisVUbalk   = VISIBLE           ;Maak de VU-balk zichtbaar (visible)
        ELSE                              ;...anders... (is de oven voorverwarmd)
          DELAYMS 100                     ;Tijd dat lamprelais goed aan is
          IF PauzeerEN  = TRUE THEN       ;Als checkbox "Pauzeer na voorverwarmen" is aangevinkt om een print in te leggen, dan...
            LampTimer   = LampTijd        ;Lamptimer instellen op zijn op de HMI ingestelde tijd
            ProcesState = PrintInleggen   ;Als de temperatuur bereikt is, dan naar het volgende proces
          ELSE                            ;...anders...
            ProcesState = Solderen        ;Meteen door met solderen (aangenomen wordt dat de print bij opstart al in de oven is gelegd)
          ENDIF
        ENDIF

      ELSE                                ;...anders... (is de deur geopend)
        DisplayTekst  = ERR_DeurIsOpen    ;Plaats tekst op het display van de HMI
        AllesUit()                        ;Zet ventilator, heatings en plateaumotor uit (via nuldoorgangsdetectie)
      ENDIF


    CASE PrintInleggen
      IF DeurToestand = DICHT THEN
        DisplayTekst  = LCD_PlaatsPCB     ;Plaats tekst op het display van de HMI
        AllesUit()                        ;Zet ventilator, heatings en plateaumotor uit (via nuldoorgangsdetectie)
        VisVUbalk     = VISIBLE           ;Maak de VU-balk zichtbaar (visible)
       
      ELSE                                ;Zodra de deur geopend wordt, dan...
        NogSolderen   = TRUE              ;Print moet nog gesoldeerd worden (dit bit zorgt ervoor dat niet meteen in processtate 'Print afkoelen' komt in proces 'Solderen' na openen van de deur
        ProcesState   = Solderen          ;Als de deur wordt geopend wordt "alvast" naar de volgende processtap gegaan
      ENDIF


    CASE Solderen
      IF DeurToestand = DICHT THEN
        DisplayTekst  = LCD_Solderen      ;Plaats tekst op het display van de HMI
        NogSolderen   = FALSE             ;Print wordt gesoldeerd
        Ventilator    = HOOG              ;Altijd ventilator aan tijdens heating
        PlateauMotor  = PlateauEN         ;Laat plateaumotor draaien als de HMI hierop is ingesteld
        VisVUbalk     = VISIBLE           ;Maak de VU-balk zichtbaar (visible)
        btLamp        = HOOG              ;Altijd verlichting aan tijdens het soldeerproces
        LampTimer     = FALSE             ;Anders kans dat een lopende timer alsnog de lamp uit gaat zetten

        IF Temperatuur > (Thermostaat - OvershootBack) THEN
          HeatingBack = LAAG              ;HeatingBack alvast uitzetten omdat temperatuur bijna bereikt is
        ELSEIF Temperatuur < (Thermostaat - OvershootBack) THEN ;...anders... (hier opnieuw vergelijking doen (dan alleen een losse ELSE) cree rt een hysteresis)
          HeatingBack = btBackEN          ;HeatingBack ook aan
        ENDIF

        IF Temperatuur > (Thermostaat - OvershootTop) THEN
          HeatingTop  = LAAG              ;HeatingTop alvast uitzetten omdat temperatuur bijna bereikt is
        ELSEIF Temperatuur < (Thermostaat - OvershootTop) THEN  ;...anders... (hier opnieuw vergelijking doen (dan alleen een losse ELSE) cree rt een hysteresis)
          HeatingTop  = btTopEN           ;HeatingTop ook aan
        ENDIF

        IF Temperatuur >= Thermostaat THEN ;Als de ingestelde temperatuur bereikt is, dan...
          IF BuzzerAfkoelEN = TRUE    THEN ;Als checkbox 'Buzzer deur openen bij afkoelen' is aangevinkt, dan...
            HPWM 1, 127, 2000             ;Buzzer continu aanzetten
            DeurMoetOpen    = TRUE        ;Controlebit op TRUE zetten
          ENDIF
          IF LampAfkoelenEN = FALSE   THEN LampTimer = LampTijd       ;Dit zorgt ervoor dat de lamp een minimale tijd blijft doorbranden, ook als in de HMI 'VerlichtingKoel' op uitgeschakeld staat
          ProcesState  = Afkoelen         ;Ga naar proces afkoelen
        ENDIF

      ELSE                                ;...anders... (is de deur geopend)
        IF NogSolderen = TRUE OR Temperatuur <= TempVerderGaan THEN ;Als de print nog gesoldeerd moet worden, dan...
          DisplayTekst = ERR_DeurSluiten  ;Plaats tekst op het display van de HMI
          AllesUit()                      ;Zet ventilator, heatings en plateaumotor uit (via nuldoorgangsdetectie)
        ELSE                              ;...anders... (is de print w l gesoldeerd)
          IF LampAfkoelenEN = FALSE THEN LampTimer = LampTijd  ;Dit zorgt ervoor dat de lamp een minimale tijd blijft doorbranden, ook als in de HMI 'VerlichtingKoel' op uitgeschakeld staat
          ProcesState  = Afkoelen
        ENDIF
      ENDIF     
   

   
    CASE Afkoelen
      IF DeurMoetOpen = TRUE THEN         ;Als de deur open moet worden gedaan om af te koelen, dan...
        DisplayTekst  = ERR_DeurOpenen    ;Plaats waarschuwings tekst op het display van de HMI
      ELSE                                ;...anders... (is het bit niet geactiveerd omdat checkbox 'Buzzer deur openen bij afkoelen' niet is aangevinkt of omdat de deur al open is (geweest))
        DisplayTekst  = LCD_Afkoelen      ;Plaats tekst op het display van de HMI
      ENDIF
      HeatingBack     = LAAG              ;Achterste verwarming uit
      HeatingTop      = LAAG              ;Bovenste verwarming uit
      Ventilator      = FanAfkoelenEN     ;Ventilator tijdens afkoelen instellen volgens de instelling in de HMI
      PlateauMotor    = PlateauEN         ;Laat plateaumotor draaien als de HMI hierop is ingesteld
      VisVUbalk       = VISIBLE           ;Maak de VU-balk zichtbaar (visible)
      IF Temperatuur <= TempFinish THEN
        FOR BD1 = 0 TO 2                  ;=  -_-_-
          HPWM 1, 0, 2000                 ;Buzzer uit
          DELAYMS BuzzerTijd / 3          ;1/3 Buzzertijd
          HPWM 1, 127, 2000               ;Buzzer (15 = zacht volume)
          DELAYMS BuzzerTijd / 3          ;1/3 Buzzertijd
        NEXT
        DELAYMS BuzzerTijd                ;Buzzertijd
        HPWM 1, 0, 2000                   ;Buzzer uit
        DeurSituatie  = DeurToestand      ;'DeurSituatie' onthoudt of afkoelen is afgerond met de deur open of met de deur dicht
        LampTimer     = LampTijd          ;Zet de lamp aan inclusief time-out voor het 'printklaar' proces
        ProcesState   = PrintKlaar        ;Volgende processtap
      ENDIF
     
     

    CASE PrintKlaar
      IF DeurToestand = DeurSituatie THEN ;Zolang de deur in de situatie blijft als ie was tijdens aflopen van proces 'Afkoelen', dan...
        DisplayTekst  = LCD_PCB_Gereed    ;Plaats tekst op het display van de HMI
        AllesUit()                        ;Zet ventilator, heatings en plateaumotor uit (via nuldoorgangsdetectie)
        VisVUbalk     = INVISIBLE         ;Maak de VU-balk onzichtbaar (invisible)       
      ELSE                                ;...anders... (Zodra de deur van situatie veranderd (dus wordt gesloten dan wel geopend))
        ProcesState   = OvenStandBy       ;De oven op stand-by zetten
      ENDIF

             
                                 
    CASE ELSE                             ;Oven op standby (uitgeschakeld)
      VisVUbalk       = INVISIBLE         ;Maak de VU-balk onzichtbaar (invisible)
      IF DeurToestand = DICHT THEN
        DisplayTekst  = LCD_StandBy       ;Plaats tekst op het display van de HMI
      ELSE
        DisplayTekst  = ERR_DeurIsOpen    ;Plaats tekst op het display van de HMI
      ENDIF
      AllesUit()                          ;Zet ventilator, heatings en plateaumotor uit (via nuldoorgangsdetectie)

  ENDSELECT

LOOP



SUB TemperatuurMeten
  TempSensor = 60 * ADIN 0  ;Max 64! (1023 x 64 = 65472)
 
  WD1 = Gemiddelde
  WD2 = WD1 / TempSamples
  WD2 = WD1 - WD2
  Gemiddelde = WD2 + (TempSensor / TempSamples)


  ;Berekening zie FRIKI map deel 12
  SELECT Gemiddelde
  CASE > 56280                              ;>=270 C
    WD1 = 208
  CASE > 55080                              ;260 C...269 C
    WD1 = (Gemiddelde - 55080) / 240
    WD1 = 211 - WD1
  CASE > 53880                              ;250 C...259 C
    WD1 = (Gemiddelde - 53880) / 300
    WD1 = 215 - WD1
  CASE > 52500                              ;240 C...249 C
    WD1 = (Gemiddelde - 52500) / 460
    WD1 = 218 - WD1
  CASE > 47220                              ;220 C...239 C
    WD1 = (Gemiddelde - 47220) / 1320
    WD1 = WD1 + 214
  CASE > 40860                              ;200 C...219 C
    WD1 = (Gemiddelde - 40860) / 636
    WD1 = WD1 + 204
  CASE > 32160                              ;180 C...199 C
    WD1 = (Gemiddelde - 32160) / 334
    WD1 = WD1 + 178
  CASE > 23400                              ;160 C...179 C
    WD1 = (Gemiddelde - 23400) / 273 
    WD1 = WD1 + 146
  CASE > 17280                              ;140 C...159 C
    WD1 = (Gemiddelde - 17280) / 266
    WD1 = WD1 + 123
  CASE > 12000                              ;120 C...139 C
    WD1 = (Gemiddelde - 12000) / 229
    WD1 = WD1 + 100
  CASE > 8340                               ;100 C...119 C
    WD1 = (Gemiddelde -  8340) / 215
    WD1 = WD1 + 83
  CASE > 5760                               ; 80 C...99 C
    WD1 = (Gemiddelde -  5760) / 234
    WD1 = WD1 + 72
  CASE > 4020                               ; 60 C...79 C
    WD1 = (Gemiddelde -  4020) / 348
    WD1 = WD1 + 67
  CASE > 2940                               ; 40 C...59 C
    WD1 = (Gemiddelde -  2940) / 180
    WD1 =  73 - WD1
  CASE > 2220                               ; 25 C...39 C
    WD1 = (Gemiddelde -  2220) /  45
    WD1 =  88 - WD1
  CASE ELSE                                 ;<25 C
    WD1 =  88 
  END SELECT     
 
  Temperatuur = Gemiddelde / WD1
ENDSUB



;=============================
;===== INTERRUPTROUTINE ======
;=============================
InterruptAfhandeling:         ;
CONTEXT SAVE
;=========== UART ============
  IF RCIF = TRUE THEN         ;Als Receive USART, dan... (op UART zit de HMI aangesloten)
    Ontvangst1    = RCREG     ;'Ontvangst1' bevat de returncode van de Nextion HMI
    IF Ontvangst1 = 0x65 THEN                                         ;0x65 = Nextion HMI Touch Event
      HSERIN1 TimeOutTijd1, TimeOut1, [HMI_Page, HMI_CompID, HMI_Event]  ;Touch event

    ELSEIF Ontvangst1 = 0x66 THEN                                     ;0x66 = Nextion HMI Current Page Number
      HSERIN1 TimeOutTijd1, TimeOut1, [HMI_ActivePage]                ;Lees huidig pagina nummer (door instructie 'sendme' in HMI) (plaats in elk Nextion Preinitialize Event scherm de instructie 'sendme') (in PostInit van 'pgNumeric')
    ENDIF

    HSERIN1 TimeOutTijd1, TimeOut1, [Dump, Dump, Dump] ;De HMI zendt achter elk bericht "0xFF, 0xFF, 0xFF", dit kan richting vuilnisbak
   
TimeOut1:
    RCIF   = FALSE            ;Receive USART1 Interrupt Flag resetten
    RCSTA  = 0                ;\
    DELAYCS 4                 ;- Maak ontvangsbuffer 1 leeg
    RCSTA  = %10010000        ;/
  ENDIF



;========== TIMERS ===========
  IF TMR1IF = TRUE THEN       ;Als TMR1 een overflow heeft, dan...

;*** Prescaler 1:1 - 20MHz zonder PLL (1000 = 1 sec.)
   'TMR1H  = 236              ;\ Programma draait op 20MHz.  TMR1OSC is Fosc/4, dus dat is 20000 / 4 = 5000.  In 5000 klokslagen per seconde zitten 19 HIGHBYTES, dus dat is 255 - 19 = 236 voor TMR1H
   'TMR1L  = 119              ;/ De restwaarde wordt in TMR1L gezet, dus 5000 - (19 x 256) = 136.  Nog inverteren, dus dat is 255 - 136 = 119 voor TMR1L.  Zodoende staat 1000 gelijk voor 1 seconde (prescaler 1:1!)

;*** Prescaler 1:8 - 20MHz zonder PLL (10 = 1 sec.)
    TMR1H  = 10               ;- Deze waarden zorgen er (samen met de prescaler op 1:8) voor dat de timer 10x per seconde wordt verlaagd, dus 600 staat voor 60 seconden
    TMR1L  = 1                ;/
    TMR1IF = FALSE            ;Reset de TMR1 overflow flag
   
    ;TMR1 wordt elke 1/10e seconde afgehandeld (te gebruiken voor timing functies)
    IF BuzzerTimer  > 1 THEN DEC BuzzerTimer      ;Tijd die de buzzerpiep bepaalt
    IF SecondeTimer > 0 THEN DEC SecondeTimer     ;Creeert een seconde in het hoofdprogramma
    IF ToetsTimer   > 0 THEN DEC ToetsTimer       ;Tijd die vasthouden van een HMI toets bijhoudt (voor bijvoorbeeld het automatisch verhogen/verlagen van de thermostaat)
  ENDIF
CONTEXT RESTORE

Ohm sweet Ohm | www.picbasic.nl

Frizie

#6
How quickly you forget something, in the beginning I did not have a Bluetooth HC-05 module, but an ESP8266 (bottom right) on this print.
But I found it difficult to always have the smartphone activated when making PCBs, and the connection sometimes dropped out (perhaps because of the steel casing of the oven).
In addition, it was annoying that the app on the smartphone had to be updated after Android updates once in a while.
I am now happy with the built-in Nextion HMI.

Although the communication with the Nextion can be set to 115200 Baud, the oven works with a very low baud rate of 4800 Baud, and that works fine as can be seen in the Youtube video (I normally use 9600 Baud).
This is possible because I have already programmed the Dutch and English texts for the HMI in the Nextion.
So I only have to tell the Nextion which language it should display.

The PCB is not very extensive, a Meanwell 24V power supply, a 7805 voltage regulator, 24V relays and buzzer from the original microwave steering, an ULN2003 to control the relays, a (now unused) 3.3V power supply for the ESP8266, PIC18F242, etc.

-

At the top left you can still see the previous PLED display in the oven.
Ohm sweet Ohm | www.picbasic.nl