Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 8041

MicroPython • Re: Accurate Edge Counter with RP2040 PIO — Pulse Counting on Demand

$
0
0
I have analyzed your PIO program out of interest. From my analysis it only counts Rising edges, not both rising and falling edges as you claimed. Here is the pseudo-code I created based on the PIO program.

Code:

// InitializationInterrupt_Status_Register = 0Initial_Pin_State = Read state of the configured input pin (associated with 'in_base' - btn0)Interrupt_Status_Register = Initial_Pin_Staterestart_counting:    Counter_Y = 0main_loop:    Previous_Pin_State = Interrupt_Status_Register    // Check the current state of the input pin (associated with 'jmp_pin' - btn0)    if Input_Pin_State is HIGH:        goto pin_is_high    else:        goto check_previous_state_lowcheck_previous_state_low:    if Previous_Pin_State is LOW:        goto skip_incrementing // No rising edge detected    else:        // Previous state was HIGH, current is LOW (falling edge - ignore)        Previous_Pin_State = 0        goto continue_monitoringpin_is_high:    if Previous_Pin_State is LOW:        goto rising_edge_detected    else:        goto skip_incrementing // Still HIGH, no new rising edgerising_edge_detected:    // Record that the pin is now HIGH    Previous_Pin_State = 1continue_monitoring:    // Increment the counter Y (using bitwise NOT operations which effectively increment)    Counter_Y = ~Counter_Y    Decrement_and_Jump_if_Not_Zero Counter_Y to continue_increment // Acts as a second incrementcontinue_increment:    Counter_Y = ~Counter_Yskip_incrementing:    // Temporarily store the current/previous pin state    Interrupt_Status_Register (temporary) = Previous_Pin_State    // Prepare to check for a pull request    Pull_Request_Signal = 0    // Attempt to pull data from the TX FIFO (non-blocking)    if TX_FIFO is not empty:        Pulled_Data = Pop from TX_FIFO        Pull_Request_Signal = Pulled_Data    else:        Pull_Request_Signal = 0 // Remains 0 if FIFO was empty    // If no pull request was made    if Pull_Request_Signal is 0:        goto main_loop // Continue monitoring the pin    // A pull request was made, output the counter value    Interrupt_Status_Register (temporary) = Previous_Pin_State    Interrupt_Status_Register = Counter_Y    Push Interrupt_Status_Register to RX_FIFO    Interrupt_Status_Register = Interrupt_Status_Register (temporary)    Set IRQ flag 0 (relative to the PIO block)    goto restart_counting // Reset counter and start again
I summarize the PIO program as acting as a hardware counter for rising edges on btn0. The Python code uses btn1 to signal a request for the current count. Upon request, the PIO program sends the count back to the Python code via the RX FIFO and triggers an interrupt, which then prints the count. The counter then resets to zero to begin counting new rising edges on btn0.
Hi! Thank you for your reply and I'm glad my program interested you :D There is something you're missing in your analysis of my logic. Notice in this snippet here, I numbered lines:

Code:

[1] jmp(pin,"pin_hi")[2] jmp(not_x,"skip_increment")[3] set(x,0)[4] jmp("increment")


Assume pin is low, and x is 1 (previous pin state stored), i.e. a falling edge:
  • Because the pin is low, the jmp in line [1] does not execute, the code continues.
  • Because not_x is false (x=1 at the moment), the jump in line [2] isn't performed either, the execution proceeds to the next line.
  • The execution proceeds to line [3] where x is set to 0, which stores the current pin state (just checked that pin is low). Proceed.
  • In line [4] unconditionally jump to increment section in the following part of the code.
So, clearly, the program does count falling edges too :) Feel free to whip out a pico, a breadboard and two buttons and check for yourself!

Statistics: Posted by seventz — Mon Apr 07, 2025 12:57 pm



Viewing all articles
Browse latest Browse all 8041

Trending Articles