[atmega8][bascom avr] Regulator temperatury z DS18B20 i PWM

Miejsce dobre do dyskusji nad własnymi projektami - pochwal się wszystkim co samodzielnie stworzyłeś.
ODPOWIEDZ
Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

[atmega8][bascom avr] Regulator temperatury z DS18B20 i PWM

Post autor: Pikczu » 13 lip 2010, 22:02

Witam
Właśnie ukończyłem regulator obrotów wentylatorów do zasilacza laboratoryjnego
Matrix MPS3005l-3.

Zasilacz w wersji standardowej ma wbudowane 2 wentylatory które są niestety bardzo głośne.
Hałas staje się uciążliwy przy dłuższej pracy zasilacza.
Aby zredukować hałas najprostrzą metodą było obniżenie obrotów wentylatorów i sterowanie nimi w zależności od wartości temperatury zasilacza.
Serce układu stanowi Atmega8 w obudowie SMD tqfp32
Do pomiaru temperatury użyłem trzech termometrów 1-wire DS18B20.
Dwa z trzech czujników temperatury, umieszczone są na tylnim radiatorze który jest podzielony na dwie niezależne części z jednym wspólnym wentylatorem.
Trzeci czujnik mierzy temperature transforamtora.
Ukałd posiada dwa tryby pracy :
Automatyczny – prędkość wentylatorów zależna jest od temperatury zmierzonej przez DS-y
Ręczny –(sterowanie przez rs232) pozwala na ustawienie prędkości wentylatorów przez wpisanie wartości PWM w oknie terminala .
Płytka dwustronna została zaprojektowana w całości w Kicadzie, i wykonana metoda termo transferu w większości użyłem elementów SMD.
Kod napisany w całości w Bascom AVR .

Kod: Zaznacz cały

'$sim
'*******************************************************************************
 '------------------------------ATmega8-----------------------------------------
'------------------------------3xDS18b20----------------------------------------
'--------------------------2x PWM controlled FAN--------------------------------
'-------------------------- UART controlled ------------------------------------
'-------------------------Auto and manual mode----------------------------------
'-----------------------------Version: 2.0--------------------------------------
'-------------------------- Flash used 66%--------------------------------------
'------------------------By Pawel L. aka Pikczu---------------------------------
'--------------------------------2010-------------------------------------------
'*******************************************************************************
'DALLAS DS18B20 ROM and scratchpad commands''''''''''''''''''''''''''
'1wwrite....
'&H 33 read rom - single sensor
'&H 55 match rom, followed by 64 bits
'&H CC  skip rom
'&H EC  alarm search  - ongoining alarm >TH <TL
'&H BE  read scratchpad
'&H 44  convert T
'*******************************************************************************
'*******************************************************************************

$prog &HFF , &H3F , &HD9 , &H00                             ' generated. Take care that the chip supports all fuse bytes.
$regfile = "m8def.DAT"                                      'uc type
$crystal = 11059200                                         'crystal frequency
$baud = 9600
Config Serialin = Buffered , Size = 20
'Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Portd.1 = Output                                     'TX
Config Portd.0 = Input                                      'RX

Config Portd.6 = Input                                      'PUSHBUTTON
Portd.6 = 1                                                 'PULL UP
Config 1wire = Portd.2                                      '1Wire
Config Portd.7 = Output                                     'BUZZER
Portd.7 = 0                                                 'initial status
Config Portb.0 = Output                                     'STATUS LED
Portb.0 = 0                                                 'initial status
Config Portb.1 = Output                                     'oc1a
Config Portb.2 = Output                                     'oc1b

'*******************************************************************************
'****************************Variables*****************************************
Dim B As Byte                                               'beep
Dim Index As Byte                                           'index
Dim Ile As Byte                                             'How many ds sensor found on 1 wire bus
Dim I1(2) As Byte                                           'Array for 2 bytes read from DS sensor
Dim I2(2) As Byte                                           'Array for 2 bytes read from DS sensor
Dim I3(2) As Byte                                           'Array for 2 bytes read from DS sensor
Dim Dsx(8) As Byte                                          'Array for 8 bytes read from DS during registration
Dim Ds1(8) As Byte                                          'Array for 8 bytes from Ds 1
Dim Eds1(8)as Eram Byte At &H10                             'Space in eeprom  to write 1 ds data
Dim Ds2(8) As Byte                                          'Array for 8 bytes from Ds 2
Dim Eds2(8) As Eram Byte At &H20                            'Space in eeprom  to write  2 ds data
Dim Ds3(8) As Byte                                          'Array for 8 bytes from Ds 3
Dim Eds3(8) As Eram Byte At &H30                            'Space in eeprom  to write 3 ds data
Dim Ds_y As Byte                                            'used just for registering ds
Dim Temp1 As Integer                                        'variable to keep value temp1
Dim Temp_1 As Byte
Dim Temp2 As Integer                                        'variable to keep value temp2
Dim Temp_2 As Byte
Dim Temp3 As Integer                                        'variable to keep value temp3
Dim Temp_3 As Byte
Dim T_array(2) As Byte                                      'master and slave temperature array
Dim T_a_m As Byte                                           'Temp array max value
Dim Speed1 As Byte                                          'PWM variable
Dim Speed2 As Byte                                          'PWM variable
Dim Mod_e As Bit                                            'variable for auto/manual mode
Dim Czas As Word                                            'variable for counting time
Dim Czas2 As Byte                                           'variable counting time for flash and beep
Dim H1 As Byte                                              'variable
Dim H2 As Byte                                              'variable
Dim Flag0 As Bit                                            'Flag for timer 0
Dim Flag1 As Bit                                            'flag
Dim Flag2 As Bit                                            'flag temp changed
Dim Serial_flag As Byte                                     'flag set if char received from serial
Dim Y As Single
Dim Z As Single


'*******************************************************************************
'*******************************************************************************
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Enable Interrupts
Enable Oc1a
Enable Oc1b
Config Timer0 = Timer , Prescale = 1024
Config Timer2 = Timer , Async = Off , Prescale = 1024
On Timer2 Timer2_isr                                        'interrupt timer2 for  flash and beep

'*******************************************************************************
'*******************************************************************************
Wait 1
Print "Restart"
Wait 1

Debounce Pind.6 , 0 , Zapisz , Sub                          'register DS sensors
Wait 1                                                      '
Ile = 1wirecount()                                          'ile czujnków w ukladzie
Wait 1                                                      'short delay                                             '
Enable Timer2
Flag1 = 0                                                   'flag set to 0 just in case
For B = 1 To Ile                                            'now depend how many sensors flash and beep
Start Timer2                                                'now start timer2 just to count delay time
Gosub Flash                                                 'jump to flash
Gosub Beep                                                  'jump to beep
Bitwait Flag1 , Set                                         'if flag set timer2 counted delay (line 318)
Czas2 = 0                                                   'reset czas2

Next B
Stop Timer2                                                 'now stop timer2
     Czas2 = 0                                              'reset czas2 variable
Disable Timer2
'*************************Read from Eeprom *************************************
'*******************************************************************************
For Index = 1 To 8
    Ds1(index) = Eds1(index)                                'read numbers from eeprom for ds sensors after power up
    Ds2(index) = Eds2(index)                                'read numbers from eeprom for ds sensors after power up
    Ds3(index) = Eds3(index)                                'read numbers from eeprom for ds sensors after power up
Next Index
     Index = 0
'*******************************************************************************
'After power Up first reading will be 85 degrees, is necessarily to convert temp
'*************konwersja temp dla wszystkich dsow********************************
1wreset
1wwrite &HCC                                                'skip all
1wwrite &H44
'*******************************************************************************
'*******************************************************************************
Pwm1a = 255                                                 'set fan speed to max just to test it
Pwm1b = 255                                                 'set fan speed to max just to test it
Wait 2
Pwm1a = 0
Pwm1b = 0




'***************************Ustawienie Timera0**********************************
Load Timer0 , 216
On Ovf0 Timer0_isr
Enable Timer0
'*******************************************************************************
'****************************Poczatek Petli*************************************
Czas = 0
Do

If Czas >= 100 Then

   Disable Timer0

   1wreset
   1wwrite &H55
   1wwrite Ds1(1) , 8                                       'sending address of first ds sensor
   1wwrite &HBE
   I1(1) = 1wread(2)


   1wreset
   1wwrite &H55
   1wwrite Ds2(1) , 8                                       'sending address of second ds sensor
   1wwrite &HBE
   I2(1) = 1wread(2)

   1wreset
   1wwrite &H55
  1wwrite Ds3(1) , 8                                        'sending address of third ds sensor
   1wwrite &HBE
   I3(1) = 1wread(2)


   Temp1 = I1(2)                                            'Most significant byte of temp
   Shift Temp1 , Left , 8                                   'shift left
   Temp1 = Temp1 + I1(1)
   Shift Temp1 , Right , 4

   Temp2 = I2(2)                                            'Most significant byte of temp
   Shift Temp2 , Left , 8                                   'shift left
   Temp2 = Temp2 + I2(1)
   Shift Temp2 , Right , 4

   Temp3 = I3(2)                                            'Most significant byte of temp
   Shift Temp3 , Left , 8                                   'shift left
   Temp3 = Temp3 + I3(1)
   Shift Temp3 , Right , 4
'  ****konwersja temp dla wszystkich dsow**

   1wreset
   1wwrite &HCC                                             'skip all
   1wwrite &H44

   Czas = 0
   Enable Timer0                                            'all DS do covert T
   Gosub Flash
End If                                                      'end if czas>=100 odczyt temperatury z ds

If Temp_1 <> Temp1 Or Temp_2 <> Temp2 Or Temp_3 <> Temp3 Then
Temp_1 = Temp1
T_array(1) = Temp1
       Temp_2 = Temp2
       T_array(2) = Temp2
          Temp_3 = Temp3
                 Print "Master T= " ; Temp_2 ; "C " ; "Slave T= " ; Temp_1 ; "C " ; "Trafo T= " ; Temp_3 ; "C"
Set Flag2
End If



If Mod_e = 0 Then                                           'mode = Auto

         If Flag2 = 1 Then                                  'if flag2 =1 new temperature value
         T_a_m = Max(t_array(1))                            'pick up from array max value of temp
         Y = 8.75 * T_a_m                                   ' do maths
         Y = Y - 182.5
        ' Speed1 = Abs(y)
          Speed1 = Y
                 If T_a_m <= 30 Then                        'if temperature array max value smaller than 30 then
                 Speed1 = 0                                 'fan speed = 0
                 End If                                     '
                     If T_a_m >= 50 Then                    'if temperature array max value greater or equal 50 then
                        Speed1 = 255
                     End If
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          Z = 7 * Temp_3                                    'same as above but just for small fan and internal temp value
         Z = Z - 95
          Speed2 = Z
          If Temp_3 <= 25 Then
          Speed2 = 0
          End If
              If Temp_3 >= 50 Then
                 Speed2 = 255
              End If

         Print "Radiator Fan=" ; Speed1

         Print "Case Fan=" ; Speed2
         Reset Flag2
         Pwm1a = Speed1
         Pwm1b = Speed2
         End If
'Pwm1a = Speed1
'Pwm1b = Speed2
End If


Serial_flag = Ischarwaiting()                               'if some char in buffer then set serialflag

If Serial_flag = 1 Then                                     '
   Index = Inkey()                                          'copy char from buffer to index
         If Index = 097 Or Index = 065 Then                 ' if char = a or A
            Print "MODE:"auto ""                            'print in terminal window mode was change to auto
            Temp_1 = Temp1
            Temp_2 = Temp2
            Temp_3 = Temp3
            Print "Slave T= " ; Temp_1 ; "C " ; "Master T= " ; Temp_2 ; "C " ; "Internal T= " ; Temp_3 ; "C"
           Reset Mod_e                                      'set mode flag to 0
           Set Flag2
         End If

             If Index = 109 Or Index = 077 Then
             Print "MODE:"manual ""
             Set Mod_e
             Temp_1 = Temp1
             Temp_2 = Temp2
             Temp_3 = Temp3
             Print "Slave T= " ; Temp_1 ; "C " ; "Master T= " ; Temp_2 ; "C " ; "Internal T= " ; Temp_3 ; "C"
             Input "Input Speed value for radiator Fan=" , Speed1

             If Speed1 < 80 Then
             Speed1 = 0
             End If
             If Speed1 > 255 Then
             Speed1 = 255
             End If
                Pwm1a = Speed1
                Input "Input Speed Value for Case Fan=" , Speed2
                 If Speed2 < 80 Then
             Speed2 = 0
             End If
             If Speed2 >= 255 Then
             Speed2 = 255
             End If
                      Pwm1b = Speed2

             End If
Clear Serialin
End If

Enable Timer0
Loop

End
'*******************************************************************************
'*****************************SUBS**********************************************
'*******************************************************************************

Timer0_isr:
Load Timer0 , 216                                           'co Xms
Incr Czas
If Czas >= 100 Then
Set Flag0
Else
Reset Flag0
End If
Return

'******************************Timer2_isr:**************************************
'*******************************************************************************
Timer2_isr:
Load Timer2 , 255
Incr Czas2
If Czas2 = 4 Then                                           'Acive
         Reset Portb.0
               Reset Portd.7
End If

If Czas2 >= 16 Then                                         'not active
   Flag1 = 1
End If

Return

'**********************************FlashBeep************************************
'*******************************************************************************

Fb:                                                         'Flash beep
Enable Timer2

Flag1 = 0                                                   'reset flag
Toggle Portd.7                                              'change to opposite level
Toggle Portb.0                                              'change to opposite level
Bitwait Flag1 , Set                                         'wait for confirmation bit from timer2
Czas2 = 0                                                   'set to 0 time counted by timer2

Return
'********************************BEEP*******************************************
'*******************************************************************************
Beep:
Flag1 = 0
Toggle Portd.7
Return
'********************************FLASH******************************************
'*******************************************************************************
Flash:
Flag1 = 0
Toggle Portb.0

Return
'********************************ZAPISZ*****************************************
'*******************************************************************************
Zapisz:
Czas = 0                                                    'wyzerownaie licznika czasu od timera0
Gosub Fb                                                    'skocz do flash beep
Print "Rejstracja"                                          '  wyswietla w terminalu
Disable Interrupts                                          'wylacz przerwania
Ds_y = 0                                                    'wyzeroj zmienna ilosc czojnikow ds

Do                                                          'poczatek petli rejstracyjnej
Dsx(1) = 1wsearchfirst()                                    'szukaj ds na magistrali
If Err = 0 Then                                             'jesli znalazl ds-a
   Incr Ds_y                                                'zwieksz ds_y o 1
        Select Case Ds_y:                                   'w zaleznosci ktory to ds
   Case 1:                                                  'pierwszy ds
     For Index = 1 To 8                                     'zapisz jego dane do eeprom
     Eds1(index) = Dsx(index)
     Next Index                                             'i tak 8 razy
     Print "Registered DS1 as Master "                      'no i potwierdz
           Enable Interrupts                                'wlacz przerwania
           Gosub Fb                                         'skocz do flash beep
           Disable Timer2                                   'juz po to wylacz tiemr 2
           Enable Timer0                                    'Wlacz timer0
        Bitwait Flag0 , Set                                 'czekaj na flage od timera 0
        Disable Timer0                                      'wy³acz timer0
       Disable Interrupts                                   'wylacz przerwania
   Czas = 0                                                 'wyzerownaie licznika czasu od timera0
   Case 2:                                                  'dla ds-a 2
     For Index = 1 To 8                                     'zapisz jego dane do eeprom
     Eds2(index) = Dsx(index)
     Next Index                                             'i tak 8 razy
     Print "Registered DS2 as Slave "
           Enable Interrupts                                'wlacz przerwania
           Gosub Fb                                         'skocz do flash beep
           Gosub Fb                                         'skocz do flash beep
           Disable Timer2                                   'juz po to wylacz timer 2
           Enable Timer0
        Bitwait Flag0 , Set                                 'czekaj na flage od timera 0
        Disable Timer0                                      'wylacz timer0
        Disable Interrupts                                  'wylacz przerwania
        Czas = 0                                            'wyzerownaie licznika czasu od timera0
  Case 3:                                                   'dla ds-a 3
     For Index = 1 To 8                                     'zapisz jego dane do eeprom
     Eds3(index) = Dsx(index)
     Next Index                                             'i tak 8 razy
     Print "Registered DS3 as internal  "                   'no i potwierdz
           Enable Interrupts                                'wlacz przerwania
           Gosub Fb                                         'skocz do flash beep
           Gosub Fb                                         'skocz do flash beep
           Gosub Fb                                         'skocz do flash beep
           Disable Timer2
           Enable Timer0                                    'juz po to wylacz timer 2
           Bitwait Flag0 , Set                              'czaekja na flage od timera 0
           Disable Timer0                                   'wylacz timer0
           Disable Interrupts                               'wylacz przerwania
            Czas = 0                                        'wyzerownaie licznika czasu od timera0
   End Select                                               'koniec wyboru ds-ow
End If                                                      'koniec warunklu
Loop Until Ds_y = 3                                         'koniec petli do 3-ech
Enable Interrupts                                           'wlacz przerwania
Return                                                      'powrot
'*******************************************************************************
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'Y = 8.75 * X -182.5    range from 30 up to 50 degree
'y=predkosc
'x= temp

'Y = 7 * x-95   range from 25 up to 50

'******************************************************************************

Obrazek
Obrazek
Obrazek
Obrazek
Obrazek


Pozdrawiam Pikczu
Ps: Dla zainteresowanych plik bas i bin etc.
------------------------------------Edit--- 8.08.2010-------------------------------------------------
Ps: Poprawiłem błędy w kometarzach.
W samym sofcie nic się nie zmieniło.
Załączniki
TERMOMETR V2.rar
(22.7 KiB) Pobrany 1017 razy
matrix.jpg
Ostatnio zmieniony 08 sie 2010, 11:34 przez Pikczu, łącznie zmieniany 11 razy.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 13 lip 2010, 22:20

wreszcie skończyłeś. gratuluję jak diabli. jeśli znajdę fundusze to nieomieszkam wykonać.
Pikczu pisze:Ps: Dla zainteresowanych próbowałem dodać plik bas i bin ale niestety nie mogę dodać takiego załącznika na forum.
zazipuj i bez kłopotu wejdzie. pozdrawiam.
Piotr.

ODPOWIEDZ