what does this line of code do? - Page 1
Forum section: electronics / beginners

author: amateur_25
author_rank: Regular Contributor
timestamp: April 15, 2014, 12:20:26 am
content: Hi I borrowed this code from circuits@home. He did a post on reading encoders as gray code. HOwever it seems to only work on A0 A1 pins. Due board layout issues I want it to work on A1 and A2 instead.Code:int8_t read_encoder(){static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};static uint8_t old_AB = 0;/**/old_AB <<= 2; //remember previous stateold_AB |= ( ENC_PORT & 0x03 ); //add current statereturn ( enc_states[( old_AB & 0x0f )]);}I have a feeling it's this "old_AB |= ( ENC_PORT & 0x03 ); //add current state" line I need to change. What does it do?

author: wilheldp
author_rank: Regular Contributor
timestamp: April 15, 2014, 12:28:11 am
content: I'm pretty sure all you need to do is change the ENC_PORT declaration in the setup void in order to change the pin assignment.

author: Andy Watson
author_rank: Super Contributor
timestamp: April 15, 2014, 12:39:06 am
content: QuoteIt adds the present two bits from the port to the previous two bits (which have already been shifted to the higher position) to make a 4 bit index into the "enc_states" table. Try:old_AB |= (ENC_PORT & 0x06) >> 1;

author: Mr Smiley
author_rank: Frequent Contributor
timestamp: April 15, 2014, 02:19:34 am
content: It's not adding, it's inclusive ORing the new reading with the last reading which is also being anded with 0x03 to clear all but the lower two bits. And then replacing the old_AB with the result.Soold_AB |= ( ENC_PORT & 0x03)is actuallyold_AB = old_AB | ( ENC_PORT & 0x03)

author: miguelvp
author_rank: Super Contributor
timestamp: April 15, 2014, 02:38:25 am
content: I believe he meant adding as in appending, due to the shift left two bit above.Code:int8_t read_encoder(){static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};static uint8_t old_AB = 0;/**/old_AB <<= 2; //remember previous stateold_AB |= ( ENC_PORT & 0x03 ); //add current statereturn ( enc_states[( old_AB & 0x0f )]);}So you start with 0, then it shifts two bits to the left from the previous read, then appends (adds) A0 & A1 into it.So Andy is right but I would put a couple more parenthesis just in case:old_AB |= ((ENC_PORT & 0x06) >> 1); // This will read A1 & A2 and move them one bit right so old_AB will end up with the needed index to enc_states.

author: Bored@Work
author_rank: Super Contributor
timestamp: April 15, 2014, 05:31:26 am
content: Since no one mentioned it until now, the code that is decoded there is reversed Gray Code. Because that source code translates a step up into -1 and a step down into 1. Either the encoder pins are switched or it is a counter clockwise encoder.

author: amateur_25
author_rank: Regular Contributor
timestamp: April 15, 2014, 08:40:19 am
content: Quote from: miguelvp on April 15, 2014, 02:38:25 amHi miguelvp,Sorry could you explain how 0x06 represents A1 and A2? I dont do much bit twiddling.I'm a beginner that just uses the Arduino API and ignores low level bit twiddling gives me a head ache.Perhaps you can recommend a tutorial?

author: Rerouter
author_rank: Super Contributor
timestamp: April 15, 2014, 08:58:26 am
content: each physical port (Array of pins) is addressed, with the first pin being 0, e.g. 00000000bso pins 1 and 2 would be 00000011b (b being the binary designator for the software) which when you convert binary to decimal equals 3, shift it across by 1 and you get 00000110b which equals 6 (2 and 4) thus the 6,

author: amateur_25
author_rank: Regular Contributor
timestamp: April 15, 2014, 09:29:50 am
content: ah ok.I have to say I don't like math or numbers. Ok if my little brain has understood 00011000b for A3 and A4. That works out to be 0x18 in hex I have two encoders. IT's a volume controller so I have one for bass and one for volume.Just out of curiosity is this how Microchip PIC micros and all the other more professional micros ( ti msp430) work?

author: Rerouter
author_rank: Super Contributor
timestamp: April 15, 2014, 09:43:47 am
content: yes, or at-least in very similar ways, you generally have set of bits as big as the architecture (ATmega328 is an "8 bit" microcontroller) which controls some part of the device, e.g. which pin is which (addressing) or configuring (if its an output or input) and various other features that the datasheet goes into in detail (they are long for a reason)howerver with most of these devices there is already a description file made for your favorite editor, which tells the compiler (arduino ide in your case) how many bits these registers are, and lists all the fancy names (e.g. PORTA) so you only need to describe how you want them set up, if you ever glance PIC code you will see weird register names your not familiar with, but they are just there configuration registers by a different name, if you know what each bit does then you can use it to your hearts contentpeople even in arduino ide use these registers as it can be a large amount faster than digital write for example, setting the state of 8 pins in 1 clock cycle, as opposed to running the digital write bit of code 8 times, (digitalwrite does error checking that takes time, but if your only using it as an input or output at once, it generally doesn't matter)