How can I set raspberry pi GPIO output to high impedance? - raspberry-pi

I am using RPi.GPIO Raspberry Pi GPIO library.
I know how to set an output to high or low, but i need to set it as high impedance.
GPIO.output(PIN, GPIO.HIGH) # or GPIO.LOW
Is there a way to set the output as "high impedance", something like:
GPIO.output(PIN, GPIO.FLOAT)
so that the output is floating and constrained by surrounding circuitry only? (like the drain or collector of a MOS or BJT)?
A possible way would be switch the pin mode to input and set pull up/down resistors to no pullup or pull down, is this the only way, or there is a better solution?

Setting the pin to input and disabling the pull-up/-down resistors seems the way to go. You would have to define a helper function that accepts low, high and float as parameters.
FLOAT:
GPIO.setup(port_or_pin, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
LOW:
GPIO.setup(port_or_pin, GPIO.OUT)
GPIO.output(self.reset_pin, GPIO.LOW)
HIGH:
GPIO.setup(port_or_pin, GPIO.OUT)
GPIO.output(self.reset_pin, GPIO.HIGH)

Related

MPR121 sensor sensitivity

I have connected and tested the two break-board versions of MPR121 Proximity Capacitive Touch Sensor Controller with various mcu's (ESP32, RPI pico, ARDUINO)
The one on a keypad version (Sparkfun compatible) and the one that you can connect custom pads to it. I tried them both with cpp and micropython. I connected them via I2C and everything is functioning on all occasions, with the IRQ option as well.
However I have trouble increasing sensitivity and by that I mean that if I place even a thin piece of paper or other layer before the touch pads, I can't get a touch signal.
Looking into the MPR121 micropython example Library I modified the following:
MicroPython MPR121 capacitive touch keypad and breakout board driver
https://github.com/mcauser/micropython-mpr121
Inside this library I see the following parameters for tuning that I tried:
# Set touch and release trip thresholds
#self.set_thresholds(15, 7) default....
self.set_thresholds(15, 7)
# Set config registers
# Debounce Touch, DT=0 (increase up to 7 to reduce noise)
# Debounce Release, DR=0 (increase up to 7 to reduce noise) .....default was 0x00
self._register8(MPR121_DEBOUNCE, 0x00)
# First Filter Iterations, FFI=0 (6x samples taken)
# Charge Discharge Current, CDC=16 (16uA) .default was 0x10 5-30 less to more sensitive
self._register8(MPR121_CONFIG1, 0x30)
# Charge Discharge Time, CDT=1 (0.5us charge time)
# Second Filter Iterations, SFI=0 (4x samples taken)
# Electrode Sample Interval, ESI=0 (1ms period) .default was 0x20 5-30 less to more sen
self._register8(MPR121_CONFIG2, 0x20)
I tried various combinations but the effect is minimal if non-existent. My target or best case scenario is to be able to place a 3mm plexiglass on top of the breakout board or custom pads.

STM32F429 GPIO DMA Read and Write

Hello,
I'm making a project where I want to bit-bang the JTAG protocol.
According to the AN4666 provided by ST, DMA + GPIO can achieve high speeds in bit-banging synchronous protocols.
I want to:
Generate N PWM pulses (the CLK signal).
With the falling edge of each pulses, I want to set some GPIO with DMA.
With the rising edge, I want to read from the GPIO using DMA.
What is the best way to achieve these specs using HAL?
even withtout dma you can reach quite high freq bit banged i/o i'll say in range 2 - 10MHz assuming fast enougth mcu and gpio bus clock high enough (48 96MHz)
Clock just wan't be as stable and may suffer "stall" say idle time when iterrupt occur vs dma. but is way simpler
for DMA base , if you use 3 bit of one port, one for clk and one for TDI and one for TDO then use 2 dma one to wr and one that rd on same timer source (if possible) at double rate of the TCK signal
the data in is rebuilt by taking teh i bit of one read data over 2
index like 0 2 4 or 1 3 5 ... depending on edge you want and how you wr clk array in mem is coded.
last if your jtag chain is 8 bit multiple SPI is even simpler and dma easy ;)

STM32 generate 22Mhz clock on gpio out from SystemCoreClock 110Mhz

I want to generate clock for PCA9959 LED driver with my STM32L552. The LED driver needs an external clock at 20 MHz (+/- 15%). I'm trying to generate a 22 MHz clock on port PA8 on STM32L552. I managed to generate a PWM on port PA8, but I can't reach the frequency of ~22Mhz. I arrive at a maximum of 8Mhz.
Here are the PWM parameters:
I'm not sure I filled in the pwm parameters correctly. Normally with his settings I guess I should have a 22 MHz PWM with a 20% duty cycle.
PWM (MHz) = SystemCoreClock (MHz) / Prescaler => 22MhZ = 110MHz / 5
My clock configuration:
Thanks for your help.
The easiest way to output a high speed clock like this is with the MCO peripheral, rather than a timer. Fortunately for you the MCO pin is PA8. Perhaps the person who designed your board knew this and intended you to use MCO. Read the reference manual to see how.
If you do want to use a timer to do 22MHz, then as you have correctly identified you cannot get a 50% duty-cycle on your PWM. I would recommend starting with a 40% or 60%, with an output-compare value of 2-out-of-5 or 3-out-of-5, not 1 as you have above.
There is no detail in the PCA9959 datasheet about what the required mark-space ratio of the clock is, but I guess anything other than 50% could be a problem. You would be better to divide the clock by an even number. Either just divide 110MHz by 6 and output 18.33MHz, or else slow your core down a bit and divide by 4 (reduce the N parameter of your PLL).
Whether you use MCO or PWM don't forget to set the GPIO pin mode to the fastest slew rate available. Maybe the 8MHz you are measuring is the result of aliasing a faster clock that has been through the wrong GPIO mode. You could test this using a scope with at least 100MHz bandwidth.

I2C slave implementation - clock frequency?

I want to implement a I2C SLAVE in an FPGA, just for learning purposes. I read in the I2C specification that for the FAST mode there is a timing parameter tPS = 50ns (max) which means "pulse width of spikes that must be suppressed by the input filter". Should this be a digital filter inside the slave? If yes, does that mean my slave must have a maximum clock period of 25ns (or something)?
Another question would be: is there a (robust) way of implementing this slave using the SCL line as the only clock? Or a faster second clock is needed (and in this case I would treat the SCL line as "data")? If so, how do I calculate the minimum frequency of this other clock?
Thanks in advance!

Raspberry Pi - How to measure 2 resistor values with GPIO

Is it possible to measure 3 specific resistor values by using GPIO / Without using a full ADC setup?
I have an alarm sensor that I want to hook up to my GPIO. This sensor has 3 specific resistors value, based on it's state:
1) Normal - 4k7
2) Alarm - 9k3
3) Tamper - infinite.
Due to long lines, I would prefer 12V power on one side.
I would like to be able to detect these states by 2 normal GPIO input pins.
Is that even possible? What would be the schematic needed for this?
Or is the only solution to use (external) ADC's?
I am thinking about a voltage diver with resistors and a 1N4148 diode to clip it to 3v3. But so far my results are unfruitfull.
Thanks.
The problem here is you have three levels to measure. If we had two we could use a simple resistor divider setup to make (say) the 4k7 and 9k3 outputs on the sensor to logic 0 (<=0.8V) or logic 1 (>=1.3V) on a single GPIO pin. We could do this on two GPIO pins if we had two "independent samples" of the sensor output rather than one.
Given the above it is possible to design some simple logic network to do the comparisons but as the other comment mentions you're off into the realms of electronics.
ADC is the simplest way to go if you want to stay in the software domain. The are other SBC devices e.g. ESP8266 which have onboard ADC functionality and built-in Wifi https://esp8266-projects.org/2015/03/internal-adc-esp8266/ or you can hook up an add-on ADC to the Rpi for example https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters
Good luck