The original sketch was built to use an NTC Thermistor to monitor a remote mountaintop shack's ambient temperature ... this has been in operation for over 3 years ... we recently added some batteries with a Victron BP65 over/under voltage device ... because Victron doesn't provide an API for Bluetooth to allow monitoring of the Battery Voltage on the Pi, we were thinking we would just add a simple voltage divider to monitor the voltage using one of the unused Channels on the existing ADC. HOWEVER, for some unknown reason, the moment voltage is applied to the Vbat pin (top of the 100k pot) both Channel 0 and Channel 1 read 0V even though actual voltages of 1.2V and 2.2V respectively are being applied to the inputs of these channels ... the code listed below shows that these channels are being configured for single-ended use so completely stumped as to why this simple addition not only fails to provide any readings on Channel 1 but ALSO affects Channel 0.
Can anyone explain what I might be missing here?
The only change made was to add the 100k Pot which was pre-adjusted with a 20V input so the wiper reads 3.3V to ground ... this allows for the Pi to estimate the vBat as (ADC Val) / 1024 * 20 where ADC Val would be (Vchn1 / 3.3 * 1024) ... ADC read function unchanged
ch1 ip => 2.2V -> expected ADC reading => 683 -> estimated VBat => 13.4V
Instead, both Chn0 and 1 are returning readings of 0 until the VBat voltage is removed from the 100k pot
NOTE: pg and pgl referenced in the code are defined as follows: pg is a CLI process that allows a user to manually request current status ... pgl is a continuous loop process running in the background with a watchdog used to monitor and provide instant email notifications when readings hit or exceed set limits. An unused GPIO pin on the Pi is being used as a hardware Flag to ensure a CLI request doesn't collide with a Loop Request
#----------------- readADC( Channel# ) --------------------------------------- # Microchip ADC MCP300X family has 3 variations; 2, 4 or 8 Channel 10bit A/D # all 3 use a Serial Data Pin to Clock in Commands & Clock out Digital Data # representing the Analog values # def readAdc(iChn): # MCP3004 has 4 Channels: 0 to 3 # ensure both pgl and pg don't attempt to read adc at the same time bArf = GPIO.input(ARF[_PIN]) # is there a Read in Progress while bArf == 1: bArf = GPIO.input(ARF[_PIN]) # wend GPIO.output(ARF[_PIN], GPIO.HIGH) # set Read in Progress # Datasheet says chip select must be pulled high between conversions GPIO.output(CS[_PIN], GPIO.HIGH) # Start the read with clock high and chip select low GPIO.output(CS[_PIN], GPIO.LOW) GPIO.output(CLK[_PIN], GPIO.HIGH) # ADC commands are 5 bits long: # start bit = 1 # single-ended comparison = 1 (vs. pseudo-differential = 0) # channel num bit 2 (MSB) (for MCP3004 this is always 0) # channel num bit 1 # channel num bit 0 (LSB) # ie for single-ended channel 0 this command should be 1 1 0 0 0 or 0x18 iAdcCmd = 0x18 # base command for Channel 0 iAdcCmd |= iChn # add Channel to command for iBit in range(5): # output MSB bit: HI or LO if iAdcCmd & 0x10: # is MSB HI? GPIO.output(MOSI[_PIN], GPIO.HIGH) else: GPIO.output(MOSI[_PIN], GPIO.LOW) # endif # Shift next bit to MSB iAdcCmd <<= 1 # Send a clock pulse HI then immediately LO GPIO.output(CLK[_PIN], GPIO.HIGH) GPIO.output(CLK[_PIN], GPIO.LOW) # next iAdcVal = 0 for iBit in range(12): # Pulse clock pin GPIO.output(CLK[_PIN], GPIO.HIGH) GPIO.output(CLK[_PIN], GPIO.LOW) # Read 1 data bit in if GPIO.input(MISO[_PIN]): iAdcVal |= 0x1 # endif # Shift in next bit iAdcVal <<= 1 # next # Divide by two to drop the stop bit iAdcVal = (iAdcVal/2) iAdcVal &= 0x3FF # Set chip select high to end the read GPIO.output(CS[_PIN], GPIO.HIGH) GPIO.output(CS[_PIN], GPIO.LOW) GPIO.output(ARF[_PIN], GPIO.LOW) # clear Read in Progress return iAdcVal # end readACD