jholov
Posts: 7
Joined: Fri Jul 15, 2016 1:13 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Fri Jul 15, 2016 1:25 pm

Hi,

I recently purchased the same board and I currently want to use it for ad conversion for a thermistor. However I am having problems running the ads1256 test code. Every time I try to run it I get a warning: null characters ignored. Then when I actually try the next step ./program i get this message saying bcm2835_init: Unable to open /dev/gpiomem: No such file or directory.
I think this problem could be due to the fact that whenever I run this command echo “device_tree=bcm2709-rpi-2-b.dtb” >> /boot/config.txt I get a permision denied warning. I have tried running sudo before but that doesn't help. Also I have already installed wiringPi and bcm2835-1.50 any help would be greatly appreciated.

Thanks

jholov
Posts: 7
Joined: Fri Jul 15, 2016 1:13 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Fri Jul 15, 2016 2:09 pm

I actually found what I needed manual. Program works good now

novitsky
Posts: 25
Joined: Sun Oct 06, 2013 12:22 pm
Contact: Website

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Fri Jul 15, 2016 2:17 pm

Try adding "sudo" in front of the device-tree command.
Raspberry PI 2B, Raspbian Jessie RT patched.

SherlockHao
Posts: 6
Joined: Thu Jun 02, 2016 2:04 am

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Tue Jul 26, 2016 11:32 pm

Thanks to Hateful7 and Ran,

I solved this problem. Just as Hateful7 said the version of BCM library should be bcm2835-1.45. But I meet another problem with the sampling rate. I change the sampling rate to 30k sps, and using bcm2835_spi_transfer() from bcm2835.c to read the data. But the sampling rate is just around 2k. Anyone has the similar issue?

novitsky
Posts: 25
Joined: Sun Oct 06, 2013 12:22 pm
Contact: Website

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Wed Jul 27, 2016 12:18 am

I use BCM2835-1.50. That should not be the problem. You might need to direct to the propert device tree file.
On RPI 2B:

Code: Select all

sudo echo "device_tree=bcm2709-rpi-2-b.dtb" >> /boot/config.txt
Onr RPI 3B:

Code: Select all

sudo echo "device_tree=bcm2710-rpi-3-b.dtb" >> /boot/config.txt
Please note that the sampling rate will change the rate of reading on the ADC, but not the rate of the RPI. You'll have to adjust the RPI reading speed too. I also think the RPI is limited to read at such rates since the SPI protocol is tool slow on the PI and will add delays.
Raspberry PI 2B, Raspbian Jessie RT patched.

tegtmeye
Posts: 1
Joined: Thu Aug 04, 2016 2:52 am

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Thu Aug 04, 2016 3:01 am

Hello all,

I have the same board and have had some success refactoring the sample code into something more sophisticated. One question though, has anyone figured out what the VREF jumper does? It isn't VREF on the ADC as the LM285-2.5 seems to be providing that. Jumpering it back and forth between the 5V and 3.3V doesn't seem to change the 5V full scale range either. Any ideas?

Thanks in advance

novitsky
Posts: 25
Joined: Sun Oct 06, 2013 12:22 pm
Contact: Website

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Thu Aug 04, 2016 1:14 pm

I think its just for selecting power source for the reference. It would still be 2.5v
Raspberry PI 2B, Raspbian Jessie RT patched.

ufo2001
Posts: 4
Joined: Sun Mar 10, 2013 12:07 am

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Wed Oct 19, 2016 11:58 am

Is there any Python code available to get readings from thermocouplers connected to Waveshare High-Precision board?

ads1256 example code works but is it C language and it gives values in a loop.
I need just one value from one pin.

Thanks.

ChristophK
Posts: 15
Joined: Thu Oct 06, 2016 1:34 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Mon Oct 24, 2016 8:06 am

I managed to read the Waveshare AD-DA using Python with pigpio. You need a running pigpio daemon, so "sudo pigpiod".
Here is my code:

Code: Select all

"""
Waveshare AD/DA board, www.waveshare.com/high-precision-ad-da-board.htm
AD-converter ADS1256 (ti.com), first test with on-board trimpot
DA-converter DAC8534 (ti.com), not yet used
"""
import time
import pigpio

pi= pigpio.pi()

# set GPIO data direction          ("pin*" = 40pin only):
# pi.set_mode(0, pigpio.INPUT)     # pin*27 (Raspi-hat ID_SD)
# pi.set_mode(1, pigpio.INPUT)     # pin*28 (Raspi-hat ID_SC) 
# pi.set_mode(2, pigpio.INPUT)     # pin  3 (I2C SDA, fixed 1k8 pull-up)
# pi.set_mode(3, pigpio.INPUT)     # pin  5 (I2C SCL, fixed 1k8 pull-up)
# pi.set_mode(4, pigpio.INPUT)     # pin  7 (free)
# pi.set_mode(5, pigpio.INPUT)     # pin*29 (free)
# pi.set_mode(6, pigpio.INPUT)     # pin*31 (free)
# pi.set_mode(7, pigpio.INPUT)     # pin 26 (main SPI CE1)
# pi.set_mode(8, pigpio.OUTPUT)    # pin 24 AD9952 /CS (main SPI CE0) 
pi.set_mode(9, pigpio.INPUT)       # pin 21 (ADS1256 DOUT)
pi.set_mode(10, pigpio.OUTPUT)     # pin 19 (ADS1256 DIN)
pi.set_mode(11, pigpio.OUTPUT)     # pin 23 (ADS1256 SCLK)
# pi.set_mode(12, pigpio.INPUT)    # pin*32 (free)
# pi.set_mode(13, pigpio.INPUT)    # pin*33 (free)
# pi.set_mode(14, pigpio.OUTPUT)   # pin  8 (Serial TXD)
# pi.set_mode(15, pigpio.INPUT)    # pin 10 (Serial RXD)
# pi.set_mode(16, pigpio.INPUT)    # pin*36 (aux SPI ce2)
pi.set_mode(17, pigpio.INPUT)      # pin 11 ADS1256 /DRDY (aux SPI ce1)
pi.set_mode(18, pigpio.OUTPUT)     # pin 12 ADS1256 /RESET (aux SPI ce0)
# pi.set_mode(19, pigpio.INPUT)    # pin*35 (aux SPI miso)
# pi.set_mode(20, pigpio.INPUT)    # pin*38 (aux SPI mosi)
# pi.set_mode(21, pigpio.INPUT)    # pin*40 (aux SPI sclk)
pi.set_mode(22, pigpio.OUTPUT)     # pin 15 ADS1256 /CS input
pi.set_mode(23, pigpio.OUTPUT)     # pin 16 DAC8532 /CS input
# pi.set_mode(24, pigpio.OUTPUT)   # pin 18 AD9952 Reset)
# pi.set_mode(25, pigpio.OUTPUT)   # pin 22 AD9952 I/O-Update)
# pi.set_mode(26, pigpio.INPUT)    # pin*37 (free)
pi.set_mode(27, pigpio.OUTPUT)     # pin 13 ADS1256 /PDWN input

# set GPIO outputs to start values
pi.write(23, 1)    # DAC8532 /CS deselected
pi.write(22, 1)    # ADS1256 /CS deselected
pi.write(11, 0)    # ADS1256 SCLK low (later overridden by spi_open)
pi.write(10, 0)    # ADS1256 DIN  low (later overridden by spi_open)
pi.write(27, 1)    # ADS1256 /PDWN high
pi.write(18, 1)    # ADS1256 /RESET high
# pi.write(8, 1)     # AD9952  /CS high
# pi.write(24, 0)    # AD9952  RESET low
# pi.write(25, 0)    # AD9952  I/O-Update low

# Delay until DRDY line goes low, allowing for automatic calibration:
#https://raw.githubusercontent.com/heathsd/PyADS1256/master/pyads1256.py
def WaitDRDY():
    start = pi.get_current_tick()
    elapsed = pi.get_current_tick() - start
    # Waits for DRDY to go to zero or TIMEOUT seconds to pass
    drdy_level = pi.read(17) # ADS1256 /DRDY
    while (drdy_level == 1) and (elapsed < 500000):
        elapsed = pi.get_current_tick() - start
        drdy_level = drdy_level = pi.read(17)
    if elapsed >= 800000:
        print("WaitDRDY() Timeout\r\n")

# reset ADC:
pi.write(18, 0)    # ADS1256 /RESET low
time.sleep(0.001)  # wait 1 msec
pi.write(18, 1)    # ADS1256 /RESET high
time.sleep(0.5)    # wait 0.5 sec

# reset DDS:
# pi.write(24, 1)    # AD9952  RESET high
# time.sleep(0.001)  # wait 1 msec
# pi.write(24, 0)    # AD9952  RESET low
# time.sleep(0.5)    # wait 0.5 sec

# open main SPI:
ad_da = pi.spi_open(0, 200000, 0x00000061) # 0x61 = 97
# handle = spi_open(spi_channel, baud, spi_flags)

# spi_flags (22 bit):
# 21 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
#  b  b  b  b  b  b  R  T  n  n  n  n  W  A u2 u1 u0 p2 p1 p0  m  m
#  x  x |x  x  x  x |0  0  x  x |x  x  0  0 |x  1  1  x |x  x  0  1
# set to 0x00000061 = MSB-1st, 4-wire, main-SPI, disable CE0/1, mode1)

# set ADC registers to start values (other registers default values ok):
# spi_write(handle, databytes)

# select ADC:
pi.write(22, 0)    # ADS1256 /CS low
WaitDRDY()

pi.spi_write(ad_da, b'\xfe') # command 0xfe: soft-reset command
time.sleep(0.5)    # wait 0.5 sec

# set register 00 (STATUS) reg.00,one byte,no autocal,no buffer
WaitDRDY()
pi.write(22, 0)    # ADS1256 /CS low
pi.spi_write(ad_da, b'\xfc\x00\x50\x00\x01')
pi.write(22, 1)    # ADS1256 /CS high
time.sleep(0.0001)  # wait 0.1 msec

# set register 02 (ADCON)
WaitDRDY()
pi.write(22, 0)    # ADS1256 /CS low
pi.spi_write(ad_da, b'\xfc\x00\x52\x00\x00') 
pi.write(22, 1)    # ADS1256 /CS high
time.sleep(0.0001)  # wait 0.1 msec

# pi.set register 03 (DRATE) reg.03,one byte,10 samples per secondc
WaitDRDY()
pi.write(22, 0)    # ADS1256 /CS low
pi.spi_write(ad_da, b'\xfc\x00\x53\x00\x23') 
pi.write(22, 1)    # ADS1256 /CS high
time.sleep(0.0001)  # wait 0.1 msec
       
# now read ADC continously, print values on screen:
try:
    while True:
        WaitDRDY()
        pi.write(22, 0)    # ADS1256 /CS low
        # set register01(MUX) reg.01,one byte,AIN0/AINCOM:0x51,0x00,0x08
        # send commands 0xfc:sync ,0x00:wakeup, 0x01:read data      
        # and read one ADC-value (3 bytes):
        (count, databyte) = pi.spi_xfer(ad_da, b'\x51\x00\x08\xfc\x00\x01\x00\x00\x00')
        pi.write(22, 1)    # ADS1256 /CS high
        # discard databyte[0:5]
        # concatenate 3 bytes of databyte[6:8], [6] is MSB:
        data = (databyte[6]<<16 | databyte[7]<<8 | databyte[8])
        print( "Test1", data)

except:
    print( "ctl-C pressed")
    pi.write(22, 1) # ADS1256 /CS high
    print( "/CS ADS1256 high")
    pi.spi_close(ad_da)
    print( "spi closed")
    pi.stop()

When I stop it with "ctrl-c" the daemon sometimes crashes.
killing it and restarting pigpiod helps.

Setting the baudrate to >200kHz reduces the gap between sending "01" and receiving the first databyte to less than the 6.5 µs from the datasheet.

Switch off the hdmi audio output, it disturbs pigpio's clock settings.

fabio.oliveira
Posts: 1
Joined: Fri Feb 17, 2017 1:12 am

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Fri Feb 17, 2017 1:19 am

Hi everyone,

Just to let you know, I'm trying to make a more friendly way to use this ADC, so I've made some Python code for it here:

https://github.com/fabiovix/py-ads1256

It currently does support all the Gain and SPS settings in single-ended mode. I've based on the original C sample code. It still lacks the buffer setting.

I hope it can by useful for you.

AshPowers
Posts: 83
Joined: Thu Apr 20, 2017 12:10 am
Location: Ormond Beach, FL
Contact: Website

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Thu May 04, 2017 1:49 am

Need some help here.

I need to take advantage of a couple of PWM pins on the GPIO header. I see that the GPIO pin 12 is being used as a reset for the ADS1256 so that one is out. I would prefer to use a hardware based PWM and I *think* pin 23 may be used for that? I will be using it to operate a boost control solenoid at only ~10Hz and with 0-100% duty cycle, with changes in that duty cycle only probably needed about every 0.25s at best, so nothing real quick.

It appears that the pigpio interferes with the the pyads1256 so I Cannot use that in combination with pyads1256. . Can you help me figure out how to use the other unused pins as PWM outputs?

AshPowers
Posts: 83
Joined: Thu Apr 20, 2017 12:10 am
Location: Ormond Beach, FL
Contact: Website

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Thu May 04, 2017 3:51 am

The solution to this is just simply using the standard RPi.GPIO module and set it to use one of the other GPIO pins that the ADS1256 AD board is not using. I'm running it on pin 18 and it works flawlessly.

senovr
Posts: 3
Joined: Sat Jun 25, 2016 8:48 am

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Mon May 15, 2017 1:12 pm

Colleagues,
I am using a code from fabio.
It works ok, but I have another issue:
I setting up a sampling rate to 500, but it seems that delta between the datapoints is not constant.
Most of the times it is a bit higher than 0.02 secs ( that is supposed to be in case of 500 Hz)
Any suggestions?

chrisbeuglet
Posts: 3
Joined: Sun Jun 11, 2017 10:13 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Thu Oct 12, 2017 5:34 pm

Fabio's ads1256 is working well for me. Thank you.
Has anyone (Fabio?) done the same for the DAC8532 chip? I'm struggling and everything I have found is in C. I'd like to write something in python to access the 2 digital channels.

iradevic
Posts: 1
Joined: Fri Nov 10, 2017 2:30 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Fri Nov 10, 2017 2:38 pm

Hi to all,

I am facing a problem with ADS1256 library installation.

After I run sudo ./ads1256_test I get an error:

ADS1256_WaitDRDY() Time Out ...
Error, ASD1256 Chip ID = 0x0
ADS1256_WaitDRDY() Time Out

I connected the jumpers as required and SPI is enabled. I am able to run DAC test file without any problems.

I would appreciate any advise from you

Thanks

Isidora

User avatar
legendisback
Posts: 11
Joined: Thu Sep 01, 2016 12:58 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Fri Nov 17, 2017 9:26 am

for those who are still interested in using both AD and DA (not at the same time) here is my code !!!

save this as my_lib.py

Code: Select all

import time
import wiringpi as wp

def debug_print(string):
    if False:
        print("DEBUG: " + string)


class ADS1256:
    """ Wiring Diagram
     +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
     | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
     +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
     |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
     |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5V      |     |     |
     |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
     |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT0 | TxD     | 15  | 14  |
     |     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
     |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 1 | IN   | GPIO. 1 | 1   | 18  |
     |  27 |   2 | GPIO. 2 |   IN | 1 | 13 || 14 |   |      | 0v      |     |     |
     |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
     |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
     |  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |
     |   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
     |  11 |  14 |    SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |
     |     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |
     |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
     |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
     |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
     |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
     |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
     |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
     |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
     +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
     | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
     +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
    """

    # These options can be adjusted to facilitate specific operation of the
    # ADS1256, the defaults are designed to be compatible with the Waveforms
    # High Precision AD/DA board
    SPI_MODE        = 1
    SPI_CHANNEL     = 1
    SPI_FREQUENCY   = 1000000 # The ADS1256 supports 768kHz to 1.92MHz
    DRDY_TIMEOUT    = 0.5 # Seconds to wait for DRDY when communicating
    DATA_TIMEOUT    = 0.00001 # 10uS delay for sending data
    SCLK_FREQUENCY  = 7680000 # default clock rate is 7.68MHz

    # The RPI GPIO to use for chip select and ready polling
    CS_PIN      = 15 
    DRDY_PIN    = 11
    RESET_PIN   = 12
    PDWN_PIN    = 13

    # Register addresses
    REG_STATUS  = 0x00
    REG_MUX     = 0x01
    REG_ADCON   = 0x02
    REG_DRATE   = 0x03
    REG_IO      = 0x04
    REG_OFC0    = 0x05
    REG_OFC1    = 0x06
    REG_OFC2    = 0x07
    REG_FSC0    = 0x08
    REG_FSC1    = 0x09
    REG_FSC2    = 0x0A
    NUM_REG     = 11

    """
    DRATE Register: A/D Data Rate Address 0x03 The 16 valid Data Rate settings are shown below. Make sure to select a
    valid setting as the invalid settings may produce unpredictable results.
    Bits 7-0 DR[7: 0]: Data Rate Setting(1)
        11110000 = 30,000SPS (default)
        11100000 = 15,000SPS
        11010000 = 7,500SPS
        11000000 = 3,750SPS
        10110000 = 2,000SPS
        10100001 = 1,000SPS
        10010010 = 500SPS
        10000010 = 100SPS
        01110010 = 60SPS
        01100011 = 50SPS
        01010011 = 30SPS
        01000011 = 25SPS
        00110011 = 15SPS
        00100011 = 10SPS
        00010011 = 5SPS
        00000011 = 2.5SPS
        (1) for fCLKIN = 7.68MHz. Data rates scale linearly with fCLKIN
    """
    # sample rates
    DRATE_30000     = 0b11110000 # 30,000SPS (default)
    DRATE_15000     = 0b11100000 # 15,000SPS
    DRATE_7500      = 0b11010000 # 7,500SPS
    DRATE_3750      = 0b11000000 # 3,750SPS
    DRATE_2000      = 0b10110000 # 2,000SPS
    DRATE_1000      = 0b10100001 # 1,000SPS
    DRATE_500       = 0b10010010 # 500SPS
    DRATE_100       = 0b10000010 # 100SPS
    DRATE_60        = 0b01110010 # 60SPS
    DRATE_50        = 0b01100011 # 50SPS
    DRATE_30        = 0b01010011 # 30SPS
    DRATE_25        = 0b01000011 # 25SPS
    DRATE_15        = 0b00110011 # 15SPS
    DRATE_10        = 0b00100011 # 10SPS
    DRATE_5         = 0b00010011 # 5SPS
    DRATE_2_5       = 0b00000011 # 2.5SPS

    # Commands
    CMD_WAKEUP  = 0x00 # Completes SYNC and exits standby mode
    CMD_RDATA   = 0x01 # Read data
    CMD_RDATAC  = 0x03 # Start read data continuously
    CMD_SDATAC  = 0x0F # Stop read data continuously
    CMD_RREG    = 0x10 # Read from register
    CMD_WREG    = 0x50 # Write to register
    CMD_SELFCAL = 0xF0 # Offset and gain self-calibration
    CMD_SELFOCAL= 0xF1 # Offset self-calibration
    CMD_SELFGCAL= 0xF2 # Gain self-calibration
    CMD_SYSOCAL = 0xF3 # System offset calibration
    CMD_SYSGCAL = 0xF4 # System gain calibration
    CMD_SYNC    = 0xFC # Synchronize the A/D conversion
    CMD_STANDBY = 0xFD # Begin standby mode
    CMD_RESET   = 0xFE # Reset to power-on values

    """
    Status Register Configuration - logically OR all desired options together
    to form a 1 byte command and write it to the STATUS register
    STATUS REGISTER - ADDRESS 0x00
    Bits 7-4 ID3, ID2, ID1, ID0 Factory Programmed Identification Bits 
    (Read Only)
    Bit 3 ORDER: Data Output Bit Order
        0 = Most Significant Bit First (default)
        1 = Least Significant Bit First
        Input data is always shifted in most significant byte and bit first.
        Output data is always shifted out most significant byte first. The
        ORDER bit only controls the bit order of the output data within the
        byte.
    Bit 2 ACAL: Auto-Calibration
        0 = Auto-Calibration Disabled (default)
        1 = Auto-Calibration Enabled
        When Auto-Calibration is enabled, self-calibration begins at the
        completion of the WREG command that changes the PGA (bits 0-2 of ADCON
        register), DR (bits 7-0 in the DRATE register) or BUFEN (bit 1 in the
        STATUS register) values.
    Bit 1 BUFEN: Analog Input Buffer Enable
        0 = Buffer Disabled (default)
        1 = Buffer Enabled
    Bit 0 DRDY: Data Ready (Read Only)
        This bit duplicates the state of the DRDY pin, which is inverted logic.
    """
    STATUS_BUFFER_ENABLE    = 0x02
    STATUS_AUTOCAL_ENABLE   = 0x04
    STATUS_ORDER_LSB        = 0x08


    """
    A/D Control Register - Address 0x02
    Bit 7 Reserved, always 0 (Read Only)
    Bits 6-5 CLK1, CLK0: D0/CLKOUT Clock Out Rate Setting
        00 = Clock Out OFF
    01 = Clock Out Frequency = fCLKIN (default)
    10 = Clock Out Frequency = fCLKIN/2
    11 = Clock Out Frequency = fCLKIN/4
    When not using CLKOUT, it is recommended that it be turned off. These
    bits can only be reset using the RESET pin.
    Bits 4-3 SDCS1, SCDS0: Sensor Detect Current Sources
    00 = Sensor Detect OFF (default)
    01 = Sensor Detect Current = 0.5uA
    10 = Sensor Detect Current = 2uA
    11 = Sensor Detect Current = 10uA
    The Sensor Detect Current Sources can be activated to verify the
    integrity of an external sensor supplying a signal to the ADS1255/6.
    A shorted sensor produces a very small signal while an open-circuit
    sensor produces a very large signal.
    Bits 2-0 PGA2, PGA1, PGA0: Programmable Gain Amplifier Setting
        000 = 1 (default)
        001 = 2
        010 = 4
        011 = 8
        100 = 16
        101 = 32
        110 = 64
        111 = 64
    """
    # Gain levels
    AD_GAIN_1      = 0x00
    AD_GAIN_2      = 0x01
    AD_GAIN_4      = 0x02
    AD_GAIN_8      = 0x03
    AD_GAIN_16     = 0x04
    AD_GAIN_32     = 0x05
    AD_GAIN_64     = 0x06

    # Sensor Detect Current Sources
    AD_SDCS_500pA   = 0x08
    AD_SDCS_2uA     = 0x10
    AD_SDCS_10uA    = 0x18

    # Clock divider
    AD_CLK_EQUAL    = 0x20
    AD_CLK_HALF     = 0x40
    AD_CLK_FOURTH   = 0x60

    # Mux channel selection
    MUX_AIN0 = 0x0
    MUX_AIN1 = 0x1
    MUX_AIN2 = 0x2
    MUX_AIN3 = 0x3
    MUX_AIN4 = 0x4
    MUX_AIN5 = 0x5
    MUX_AIN6 = 0x6
    MUX_AIN7 = 0x7
    MUX_AINCOM = 0x8



    # The RPI GPIO to use for chip select and ready polling
    def __init__(self):
        # Set up the wiringpi object to use physical pin numbers
        wp.wiringPiSetupPhys()

        # Initialize the DRDY pin
        wp.pinMode(self.DRDY_PIN, wp.INPUT)

        # Initialize the reset pin
        wp.pinMode(self.RESET_PIN, wp.OUTPUT)
        wp.digitalWrite(self.RESET_PIN, wp.HIGH)

        # Initialize PDWN pin
        wp.pinMode(self.PDWN_PIN, wp.OUTPUT)
        wp.digitalWrite(self.PDWN_PIN, wp.HIGH)

        # Initialize CS pin
        wp.pinMode(self.CS_PIN, wp.OUTPUT)
        wp.digitalWrite(self.CS_PIN, wp.HIGH)

        # Initialize the wiringpi SPI setup
        spi_success = wp.wiringPiSPISetupMode(self.SPI_CHANNEL, self.SPI_FREQUENCY, self.SPI_MODE)
        debug_print("SPI success " + str(spi_success))

    def delayMicroseconds(self, delayus):
        wp.delayMicroseconds(delayus)

    def chip_select(self):
        wp.digitalWrite(self.CS_PIN, wp.LOW)

    def chip_release(self):
        wp.digitalWrite(self.CS_PIN, wp.HIGH)

    def WaitDRDY(self):
        """
        Delays until DRDY line goes low, allowing for automatic calibration
        """
        start = time.time()
        elapsed = time.time() - start

        # Waits for DRDY to go to zero or TIMEOUT seconds to pass
        drdy_level = wp.digitalRead(self.DRDY_PIN)
        while (drdy_level == wp.HIGH) and (elapsed < self.DRDY_TIMEOUT):
            elapsed = time.time() - start
            drdy_level = wp.digitalRead(self.DRDY_PIN)

        if elapsed >= self.DRDY_TIMEOUT:
            print("WaitDRDY() Timeout\r\n")

    def SendString(self, mystring):
        debug_print("Entered SendString: " + mystring)
        result = wp.wiringPiSPIDataRW(self.SPI_CHANNEL, mystring)
        debug_print("SendString read: " + str(result[1]))



    def SendByte(self, mybyte):
        """
        Sends a byte to the SPI bus
        """
        debug_print("Entered SendByte")
        debug_print("Sending: " + str(mybyte) + " (hex " + hex(mybyte) + ")")
        mydata = chr(mybyte)
        result = wp.wiringPiSPIDataRW(self.SPI_CHANNEL, "%s" % mydata)   # notice workaround for single byte transfers JKR
        debug_print("Read " + str(result[1]))

    def ReadByte(self):
        """
        Reads a byte from the SPI bus
        :returns: byte read from the bus
        """
        MISObyte = wp.wiringPiSPIDataRW(self.SPI_CHANNEL, chr(0xFF))
        return ord(MISObyte[1]) #JKR

    def DataDelay(self):
        """
        Delay from last SCLK edge to first SCLK rising edge
        Master clock rate is typically 7.68MHz, this is adjustable through the
        SCLK_FREQUENCY variable
        
        Datasheet states that the delay between requesting data and reading the
        bus must be minimum 50x SCLK period, this function reads data after
        60 x SCLK period.
        """
        timeout = (60 / self.SCLK_FREQUENCY)


        start = time.time()
        elapsed = time.time() - start

        # Wait for TIMEOUT to elapse
        while elapsed < self.DATA_TIMEOUT:
            elapsed = time.time() - start


    def ReadReg(self, start_reg, num_to_read):
        """
        Read the provided register, implements:
        
        RREG: Read from Registers
        Description: Output the data from up to 11 registers starting with the
        register address specified as part of the command. The number of
        registers read will be one plus the second byte of the command. If the
        count exceeds the remaining registers, the addresses will wrap back to
        the beginning.
        1st Command Byte: 0001 rrrr where rrrr is the address of the first
        register to read.
        2nd Command Byte: 0000 nnnn where nnnn is the number of bytes to read
        1. See the Timing Characteristics for the required delay between the
        end of the RREG command and the beginning of shifting data on DOUT: t6.
        """

        # Pull the SPI bus low
        self.chip_select()
        
        # Send the byte command
        self.SendByte(self.CMD_RREG | start_reg)
        self.SendByte(0x00)

        # Wait for appropriate data delay
        self.DataDelay()

        # Read the register contents
        read = self.ReadByte()

        # Release the SPI bus
        self.chip_release()

        return read

    def WriteReg(self, start_register, data):
        """
        Writes data to the register, implements: 
        
        WREG: Write to Register
        Description: Write to the registers starting with the register
        specified as part of the command. The number of registers that
        will be written is one plus the value of the second byte in the
        command.
        1st Command Byte: 0101 rrrr where rrrr is the address to the first
        register to be written.
        
        2nd Command Byte: 0000 nnnn where nnnn is the number of bytes-1 to be
        written
        
        TODO: Implement multiple register write
        """

        # Select the ADS chip
        self.chip_select()

        # Tell the ADS chip which register to start writing at
        self.SendByte(self.CMD_WREG | start_register)

        # Tell the ADS chip how many additional registers to write
        self.SendByte(0x00)

        # Send the data
        self.SendByte(data)

        # Release the ADS chip
        self.chip_release()


    def ConfigADC(self):

        debug_print("configuring ADC")

        self.chip_select()

        self.SendByte(self.CMD_WREG | 0x00)  # start write at addr 0x00

        self.SendByte(self.REG_DRATE)  # end write at addr REG_DRATE 

        self.SendByte(self.STATUS_AUTOCAL_ENABLE)   # status register
        self.SendByte(0x08)			    # input channel parameters
        self.SendByte(self.AD_GAIN_2)		    # ADCON control register, gain
        self.SendByte(self.DRATE_500)			    # data rate
        
        self.chip_release()

        self.DataDelay()


    def SetInputMux(self,possel,negsel):
        debug_print("setting mux position")

        self.chip_select()
        self.SendByte(self.CMD_WREG | 0x01)
        self.SendByte(0x00)
        self.SendByte( (possel<<4) | (negsel<<0) )
        self.chip_release()

    def SyncAndWakeup(self):
        debug_print("sync+wakeup")

        self.chip_select()
        self.SendByte(self.CMD_SYNC)
        self.chip_release()
        self.delayMicroseconds(10)

        self.chip_select()
        self.SendByte(self.CMD_WAKEUP)
        self.chip_release()
        self.delayMicroseconds(10)

	
    def SetGPIOoutputs(self,D0,D1,D2,D3):
        debug_print("set GPIO outputs")

        IObits = D3*0x8 + D2*0x4 + D1*0x2 + D0*0x1

        self.WriteReg(self.REG_IO,IObits)
	

    def ReadADC(self):
        """
        Reads ADC data, implements:
        RDATA: Read Data
        Description: Issue this command after DRDY goes low to read a single
        conversion result. After all 24 bits have been shifted out on DOUT,
        DRDY goes high. It is not necessary to read back all 24 bits, but DRDY
        will then not return high until new data is being updated. See the
        Timing Characteristics for the required delay between the end of the
        RDATA command and the beginning of shifting data on DOUT: t6
        """

        # Pull the SPI bus low
        self.chip_select()

        # Wait for data to be ready
        self.WaitDRDY()

        # Send the read command
        self.SendByte(self.CMD_RDATA)
        
        # Wait through the data pause
        self.DataDelay()

        # The result is 24 bits
        #result.append(self.ReadByte())
        result1 = self.ReadByte()
        result2 = self.ReadByte()
        result3 = self.ReadByte()
        debug_print('ReadADC result bytes: ' + hex(result1) + ' ' + hex(result2) + ' ' + hex(result3))

        # Release the SPI bus
        self.chip_release()

        # Concatenate the bytes
        total  = (result1 << 16) + (result2 << 8) + result3

        return total


    def ReadID(self): 
        """
        Read the ID from the ADS chip
        :returns: numeric identifier of the ADS chip
        """
        self.WaitDRDY()
        myid = self.ReadReg(self.REG_STATUS, 1)
        debug_print("readID: myid = " + str(myid>>4))
        return (myid >> 4)
and here my code that does some stuff (reading temperature, reading ad, setting da, getting tcp command, sending telegram message checking mysql database for some other stuff saving data to mysql (not gonna give mysql functions))
its up to you guys to do the configuration to the way you want !!!
it read 4 differential analog data so i am using all inputs!!!
you have to do the libbcm2835 configurations !!!
python 2.7 !!!

Code: Select all

import libbcm2835._bcm2835 as soc
import my_lib
import select
import sys
import time
import datetime
import threading
import socket
import telepot
import numpy as np
import matplotlib.pyplot as plt
import chart_functions_d as cf
import mysql_data_save as mysql
import os
import glob

ads = my_lib.ADS1256()
idNumber = ads.ReadID()

print("\nADS1256 reported ID value: {}".format(idNumber))

SPICS = 23
control_pin=20 
channel_A  = 0x30
channel_B  = 0x34
read_am=1500
tim = []
ad0 = []
ad1 = []
ad2 = []
ad3 = []

def temperature_1():
    file = open('/sys/bus/w1/devices/10-000000084899/w1_slave')
    filecontent = file.read()
    file.close() 
    stringvalue = filecontent.split("\n")[1].split(" ")[9]
    temperature = float(stringvalue[2:]) / 1000
    t_1 = '%6.2f' % temperature 
    return(t_1)

def Voltage_Convert(Vref,voltage):
    _D_=(65536*voltage/Vref)   
    return (_D_)

def Write_DAC8532(channel, Data):  
    Data = int(Data)
    soc.bcm2835_gpio_write(SPICS,1)     
    soc.bcm2835_gpio_write(SPICS,0)
    soc.bcm2835_spi_transfer(channel)
    soc.bcm2835_spi_transfer((Data>>8))
    soc.bcm2835_spi_transfer((Data&0xff))    
    soc.bcm2835_gpio_write(SPICS,1)
    
def send_text(msg):
    try:
        bot = telepot.Bot(token=" ")
        chat_id = " "
        command = msg
        bot.sendMessage(chat_id, text=command)
        print("send text")
    except Exception,ex:
        print(str(ex))
        
def connect_as_reciever():
    ar0=[]
    ar1=[]
    d_t=[] 
    count=0
    while True:        
        try:
            TCP_PORT = 5555
            BUFFER_SIZE = 1024
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            s.bind(('', TCP_PORT))
            s.listen(1)
            while 1:
                try:                
                    conn, addr = s.accept()
                    data = conn.recv(BUFFER_SIZE)                
                    if data =="":
                        print("nothing from tcp")
                        conn.close()
                    elif data=="read":
                        read_ad()                      
                        s_data="Read all AD"
                        conn.send(s_data)                       
                    else:
                        Write_DAC8532(0x30, Voltage_Convert(5.0,0.0+float(data)/1000))
                        
                        #set_value(data)
                        data2 = "DA is set"
                        conn.send(data2) 
                except Exception ,ex:
                    #print("ER - 1 :",ex)
                    conn.close()
                    #break
        except Exception ,ex:
            a=2
            #print("ER -2 :",ex)
            

def read_ad():
    try:
        temp1=0
        c=0
        d=0
        volt=0
        amper=0
        ft = time.time()       
        ads.SetInputMux(ads.MUX_AIN3, ads.MUX_AIN7)        
        time.sleep(0.05)
        volt=ads.ReadADC()
        ads.SetInputMux(ads.MUX_AIN0, ads.MUX_AIN4)
        time.sleep(0.05)
        while 1:
            time.sleep(0.0001)
            ad0.append(ads.ReadADC())            
            tim.append(datetime.datetime.now())
            ad1.append(0)            
            ad2.append(0)            
            ad3.append(0)
            c=c+1
            d=d+1 
            if c==read_am:                
                ads.SetInputMux(ads.MUX_AIN1, ads.MUX_AIN5)
                time.sleep(0.05)
                c=0
                while 1:
                    time.sleep(0.0001)
                    ad1.append(ads.ReadADC())
                    tim.append(datetime.datetime.now())
                    ad0.append(0)                    
                    ad2.append(0)                   
                    ad3.append(0)
                    c=c+1
                    d=d+1
                    if c==read_am:                         
                        ads.SetInputMux(ads.MUX_AIN2, ads.MUX_AIN6)
                        time.sleep(0.05)
                        c=0
                        while 1:
                            time.sleep(0.0001)
                            ad2.append(ads.ReadADC())                            
                            tim.append(datetime.datetime.now())
                            ad0.append(0)
                            ad1.append(0)
                            ad3.append(0)                            
                            c=c+1
                            d=d+1
                            if c==read_am:
                                ads.SetInputMux(ads.MUX_AIN3, ads.MUX_AIN7)
                                time.sleep(0.05)
                                c=0
                                while 1:
                                    time.sleep(0.0001)                                    
                                    ad3.append(ads.ReadADC())
                                    tim.append(datetime.datetime.now())
                                    ad0.append(0)                                    
                                    ad1.append(0)                                    
                                    ad2.append(0)
                                    c=c+1
                                    d=d+1
                                    if c==read_am:
                                        temp1=temperature_1()
                                        temp1_date=datetime.datetime.now()
                                        ads.SetInputMux(ads.MUX_AIN0, ads.MUX_AIN4)
                                        time.sleep(0.05)
                                        c=0
                                        break
                                break
                        break
                break 
        if float(d)>100000:
            print("too much data for chart it will crash skipping chart show")
        else:
            copy_0=ad0[:]
            copy_1=ad1[:]
            copy_2=ad2[:]
            copy_3=ad3[:]
            copy_t=tim[:]
            copy_tmp=temp1
            copy_tmp_date=temp1_date
            
            d_val,cdis=mysql.chck_da_is_set()
            if cdis=='1':              
                Write_DAC8532(0x30, Voltage_Convert(5.0,0.0+float(d_val)/1000))
                mysql.update_da_is_set()              
            
            #cf.show_chart(ad0,ad1,ad2,ad3,tim)            
            mysql.write_to_db(copy_0,copy_1,copy_2,copy_3,copy_t,copy_tmp,copy_tmp_date)
            
        del tim [:]
        del ad0 [:]
        del ad1 [:]       
        del ad2 [:]
        del ad3 [:]              
        d=0
        c=0
        
    except Exception, ex:
        send_text("Error from Raspi 15 : " + str(ex))
        print("er at read_0"+str(ex))
        
if not soc.bcm2835_init():    
    print ("noit")
else:
    soc.bcm2835_spi_begin()
    soc.bcm2835_spi_setBitOrder(soc.BCM2835_SPI_BIT_ORDER_LSBFIRST )
    soc.bcm2835_spi_setDataMode(soc.BCM2835_SPI_MODE1)
    soc.bcm2835_spi_setClockDivider(soc.BCM2835_SPI_CLOCK_DIVIDER_1024)
    soc.bcm2835_gpio_fsel(SPICS, soc.BCM2835_GPIO_FSEL_OUTP)
    soc.bcm2835_gpio_fsel(control_pin, soc.BCM2835_GPIO_FSEL_INPT)    
    soc.bcm2835_gpio_write(SPICS, 0)
    while True:
        read_ad()
        #connect_as_reciever() 
     

I am the terror that flaps in the night...
I am the surprise you find in your cereal box!
I am DARKWING DUCK!!!

soumitra2012.kbc
Posts: 2
Joined: Tue Aug 22, 2017 8:36 am

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Fri Dec 01, 2017 5:47 am

novitsky wrote:
Thu Jan 28, 2016 1:02 am
I'm connecting WaveShare High-Percision AD/DA http://www.waveshare.com/wiki/High-Prec ... D/DA_Board with ADS1256 24bit ADC to a RaspberryPi 2B. I used Waveshare example code to create my own code to test it. I have the PI connected to a WiFi dangle, 5V 2A power adapter keyboard and a LAN cable. I get lots of noise from the device.Waveform Figure below shows the digital output with red arrows showing examples of the noise spikes (other spikes are also noise). The code reads the samples and each second create a file and send it to a ringbuffer. A different code on a remote client then reads the data from the buffer and present it as you see in the figure. I get similar noise patterns if the PI is only connected to the power adapter and have the client installed locally, saving the data to a file (no WiFi,LAN,keyboard etc.). I think this problem is due to non-stable power supply from the PI to the converter. Does anyone know of such a problem? Any solution suggestion?
Thanks, Ran

Screenshot.png
Kindly help me in achieving sampling speed as high as 30 KSPS, with the example code provided I could only achieve 15 SPS. Please share the code (if possible). It would be a great help. Moreover, Please help me in replicating your project.

Tsegaab
Posts: 1
Joined: Thu Aug 23, 2018 5:19 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Thu Aug 23, 2018 5:24 pm

I need to reach 30K SPS on the board but I don't know how. please help!

xiayang1995
Posts: 1
Joined: Thu Jan 03, 2019 2:56 am

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Thu Jan 03, 2019 3:02 am

SherlockHao wrote:
Thu Jun 02, 2016 2:15 am
Hi Dude, I am using the same AD/DA adc with RPI 3. But I cannot get any output from when I run the source code. I double checked the required libraries. I am trying to modified the source code to get any output from my screen but failed. I didn't connect any pins just put the AD/DA adc on the RPI 3. Here is what I got.

ASD1256 Chip ID = 0x255

ID=
Error, ASD1256 Chip ID = 0x15
0=FFFFFF, -1 ( 0.000 000 V)
1=FFFFFF, -1 ( 0.000 000 V)
2=FFFFFF, -1 ( 0.000 000 V)
3=FFFFFF, -1 ( 0.000 000 V)
4=FFFFFF, -1 ( 0.000 000 V)
5=FFFFFF, -1 ( 0.000 000 V)
6=FFFFFF, -1 ( 0.000 000 V)
7=FFFFFF, -1 ( 0.000 000 V)


Appreciate any response!
Hi Sherlock Hao
Have you solved this problem? I've also faced this ID error. How do you deal with that?
Thanks

Abrar007
Posts: 1
Joined: Wed Mar 20, 2019 1:35 am

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Wed Mar 20, 2019 1:46 am

Hello Everyone here, I recently bought a WaveShare High-Percision AD/DA (ADS1256) board and i am using it Raspberry pi 3b+ and i followd all the steps to execute the sample code which given at Waveshare website and it's working fine for me i got the built-in sensors result ( Pot & LDR) in my terminal window of raspberry pi.
My problem is that i want to visualize the sensor result from waveshare board in Node red, so is there anybody did that? because in Node red i don't know how to get the sensor result from the output of the waveshare board because i am new to Node red :D .
i really appreciate any response to my quireis.
Thank you very much
Abrar khan

picandies
Posts: 236
Joined: Wed Nov 26, 2014 5:13 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Fri Oct 25, 2019 7:19 am

I'm using their basic code from their link to read all channels (just prints them to the screen)
https://www.waveshare.com/wiki/File:Hig ... rd-Code.7z

However, it seems like it's only taking about 10 samples per second...mighty slow.
How can you increase the speed, maybe to 100/sec? I tried adding ADC.ADS1256_ConfigADC(1,1) after the init with several different values, but the speed doesn't seem to change (or if it does, not by much)

Code: Select all

import time
import ADS1256
import RPi.GPIO as GPIO


try:
    ADC = ADS1256.ADS1256()
    ADC.ADS1256_init()

    while(1):
        ADC_Value = ADC.ADS1256_GetAll()
        print ("0 ADC = %lf"%(ADC_Value[0]*5.0/0x7fffff))
        print ("1 ADC = %lf"%(ADC_Value[1]*5.0/0x7fffff))
        print ("2 ADC = %lf"%(ADC_Value[2]*5.0/0x7fffff))
        print ("3 ADC = %lf"%(ADC_Value[3]*5.0/0x7fffff))
        print ("4 ADC = %lf"%(ADC_Value[4]*5.0/0x7fffff))
        print ("5 ADC = %lf"%(ADC_Value[5]*5.0/0x7fffff))
        print ("6 ADC = %lf"%(ADC_Value[6]*5.0/0x7fffff))
        print ("7 ADC = %lf"%(ADC_Value[7]*5.0/0x7fffff))
        print ("\33[9A")

        

Amritpal
Posts: 4
Joined: Tue Dec 17, 2019 3:06 pm

Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B

Wed Jan 15, 2020 10:12 am

i am working in one of the project and i am using AD/DA high precision expansion board with raspberry pi 4. i am using 50 Hz frequency with amplitude 1.5 vpp and offset 1.5v with 30000 sps by using sinusoidal waveform as input i am expecting to get 600 value of ADC data per second from single channel but unfortunately i am getting only 55 data value per second. could you please tell me is it possible to get 600 value data per second if possible how i will get ?

acatalano
Posts: 19
Joined: Mon Jun 22, 2015 1:49 pm
Location: Boulder, CO USA
Contact: Website

WaveShare High-Percision AD/DA (ADS1256) with RPI 4

Fri Jan 24, 2020 9:02 pm

Amritpal, if you would be so kind, can you explain how you got the Waveshare board to work on the RPi4? I've been working so far unsuccessfully to get any result. I have been able to get it to run in C++ but not python (actually at this moment even the C++ code isn't working as I flail about.) Any suggestions would be appreciated. Which version of the bcm2835 code are you using (I'm using the 1.62). Any advice would be MOST appreciated!!
Anthony Catalano, PhD
Boulder, CO USA
Weather Station & Webcams at:
www.boulderwx.com
www.boulderweather.org

acatalano
Posts: 19
Joined: Mon Jun 22, 2015 1:49 pm
Location: Boulder, CO USA
Contact: Website

WaveShare High-Percision AD/DA (ADS1256) with Python on RPI 4: Solved

Sat Jan 25, 2020 4:39 pm

Problem solved! I got the WaveShare board working in python 2.7. (So Amritpal, no need to bother..) At least part if not all the problem has been with the incomplete and sometimes conflicting guidance provided on the Waveshare wiki and on their related documents, (https://www.waveshare.com/wiki/High-Pre ... D/DA_Board) Although I was able to use the downloaded information to run the board in C++, python just did not seem to work. However, I found a reference on this Board to PyPiADC (https://github.com/ul-gh/PiPyADC). The download works beautifully in python2.7 on the RPi4.

As much as I appreciate the mental "burn" of C++, for quick program development python is hard to beat.
Anthony Catalano, PhD
Boulder, CO USA
Weather Station & Webcams at:
www.boulderwx.com
www.boulderweather.org

Return to “Troubleshooting”