How to know which of 3 pins is interrupted?

4jaba6

New Member
Am using a 20M2 and only pins C.1---> C.5 can be interrupted on this processor.
I have 2 pins ( C.2 and C.3 ) and want to know which one goes low and causes an interrupt.
I wish to identify which by flashing a red ( C.2 ) or green ( C.3 ) led.

Code to interrupt "ONE" pin could be:

Code:
Symbol InputA = PINC.2

main:
setint %00000000, %00000100
pause 500
high 5           'Yellow LED
pause 1000
low 5
pause 1000
goto main

interrupt:
If pin 2 = 0 then interrupt
If InputA = 0 then Flashred 
Goto Interdone

interdone:
setint %00000000, %00000100
return

Flashred:
low 5
high 4
pause 2000
low 4
pause 200
goto interdone

I need help programming with identifying if PINC.3 ( and not C.2 after checking it for interrupt ) is interrupted with the conditions/constraints of "interrupt coding"?.
How could I also check PINC.3 after checking PINC.2?
I cannot use:  "setint %00000000, %00001100" because this means BOTH 
pins must go low to cause an interrupt. (Manual "Getting Started", bottom page 68 ). 

Thanks in Advance
 
Am using a 20M2 and only pins C.1---> C.5 can be interrupted on this processor.
I have 2 pins ( C.2 and C.3 ) and want to know which one goes low and causes an interrupt.
I wish to identify which by flashing a red ( C.2 ) or green ( C.3 ) led.

Code to interrupt "ONE" pin could be:

Code:
Symbol InputA = PINC.2

main:
setint %00000000, %00000100
pause 500
high 5           'Yellow LED
pause 1000
low 5
pause 1000
goto main

interrupt:
If pin 2 = 0 then interrupt
If InputA = 0 then Flashred
Goto Interdone

interdone:
setint %00000000, %00000100
return

Flashred:
low 5
high 4
pause 2000
low 4
pause 200
goto interdone

I need help programming with identifying if PINC.3 ( and not C.2 after checking it for interrupt ) is interrupted with the conditions/constraints of "interrupt coding"?.
How could I also check PINC.3 after checking PINC.2?
I cannot use:  "setint %00000000, %00001100" because this means BOTH
pins must go low to cause an interrupt. (Manual "Getting Started", bottom page 68 ).

Thanks in Advance
OOOPS! Title should be "Which of 2 pins" and not "3"!
 
Hi,

The simple answer is that, on entry into the interrupt routine, the program tests which pin is low !

But it's more complicated if the interrupt condition "disappears" before the interrupt is serviced. Then, it's possible to use the "Interrupt on Change" Flags byte. The flags can be read with a PEEKSFR command, but it's quite complicated because the PICaxe Port.Pin numbers are not (necessarily) the same as the base PIC's Port.Pin numbering (which is why only 5 interrupt inputs are available). If you need to do this, ask again and I can give links to some of the details.

EDIT: Hmm, the 14M2 and 20M2 are "complicated" because the "Base PIC" names its ports A, B and C, but PICaxe names only B and C with a different (but neater) port and number mapping. I've not noticed before that the IOC feature is available only on PIC ports A and B, but all PICaxe interrupts are on Port C, so there appear to be NO interrupt pins on these two chips, nor the 18M2, which can support Interrupt On Change. :( Thus you would need to link together pairs of suitable pins to achieve a PICaxe Interrupt with IOC detection capability. The 08M2 has only one port (internally named A), but the PICaxe compiler accepts either B or C, so it appears to be the ONLY M2 which happens to support interrupts with IOC on nearly ALL of its pins (for no physical reason, the compiler excludes interrupts on the Programming Input and Output pins).

BTW, your present interrupt structure looks rather "strange", and you shouldn't generally be using PAUSEs within an interrupt routine.

Cheers, Alan.
 
Last edited:
Hi John, As Alan mentions, pauses in the interrupt routine can be problematic. While executing code in the interrupt routine, interrupts are disabled. If either input pin changes state to low while executing the interrupt code (eg during the 2+ seconds it takes to exit the interrupt routine), then it will not be detected. I'm also presuming you have pullups on these two inputs.
 
Many moons ago I had a similar problem, determining which of two powerline zero-crossing was coming ahead of the other. I only had 1/120 seconds to execute the code, and the Picaxe simply couldn’t do it reliably.
Keyword: Reliably.

I had to use an external flip-flop to latch the event.
Sorry, I know this isn’t the answer you were expecting.
 
Last edited:
Hi John, As Alan mentions, pauses in the interrupt routine can be problematic. While executing code in the interrupt routine, interrupts are disabled. If either input pin changes state to low while executing the interrupt code (eg during the 2+ seconds it takes to exit the interrupt routine), then it will not be detected. I'm also presuming you have pullups on these two inputs.
Ally Cat, Inglewood and Fernando, I am replying via Inglewood's message because he is a good friend of mine. Thank you ALL for your responses and detailed information. I do not have time today but hopefully next week to dive into and absorb your technical suggestions. I have only a rudimentary understanding of electronics and no formal training in Basic but almost 60 years ago was trained in COBOL ( yes, am a fossil! )
( however, could probably get a position with FAA using their hardware....apologies to my US compatriots because I should not be bashing my home country on this international forum! ). The 2+ sec info was right away helpful. I can understand that quickly but much of the rest is "complicated" and hopefully not above my pay grade. I did find a temporary "work-around" at the bottom of page 69 of PICAXE manual, Section 1 " Getting Started".
It does not use interrupts but may work and quite possibly one have to use the code several times if used in a long program, I also posted the following question to X a. I. ( GROK ) and Chat GPT and got some very interesting answers which also have not yet had time to absorb.
One question( request )....
"I am attempting to write a program for the Picaxe 20M2 microprocessor using "interrupt code.
I am using 2 pins: C.2 and C.3, either of which can go low if an outside condition
trips the pin (they will not both go low at the same time ). To identify which pin goes low, the code should light an led ( different color for each pin ). An example of possible similar code for only "one pin" is given at the top of page 69 in the PicAxe manual titled "Getting Started".
I am requesting you assist and provide code for "two" pins."
One of the responses from GROK as I posted Followup questions was:


"#picaxe 20m2

symbol LED1 = B.0 ; LED for pin C.2 (e.g., red LED) symbol LED2 = B.1 ; LED for pin C.3 (e.g., green LED)

; Set pins B.0 and B.1 as outputs dirsB = %00000011

; Start with interrupt on C.2 going low setint %00000000, %00000100 ; Interrupt when C.2 = 0

main: pause 10 ; Short pause to allow interrupt checking ; If no interrupt, switch to check C.3 setint %00000000, %00001000 ; Interrupt when C.3 = 0 pause 10 ; Short pause ; Switch back to check C.2 setint %00000000, %00000100 ; Interrupt when C.2 = 0 goto main

interrupt: if pinC.2 = 0 then high LED1 ; Turn on LED1 do : loop until pinC.2 = 1 ; Wait until pin C.2 goes high low LED1 ; Turn off LED1 elseif pinC.3 = 0 then high LED2 ; Turn on LED2 do : loop until pinC.3 = 1 ; Wait until pin C.3 goes high low LED2 ; Turn off LED2 endif ; Re-enable interrupt for C.2 setint %00000000, %00000100 ; Interrupt when C.2 = 0 return"

Again , I have not had time to review this prog. or any of the other responses as I questioned with a. I.

Thank you all again for your assistance,

John
 
Hi,

The first question should be "Why do you want (or think you need) to use interrupts?". They really aren't one of PICaxe's strengths (particularly M2s); Polled, with no Address Vectoring, no User-Priority selection, nor Error-handling capabilities, etc..

Strictly, you shouldn't be telling "A.I" (or anybody else) that you need/want to use interrupts, you should specify a "Requirements Specification" and leave the responder to offer a solution which might involve interrupts (if necessary). Of course you could ask the A.I. for an example of "When interrupts would be appropriate" and work from there. ;)

In my (limited) experience, ChatGPT/A.I. generally produces a "plausible" result, but not normally functional, or at least not in any way creative. However, your posted code doesn't even look that good, because it doesn't seem to understand the (separator) significance of NewLines (CR, LF), and tends to put comments both before and after the active Code. I've tidied up the listing to what I think was intended (it now passes a Syntax check):
Code:
#picaxe 20m2
symbol LED1 = B.0      ; LED for pin C.2 (e.g., red LED)
symbol LED2 = B.1      ; LED for pin C.3 (e.g., green LED)
; Set pins B.0 and B.1 as outputs
dirsB = %00000011
; Start with interrupt on C.2 going low
setint %00000000, %00000100   ; Interrupt when C.2 = 0
main:
pause 10                      ; Short pause to allow interrupt checking
; If no interrupt, switch to check C.3
setint %00000000, %00001000   ; Interrupt when C.3 = 0
pause 10                      ; Short pause ; Switch back to check C.2
setint %00000000, %00000100   ; Interrupt when C.2 = 0
goto main

interrupt:
if pinC.2 = 0 then
   high LED1                  ; Turn on LED1
   do : loop until pinC.2 = 1 ; Wait until pin C.2 goes high
   low LED1                   ; Turn off LED1
elseif pinC.3 = 0 then
   high LED2                  ; Turn on LED2
   do : loop until pinC.3 = 1    ; Wait until pin C.3 goes high
   low LED2                   ; Turn off LED2
endif                         ; Re-enable interrupt for C.2
setint %00000000, %00000100 ; Interrupt when C.2 = 0    [should set C.2 and C.3 as in main: ]
return

Firstly, the A.I. doesn't appear to understand the concept of Interrupts, because it's continually changing the interrupt configuration as one might multiplex a Keypad input. So main: should simply contain a single setint %00000000, %00001100 ; Interrupt when C.2 or C.3 = 0 and then go off and do something else useful (otherwise there's no need for an interrupt structure).

The interrupt: section does seem to do (approximately) what you've asked for, but it just waits (with the LED lit) until the Interrupt request (pulse) is removed. Thus the LEDs are doing no more than mirroring the status of the Interrupt line(s), and not even that if both lines are activated together. Interrupts are difficult enough to use anyway, without allowing them to totally "Hijack" the program flow, potentially forever (i.e. far worse than containing a PAUSE). Reminiscent of the "Blue Screen of Death" :(

Cheers, Alan.
 
Hi,

The first question should be "Why do you want (or think you need) to use interrupts?". They really aren't one of PICaxe's strengths (particularly M2s); Polled, with no Address Vectoring, no User-Priority selection, nor Error-handling capabilities, etc..

Strictly, you shouldn't be telling "A.I" (or anybody else) that you need/want to use interrupts, you should specify a "Requirements Specification" and leave the responder to offer a solution which might involve interrupts (if necessary). Of course you could ask the A.I. for an example of "When interrupts would be appropriate" and work from there. ;)

In my (limited) experience, ChatGPT/A.I. generally produces a "plausible" result, but not normally functional, or at least not in any way creative. However, your posted code doesn't even look that good, because it doesn't seem to understand the (separator) significance of NewLines (CR, LF), and tends to put comments both before and after the active Code. I've tidied up the listing to what I think was intended (it now passes a Syntax check):
Code:
#picaxe 20m2
symbol LED1 = B.0      ; LED for pin C.2 (e.g., red LED)
symbol LED2 = B.1      ; LED for pin C.3 (e.g., green LED)
; Set pins B.0 and B.1 as outputs
dirsB = %00000011
; Start with interrupt on C.2 going low
setint %00000000, %00000100   ; Interrupt when C.2 = 0
main:
pause 10                      ; Short pause to allow interrupt checking
; If no interrupt, switch to check C.3
setint %00000000, %00001000   ; Interrupt when C.3 = 0
pause 10                      ; Short pause ; Switch back to check C.2
setint %00000000, %00000100   ; Interrupt when C.2 = 0
goto main

interrupt:
if pinC.2 = 0 then
   high LED1                  ; Turn on LED1
   do : loop until pinC.2 = 1 ; Wait until pin C.2 goes high
   low LED1                   ; Turn off LED1
elseif pinC.3 = 0 then
   high LED2                  ; Turn on LED2
   do : loop until pinC.3 = 1    ; Wait until pin C.3 goes high
   low LED2                   ; Turn off LED2
endif                         ; Re-enable interrupt for C.2
setint %00000000, %00000100 ; Interrupt when C.2 = 0    [should set C.2 and C.3 as in main: ]
return

Firstly, the A.I. doesn't appear to understand the concept of Interrupts, because it's continually changing the interrupt configuration as one might multiplex a Keypad input. So main: should simply contain a single setint %00000000, %00001100 ; Interrupt when C.2 or C.3 = 0 and then go off and do something else useful (otherwise there's no need for an interrupt structure).

The interrupt: section does seem to do (approximately) what you've asked for, but it just waits (with the LED lit) until the Interrupt request (pulse) is removed. Thus the LEDs are doing no more than mirroring the status of the Interrupt line(s), and not even that if both lines are activated together. Interrupts are difficult enough to use anyway, without allowing them to totally "Hijack" the program flow, potentially forever (i.e. far worse than containing a PAUSE). Reminiscent of the "Blue Screen of Death" :(

Cheers, Alan.
Alan,

Thank you for supplying the "Tidy Up" code! It tested and works well for me. Later I shall attempt to insert in a lengthy program.
As to why I am attempting to use interrupts, it is because I may possibly need to use in a future program. The only alternative seems to be the "polling" I mentioned in my previous "work-around" post. However, this would probably have to be done multiple times in the code because of not using an "interrupt".
After your code you stated that a "setint %00000000, %00001100: Interrupt when C.2 OR C.3 = 0" could be used. I do not understand the "OR".
The Picaxe manual Section 2 page 226 says: "- SETINT %10000000,%10000100 The interrupt will then occur when, and only when, pin 7 is high and pin 2 is low. If pin 7 is low or pin 2 is high the interrupt will not happen as two pins are‘looked at’ in the mask. "
It is my understanding that "BOTH" pins in your example of tidy up code would cause an interrupt but not just one pin ( the "OR" )? I do not want both pins tripped to cause an interrupt, but only one pin at a time. This you did in your "Tidy Up" code.
Thanks again for massaging the "GROK" code and making it workable as well as your other useful info throughout this thread.

Best, John
 
I asked ChatGPT a similar question, and below is the answer....
( I apologize for the code not being in the required format and not cleaned up as Alan did with my previous ex.
I plan on doing this and furnishing it to the forum after I tidy it up and test it. )

You said:​

I am attempting to write a program for the Picaxe 20M2 microprocessor.I am using 2 pins: C.2 and C.3, either of which can go low if an outside condition trips the pin using an interrupt (they will not both go low at the same time ). To identify which pin goes low, the code should light an led ( different color for each pin B.4 for C.2 and B.5 for C.3 ). An example of possible similar code for only "one pin" is given at the top of page 69 in the PICAXE manual titled "Getting Started". I am requesting you assist and provide code using "interrupt" for sequentially checking the "two" pins.

ChatGPT said:​

Got it — you want to handle two separate input pins (C.2 and C.3) on a PICAXE 20M2 using an interrupt-based approach so that when either pin goes low, it triggers an action (lighting a different LED for each pin). You also mentioned that only one pin will ever be low at a time.

Since the PICAXE setint command only lets you watch a pattern of inputs at one time, we’ll need to:

  1. Set the interrupt to trigger whenever either C.2 or C.3 goes low.
  2. Inside the interrupt routine, check which pin caused it.
  3. Light the correct LED (B.4 for C.2, B.5 for C.3).
  4. Clear LEDs when reset.
  5. Re-enable the interrupt after servicing it.
Here’s working example code:

picaxe
CopyEdit
; PICAXE 20M2<br>; C.2 input -&gt; LED on B.4<br>; C.3 input -&gt; LED on B.5<br>; Interrupt triggers if either C.2 or C.3 goes low<br><br>symbol LED_C2 = B.4<br>symbol LED_C3 = B.5<br>symbol PIN_C2 = pinC.2<br>symbol PIN_C3 = pinC.3<br><br>; ----------------------------<br>; Setup<br>; ----------------------------<br>init:<br> high LED_C2 ; start LEDs off (high for active-low wiring, low if direct drive)<br> high LED_C3<br> setint %00001100, %00000000 ; Watch C.2 and C.3, trigger when either goes low<br> ; Mask bits: C.3 = bit 3, C.2 = bit 2<br>main:<br> ; Main loop does nothing — waiting for interrupts<br> pause 100<br> goto main<br><br>; ----------------------------<br>; Interrupt Service Routine<br>; ----------------------------<br>interrupt:<br> if PIN_C2 = 0 then<br> low LED_C2<br> high LED_C3<br> elseif PIN_C3 = 0 then<br> low LED_C3<br> high LED_C2<br> endif<br><br> ; Wait for condition to clear before re-enabling<br> do : loop while PIN_C2 = 0 or PIN_C3 = 0<br><br> ; Turn LEDs off (or set as desired)<br> high LED_C2<br> high LED_C3<br><br> ; Re-enable interrupt<br> setint %00001100, %00000000<br> return<br>

How It Works​

  • setint %00001100, %00000000
    • %00001100 is the mask — bits 2 (C.2) and 3 (C.3) are monitored.
    • %00000000 is the pattern — we want an interrupt when both bits are not high (i.e., when either is low).
  • When the interrupt triggers, the interrupt: label runs.
  • The code checks pinC.2 and pinC.3 to see which caused it.
  • The correct LED is lit while the other stays off.
  • The routine waits until the pin returns high before re-enabling the interrupt.
 
I asked ChatGPT a similar question, and below is the answer....
( I apologize for the code not being in the required format and not cleaned up as Alan did with my previous ex.
I plan on doing this and furnishing it to the forum after I tidy it up and test it. )

You said:​

I am attempting to write a program for the Picaxe 20M2 microprocessor.I am using 2 pins: C.2 and C.3, either of which can go low if an outside condition trips the pin using an interrupt (they will not both go low at the same time ). To identify which pin goes low, the code should light an led ( different color for each pin B.4 for C.2 and B.5 for C.3 ). An example of possible similar code for only "one pin" is given at the top of page 69 in the PICAXE manual titled "Getting Started". I am requesting you assist and provide code using "interrupt" for sequentially checking the "two" pins.

ChatGPT said:​

Got it — you want to handle two separate input pins (C.2 and C.3) on a PICAXE 20M2 using an interrupt-based approach so that when either pin goes low, it triggers an action (lighting a different LED for each pin). You also mentioned that only one pin will ever be low at a time.

Since the PICAXE setint command only lets you watch a pattern of inputs at one time, we’ll need to:

  1. Set the interrupt to trigger whenever either C.2 or C.3 goes low.
  2. Inside the interrupt routine, check which pin caused it.
  3. Light the correct LED (B.4 for C.2, B.5 for C.3).
  4. Clear LEDs when reset.
  5. Re-enable the interrupt after servicing it.
Here’s working example code:

picaxe
CopyEdit
; PICAXE 20M2<br>; C.2 input -&gt; LED on B.4<br>; C.3 input -&gt; LED on B.5<br>; Interrupt triggers if either C.2 or C.3 goes low<br><br>symbol LED_C2 = B.4<br>symbol LED_C3 = B.5<br>symbol PIN_C2 = pinC.2<br>symbol PIN_C3 = pinC.3<br><br>; ----------------------------<br>; Setup<br>; ----------------------------<br>init:<br> high LED_C2 ; start LEDs off (high for active-low wiring, low if direct drive)<br> high LED_C3<br> setint %00001100, %00000000 ; Watch C.2 and C.3, trigger when either goes low<br> ; Mask bits: C.3 = bit 3, C.2 = bit 2<br>main:<br> ; Main loop does nothing — waiting for interrupts<br> pause 100<br> goto main<br><br>; ----------------------------<br>; Interrupt Service Routine<br>; ----------------------------<br>interrupt:<br> if PIN_C2 = 0 then<br> low LED_C2<br> high LED_C3<br> elseif PIN_C3 = 0 then<br> low LED_C3<br> high LED_C2<br> endif<br><br> ; Wait for condition to clear before re-enabling<br> do : loop while PIN_C2 = 0 or PIN_C3 = 0<br><br> ; Turn LEDs off (or set as desired)<br> high LED_C2<br> high LED_C3<br><br> ; Re-enable interrupt<br> setint %00001100, %00000000<br> return<br>

How It Works​

  • setint %00001100, %00000000
    • %00001100 is the mask — bits 2 (C.2) and 3 (C.3) are monitored.
    • %00000000 is the pattern — we want an interrupt when both bits are not high (i.e., when either is low).
  • When the interrupt triggers, the interrupt: label runs.
  • The code checks pinC.2 and pinC.3 to see which caused it.
  • The correct LED is lit while the other stays off.
  • The routine waits until the pin returns high before re-enabling the interrupt.

OK, code is tidy'd up but not tested.... ( from ChatGPT )

[CODE}
; PICAXE 20M2
; C.2 input -> LED on B.4
; C.3 input -> LED on B.5
; Interrupt triggers if either C.2 or C.3 goes low

symbol LED_C2 = B.4
symbol LED_C3 = B.5
symbol PIN_C2 = pinC.2
symbol PIN_C3 = pinC.3

; ----------------------------
; Setup
; ----------------------------
init:
high LED_C2 ; start LEDs off (high for active-low wiring, low if direct drive)
high LED_C3
setint %00001100, %00000000 ; Watch C.2 and C.3, trigger when either goes low
; Mask bits: C.3 = bit 3, C.2 = bit 2
main:
; Main loop does nothing — waiting for interrupts
pause 100
goto main

; ----------------------------
; Interrupt Service Routine
; ----------------------------
interrupt:
if PIN_C2 = 0 then
low LED_C2
high LED_C3
elseif PIN_C3 = 0 then
low LED_C3
high LED_C2
endif

; Wait for condition to clear before re-enabling
do : loop while PIN_C2 = 0 or PIN_C3 = 0

; Turn LEDs off (or set as desired)
high LED_C2
high LED_C3

; Re-enable interrupt
setint %00001100, %00000000
return
 
Hi,

Sorry, my "; Interrupt when C.2 or C.3 = 0" in #7 was a comment and I was being lazy; it should have said "Interrupt when C.2 = 0 or C.3 = 0".

The code immediately above in #10 looks as if it should work, but I still take the view that it's not acceptable for the interrupt to "Wait" until the input request finishes. IMHO the correct structure is to switch ON a LED and then exit. Then later, the interrupt would be entered again to switch the LED OFF. The second interrupt might be when the interrupt request signal ends, or perhaps a timed interrupt to occur after say 2 seconds. Therefore, I wrote a simple Demo Program:
Code:
#picaxe 20m2
symbol LED1 = B.0     ; LED for pin C.2 (e.g., red LED)
symbol LED2 = B.1     ; LED for pin C.3 (e.g., green LED)
symbol last = b0         ; Contains bit7 .... bit0
dirsB = %00000011
last = %00001100
setint last , %00001100         ; Interrupt when C.2 = 0 OR C.3 = 0
do
   pause 100
loop

interrupt:
if pinC.2 = bit2 then
   toggle LED1                 ; Turn on/off LED1
   last = last XOR %00000100
else if pinC.3 = bit3 then
   toggle LED2                  ; Turn on/off LED2
   last = last XOR %00001000
endif   
setint last , %00001100      ; Re-enable interrupts
return
Now I'm only using the simulator (in PE5, however PE6 appears to behave the same), but that code doesn't work as (I) intended. Often it doesn't enter the interrupt routine when expected, and even more surprising it doesn't exit the interrupt at the end. :( Looking at the on-line command syntax, it appears that the default for multiple bits is AND , but it then explains that the keyword OR may be used with M2 and X2 chips, with variable or constant parameters. However, a Syntax check responds with "Error: setint 'OR' only supports constants". Even in this example, there are 4 permutations for the variable "last" (and the number might be into high double-digits) so IMHO a Branch to all possible versions of SETINT const , const is not acceptable, but I don't know how else to code it. The Syntax check does accept the NOT keyword (apparently NOT AND), which seems to give a more correct Simulation output, but only because it continues to loop within the Interrupt routine rather than exiting.

EDIT: Of course with Active Low (Negative Logic) signals, the (Positive Logic) AND becomes OR and vice versa, however the simulation still doesn't seem to work as I would have expected.

I'm getting to hate Interrupts even more than before. :(

Cheers, Alan.
 
Last edited:
I apologize for the code not being in the required format
4jaba6,

FYI: The reason that you are getting unformatted code, like in your post #9, appears to be a side-effect of how you are saving the code that ChatGPT produces.

I didn't recognize the <br> string in the code and when I googled it, it is the html syntax for a carriage return.
So I cut-and-pasted the code from your post #9 into a text file "tests.html", opened it in a web browser and the code with the <br> strings is displayed formatted with carriage returns as we would expect:
tests_html.PNG

What method are you using to save the output from ChatGPT to paste into your post?
 
4jaba6,

FYI: The reason that you are getting unformatted code, like in your post #9, appears to be a side-effect of how you are saving the code that ChatGPT produces.

I didn't recognize the <br> string in the code and when I googled it, it is the html syntax for a carriage return.
So I cut-and-pasted the code from your post #9 into a text file "tests.html", opened it in a web browser and the code with the <br> strings is displayed formatted with carriage returns as we would expect:
View attachment 26723

What method are you using to save the output from ChatGPT to paste into your post?
Flesner,

Currently I know of no way of saving a ChatGPT reply. I would like to know!
What I do is highlite and copy and then paste to email or in some cases if code
paste to a Picaxe program. I hope this answered your question and thanks for the input.

JB
 
This is my take on coding this exercise. (And I'm not a fan of so-called AI for code preparation).
  • Interrupts are only active when button press input is required
  • Neither input gets priority over the other, since a copy of the port inputs is processed
  • Interrupts are reenabled once the red or green LED flash has completed
  • You may need to adjust pin symbol definitions for LEDs to suit your hardware
  • I have used PinC.2 and PinC.3 as inputs because these were specified in the original code
Since I don't have the exact hardware configured, the code is syntax-checked but has not been tested.

Rich (BB code):
#PICAXE 20M2
Symbol InputA = PinC.2
Symbol InputB = PinC.3
Symbol RedLED = C.4
Symbol YellowLED = C.5
'Pin C.6 is input only
Symbol GreenLED = C.7

Symbol Counter = b10

Init: SetInt %00000000, %00001100
      b0 = 255
      Pause 500
Main: Do
         If Counter = 0 Then  'Waiting for a button press
            High YellowLED
            Pause 100         '2 x 100mS gives a 200mS loop time
            Low YellowLED
            Pause 100
         Else                 'Timer is active
            Dec Counter
            If Counter = 0 Then
               Low RedLED
               Low GreenLED
               SetInt %00000000, %00001100
            Else
               Pause 200      'Maintain a 200mS loop period
            EndIf
         EndIf
      Loop
   
Interrupt:  b0 = PinsC        'Take a copy of all input pin of PortC
            If bit2 = 0 Then
               High RedLED
               Counter = 10   'Loop Counter (200mS Loop times 10)
            EndIf
            If bit3 = 0 Then
               High GreenLED
               Counter = 10
            EndIf
            ' Don't restore interrupts until Flash Timer Counter has expired
            Return
 
This is my take on coding this exercise. (And I'm not a fan of so-called AI for code preparation).
  • Interrupts are only active when button press input is required
  • Neither input gets priority over the other, since a copy of the port inputs is processed
  • Interrupts are reenabled once the red or green LED flash has completed
  • You may need to adjust pin symbol definitions for LEDs to suit your hardware
  • I have used PinC.2 and PinC.3 as inputs because these were specified in the original code
Since I don't have the exact hardware configured, the code is syntax-checked but has not been tested.

Rich (BB code):
#PICAXE 20M2
Symbol InputA = PinC.2
Symbol InputB = PinC.3
Symbol RedLED = C.4
Symbol YellowLED = C.5
'Pin C.6 is input only
Symbol GreenLED = C.7

Symbol Counter = b10

Init: SetInt %00000000, %00001100
      b0 = 255
      Pause 500
Main: Do
         If Counter = 0 Then  'Waiting for a button press
            High YellowLED
            Pause 100         '2 x 100mS gives a 200mS loop time
            Low YellowLED
            Pause 100
         Else                 'Timer is active
            Dec Counter
            If Counter = 0 Then
               Low RedLED
               Low GreenLED
               SetInt %00000000, %00001100
            Else
               Pause 200      'Maintain a 200mS loop period
            EndIf
         EndIf
      Loop
   
Interrupt:  b0 = PinsC        'Take a copy of all input pin of PortC
            If bit2 = 0 Then
               High RedLED
               Counter = 10   'Loop Counter (200mS Loop times 10)
            EndIf
            If bit3 = 0 Then
               High GreenLED
               Counter = 10
            EndIf
            ' Don't restore interrupts until Flash Timer Counter has expired
            Return
Thanks Peter,

I have not judged a. i. because I have only tried it in this ( thread ) situation.
GROK came very close in its first try; Alan tidied it up and it seemed to work well.

ChatGPT missed on its first try. I subsequently made Chat aware of the issues and posed a different question and it gave a new
program. Alan "tidied" it up but I have not had a chance to test yet as well as not tested Flenser's code.
I shall add your code to the list and hopefully test all three prog.'s this week.

It is amazing to me that a. i. nailed it with Grok and came close with ChatGPT. Perhaps I did not
pose my question properly. I think a. I. is a great "tool" and only that. That is to say "buyer beware"
but has possibility of saving a lot of time in many situations ( esp. for the likes of me a somewhat lazy person ).
At the risk of stating the obvious, am basically saying the a. i. code has to be reviewed and then tested and not accepted as gospel.


Best, John
 
Hi,
GROK came very close in its first try; Alan tidied it up and it seemed to work well.
Yes, it appears to make the LEDs flash correctly, BUT it's not actually "Using" interrupts ! It was repeatedly swapping the test condition in main: and a jump to interrupt: occurs when the conditions match. Also, I wonder what it would have offered if you had asked for a Positive-going interrupt. I haven't yet managed to get that to run correctly in the Simulator and am suspecting a Bug in the PICaxe Compiler, Interpreter or Simulator. :(

But it certainly did better than ChatGPT, which has managed to get the mask and mode/polarity bytes swapped :eek:. Also, IMHO it's a very poor "tutor" with at least three examples of poor practice. First, the ; PICAXE 20M2 at the top is commendable, but it's only as a Comment which can be ignored or even wrong. Written as #PICAXE 20M2 almost guarantees that we and our hardware will all be using the same/correct compiler. Second, there is no indenting in the listing, not essential for most languages but certainly good practice. Thirdly the GOTO main: . Now I am certainly NOT a "Purist Programmer" and will often use and defend the GOTO. But in this particular case, surely the following is a preferable construction?
Code:
DO
   PAUSE 100 ; Waiting for an Interrupt
LOOP

In my very limited trials of A.I. I have been quite impressed by the "plausibility" of the answer, by my response has nearly always been "Yes, BUT....". The answer has usually been, "Yes, you're correct so ....", but after about 4 iterations I found us back where we started. Recently, I asked how to Disable Interrupts on a PICaxe M2 (expecting to be told it wasn't possible) so was surprised by the (technically correct) response to use SETINT OFF . Then I realised I should have asked how to Re-Enable Interrupts, and received a vague reference to doing that at the end of the Interrupt Routine. :

However, the issue is that it's often necessary to Disable and Re-Enable interrupts in a subroutine in an entirely different section of a large program, where the writer may have no idea what other interrupt flags might have been set up. Of course the answer is to keep a record in variables for the mode and mask bytes, so I was rather horrified to be told by the PICaxe Compiler (not the formal documentation) that the SETINT {OR} parameters are not permitted to be a variable.

For me, there are two Golden Rules for using Interrupts (in addition to "Don't..." :) ). Firstly, exit the Interrupt Routine as quickly as possible (i.e. no Pauses of any type) and secondly, ensure that you don't use the same variable for different purposes inside and outside of the Interrupt routine. This can be quite difficult with PICaxe because it has no concept of "Local" variables, so very much limits the use of generalised subroutines and the @BPTR command/variable, etc.. The answer of course is to "Bank Switch" all the main working variables, but how many PICaxe programmers are actually going to do that?

Cheers, Alan.
 
Alan,

WOW, a trainload of info. I appreciate the info and your diligence into info that will probably take me awhile to digest.
I am getting an education on interrupts that I never expected. Thanks for the info and I look forward to putting on my thinking cap and
studying it in more depth than my so far cursory read. Did read enough to enjoy the "Don't"!

John
 
Back
Top