im having trouble with software serial receive. i have serial from a pc running into a pic through the pics ext int pin. i receive the characters just fine, but sometimes, randomly it doesnt exit my serial interrupt sub (i have the ext int set up to go into a sub that only received the byte from the serial, and repeats it back out to the pc, itll receive the byte, retransmit it, but it doesnt exit the sub to take the action based on what the byte was, but it usually (but not always) will still retrasmit the character, but randomly will stop exiting the interrupt sub and take the action). ive tryed using IntOff at the begining of the interrupt sub, and IntOn at the end of the sub, i still get a random crash after a while of receiving charecters. i took the interrupt sub out and so far have no crash. oh and i have another interrupt for timer0 for my IR remote decodeing section of my program. is this a problem with GCbasic or is there something im missing?
;Chip Settings
#chip 16F616,8
#config MCLRE=OFF, WDT=OFF
;Defines (Constants)
#define button_on porta.3=0
#define button_off porta.3=1
#define led1 portc.3
#define output1 portc.4
#define SendAHigh porta.1= on
#define SendALow porta.1 = off
#define RecAHigh porta.2 on
#define RecALow porta.2 off
#define PWM_Freq 40
#define PWM_Duty 100
#define led2 portc.5
#define remote_in porta.0
#define relay_out portc.0
;Variables
Dim power_out As bit
Dim temp As byte
Dim light_sensor As byte
Dim sensor(2)
Dim sensor_counter As byte
Dim brightness As byte
Dim nightlight_var As bit
Dim print_out As bit
Dim toggle As bit
Dim counter As byte
Dim delay_temp As byte
Dim timeout As bit
Dim start_byte As byte
Dim code_word As word
Dim hold_counter As byte
Dim button_held As bit
Dim serial_send As bit
Dim toggle_power As bit
;Interrupt Handlers
On Interrupt ExtInt0 Call serial_receive
On Interrupt Timer0Overflow Call timer0_overflow
'x power
'xxx sesor1
'xxx sesor2
'xxx brightness
'x nightlight_var
'xxxx remote
Set relay_out Off
Dir portc.5 Out
Set NOT_RAPU Off
Set WPUA.0 On
InitSer 1, r4800, 1+WaitForStart, 8, 1, None, Invert
InitTimer0 Osc, PS0_1/32
brightness = 200
Do Forever
If button_on Then
toggle_power = 1
Wait 250 ms
End If
If toggle_power=1 Then
toggle_power = 0
If power_out=0 Then
nightlight_var = 0
power_out = 1
Goto skip_off
End If
power_out = 0
skip_off:
serial_send = 1
End If
If power_out=0 Then
Set output1 Off
Set led1 Off
End If
If power_out=1 Then
Set output1 On
Set led1 On
End If
If sensor(1)<1 and power_out=0 Then
If toggle=0 Then
toggle = 1
nightlight_var = 1
End If
End If
If sensor(1)>15 or power_out=1 Then
If toggle=1 Then
toggle = 0
nightlight_var = 0
End If
End If
If nightlight_var=0 Then
HPWM 1, 40, 0
End If
If nightlight_var=1 Then
HPWM 1, 40, brightness
End If
If remote_in=0 Then
remote_receive
End If
sensor(1) = readAD(an6)
sensor(2) = readAD(an5)
hold_counter = hold_counter+1
If hold_counter>=255 Then
hold_counter = 0
Set relay_out Off
End If
If serial_send=1 Then
serial_send = 0
SerPrint 1, power_out
sensor_counter = 0
Do Until sensor_counter=>2
sensor_counter = sensor_counter+1
If sensor(sensor_counter)<100 Then
SerPrint 1, "0"
End If
If sensor(sensor_counter)<10 Then
SerPrint 1, "0"
End If
SerPrint 1, sensor(sensor_counter)
Loop
If brightness<100 Then
SerPrint 1, "0"
End If
If brightness<10 Then
SerPrint 1, "0"
End If
SerPrint 1, brightness
SerPrint 1, nightlight_var
If code_word<1000 Then
SerPrint 1, "0"
End If
If code_word<100 Then
SerPrint 1, "0"
End If
If code_word<10 Then
SerPrint 1, "0"
End If
SerPrint 1, code_word
code_word = 1111
End If
Loop
Sub serial_receive
IntOff
SerReceive 1, temp
IntOff
If temp=43 Then
'+
nightlight_var = 1
End If
If temp=45 Then
'-
nightlight_var = 0
End If
If temp=48 or temp=49 Then
'0 or 1
power_out = temp-48
End If
If temp=>97 and temp<=122 Then
'a to z
brightness = (temp-97)*10
End If
temp = 0
serial_send = 1
IntOn
End Sub
Sub remote_receive
If power_out=1 Then
Set led1 Off
End If
If power_out=0 Then
Set led1 On
End If
hold_counter = 0
code_word = 0
start_byte = 0
counter = 0
ClearTimer 0
timeout = 0
Do Until counter=>22
counter = counter+1
ClearTimer 0
If remote_in=0 Then
Wait Until remote_in=1 or timeout=1
Goto skip_wait_zero
End If
Wait Until remote_in=0 or timeout=1
skip_wait_zero:
delay_temp = Timer0
If remote_in=0 Then
delay_temp = delay_temp+10
End If
If timeout=1 Then
delay_temp = 33
End If
If counter<=8 Then
Rotate start_byte Left
If delay_temp<90 Then
start_byte.0 = 0
End If
If delay_temp>90 Then
start_byte.0 = 1
End If
End If
If counter>12 Then
Rotate code_word Left
If delay_temp<90 Then
code_word.0 = 0
End If
If delay_temp>90 Then
code_word.0 = 1
End If
End If
Loop
If start_byte=9 or start_byte=33 Then
Goto code_accept
End If
Wait 20 ms
Goto remote_end
code_accept:
If code_word=9 Then
'power
Set relay_out On
End If
If code_word=512 Then
'mute
toggle_power = 1
Wait 114 ms
Goto remote_end
End If
If code_word=530 Then
'CHUP
nightlight_var = 1
If brightness<250 Then
brightness = brightness+10
Wait 150 ms
End If
End If
If code_word=584 Then
'CHDN
nightlight_var = 1
If brightness>0 Then
brightness = brightness-10
Wait 150 ms
End If
End If
serial_send = 1
remote_end:
Wait 80 ms
End Sub
Sub timer0_overflow
timeout = 1
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ignore the previous code, when the interrupt wouldnt exit, with that code it wouldnt retransmit the info. with this code itll retransmit the info, and change the variables but will not exit to make the variables take action
by the way, it would be nice to have a remote control decode library but ive managed to make a decode routine for my remote (which uses a highly non standard set of pulses) which times the length of the high, and low pulses and turns long pulses into 1's and short ones into 0's. for my remote the first 12 bits are start bits, and device id (i guess) and the rest is the button code (though the amount of pulses arent constant, hence the need for the timer overflow to prevent and endless wait for a bit that isnt going to arrive)
;Chip Settings
#chip 16F616,8
#config MCLRE=OFF, WDT=OFF
;Defines (Constants)
#define button_on porta.3=0
#define button_off porta.3=1
#define led1 portc.3
#define output1 portc.4
#define SendAHigh porta.1= on
#define SendALow porta.1 = off
#define RecAHigh porta.2 on
#define RecALow porta.2 off
#define PWM_Freq 40
#define PWM_Duty 100
#define led2 portc.5
#define remote_in porta.0
#define relay_out portc.0
;Variables
Dim power_out As bit
Dim temp As byte
Dim light_sensor As byte
Dim sensor(2)
Dim sensor_counter As byte
Dim brightness As byte
Dim nightlight_var As bit
Dim print_out As bit
Dim toggle As bit
Dim counter As byte
Dim delay_temp As byte
Dim timeout As bit
Dim start_byte As byte
Dim code_word As word
Dim hold_counter As byte
Dim button_held As bit
Dim toggle_power As bit
;Interrupt Handlers
On Interrupt ExtInt0 Call serial_receive
On Interrupt Timer0Overflow Call timer0_overflow
'x power
'xxx sesor1
'xxx sesor2
'xxx brightness
'x nightlight_var
'xxxx remote
Set relay_out Off
Dir portc.5 Out
Set NOT_RAPU Off
Set WPUA.0 On
InitSer 1, r4800, 1+WaitForStart, 8, 1, None, Invert
InitTimer0 Osc, PS0_1/32
brightness = 200
Do Forever
If button_on Then
toggle_power = 1
Wait 250 ms
End If
If toggle_power=1 Then
toggle_power = 0
If power_out=0 Then
nightlight_var = 0
power_out = 1
Goto skip_off
End If
power_out = 0
skip_off:
send_info
End If
If power_out=0 Then
Set output1 Off
Set led1 Off
End If
If power_out=1 Then
Set output1 On
Set led1 On
End If
If sensor(1)<1 and power_out=0 Then
If toggle=0 Then
toggle = 1
nightlight_var = 1
End If
End If
If sensor(1)>15 or power_out=1 Then
If toggle=1 Then
toggle = 0
nightlight_var = 0
End If
End If
If nightlight_var=0 Then
HPWM 1, 40, 0
End If
If nightlight_var=1 Then
HPWM 1, 40, brightness
End If
If remote_in=0 Then
remote_receive
End If
sensor(1) = readAD(an6)
sensor(2) = readAD(an5)
hold_counter = hold_counter+1
If hold_counter>=255 Then
hold_counter = 0
Set relay_out Off
End If
Loop
Sub serial_receive
IntOff
SerReceive 1, temp
IntOff
If temp=43 Then
'+
nightlight_var = 1
End If
If temp=45 Then
'-
nightlight_var = 0
End If
If temp=48 or temp=49 Then
'0 or 1
power_out = temp-48
End If
If temp=>97 and temp<=122 Then
'a to z
brightness = (temp-97)*10
End If
temp = 0
send_info
IntOn
End Sub
Sub remote_receive
If power_out=1 Then
Set led1 Off
End If
If power_out=0 Then
Set led1 On
End If
hold_counter = 0
code_word = 0
start_byte = 0
counter = 0
ClearTimer 0
timeout = 0
Do Until counter=>22
counter = counter+1
ClearTimer 0
If remote_in=0 Then
Wait Until remote_in=1 or timeout=1
Goto skip_wait_zero
End If
Wait Until remote_in=0 or timeout=1
skip_wait_zero:
delay_temp = Timer0
If remote_in=0 Then
delay_temp = delay_temp+10
End If
If timeout=1 Then
delay_temp = 33
End If
If counter<=8 Then
Rotate start_byte Left
If delay_temp<90 Then
start_byte.0 = 0
End If
If delay_temp>90 Then
start_byte.0 = 1
End If
End If
If counter>12 Then
Rotate code_word Left
If delay_temp<90 Then
code_word.0 = 0
End If
If delay_temp>90 Then
code_word.0 = 1
End If
End If
Loop
If start_byte=9 or start_byte=33 Then
Goto code_accept
End If
Wait 20 ms
Goto remote_end
code_accept:
If code_word=9 Then
'power
Set relay_out On
End If
If code_word=512 Then
'mute
toggle_power = 1
Wait 114 ms
Goto remote_end
End If
If code_word=530 Then
'CHUP
nightlight_var = 1
If brightness<250 Then
brightness = brightness+10
Wait 150 ms
End If
End If
If code_word=584 Then
'CHDN
nightlight_var = 1
If brightness>0 Then
brightness = brightness-10
Wait 150 ms
End If
End If
send_info
remote_end:
Wait 80 ms
End Sub
Sub timer0_overflow
timeout = 1
End Sub
Sub send_info
SerPrint 1, power_out
sensor_counter = 0
Do Until sensor_counter=>2
sensor_counter = sensor_counter+1
If sensor(sensor_counter)<100 Then
SerPrint 1, "0"
End If
If sensor(sensor_counter)<10 Then
SerPrint 1, "0"
End If
SerPrint 1, sensor(sensor_counter)
Loop
If brightness<100 Then
SerPrint 1, "0"
End If
If brightness<10 Then
SerPrint 1, "0"
End If
SerPrint 1, brightness
SerPrint 1, nightlight_var
If code_word<1000 Then
SerPrint 1, "0"
End If
If code_word<100 Then
SerPrint 1, "0"
End If
If code_word<10 Then
SerPrint 1, "0"
End If
SerPrint 1, code_word
code_word = 1111
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ok ive narrowed down the problem. the serial interrupt isnt playing nicely with the ADC. without the "readAD(an…)" in the code, it never hangs, but as soon as i put that in there, and repeatedly send a key through the serial of my pic, itll eventually hang. ive slimmed down the code to just the amount that duplicates the problem. the hardware is like this.. the "led1" pin is hooked to an leds + side, and turns ON when a 1 is written to it. when i run this code, the code hangs with the led OFF, which leads me to believe that the code is going back to the main loop where the "set led1 off" is to shut off the led. im at a loss here, i need the ADC and i would like to be able to receive (reliably without haveing to use the WDT) through the serial. any help on this one?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
oops, forgot to post the code with my last reply, here it is..
;Chip Settings
#chip 16F616,8
#config MCLRE=OFF, WDT=OFF
;Defines (Constants)
#define led1 portc.3
#define SendAHigh porta.1= on
#define SendALow porta.1 = off
#define RecAHigh porta.2 on
#define RecALow porta.2 off
;Variables
Dim temp As byte
Dim sensor(2)
;Interrupt Handlers
On Interrupt ExtInt0 Call serial_receive
InitSer 1, r4800, 1+WaitForStart, 8, 1, None, Invert
Do Forever
sensor(1) = readAD(an6)
sensor(2) = readAD(an5)
Set led1 Off
Loop
Sub serial_receive
SerReceive 1, temp
Set led1 On
SerSend 1, temp
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
im having trouble with software serial receive. i have serial from a pc running into a pic through the pics ext int pin. i receive the characters just fine, but sometimes, randomly it doesnt exit my serial interrupt sub (i have the ext int set up to go into a sub that only received the byte from the serial, and repeats it back out to the pc, itll receive the byte, retransmit it, but it doesnt exit the sub to take the action based on what the byte was, but it usually (but not always) will still retrasmit the character, but randomly will stop exiting the interrupt sub and take the action). ive tryed using IntOff at the begining of the interrupt sub, and IntOn at the end of the sub, i still get a random crash after a while of receiving charecters. i took the interrupt sub out and so far have no crash. oh and i have another interrupt for timer0 for my IR remote decodeing section of my program. is this a problem with GCbasic or is there something im missing?
ignore the previous code, when the interrupt wouldnt exit, with that code it wouldnt retransmit the info. with this code itll retransmit the info, and change the variables but will not exit to make the variables take action
by the way, it would be nice to have a remote control decode library but ive managed to make a decode routine for my remote (which uses a highly non standard set of pulses) which times the length of the high, and low pulses and turns long pulses into 1's and short ones into 0's. for my remote the first 12 bits are start bits, and device id (i guess) and the rest is the button code (though the amount of pulses arent constant, hence the need for the timer overflow to prevent and endless wait for a bit that isnt going to arrive)
ok ive narrowed down the problem. the serial interrupt isnt playing nicely with the ADC. without the "readAD(an…)" in the code, it never hangs, but as soon as i put that in there, and repeatedly send a key through the serial of my pic, itll eventually hang. ive slimmed down the code to just the amount that duplicates the problem. the hardware is like this.. the "led1" pin is hooked to an leds + side, and turns ON when a 1 is written to it. when i run this code, the code hangs with the led OFF, which leads me to believe that the code is going back to the main loop where the "set led1 off" is to shut off the led. im at a loss here, i need the ADC and i would like to be able to receive (reliably without haveing to use the WDT) through the serial. any help on this one?
oops, forgot to post the code with my last reply, here it is..