0

Explanatory comment: I'm a beginner. I'm examining the feasibly of bit shifting to the right 6 places to divide up the range of the Arduino ADC (has a range of 0 to 1023) to something much smaller. Such that any number in the ADC registers, between 0 and 63 produces a value of 0, a number between 64 and 127 a 1, between 128 and 191 a 2, between 192 and 255 a 3, etc. There is a change every 64 increase in the initial number.

I think this is possible to do. But some doubt has been expressed I think.

As far as I have determined, after right shifting 6 places to the right the following values of numbers are resident in the ADC registers: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15.

I wish you to consider, is there anything in the way Arduino's IDE works, or with the nature of the initial number in the register (signed/unsigned) that makes the results I have indicated false. I think, that the initial number will be unsigned, just guessing.

1
  • 3
    analogRead(pin_number) >> 6 will give you wat you want, as a signed integer in the range 0 – 15. Dec 19 '17 at 12:23
1

There are two types of right-shift in C - logical and arithmetic.

GCC (which is the compiler the Arduino IDE uses) selects which one to use depending on whether the type you are shifting is signed or not:

  • If it's signed then use an arithmetic shift
  • If it's unsigned then use a logical shift

In a logical shift, the value is literally shifted to the right padding the left side with zeros. An arithmetic shift, however, shifts and extends the sign. I.e., it performs an arithmetical "divide by 2". That means if you right shift a negative value to still have a negative value (Note: this behaviour is implementation specific, so is only applicable to GCC. For other compilers in other situations you will have to check the documentation of that compiler).

So if you store the results of analogRead() in an unsigned integer variable >> N will right shift the value N times. If you store it in a signed integer it will divide the value by 2 N times.

For a positive value, which the results of analogRead() will be, the end result is the same - divide by 2 N times.

So if you right-shift 6 times you reduce a 10-bit value down to (10-6) 4 bits. 24 is 16, so you get 16 possible values. 24-1 is 15, so you get values 0-15 in your final value.

2
  • 2
    Why should it make a difference in terms of efficiency? On the AVR at least, both lsr (logical shift right) and asr (arithmetic shift right) are one-cycle instructions. Dec 19 '17 at 13:05
  • I was not aware of asr.
    – Majenko
    Dec 19 '17 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.