import machine
import struct
from machine import I2C, Pin
from time import sleep
from pico_i2c_lcd import I2cLcd
import utime
# Initialize I2C and LCD
i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000)
I2C_ADDR = i2c.scan()[0]
lcd = I2cLcd(i2c, I2C_ADDR, 2, 16)
MotorHiz = 500
count = 0
max_speed = 1200 # Maximum speed (steps per second)
acceleration =4000 # Acceleration rate (speed change per step)
# Stepper Motor Pins
STEP_PIN = Pin(14, Pin.OUT)
DIR_PIN = Pin(15, Pin.OUT)
# Keypad Settings
row_pins = [Pin(i, Pin.OUT) for i in range(6, 10)]
col_pins = [Pin(i, Pin.IN, Pin.PULL_DOWN) for i in range(2, 6)]
keypad_map = [
['1', '2', '3', 'A'],
['4', '5', '6', 'B'],
['7', '8', '9', 'C'],
['*', '0', '#', 'D']
]
# Global Variables
entered_value = "0" # Stores keypad input
current_position = 0 # Stepper motor current position
def read_keypad():
"""Reads a single key press from the keypad."""
for row in range(4):
row_pins[row].high()
for col in range(4):
if col_pins[col].value() == 1:
row_pins[row].low()
return keypad_map[row][col]
row_pins[row].low()
return None
def move_stepper(target_steps, max_speed, acceleration):
"""
Moves the stepper motor to the target position with configurable acceleration and max speed.
:param target_steps: Target step count
:param max_speed: Maximum speed (steps per second)
:param acceleration: Acceleration rate (steps per second squared)
"""
global current_position
steps_to_move = abs(target_steps - current_position)
if steps_to_move == 0:
return # No movement needed
# Set direction
if target_steps > current_position:
DIR_PIN.high() # Forward
else:
DIR_PIN.low() # Backward
# Initialize speed and delay
current_speed = 100 # Start at minimum speed
delay = 1_000_000 // current_speed # Initial delay in microseconds
min_delay = 1_000_000 // max_speed # Delay at maximum speed
acceleration_step = acceleration / current_speed # Dynamic acceleration step
for step in range(steps_to_move):
STEP_PIN.high()
utime.sleep_us(int(delay))
STEP_PIN.low()
utime.sleep_us(int(delay))
# Accelerate during the first half
if step < steps_to_move // 2 and delay > min_delay:
delay -= acceleration_step
# Decelerate during the second half
elif step >= steps_to_move // 2 and delay < (1_000_000 // 100): # Minimum safe speed
delay += acceleration_step
current_position = target_steps
def case1():
lcd.clear()
lcd.putstr("Case 1 executed")
return "Case 1 executed"
def case2():
lcd.clear()
lcd.putstr("Case 2 executed")
return "Case 2 executed"
def case3():
lcd.clear()
lcd.putstr("Case 3 executed")
return "Case 3 executed"
def default_case():
lcd.clear()
lcd.putstr("Default case")
return "Default case executed"
def switch_case(value):
global count, entered_value
if not entered_value.strip(): # Ensure entered_value is not empty
entered_value = "0"
switch = {
1: case1,
2: case2,
3: case3,
}
# Reset count if it reaches 3
if count == 3:
count = 0
return switch.get(value, default_case)()
# Main Loop
lcd.clear()
lcd.putstr("Olcu:")
while True:
key = read_keypad()
if key:
if key.isdigit():
entered_value += key
lcd.clear()
lcd.putstr(f"Olcu:{entered_value}")
elif key == 'A' and entered_value.isdigit():
target_steps = int(entered_value)
lcd.clear()
lcd.putstr(f"Hareket: {target_steps}")
lcd.move_to(0, 1)
lcd.putstr(f"Siper: {current_position}")
move_stepper(target_steps, max_speed=max_speed, acceleration=acceleration)
entered_value = ""
sleep(0.5)
lcd.clear()
lcd.putstr(f"Siper: {current_position}")
elif key == 'C':
entered_value = ""
lcd.clear()
lcd.putstr("Olcu:")
lcd.putstr(f"Siper: {current_position}")
elif key == 'B' and entered_value.isdigit():
current_position = int(entered_value)
entered_value = ""
lcd.clear()
lcd.putstr("Olcu:")
lcd.putstr(f"Siper: {current_position}")
elif key == '#' and (not entered_value.strip() or entered_value.isdigit()):
count += 1 # Increment the count
switch_case(count)
sleep(0.1)