Author Topic: what does this line of code do?  (Read 4421 times)

0 Members and 1 Guest are viewing this topic.

Offline amateur_25Topic starter

  • Regular Contributor
  • *
  • Posts: 106
what does this line of code do?
« on: April 15, 2014, 12:20:26 am »
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: [Select]
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 state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( 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?
 

Offline wilheldp

  • Regular Contributor
  • *
  • Posts: 223
  • Country: us
Re: what does this line of code do?
« Reply #1 on: April 15, 2014, 12:28:11 am »
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. 
 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 2082
Re: what does this line of code do?
« Reply #2 on: April 15, 2014, 12:39:06 am »
Quote
I have a feeling it's this   "old_AB |= ( ENC_PORT & 0x03 );  //add current state" line I need to change. What does it do?
It 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;

 

Offline Mr Smiley

  • Frequent Contributor
  • **
  • Posts: 324
  • Country: gb
Re: what does this line of code do?
« Reply #3 on: April 15, 2014, 02:19:34 am »
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.

So

old_AB |= ( ENC_PORT & 0x03)

is actually

old_AB = old_AB | ( ENC_PORT & 0x03)

 :)
There is enough on this planet to sustain mans needs. There will never be enough on this planet to sustain mans greed.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: what does this line of code do?
« Reply #4 on: April 15, 2014, 02:38:25 am »
I believe he meant adding as in appending, due to the shift left two bit above.

Code: [Select]
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 state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( 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.
 


 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: what does this line of code do?
« Reply #5 on: April 15, 2014, 05:31:26 am »
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.
« Last Edit: April 15, 2014, 05:34:06 am by Bored@Work »
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline amateur_25Topic starter

  • Regular Contributor
  • *
  • Posts: 106
Re: what does this line of code do?
« Reply #6 on: April 15, 2014, 08:40:19 am »
I believe he meant adding as in appending, due to the shift left two bit above.

Code: [Select]
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 state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( 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.


Hi 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?
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4694
  • Country: au
  • Question Everything... Except This Statement
Re: what does this line of code do?
« Reply #7 on: April 15, 2014, 08:58:26 am »
each physical port (Array of pins) is addressed, with the first pin being 0, e.g. 00000000b
so 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,
 

Offline amateur_25Topic starter

  • Regular Contributor
  • *
  • Posts: 106
Re: what does this line of code do?
« Reply #8 on: April 15, 2014, 09:29:50 am »
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?
« Last Edit: April 15, 2014, 10:44:00 am by amateur_25 »
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4694
  • Country: au
  • Question Everything... Except This Statement
Re: what does this line of code do?
« Reply #9 on: April 15, 2014, 09:43:47 am »
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 content

people 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)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf