18M2 Interrupt on Serial In

rokison

New Member
Hi there,
I'm having real difficulty with a binary clock I'm trying to make which should activate when given an instruction on a serial bus.
I'm using an interrupt to tell the clock to check the serial bus for an instruction but I'm using pin C.4 as the interrupt pin (which happens to be the serial in).
I found out about the disconnect command to make pin C.4 a standard input, but it doesn't seem to work properly.
I get a flashing LED (connected to output C.3 which is the Serial Out) about every second and nothing else.
Am I doing something stupid here or can you not use pin C.4 as an interrupt?
Here is my code:


'***** Input/Output Pins *****
symbol min1 = b.7
symbol min2 = c.6
symbol min4 = c.0
symbol min8 = c.2
symbol min16 = b.5
symbol min32 = b.0
symbol hours1 = b.6
symbol hours2 = c.7
symbol hours4 = c.1
symbol hours8 = c.3

symbol serdata = b.3
'input c.4 interrupt (serial data coming)

'***** Variables *****
symbol mins = b0 ' store for minutes value
symbol hours = b1 ' store for hours value
symbol days = b2 ' store for days value
symbol months = b3
symbol year = b4
symbol temp = b5 ' temporary
symbol temp_portb = b6 ' temporary port value


'***** Initialisation *****
init:
' setup portC
' as some inputs are changed to be outputs
let dirsc = %11001111
let dirsb = %11100001

'disconnect the download on c.4 and c.3
disconnect

' setup i2c for DS1307 clock operation
i2cslave %11010000, i2cslow, i2cbyte

'setup interrupt for reading a serial command
'setint %00000000, %00010000, C

'setup on/off flag to be off
let b7 = 1


'***** Main Loop *****
main:
'check on/off flag
if b7=0 then
low hours1,hours2,hours4,hours8,min1,min2,min4,min8,min16,min32
goto main
endif
' read current time from DS1307
readi2c 0,(temp,mins,hours)
'change clock values from BCD to binary
gosub bcd_bin
'optionally display on computer via debug
'debug

'display the hours and minutes
gosub display_mins
gosub display_hours
'debug
goto main


'***** Sub Procedure - convert BCD to binary *****
bcd_bin:
' convert the DS1307 BCD values to binary
temp = mins AND %00001111
mins = mins AND %11110000 * 10 / 16 + temp

temp = hours AND %00001111
hours = hours AND %11110000 * 10 / 16 + temp

' convert 24 hour clock values to 12 hour clock
if hours < 13 then do_return
hours = hours - 12

do_return:
return


'***** Sub Procedure - display the hours/mins *****
display_mins:
let temp= mins AND %00000001
if temp <> 0 then
high min1
else
low min1
endif
let temp= mins AND %00000010
if temp <> 0 then
high min2
else
low min2
endif
let temp= mins AND %00000100
if temp <> 0 then
high min4
else
low min4
endif
let temp= mins AND %00001000
if temp <> 0 then
high min8
else
low min8
endif
let temp= mins AND %00010000
if temp <> 0 then
high min16
else
low min16
endif
let temp= mins AND %00100000
if temp <> 0 then
high min32
else
low min32
endif
return

display_hours:
let temp= hours AND %00000001
if temp <> 0 then
high hours1
else
low hours1
endif
let temp= hours AND %00000010
if temp <> 0 then
high hours2
else
low hours2
endif
let temp= hours AND %00000100
if temp <> 0 then
high hours4
else
low hours4
endif
let temp= hours AND %00001000
if temp <> 0 then
high hours8
else
low hours8
endif
return


'***** Sub Procedure - Interrupt Handler *****
interrupt:
'reinstate the interrupt on return
setint %00000000, %00010000, C

high hours1,hours2,hours4,hours8
serin [500, returnint],serdata, N2400,("device 1")
if b7 = 0 then
let b7 = 1
else
let b7 = 0
endif
return

returnint:
return
 

cdngunner

Senior Member
Code:
***** Input/Output Pins *****
symbol min1 = b.7
symbol min2 = c.6
symbol min4 = c.0
symbol min8 = c.2
symbol min16 = b.5
symbol min32 = b.0
symbol hours1 = b.6
symbol hours2 = c.7
symbol hours4 = c.1
symbol hours8 = c.3

symbol serdata = b.3
'input c.4 interrupt (serial data coming)

'***** Variables *****
symbol mins = b0 ' store for minutes value
symbol hours = b1 ' store for hours value
symbol days = b2 ' store for days value
symbol months = b3
symbol year = b4
symbol temp = b5 ' temporary
symbol temp_portb = b6 ' temporary port value


'***** Initialisation *****
init:
' setup portC
' as some inputs are changed to be outputs
let dirsc = %11001111
let dirsb = %11100001

'disconnect the download on c.4 and c.3
disconnect

' setup i2c for DS1307 clock operation
i2cslave %11010000, i2cslow, i2cbyte

'setup interrupt for reading a serial command
'setint %00000000, %00010000, C

'setup on/off flag to be off
let b7 = 1


'***** Main Loop ***** 
main:
'check on/off flag
if b7=0 then 
low hours1,hours2,hours4,hours8,min1,min2,min4,min8,mi n16,min32
goto main
endif
' read current time from DS1307
readi2c 0,(temp,mins,hours)
'change clock values from BCD to binary
gosub bcd_bin
'optionally display on computer via debug
'debug

'display the hours and minutes
gosub display_mins 
gosub display_hours
'debug
goto main


'***** Sub Procedure - convert BCD to binary *****
bcd_bin:
' convert the DS1307 BCD values to binary
temp = mins AND %00001111
mins = mins AND %11110000 * 10 / 16 + temp

temp = hours AND %00001111
hours = hours AND %11110000 * 10 / 16 + temp

' convert 24 hour clock values to 12 hour clock
if hours < 13 then do_return
hours = hours - 12

do_return:
return


'***** Sub Procedure - display the hours/mins *****
display_mins:
let temp= mins AND %00000001
if temp <> 0 then
high min1
else
low min1
endif
let temp= mins AND %00000010
if temp <> 0 then
high min2
else
low min2
endif
let temp= mins AND %00000100
if temp <> 0 then
high min4
else
low min4
endif
let temp= mins AND %00001000
if temp <> 0 then
high min8
else
low min8
endif
let temp= mins AND %00010000
if temp <> 0 then
high min16
else
low min16
endif
let temp= mins AND %00100000
if temp <> 0 then
high min32
else
low min32
endif
return

display_hours:
let temp= hours AND %00000001
if temp <> 0 then
high hours1
else
low hours1
endif
let temp= hours AND %00000010
if temp <> 0 then
high hours2
else
low hours2
endif
let temp= hours AND %00000100
if temp <> 0 then
high hours4
else
low hours4
endif
let temp= hours AND %00001000
if temp <> 0 then
high hours8
else
low hours8
endif
return


'***** Sub Procedure - Interrupt Handler *****
interrupt:
'reinstate the interrupt on return
setint %00000000, %00010000, C

high hours1,hours2,hours4,hours8
serin [500, returnint],serdata, N2400,("device 1")
if b7 = 0 then
let b7 = 1
else
let b7 = 0
endif
return

returnint:
return
your welcome
 

hippy

Ex-Staff (retired)
This works for me, which proves the principle that it can work ...

Code:
#Picaxe 08M

Do
  High   1 : Pause 100
  Low    1 : Pause 100
  SerOut 1, N2400,( "REM", b0 )
  b0 = b0 + 1
  Pause 1000
Loop
Code:
#Picaxe 18M2
#Terminal 4800

Disconnect
Gosub Interrupt_Enable
Do : Loop

Interrupt:
  Do : Loop While pinC.4 = 1
  SerIn C.4, N2400, ( "REM" ), b0
  SerTxd( #b0, CR, LF )

Interrupt_Enable:
  SetInt %00010000, %00010000, C
  Return
 

rokison

New Member
Many thanks for the help.
Must be a hardware issue.
I still don't see how the hardware could cause the LED to flash though, and there's nothing in the code that controls only output C.3.
Any ideas?
 

hippy

Ex-Staff (retired)
Possibly the "setint %00000000, %00010000, C" meaning most time is spent in interrupt.
 

Technical

Technical Support
Staff member
The default state of the serrxd pin is low (pulled low by the 10k/22k resistors).
You are telling the interrupt to occur when that pin is low (logic level 0).
Therefore the interrupt will keep processing over and over and over again.

Look at Hippy's example and spot the difference.
 
Last edited:

hippy

Ex-Staff (retired)
As Technical describes.

As for C.3 pulsing ...

In the interrupt you set C.3 high (hours8), there's a 500ms timeout which likely delays until the timeout expires, you then switch b7 between 0 and 1, return from interrupt. Whenever the code reaches 'main:' and b7 is zero, you clear C.3 (hours8).

Whether that's it or not I don't know but it's a possible scenario. All sorts of weird things can happen when the code design isn't right. All you can do is fix one thing at a time, then move onto the next.
 

rokison

New Member
The default state of the serrxd pin is low (pulled low by the 10k/22k resistors).
You are telling the interrupt to occur when that pin is low (logic level 0).
Therefore the interrupt will keep processing over and over and over again.

Look at Hippy's example and spot the difference.
Here is the problem with that scenario. I am using the little download pcb with the jack socket and the resistors on it, and removing it after programming, so there is no 10k/22k resistor network.

As for the other point
As for C.3 pulsing ...

In the interrupt you set C.3 high (hours8), there's a 500ms timeout which likely delays until the timeout expires, you then switch b7 between 0 and 1, return from interrupt. Whenever the code reaches 'main:' and b7 is zero, you clear C.3 (hours8).

Whether that's it or not I don't know but it's a possible scenario. All sorts of weird things can happen when the code design isn't right. All you can do is fix one thing at a time, then move onto the next.
I switch high the other outputs first in the interrupt so I would expect the other LEDs to light up as well (or at least first). I can't see why ONLY C.3 lights up. (and before you ask, I have checked all the other LEDs work. Indeed the whole system works when I remove the interrupt).

Sorry for the constant stream of this but it's doing my head in!

Many, many thanks for all your help. I do really appreciate it.
 

hippy

Ex-Staff (retired)
I am using the little download pcb with the jack socket and the resistors on it, and removing it after programming, so there is no 10k/22k resistor network.
But presumably serial is coming in from somewhere, and if that's Nxxxx baud rate, active low, then you'll be continually entering interrupt.

If you have the input not connected, floating, then that's another 'spanner in the works' which could be affecting things.

As for the other point ... I can't see why ONLY C.3 lights up.
I'd ignore that issue as it could well be a red herring. Get serial working and then see how it goes. The flashing light is distracting you from what looks to be the fundamental problem, but yes it seems odd.

I'd say take out all code, including LED control, until you have the serial working perfectly and then add the code back in a bit at a time, testing as you go.
 

rokison

New Member
But presumably serial is coming in from somewhere, and if that's Nxxxx baud rate, active low, then you'll be continually entering interrupt.

If you have the input not connected, floating, then that's another 'spanner in the works' which could be affecting things.
The signal on the interrupt pin is being controlled by a transistor and a pull-up resistor, and has been checked using a multimeter and proved to be at 5V.
 

hippy

Ex-Staff (retired)
The signal on the interrupt pin is being controlled by a transistor and a pull-up resistor, and has been checked using a multimeter and proved to be at 5V.
As the interrupt pin is the same you're reading serial on ( and is also Download Serial In ) then that seems to indicate the idle state is +5V, high, so you should be using Txxxx baud rates to read the serial, but I'm not sure what effect this would have; whether holding Download Serial In high will let the PICAXE execute the DISCONNECT to prevent a download being detected.

What you describe would be a very peculiar setup and would not be recommended. It's also not entirely clear what you exactly have. I would recommend you post a full circuit diagram.
 

Technical

Technical Support
Staff member
The signal on the interrupt pin is being controlled by a transistor and a pull-up resistor, and has been checked using a multimeter and proved to be at 5V.
If we had this info at the start it would have made much more sense!

This is just a completely wrong design for the serial download pin. What is happening at power up is that the serrxd pin is being held high by your transistor. This tells the PICAXE chip to start a new download and so it 'replies' via the sertxd pin (which is why you see the LED flicker).

The download fails, the chip resets, it checks the serrxd line, thinks a new download is in progress and hence replies again. Vicious circle that continues forever.

So none of your BASIC program ever processes, as it never gets a chance to get to the BASIC processing stage, so your 'disconnect' command never gets a chance to process.
 

rokison

New Member
If we had this info at the start it would have made much more sense!

This is just a completely wrong design for the serial download pin. What is happening at power up is that the serrxd pin is being held high by your transistor. This tells the PICAXE chip to start a new download and so it 'replies' via the sertxd pin (which is why you see the LED flicker).

The download fails, the chip resets, it checks the serrxd line, thinks a new download is in progress and hence replies again. Vicious circle that continues forever.

So none of your BASIC program ever processes, as it never gets a chance to get to the BASIC processing stage, so your 'disconnect' command never gets a chance to process.
AMAZING!
Thank you so much.
Should have realised this.
I shall do a redesign and see if I can use another pin.
Many many thanks again, and sorry for the rookie error!
 
Top