【RPi PICO】Use PIO to get more Sigma Delta ADC inputs
[Copy link]
From: https://forum.micropython.org/viewtopic.php?t=9839&p=55065#p55065
The ADC input channels on PRP2040 are relatively few. The following method can provide more ADC channels. Each channel requires 2 pins, 2 resistors and 2 capacitors.
The charge of the two capacitors is balanced by the current through the input resistor R2 and the feedback resistor R1. The PIO tries to keep the voltage on the input pin between its low/high thresholds. If the appropriate input resistors are used, higher and lower voltages can be measured.
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)
|