Sturing warmteverdeling met PWM in Bascom AVR met ATmega8

Ik zou met ATmega8 mijn warmte willen verdelen van mijn aardgascassette.
Het is de bedoeling om aan de cassette uitgangen waar de warme lucht uitkomt de temp te meten als deze hoog genoeg is mag de processor een ventilator inschakelen. Achter de ventilator zit terug een temp sensor (LM 35)die de temp meet en hoe warmer dat de lucht krijgt, hoe harder de ventilator mag draaien. Nu zit ik met drie zo een zone's die ik allemaal zou willen sturen met die ene processor. Ik ben een leek in programmeren en heb het gedaan in Bascom AVR. Het programma begint er (naar mijn bescheiden mening) al aardig op te gelijken tot één grote ergernis. Ik kan één zone laten lopen maar hoe kan ik nu overschakelen naar een volgende zone in mijn programma als ik met een lus werk? (Ik heb slechts het programma gemaakt voor één zone aangezien ik niet weet waar ik het programma voor zone2 en zone3 zou moeten zetten.
Bij deze stuur ik het programma mee.
De eerste adc meet de temp aan de cassette. De tweede aan de ventilator uitgang.

Kan mij iemand verder helpen?


$regfile = "m8def.dat"
$crystal = 1600000

'----------------------------config--------------------------------------------
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.0 , Rs = Portd.1
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down , Prescale = 1
Config Pind.4 = Output       'OC1B
Config Pind.5 = Output       'OC1A

'----------------------------Dim Zone1-----------------------------------------
Dim Zandloper As Word , Voeler0 As Word , Voeler1 As Word , Som As Word
Dim Berekening As Word , Zone1 As Word , Opstart As Word
Dim S As Word , Controle As Word , Relantie As Word



S = 1
Zandloper = 1
Voeler0 = 0
Voeler1 = 0

Compare1a = 1
Compare1b = 1

Start Timer1
Start Adc

'----------------------------Opstartscherm-------------------------------------
Cursor Off
Cls
Locate 1 , 1
Lcd "      Cassette      "
Locate 2 , 1
Lcd " ventilator sturing "
'Wait 3
Cls

Do

'----------------------------Opmeten Zone1-------------------------------------
Zone1:


      Waitms 10
      Cls
      Voeler0 = Getadc(0)
      'Waitms 100
      Voeler0 = Voeler0 / 10
      Locate 1 , 1
      Lcd "In" ; Voeler0 ; Chr(0) ;
      'Waitms 50

      Voeler1 = Getadc(1)
      'Waitms 100
      Voeler1 = Voeler1 / 10
      Locate 1 , 8
      Lcd "Out" ; Voeler1 ; Chr(0) ;
      'Waitms 50

'----------------------------Vergelijken voelers-------------------------------
If Voeler0 > 35 And S = 1 Then Goto Controle
If Voeler0 > 35 And Voeler1 < 30 Then Goto Relantie
If Voeler1 > 30 Then Goto Motor1
If Voeler1 <= 30 And Voeler1 >= 25 Then Goto Relantie
If Voeler1 < 25 Then Goto Motor0


'----------------------------Hoofdprogramma------------------------------------
Motor0:


       Compare1a = 1
       Compare1b = 1
       Berekening = 0
       Locate 1 , 15
       Lcd "PWM" ; "Uit" ;
       S = 1
       Goto Zone1


Motor1:


   Som = Voeler0 + Voeler1
   Berekening = Som * 5
   Berekening = Berekening + 50

       If Berekening > 900 Then
       Berekening = 1023
       Locate 1 , 15
       Lcd "PWM" ; "MAX" ;
       End If

       If Berekening =< 900 Then
       Locate 1 , 15
       Lcd "PWM" ; Berekening ;
       End If

   Compare1a = Berekening
   Compare1b = Berekening
   Goto Zone1

Controle:


       If S = 1 Then Gosub Opstart Else Gosub Relantie

Opstart:


       Berekening = 1023
       Locate 1 , 1
       Lcd "** Opstarten fan **"
'      Waitms 500
       S = 0

   Compare1a = Berekening
   Compare1b = Berekening

Relantie:


       Berekening = 250
       Locate 1 , 1
       Lcd " ** Relantie fan **"

   Compare1a = Berekening
   Compare1b = Berekening
   Goto Zone1


Loop

End

[Bericht gewijzigd door Henry S. op (0%)]

Zoiets misschien


do
	select case zone1
		case 0    'meten
			Waitms 10
			Cls
			Voeler0 = Getadc(0)
			'Waitms 100
			Voeler0 = Voeler0 / 10
			Locate 1 , 1
			Lcd "In" ; Voeler0 ; Chr(0) ;
			'Waitms 50
			Voeler1 = Getadc(1)
			'Waitms 100
			Voeler1 = Voeler1 / 10
			Locate 1 , 8
			Lcd "Out" ; Voeler1 ; Chr(0) ;
			'Waitms 50
			If Voeler0 > 35 then
				if  S = 1 Then
					zone1 = 3  
				else
					zone1 = 1
				end if 
			end if
			If Voeler0 > 35 And Voeler1 < 30 Then zone1 = 4    'Relantie
			If Voeler1 > 30 Then  zone1 = 2   'Motor1
			If Voeler1 <= 30 And Voeler1 >= 25 Then zone1 = 4  'Relantie
			If Voeler1 < 25 Then zone1 = 1   'Motor0
		case 1  'motor0
			Compare1a = 1
			Compare1b = 1
			Berekening = 0
			Locate 1 , 15
			Lcd "PWM" ; "Uit" ;
			S = 1
			zone1 =  0   'Meten
		case 2    'motor1
			Som = Voeler0 + Voeler1
			Berekening = Som * 5
			Berekening = Berekening + 50
			If Berekening > 900 Then
				Berekening = 1023
				Locate 1 , 15
				Lcd "PWM" ; "MAX" ;
			End If
			If Berekening =< 900 Then
				Locate 1 , 15
				Lcd "PWM" ; Berekening ;
			End If
			Compare1a = Berekening
			Compare1b = Berekening
			zone1 =  0  'Meten
		case 3     'Opstart
			Berekening = 1023
			Locate 1 , 1
			Lcd "** Opstarten fan **"
			' Waitms 500
			S = 0
			Compare1a = Berekening
			Compare1b = Berekening
		case 4     'Relantie
			Berekening = 250
			Locate 1 , 1
			Lcd " ** Relantie fan **"
			Compare1a = Berekening
			Compare1b = Berekening
			zone1 =  0  ' 'Meten
		end select
	select case zone2
		case 0 'meten
		case 1 'motor0
		case 3 'opstart
		case 4 'relantie
	end select
	select case zone3
	.
	.
	.
loop
	

Bedankt voor de reactie ElekTech. Hopelijk geraak ik nu verder.

Het werkt toch niet helemaal zoals het moet. Het is de bedoeling dat als de voeler0 meer is dan 35 graden EN S=1 dat dan naar case 3 gesprongen word. Dat moet om de ventilator op gang te krijgen (1/2 à 1seconde op vol vermogen) dan pas mag er verder gegaan worden met case4 tot 30graden. Ik heb al heel wat pogingen gedaan om het werkende te krijgen maar momenteel zonder resultaat.

[Bericht gewijzigd door Henry S. op (76%)]

Er zijn foutjes in mijn voorbeeld. Ik bekijk het opnieuw.

Dag Elektech


If Voeler0 > 35 then
        if  S = 1 Then
	   zone1 = 3  
	else
	   zone1 = 1
	end if 
end if
If Voeler0 > 35 And Voeler1 < 30 Then zone1 = 4    'Relantie
If Voeler1 > 30 Then  zone1 = 2   'Motor1
If Voeler1 <= 30 And Voeler1 >= 25 Then zone1 = 4  'Relantie
If Voeler1 < 25 Then zone1 = 1   'Motor0

Achter else zone1 = 1 loopt het fout.
zone1 = 1 moet waarschijnlijk zone1 = 4 worden
en dan ook if Voeler0 > 35 And Voeler1 < 30 ....

het programma slaat zone1 = 3 over

[Bericht gewijzigd door Henry S. op (2%)]


Do
 Select Case Zone1
  Case 0  'Meten
   'Waitms 10       'deze vertraging weg gedaan
   Cls
   Voeler0 = Getadc(0)
   'Waitms 100
   Voeler0 = Voeler0 / 10
   Locate 1 , 1
   Lcd "In" ; Voeler0 ; Chr(0) ;
   'Waitms 50
   Voeler1 = Getadc(1)
   'Waitms 100
   Voeler1 = Voeler1 / 10
   Locate 1 , 8
   Lcd "Out" ; Voeler1 ; Chr(0) ;
   'Waitms 50
   If Voeler0 > 35 And S = 1 Then Zone1 = 3       'Opstart
   If Voeler0 > 35 And Voeler1 < 30 Then Zone1 = 4       'Relantie
   If Voeler1 > 30 Then Zone1 = 2       'Motor1
   If Voeler1 <= 30 And Voeler1 >= 25 Then Zone1 = 4       'Relantie
   If Voeler1 < 25 Then Zone1 = 1       'Motor0
  Case 1  'motor0
   Compare1a = 1
   Compare1b = 1
   Berekening = 0
   Locate 1 , 15
   Lcd "PWM" ; "Uit" ;
   S = 1
   Zone1 = 0       'Meten
  Case 2  'motor1
   Som = Voeler0 + Voeler1
   Berekening = Som * 5
   Berekening = Berekening + 50
   If Berekening > 900 Then
    Berekening = 1023
    Locate 1 , 15
    Lcd "PWM" ; "MAX" ;
   End If
   If Berekening =< 900 Then
    Locate 1 , 15
    Lcd "PWM" ; Berekening ;
   End If
   Compare1a = Berekening
   Compare1b = Berekening
   Zone1 = 0       'Meten
  Case 3  'Opstart
   Berekening = 1023
   Locate 1 , 1
   Lcd "** Opstarten fan **"
   Compare1a = Berekening
   Compare1b = Berekening
   Incr Opstarttijd       ' tel het aantal do loop lussen
   If Opstarttijd = 500 Then       'na 500 lussen van 1ms is er 500ms voorbij
     Opstartarttijd = 0
     S = 0       'opstart is uitgevoerd
     Zone1 = 0       'meten
   End If
  Case 4  'Relantie
   Berekening = 250
   Locate 1 , 1
   Lcd " ** Relantie fan **"
   Compare1a = Berekening
   Compare1b = Berekening
   Zone1 = 0       'Meten
  End Select
 Select Case Zone2
  Case 0  'meten
  Case 1  'motor0
  Case 3  'opstart
  Case 4  'relantie
 End Select
 Select Case Zone3
  Case 0  'meten
  Case 1  'motor0
  Case 3  'opstart
  Case 4  'relantie
 End Select
 .
 .
 .
 Waitms 1 'zorgt ervoor dat de lus ongeveer 1ms duurt, is nauwkeurig genoeg voor dit project
          'er mogen dan wel geen andere Waitms in de do loop lus staan
Loop



Het probleem is nog altijd hetzelfde. Ook ik had het al op die manier geprobeerd. Het programma klopt (zelfs je vorige) zolang Voeler1 méér is dan 25graden. Maar als Voeler1 minder is dan 25graden dan blijft enkel case0 en case1 lopen. (Het programma geraakt ook niet verder door het laatste "If" commando)

Wat dus mijn bedoeling is:
STAP1) Het programma begint zijn lus case0 een meet de temperatuur van Voeler0. Zolang Voeler0 < is dan 25 graden wordt er terug naar case1 gesprongen en vind daarop een nieuwe meting case0 plaats.
STAP2) Als Voeler0 warmer is dan 35 graden EN 'S = 1' dan moet er naar case3 gesprongen worden.
**** !!!
STAP3) De ventilator moet 500ms vol vermogen draaien als hij niet eerder draaide. Dat is om 'op gang' te komen (vol vermogen). Daarna komt 'S' van toestand 1 naar toestand 0.
STAP4) Vanaf die moment (dus na éénmaal Case3 doornomen te hebben moet de ventilator in 'relantie' case4 mode draaien totdat Voeler1 een temp heeft van 30graden.
STAP5) Als de Voeler1 méér is dan 30graden dan werkt de ventilator in 'berekening' case2 mode.
STAP6) Als de cassette niet meer verwarmt (en er dus na een tijdje ook niet meer voldoende warmte van de mantel kan onttrokken worden) moet de ventilator terug in 'relantie' case4 mode gaan zolang Voeler1 tussen de 30graden en de 25graden is.
STAP6) Als de temperatuur van voeler1 < is dan 25graden gaat de ventilator 'uit' case1. Op dit moment gaat ook 'S' terug van toestand 0 naar toestand 1 om in een later stadium de ventilator terug 500ms op vol vermogen te laten draaien.

*****Mijn probleem zit hem waar de sterretjes staan.
Ook de andere 'IF - Then' commando's worden gelezen en het laatste commando is 'als Voeler1 < 25 dan moet de ventilator uit' !!!! Op die manier kan er NOOIT naar case3 gesprongen worden want Voeler1 is kouder dan 25 graden bij een eerste opstart.

Hopelijk begrijp je mijn uiteen doening en kan je mij alsnog verder helpen.

Ik heb in jou oorspronkelijk programma in het deel ---Vergelijken voelers--- de goto's weg gedaan en vervangen door Zone1 = ...
Door die wijziging loopt het programma anders.
Na het uitvoeren van de code waarnaar de Goto verwijst komt het programma terug op de plaats na de Goto. Zonder de Goto gaat het programma ook naar de volgende regel naar nu is er niets extra's uitgevoerd en telt de laatste If Them die waar is. Waarschijnlijk gaat het hierdoor fout.Ik bekijk het opnieuw.

edit:
STAP1) Het programma begint zijn lus case0 een meet de temperatuur van Voeler0. Zolang Voeler0 < is dan 25 graden wordt er terug naar case1 gesprongen en vind daarop een nieuwe meting case0 plaats.
Dit is de eerste keer dat ik "Voeler0 < is dan 25 graden" zie.

edit2:
"Voeler0 < is dan 25 graden" is een typfoutje denk ik.

Vervang in mijn laatste code


If Voeler0 > 35 And S = 1 Then Zone1 = 3       'Opstart
If Voeler0 > 35 And Voeler1 < 30 Then Zone1 = 4       'Relantie
If Voeler1 > 30 Then Zone1 = 2       'Motor1
If Voeler1 <= 30 And Voeler1 >= 25 Then Zone1 = 4       'Relantie
If Voeler1 < 25 Then Zone1 = 1       'Motor0

door dit


If Voeler1 < 25 Then Zone1 = 1       'Motor0
If S = 1 Then 
	If  Voeler0 > 35  Then Zone1 = 3       'Opstart
Else
	If Voeler0 > 35 And Voeler1 < 30 Then Zone1 = 4       'Relantie   
	If Voeler1 <= 30 And Voeler1 >= 25 Then Zone1 = 4       'Relantie
	If Voeler1 > 30 Then Zone1 = 2       'Motor1
End if

[Bericht gewijzigd door Henry S. op (29%)]

Ik zie weinig reactie van je, dus of je zit vast, geen tijd of het werkt.
Maar, ik wil ook een poging doen. Ik weet echter niets van ATMega en bascom.

Als ik het goed begrijp heeft je aardgas cassette 3 uitgangen met ieder een ventilator blazend naar ieder een eigen zone. Ieder uitgang heeft een temp sensor en achter iedere ventilator zit ook een sensor.

Waarom 'Compare1a' en 'Compare1b' ? Heb het nergens kunnen vinden. Oké, heb 1 minuut gebingt maar kon alleen 'Compare1a' vinden.

Vraagje tussendoor, is het echt nodig dat van binnen in de cassette bij iedere uitgang ook een interne sensor zit, of mag het ook 1 interne sensor zijn? Tenslotte zal die cassette binnenin overal praktisch gelijke temperatuur hebben. Ik heb jier gekozen voor een interne sensor.

Je weet ook zeker dat je benaming voeler0, de voeler is die binnen zit?
Je kan de eisen van wanneer wat er moet gebeuren tuurlijk aanpassen. Maar ik denk dat je de fan's niet wilt laten draaien als de cassette niet warmer is dan de zones.

hier mijn poging om met drie zones te werken.
Heb ook de benaming wat aangepast. Het is alleen getypt en NIET getest. Je zal zelf de BasCom taalfouten eruit moeten vissen. Weet niet of chr$(0) nodig is?

De stappen gedachte


Init de waarden
lcd info
start:
  doe per zone {
    meet waarden
    voorwaarden test
    setup status
    }
  voer statussen uit
  lcd data
ga naar start


' hier jouw init code e.t.c

'declare sub's
Declare Sub StatusToActionsSetup()
Declare Sub ZoneExecution()
Declare Sub LCDShowInfo()
Declare Sub LCDShowData

Dim vers as String*4
Dim datum as String*8
vers = "V0.1"
datum = "Nov 2013"

'status
Const HALT = 0 
Const STARTUP = 1
Const REL = 2
Const RUN = 3
Dim statusVent as Integer
statusVent = HALT            ' motor uit bij opstarten programma

'
Const ZONES = 3

Dim StatusFan[ZONES] as String*4
Dim VentilatorM[ZONES] as Word
Dim ZoneVentCurRuntime(ZONES) As Integer
ZoneVentMaxTime = 200       ' Aantal loops om op te starten. kan een timer worden.
ZoneVentCurRuntime[1] = 0   ' opstart loops
ZoneVentCurRuntime[2] = 0
ZoneVentCurRuntime[3] = 0



'showInfo:
Call LCDShowInfo()
Waitms 5000

Do
'Meten:
    InterneTempVoeler = getADC(0)/10
    ZoneTempVoeler[1] = getADC(1)/10
    ZoneTempVoeler[2] = getADC(2)/10
    ZoneTempVoeler[3] = getADC(3)/10

'ZoneActionsSetup:
  For zone = 1 to ZONES
    If InterneTempVoeler > ZoneTempVoeler[zone] Then ' denk dat je wilt dat er warme lucht geblazen wordt
        If  InterneTempVoeler <= 35 Then
            If ZoneTempVoeler[zone] < 25 
                statusVent = HALT
            Else If ZoneTempVoeler[zone] <= 30 Then
                statusVent = REL
            Else
                statusVent = RUN
            End If
        Else
            If VentilatorM[zone] > HALT ' Ventilator is draaiend
                If statusVent = STARTUP Then
                    Incr  ZoneVentCurRuntime[Zone]
                    If ZoneVentCurRuntime[Zone] > ZoneVentMaxTime ' e.v.t. als timer opzetten
                        statusVent = REL
                        ZoneVentCurRuntime[Zone] = 0
                    End If
                End If
            End If
            If statusVent = HALT
                statusVent = STARTUP
            End If
        End If
    Else
        statusVent = HALT ' als cassette temp gelijk of lager is aan uitgang dan ventilator uit.
    EndIf
    Call StatusToActionsSetup()
  Next
  Call ZoneExecution()
  Call LCDShowData()
Loop
' komt nooit hier

Sub StatusToActionsSetup
Const PWM_HALT = 1
Const PWM_MAX = 1023
Const PWM_REL = 250
Const PWM_VAR = 0

Select Case statusVent
    Case HALT  'Stop
        VentilatorM[zone] = PWM_HALT
        StatusFan[zone] = "Uit"

    Case STARTUP  'Fast Start
        VentilatorM[zone] = PWM_MAX
        StatusFan[zone] = "Start"

    Case REL  'Relantie
        VentilatorM[zone] = PWM_REL
        StatusFan[zone] = "Rel"

    Case RUN  'Run
        PWM_VAR = ( InterneTempVoeler + ZoneTempVoeler[zone] ) * 5  + 50
        If PWM_VAR > 900 Then
            VentilatorM[zone] = PWM_MAX
        Else
            VentilatorM[zone] = PWM_VAR
        End If
        StatusFan[zone] = Str(VentilatorM[zone]) 
        
    End Select
End Sub


' sub ZoneExecution
' voer de acties uit per zone
Sub ZoneExecution
    Compare1a = VentilatorM[1]
    Compare1b = VentilatorM[1]

    Compare2a = VentilatorM[2]
    Compare2b = VentilatorM[2]

    Compare3a = VentilatorM[3]
    Compare3b = VentilatorM[3]
End Sub


'LCD 20 Char 4Rows
'12345678901234567890
'Tin xx. Tuit PWM-FAN
'Zone 1   xx     run
'Zone 2   xx     uit
'Zone 3   xx     max

'Zone 2   xx     xxx

Sub LCDShowData:
    Locate 1,1
    Lcd "Tin "; ZoneVentMaxTime
    Locate 1,9
    Lcd "Tuit PWM-FAN"

    for zoneRow = 1 to ZONES
        ' print zone
        rowTxt = "Zone " ; zoneRow ;
        Locate zoneRow+1,1
        Lcd rowTxt ; chr$(0);
        
        ' print temp out value
        rowTxt = ZoneTempVoeler[zoneRow]; chr$(0);
        Locate zoneRow+1, (12 - len(rowTxt))
        Lcd rowTxt ; chr$(0);
        
        ' print fan status
        rowTxt = StatusFan[zoneRow]; chr$(0); ' moet chr$(0) erachter?
        Locate zoneRow+1, ( 21 - len(rowTxt))
        Lcd rowTxt ; chr$(0);
    next
End Sub


'LCD 20 Char 4Rows
'12345678901234567890
'--------------------
'     Cassette       
' Ventilator sturing 
'  V0.1  - Nov 2013  

Sub LCDShowInfo:
    Locate 1,1
    Lcd "--------------------";
    Locate 2,6
    Lcd "Cassette"
    Locate 3,2
    Lcd "Ventilator sturing"
    Locate 4,3
    Lcd vers ;
    Locate 4,3
    Lcd "- "; datum;
End Sub

Dag Lord Anubis. Ik was er idd even niet meer mee bezig.
Nu werkt mijn volledige 'simulatie' van het project met BasCom AVR en kan ik overgaan naar de volgende stap... het aanschaffen van de componenten.
Hopelijk werkt het in real life want simulatie en echt... nog altijd een verschil. Ik ben niet helemaal zeker van de PWM uitgangen die naar de stuurtransistoren zullen gaan maar dat zie ik dan wel. Mocht het nodig zijn dan post ik het project nogmaals om eventuele commentaar, suggesties of om iemand op gang te helpen. Ik moet zeker ElekTech bedanken en daar ben ik niet te bescheiden om want zonder hem had het mij waarschijnlijk niet gelukt. Nogmaals dank ElekTech.