Need Help with CNC Feedrate Adjustment Project Using a Raspberry Pi Pico

Hi there,

I’m working on a project to manipulate the feedrate on my CNC machine, but unfortunately, the controller doesn’t have built-in support for this feature. To work around this, I’m trying to build a custom solution using a Raspberry Pi Pico and a potentiometer to control the feedrate externally.

The controller supports feedrate adjustments through keyboard inputs like F11 for increasing and decreasing feedrate (+/-), so my idea is to simulate a keyboard using the Pico. The plan is to detect changes in the potentiometer (I’m using a 10K ohm pot) and then send simulated keypresses (either “+” or “-”) to the controller whenever the potentiometer moves by 1% or more. If the potentiometer is not moved, no input should be sent.

I’ve written some code to handle this, but I’m struggling with reliability. The current implementation doesn’t work as expected. The goal is for the code to accurately detect changes and send the “+” or “-” keypress immediately when the potentiometer is adjusted by 1%. However, it sometimes sends the wrong inputs or doesn’t react quickly enough.

Here’s the code I’ve written so far. I’d really appreciate any advice or suggestions to improve its accuracy and reliability.

Thanks in advance for your help!

import time
import analogio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
import board

# Setup potentiometer for feedrate pin and HID keyboard
pot_feedrate = analogio.AnalogIn(board.GP26_A0)  # Using only feedrate potentiometer
kbd = Keyboard(usb_hid.devices)

# Function to map potentiometer values to a percentage
def get_percentage(pin):
    return (pin.value / 65535) * 100

# Parameters for adjustments
change_threshold = 2.4  # Sensitivity with a 2.4% deviation trigger
step_size = 2.4  # Adjustments made in 2.4% increments
debounce_time = 0.3  # Debounce time for avoiding rapid changes
dead_zone = 1.5  # Small dead zone to ignore small changes

feedrate_values = []
moving_average_length = 10

# Moving average calculation
def moving_average(values, new_value, length):
    values.append(new_value)
    if len(values) > length:
        values.pop(0)
    return sum(values) / len(values)

last_feedrate_time = time.monotonic()

while True:
    # Read current value from potentiometer
    current_feedrate = get_percentage(pot_feedrate)

    # Calculate moving average
    avg_feedrate = moving_average(feedrate_values, current_feedrate, moving_average_length)

    # Output feedrate change only when it exceeds the change threshold
    if abs(current_feedrate - avg_feedrate) > change_threshold:
        steps = int((current_feedrate - avg_feedrate) / step_size)
        if abs(current_feedrate - avg_feedrate) > dead_zone:
            if current_feedrate > avg_feedrate:
                print(f"Increasing feedrate by {steps * step_size:.2f}% +")
                for _ in range(steps):
                    kbd.press(Keycode.KEYPAD_PLUS)
                    time.sleep(0.05)
                kbd.release_all()
            elif current_feedrate < avg_feedrate:
                print(f"Decreasing feedrate by {abs(steps) * step_size:.2f}% -")
                for _ in range(abs(steps)):
                    kbd.press(Keycode.KEYPAD_MINUS)
                    time.sleep(0.05)
                kbd.release_all()
            last_feedrate_time = time.monotonic()

    # Debug output showing feedrate and average
    if time.monotonic() - last_feedrate_time > debounce_time:
        print(f"Feedrate: {current_feedrate:.2f}% (Avg: {avg_feedrate:.2f}%)")
        last_feedrate_time = time.monotonic()

    time.sleep(0.1)

Hi Noah,

Welcome to the forum! There are a few things right off the bat that if you could get us would help immensely.

Can you send us some pictures of your current setup?
What is the controller on your CNC machine?

Hi Noah,

From what you’ve described it sounds like you’d be better off with a rotary encoder rather than a potentiometer and setting up your code to treat movements left or right as either negative or positive changes to your feedrate.