Hallo,
das Programm liest ein Signal von einer Fernsteuerung und schaltet in Abhängigkeit von der Länge des Impulses einen Ausgang (eine LED ein) bzw. gibt bei einem längerem Impuls ein PWM-Signal an einen zweiten Ausgang, mit dem die Helligkeit einer weiteren LED gesteuert wird. Später soll das Programm in einen ATTiny45, jetzt läuft es aber erst einmal auf dem evaluation board von Pollin. Grundsätzlich tut das Programm auch, was es soll, aber ab und an bleibt es einfach stehen. Das Problem liegt in dem Teil von Zeile 153 bis 165. Wenn der Impuls an der Einschaltschwelle (158) des zweiten Ausgangs liegt (minmale Impulslänge ist 137 und maximale 243), wird ein PWM1A von 2 ausgegeben und damit hängt sich das Programm reproduzierbar auf.
Ich vermute, dass es irgendetwas mit der Berechnung von PWW1A zu tun hat. Deshalb habe ich versucht, mit der Bedingung in Zeile 176 eine gültige Impulslänge sicher zustellen; aber leider vergeblich. Natürlich ließe sich ein Neustart per watchdog erzwingen, aber das finde ich irgendwie unbefriedigend, weil es nur am Symptom arbeitet anstatt das Problem zu lösen.
Falls jemand dazu eine Idee hat, bitte her damit - ich komme mit meinem Latein nicht weiter.
Alles anzeigen
das Programm liest ein Signal von einer Fernsteuerung und schaltet in Abhängigkeit von der Länge des Impulses einen Ausgang (eine LED ein) bzw. gibt bei einem längerem Impuls ein PWM-Signal an einen zweiten Ausgang, mit dem die Helligkeit einer weiteren LED gesteuert wird. Später soll das Programm in einen ATTiny45, jetzt läuft es aber erst einmal auf dem evaluation board von Pollin. Grundsätzlich tut das Programm auch, was es soll, aber ab und an bleibt es einfach stehen. Das Problem liegt in dem Teil von Zeile 153 bis 165. Wenn der Impuls an der Einschaltschwelle (158) des zweiten Ausgangs liegt (minmale Impulslänge ist 137 und maximale 243), wird ein PWM1A von 2 ausgegeben und damit hängt sich das Programm reproduzierbar auf.
Ich vermute, dass es irgendetwas mit der Berechnung von PWW1A zu tun hat. Deshalb habe ich versucht, mit der Bedingung in Zeile 176 eine gültige Impulslänge sicher zustellen; aber leider vergeblich. Natürlich ließe sich ein Neustart per watchdog erzwingen, aber das finde ich irgendwie unbefriedigend, weil es nur am Symptom arbeitet anstatt das Problem zu lösen.
Falls jemand dazu eine Idee hat, bitte her damit - ich komme mit meinem Latein nicht weiter.
Quellcode
- '----- Settings ----------------------------------------------------------------
- $regfile = "m16DEF.Dat"
- $crystal = 1000000 'Frequency 1 MHz
- $hwstack = 48
- $swstack = 20
- $framesize = 32
- '----- Settings for Pollin Evaluation Board -----
- ' Port selected as given by addon board to use jumpers instead of cables to ports
- Lcd_db4 alias Porta.4
- Lcd_db5 alias Porta.5
- Lcd_db6 alias Porta.6
- Lcd_db7 alias Porta.7
- Lcd_e alias Portb.0
- Lcd_rs alias Portb.2
- config Portb.1 = output 'R/W of LCD to be connected to GND
- reset Portb.1 'PortB.1 set to GND
- ' 76543210
- Ddrd = &B00110001 '0 = input
- ' 76543210
- Portd = &B11001110 '1 = PullUp active
- '----- Variables ---------------------------------------------------------------
- dim wPulse as word 'stores current reading of RC signal
- dim wPulseMin as word : dim wPulseMinStore as word 'minimum pulse lenght
- dim wPulseMax as word : dim wPulseMaxStore as word 'maximum pulse length
- dim wPulseWidth as word 'pulse width
- dim ewPulseMin as eram word 'Minimum pulse length in EEPROM
- dim ewPulseMax as eram word 'Maximum pulse length in EEPROM
- dim wFactorPWM1 as word 'Division factor
- dim bCount as byte 'used as loop counter
- dim bSigMeasErr as byte 'used to indicate error in signal measurement routine
- dim wcloseUpOn as word
- dim wFarRangeOn as word
- RC_In alias pind.2 'PortD.2, Pin 16 (INT0) to read RC signal
- SigMeas alias pind.3 'PortD.3, Pin 17 to start signal measurement
- FeedBack alias portd.4 'Pin 18
- CloseUp alias portD.0 'Pin 14
- const PrecisionPWM1 = 2500 'Multiplied by 10 to get better precision of PWM
- const PulseTolerance = 3 'range to define valid switch bias
- const CloseUpOn = 10 'minimum value to switch CloseUp on
- const FarRangeOn = 20 'minimum value to switch FarRange on
- const ReadRepeat = 5 'necessary pulse readings before program continues
- '----- Initialization ----------------------------------------------------------
- config lcd = 16x2
- config Lcdpin = Pin , Db4 = Lcd_db4 , Db5 = Lcd_db5 , Db6 = Lcd_db6 , Db7 = Lcd_db7 , E = Lcd_e , Rs = Lcd_rs
- config Lcdbus = 4
- initlcd
- cls 'LCD used in 4-bit-mode
- config timer0 = timer , Prescale = 8
- config int0 = change
- on int0 GetPulse
- config Timer1 = Pwm, Pwm = 8, Compare_A_Pwm = Clear_Up, Prescale = 8
- wPulse = 0
- Timer0 = 0
- FeedBack = 0
- '===== Program =================================================================
- enable Timer0
- enable int0
- enable interrupts
- '----- Part 1 - Check for reliable pulse min & max value in EEPROM -------------
- wPulseMinStore = ewPulseMin 'read stored values of EEPROM
- wPulseMaxStore = ewPulseMax
- gosub PulseCheck
- if bSigMeasErr > 0 then
- gosub ErrorSignal
- else
- for bCount = 1 to 6 '3 slow LED signals = o.k. to start
- toggle Feedback
- Waitms 300
- Next bCount
- cls
- upperline : Lcd "Min " ; wPulseMinStore
- locate 1,9 : Lcd "Max " ; wPulseMaxStore
- wait 2
- end if
- '----- Part 2 - Measures minimum & maximum pulse length -----------------------
- if SigMeas = 0 or bSigMeasErr > 0 then
- do
- wait 1
- wPulseMinStore = wPulse 'measurement of min pulse
- for bCount = 1 to 4 '2 slow LED signals = finished
- toggle Feedback
- Waitms 300
- Next bCount
- wait 1 'measurement of max pulse
- wPulseMaxStore = wPulse
- gosub PulseCheck
- select case bSigMeasErr 'error handling
- case is > 0
- gosub ErrorSignal
- Wait 1
- case is = 0
- for bCount = 1 to 8 '4 slow LED signals = final o.k.
- toggle Feedback
- Waitms 300
- Next bCount
- ewPulseMin = wPulseMinStore 'store values in EEPROM
- ewPulseMax = wPulseMaxStore
- end select
- loop until bSigMeasErr = 0
- else 'read stored values of EEPROM
- wPulseMinStore = ewPulseMin
- wPulseMaxStore = ewPulseMax
- endif
- wCloseUpOn = wPulseMinStore + CloseUpOn 'effective treshold to switch close up LED
- wFarRangeOn = wPulseminStore + FarRangeOn 'effective treshold to switch far range LED's
- wPulseWidth = wPulseMaxStore - wPulseMinStore
- wPulseWidth = wPulseWidth - FarRangeOn 'effective puls width for PWM
- wFactorPWM1 = PrecisionPWM1 / wPulseWidth 'calculates PWM multiplication factor
- upperline : Lcd "Show pulse "
- wait 1
- locate 1 , 1 :lcd "P-Length "
- waitms 500
- '----- Part 3 - Main: Pulse width calculation & output switches ----------------
- do
- bCount = 0
- wPulseMin = wPulse - PulseTolerance
- wPulseMax = wPulse + PulseTolerance
- do 'repeat pulse readings
- if wPulse > wPulseMin and wPulse < wPulseMax then
- incr bCount
- waitms 25
- if wPulse > PulseTolerance then
- wPulseMin = wPulse - PulseTolerance
- end if
- wPulseMax = wPulse + PulseTolerance
- end if
- Loop until bCount = ReadRepeat
- ' Shows current pulse length
- locate 1 , 10
- lcd wPulse ; spc(8)
- if wPulse > wCloseUpOn then 'Switch close up LED
- CloseUp = 1
- else
- CloseUp = 0
- end if
- if wPulse > wFarRangeOn then 'Switch far range LED's
- wPulse = wPulse - wFarRangeOn
- if wPulse > 0 and wPulse < wPulseMaxStore then
- wPulse = wPulse * wFactorPWM1
- wPulse = wPulse / 10
- PWM1A = wPulse
- else
- PWM1A = 0
- end if
- else
- PWM1A = 0
- end if
- locate 2, 10 : lcd wPulse ; spc(8)
- loop
- End 'end program
- '===== End of program ==========================================================
- '----- Sub routines ------------------------------------------------------------
- PulseCheck:
- if wPulseMinStore < wPulseMaxStore then bSigMeasErr = 0
- if wPulseMinStore > wPulseMaxStore then bSigMeasErr = 1
- if wPulseMinStore = wPulseMaxStore then bSigMeasErr = 2
- return
- ErrorSignal:
- for bCount = 1 to 20 '10 quick LED signals = n.o.k.
- toggle Feedback
- Waitms 100
- Next bCount
- return
- '----- Interrupts --------------------------------------------------------------
- GetPulse:
- if RC_In = 1 then 'start Timer1 if positive signal on input
- start timer0
- Else 'stop Timer1 if no positive signal
- stop timer0
- wPulse = timer0
- timer0 = 0
- end if
- return
Beste Grüße
Jürgen
Jürgen