PDA

View Full Version : Rotary encoder with DT interrupts



louislouis
- 15th December 2020, 22:28
Hi All,
I'm struggling around rotary encoder with push button. I read the forum but not find any successfully solved example.
Here is my code:


; PIC16F1847

#CONFIG ; 16FF1847.
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_OFF
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF
#ENDCONFIG

DEFINE OSC 32

OSCCON = %11110000 ;32 MHz

ANSELA = 0
ANSELB = 0
TRISA=%00000000
TRISB=%00000011
LATB = %00000011

Include "modedefs.bas"
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts

INTCON=%10001000
IOCBP=%00000000
IOCBN=%00000011 ;on change interrupt NEGATIVE port RB.0, RB.1
IOCBF=%00000011

wsave VAR BYTE $70 SYSTEM ' alternate save location for W

enc_new VAR BYTE bank0
enc_old VAR BYTE bank0
enc_counter VAR word bank0
Flag var BYTE bank0

asm
INT_LIST macro ;IntSource,Label, Type, Resetflag?
INT_Handler IOC_INT, _enc, asm, yes
endm
INT_CREATE ; Creates the interrupt processor
;================================================
endasm
; Set variable value @ startup
Flag = 0
enc_new = 0
enc_old = 0
enc_counter = 0

@ INT_ENABLE IOC_INT ; enable external (INT) interrupts

Main:
if flag=1 then
SEROUT portb.4,t9600,[#enc_counter,13]
endif

goto main

enc:
asm
;Read latest input from PORTB & put the value in _enc_new.
MOVE?CB 1,_Flag
movf PORTB,W
movwf _enc_new
;Strip off all but the 2 MSBs in _enc_new.
movlw B'00000011' ;Create bit mask (bits 1 & 0).
andwf _enc_new,F ;Zero bits 5 thru 0.
;Determine the direction of the Rotary encoder.
rlf _enc_old,F ;left shift it into _enc_old to align bit 6 of
;_enc_old with bit 7 of _enc_new.
movf _enc_new,W ;Move the contents of _enc_new to W in order to XOR.
xorwf _enc_old,F ;XOR previous inputs (in _enc_old) with latest
;inputs (in W) to determine CW or CCW.

btfsc _enc_old,0 ;Test bit 0 of result (in _enc_old). Skip next line
;if it is 0 (direction is CCW).
goto Up ;Bit is 1 (direction is CW). Go around Down
;and increment counter.

Down
;Decrements _enc_counter because the rotary encoder moved CCW.
;Decrements _enc_counter (16 bit value), sets Z on exit.

decf _enc_counter,F ; Decrement low byte
incfsz _enc_counter,W ; Check for underflow
incf _enc_counter+1,F ; Update
decf _enc_counter+1,F ; Fixup
movf _enc_counter,W
iorwf _enc_counter+1,W ; Set Z bit

;Add here code for the CCW LED if needed.

goto Continue ;Branch around UP.
Up
;Increments _enc_counter because the rotary encoder moved CW.
;Increments _enc_counter (16 bit value), sets Z on exit.
incfsz _enc_counter,W ; Add one to low byte
decf _enc_counter+1,F ; No carry (negates next step)
incf _enc_counter+1,F ; Add one to high byte
movwf _enc_counter ; Store updated low byte back.
iorwf _enc_counter+1,W ; Set Z flag

;Add here code for the CW LED if needed.

Continue

;Assign the latest encoder inputs (in _enc_new) to _enc_old.
movf _enc_new,W
movwf _enc_old
CHK?RP IOCBF
CLRF IOCBF
INT_RETURN
;============ END OF THE ROTARY ENCODER CODE =====
endasm

The problem is, I can't get correct encoder reading. In serial monitor I can see the result but the values goes only to increment no matter if I rotate CW or CCW.
The values increment randomly. I dont know, what is the problem.
The encoder is wired with 10k pullups and debounce capacitors.
I need quic response to rotation fot that I try to use this ASM and DT interrupts metod.

Anyway If I tried another example with no ASM and Interrupts only for testing, the encoder works fine CW and CCW, increments, decrements by one just fine.

Can someone check my code and correct me what Im doing wrong.
Thanks.

richard
- 15th December 2020, 23:11
for mechanical encoder with button i use something like this

louislouis
- 16th December 2020, 13:02
Cool, thanks. Both pbp,asm version works. Anyway, I tried two encoder types which I had on hand. Both works, but one count two counts to one detent, and the second count four to one detent.
I tried set the IOCBP and IOCBN to trigger only on positive edge or only on negative edge or different comination but it doesn't hepl.
Any trick to adjust this to one detent one count?

richard
- 16th December 2020, 21:56
oneway to count detents divide the absolute raw cnt value by the number of edges/detent ,then restore the sign
eg
sb= cnt.15
detents = abs(cnt)<<2; four edges
if sb then detents= ~detents+1

another is to just poll the rotation direction at an acceptable rate
if clockwise add a count if anticlockwise subtract


poll: ; call this sub say 5 times / sec or whatever
if cnt>lastcnt then
detent=detent+1
elseif cnt<lastcnt
detent=detent-1
endif
lastcnt=cnt
return

another way is to only inc/dec detent counter only when enca and encb both = 1 (ie at detent pos)
in the re isr

louislouis
- 31st December 2020, 10:05
Hi Richard, sorry for later response. Thanks for pointing me in to right way how to do it. Your first method not works for me, the second method polling works just fine but slows down the response time. The third method inc/dec detent counter only when enca and encb both = 1 works but count every second detent and also slowes down the reading.
My encoder has 30.position and give 15.pulses/rew. My solution is simply divide the CNT by 2.


enc_isr:
ev=ev<<2 ;shift last reading into position
ev=ev|((portb&12)>>2) ;read enc pins 2,3 mask off others then combine this reading with last reading
LOOKUP (ev&$f),[0,255, 1, 0, 1, 0, 0, 255, 255, 0, 0, 1, 0, 1, 255, 0],tmp ;lookup the decision matrix
if tmp then ; decide to inc , dec or ignore
if tmp.1 then
cnt=cnt+1
else
cnt=cnt-1
endif
endif
detent=cnt
detent=detent/2


By the way, here is the nearly finished product where i used this solution and skills learned here.

https://www.youtube.com/watch?v=AAf0UUN3kZ0

It's a stick welder controller with "advanced" functions like softstart, fan control, pulse welding, antistick, arcforce, hotstart, voltage and current measurement and so on.
It's based on PIC16F1847, when I used sw multiplexing, multiple interrupts, direct register controls, mixed code ASM/PB and so on.


Thanks for this great forum and helpful members, happy New Year to all.

wjsmarine
- 7th February 2021, 07:26
Hi Folks,

I'm trying to get my head around what is happening with my attempt at using a Rotary Encoder... it is functional however something weird is happening periodically returning from the interrupt.

My "I'm Alive" serial string is returned to and finds itself sprinkled among the debug terminal data. I'm sure it is staring at me but I can't see why. Any help appreciated.

Thanks,
Bill

PS
@ richard
I persisted for hours trying your method (with appropriate pin changes) and had no joy so went with the Old vs New method. It would only count in one direction with either CW or CCW.





'************************************************* ************************************************** *
'* Name : RE test WJS.pbp *
'* Author : WJ Sherwood *
'* Notice : Copyright (c) 2021 *
'* : All Rights Reserved *
'* Date : 07/02/21 *
'* Device : 16F1788 *
'* Version : 1 (PBP 3.0.10.4) *
'* Notes : Spurious "I'm Alive" serial traffic following RE action - what am I missing? *
'* : REa portb.6, REb portb.5, REsw portb.4 all pulled up, active low. *
'* : *
'************************************************* ************************************************** *
'

'================================================= ================================================== ======
' CONFIGURE DEVICE
'================================================= ================================================== ======
#CONFIG ; 16F1788.
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _LVP_OFF & _BORV_HI & _LPBOR_OFF
#ENDCONFIG

' -----[ Initialization ]------------------------------------------------------------------------------------------------
TRISA = %00000000 ' Set I/O.
TRISB = %01111111 ' Set I/O.
TRISC = %00000000 ' Set I/O.

define OSC 4
OSCCON = %01101010 ' 4Mhz (F1788).
'define OSC 32
' OSCCON = %11110000 ; 32 MHz,

ANSELA = 0 ; all digital
ANSELB = 0 ; all digital

' Define LCD connections
DEFINE LCD_DREG PORTA ' LCD Data Port
DEFINE LCD_DBIT 0 ' Starting Data Bit
DEFINE LCD_RSREG PORTA ' Register Select Port
DEFINE LCD_RSBIT 4 ' Register Select Bit
DEFINE LCD_EREG PORTA ' Enable Port
DEFINE LCD_EBIT 7 ' Enable Bit
DEFINE LCD_BITS 4 ' Data Bus Size
DEFINE LCD_LINES 2 ' Number of Lines on LCD

'================================================= ================================================== ======
' PIN ASSIGNMENTS, SYSTEM CONSTANTS, TEMPORARY VARIABLES
'================================================= ================================================== ======
' Rotary Encoder stuff
Old_Bits VAR BYTE bank0 ' Encoder port bits before change.
New_Bits VAR BYTE bank0 ' Encoder port bits after change.
RotEnc1_val VAR word bank0 ' Connected to PORTB<5:6>.
MaxLimit var word bank0 ' Used for setting upper limit for encoder counts.
RotEncDir VAR BIT bank0 ' Direction of rotation bit.
ButtPush var bit bank0 ' Flag shows button was pushed, allows quick exit from Int handler.


Include "MODEDEFS.BAS" ' Include Shiftin/out modes.
INCLUDE "DT_INTS-14.bas" ' Needs to be assembled with MPASM **********
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts

OPTION_REG.6 = 0 ' INTEDG set to interrupt on falling edge.
' OPTION_REG.6 = 1 ' INTEDG set to interrupt on rising edge.

' IOCBP = %01110000 ; REa portb.6, REb portb.5 pos edge trigger
IOCBN = %01110000 ; REa portb.6, REb portb.5, REsw portb.4 neg edge trigger - falling edge only.
IOCBF = 0 ; Reset the PortB flag.
INTCON = %11001000 ; GIE, PEIE, IOCIE.

' RotEnc1_val = 0 '
pause 500 ' Let everything settle...

'latc.6 = 0 ' Prevent garbled serial - newer PICs, true.
latc.6 = 1 ' Prevent garbled serial - newer PICs, inverted.
serout2 PORTC.6,16468,[13,10,"I'm Alive",13,10,10]

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Rot_Encoder, PBP, yes ; Newer PICs.
endm
INT_CREATE ; Creates the interrupt processor .
ENDASM

@ INT_ENABLE IOC_INT ; Newer PICs.
Old_Bits = PORTB & (%01100000) ; RE uses B.6,B.5 - REa and REb.
'Old_Bits = PORTB & (%01110000) ; RE uses B.6,B.5,B.4 - includes RE push button.


Main:
goto main ' endless loop waiting for INT.



'---[IOC - interrupt handler]---------------------------------------------------
Rot_Encoder:
if PortB.4 = 0 then ' Check if Encoder pushbutton was pushed.
serout2 PORTC.6,16468,[13,10,"ButtPush = 1, RE ",dec5 RotEnc1_val]
ButtPush = 1 ' Set the flag for a quick exit.
goto DoneRotEnc ' Clean up and exit.
endif

' Don't forget 4 counts per detent (Quadrature).
New_Bits = PORTB & (%01110000) ' Set port bits for Encoder's chosen A and B channels.
IF (New_Bits & %01110000) = (Old_Bits & %01110000) then DoneRotEnc ' No change.
RotEncDir = New_Bits.6 ^ Old_Bits.5 ' Bit XOR compare to get direction of rotation.
if RotEncDir = 0 then ' CCW so decrement.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val - 1 ' Decrement the count.
if RotEnc1_val => 65530 then RotEnc1_val = 0 ' Limit the max.
if RotEnc1_val <= 4 then RotEnc1_val = 0 ' Limit the min.
serout2 PORTC.6,16468,[13,10,"RE_val ",dec5 RotEnc1_val]
endif
ELSE ' RotEncDir = 1, CW so increment.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val + 1 ' Increment the count.
if RotEnc1_val >= MaxLimit then RotEnc1_val = MaxLimit ' Limit the count.
serout2 PORTC.6,16468,[13,10,"RE_val ",dec5 RotEnc1_val]
endif
ENDIF


DoneRotEnc:
Old_Bits = New_Bits
INTCON.0 = 0 ; Clean up and exit - clear IOCIF.
IOCBF = 0 ; Reset the flag.
@ INT_RETURN

end

richard
- 7th February 2021, 08:12
@ richard
I persisted for hours trying your method (with appropriate pin changes) and had no joy


all you have to do is post the code for your attempt and i will have a look


hints

serout2 PORTC.6,16468,[13,10,"RE_val ",dec5 RotEnc1_val] once in an isr is bad twice is just asking for trouble , use flags

using a pin change int for a switch is a giant over kill

wjsmarine
- 8th February 2021, 02:22
Hi Richard,

Thanks for your help and guidance, as always.

I took your hints and made appropriate adjustments (see below) but the rogue serial persists... With your preferred method I'd like to crack this existing problem before exploring your offer if that's okay.

Stay safe,
Bill






'************************************************* ************************************************** *
'* Name : RE test WJS.pbp *
'* Author : WJ Sherwood *
'* Notice : Copyright (c) 2021 *
'* : All Rights Reserved *
'* Date : 07/02/21 *
'* Device : 16F1788 *
'* Version : 1 (PBP 3.0.10.4) *
'* Notes : Spurious "I'm Alive" serial traffic following RE action (still) and corrupt chars if *
'* : Pause at line 75 (following MaxLimit = 60) removed - what am I missing? *
'* : *
'* : REa portb.6, REb portb.5, REsw portb.4 all pulled up, active low. *
'* : *
'************************************************* ************************************************** *

'================================================= ================================================== ======
' CONFIGURE DEVICE
'================================================= ================================================== ======
#CONFIG ; 16F1788.
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _LVP_OFF & _BORV_HI & _LPBOR_OFF
#ENDCONFIG

' -----[ Initialization ]---------------------------------------------------------------------------------
TRISA = %00000000 ' Set I/O.
TRISB = %01111111 ' Set I/O.
TRISC = %00000000 ' Set I/O.

define OSC 4
OSCCON = %01101010 ' 4Mhz (F1788).
'define OSC 32
' OSCCON = %11110000 ; 32 MHz,

ANSELA = 0 ; all digital
ANSELB = 0 ; all digital

' Define LCD connections
DEFINE LCD_DREG PORTA ' LCD Data Port
DEFINE LCD_DBIT 0 ' Starting Data Bit
DEFINE LCD_RSREG PORTA ' Register Select Port
DEFINE LCD_RSBIT 4 ' Register Select Bit
DEFINE LCD_EREG PORTA ' Enable Port
DEFINE LCD_EBIT 7 ' Enable Bit
DEFINE LCD_BITS 4 ' Data Bus Size
DEFINE LCD_LINES 2 ' Number of Lines on LCD

'================================================= ================================================== ======
' PIN ASSIGNMENTS, SYSTEM CONSTANTS, TEMPORARY VARIABLES
'================================================= ================================================== ======
' Rotary Encoder stuff
Old_Bits VAR BYTE bank0 ' Encoder port bits before change.
New_Bits VAR BYTE bank0 ' Encoder port bits after change.
RotEnc1_val VAR word bank0 ' Connected to PORTB<6:5>.
MaxLimit var word bank0 ' Used for setting upper limit for encoder counts.
RotEncDir VAR BIT bank0 ' Direction of rotation bit.
ButtPush var bit bank0 ' Flag shows button was pushed, allows quick exit from Int handler.
REdec var bit bank0 ' Flag shows RE decrement, allows quick exit from Int handler.
REinc var bit bank0 ' Flag shows RE increment, allows quick exit from Int handler.

Include "MODEDEFS.BAS" ' Include Shiftin/out modes.
INCLUDE "DT_INTS-14.bas" ' Needs to be assembled with MPASM **********
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts

OPTION_REG.6 = 0 ' INTEDG set to interrupt on falling edge.
' OPTION_REG.6 = 1 ' INTEDG set to interrupt on rising edge.

' IOCBP = %01110000 ; REa portb.6, REb portb.5 pos edge trigger
IOCBN = %01110000 ; REa portb.6, REb portb.5, REsw portb.4 neg edge trigger - falling edge only.
IOCBF = 0 ; Reset the PortB flag.
INTCON = %11001000 ; GIE, PEIE, IOCIE.

MaxLimit = 60 ' Menu value limit.
' pause 100 ' Let everything settle...

latc.6 = 1 ' Prevent garbled serial - newer PICs, inverted.
serout2 PORTC.6,16468,[13,10,"I'm Alive",13,10,10]

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Rot_Encoder, PBP, yes ; Newer PICs.
endm
INT_CREATE ; Creates the interrupt processor .
ENDASM

@ INT_ENABLE IOC_INT ; Newer PICs.
Old_Bits = PORTB & (%01100000) ; RE uses B.6,B.5 - REa and REb.


Main:
if PortB.4 = 0 then ' Check if Encoder pushbutton was pushed.
while PortB.4 = 0:wend ' Wait for release.
pause 50 ' Debounce delay.
serout2 PORTC.6,16468,[13,10,"ButtPush = 1, RE ",dec5 RotEnc1_val]
endif

if REdec or REinc = 1 then
serout2 PORTC.6,16468,[13,10,"RE_val ",dec5 RotEnc1_val]
REdec = 0:REinc = 0 ' Reset the flags.
endif

goto main ' endless loop waiting for INT.



'---[IOC - interrupt handler]---------------------------------------------------
' Don't forget 4 counts per detent (Quadrature).
Rot_Encoder:
New_Bits = PORTB & (%01100000) ' Set port bits for Encoder's chosen A and B channels.
IF (New_Bits & %01100000) = (Old_Bits & %01100000) then DoneRotEnc ' No change.
RotEncDir = New_Bits.6 ^ Old_Bits.5 ' Bit XOR compare to get direction of rotation.
if RotEncDir = 0 then ' CCW so decrement.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val - 1 ' Decrement the count.
if RotEnc1_val => 65530 then RotEnc1_val = 0 ' Limit the max.
if RotEnc1_val <= 4 then RotEnc1_val = 0 ' Limit the min.
REdec = 1 ' Flag the event.
endif
ELSE ' RotEncDir = 1, CW so increment.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val + 1 ' Increment the count.
if RotEnc1_val >= MaxLimit then RotEnc1_val = MaxLimit ' Limit the count.
REinc = 1 ' Flag the event.
endif
ENDIF

DoneRotEnc:
Old_Bits = New_Bits
INTCON.0 = 0 ; Clean up and exit - clear IOCIF.
IOCBF = 0 ; Reset the flag.
@ INT_RETURN

end

richard
- 8th February 2021, 12:45
if you look at the expected b5,b6 pin values at each interrupt
for neg edge trigger only

ints occur on orange lines
9010
under ideal conditions you get for say cw rotation
01,00,01,00,01............
for ccw
00,10,00,10,00............





so for cw


old = 01000000 new 00000000 or old = 00000000 new 01000000
new.6 ^ old.5 =1 new.6 ^ old.5 = 0




so for ccw


old = 00100000 new 00000000 or old = 00000000 new 00100000
new.6 ^ old.5 = 0 new.6 ^ old.5 = 1

i don't see your logic decoding direction at all successfully

wjsmarine
- 9th February 2021, 09:06
Hi Richard,

I don't see where you're going with your comments, maybe I'm just thick.

In any case the Int Handler does recognize CW and CCW correctly with every turn and RE_val does increment or decrement accordingly by 1 count per detent as needed - the only issue is these unwanted regular serial disturbances following RE action, including the push button. Speed of rotation isn't a factor with their appearance.

Something else is going on also - if I insert a Clear statement as below the RE_val resets to 0 - as if the PIC is reinitializing following the RE action hence the "I'm Alive" serial traffic. Without the Clear the count remains as it was prior to the serial disturbance.

Is there a chance you could breadboard a 16F1788 and confirm my findings?

Thanks,
Bill




' IOCBP = %01110000 ; REa portb.6, REb portb.5 pos edge trigger
IOCBN = %01110000 ; REa portb.6, REb portb.5, REsw portb.4 neg edge trigger - falling edge only.
IOCBF = 0 ; Reset the PortB flag.
INTCON = %11001000 ; GIE, PEIE, IOCIE.

clear ' Clear all vars.

MaxLimit = 60 ' Menu value limit.
' pause 100 ' Let everything settle...

serout2 PORTC.6,16468,[13,10,"I'm Alive",13,10,10]

SAMPLE of terminal
RE_val 00001
RE_val 00002
RE_val 00003
ButtPush = 1, RE 00003
RE_val 00004
RE_val 00005
RE_val 00006
RE_val 00005
RE_val 00000
RE_val 00000
ButtPush = 1, RE 00000
RE_val 00001
RE_val 00002
RE_val 00003
RE_val 00004
RE_val 00005
RE_val 00006
RE_val 00007
RE_val 00008
RE_val 00009
RE_val 00010
RE_val 00011
RE_val 00010
RE_val 00009
RE_val 00008
RE_val 00007
RE_val 00006
RE_val 00005
ButtPush = 1, RE 00005
RE_val 00006
RE_val 00007
RE_val 00008
I'm Alive


RE_val 00001
RE_val 00002
RE_val 00003
RE_val 00004

HenrikOlsson
- 9th February 2021, 19:42
Since the I'm alive output is outside of and before Main it looks to me as if the PIC is resetting and starting over. Try something like:

serout2 PORTC.6, 16468, [BIN8 STATUS, " - ", BIN8 PCON, 10,13]
serout2 PORTC.6,16468,[13,10,"I'm Alive",13,10,10]

What does it say when you power up and what does it say when you get that rouge output?

/Henrik.

richard
- 10th February 2021, 00:06
i breadboarded a 1788 and using the code as posted in reply 8 with one slight change in that serout2 is set to T9600 it
1. fails to count properly as predicted
2. shows no signs of resets occurring

interestingly using an encoder with no filtering it gives the appearance of functioning
curious , not sure what to think .


'************************************************* ************************************************** *'* Name : RE test WJS.pbp *
'* Author : WJ Sherwood *
'* Notice : Copyright (c) 2021 *
'* : All Rights Reserved *
'* Date : 07/02/21 *
'* Device : 16F1788 *
'* Version : 1 (PBP 3.0.10.4) *
'* Notes : Spurious "I'm Alive" serial traffic following RE action (still) and corrupt chars if *
'* : Pause at line 75 (following MaxLimit = 60) removed - what am I missing? *
'* : *
'* : REa portb.6, REb portb.5, REsw portb.4 all pulled up, active low. *
'* : *
'************************************************* ************************************************** *
.
'================================================= ================================================== ======
' CONFIGURE DEVICE
'================================================= ================================================== ======
#CONFIG ; 16F1788
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _LVP_OFF & _BORV_HI & _LPBOR_OFF
#ENDCONFIG


' -----[ Initialization ]---------------------------------------------------------------------------------
TRISA = 000000 ' Set I/O.
TRISB = 111111 ' Set I/O.
TRISC = 000000 ' Set I/O.


define OSC 4
OSCCON = 101010 ' 4Mhz (F1788).
'define OSC 32
' OSCCON = 110000 ; 32 MHz,


ANSELA = 0 ; all digital
ANSELB = 0 ; all digital


' Define LCD connections
DEFINE LCD_DREG PORTA ' LCD Data Port
DEFINE LCD_DBIT 0 ' Starting Data Bit
DEFINE LCD_RSREG PORTA ' Register Select Port
DEFINE LCD_RSBIT 4 ' Register Select Bit
DEFINE LCD_EREG PORTA ' Enable Port
DEFINE LCD_EBIT 7 ' Enable Bit
DEFINE LCD_BITS 4 ' Data Bus Size
DEFINE LCD_LINES 2 ' Number of Lines on LCD


'================================================= ================================================== ======
' PIN ASSIGNMENTS, SYSTEM CONSTANTS, TEMPORARY VARIABLES
'================================================= ================================================== ======
' Rotary Encoder stuff
Old_Bits VAR BYTE bank0 ' Encoder port bits before change.
New_Bits VAR BYTE bank0 ' Encoder port bits after change.
RotEnc1_val VAR word bank0 ' Connected to PORTB<6:5>.
MaxLimit var word bank0 ' Used for setting upper limit for encoder counts.
RotEncDir VAR BIT bank0 ' Direction of rotation bit.
ButtPush var bit bank0 ' Flag shows button was pushed, allows quick exit from Int handler.
REdec var bit bank0 ' Flag shows RE decrement, allows quick exit from Int handler.
REinc var bit bank0 ' Flag shows RE increment, allows quick exit from Int handler.

Include "MODEDEFS.BAS" ' Include Shiftin/out modes.
INCLUDE "DT_INTS-14.bas" ' Needs to be assembled with MPASM **********
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts


OPTION_REG.6 = 0 ' INTEDG set to interrupt on falling edge.
' OPTION_REG.6 = 1 ' INTEDG set to interrupt on rising edge.


' IOCBP = 110000 ; REa portb.6, REb portb.5 pos edge trigger
IOCBN = 110000 ; REa portb.6, REb portb.5, REsw portb.4 neg edge trigger - falling edge only.
IOCBF = 0 ; Reset the PortB flag.
INTCON = 001000 ; GIE, PEIE, IOCIE.

MaxLimit = 60 ' Menu value limit.
' pause 100 ' Let everything settle...


latc.6 = 1 ' Prevent garbled serial - newer PICs, inverted.
serout2 PORTC.6,84,[13,10,"I'm Alive",13,10,10]


ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Rot_Encoder, PBP, yes ; Newer PICs.
endm
INT_CREATE ; Creates the interrupt processor .
ENDASM


@ INT_ENABLE IOC_INT ; Newer PICs.
Old_Bits = PORTB & (100000) ; RE uses B.6,B.5 - REa and REb.




Main:
if PortB.4 = 0 then ' Check if Encoder pushbutton was pushed.
while PortB.4 = 0:wend ' Wait for release.
pause 50 ' Debounce delay.
serout2 PORTC.6,84,[13,10,"ButtPush = 1, RE ",dec5 RotEnc1_val]
endif

if REdec or REinc = 1 then
serout2 PORTC.6,84,[13,10,"RE_val ",dec5 RotEnc1_val]
REdec = 0:REinc = 0 ' Reset the flags.
endif

goto main ' endless loop waiting for INT.





'---[IOC - interrupt handler]---------------------------------------------------
' Don't forget 4 counts per detent (Quadrature).
Rot_Encoder:
New_Bits = PORTB & (100000) ' Set port bits for Encoder's chosen A and B channels.
IF (New_Bits & 100000) = (Old_Bits & 100000) then DoneRotEnc ' No change.
RotEncDir = New_Bits.6 ^ Old_Bits.5 ' Bit XOR compare to get direction of rotation.
if RotEncDir = 0 then ' CCW so decrement.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val - 1 ' Decrement the count.
if RotEnc1_val => 65530 then RotEnc1_val = 0 ' Limit the max.
if RotEnc1_val <= 4 then RotEnc1_val = 0 ' Limit the min.
REdec = 1 ' Flag the event.
endif
ELSE ' RotEncDir = 1, CW so increment.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val + 1 ' Increment the count.
if RotEnc1_val >= MaxLimit then RotEnc1_val = MaxLimit ' Limit the count.
REinc = 1 ' Flag the event.
endif
ENDIF


DoneRotEnc:
Old_Bits = New_Bits
INTCON.0 = 0 ; Clean up and exit - clear IOCIF.
IOCBF = 0 ; Reset the flag.
@ INT_RETURN


end

wjsmarine
- 10th February 2021, 02:10
Hi Henrik,

Thanks for joining, your input is welcome.

Inserting your code shows (terminal output):



00011001 - 01010100

I'm Alive

RE_val 00001
RE_val 00002
RE_val 00003
RE_val 00004
RE_val 00005
RE_val 00006
RE_val 00007
RE_val 00008
RE_val 00007
RE_val 00006
RE_val 00005
ButtPush = 1, RE 00005
RE_val 00006
RE_val 00007
RE_val 00008
RE_val 00009
00011001 - 01010100

I'm Alive


... so no change from original states once the 'reset' occurs - if that is what it is (I'm still decyphering the data sheet).

Any comments?

Cheers,
Bill

richard
- 10th February 2021, 02:25
mine has been running for 4 hours now , nill resets

Ioannis
- 10th February 2021, 09:36
Try to disable the WDT and see if it resets.

Ioannis

HenrikOlsson
- 10th February 2021, 10:24
I was a little quick with that PCON thing, on startup set PCON = %00011111 then let the program run



serout2 PORTC.6, 16468, ["Power-on:", BIN8 STATUS, " - ", BIN8 PCON, 10,13]
PCON = %00011111
serout2 PORTC.6, 16468, ["Priming PCON:", BIN8 STATUS, " - ", BIN8 PCON, 10,13]
serout2 PORTC.6,16468,[13,10,"I'm Alive",13,10,10]

wjsmarine
- 11th February 2021, 00:21
Thanks for your help guys,

@ Ioannis
Disabling the WDT was one of the first things I tried, no change.

@ Henrik
Please see terminal capture below after including your suggested debug code...




Power-on: 00011001 - 00010110
Priming PCON: 00011001 - 00011111

I'm Alive

RE_val 00000
RE_val 00001
RE_val 00002Power-on: 00011001 - 01011111
Priming PC9é 00011001 - 00011111

I'm Alive

RE_val 00001


Bit 6 of PCON changed - WTF is a stack underflow? Masking the problem, I know - but I added '& _STVREN_OFF' to _CONFIG2 to see if there was a difference and the results are below.



Power-on: 00011001 - 00010110
Priming PCON: 00011001 - 00011111

I'm Alive

RE_val 00001
RE_val 00002
RE_val 00003
RE_val 00004
RE_val 00005
RE_val 00006
RE_val 00007
RE_val 00008
RE_val 00009
RE_val 00010Power-oîé 00011001 - 11011111
Priming PCON: 00011001 - 11011111

I'm Alive

RE_val 00000
RE_val 00000
RE_val 00001
RE_val 00002
RE_val 00003Power-on: 00011001 €- 110111ˆR
Primin?PCON: 00011001 - 11011111

I'm Alive



So it looks like there is now a Stack overflow and underflow if I'm reading the data sheet correctly - how can this happen with STVREN off? Or have I lost the plot?

I'm floundering.

Cheers,
Bill

richard
- 11th February 2021, 00:31
one thing you can eliminate is a code problem [assuming code as posted] mine is has run for 24 hours+ without resetting

describe your setup including whether you leave the programmer attached when testing

wjsmarine
- 11th February 2021, 02:37
Hi Richard,

I made a general purpose pcb a while ago for dil28 PICs that has breakouts for each pin and a 'shield' that sits over it for ease of changing displays (Nokia, 16x2, GLCD, etc). It has LED's via jumpers, +5 or +3v3 selection and a RE on there as well, I tried to make it as universal as possible and it's been a workhorse for a lot of testing in the past. There is also a slide switch that is program/run for ease of ICSP and isolation when done.

To eliminate any possibility of the pcb being the problem I changed to a breadboard and used my other flying lead program/run slide switch arrangement to the breadboard. Same results. Only thing I haven't tried yet is a different 1788 which I know I have somewhere but it is eluding me but I'll look up the specs and see if there is a close family member I can use in the meantime. I don't have to use the 1788 so will also explore other dil28 chips I have to get a good end result.

I'll get back to you when I have something.

Cheers,
Bill

richard
- 11th February 2021, 03:07
the reason i ask is that if your programmer is still connected and the programmer is used to power your proto board .
some leave the icspclk pin on the programmer as a high output , if your RE tries to drag B.6 low the power stability will suffer giving all sorts of problems
imho using any of the icsp pins while prototyping makes life difficult

wjsmarine
- 11th February 2021, 07:16
Well, I found and tried another (new) 1788 but no difference. Fully isolating the programming cable and interface also made no difference, the fault persists.

I then went to a 16F886 and made appropriate changes - works without 'resets' (with programming cable and interface attached as normal) and only some rare serial corruption but maintaining its RE count still, both CW and CCW. This tells me my hardware test setup is not at fault and the code is basically correct. So is there an issue with 16F1788's? Richard's setup hasn't identified any so I'm mystified. Below is what current code is:





'************************************************* ************************************************** *
'* Name : RE test WJS.pbp *
'* Author : WJ Sherwood *
'* Notice : Copyright (c) 2021 *
'* : All Rights Reserved *
'* Date : 07/02/21 *
'* Device : 16F1788 [tests using 16F886 (and appropriate Reg changes) works correctly.] *
'* Version : 1 (PBP 3.0.10.4) *
'* Notes : Spurious "I'm Alive" serial traffic following RE action (still) and corrupt chars if *
'* : Pause at line 75 (following MaxLimit = 60) removed - what am I missing? *
'* : *
'* : REa portb.6, REb portb.5, REsw portb.4 all pulled up, active low. *
'* : *
'************************************************* ************************************************** *

'================================================= ================================================== ======
' CONFIGURE DEVICE
'================================================= ================================================== ======
#CONFIG ; 16F1788.
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _LVP_OFF & _BORV_HI & _LPBOR_OFF ;& _STVREN_OFF
#ENDCONFIG

'' What happens with a different PIC?
'#CONFIG ; F886
' __config _CONFIG1, _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_ON & _LVP_OFF & _CP_OFF
'#ENDCONFIG

' -----[ Initialization F1788]---------------------------------------------------------------------------------
TRISA = %00000000 ' Set I/O.
' TRISB = %01111111 ' Set I/O.
TRISB = %01110000 ' Set I/O. Only RE bits set as inputs.
TRISC = %00000000 ' Set I/O.

define OSC 4
OSCCON = %01101010 ' 4Mhz (F1788).
'define OSC 32
' OSCCON = %11110000 ; 32 MHz,

ANSELA = 0 ; all digital
ANSELB = 0 ; all digital
' --------------------------------------------------------------------------------------------------------------

'' -----[ Initialization F866]-----------------------------------------------------------------------------------------------
' CM1CON0 = 0 ' Comparators off.
' ANSEL = %00000000 ' Make PortA AN0-AN7 digital.
'' ANSEL = %00000011 ' All digital except An0 and An1.
' TRISA = %00000000 ' Set I/O.

' CM2CON0 = 0 ' Comparators off.
' ANSELH = 0 ' Make PortB AN8-AN13 digital.

'' PortB Int-On-Change: 1 = Int enabled. 0 = Int disabled.
' IOCB.0 = 0 ' No.
' IOCB.4 = 1 ' Yes, encoder pushbutton.
' IOCB.5 = 1 ' Yes, encoder Channel A.
' IOCB.6 = 1 ' Yes, encoder Channel B.
' IOCB.7 = 0 ' No.

' TRISB = %01110000 ' 4-6 encoder inputs.
' CCP1CON = %00000000 '

' TRISC = %00000000 ' Set I/O.

'' ADCON0 = %11001000 ' Set A/D to Frc, Channel 3, On (F88).
' ADCON0 = 0 ' Disable A/D.
' ADCON1 = %00000110 ' All digital.
'' ADCON1 = %10000000 ' R justify (where the 6 MSB of ADRESH read as 0 i.e. 10 bit), Vdd for Vref.

' Define OSC 4 ' Set Operating Frequency
' OSCCON = %01100000 ' 4Mhz (F886).

'' Define OSC 8 '
'' OSCCON = %01110000 ' 8Mhz (F886).

' INTCON = %10001000 ' Port B int on change and global interrupt enable.

' clear ' ****** Clear statement must be before the INC file.******

'wsave VAR BYTE $70 SYSTEM ' alternate save location for W
'' --------------------------------------------------------------------------------------------------------------

' Define LCD connections
DEFINE LCD_DREG PORTA ' LCD Data Port
DEFINE LCD_DBIT 0 ' Starting Data Bit
DEFINE LCD_RSREG PORTA ' Register Select Port
DEFINE LCD_RSBIT 4 ' Register Select Bit
DEFINE LCD_EREG PORTA ' Enable Port
DEFINE LCD_EBIT 7 ' Enable Bit
DEFINE LCD_BITS 4 ' Data Bus Size
DEFINE LCD_LINES 2 ' Number of Lines on LCD

'================================================= ================================================== ======
' PIN ASSIGNMENTS, SYSTEM CONSTANTS, TEMPORARY VARIABLES
'================================================= ================================================== ======
' Rotary Encoder stuff
Old_Bits VAR BYTE bank0 ' Encoder port bits before change.
New_Bits VAR BYTE bank0 ' Encoder port bits after change.
RotEnc1_val VAR word bank0 ' Connected to PORTB<6:5>.
MaxLimit var word bank0 ' Used for setting upper limit for encoder counts.
RotEncDir VAR BIT bank0 ' Direction of rotation bit.
ButtPush var bit bank0 ' Flag shows button was pushed, allows quick exit from Int handler.
REdec var bit bank0 ' Flag shows RE decrement, allows quick exit from Int handler.
REinc var bit bank0 ' Flag shows RE increment, allows quick exit from Int handler.

'Temp var byte ' Used for Int clearing by reading PortB. F886

Include "MODEDEFS.BAS" ' Include Shiftin/out modes.
INCLUDE "DT_INTS-14.bas" ' Needs to be assembled with MPASM **********
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts

OPTION_REG.6 = 0 ' INTEDG set to interrupt on falling edge.
' OPTION_REG.6 = 1 ' INTEDG set to interrupt on rising edge.

' ----- F1788 --------------------------------------------------------------------------------------------------
' IOCBP = %01110000 ; REa portb.6, REb portb.5 pos edge trigger
IOCBN = %01110000 ; REa portb.6, REb portb.5, REsw portb.4 neg edge trigger - falling edge only.
IOCBF = 0 ; Reset the PortB flag.
INTCON = %11001000 ; GIE, PEIE, IOCIE.
' --------------------------------------------------------------------------------------------------------------

clear ' Clear all vars.

MaxLimit = 60 ' Menu value limit.
' pause 100 ' Let everything settle...

serout2 PORTC.6, 16468, ["Power-on: ",BIN8 STATUS, " - ",BIN8 PCON,10,13] ' thanks to Henrik.
PCON = %00011111
serout2 PORTC.6,16468,["Priming PCON: ",BIN8 STATUS," - ",BIN8 PCON,10,13]
serout2 PORTC.6,16468,[13,10,"I'm Alive",13,10,10]

' ----- F1788 --------------------------------------------------------------------------------------------------
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler IOC_INT, _Rot_Encoder, PBP, yes ; Newer PICs.
endm
INT_CREATE ; Creates the interrupt processor .
ENDASM

@ INT_ENABLE IOC_INT ; Newer PICs.
' --------------------------------------------------------------------------------------------------------------

'' ----- F886 ---------------------------------------------------------------------------------------------------
'ASM
'INT_LIST macro ; IntSource, Label, Type, ResetFlag?
' INT_Handler RBC_INT, _Rot_Encoder, PBP, yes
' endm
' INT_CREATE ; Creates the interrupt processor
'ENDASM

'@ INT_ENABLE RBC_INT ; RB Port Change Interrupt
'' --------------------------------------------------------------------------------------------------------------

Old_Bits = PORTB & (%01100000) ; RE uses B.6,B.5 - REa and REb.


Main:
if PortB.4 = 0 then ' Check if Encoder pushbutton was pushed.
while PortB.4 = 0:wend ' Wait for release.
pause 50 ' Debounce delay.
serout2 PORTC.6,16468,[13,10,"ButtPush = 1, RE ",dec5 RotEnc1_val]
'serout2 PORTC.6,16468,[13,10,BIN8 STATUS," - ",BIN8 PCON,10,13] ' thanks to Henrik.
endif

if REdec or REinc = 1 then
serout2 PORTC.6,16468,[13,10,"RE_val ",dec5 RotEnc1_val]
REdec = 0:REinc = 0 ' Reset the flags.
endif

goto main ' endless loop waiting for INT.



'---[IOC - interrupt handler]---------------------------------------------------
' Don't forget 4 counts per detent (Quadrature).
Rot_Encoder:
New_Bits = PORTB & (%01100000) ' Set port bits for Encoder's chosen A and B channels.
IF (New_Bits & %01100000) = (Old_Bits & %01100000) then DoneRotEnc ' No change.
RotEncDir = New_Bits.6 ^ Old_Bits.5 ' Bit XOR compare to get direction of rotation.
if RotEncDir = 0 then ' CCW so decrement.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val - 1 ' Decrement the count.
if RotEnc1_val => 65530 then RotEnc1_val = 0 ' Limit the max.
if RotEnc1_val <= 4 then RotEnc1_val = 0 ' Limit the min.
REdec = 1 ' Flag the event.
endif
ELSE ' RotEncDir = 1, CW so increment.
if PORTB.6 and PORTB.5 = 1 then ' Only when RE both pins high (convert quad counts to singles).
RotEnc1_val = RotEnc1_val + 1 ' Increment the count.
if RotEnc1_val >= MaxLimit then RotEnc1_val = MaxLimit ' Limit the count.
REinc = 1 ' Flag the event.
endif
ENDIF

DoneRotEnc:
Old_Bits = New_Bits
INTCON.0 = 0 ; Clean up and exit - clear IOCIF. F1788
IOCBF = 0 ; Reset the flag. F1788
' Temp = PORTB ' Read PortB to clear the Int (F886).
@ INT_RETURN

end


Next up I'm going to try a 16F1938 (and maybe some 18F's) but out of time now and it will have to wait for the weekend. While I can use the F886 for this project it gives me no confidence to use F1788's for Int duties in future until sorted.

Cheers,
Bill

mpgmike
- 11th February 2021, 19:00
A STACK Underflow condition is caused by more RETURNs than CALLs (GOSUBs). I have a suggestion; in your ISR Rot_Encoder: change


IF (New_Bits & 100000) = (Old_Bits & 100000) then DoneRotEnc ' No change.

to


IF (New_Bits & 100000) = (Old_Bits & 100000) then
@ GOTO DoneRotEnc ; No change.
ENDIF

Ioannis
- 11th February 2021, 20:02
Mike, why your suggestion is not the same?

Ioannis

mpgmike
- 12th February 2021, 04:16
Louis stated there was a STACK Underflow flag set in the PCON Register. I looked over his/her posted code and the only place I could find where a CALL/RETURN mis-match could occur was in the posted line of code. By specifying a "GOTO" there, the Stack would not be modified with a RETURN PC Address. I suggested a test to eliminate the possibility of the STACK Underflow condition being caused by that line of code.

Ioannis
- 12th February 2021, 06:44
The


then DoneRotEnc


is exactly the same as


then goto DoneRotEnc


or


@ goto DoneRotEnc


Or not?

Ioannis

richard
- 12th February 2021, 07:02
not to mention that mine ,same code same chip does not reboot

Ioannis
- 12th February 2021, 07:12
Then maybe a bad supply voltage, bad decoupling capacitors, bad breadboard connections...

Ioannis

richard
- 12th February 2021, 07:26
would seem that way , although his dt_ints may be altered.
only changes i made

latc.6 = 1 ' reversed polarity tty
serout2 PORTC.6,84,[13,10,"I'm Alive",13,10,10]





although code has a few weird things they don't cause the problems, if i use a nice clean optical re the code fails to count up or down as per reply 9
a filtered mechanical re also miscounts , no filter gives a semblance of functionality. i will keep to my code



OPTION_REG.6 = 0 ' INTEDG set to interrupt on falling edge. ?
' OPTION_REG.6 = 1 ' INTEDG set to interrupt on rising edge.

IOCBN = %01110000 ; REa portb.6, REb portb.5, REsw portb.4 neg edge trigger - falling edge only.
why set the sw to cause an interrupt

Ioannis
- 12th February 2021, 07:55
More responsive I suppose?

wjsmarine
- 12th February 2021, 08:54
Hi All,

Just had a chance to try Mike's suggestion, terminal result below, still no good.



Power-on: 00011001 - 00011101
Priming PCON: 00011001 - 00011111

I'm Alive

RE_val 00001
RE_val 00002
RE_val 00003
RE_val 00004
RE_val 00005
RE_val 00006
RE_val 00007
RE_val 00008
RE_val 00009Power-on: 00011001 - 01011111
Priming PCON: 00011001 - 00011111

I'm Alive

RE_val 00001


@ Richard
I take your point about using an Int for the REsw but this code is only a snippet of a much larger, intensive program and the normal scan of the switch may be delayed due other processes - hence my using an Int for the pushbutton. I have not run the full code with this problem, only what has been submitted for this very reason (isolation of where the problem lies). I have tried with and without the REsw bit, still no difference with the bug.

@ Ioannis
The test pcb I've been using all along (and a breadboard to confirm) runs very well when I switch to the 16F886, supply is from a well regulated 9v bench unit which then gets regulated on board to either 5v or 3v3 as needed. The RE and all peripheral components are hard soldered on the pcb.

AFAIK I'm running the latest version of DTInts having found that out the hard way a number of weeks ago, identified by Richard (thanks again mate).

Maybe it is time to give up on this and go with your preferred way of using a RE Richard... but I'd like to solve the mystery if possible else have that nagging doubt using 16F1788 chips with Ints.

Cheers,
Bill

richard
- 12th February 2021, 09:25
your not trying to run chip at less than 5v ? decouple caps etc [i'm using none]
reset is pulled high ?
enc and sw pins are pulled high with suitable r

i cannot get mine to fail no matter hard i try , no caps, pwr off pk4 , dupont leads on a breadboard [you can't get worse conditions]
even using wpu is ok

i will go out on a limb and say
code cause 0%, isr cause 0% . other 100%

also when breadboarding all unused pins set as i/p is a good thing

wjsmarine
- 12th February 2021, 10:25
No, 5v all the way unless the app calls for 3v3 (typically when I use a Nokia GLCD). In any case the PIC should be able to handle 3v3 at low speeds, surely?

The pcb has bunches of decoupling caps, selectable 10k pullups (as used on the RE) and .1 caps to ground also to minimize and bounce at the source.

Reset is pulled high via a 10k series diode combination for the ICSP requirements.

I make unused pins output so don't need to worry about pullups as you would with inputs (else floating nightmares). I guess your wpu's take care of your inputs.

Worse case I'll develop with the F886 (yet to try the F1938, hopefully tomorrow - I think you have one or two of these IIRC).

What's next wise one?

Regards,
Grasshopper

richard
- 12th February 2021, 21:27
no, 5v all the way unless the app calls for 3v3 (typically when I use a Nokia GLCD). In any case the PIC should be able to handle 3v3 at low speeds, surely?
not sure , for the 16f1788 the microchip ipe with pk4 warns , 5.00 v recommended (not sure where the ldo comes into play)




I make unused pins output so don't need to worry about pullups as you would with inputs (else floating nightmares). I guess your wpu's take care of your inputs.
as i don't , i have never seen or heard of a pic having an adverse effect from an unused floating input. if your program is affected by an unused input then its incomplete.
the only measurable effect is a slight increase in power consumption (you need a microamp meter to detect it). floating pin nightmares for pic chips are a myth based on other logic families with fixed i/p pin to o/p pin relationships where totem-pole outputs could be driven at prodigious rates unnecessarily to bad effect, pics are not like that.
when breadboarding all unused pins set as i/p is a good thing, you won't damage anything with misplaced connections.

picster
- 21st March 2021, 15:45
I just use regular polling instead of interrupts when using a pb rotary, and only increment/decrement the "true status" upon TWO successive state changes in the SAME "direction". This eliminates debouncing and does not require interrupt use and it's infallible.

Picster