Continue to Site

# Has anyone had problems with QEI affecting the rest of the CODE?

#### camerart

##### Active Member
Hi,
I am using an 18F4431 with a QEI and an incremental encoder.
On it's own it works perfectly, and I use it for degrees so 0 to 359 then over to 0 again.

I've now added a second section for reading a GPS module, which also works ok, but when the QEI goes over 359, then it stalls the program.
Cheers, Camerart

Last edited:

#### jjw

##### Member
Show the QEI code.

#### camerart

##### Active Member
Show the QEI code.
Hi J,
SET_UP:
'************************ QEI **********************************
Dim qeideg As Word
Dim qeideglb As Byte
Dim qeideghb As Byte

QEICON = %00011011 'QEI enabled in 4x Update mode; position TIME is reset on period match (POSCNT = MAXCNT)
'QEICON VELM=0 Velocity mode enabled, QERR=0 No over/underflo, UP/DOWN=0 REVERSE, QEIM=110 QEI EN POSCNT=MAXCNT), PDEC=11 1:64
IPR3.IC2QEIP = 1 'high pri intr QEI Interrupt priority bit
PIE3.IC2QEIE = 1 'qei intr enb QEI Interrupt flag enable bit
PIR3.IC2QEIF = 0 'Has reached the MAXCNT value, INT QEI MODULE Interrupt flag bit
PIR3.IC3DRIF = 0 'clr in s/w REG file motion feedback filter(NOT USED)??
PIE1.RCIE = 0 '0= Disables the EUSART receive interrupt??

CAP2BUFL = 0x00
CAP2BUFH = 0x00
CAP3BUFL = 0x9f 'CAP3BUFL = 0x67
CAP3BUFH = 0x05 'CAP3BUFH = 0x01
'*************************************************************************
IN LOOP:
qeideg.LB = CAP2BUFL
qeideg.HB = CAP2BUFH

------------------------------------------------------------
C.

#### rjenkinsgb

##### Well-Known Member
You appear to be enabling interrupts for various QEI events, but don't have interrupt handler routines?

#### tumbleweed

##### Active Member
There's a LOT of code missing, so there's no way to tell.

#### camerart

##### Active Member
Hi R and T,
This is HW on an 18F4431 PIC, and that's how it's been running for years, I don't think I missed any other related CODE?

I've attached the QEI CODE fro 2019
C

#### Attachments

• 18F4431 8MHz INT COUNT 0_359 SPI J 110219 1030.txt
2.5 KB · Views: 24
Last edited:

#### Dr_Doggy

##### Well-Known Member
Hserout "AZILB=", #azi.LB, " ", "AZIHB=", #azi.HB, CrLf

I have seen strings cause mem leaks, I think cos each time it writes somthing like "AZILB=" it has to create a whole new array for each iteration, causing the mem to run out and a overflow, i think they called it a mem leak.

the proper way is to store the string in a variable and then print the var.
so
a= "azlib="
b="azihb="
c= " "

#### camerart

##### Active Member
Hserout "AZILB=", #azi.LB, " ", "AZIHB=", #azi.HB, CrLf

I have seen strings cause mem leaks, I think cos each time it writes somthing like "AZILB=" it has to create a whole new array for each iteration, causing the mem to run out and a overflow, i think they called it a mem leak.

the proper way is to store the string in a variable and then print the var.
so
a= "azlib="
b="azihb="
c= " "
Hi DD,
I've never heard of that, I'll investigate, thanks.
C

#### camerart

##### Active Member
Hi,
Is it possible that the QEI and the UART are both using HIGH priority INTERRUPTS, and this shouldn't be done?
C

#### Nigel Goodwin

##### Super Moderator
Hi,
Is it possible that the QEI and the UART are both using HIGH priority INTERRUPTS, and this shouldn't be done?
C
As in post #4, where's your interrupt code? - you're enabling QEI interrupts, but there's no sign of any code for it?.

It doesn't matter if you're using shared interrupts (which is what's normally done), your interrupt routine checks which one called it, and runs accordingly.

#### camerart

##### Active Member
As in post #4, where's your interrupt code? - you're enabling QEI interrupts, but there's no sign of any code for it?.

It doesn't matter if you're using shared interrupts (which is what's normally done), your interrupt routine checks which one called it, and runs accordingly.
Hi R and N,
As mentioned, this is how it's always run, and I didn't know it was wrong.
I'll ask my mate to help he's better at this sort of thing, than I am.
Thanks both.
EDIT: I just looked up 2x interrup routines, and get pointed to me asking the same thing 4years ago
C

Last edited:

#### camerart

##### Active Member
Hi,
To give me an idea of what's going on with especially the QEI, it would be good to clarify things a bit.
On the 18F2431 and 18F4431 PICs, the QEI, is HW, and as I had it set was to count to 359 then go over to 0.
With HW like this, once set up correctly, to run, does it run in the background whether the interrupts are on or off?
I'm trying to figure out how it can be switched off for the UART, and still count.
It has to be able to count at any time.
C

#### Nigel Goodwin

##### Super Moderator
Hi,
To give me an idea of what's going on with especially the QEI, it would be good to clarify things a bit.
On the 18F2431 and 18F4431 PICs, the QEI, is HW, and as I had it set was to count to 359 then go over to 0.
With HW like this, once set up correctly, to run, does it run in the background whether the interrupts are on or off?
I'm trying to figure out how it can be switched off for the UART, and still count.
It has to be able to count at any time.
C
It may well run, but also may well not do anything - but from what I see of your code, you're enabling interrupts

IPR3.IC2QEIP = 1 'high pri intr QEI Interrupt priority bit
PIE3.IC2QEIE = 1 'qei intr enb QEI Interrupt flag eneble bit

Which if it doesn't have anywhere to go sounds like a serious problem. How do you write interrupt routines in Oshonsoft?.

#### camerart

##### Active Member
It may well run, but also may well not do anything - but from what I see of your code, you're enabling interrupts

Which if it doesn't have anywhere to go sounds like a serious problem. How do you write interrupt routines in Oshonsoft?.
Hi N,
I'm not good at programming, and mainly search for CODE to copy and paste, or if I'm lucky, forum members help me. When I started this project, I simply didn't understand just how involved it was going to be.
The CODE I posted in #6, is from 2019, todays CODE is slightly different, also it has UART CODE joined to it.
C

#### camerart

##### Active Member
Hi,
I played with HIGH and LOW INTERRUPTs, switching them OFF/ON and once I set QEI to LOW and GPS to HIGH, it started working.
I'm sure my CODE would not be approved, though.
C

#### Nigel Goodwin

##### Super Moderator
Hi,
I played with HIGH and LOW INTERRUPTs, switching them OFF/ON and once I set QEI to LOW and GPS to HIGH, it started working.
I'm sure my CODE would not be approved, though.
C
Well you're hampering yourself by using an obscure compiler, that almost no one here uses, or has ever used, so most people (including myself) have no idea how interrupts are handled.

However, in assembler, C, and other BASIC's I have used, there HAS to be an ISR (Interurrupt Service Routine), and in XC8 (depending on processor) it starts something like this:

C:
void interrupt isr(void)
//void interrupt INTERRUPT_InterruptManager (void)
{
// interrupt handler
if(INTCONbits.PEIE == 1)
{
// code here
}
}

Once you've set the Interrupt Enable bit for QEI it will just to the ISR once triggered, which then must disable the Interrupt Flag, in order to allow it to work again, plus whatever processing is done.

Oshonsoft must have instructions, helpfiles, and it's own forum? - you need to read how it's supposed to work, rather than just randomly altering things in the vague hope it might work.

It's absolutely critical that interrupts are dealt with properly and accurately, otherwise you're likely to get all kinds of weird problems and crashes.

For a crude 'example' of what I mean, if I wanted you to go and fetch me some beer, I would ask you to "Go down the road to xxxx supermarket, and fetch me two bottles of YYYY beer, and bring it back to me". Your method would just be to say "go".

#### Nigel Goodwin

##### Super Moderator
A few seconds googling produces the reference manual:

Code:
• Using interrupts

Interrupt routine should be placed as all other subroutines after the END statement. It should begin with ON INTERRUPT and end with RESUME statement. If arithmetic operations, arrays or any other complex statements are used in interrupt routine, then SAVE SYSTEM statement should be placed right after ON INTERRUPT statement to save the content of registers used by system. However, it is always a good programming practice to keep interrupt routines as small as possible. ENABLE and DISABLE statements can be used in main program to control GIE bit in INTCON register. Peripheral interrupts must be separately enabled, for example with the statement INTCON.PEIE =1. RESUME statement will set the GIE bit and enable new interrupts. For example:
Example 1:
Dim x As Byte
x = 255
TRISA = 0
PORTA = x
INTCON.INTE = 1
Enable
End

On Interrupt
x = x - 1
PORTA = x
INTCON.INTF = 0
Resume

Example 2:
Dim t As Word
t = 0
TRISA = 0xff
TRISB = 0
OPTION_REG.T0CS = 0
INTCON.T0IE = 1
Enable
loop:
Goto loop
End

On Interrupt
Save System
t = t + 1
INTCON.T0IF = 0
Resume

#### camerart

##### Active Member
Well you're hampering yourself by using an obscure compiler, that almost no one here uses, or has ever used, so most people (including myself) have no idea how interrupts are handled.
Hi N,
It's my skill level that's hampering me, I'm skilled in other ways, but my weakest link is programming. I've tried to learn 'C' and assembler, but I'm stuck in time since my son's spectrum days.
I use my stumbling around method to corner any problems, then try in some way to correct it.

Anyway, I have a mate who I go to at the weekends, who is good at this sort of thing, and we'll go through all this then, and there is an ISR, which he will change as you suggest. I've sent him the link to your reply.

Next for me, is to time TX/RX between two units, using GPS time, so you may see a question about that

Thanks.
C

Last edited:

#### camerart

##### Active Member
It may well run, but also may well not do anything - but from what I see of your code, you're enabling interrupts

Which if it doesn't have anywhere to go sounds like a serious problem. How do you write interrupt routines in Oshonsoft?.
Hi N,
After talking to my mate today, he also came up with the
IPR3.IC2QEIP = 0
PIE3.IC2QEIE = 0
answer, which are now set to '0', and working.
Thanks.
C

#### Nigel Goodwin

##### Super Moderator
Hi N,
After talking to my mate today, he also came up with the
IPR3.IC2QEIP = 0
PIE3.IC2QEIE = 0
answer, which are now set to '0', and working.
Thanks.
C
Disabled the interrupts then.

Replies
25
Views
12K
Replies
18
Views
13K
Replies
9
Views
8K
Replies
0
Views
4K
Replies
7
Views
7K