10 years later I finally got back to this
OK, so I used ChatGPT as a starting point here. Again, I know absolutely nothing about writing Python/micropython stuff so the idea for this project was to start with a very basic code and build/modify from there to learn a bit. Like I know enough to flash some LEDs or perform some calculations or whatever, but absolutely nothing about interfacing with ADCs and so on.
This thing is just supposed to read 4 voltages and I'll manipulate that info to do stuff from there. I've successfully written code to do what I want to do with that data multiple times now so apparently I'm not completely braindead, but given I can't get the right data in whatever else I'm writing is useless.
After a few tweaks on the ChatGPT starting point the code below basically works (this has none of my data manipulation stuff, just bare bones reading), but with a couple issues:
import time
from machine import I2C, Pin
# Define the SDA and SCL pins for the Raspberry Pi Pico
i2c = I2C(0, sda=Pin(0), scl=Pin(1)) # Use GPIO 0 for SDA, GPIO 1 for SCL
ad7994_address = 0x21 # Replace XX with the AD7994 I2C address
reference_voltage = 5 # Reference voltage in volts
# Define the CONVST pin
convst_pin = Pin(2, Pin.OUT) # Use GPIO 2 as the CONVST pin
# Function to initiate ADC conversion
def initiate_conversion():
convst_pin.value(1) # Set CONVST pin high
time.sleep_us(10) # Minimum pulse width for CONVST (10 microseconds)
convst_pin.value(0) # Set CONVST pin low
# Function to read 12-bit data from the AD7994 and scale to voltage
def read_ad7994(i2c, address):
# Read from all 4 channels sequentially
readings = []
for channel in range(4):
initiate_conversion() # Initiate ADC conversion
time.sleep_ms(10) # Wait for the ADC conversion to complete (adjust this delay if needed)
i2c.writeto(address, bytes([0x80 | (channel << 4)])) # Write to the config register for the specified channel
time.sleep_ms(1) # Wait for the configuration write to complete (adjust this delay if needed)
data = i2c.readfrom(address, 2)
value = ((data[0] << 8) | data[1]) & 0xFFF
voltage = (value / 4095.0) * reference_voltage
readings.append(voltage)
return tuple(readings)
# Main loop to continuously read and print data from the AD7994
while True:
channel_voltages = read_ad7994(i2c, ad7994_address)
print("Channel 1: {:.2f} V".format(channel_voltages[0]))
print("Channel 2: {:.2f} V".format(channel_voltages[1]))
print("Channel 3: {:.2f} V".format(channel_voltages[2]))
print("Channel 4: {:.2f} V".format(channel_voltages[3]))
time.sleep(2) # Add a delay between readings (adjust as needed)
I've got this set up on a breadboard with a simple test- 1V going into channel 1, 2V going into channel 2, 3V going into channel 3, 4V going into channel 4.
Problem 1 is that the order is reversed. So channel 1 prints as 4V/channel 4 prints as 1V, etc.
That's not a big deal as I can change that in the print function, but I'd like to understand why this is happening in the first place.
Problem 2 is the main problem- channel 2 in the code above (which is actually channel 3 on the ADC) should be printing 3V, but it always prints 1V. The other 3 channels all give the correct readings.
There is DEFINITELY 3V on that pin, and I've even swapped IC's to rule out a bad ADC. Something about literally every working variation of the code that I've managed to punch in means it never reads this particular pin properly. And yeah, given that I know jack shit, I'm absolutely stumped as to why.
If it helps, data sheet for the ADC is here-
https://www.analog.com/media/en/technical-documentation/data-sheets/ad7993_7994.pdfI will absolutely buy a beer/coffee for the first person who can help me fix this/understand what is going on because I'm just bashing my head against the wall here haha