It needs 2 Pins per channel, 2 resistors and 2 capacitors.
The charge of the two condensers is balanced by the current through the input resistor 1meg and the current through the feedback resistor 220k. PIO code tries to hold the voltage at the input pin at its low/high threshold.
It is possible to measure higher and negative voltages, if you use an adapted input resistor.
Have fun! Christof
Code: Select all
title= "pioAdcB" # by CWE
# Adc sigma delta type
from machine import Pin
from rp2 import PIO, StateMachine, asm_pio
from time import sleep
maxTime=1_000_000
@asm_pio(sideset_init=PIO.OUT_LOW)
def cap_prog():
mov(y, osr) # OSR must be preloaded with max
mov(x, osr)
label("test_pin") #
jmp(pin, "is_set")
jmp(y_dec, "not_set") # just count it 1
label("not_set")
#nop() .side(1)
jmp(x_dec,"test_pin") .side(1) # 2
jmp("save_result")
label("is_set")
# nop() .side(0)
nop() # 1
jmp(x_dec,"test_pin") .side(0) #2
label("save_result")
mov(isr, y) #.side(0) # save result; pin low
push(noblock)
class PIOCAP:
def __init__(self, sm_id, outPin, inPin, max_count, count_freq):
self._sm = StateMachine(sm_id, cap_prog, freq=2 * count_freq, sideset_base=Pin(outPin), jmp_pin=Pin(inPin,Pin.IN))
# Use exec() to load max count into ISR
self._sm.put(max_count)
self._sm.exec("pull()")
#self._sm.exec("mov(isr, osr)")
self._sm.active(1)
self._max_count = max_count
def getCap(self):
#self._sm.exec("push()")
return self._sm.get()
cap = PIOCAP(0, 22, 17, max_count=(maxTime), count_freq=50_000_000)
mittel=0
while True:
onTime= maxTime-cap.getCap()
mittel=(9*mittel+onTime)/10
#print(onTime, mittel, (onTime/maxTime))
print(onTime, 7.309-1.4369e-5*onTime)
sleep(0.1)