A/D data polarity reversed? - Page 1
Forum section: electronics / projects

author: Circlotron
author_rank: Super Contributor
timestamp: June 25, 2022, 12:49:05 pm
content: Say we have an 8-bit A/D and we bias the input to half rail and capacitively couple the ground referenced input signal. The signed digital output with no signal is theoretically either 01111111 or 10000000.When the input signal swings positive the signed digital value is a negative number and negative signal gives a positive number. Does that make any sense at all?

author: Siwastaja
author_rank: Super Contributor
timestamp: June 25, 2022, 01:18:30 pm
content: Capacitive coupling and biasing does not invert the polarity.Signed (two's complement) integers grow monotonically (in the same direction) as a function of unsigned representation, only wrapping happens at a different spot.Unsigned representation of Vref/2 is indeed roughly 0111 1111 or 1000 0000. If you interpret this as signed value, then it will be exactly at wrapping site, between 127 and -128. This is of course inconvenient. But if you bias the unsigned number, for example by adding 128, then you can again interpret in (2's complement) signed and get the zero in the middle of Vref. This +numerical_range/2 operation nicely describes the electrical biasing by Vref/2. 2's complement system is the most intuitive and logical way of describing both negative and positive integers.C demonstration:Code:#include <stdio.h>#include <stdint.h>int main(){union u{uint8_t u8;int8_t i8;};union u v = {.u8=0};for(int i=0; i<256; i++){union u biased = {.u8 = v.u8 + 128};printf("%4u %4d %4d\n", v.u8, v.i8, biased.i8);v.u8++;}return 0;}

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 25, 2022, 07:58:48 pm
content: Quote from: Circlotron on June 25, 2022, 12:49:05 pmYour A/D yields unsigned 8-bit integer samples, but you're interpreting them as signed (two's complement) 8-bit integers.The two most common options is to either treat the samples as unsigned integers, or compensate for the two's complement.If you treat the samples as unsigned integers, zero input will correspond to sample 127 or 128, maximally negative input to sample 0, and maximally positive input to sample 127.If youconvertthe samples to signed integers by subtracting the bias, zero input will correspond to sample 0, maximally negative input to sample -128, and maximally positive input to 127.If your hardware uses two's complement form – basically all that support C; and if it supportsuintN_tandintN_ttypes in C, it definitely does so for these types –, you can compensate by unconditionally flipping the highest bit. I.e,int8_t sample = read_uint8_t_sample() - 128;whereread_uint8_t_sample()returns anint,unsigned int, oruint8_t(but notint8_t), and128is the nearest power of two (28-1=27=128) to your bias.Note that sinceint8_trange is from -128 to 127, inclusive, you can write the subtraction as+ (-128)in other languages. In C, it does not matter, because ofinteger promotions: whenever a logical or arithmetic operation is applied, all types smaller thanintare converted toint(or tounsigned int, ifintcannot describe all possible values butunsigned intcan), and so on.However, because the value affected is just the most significant bit – it's state will be flipped! –, any of the following will yield the exact same effect:int8_t sample = read_uint8_t_sample() + 128;int8_t sample = read_uint8_t_sample() - 128;int8_t sample = read_uint8_t_sample() ^ 128;int8_t sample = read_uint8_t_sample() ^ (-128);int8_t sample = (int8_t)read_uint8_t_sample() + (int8_t)-128;int8_t sample = (int8_t)read_uint8_t_sample() - (int8_t)-128;int8_t sample = (int8_t)read_uint8_t_sample() ^ 128;int8_t sample = (int8_t)read_uint8_t_sample() ^ (int8_t)(-128);Of these, only the exclusive-OR (^) ones do not rely on wraparound (modulo) arithmetic.Since C only specifies for unsigned integer types, the exclusive-OR one is the "best" option: least surprise and possibility of implementation differences.That's the real reason some use the exclusive-OR; it is not about "speed" or efficiency at all, just a portability/C technicality thing.

author: Benta
author_rank: Super Contributor
timestamp: June 25, 2022, 08:00:07 pm
content: This is basic knowledge.When you want a signed output from an A/D, you need to invert the MSB to get a 2's complement representation (which is the signed number you're looking for)

author: TimFox
author_rank: Super Contributor
timestamp: June 25, 2022, 08:20:21 pm
content: I have not worked directly with SAR ADCs in maybe 30 years, but I remember they often had two outputs for the MSB, one inverted, which the user could choose.

author: Siwastaja
author_rank: Super Contributor
timestamp: June 26, 2022, 07:56:35 am
content: Subtracting the bias is logicallythecorrect thing to do, flipping MSbit is just a corner case which is equivalent exactly and only when bias = range/2.But bias can be realistically anything. I have used some weird bias like 1/4 of the range sometimes, for example a forced CCM switch mode converter where inductor current can go slightly negative, but having highest possible resolution is advantageous so let's measure between -10A ... + 30A then.Also consider this: usually you wouldcalibrateout bias error, which is a subtraction. You can do it in one step. If you first subtract range/2 bias by flipping a bit, and then subtract calibration bias, the former step becomes unnecessary.

author: ejeffrey
author_rank: Super Contributor
timestamp: June 27, 2022, 03:00:19 am
content: Flipping the MSB is also only correct if the converter resolution matches the word size. What you actually need to do is flip the MSB and sign extend it. By instead just subtracting off the bias it will just work correctly.