I am trying to get negative ADC value by giving -2.5 v to AD/DA high precision expansion board with Raspberry Pi 4. I am using python programming with twos complement of buffer size 200, unfortunately, I am not getting negative ADC value properly. as per condition if I had applied -2.5v I will get values @ -2.53456 form but I am getting around -0.5465 which is not correct.

Anybody help me to find a negative value. if someone did work on the negative value before or now doing.

Thanks in advance

  • 1
    No evidence that this question has anything to do with the Pi.
    – joan
    Feb 25, 2020 at 14:35
  • Ah, I guess you are using ADS1250. The offset setting is a bit tricky. You need to read the datasheet very carefully not to go wrong. References: (1) raspberrypi.stackexchange.com/questions/99353/separate-spi-data, (2) raspberrypi.stackexchange.com/questions/95843/….
    – tlfong01
    Feb 25, 2020 at 14:35
  • 1
    i am using ADS1256. could you know how to get negative value. any sample program do you have in python or c Feb 25, 2020 at 15:31
  • Ref 1 describes ADS1256 board, wiring, python SPI set up functions. You can follow up and describe your spec, init, setup, config, convert, read, and print results functions. If you have a spec, perhaps somebody might help writing the complete program for you. If you has a program spec and your already written, documented, but buggy program listing, perhaps somebody can debug the program for you. PS - Ref 2 points out it is important to set the "Vrefp" and "Vrefn", "PGA". If you don't set them correctly, you result won't offset and scale correctly.
    – tlfong01
    Feb 26, 2020 at 6:33
  • 1
    Thanks for your help. please find attach link. I marked it in red where i did twos complement and reading data. penzu.com/p/f38ec540. Feb 26, 2020 at 9:21

2 Answers 2


I think the easiest way is to put the signal through a resistor divider attached to 5V (or whatever your ADC reference is): a 2x divider will let you measure voltages from +5V to -5V:


simulate this circuit – Schematic created using CircuitLab

The conversion to real voltage is linear: 0V measured by the ADC corresponds to -5V on the signal wire, 5V measurement corresponds to 5V signal value and 2.5V measurement corresponds to 0V signal value. In terms of software, that's V_real = 2*V_meas - 5*K_1Volt, where K_1Volt is the numeric value corresponding to 1V.

Obviously, your measurement resolution w.r.t the real signal value will be twice as bad, and your signal source should support a 20kOhm load for this to work properly.

  • I think your simple resistor voltage divider works. To overcome the low input impedance problem, we can use an OP Amp as a digital buffer. Or we can use a dual+-5V power supply op amp and shift up input signal by 2.5V. Just brainstorming.
    – tlfong01
    Feb 27, 2020 at 8:56
  • 1
    Ok Thanks @Dmitry Grigoryev,tlfong01 : I am doing simple register voltage divider i got now posItive measured value but how i program the formula V_real = 2*V_meas - 5*K_1Volt, in python. I gave the link of ADS 1256 file could you let me know .its library where i did twos complement .it mark in red.penzu.com/p/f38ec540. Feb 27, 2020 at 13:04
  • 1
    Thanks all for your suggestion. currently i am using two register voltage divider method but i am not getting properly output. The problem is that the ADS has a small input capacity and together with the resistors i build an RC time constant that causes the delay in its falling edge. If i decrease the value of the resistors, i can solve this problem, but then the current becomes too large, so that i have too many losses in the resistors of the voltage sources.One solution is to use an operational amplifier. I want to know which IC i can use for summing non inverting amplifier. Mar 4, 2020 at 11:22
  • 1
    @Amritpalsinghsodhi Try adding small capacitors (20 pF?) in parallel with resistors. The amplifiers also have input capacitance, so you'll have a similar problem if you use one. If you really need fast measurements, get an ADC which can cover your entire voltage range. Mar 4, 2020 at 11:37
  • 1
    @Dmitry Grigoryev, I tired by adding capacitor in parallel with resistors but it did not improve signal, same delay in its falling edge. Mar 4, 2020 at 17:40



Let us first check out the ADS1256' "Read 2's compliment results and convert to signed decimal" function.

Update 2020mar02hkt1905

If you have tested you 2's complement to signed decimal converter OK, you can then define the converter as a function, as shown in my ADXL345 demo program, to be used later. This converter function should not be defined in you ASD1256 class, and of course should not be merged with the convert analog to digital function, making debugging difficult.

Now let me suggest how to start testing your ADS1256 class. I found that you just defined the class, but have not shown how to instantiate an ADS1256 object and do the conversion, print the results etc. I usually suggest to do the "ping" thing, ie, read the device ID. In my ADXL345 demo program, you can see that my ping function is to read the device id "0xe5", I have other ping functions for other devices.

I found that your ADS1256 class has a similar ping or read device ID function, as listed below.

def ADS1256_ReadChipID(self):
    id = self.ADS1256_Read_data(REG_E['REG_STATUS'])
    id = id[0] >> 4
    # print 'ID',id
    return id

So my suggestion to start debugging is to do the following:

Write a very simple program to read device ID.

It is only when you have successfully

(1) read the device ID, then you can do

(2) the AD conversion, and

(3) convert to signed decimal and (4) print results.

My ADXL345 demo program is a plug and play self contained program without need of other libraries. If you have ADXL345, then you just run my demo program to get the results.

Then you can translate my program for your ADS1256. There is of course the read negative value, and scaling offset problem not yet solved.

Now I would suggest to solve the problem is two steps,

(a) read a standard positive value, say +2.00V, to make sure your scaling and gain is correctly set.,

(b) then set scaling and gain for negative -2.00V.

If your step (a) is debugged, then you are almost there. You can do trials and errors to do setting for negative values.

If you can show me the program listing and sample results like my ADXL345 demo program, I am happy to follow up and make more suggestions or other thing, like how to reduce noises etc.


(1) ADS1256 24-bit Analog to Digital Converter Datasheet - TI


Appendix A - ADS1256 Read three byte long 2's compliment results and convert to signed decimal

ads1256 results

Appendix B - ADXL345 Read three two-byte-long 2's compliment results and convert them to signed decimal

Troubleshooting Tips - Insert break points, fake values, and debugging print statements statements in the pink and green sections.

adxl345 1

Appendix C - ADS1256 Class

Comment: The class summarized below seems not flexible enough toe test the ADS1256 ADC device. It would be nice to include a sample instantiation and methods used to change the parameters such as gain, data rate (or one shot) with sample outputs, to clarify how a couple of tests have been made.

ads1256 class

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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