Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Micromite Feature Request Rotary Encoder
Page 1 of 2 | |||||
Author | Message | ||||
atmega8 Guru Joined: 19/11/2013 Location: GermanyPosts: 722 |
Hello, first again 1000 thanks to Geoff and everyone who helps. Micromite is nearly perfect but what i really miss is the support for rotary encorders. They are so helpfull and elegant for input tasks, making menues an so on. Also they are cheap an for everyone available. I think ( Hope) the support off this devices will use a small amount of memory. In germany there is a very popular microcontroller Forum, and there are many guy's with lots of knowledge arround. One of them is Peter Dannegger, who also made some encoder routines which work bullet proof. Here IS a link to the german forum, where Peter provides some stable c code whith english comments. I think it is really easy, for people like Geoff, to translate this to the PIC controllers. What do you think? http://www.mikrocontroller.net/articles/Drehgeber DS |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9308 |
Depending on what is involved in talking to one of these things, could you not write a sub or function to talk to it from within MMBasic? Not sure I understand the complexities of rotary encoders though - can you link me to some examples, so I can study how they work? Smoke makes things work. When the smoke gets out, it stops! |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
They are a pretty simple device to drive. They consist of two switches and use a simple 2 bit code table. There should be plenty of info on the net on the workings of. Essentially, they give a rotating code sequence that indicates whether the sequence is going forward or backward. I could send you some MCU code, but it is all in PIC 8 bit assembly. If anyone is interested, I have a i2c driven RE module. David M. |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
I think the difficulty is not programming it in C but to make those values available in MMBasic and within the space available. How would you like to use it from basic? In a loop and then querying the current value? In that case, what are the minimum, maximum and start values, etc... Get an interrupt with each step? That would be my favorite, an interrupt for each up and down step. Any other ways of using it from basic? Microblocks. Build with logic. |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
Here is some data I dug up years ago rotary encoder This is the second go at trying to post. The net is so slow tonight that I could crawl faster. @TZA - interrupt is the safer way. If the encoder is included in a dedicated firmware loop, then you can pretty well get away with testing for bit pattern and sequence. Usually set up a counter variable and increment/decrement it. David M. |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3196 |
Sounds like a good idea. I will investigate. Geoff Graham - http://geoffg.net |
||||
atmega8 Guru Joined: 19/11/2013 Location: GermanyPosts: 722 |
@ Grogster: google IS also your friend;-)... To all: The most reliable method is not interrupt driven. It is based on cyclic checking the encoder state, where the cycle time something about 10 ms. In The Main routine you can then Check a variable if it incrased or decreased and based on this the encoder could be read. Some encoders also differ in the mechanical construction, but this can be mastered in the code. The cycle time should be adjustabel to get reliable readings ( System variable?). The encoders have also a push button, could be used like an " enter" function. The Code from Peter dannegger to wich i linked Works very well an stable to all encoders i have tested ( Panasonic, Albs, etc.) It is c code for Atmegas, but i think Geoff will convert it in minutes ;-)... Picaxe, Arduino, bascom, Luna AVR, all support rotary encoders. Mmbasic should also support ;-). Geoff will make it work;-) |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Well, i would put the A on an interrupt enabled pin, and on every interrupt i would read the state of B. The B will tell the direction (Up or Down). Update a variable accordingly. This will not use a timer (Peter Dannegger's code does), so that the timer can be used for other purposes like setticks ,PWM and Servos. Microblocks. Build with logic. |
||||
atmega8 Guru Joined: 19/11/2013 Location: GermanyPosts: 722 |
Is this " speaking knowledge" or do you have deeper experience with encoders? You should test it yourself. Looking forward what you will tell then;-) |
||||
robert.rozee Guru Joined: 31/12/2012 Location: New ZealandPosts: 2350 |
the code to run a rotary encoder is pretty simple. as noted, it has a 2-bit output. one merely needs to keep track of the previous state, and for each of the possible states (after a state change): one previous state indicates anti-clockwise rotation, another indicates clockwise rotation, and the third is an invalid combination. the following bit of code should more-or-less do the trick: encoder = 0 last = 0 SETPIN 2, INTB, rotary SETPIN 3, INTB, rotary ... :rotary next = (PIN(2) * 2) + PIN 3 IF ((last+next) AND 1) = 1 THEN ' two-step change is an error IF ((next-last)=1) OR ((last-next)=3) THEN encoder = encoder + 1 IF ((last-next)=1) OR ((next-last)=3) THEN encoder = encoder - 1 ENDIF last = next IRETURN would have been much cleaner to write if MMbasic had a MOD function! rob :-) |
||||
atmega8 Guru Joined: 19/11/2013 Location: GermanyPosts: 722 |
Robert, this code will work in theory and not with all type of encoders. There is no debounce and if you rotate to fast or to slow it will loose counts. If the encoder contacts are not in neutral Position it will bounce like hell. There are lots of encoders ( Panasonic for example) where in " neutral" positionthe contacts are connected. This must be eleminated via software. Encoders/Software which counts don't follow the "haptic" are disappointing and you like to throw it in The Basket....;-), try it, test it... |
||||
MicroBlocks Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
It is knowledge from the 'old days' where i had to keep track of position on servo motors. Without interrupts it is impossible, and even with interrupts it had its limits. For slower and hand operated encoders you also do not need to process all 4 steps of the Gray encoding. [code] _____ _____ _____ A | | | | | | ______| |_____| |_____| |__ 1 2 3 4 1 2 3 4 1 2 3 4 _____ _____ _____ B | | | | | | ____| |_____| |_____| |_____ [/code] There are four distinct times, each is a change of a logic level on either line A or B. Lets imagine you are turning the encoder clockwise. You then go from left to right through the steps 1-2-3-4-1-2-3-4 etc. The A line goes from '0' to '1' on step 2. If you sample the B line at moment '2' you see that it is always '1' Now imagine going the other way, turning counter clockwise or going from right to left. The steps are now 4-3-2-1-4-3-2-1 etc. The A line goes from '0' to '1' on step 4. If you sample the B line at moment '4' you see that it is always '0' So, what you do is setup a low to high interrupt on the pin connected to A. And depending on the value on the pin connected to B you increase or decrease the value. I do not have a uMite available at the moment so this is without testing [code] RotaryValue = 0 SETPIN 2, INTH, RotaryInterrupt ... 'do other usefull stuff ... SUB RotaryInterrupt IF PIN(3) = 1 then RotaryValue = RotaryValue + 1 ELSE RotaryValue = RotaryValue - 1 ENDIF ' Even shorter but is only faster when done in C ' RotaryValue += (ReadPin(3)<<1) - 1; END SUB [/code] For this to work you need to debounce a mechanical rotary encoder, a small cap will be sufficient. You can also do it in software by measuring the time between interrupts. If it is shorter then a certain amount then ignore the interrupt. I prefer the small cap. Microblocks. Build with logic. |
||||
robert.rozee Guru Joined: 31/12/2012 Location: New ZealandPosts: 2350 |
"not in neutral Position": not quite sure what you mean there. in the past this has worked passably with 3-wire encoders. the line "IF ((last+next) AND 1) = 1 THEN..." filters out the 50% of possible states that are invalid, while the occasional back-stepping error will likely have little impact in real-world situations. one can add small caps to the input pins if desperately worried about this, but in applications where one might have a volume control (for example) with 30 or so steps the occasional glitch in a single step is unimportant. |
||||
CircuitGizmos Guru Joined: 08/09/2011 Location: United StatesPosts: 1425 |
I would guess that the implementation would be good for rotary encoders turned by human. Will it be fast enough for motor position feedback? (Not insanely high RPM, but faster than volume control knobs.) Micromites and Maximites! - Beginning Maximite |
||||
robert.rozee Guru Joined: 31/12/2012 Location: New ZealandPosts: 2350 |
given no upper speed limit, no software solution could be guaranteed to be fast enough. if dealing with a fast-turning shaft, a better approach would perhaps be to count complete revolutions, sensing the direction off whatever is driving it round. or count pulses away from an end-stop if the direction if fixed. or having the shaft drive a linear measurement device (ie, if moving the head of a lathe). or monitor the drive into the stepper motor rotating the shaft (if that is how it is driven). but then, what non-specialist applications exist that require this? the rotary encoders the average hobbyist deal with are attached to a human-driven knob. |
||||
jwettroth Regular Member Joined: 02/08/2011 Location: United StatesPosts: 71 |
I have a lot of experience with these little buggers. I designed the Digital Readout for the Sherline Mill and Lathe DRO that has sold a bunch over about 15 years. It was originally designed to be used by hand but wss robust enough to keep up with CNC setups with no changes. It is coded in assembly on a 12 MHz (1 mips) 8051 and simultaneously keeps track of three encoders, continuously displays them and corrects for backlash and never drops a count. It also reads out spindle speed simultaneously. The best way to implement this code is to have a fast timer tick (.1 ms), do a debounce pass and a then a state transtion pass to inc and dec counts. Keep the tick irq very fast and bail out quickly if nothng intersting is going on, set a flag on changes- That's it. If you look at a fast rotation speed for a CNC- perhaps a 60" per minute rapid, with a 10 turn per inch thread-, this is only 600 RPM or 10 rev/sec. With an encoder with 100 states per turn, this is about 1000 edges on the AB inputs. You'd have to go a minimum of twice this fast without debounce. 100 uS is 10x this fast. Another point- Fancy/Fast debounce and very fast inputs are generally mutually exclusive. Fast inputs will usually use optical type encoders that don't bounce. The little mechanical encoders only have about 32 ticks/revoluion and are very forgiving on debounce. I agree that it would be a nice background function to have on Micromite if Geoff can squeeze it in.. There are a lot of people that want to make DRO's if nothing else. John Wettroth |
||||
CircuitGizmos Guru Joined: 08/09/2011 Location: United StatesPosts: 1425 |
Robotics. Micromites and Maximites! - Beginning Maximite |
||||
atmega8 Guru Joined: 19/11/2013 Location: GermanyPosts: 722 |
I also think that the main use case is a human-driven encoder as an input device for menues, setting values for variables and so on. Give it a chance Geoff;-) |
||||
mbramwel Regular Member Joined: 10/07/2013 Location: CanadaPosts: 42 |
Do your encoders use natural binary or graycode binary? With 2-bits, natural binary gives us the following sequence: 00,01,10,11 With gray codes, only 1-bit changes from state to state giving us: 00,01,11,10 With gray codes, you can wrap the code around 10 becomes 00 whereas natural binary has both bits changing from time to time. With gray codes, if the current read differs more than 1-bit from the previous read, you missed a step or have a bad reading. |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3196 |
It does, it is called the MOD operator! You use it the same as the multiply or divide operators. I was going to implement the function using 1 mSec polling (the fastest that can be conveniently used) and that would restrict it to less than 500 steps/sec as John pointed out. Also, I was not planning to implement contact debounce as a bounce translates into one step back plus one step forward (ie, neutral). BUT Rob's code written in MMBasic is so elegant and simple that I am now wondering if I should bother adding this to the language in the first place. I don't have much practical experience with these devices so all comments will help. Geoff Geoff Graham - http://geoffg.net |
||||
Page 1 of 2 |
Print this page |