Rotary encoder usage

alistairsam

Senior Member
Hi,
looking through the I2C tutorial, its mentioned that "all data transfer from the mast to slave is a write, and from slave to the master is read".

but going by the manual, is the reverse possible? that is can the master read values from the slave?

if I'm using two 20X2 and no external EEPROM, can the bus speed be set to i2cfast (400KHz)

below will be the code for the slave chip which just counts and stores the position. the master chip will periodically read the position and calculate the offset and final position, then display, possibly just twice or thrice a second.

Code:
'Slave Picaxe for counting pulses

setfreq m64
#picaxe 20X2

hi2csetup i2cslave, %10100000

Symbol enccount = w0
Symbol steps = w1

enccount = 16100 'enter max encoder pulses

HIntSetup %00100010
Gosub Interrupt_Enable


Do 
Put 1, w0
Loop

incr:
hInt1Flag = 0
hInt2Flag = 0
SetIntFlags %00000010, %00000010

if steps = enccount then let steps = 0
endif
steps = steps + 1
goto interrupt_enable

decr:
hInt1Flag = 0
hInt2Flag = 0
SetIntFlags %00000010, %00000010

steps = steps - 1
if steps = 0 then let steps = enccount
endif
goto interrupt_enable

Interrupt_Enable:
SetIntFlags %00000010, %00000010
  Return

Interrupt:
if pinB.1=1 then goto Incr
if pinB.1=0 then goto Decr
 

Jeremy Leach

Senior Member
I don't think I can use the HCTL-2032 chip as it outputs counts over 32 bits, and I'll have to convert it from integer to dms
Well, it still might be possible even though it's a 32 bit number. Addition and subtraction is pretty easy even over 32 bits, so you could work out the change between count values, and if this change <=65535 then it would be pretty easy in PICAXE maths to convert this change into dms form (because you could use normal division). THEN have a routine that added (or subtracted) this dms value to/from a running dms value that represented the count value.
 
Last edited:

alistairsam

Senior Member
Well, it still might be possible even though it's a 32 bit number.
Hi,
am studying the chip to see how to use it, slightly confusing bit is sequence of loading the msb and lsb.
other thing is that the picaxe would need to send the reset pulse to reset the chip's counter, and i'll have to figure out how the picaxe would always keep track of the change in position counter in the chip.
meanwhile, i came up with this code to increment three variables for deg min sec. not very elegant as its limited by my basic skills, but it works.

have it as one code including display for simulation, but will be separating to master and slave with two 20x2's, was just testing the alternative to the chip. will be trying both methods though.
have to figure out the master slave config.

Code:
#picaxe 20x2
setfreq m64

Symbol enccount = w0
Symbol secs = w1
Symbol degr = w2
Symbol gfactor = w3
Symbol secsubtmp1 = w4
Symbol secsubtmp2 = w5
Symbol secmain = w7
Symbol sectmp1 = w8
Symbol mintmp2 = w10

Symbol sectmp2 = b24
Symbol mintmp1 = b25
Symbol mins = b29
Symbol degrflg1 = b32
Symbol degaddflg = b33



enccount = 24000 'enter max encoder pulses
gfactor = 64800 / enccount
gfactor = gfactor * 20

HIntSetup %00100010
Gosub Interrupt_Enable


Do 
Put 1, b9
Put 2, b10
Put 3, w3
Loop



Incr:
hInt1Flag = 0
hInt2Flag = 0
SetIntFlags %00000010, %00000010

addloop:
secadd:
sectmp1 = secmain + gfactor
if sectmp1 > 3600 then let secmain = sectmp1 - 3600
degaddflg=1
elseif sectmp1 < 3600 then let secmain = sectmp1
elseif sectmp1 = 3600 then let secmain = 0
degaddflg=1
goto mincalc
endif

mincalc:
mintmp1 = secmain / 60
mintmp2 = mintmp1 * 60
secs = secmain - mintmp2
if mintmp1 = 60 then let mintmp1 = 0
elseif mintmp1 > 60 then mins = mintmp1 - 60
degaddflg = 1
endif
mins = mintmp1
if degaddflg = 1 then goto degadd
if degrflg1 = 1 then goto degsub
goto interrupt_enable

degadd:
if degr = 359 then let degr = 0
elseif degr <= 358 then inc degr
endif
degaddflg = 0
goto interrupt_enable


Decr:
hInt1Flag = 0
hInt2Flag = 0
SetIntFlags %00000010, %00000010


secsub:
secsubtmp1 = secmain - gfactor
if secsubtmp1 > 64000 then let secsubtmp2 = 65535 - secsubtmp1
secmain = 3599 - secsubtmp2
degrflg1 = 1
elseif secsubtmp1 >= 0 then let secmain = secsubtmp1
endif
goto mincalc


degsub:
if degr <= 0 then let degr = 360
endif
dec degr
degrflg1 = 0
goto interrupt_enable




Interrupt_Enable:
Serout B.2,N2400,(254,1)              'Clear LCD
Serout B.2,N2400,(254,128,"RA ",#w2,"d ",#b29,"m ",#w1,"s") 'Value of B0 on top line of LCD
SetIntFlags %00000010, %00000010
  Return



Interrupt:
if pinB.1=1 then goto Incr
if pinB.1=0 then goto Decr
 

alistairsam

Senior Member
from the HCTL-2032 datasheet, "In order to prevent loss of position information, the processor must read the outputs of the IC before the count increments one- half of the maximum count capability. Two's-complement
arithmetic is normally used to compute position from these periodic position updates."

is two's complement math possible on the picaxe? its primarily to work with negative numbers, but not sure how to implement it in basic.
 

Jeremy Leach

Senior Member
The counter is just a 32bit number that rolls over.

I think in traditional usage you would want to sample the counter fairly regularly, otherwise you might misinterpret the relative movement from one sample to the next. Take a simple analogy with a 3 bit counter (values 0 to 7):

Lets say the counts are coming in very fast, but your processor is sampling slowly. One sample is the value 4 and the next sample is the value 5. Your processor takes these values and decides the position has incremented by 1. But actually the position has incremented by 9 because the counter has rolled over between samples.

So to ensure you don't get this misunderstanding you need to sample at least every half-cycle of the counter.


Ideally, the best thing to do in your case would be to make the counter rollover precisely match a 360 degree revolution. So the counter value would exactly match the absolute angular position (compared to when you initially zero the counter). The sampling problem above is then eliminated. And IF the PICAXE could easily translate the 32bit counter value to dms value then it would all be easy - you could just sample when you liked, knowing that the value would always be the absolute angular position. Which is what you want for star-gazing. You're not interested in how many revolutions your telescope has made :)

HOWEVER, I believe you still do need to sample regularly purely because of the limitations of PICAXE maths. As I said before, I think it would be difficult to write code that directly translates a 32bit counter value into a dms value, because the PICAXE can only handle division of Word values, not double Word values. The way round this problem is to work out the dms value incrementally as the counter changes, and making sure the change in count value is no bigger than 65535 between each sample.

EDIT: Thinking a bit more about this, 32Bit count per revolution is Huge. The IC also does 16 and 24 bit.
 
Last edited:

alistairsam

Senior Member
EDIT: Thinking a bit more about this, 32Bit count per revolution is Huge. The IC also does 16 and 24 bit.
I thought of the same thing as well. the pulses from the encoder are never going to exceed 40000, so 16 bit should be ample.

but I'll have to look at the chip timing more closely because the picaxe would have to sent the reset counter pulse for the chip counter to roll over, and for that, the picaxe would need to keep track of the counter fairly closely.
i think it was 3 clock cycles per pulse for the chip.
so unless I get the picaxe to poll counter values every 3 or 6 clock cycles at most, the rollover would be a bit late.
one other issue is that when I do the star alignment, i'll have to set the picaxe dms counter or decimal counter to the dms value of the star and from there, it would be clockwise or counterclockwise, thus incrementing or decrementing.
so the rollover point of the quad chip has to be properly aligned, else it would rollover backwards and i guess thats why the datasheet mentioned twos complement arithmetic.
it'll be very rarely taken through 360 deg. it'll mostly be 0 to 100 clockwise and 0 to 260 deg counterclockwise.
 

Jeremy Leach

Senior Member
the picaxe would have to sent the reset counter pulse for the chip counter to roll over, and for that, the picaxe would need to keep track of the counter fairly closely
No ... I think you misunderstand. Sure, the PICAXE must reset the counter initially for calibration/ alignment purposes, but after that the counter will rollover on it's own on the IC. That IC is simply (although it's very good) an up/down counter that is driven from the quadrature input. If the counter reaches it's maximum value it will just rollover on it's own. The same way that if you increment a byte variable on a PICAXE, the variable will rollover back to 0 when it increments past 255. i.e 255 + 1 = 0

This happens in reverse too: 0 - 1 = 255 for a PICAXE variable, and the same will happen for the 32Bit counter.

I've got an idea for a division routine that would enable you to directly translate the 32Bit counter value to a dms value. I might post it later if it works !

EDIT: Division routine didn't work out !
 
Last edited:

Jeremy Leach

Senior Member
Also, the maths side of it all comes down to the resolution you're after.

360*60*60 seconds in a revolution = 1296000 seconds.

If you had 40000 counts per revolution then each count = 32.4 seconds. Not a nice number. But if you had 43200 counts per rev, then each count would = 30 seconds. Then the sums to work out the dms value would be easy:

Degrees = INT[(Count * 30)/3600] = INT[Count / 120] = Count/120 in PICAXE maths

Remainder = Count // 120 in PICAXE maths (using modulus)

Minutes = INT(Remainder /60 = Remainder/60 in PICAXE maths

Seconds = Remainder //60


All up to you, but I think you need to work out your resolution pretty soon before going too far. Look at your encoded wheel and your gearing and work out how many counts per rev you are going to get. Then see how the maths will look.
 

tarzan

Senior Member
Settimer Count

I have not followed this thread closely so forgive me if this is unwanted.

On X1/X2 excluding 20X2 Picaxe microcontrollers the external counter is available for use. It will keep count of the external counting process while the Picaxe executes its program. With the toflag its count is extended to seventeen bits, whether you need more than a word count or not it is nice to know.

External Counter (not available on 20X2)
In external counter mode an internal counter register (not accessible to the end
user) is incremented on every positive going edge detected on input 0. This pulse
counting occurs in the background, so the PICAXE program can perform other
tasks at the same time as it is counting (unlike the count command, which stops
other processing during the count command time period). When the internal
counter register overflows from 65535 to 0, the special ‘timer’ variable is
automatically incremented.
 

alistairsam

Senior Member
360*60*60 seconds in a revolution = 1296000 seconds.

If you had 40000 counts per revolution then each count = 32.4 seconds. Not a nice number. But if you had 43200 counts per rev, then each count would = 30 seconds. Then the sums to work out the dms value would be easy:
Hi
in my dms code above, the way I got around division and remainders is to divide the seconds (1 to 3600) by 60, and then multiply it again by 60. the difference would then be the seconds. have to understand your math and see if i can apply the same principle or if you've already applied it. but would be good if I could.

about the quadrature chip and the counter reset, what I was referring to was that if I'm using 16 bits, the counter would be from 1 to 65535 and then rollover to 0 and 1 and so on. but if my pulses are only say 20000, then the chip would need to rollover at 20000, not sure how the chip would do that without an external reset pulse.

but you're right, I need to determine the encoder count first.
working on it, I have some degree of flexibility so I can adjust the number of lines so I don't get a decimal after division.

is it not a workable idea to use my code above and increment 3 variables instead of division? i know its long, but it'll be on the display picaxe, not the counting one.

On X1/X2 excluding 20X2 Picaxe microcontrollers the external counter is available for use. It will keep count of the external counting process while the Picaxe executes its program. With the toflag its count is extended to seventeen bits, whether you need more than a word count or not it is nice to know.

tarzan, is there any info in the manuals, what do i look for? you mentioned the internal registers are not available to the user. so how do we retrieve the intermediate counts before it rolls over? is there only one input pin?
 
Last edited:

Jeremy Leach

Senior Member
There are just so many options here.

For instance, even though you might do 20000 counts per revolution, it doesn't mean you 'have' to reset the IC counter on a full revolution at all. Not if you are working with change values between samples.

I think you've got three main considerations:
1. What you can physically build on the encoded wheel side, and the gearing etc, and what is actually a reasonable accuracy to try to acheive considering the mechanical side of things. This might limit your choice of counts per revolution.

2. The way the IC works (if you want to use that IC) and options for the counter size.

3. The choices of PICAXE operation: i.e do you want to A) regularly poll the IC, get the counter value, work out the change and then apply this change to your locally held dms value or B)read the IC counter value at irregular intervals when needed, and translate the counter value to dms.

And probably other factors too. That IC seems to give you a real head-start though.
 

tarzan

Senior Member
tarzan, is there any info in the manuals, what do i look for? you mentioned the internal registers are not available to the user. so how do we retrieve the intermediate counts before it rolls over? is there only one input pin?
I just thought that I would throw it into the mix. The most likely scenario would be to set the counter with a value equivalent too two set points. Look up Settimer in manual 2 for full details. Not being able to read the counter register is a difficulty I know but it could be a solution. Pin0 only.
 

alistairsam

Senior Member
I did a very crude test with a slotted wheel from a mouse, the HLC2705 quadrature IR detector, a single 28X2, and a terminal session through the programming cable, the tacho pulse output is wired to pin B.0 and generates an interrupt for every pulse, the DIR output to pin B.2, this is checked when an interrupt is raised and then directed to the add or subtract routine.

apologies for the video quality, taken from my mobile, but thought i'd share it as its a start.
this is using the code i'd included above, yet to test with the hctl chip. its on order.

http://www.youtube.com/watch?v=FJsSzXvEJ-U
 
Last edited:

alistairsam

Senior Member
interfaced a 16x2 parallel LCD to the 28x2, and it works well.

http://www.youtube.com/watch?v=t5bLYiGcMtU

this was just a test to see how a single chip at 32MHz performs with parallel lcd display routines and quadrature encoder counters.
looks like two 20x2's at 64MHz should'nt have a problem counting and displaying.
but as I'll need two quadrature encoder angular values displayed on one LCD, I'll use the decoder chip suggested by Jeremy and one picaxe and eeprom for display.
should get it tested soon.
planning to add the star alignment routine and encoder pulse count routines all in a handheld box.

but the backlit displays are not impressive as without backlighting, characters are barely visible.
anyone had experience with transflective LCD's? they transmit and reflect at the same time so should provide better contrast.

might have to post in a different thread but any pointers on pwm control for the lcd backlight? are there any commands in the hdd44780 chipset that can control backlight?
 
Last edited:

alistairsam

Senior Member
Hi,

could you please tell me how I can use the "pins = " command without affecting the state of two specific pins, I'm guessing using a mask, but if I used the "var & %00001111" command, will it change pins 5,6,7,8 to zero?

to explain further, I'm driving a parallel LCD with a 20X2, but am not using the pins as per Hippy's thread, which was B.7 -> Db7 and so on.
reason is that I'm using the I2C bus to read values from another 20x2, and therefore pins B.7 and pin B.5 can't be used as they're the sda and scl.

I got the LCD code to work by shifting bits, but am not sure if the pins B.7 and B.5 will be affected by the mask technique above.

my pinout is as below

Pin Pin Fn
1 V+
2 Serial in
3 C.7
4 C.6 (in) kpad
5 C.5 kpad
6 C.4 kpad
7 C.3 kpad
8 C.2 kpad
9 C.1 kpad
10 C.0 kpad
11 B.7 SCL ->I2C
12 B.6 lcd -> E
13 B.5 SDA -> I2C
14 B.4 lcd -> rs
15 B.3 lcd -> DB7
16 B.2 lcd -> DB6
17 B.1 lcd -> DB5
18 B.0 lcd -> DB4
19 A.0(Sout)
20 Gnd

I got the parallel LCD code working with the above pinouts with this change

Code:
Symbol En = b.6

SendDataLCD:
  chr2 = chr >> 4 
  pinsB = chr2 & %00001111 | rsbit
  pulsout En, 2

  chr2 = chr * %00010000
  chr2 = chr2 >> 4 
  pinsB = chr2 & %00001111 | rsbit
  pulsout En, 2

  rsbit = RSDATmask
 return
 
Last edited:

MPep

Senior Member
might have to post in a different thread but any pointers on pwm control for the lcd backlight? are there any commands in the hdd44780 chipset that can control backlight?
My understanding is that there is external backlight control, ie from the potentiometer.
You can use PWM out. Connect a resistor and capacitor to get an 'analogue' output. Don't know what values to use, but that's what experimentation is all about. :)

Good luck.
MPep.
 

Jeremy Leach

Senior Member
I don't know about the LCD code, but this would change the Pins variable leaving 2 bits unchanged ...
Code:
MaskedValue = Value & %11100111
Pins = Pins & %00011000 & MaskedValue
You might not need the first line, if Value always had the relevant bits at zero.
 

alistairsam

Senior Member
I don't know about the LCD code, but this would change the Pins variable leaving 2 bits unchanged ...
Code:
MaskedValue = Value & %11100111
Pins = Pins & %00011000 & MaskedValue
You might not need the first line, if Value always had the relevant bits at zero.
thanks

would this be correct

Code:
pinstmp = chr2 & %00001111 | rsbit

MaskedValue = pinstmp & %01011111
PinsB = PinsB & %10100000 & MaskedValue
I'm looking at preserving states of pins B.5 and B.7

what does this " | rsbit" do to the value?
 

alistairsam

Senior Member
I'm trying to get one 20X2 read variables off two other 20X2's sharing the same I2C bus

is this code correct for this purpose?
I am getting only 0.

I also have a 256 EEPROM sharing the same I2C bus, and am able to write and read HELLO from the same master 20X2.

I2C part of the code below

(I have posted this question in another I2C thread, but thought I'd post it here as well as continuation of this encoder project thats almost complete)

Code:
master 20x2

Do
hi2csetup i2cmaster, %10101000, i2cfast, i2cword
hi2cin 10,(w2)
sertxd (254,128,#w2,CR,LF)
loop


slave 20x2

hi2csetup i2cslave, %10101000
put 10,b29
b29 does have values, tested this with sertxd to the terminal.
4k7 resistors also present.
 

alistairsam

Senior Member
Hi,

I fixed the I2C issue by swapping the LCD pins to pinsC instead of PinsB as SDA and SCL were on pinsB.
I can now read the variables off a slave 20x2 and display on the LCD connected to the master 20x2.

but could'nt read and construct a word variable.
how do I combine the two byte variables to form a word.


eg.
on slave
word value is in w2

put 0, b6,b5

on master
hi2cin [%10101000],0,(b6,b5)

will this write a word value into w2?

edit: corrected the mistake that w2 is b5:b4
 
Last edited:

Dippy

Moderator
I haven't been following this very long thread, but in answer to:-
"how do I combine the two byte variables to form a word."
- have a look in the BASIC Manual (Manual 2) page 10 "Variables - General".
The answer lies therein.

It really is worth reading the Manuals and trying simple tests in the simulator (or on the PICAXE) just to try things out.
It shouldn't blow up :)
 

alistairsam

Senior Member
I haven't been following this very long thread, but in answer to:-
"how do I combine the two byte variables to form a word."
- have a look in the BASIC Manual (Manual 2) page 10 "Variables - General".
The answer lies therein.

It really is worth reading the Manuals and trying simple tests in the simulator (or on the PICAXE) just to try things out.
It shouldn't blow up :)
Hi

I edited my post above to mention that i found my mistake. i should've rephrased the question as i knew how to combine bytes but wasn't sure if it was correct

sometimes it takes a while to hone in on the right sections of the manual when troubleshooting as you tend to assume the wrong things and don't go back to the manual
 
Last edited:

alistairsam

Senior Member
Hi,
(update)this telescope encoder project is going on well and has changed a lot from when I started.
its basically two optical encoders providing position information for a telescope.
I'm using three 20X2's, one for each axis of the scope and one for the display. the two 20x2's on each axis count encoder pulses and store position information in variables.

had a question on clock speeds when using a serial LCD and settimer on a 20x2.

I'd ideally like to run the 20x2 at 64Mhz, but how would this affect the baud rates for serout commands? also, how would this affect the settimer.

I'm trying to do two things with a 20x2.
write the timer variable from this 20x2 to a word variable on a slave 20x2 using the I2C bus every second, read variables from two slave 20x2's and send it using serout to a serial LCD.

the manual shows t1s_16 for settimer, thats at 16Mhz, and T9600_16 for serout at 16Mhz.
does this mean I'll only be able to run the display 20x2 at 16Mhz and not 64Mhz?
I wanted to refresh the LCD a few times a second just fast enough so position information is as instantaneous as possible.
 
Last edited:

hippy

Ex-Staff (retired)
Normally you'd just alter the _16 to whatever speed you are running at; t1s_64 and T9600_64 for 64MHz.

When you go up to high speeds you can run into issues where things stop being available because of hardware limitations. The timer works by incrementing a 16-bit counter and at 64MHz there's no value which will give a 1 second tick rate, so t1s_64 does not exist.

You can however use your own value to have a timer which ticks at a faster rate, say half a second, and adjust the rest of your code for that.
 

alistairsam

Senior Member
Normally you'd just alter the _16 to whatever speed you are running at; t1s_64 and T9600_64 for 64MHz.

You can however use your own value to have a timer which ticks at a faster rate, say half a second, and adjust the rest of your code for that.
Hi
i could use a faster timer tick and adjust my code to eventually increment for 1 second. so if it increments 4 times a second, I could have my counter add 1, when 4 ticks have passed.

if I ran it at 32Mhz, would I still run into issues with hardware limitations as you mentioned, would T9600_32 work at 9600baud for serout?
 

hippy

Ex-Staff (retired)
SEROUT supports T9600_32 and T9600_64 on the 20X2, After 16MHz (t1s_16) you need to start handling timer ticks faster than one per second. How you describe is the right way to approach things ( or divide the timer count by 4 or whatever when you come to use it ).
 

alistairsam

Senior Member
Hi,

I'm using the SerLCD module from sparkfun with a 16x2 character LCD.
I wanted to display static text in fixed positions in both lines, and have values from variables in between.

my code is working as is, but issue is that when the variable values are single digit numbers, the characters shift left leaving old values at the end of the line.


I'm using a 20X2 as display chip and the I2C master reading values off two slave 20X2's.

Do I display the static lines first using decimal locations and then display values again using decimal locations?

I have 6 variables and 8 fixed text in this format

line 1 - R A 0 0 0 h r 0 0 m 0 0 s
line 2 - D e c 0 0 0 d g 0 0 m 0 0 s

how do I send word values to the LCD as it expects 8bits at a time?
do I just convert word variables to the byte variables and send them sequentially?

eg. #w2
do I send as #b5,#b4

Code:
#picaxe 20x2
setfreq m16

' w0 - b1,b0
' w1 - b3,b2
' w2 - b5,b4
' w3 - b7,b6


Symbol radeg = b0
Symbol ramin = b1
Symbol rasec = b2

Symbol decdeg = w2
Symbol decmin = b8
Symbol decsec = b9

'high b.1
pause 500

serout B.0, T9600_16,(254,1)


Do
hi2csetup i2cmaster, %10011010, i2cslow_64, i2cbyte
hi2cin [%10011010],0,(radeg)
hi2cin [%10011010],2,(ramin)
hi2cin [%10011010],4,(rasec)
hi2csetup i2cmaster, %10001010, i2cslow_64, i2cbyte
hi2cin [%10001010],0,(decdeg)
hi2cin [%10001010],5,(decmin)
hi2cin [%10001010],10,(decsec)

serout B.0, T9600_16,(254,128,"RA  ",#b0,"hr ",#b1,"m ",#b2,"s")
serout B.0, T9600_16,(254,192,"Dec",#w2,"dg ",#b8,"m ",#b9,"s")

pause 100

Loop
 

ckoehn

Member
It takes a little more work, but this is how I do it.

symbol raddeg=b5

bintoascii raddeg,b0,b1,b2

if b0=48 then 'if a zero
b0=32 'change to a space
endif
if b0=32 and b1=48 then 'if first is a space and second is a zero
b1=32 'change to a space
endif

serout T9600_16,(254,128,"RA ",b0,b1,b2)

Use this method for the rest of the numbers.
 

Electromonkey

New Member
I've tried Christophe's original code (post 1 of this thread) on an 18x, which worked fine. Now I'm trying to get it working on an 18m2 but for some reason the 'dir' randomly changes from 0 to 2 and the counter randomly goes up and down when it is turned on the same direction. I have tried changing the 'pin1' and 'pin2' to the port.pin version but it doesn't make any difference. I've also tried setting the fequency to 4 to see if it's the speed of the picaxe thats stopping it working correctly, but again no change.
Has anyone got any idea why the code wouldn't work?
 

eclectic

Moderator
I've tried Christophe's original code (post 1 of this thread) on an 18x, which worked fine. Now I'm trying to get it working on an 18m2 but for some reason the 'dir' randomly changes from 0 to 2 and the counter randomly goes up and down when it is turned on the same direction. I have tried changing the 'pin1' and 'pin2' to the port.pin version but it doesn't make any difference. I've also tried setting the fequency to 4 to see if it's the speed of the picaxe thats stopping it working correctly, but again no change.
Has anyone got any idea why the code wouldn't work?
Please post your

1. Circuit.
2. You full code.

e
 

Electromonkey

New Member
This is the code I'm using with the 18m2 -
symbol getBits = b0
symbol dir = b1
symbol counter = b3

setint %00000010,%00000010
main:
do
sertxd("Main loop - Counter=",#b3,13,10)
sertxd("Main loop - dir=",#b1,13,10) 'added to monitor random changes
pause 1000
loop

interrupt:
bit2 = C.2: bit1 = C.1
getBits = getBits & %000000110
if getBits <> 0 then
dir = bit2 * 2 'direction: if bit2=low then dir=0; if bit2=high then dir=2
counter = counter - 1 + dir
do while getBits <> 0
getBits = pins & %000000110
loop
endif
setint %00000010,%00000010
return
The encoder is a Bourns, this is the data sheet -
http://www.bourns.com/pdfs/enc1j.pdf

The two outputs are connected to C.1 and C.2.

This code and setup worked fine with 18x (C.1 and C.2 were pin1 and pin2).
 

hippy

Ex-Staff (retired)
This code and setup worked fine with 18x (C.1 and C.2 were pin1 and pin2).
That's probably the mistake, should be -

bit2 = pinC.2 : bit1 = pinC.1

not

bit2 = C.2 : bit1 = C.1

Also

getBits = pins & %000000110

Should probably be

getBits = pinsC & %000000110


Do you have the original code which you translated from; that will save some guesswork.
 

eclectic

Moderator
Electro

Nowhere near perfect, but try

Code:
;Forum Th 271011
#picaxe 18M2


; let dirsC= %00000000

symbol getBits = b0
symbol dir = b1
symbol counter = b3

setint %00000010,%00000010 ,C
main:
do
sertxd("Main loop - Counter=",#b3,13,10)
sertxd("Main loop - dir=",#b1,13,10) 'added to monitor random changes
pause 1000
loop

interrupt:
bit2 = pinC.2: bit1 = pinC.1 
;bit2 = pin2 ; ***********
;bit1 = pin1 ; ***********

getBits = getBits & %000000110
if getBits <> 0 then 
dir = bit2 * 2 'direction: if bit2=low then dir=0; if bit2=high then dir=2
counter = counter - 1 + dir 
do while getBits <> 0 
getBits = pins & %000000110
loop
endif
setint %00000010,%00000010 ,C
return
e
 
Last edited:

eclectic

Moderator
Tried your original version first, then added 'c' to pins &00000110 and played with the pin1 / port.pin but still nothing.
One final try,
(which appears to work on my setup here),
before I go into Sleep mode.

Code:
;Forum Th 271011
#picaxe 18M2

symbol getBits = b0
symbol dir = b1
symbol counter = b3

setint %00000010,%00000010 ,C
main:
do
sertxd("Main loop - Counter=",#b3,13,10)
sertxd("Main loop - dir=",#b1,13,10) 'added to monitor random changes
pause 1000
loop

interrupt:
bit2 = pinC.2: bit1 = pinC.1 

getBits = getBits & %000000110
if getBits <> 0 then 
dir = bit2 * 2 'direction: if bit2=low then dir=0; if bit2=high then dir=2
counter = counter - 1 + dir 
do while getBits <> 0 

getBits = pinsC & %000000110

loop
endif
setint %00000010,%00000010 ,C
return
e
 

hippy

Ex-Staff (retired)
The code in post #118 works for me and, as it does for eclectic, the conclusion must be that it's a fault with your hardware or wiring.
 
Top