Page 2 of 2
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Fri Jul 15, 2016 1:25 pm
by jholov
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
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Fri Jul 15, 2016 2:09 pm
by jholov
I actually found what I needed manual. Program works good now
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Fri Jul 15, 2016 2:17 pm
by novitsky
Try adding "sudo" in front of the device-tree command.
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Tue Jul 26, 2016 11:32 pm
by SherlockHao
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?
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Wed Jul 27, 2016 12:18 am
by novitsky
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.
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Thu Aug 04, 2016 3:01 am
by tegtmeye
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
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Thu Aug 04, 2016 1:14 pm
by novitsky
I think its just for selecting power source for the reference. It would still be 2.5v
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Wed Oct 19, 2016 11:58 am
by ufo2001
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.
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Mon Oct 24, 2016 8:06 am
by ChristophK
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.
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Fri Feb 17, 2017 1:19 am
by fabio.oliveira
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.
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Thu May 04, 2017 1:49 am
by AshPowers
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?
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Thu May 04, 2017 3:51 am
by AshPowers
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.
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Mon May 15, 2017 1:12 pm
by senovr
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?
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Thu Oct 12, 2017 5:34 pm
by chrisbeuglet
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.
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Fri Nov 10, 2017 2:38 pm
by iradevic
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
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Fri Nov 17, 2017 9:26 am
by legendisback
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()
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Fri Dec 01, 2017 5:47 am
by soumitra2012.kbc
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.
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Thu Aug 23, 2018 5:24 pm
by Tsegaab
I need to reach 30K SPS on the board but I don't know how. please help!
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Thu Jan 03, 2019 3:02 am
by xiayang1995
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
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Wed Mar 20, 2019 1:46 am
by Abrar007
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

.
i really appreciate any response to my quireis.
Thank you very much
Abrar khan
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Fri Oct 25, 2019 7:19 am
by picandies
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")
Re: WaveShare High-Percision AD/DA (ADS1256) with RPI 2B
Posted: Wed Jan 15, 2020 10:12 am
by Amritpal
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 ?
WaveShare High-Percision AD/DA (ADS1256) with RPI 4
Posted: Fri Jan 24, 2020 9:02 pm
by acatalano
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!!
WaveShare High-Percision AD/DA (ADS1256) with Python on RPI 4: Solved
Posted: Sat Jan 25, 2020 4:39 pm
by acatalano
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.