Author Topic: A/D data polarity reversed?  (Read 840 times)

0 Members and 1 Guest are viewing this topic.

Offline CirclotronTopic starter

  • Super Contributor
  • ***
  • Posts: 3170
  • Country: au
A/D data polarity reversed?
« on: June 25, 2022, 12:49:05 pm »
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?
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8114
  • Country: fi
Re: A/D data polarity reversed?
« Reply #1 on: June 25, 2022, 01:18:30 pm »
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: [Select]
#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;
}
 
The following users thanked this post: Nominal Animal

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6191
  • Country: fi
    • My home page and email address
Re: A/D data polarity reversed?
« Reply #2 on: June 25, 2022, 07:58:48 pm »
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?
Your 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 you convert the 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 supports uintN_t and intN_t types 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;
where read_uint8_t_sample() returns an int, unsigned int, or uint8_t (but not int8_t), and 128 is the nearest power of two (28-1=27=128) to your bias.

Note that since int8_t range is from -128 to 127, inclusive, you can write the subtraction as + (-128) in other languages.  In C, it does not matter, because of integer promotions: whenever a logical or arithmetic operation is applied, all types smaller than int are converted to int (or to unsigned int, if int cannot describe all possible values but unsigned int can), 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.
« Last Edit: June 25, 2022, 08:06:44 pm by Nominal Animal »
 

Offline Benta

  • Super Contributor
  • ***
  • Posts: 5849
  • Country: de
Re: A/D data polarity reversed?
« Reply #3 on: June 25, 2022, 08:00:07 pm »
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)
« Last Edit: June 25, 2022, 08:37:11 pm by Benta »
 

Offline TimFox

  • Super Contributor
  • ***
  • Posts: 7935
  • Country: us
  • Retired, now restoring antique test equipment
Re: A/D data polarity reversed?
« Reply #4 on: June 25, 2022, 08:20:21 pm »
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.
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8114
  • Country: fi
Re: A/D data polarity reversed?
« Reply #5 on: June 26, 2022, 07:56:35 am »
Subtracting the bias is logically the correct 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 would calibrate out 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.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3694
  • Country: us
Re: A/D data polarity reversed?
« Reply #6 on: June 27, 2022, 03:00:19 am »
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.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf