Well, it took time to put into practice your suggestions and advice.
Now the breadboard is a new one, wiring is improved, and more
important, the reason that seemed to be the cause of the problem,
which is programming CKOPT, is done. The result: The same
malfunction and unstability!
Am sure noise is not responisble this time. CKopt=0 (though am using
internal RC osc!, so does CKopt matter?), and for more stability, osc
lowered to 2MHz . Tried two MCUs of the same type, and got the same
result, so what remains is the code.
Here are the complete codes. There are many mathematical
calculations, functions and sub-programs, but probably what is
important to notice is the interfere of different interrupts activated
and used in this program. Watchdog is not responsible, for I added it
after I faced the malfunction. Hey maybe it is a 'mad MCU disease'? :-)
My guess (am not sure though) is that somewhere, sometime, two
interrupt happens one in another and this cause failure. But where and
when? And How to fix the problem. Any idea?
TNX
Behrooz Hariri
'------------------------------------------------------------------------------------------------------------
$regfile = "m16def.dat" '"m128def.dat"
' BASCOM version 1.11.7.4
$crystal = 2000000
Config Lcd = 20 * 4
Config Lcdpin = Pin , Rs = Portc.2 , E = Portc.3 , Db4 = Portc.4 , Db5
= Portc.5 , Db6 = Portc.0 , Db7 = Portc.1
Config Timer1 = Timer , Prescale = 64 'every 1
sec elaps
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Config Watchdog = 256 '1024
Config Pinb.0 = Input
Config Pina.7 = Input
Vclose_pinp Alias Pina.7
Config Pina.4 = Input
Vopen_pinp Alias Pina.4
Config Pina.5 = Output
Vopen_pout Alias Porta.5
Config Pina.6 = Output
Vclose_pout Alias Porta.6
Config Pind.7 = Output 'Alarm
Alarm_pout Alias Portd.7
Config Pind.5 = Output 'Fogger
Fogger_pout Alias Portd.5
Config Pind.6 = Output 'Alarm
Heater_pout Alias Portd.6
Declare Sub Key1
Dim Done_before As Bit
Dim Light_level As Bit
Dim Max_temp As Single '
'Byte
Dim Min_temp As Single 'Byte
Dim Max_day As Single 'Byte
Dim Min_day As Single 'As Byte
Dim Max_night As Single 'As Byte
Dim Min_night As Single 'As Byte
Dim Time_first As Single 'as integer
Dim Time_next As Single
Dim Temp_first As Single 'Byte
Dim Curr_temp As Single
Dim Curr_rh As Single
Dim Time_now As Single
Dim Stepcnt As Byte
Dim Step_temp As Single
Dim Diff As Single
Dim Init As Bit
Dim Gen_int1 As Integer
Dim Gen_int2 As Integer
Dim Gen_byte1 As Byte
Dim Gen_sing1 As Single
Dim Gen_sing2 As Single
Dim Gen_sing3 As Single
Dim R0 As Single
Dim Lux As Single
Dim Luxfinal As Single
Dim I(20) As Integer
Dim Setdata As Byte
Dim Set_alarm As Bit
Dim Time_alarm As Long
Dim Time_alarm_got As Bit
Dim Endurance As Integer
Dim Algorithm_period As Integer
Dim Last_light As Bit
Dim Elapsed As Long
Dim F_ini As Bit
Dim F_run As Bit
Dim F_out_next As Long
Dim F_in_next As Long
Dim F_in_duration As Long
Dim F_out_duration As Long
Dim H_ini As Bit
Dim H_run As Bit
Dim H_out_next As Long
Dim Set1 As Byte
Done_before = 0
Time_first = -1
Time_alarm_got = 0
Init = 0
Light_level = 0
F_run = 0
F_ini = 0
F_out_next = 0
F_in_next = 0
Set1 = 1
Timer1 = 34286
Enable Interrupts
Enable Timer1
Enable Ovf1
On Ovf1 Elaps
Enable Adc
Start Adc
Cursor Off
Cls
Gosub User_data
Max_day = I(1)
Min_day = I(2)
Max_night = I(3)
Min_night = I(4)
Endurance = I(16)
Algorithm_period = I(17)
F_in_duration = I(18)
F_out_duration = I(19)
Do
Debounce Pinb.0 , 0 , Key1 , Sub
Gosub Read_light
Gosub Read_temp
Gosub Ramp_detect
Gosub Read_rh
Gosub Show_lcd
Gosub Main_decision
Gosub Alarm
Gosub Fogger_pulse
Gosub Heater_pulse
Reset Watchdog
Loop
End
Main_decision:
If Curr_temp < Min_temp Then
Gen_sing1 = I(10) 'I(10)Cold
Alarm
If Curr_temp <= Gen_sing1 Then Set_alarm = 1
Gosub Heating
Elseif Curr_temp >= Max_temp Then
Gen_sing1 = I(9) 'I(9)Hot Alarm
If Curr_temp >= Gen_sing1 Then Set_alarm = 1
Gosub Cooling
Else
Gosub Normal
End If
Return
'---------------------------------------------------
Open_nudge:
Stop Watchdog
Reset Vopen_pout
Reset Vclose_pout
Wait 1 ' 3 in real
Set Vopen_pout
Wait Endurance
Reset Vopen_pout
Wait 1 ' 2 in real
Start Watchdog
Return
'---------------------------------------------------
Close_nudge:
Stop Watchdog
Reset Vopen_pout
Reset Vclose_pout
Wait 1 ' 3 in real
Set Vclose_pout
Wait Endurance
Reset Vclose_pout
Wait 1 ' 3 in real
Start Watchdog
Return
'---------------------------------------------------
Show_lcd:
Locate 1 , 1
Lcd "Max= " ; Fusing(max_temp , "#.&") ; " "
Locate 2 , 1
Lcd "Min= " ; Fusing(min_temp , "#.&") ; " "
Locate 1 , 10
Lcd Max_day
Locate 2 , 10
Lcd Min_day
Locate 1 , 15
Lcd Elapsed
Locate 2 , 15
Lcd F_out_next
If Luxfinal > 999 Then
Lux = Lux / 1000
Locate 3 , 11
Lcd Fusing(lux , "#.&") ; "KLux" ; " "
Else
Locate 3 , 11
Gen_int1 = Luxfinal
Lcd Gen_int1 ; "Lux " ; " "
End If
Locate 3 , 1
Lcd "I(" ; Set1 ; ")=" ; I(set1) ; " "
Locate 4 , 1
Lcd "Tmp:" ; Fusing(curr_temp , "#.&") ; " " ; "Rh:" ; Fusing(curr_rh
, "#.&") ; " "
Return
'---------------------------------------------------
User_data:
Readeeprom Setdata , 0
If Setdata = 0 Then ' Use
default data values
Restore Dta1
For Setdata = 1 To 20 '
Currently 20 Factors as data Inputs
Read I(setdata )
Next
Else ' Read
from Adress 1 of eeprom
For Setdata = 1 To 20 '
Currently 20 Factors as data Inputs
Readeeprom I(setdata ) , Setdata
Next
End If
Return
'---------------------------------------------------
Read_temp:
Gen_int1 = 0
Gen_int2 = 0
Start Adc
For Gen_byte1 = 1 To 10 '1 to 10
to eliminate escallating
Gen_int1 = Getadc(0)
Gen_int2 = Gen_int2 + Gen_int1
Next
Stop Adc
Curr_temp = Gen_int2 / 20.46 '2.046
Return
'---------------------------------------------------
Read_rh:
'For 25c , 100%rh = 3.90 V and 0%Rh =0.8 V
'So : Rh =(V -0.8) / .031
'Or , Rh =(getadc(channel) - 164) / 6.34
' For A 100 Time Average:
' Rh = Getadc_bulk
Gen_int1 = 0
Gen_int2 = 0
Start Adc
For Gen_byte1 = 1 To 20 '1 to 10
to get average
Gen_int1 = Getadc(2)
Gen_int2 = Gen_int2 + Gen_int1
Next
Stop Adc
Curr_rh = Gen_int2 - 3280 '2.046
Curr_rh = Curr_rh / 127
Return
'---------------------------------------------------
Read_light:
Gen_int1 = 0 'W = 0
Gen_int2 = 0
Start Adc
For Gen_byte1 = 1 To 10
Gen_int1 = Getadc(1)
Gen_int2 = Gen_int2 + Gen_int1
Next
Stop Adc '
Gen_sing1 = Gen_int2 / 2046 '204.6
'3996
' R0= 1MV0 / (5K - 2KV0)
R0 = 1000 * Gen_sing1
Gen_sing1 = 5 - Gen_sing1
R0 = R0 / Gen_sing1
Disable Interrupts ' to test
if occasional errors in Log10 calc. comes from interrupts?
Lux = Log10(r0)
Enable Interrupts
Lux = 5.5 - Lux
Lux = Lux / 0.64
Lux = 10 ^ Lux
Luxfinal = Lux
'Lux = 10 ^((5.5 - Log R0) / 0.7)
'Internal 2.56V reference voltage
Gen_sing1 = I(14) - I(13) ' I(14)=
Day Light Level; I(13)= Light level range
Gen_sing2 = I(14)
If Luxfinal < Gen_sing1 Then
Light_level = 0
Elseif Luxfinal > Gen_sing2 Then
Light_level = 1
End If
Return
'---------------------------------------------------
Ramp_detect:
If Done_before = 0 Then
Last_light = Light_level
Done_before = 1
End If
If Last_light = Light_level Then 'System
Starts at day or night
If Light_level = 1 Then
Max_temp = Max_day ' Max_day
is predefined
Min_temp = Min_day
Time_first = -1
Stepcnt = 0
Init = 0
Else
Max_temp = Max_night
Min_temp = Min_night
Time_first = -1
Stepcnt = 0
Init = 0
End If
Else
Gosub Ramping 'when
completed, set last_light=Light_level
End If
Return
'---------------------------------------------------
Ramping:
If Time_first = -1 Then
Time_first = Elapsed
Time_next = Time_first + I(7) ' Delay in
Seconds
Temp_first = Curr_temp
Gosub Take_action 'Take
action ' At least one time in subroutine
Incr Stepcnt
Else
'Gosub Get_time_now
Time_first = Elapsed
Time_now = Time_first ' get
current time throught the running program
If Time_now > Time_next Then
If Stepcnt < I(8) Then
Gosub Take_action 'Take action
Incr Stepcnt
Time_next = Time_next + I(7)
Else 'Now the
work is fully done
Time_first = -1
Stepcnt = 0
Last_light = Light_level
Init = 0
Done_before = 0
End If
End If
End If
Return
'---------------------------------------------------
Take_action: 'Sunrise
or Sunset ramping temp adjust
If Light_level = 1 Then 'Sunrsie
If Temp_first > Min_day Then ' No need
to ramp
Time_first = -1
Stepcnt = 0
Last_light = Light_level
Init = 0
Done_before = 0
Return
Else
If Init = 0 Then 'Do
initialization
Diff = Min_day - Temp_first
Step_temp = Diff / I(8)
Min_temp = Temp_first
Init = 1
End If
Min_temp = Min_temp + Step_temp
Max_temp = Max_day
End If
Else 'Sunset
If Temp_first < Max_night Then '
Max_night > Curr_temp, so no need to ramp
Time_first = -1
Stepcnt = 0
Last_light = Light_level
Init = 0
Done_before = 0
Return
Else
If Init = 0 Then 'Do
initialization
Diff = Temp_first - Max_night
Step_temp = Diff / I(8)
Max_temp = Temp_first
Init = 1
End If
Max_temp = Max_temp - Step_temp
Min_temp = Min_night
End If
End If
Return
'---------------------------------------------------
Heating:
If Fogger_pout = 1 Then
Gen_sing1 = I(12) 'Min Rh
If Curr_rh < Gen_sing1 Then
If Vclose_pinp = 0 Then 'Vents are
NOT close (are open)
Gosub Close_nudge
Return '*******
returnTOP
Else 'vents are
close
If Heater_pout = 0 Then
'Set Heater_pout
H_run = 1
Return
End If
Return '*******
returnTOP
End If
Else ' curr_rh
> min Rh
'Reset Fogger_pout 'stop fogger
F_run = 0
Return '*******
returnTOP
End If
Else ' Fogger=0
Gen_sing1 = I(12) ' I(12)=
min Rh
If Curr_rh < Gen_sing1 Then
If Vclose_pinp = 0 Then ' in open
vents
Gosub Close_nudge
Return
Else ' vents
are closed
If Heater_pout = 0 Then
'Set Heater_pout
H_run = 1
Return
Else 'heaters
are lready on
'Set Fogger_pout
F_run = 1
Return
End If
End If
Else ' = if
curr_rh > max_rh or CURR_RH is normal
If Vclose_pinp = 0 Then ' in open
vents
Gosub Close_nudge
Return
Else ' vents
are closed
If Heater_pout = 0 Then
'Set Heater_pout
H_run = 1
Return
End If
Return
End If
End If
End If
Return
'---------------------------------------------------
Normal:
Gen_sing1 = I(12) ' I(12)=
min Rh
Gen_sing2 = I(5)
Gen_sing3 = I(11)
If Curr_rh < Gen_sing1 Then
If Heater_pout = 1 Then
Gen_sing2 = I(5) + Min_temp ' I(5)=
temp range
If Curr_temp >= Gen_sing2 Then
'Reset Heater_pout
H_run = 0
Return
Else
If Fogger_pout = 0 Then
'Set Fogger_pout
F_run = 1
Return
End If
Return
End If
Else ' heater off
If Fogger_pout = 0 Then
'Set Fogger_pout
F_run = 1
Return
End If
End If
Elseif Curr_rh > Gen_sing3 Then 'I(11) =
max_rh
If Fogger_pout = 1 Then
'Reset Fogger_pout
F_run = 0
Return
Else
Gen_sing1 = Min_temp + I(6) 'I(6) =
IHP , Gen_sing1= Purge temp
If Curr_temp >= Gen_sing1 Then
If Heater_pout = 1 Then
'Reset Heater_pout
H_run = 0
Return
Else ' heater off
If Vopen_pinp = 0 Then 'Vants are
not fully open
Gosub Open_nudge
Return
Else
Return
End If
End If
Else
If Vclose_pinp = 1 Then 'fully close
'Set Heater_pout
H_run = 1
Return
Else 'Not fully
close
Gosub Close_nudge
Return
End If
End If
End If
Else ' Curr_rh
is between max and min
If Fogger_pout = 1 Then
'Reset Fogger_pout
F_run = 0
End If
If Heater_pout = 1 Then
Gen_sing1 = Min_temp + I(5) ' I(5):
temp_range
If Curr_temp >= Gen_sing1 Then
'Reset Heater_pout
H_run = 0
Return
End If
Else ' heater
is off
Return
End If
End If
Return
'---------------------------------------------------
Cooling:
If Heater_pout = 1 Then
'Reset Heater_pout
H_run = 0
Return
Else ' heater
is off
If Vopen_pinp = 0 Then ' not
fully open vents
Gosub Open_nudge
Return
Else 'Vents are
fully open
Gen_sing1 = I(11) 'I(11)= Max Rh
If Curr_rh > Gen_sing1 Then
'Reset Fogger_pout
F_run = 0
Return
Else
'Set Fogger_pout
F_run = 1
Return
End If
End If
End If
Return
'---------------------------------------------------
Alarm:
If Set_alarm = 0 Then
Reset Alarm_pout
Return
Else 'Set_alarm=1
If Time_alarm_got = 0 Then
'Gosub Get_time_now
Time_alarm = Elapsed
Time_alarm = Time_alarm + I(15) 'I(15)=
Alarm Duration In second
Time_alarm_got = 1
Set Alarm_pout 'Pind.7
Else
'Gosub Get_time_now
If Elapsed > Time_alarm Then 'Duration
is over
Reset Alarm_pout 'Pind.7
Set_alarm = 0
Time_alarm_got = 0
End If
End If
End If
Return
'---------------------------------------------------
Heater_pulse:
If H_run = 1 Then
If H_ini = 0 Then
H_out_next = Elapsed + I(20)
H_ini = 1
Set Heater_pout
End If
Else ' Stop command
If H_out_next < Elapsed Then
Reset Heater_pout
H_ini = 0
End If
End If
Return
'---------------------------------------------------
Fogger_pulse:
If F_run = 1 Then
If F_ini = 0 Then
F_out_next = F_in_duration + Elapsed
F_in_next = F_out_duration + F_out_next
F_ini = 1
End If
End If
If Elapsed < F_out_next Then
Set Fogger_pout
Elseif F_out_next < Elapsed Then
If Elapsed < F_in_next Then
Reset Fogger_pout
Else
Reset Fogger_pout
F_ini = 0
End If
End If
Return
'---------------------------------------------------
Elaps:
Stop Timer1
Elapsed = Elapsed + 1
Timer1 = 34286
Start Timer1
Return
'---------------------------------------------------
Sub Key1
Set1 = Set1 + 1
If Set1 > 20 Then Set1 = 1
Return
End Sub
'---------------------------------------------------
Dta1:
'1- Max Day
'2- Min Day
'3- Max Night
'4- Min Night
'5- Temp. Range
'6- IHP
'7- Ramp Duration in seconds 300 in real
'8- Ramp Steps
'9- Hot Alarm
'10- Cold Alarm
'11- Max Rh
'12- Min Rh
'13- Light level range
'14- Day light level
'15- Alarm duration in seconds
'16- Duration of any open/close nudge in seconds (Endurance)
'17- Algorithm Period in seconds (100 in real)
'18- Fogger on duration (F_in_duration)
'19- Fogger off duration (F_out_duration)
'20- Minimum Heater On duration (sec)
Data 30% , 15% , 30% , 15% , 1% , 3% , 10% , 4% , 35% , 10% , 60% ,
15% , 200% , 300% , 10% , 3% , 2% , 2% ,
8% , 5%
'---------------------------------------------------
--- In AVR-Chat@yahoogroups.com, Zack Widup <w9sz@...> wrote:
>
>
> Yep, my first AVR project gave me fits and starts because I had the
CKOPT
> set incorrectly. Once I learned what to do with it, I never had that
> trouble again.
>
> Zack
>
> On Mon, 10 Jul 2006, kernels_nz wrote:
>
> > Yup, that CKOPT Fuse has caught everyone I know involved with AVRs. It
> > personally gave me hours of grief trying to figure out why my micro
> > would reset when doing UART Comms on a MEGA16.
> >
>Message
Re: AVR Power Supply Noise
2006-07-12 by behrooz_hariri
Attachments
- No local attachments were found for this message.