PDA

View Full Version : Quad encoder problems



smitty505000
- 9th September 2006, 18:01
Hey all,

I am trying to get a couple of quad encoders to work in Picbasic
pro. I know the basics of how they work and simple programing
abilities. Here is what I have:

Qty 2 quad encoders with 36 slots each
Pic 16F628-20p
parallel lcd

I want to be able to return a value of 1-36 from each encoder so I
know the exact position of each.

The code I wrote is very simple using if then statements and reading
the ports to see if it is high or low. It kinda works but only if
the encoder is turned extremly slow and even then I get glitching.

From the information I have been able to find, it looks as if I need
to do it in assembly but like I said before, I only know simple
Basic programing.

Can anyone help??

Thanks,
Smitty

sayzer
- 9th September 2006, 18:15
If you do not need to determine the direction of the encoders, use TMR1 in counter mode instead of a PORT.

In this case, the TMR1 as counter can work in the background while you do other things in foreground.

However, if you have to use a PORT to read the encoder (mostly for direction), then you need to make sure that there is no "Pause" in your code. Any Pause will give you missing counts since the encoder is encoding the ticks faster then the "Pause" you have. This may explain why slow speed creates no problem in your case.

Since you have LCD, you probably have a Pause to match the refresh rate.

smitty505000
- 9th September 2006, 18:30
Hi sayzer,

Thanks for the reply.

Dont I need direction if I want to know the exact position? 36 slots = 10deg per slot for a total of 360deg. I need it to count up to 36 in one direction until one revoluton where it returns to 1. And count down to 1 in the other direction until one revolution where it returns to 36.

In other words I need a value between 1 and 36 corosponding to the exact slot it is currently on.

Smitty

sayzer
- 9th September 2006, 18:56
...I need it to count up to 36 in one direction until one revoluton where it returns to 1...
Smitty

As you know, usually in rotary encoders, it won't return to 1. It will always give you ticks as long as it rotates and you count the ticks. You need to use "Reference" signal out of the encoder which gives you a single tick only at the exact same point per revolution. When you get this tick then you know that "one revolution" is complete.

As you see, you need to also count or check this tick. The safest way, I think, would be to use TMR0 to count reference signal, and TMR1 to count one of the other signals (this is where you do not need to know the direction). The reason why I point out Timer modules is that they work in the background.


If you had a choice in which your encoder turned one direction and it was enough for you, then you could solve your problem here. But, you say you need both directions. In this case, you will have to use a PORT to read the encoder.

I added some links to some posts in this forum. Pls check them and see what kind of problems others encountered and how they approach to the similar issues.

1. http://www.picbasic.co.uk/forum/showthread.php?t=3316&highlight=rotary+encoder
2. http://www.picbasic.co.uk/forum/showthread.php?t=2066&highlight=rotary+encoder
3. http://www.picbasic.co.uk/forum/showthread.php?t=1552&highlight=rotary+encoder
4. http://www.picbasic.co.uk/forum/showthread.php?t=778&highlight=rotary+encoder

mister_e has a clever approach to a similar encoder issue (Item 4).


Regards.


Edit: What you say kind a sounds that you may actually not need the direction.


------------

smitty505000
- 9th September 2006, 23:12
Thanks for the info sayzer! Not sure I explained what I am doing very well. I did some more searching and found out I have 2 bit encoders, not quad. I am using them with a weight attached to one side so they are always parallel to the ground. What I want to do is use them as attitude sensors for pitch and roll in a telemetry system I am building.

They have 36 slots each and return a code of 00 01 11 10 in one direction and 10 11 01 00 in the other. I have it working but it seams to bounce or glitch. I think the 16f628 at 20mhz isnt fast enough to keep up.

Here is what I have so far.
Val should return a value from 2 to 145. Its for 36 slots * 4 states per slot.


INPUT PORTB.4
INPUT PORTB.5
LCDOUT $FE, 1
VAL VAR WORD
VAL = 2

MAIN:
LCDOUT $FE, 1
LCDOUT $FE, $80, #PORTB.4, #PORTB.5
LCDOUT $FE, $C0, #VAL
IF PORTB.4 = 0 AND PORTB.5 = 0 THEN Q00
IF PORTB.4 = 0 AND PORTB.5 = 1 THEN Q01
IF PORTB.4 = 1 AND PORTB.5 = 1 THEN Q11
IF PORTB.4 = 1 AND PORTB.5 = 0 THEN Q10
GOTO MAIN
Q00:
IF PORTB.4 = 0 AND PORTB.5 = 1 THEN VALADD
IF PORTB.4 = 1 AND PORTB.5 = 0 THEN VALMINUS
GOTO Q00


Q01:
IF PORTB.4 = 1 AND PORTB.5 = 1 THEN VALADD
IF PORTB.4 = 0 AND PORTB.5 = 0 THEN VALMINUS
GOTO Q01


Q11:
IF PORTB.4 = 1 AND PORTB.5 = 0 THEN VALADD
IF PORTB.4 = 0 AND PORTB.5 = 1 THEN VALMINUS
GOTO Q11


Q10:
IF PORTB.4 = 0 AND PORTB.5 = 0 THEN VALADD
IF PORTB.4 = 1 AND PORTB.5 = 1 THEN VALMINUS
GOTO Q10

VALADD:
VAL = VAL + 1
IF VAL > 145 THEN VAL = 2
GOTO MAIN

VALMINUS:
VAL = VAL - 4
IF VAL < 2 THEN VAL = 145
GOTO MAIN

SteveB
- 10th September 2006, 02:41
Smitty,

Go to Darrel Taylor's Instant Interrupt Site (http://darreltaylor.com/DT_INTS-14/intro.html) and download DT_INTS-14.bas (http://www.darreltaylor.com/DT_INTS-14/downloads.htm) and ReEnterPBP.bas (http://www.darreltaylor.com/DT_INTS-14/downloads.htm)

In the DT_INTS-14.bas file, comment out the Highlighted line below, as shown.


'************************************************* ***************
'* Name : DT_INTS-14.bas *
'* Author : Darrel Taylor *
'* Version : 0.93 BETA *
'* Date : JAN 29, 2006 *
'************************************************* ***************
'* Rev 0.93 Fixed CMIF and EEIF problem with older PIC's *
'* that have the Flags in PIR1 instead of PIR2 *
'* Rev 0.92 solves a "Missed Interrupt" and *
'* banking switching problem *
'************************************************* ***************
DEFINE INTHAND INT_ENTRY

wsave var byte $20 SYSTEM ' location for W if in bank0
;wsave var byte $70 SYSTEM ' alternate save location for W
' if using $70, comment out wsave1-3

' --- IF any of these three lines cause an error ?? ----------------------------
' Comment them out to fix the problem ----
' -- It depends on which Chip you are using, as to which variables are needed --
wsave1 var byte $A0 SYSTEM ' location for W if in bank1
wsave2 var byte $120 SYSTEM ' location for W if in bank2
'wsave3 var byte $1A0 SYSTEM ' location for W if in bank3
' ------------------------------------------------------------------------------


Below is a bit of untested code (I don't have a 16F628 nor 2 Available Rotary Encoders) I threw together to get you started. It did compile without errors (if you made the change to DT_INTS-14.bas above), just can't actually try it in a PIC (let alone your setup). This code should allow you do keep track of both the rotary encoders regardless of what else your program is doing.




Old_Bits VAR BYTE
New_Bits VAR BYTE
RotEnc1_val VAR BYTE 'Connected to PORTB<4:5>
RotEnc2_val VAR BYTE 'Connected to PORTB<6:7>
TRISB = %11110000
RotEncDir VAR BIT
'************************
' SETUP YOUR LCD HERE!!!
'************************


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

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 & (%11110000)
Main:
LCDOUT $FE, 2,"ROT1:", DEC2 RotEnc1_val,"ROT2:", DEC2 RotEnc2_val
pause 10
GOTO Main

'---[RBC - interrupt handler]---------------------------------------------------
Rot_Encoder:
New_Bits = PORTB & (%11110000)
IF (New_Bits & %00110000) = (Old_Bits & %00110000) then No_Change_Rot1
RotEncDir = New_Bits.5 ^ Old_Bits.4
if RotEncDir = 1 then
RotEnc1_val = RotEnc1_val + 1
if RotEnc1_val = 36 then RotEnc1_val = 0
ELSE
RotEnc1_val = RotEnc1_val - 1
if RotEnc1_val = 255 then RotEnc1_val = 35
ENDIF
No_Change_Rot1:
IF (New_Bits & %11000000) = (Old_Bits & %11000000) then DoneRotEnc
RotEncDir = New_Bits.7 ^ Old_Bits.6
if RotEncDir = 1 then
RotEnc2_val = RotEnc2_val + 1
if RotEnc2_val = 36 then RotEnc2_val = 0
ELSE
RotEnc2_val = RotEnc2_val - 1
if RotEnc2_val = 255 then RotEnc2_val = 35
ENDIF
DoneRotEnc:
Old_Bits = New_Bits
@ INT_RETURN


A couple of items to mention. It assumes the you have connected your rotary encoders with the "A" Pins on PORTB.4 and 6, and "B" Pins on PORTB.5 and 7. Also, you have to have pull-ups on all 4 lines. If it "sort-of" works, try switching the lines on the encoders to the opposite pins.

I assumed you will configure you lcd on you own as needed.

Also make sure the files downloaded from Darrel Taylor are in the some directory as the main program file.

HTH,
Steve B

smitty505000
- 10th September 2006, 05:15
WOW! Thanks Steve!

Makes my code look like a 5 yo did it. LOL

Ok, did what you said and commented out the line you highlighted.
Then put both "DT_INTS-14.bas" and "ReEnterPBP.bas" into the same folder as your code.

"DT_INTS-14.bas" had to be renamed because it downloaded as "DT_INTS-14[1].bas.txt"

"ReEnterPBP.bas" had to be renamed because it downloaded as "ReEnterPBP.bas[1].bas.txt"

When I try to compile it in PBP I get some errors. I am not used to asm includes so I might be doing something wrong.

It is unable to load both include files and 3 other errors.

See attached screencap

Thanks,
Smitty

SteveB
- 10th September 2006, 06:43
Smitty,
Try this on your cmd line:

pbpw -p16f628 -ampasmwin yourfilename

The trouble is actually two fold.
1) PBP is DOS based, and does not like long file names. PBPW is ok with them.
2) You need to use the MPASM assembler. So make sure it is installed before you run the above line! It is needed for the Macros, as well as if you make the switch to the 18F series.

Out of curiosity, why not use MicroCode Studio?

Good Night,
Steve B

EDIT: Use the name for your file on the above cmd line

smitty505000
- 10th September 2006, 19:02
After 5 hours trying to get things to work I am at a loss. :(

And a bit hungry. LOL

I dl and installed mplab and the plugins for pbp. I followed the instructions for setting it all up.

I tried to compile from dos "pbpw -ampasmwin -p16f628" and also from mplab and get the same error "unable to execute mpasm".

I set the path as directed for xp and have rechecked it.

Even though everything I read said do not put mpasm.exe into the pbp directory, I tried it and it then got past unable to execute mpasm.

Now I get about 117 errors starting off with cannot find 16f628.inc file. This file is in the same directory!

Not sure what to try next.

PBP v2.44
MPlab v7.42

Thank you for your help

Smitty

sayzer
- 10th September 2006, 19:22
Smitty,
.....
Out of curiosity, why not use MicroCode Studio?
.....

Hi Smitty,

As Steve B also asks about it here, is there a particular reason why you are not using MicroCode Studio?

Also, for the encoder , don't you think that you can do what you need with one direction?

If you think you can, then I can give you some piece of code for TMR1 and TMR0 so that you can set it up for reading the encoder, and suggest some ways of having the missing counts minimized.

In your case, as much as I understood it, the degrees needed are wide enough to cover the missing counts.

smitty505000
- 10th September 2006, 20:09
I just tried microcode studio and get the same errors. Cant find 16F628.inc

This file is in the pbp directory, I do not understand.

sayzer, Thanks for the offer but I do need both directions to be able to tell if it is a right or left roll ,an up or down pitch and how far for both.

Microcode studio is pretty sweet I must say. Thanks for recommending it.

Smitty

SteveB
- 10th September 2006, 20:30
You did restart your computer, right? Well, if we don't have any success going that route, there are alternatives.

Look at the code in the Interrupt Handler. Put this in your main loop, so it repeatedly checks PORTB for changes. Like This:



'************************
' DEFINE your OSC
' and any other
' configuation items
'************************


Old_Bits VAR BYTE
New_Bits VAR BYTE
RotEnc1_val VAR BYTE 'Connected to PORTB<4:5>
RotEnc2_val VAR BYTE 'Connected to PORTB<6:7>
TRISB = %11110000
RotEncDir VAR BIT

'************************
' SETUP YOUR LCD HERE!!!
'************************

Old_Bits = PORTB & (%11110000)

Main:
New_Bits = PORTB & (%11110000)
IF (New_Bits & %00110000) = (Old_Bits & %00110000) then No_Change_Rot1
RotEncDir = New_Bits.5 ^ Old_Bits.4
if RotEncDir = 1 then
RotEnc1_val = RotEnc1_val + 1
if RotEnc1_val = 36 then RotEnc1_val = 0
ELSE
RotEnc1_val = RotEnc1_val - 1
if RotEnc1_val = 255 then RotEnc1_val = 35
ENDIF
No_Change_Rot1:
IF (New_Bits & %11000000) = (Old_Bits & %11000000) then DoneRotEnc
RotEncDir = New_Bits.7 ^ Old_Bits.6
if RotEncDir = 1 then
RotEnc2_val = RotEnc2_val + 1
if RotEnc2_val = 36 then RotEnc2_val = 0
ELSE
RotEnc2_val = RotEnc2_val - 1
if RotEnc2_val = 255 then RotEnc2_val = 35
ENDIF
DoneRotEnc:
Old_Bits = New_Bits

LCDOUT $FE, 2,"ROT1:", DEC2 RotEnc1_val,"ROT2:", DEC2 RotEnc2_val
GOTO Main


http://home.earthlink.net/~2hosting/Files/Working.JPG


Let's walk before we run and get this working. :)

Steve

smitty505000
- 10th September 2006, 22:09
Steve,
Yup, restarted pc many times. LOL. I would really like to know what the problem is. I guess I will have to look into it further.

You said "Look at the code in the Interrupt Handler. Put this in your main loop"

Did you mean to compile just the code you listed or to add it to one of the others? If you meant by itself then it compiled just fine.

I tried it out and had some strange readings. It starts with Rot1:00 and Rot2:35. When I rotate the encoders nothing happens.

To test and see if it was the encoder or the program, I unpluged the a & b chanels from encoder 1 and alternately touched them to ground and the numbers changed. This makes me think something is wrong in the encoder circuit. I played arround with different values on the resistors to no avail. The encoders output a positive voltage between ~1.85 and 5 and I have 4.7K resistors pulled to ground on each channel.

I did notice if I was under a bright light and held the encoders at just the right angle the numbers changed but they were jumping arround and not going 1.2.3.4~.

Man I didnt think encoders were so tough.

Smitty

SteveB
- 10th September 2006, 23:04
Smitty,


You said "Look at the code in the Interrupt Handler. Put this in your main loop"

Did you mean to compile just the code you listed or to add it to one of the others? If you meant by itself then it compiled just fine.

Just use the "new code" in the last post by itself (I did the moving for you).


It starts with Rot1:00 and Rot2:35

Add something like this just below the variable declarations to give an initial starting value.

RotEnc1_val = 0
RotEnc2_val = 0


OK. Do you have the datasheet for the encoders? I assumed (always bad) that they where mechanical encoders, similar to the one shown here (http://www.mcmanis.com/chuck/robotics/projects/lab-x3/quadratrak.html). Hook-up as per the nice diagram.

If they are not mechanical encoders, then they are optical. If so, they will have a Vcc, GND, ChA, and ChB. Also, no pull-ups (or downs) required.

At least it looks like the code is working. More info please. :)

Steve

smitty505000
- 10th September 2006, 23:54
Ok, I did just use the code by itself and I understand setting the variables to =0. Off to a good start :)

The encoders are optical with no data sheet since I pulled them out of a ball mouse. There is an emitter, wheel with 36 slots, and reciever for each encoder. They are in the same mounting positions as when the mouse was a mouse. I just chopped off the pc board behind them and attached my wires. The emitters only have 2 pins, +5v and ground. The recievers have 3 pins, A,B, & +5v. I know this because I traced them back on the mouse board before cutting. I also checked another mouse to be sure. (I bought 4 of them to play with).

With my original code (the really simple one a few posts back) nothing happened until I put in the resistors to ground. Thats the only reason they are in the circuit. The read out on the lcd also displayed channel A and B status and I could see 00 01 11 10 00 when rotated very slowly.

I did try your code without the resistors and it didnt make any difference.

I agree with you when you say we need to walk before we run. So I checked the outputs of the encoders with a logic probe. I am getting a high/low pulse out of each of the channels when they are rotated.

Smitty

SteveB
- 11th September 2006, 01:12
So I checked the outputs of the encoders with a logic probe. I am getting a high/low pulse out of each of the channels when they are rotated.

What voltage do they output on the channels? I haven't hacked any mouse encoders, so a google on that (or someone else on this forum who has could chime in) could help make sure the hardware portion is working properly.

I do know the code is working now. I scared up 2 mech encoders, and hooked them up to an 18F4620 I have. Using the internal pull-ups on port B, worked without a hitch. I see no reason it wouldn't work on the 16F628.

Steve

smitty505000
- 11th September 2006, 02:25
I just did a little more testing and found that the photodiode reciever has a ramp up and a ramp down on the voltage. If turned to fast the voltage stays high. I do not think it is as easy as on/off pulses. That could explain the eratic behavior. If this is correct then I need to measure freq along with the change right? Or am I going in the wrong direction.

I am looking at another alternative. A pair of mems 360deg inclinometers with spi output. Here:
http://www.analog.com/en/prod/0%2C2877%2CADIS16203%2C00.html

I ordered a couple of the pcb samples :)

I love samples :)

I have a couple of 16f876 lying around and they have spi.

mister_e
- 11th September 2006, 04:13
if you don't need a 360 degree, a simple POT may do the job.
A mechanical or optical encoder will work as well.
Some photo detector (taken in VCR, Tape deck or else) like GPIA70R (if my memory is good) have to work AS-IS

mister_e
- 11th September 2006, 04:41
The encoders output a positive voltage between ~1.85 and 5 and I have 4.7K resistors pulled to ground on each channel.

So it's never 0V? @1.85 you're probably sometimes in-between Low and High logic Level. You may need to 'filter' it a little bit to avoid oddity.

1.Use the internal voltage comparator, set the threshold and use their interrupt to increment the counter.
OR
2.try something like...
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1067&stc=1&d=1157946206">
maybe one diode could be enough... maybe not
HTH

smitty505000
- 15th September 2006, 20:49
I got it working! Sort of. I played arround with different value resistors and some diodes as sugested by mister_e and ended up with 30K resistors. Also seams my pic16f628-20p dosnt have a very accurate osc in it. I hooked up an external resonator and it works at 20mhz using Steve's slightly modified code from post #12. Thanks Steve!
The only thing now is it sometimes skips or looses count. Either the pic running at 20mhz cant keep up or the infrared red rx cant keep up. These encoders came out of a PS2 computer mouse. The ones that turn off the ball.

Any ideas guys?

Thanks!
Smitty

SteveB
- 17th September 2006, 01:41
I got it working! Sort of. I played arround with different value resistors and some diodes as sugested by mister_e and ended up with 30K resistors. Also seams my pic16f628-20p dosnt have a very accurate osc in it. I hooked up an external resonator and it works at 20mhz using Steve's slightly modified code from post #12. Thanks Steve!
The only thing now is it sometimes skips or looses count. Either the pic running at 20mhz cant keep up or the infrared red rx cant keep up. These encoders came out of a PS2 computer mouse. The ones that turn off the ball.

Any ideas guys?

Thanks!
Smitty


Now your walking, time to RUN!! Go back to post #6 and give the interrupts a try. With the optical encoders and interrupts, you should have not any switch bounce, and you should also not have any "skips". Well, if it turns faster than the interrupts can process the inputs, you can have some skips, but the nice thing about the interrupts is that the updates to the rotarty encoders count will not "wait" on the LCD output to finish.

Give it a shot,
Steve

smitty505000
- 23rd September 2006, 22:39
Steve,
I am ready to run but cant get it to compile. I am not sure what I am doing wrong. Did you get it to compile?

Thank you for all your help!

Smitty

SteveB
- 23rd September 2006, 23:45
Yes, it compiles. You need to use Microchips Assembler instead of the MeLabs. What errors are you getting? (Are you using MicroCode Studio?)

smitty505000
- 26th September 2006, 02:03
Hey Steve,

I have tried microcode studio and microchips mpasm. I think I might have a problem with mpasm talking to pbp or I installed something wrong. I was going to unistall everything and try again but my pbp is on a floppy and I found out my floppy drive (havent used it in years! LOL) is bad. I ordered a new one and will have it by the end of the week. Its amazing how cheap a floppy drive is these days. I also ordered my first Oscilloscope! Its only a BK precision 2120b 30mhz dual channel but it should be able to handle everything I do.

Thanks,
Smitty

SteveB
- 26th September 2006, 03:35
I think others may have had the same problem. DynamoBen recently got his to work. (http://www.picbasic.co.uk/forum/showthread.php?t=3860) Maybe he can help sort out whats wrong. He mentions that he "changed the registry", but no specifics. Not having had a problem with my setup, I'd just be guessing.

The other alternative is writing the interrupt routine is ASM. :eek: Better to get your compiler/assembler arrangement working properly.

Steve

smitty505000
- 28th September 2006, 23:15
I got it to compile!!! Using microcode studio. :) Happy dance. LOL

On a down note, it dosnt do anything. The LCD has a value of 0 for both encoders. I tried switching the a&b channels and still nothing. I checked all my connections and everything looks good. I am using a 16F876A now instead of the 16F628. I need to check those pins and see if anything needs to be turned off.

I think I am getting close!

Thanks,
Smitty

SteveB
- 29th September 2006, 03:18
I got it to compile!!! Using microcode studio. :) Happy dance. LOL

http://home.earthlink.net/~2hosting/arg-dancing-awesome-yellow-url%5b1%5d.gif

Once you check over the hardware to eliminate any problems there, then post the code you are using. Lots of folks can help out with that!

Steve

mister_e
- 29th September 2006, 04:50
Hey Steve, seems we use the same source for this 'Dancing Awesome' :D
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=881&d=1148640458">

smitty505000
- 29th September 2006, 20:15
LOL, Thanks for the help and support guys!

Here is the run down

Code from Steve on post 12 works but looses count if rotated too fast so I know the circuit is good.

I then went to the code in post 6 with both asm routines and compiled it with microcode studio. Compiled fine. The only things I changed in the code from post 6 was adding:
DEFINE OSC 20
PAUSE 1000
SEROUT2 on PORTB.0 FOR LCD clear

SEROUT2 ON PORTB.0 FOR DISPLAY

Here it is:

Old_Bits VAR BYTE
New_Bits VAR BYTE
RotEnc1_val VAR BYTE 'Connected to PORTB<4:5>
RotEnc2_val VAR BYTE 'Connected to PORTB<6:7>
TRISB = %11110000
RotEncDir VAR BIT
'************************
' SETUP YOUR LCD HERE!!!
'************************
DEFINE OSC 20
PAUSE 1000 'Pause for LCD Power up

SEROUT2 PORTB.0, 84,[254, 88] 'Clear LCD

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

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

@ INT_ENABLE RBC_INT ;RB Port Change Interrupt

Old_Bits = PORTB & (%11110000)
Main:
SEROUT2 PORTB.0, 84,[254, 71, 1, 1, "ROT1:", DEC2 RotEnc1_val,"ROT2:",_
DEC2 RotEnc2_val]
pause 10
GOTO Main

'---[RBC - interrupt handler]---------------------------------------------------
Rot_Encoder:
New_Bits = PORTB & (%11110000)
IF (New_Bits & %00110000) = (Old_Bits & %00110000) then No_Change_Rot1
RotEncDir = New_Bits.5 ^ Old_Bits.4
if RotEncDir = 1 then
RotEnc1_val = RotEnc1_val + 1
if RotEnc1_val = 36 then RotEnc1_val = 0
ELSE
RotEnc1_val = RotEnc1_val - 1
if RotEnc1_val = 255 then RotEnc1_val = 35
ENDIF
No_Change_Rot1:
IF (New_Bits & %11000000) = (Old_Bits & %11000000) then DoneRotEnc
RotEncDir = New_Bits.7 ^ Old_Bits.6
if RotEncDir = 1 then
RotEnc2_val = RotEnc2_val + 1
if RotEnc2_val = 36 then RotEnc2_val = 0
ELSE
RotEnc2_val = RotEnc2_val - 1
if RotEnc2_val = 255 then RotEnc2_val = 35
ENDIF
DoneRotEnc:
Old_Bits = New_Bits
@ INT_RETURN


The LCD comes up and displays ok. Then when I rotate an encoder, sometimes I get a little garbage on the screen and then it just seams to hang. I can go thru many restarts before the LCD will display properly again. It kinda seams like the chip is stuck. Is that possible even though I disconnect power and then reconnect? Is the pic holding something in memory where it hangs? I am using a 16F876A

Thanks guys!
Smitty

SteveB
- 30th September 2006, 03:58
OK, I found an error in the interrupt setup. Make the change highlighted in red.


ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _Rot_Encoder, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
INT_ENABLE RBC_INT ;RB Port Change Interrupt
ENDASM

I tried this out on a 16F877a (since I don't have your model). Worked fine with the one encoder I have available hooked to Rot1. Don't see any reason it wouldn't work with both hooked up.

Steve

SteveB
- 30th September 2006, 13:25
Since you are using a serial LCD and software based serial routine, the interrupts will be disrupting the timing of the serial output. I would recommend using HSEROUT. The timing won't be affected with the interrupts.

EDIT:
Here is how you can do this:

1) Switch your serial cable to RB2 (pin 8)

3) Setup the HSER defines:

'Setup for 9600 baud
' Set transmit register to TXEN =1 (TX enabled) and BRGH = 1
DEFINE HSER_TXSTA 24h
' Set baud rate
DEFINE HSER_BAUD 9600

3) Change your SEROUT2 commands to HSEROUT.


HSEROUT [254, 88] 'Clear LCD

and

HSEROUT [254, 71, 1, 1, "ROT1:", DEC2 RotEnc1_val," ROT2:", DEC2 RotEnc2_val]



Steve

smitty505000
- 1st October 2006, 01:32
I think someone dosnt want this to work :(
I did the hserout just as you said and still got garbage. I then checked the pbp manual and double checked the define's. all ok. Wait a sec, the 16f876a has the usart tx on pin c6! Right? So I moved the lcd serial line to c6 and still got garbage! What is going on! So then I programed a simple code into the pic to just do a hserout to print to the lcd. I used the proper define's and still got garbage. At this point I am thinking what the heck is going on. So then went back to a simple program to print on the lcd with the serout2 command just to check the lcd. And sure enough garbage! Is the lcd bad? Well I then hooked it to the pc and ran a program that tests it and sure enough the lcd is shot! Not sure what happened. I never hooked it up reverse polarity. Is it possible that with the initial garbage coming out of the pic it sent something to the lcd that screwed something up? I am totaly scratching my head. LOL
The only thing that I might have done is connect the serial line going to the lcd to 5v. Would that kill it?
I am going to try the my old parallel lcd and see what happens.

Thank you for putting up with me this long. I will get this thing running if it kills me! LOL

Smitty

SteveB
- 1st October 2006, 02:01
In your first post in the thread, you said you were using the following:

Qty 2 quad encoders with 36 slots each
Pic 16F628-20p
parallel lcd

So, I figured you opted for a serial LCD to save on I/O lines with an 18 pin pic. So my last post was geared to the 16F628.

Wait a sec, the 16f876a has the usart tx on pin c6! Right?
Seems you switched PIC as well. :cool: Guess I could have been more generic and just said to hook up the serial out to the TX pin. :)


Is it possible that with the initial garbage coming out of the pic it sent something to the lcd that screwed something up?
Not likely. But worth a query to the distributor/manufacturer.


I will get this thing running if it kills me!
Well, I am sure it won't come to that. But this is one of those things that most of us have been through at least once (often multiple times), where we learn more than we expected going into it. ;)

Steve

mister_e
- 1st October 2006, 10:42
<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=639&d=1133445289">

smitty505000
- 1st October 2006, 19:11
I looked just like that guy! LOL

Well I just hooked up my old parallel LCD and got it working! The program with interupts is better but still loses count. I wonder if it is because the encoders do not have detents and can change direction in between?

A little more background on what I want to do with these in case someone has an alternative or any other input.

I have the two encoders set up so they are perpendicular to each other. Each has a small weight on one side so they stay oriented to gravity. One is for pitch and one is for roll. The numbers returned will be converted into degrees and then sent to a BOB-4 video module. For those who do not know, the bob-4 is a video overlay module and it supports vector graphics! I am setting it up to display a HUD for my RC plane. This HUD will have Altitude, heading, air speed, artificial horizon, temperature, miliamp hour meter, and some other nifty stuff. All viewed on the ground via a monitor or my video glasses.

Smitty

smitty505000
- 1st October 2006, 19:15
Oh yea, these encoders obviously will be in constant motion and I plan on using a dedicated pic to keep track of them.

Smitty

smitty505000
- 3rd October 2006, 02:51
I found something that looks easier to use and more accurate. What do you guys think about these little puppies?

http://www.usdigital.com/products/ma2/

The PWM type with ball bearings look like they will fit the bill. The best thing is, a simple pulsein command will read the absolute position. Also they are cheaper than going to mem's 360 degree inclinometers.
The ball bearing type are free spinning so a very small amount of weight will needed to keep them parallel with the gound. I have two ordered and should be able to have them working by this weekend. Then on to the code to do the vector graphics on the bob4.

Smitty

Darrel Taylor
- 3rd October 2006, 05:32
I've been watching this thread for quite some time now. Waiting for Steve's great example to provide the final, Yeah! it works.

But now to find out what the intended purpose was, I've assumed the position of hanging my head while shaking it back and forth. &nbsp;While this idea might have worked for a robot moving at a few inches per second, it doesn't have a chance in an R/C plane.

There are 2 parts to the gravity equation. There's the gravitational force (A force that pulls things together based on their mass and how close they are together). And, there's Inertia (The tendency of an object at rest to remain at rest, and of an object in motion to remain in motion.)

Gravity is the Weak force, and can be easily overcome by Inertia. So as the plane is making any kind of movement, the inertia stored in the weight on the sensor will want to continue moving in the direction it was going before the change in direction. It's not going to stay pointing straight down at the earth to relate to an artificial horizon. And the heavier it is, the more inertia it stores. Depending on the G forces applied, you can make a full loop and never have the weight move at all.

In order to track the changes in direction of a moving object that has no other reference point, you'll need a Gyroscope and an 3-axis Accelerometer. The accelerometer allows it to find out which way is down during straight and level flight, and the gyro tells it the orientation relative to the original accelerometer reading.

Now if all that sounds complicated, it's because it is. Just be glad you're not flying in space. Then you'd need to fix the location by star sightings. But you'd still need the gyro.
<br>

smitty505000
- 3rd October 2006, 14:04
Hi Darrel,
Thanks for your input! Please forgive me for not explaining everything. I understand inertia and centripetal force and I totally agree with you. However, the plane this unit is going into is slow and very stable. Yes it can do loops and rolls but I do not plan on doing any (or at least I don’t expect the reading to mean anything if I do). I plan on just slow gentle flying and gliding. For this, I believe my setup should work just fine. Please correct me if I am wrong.

Smitty

Darrel Taylor
- 3rd October 2006, 15:18
I still think you'll have problems with the weight swinging back and forth, and wild readings in general just do to the different G forces.

If you're just looking for a way of finding which way is down during level flight. Perhaps as an aid to setting the trim. I think it'll be a lot easier to use an accelerometer. It's not going to give an artificial horizon, but it can find which way is Up. It can also give other interesting info like the G force of a turn or the amount of turbulence.

There's a nice one at Parallax for pretty cheap. And it works with PULSIN, so no interrupts or quadrature encoders to deal with.

Memsic 2125 Dual-axis Accelerometer
http://www.parallax.com/detail.asp?product_id=28017

Understanding the Basics of an Accelerometer
http://www.parallax.com/html_pages/resources/catapps/cat_acce.asp

HTH,

SteveB
- 3rd October 2006, 15:18
Having a little experiance with this from the operator end, Darrel is right, at any flight speed. It is inconcievable that you will only be flying in straight, unaccelerated flight, and this is the only time your concept would be accurate. Even at slight bank angles and accelerations, your "gravity" based system would not give you useful or accurate infomation.

Doing a little searching, found an adequate explaination (http://www.auf.asn.au/groundschool/umodule1b.html#turns) of why this the the case.

Steve

Darrel Taylor
- 3rd October 2006, 15:32
Darn 40 posts per page.

Smitty, if you missed it, go back to post #40, page 1.
Steve and I both hit it at the same minute :)
<br>

smitty505000
- 3rd October 2006, 15:50
Crud! You guys are convincing me that this will not work. I didnt think the forces would be that bad. I guess it is like walking and carrying a glass of water, and we all know how it sloshes around.

Ok so a Parallax dual accelerometer shows where down is? Is it effected by inertia?

What about a pair of Mem's inclinometers from Digital ADIS16203?

I need to do some more reading I guess.

Smitty

Darrel Taylor
- 3rd October 2006, 16:38
Is it effected by inertia?Yes it is. That's why it can't give an artificial horizon.


What about a pair of Mem's inclinometers from Digital ADIS16203?At $48 a piece for a single axis, It's makes the dual axis for $29.95 look a lot better.
<br>

smitty505000
- 3rd October 2006, 17:20
I am a little confused. Will inertia effect the ADIS16203 digital inclinometer as well? Dosnt it work off the earths magnetic field?

Is there any way I can make this artificial horizon work without a PHD in astrophysics?

Smitty

sayzer
- 3rd October 2006, 17:25
....

Is there any way I can make this artificial horizon work without a PHD in astrophysics?
..

I was about the say that this issue is getting too complicated for me to follow.

SteveB
- 3rd October 2006, 17:30
Here is a quote from the datasheet of the ADIS16203:


The ADIS16203 is a calibrated digital inclinometer that provides a full 360° of measurement range in any rotational plane that is parallel to the earth’s gravity. A dual-axis accelerometer provides the base-sensing function, which resolves the earth’s gravity into two orthogonal vectors, as displayed in Figure 23. A power-efficient approach to a common trigonometric identity converts these orthogonal vectors into an incline-angle measurement.

It is an accelerometer. Thus, in flight, will only be accurate when the plane is in wings level, unaccelerated flight. In other conditions, it will be giving you the resulting sum of all accelerations on the plane, which will certianly not be the same as the acceleration of the earth's gravity.

Steve

sayzer
- 3rd October 2006, 18:17
Does that mean that if the speed in any direction is constant (meaning not increasing or decreasing) then you get zero?



--------------

Luciano
- 3rd October 2006, 20:53
Hi,

See these links.

Vibrating structure gyroscope

http://www.invensense.com/shared/pdf/MEMSGyroComp.pdf
http://www.analog.com/library/analogDialogue/archives/37-03/gyro.pdf
http://www.nec-tokin.com/english/product/piezodevice2/ceramicgyro.html
http://www.nec-tokinamerica.com/products/PDF-New-Products/pd-057e.pdf

Best regards,

Luciano

SteveB
- 3rd October 2006, 21:30
Does that mean that if the speed in any direction is constant (meaning not increasing or decreasing) then you get zero?

An aircraft can experiance both linear and angular acceleration in 3 axis (6 in total). If there is NO acceleration in any axis, the answer to your question is yes (and maybe no-see next paragraph). This is not "0 g". In this stabilized flight, the aircraft (and occupants) would experiance "1 g", just like what you feel sitting in front of your computer screen (unless you are really exicted playing the lastest and greatest video game :D)). Accelerometers would read "0", since no acceleration is occuring.

The main problem with accelerometers is that they will always be referenced to the aircraft itself. I can fly my airplane upside-down, and still make it "feel" to the accelerometer as if It was experiancing the same accelerations as level flight (but not for long). This makes them unable to provide useful attitude infomation.

A Gyro, on the otherhand, can be "spun-up" and aligned with the surface of the earth. The better the gyro, the longer it will remain aligned with it's initial reference. This will then provide the independent reference needed for attitude information.

Don't know if this helped, or just made the water muddier.

Steve

SteveB
- 3rd October 2006, 22:36
Smitty,
Here (http://autopilot.sourceforge.net/faq.html#2) is an interesting link to a site on a homebrew UAV. It deals with the problems associated with accurately calculating attitude of an aerospace vehicle. You may get some ideas you can implement on a smaller/limited scale to achieve your objectives.


Better link (http://autopilot.sourceforge.net/ahrs-survey.html), check out items under "Design:". Particularly AHRS and Sensors.

HTH,
Steve

EDIT: One final note, there is a reason the off the self systems are very expensive. It is not a trivial task!

smitty505000
- 5th October 2006, 22:44
Thanks for all the info guys!! I have been doing some reading and I see what you mean. At least I know how to read encoders now. :)

I do have an idea how to make the artificial horizon. I need to do some tests but the basic idea is to use a couple or RC heading hold gyros. I have a futaba gy401 and have already done some tests on it. It outputs a pwm signal to move a servo. The down side is It only tracks about 30-35 degrees of movment. Now here is the interesting part. It can be reset to 0 via another pwm signal! So here is my idea. Have it set up to read movement and output to the pic. Then in the program have it set to reset when it reaches its limit. A counter will keep track of which set of 30-35 degrees it is on. This should be able to keep track with a certain amount of drift or error. Depending on how much error there is, I thought it could also be reset when level to the ground. To do this I can use a futaba pa1 pilot assist unit. This unit detects the light to dark difference optically and knows when it is level. It outputs 2 pwm channels that can reset both gyros! Hope this makes sense, I am in a hurry.

What do you think?

Smitty