rpm sensor+pwm is working in a slightly cursed way

This commit is contained in:
Robert Schauklies 2025-11-02 00:02:25 +01:00
parent b8a7f23f30
commit 38ea428824

View file

@ -1,7 +1,7 @@
# test of printing multiple fonts to the ILI9341 on an M5Stack using H/W SP # test of printing multiple fonts to the ILI9341 on an M5Stack using H/W SP
# MIT License; Copyright (c) 2017 Jeffrey N. Magee # MIT License; Copyright (c) 2017 Jeffrey N. Magee
from ili934xnew import ILI9341, color565 from ili934xnew import ILI9341, color565
from machine import Pin, SPI,Timer from machine import Pin, SPI,Timer, UART,PWM
from ST7735 import TFT,TFTColor from ST7735 import TFT,TFTColor
import m5stack import m5stack
import tt14 import tt14
@ -80,7 +80,7 @@ def fafo():
for col in range(w): for col in range(w):
bgr = f.read(3) bgr = f.read(3)
tft._pushcolor(TFTColor(bgr[2],bgr[1],bgr[0])) tft._pushcolor(TFTColor(bgr[2],bgr[1],bgr[0]))
time.sleep(10) time.sleep(5)
def tftprinttest(): def tftprinttest():
tft.fill(TFT.BLACK) tft.fill(TFT.BLACK)
v = 30 v = 30
@ -155,17 +155,17 @@ def draw_rpm(rpm):
def deposit_view(state, rotary): def deposit_view(state, rotary):
# display.fill_rect(0, 0, 127, 14, 1) # display.fill_rect(0, 0, 127, 14, 1)
display.text("Deposit") display.print("Deposit")
draw_rpm(state["rpm"]) draw_rpm(state["rpm"])
display.text("Press to") display.print("Press to")
display.text("continue") display.print("continue")
def coating_view(state, rotary): def coating_view(state, rotary):
# display.fill_rect() # display.fill_rect()
display.text("Coating") display.print("Coating")
draw_rpm(state["rpm"]) draw_rpm(state["rpm"])
display.text("{: >{w}} sec".format(state["timer"], w=4)) display.print("{: >{w}} sec".format(state["timer"], w=4))
def decode_ESC_telemetry(data, motor_poles=14): def decode_ESC_telemetry(data, motor_poles=14):
@ -201,7 +201,7 @@ async def update_display():
global state global state
global rotary global rotary
while True: while True:
display.fill(color565(0,0,0)) display.print("LOLOLOL")
state["view"](state, rotary) state["view"](state, rotary)
await uasyncio.sleep_ms(200) await uasyncio.sleep_ms(200)
@ -210,7 +210,7 @@ async def update_motor():
global state global state
#we want to use 18 for the SPI-Bus! #we want to use 18 for the SPI-Bus!
#https://docs.micropython.org/en/latest/esp32/quickref.html#hardware-spi-bus #https://docs.micropython.org/en/latest/esp32/quickref.html#hardware-spi-bus
dshot = Dshot(pin=Pin(26)) dshot = Dshot(pin=Pin(25))
rpm_pid = PID( rpm_pid = PID(
Kp=config["PID"]["Kp"], Kp=config["PID"]["Kp"],
Ki=config["PID"]["Ki"], Ki=config["PID"]["Ki"],
@ -229,14 +229,14 @@ async def update_motor():
if telemetry is not None: if telemetry is not None:
state["rpm"] = telemetry[5] state["rpm"] = telemetry[5]
throttle = rpm_pid(state["rpm"]) throttle = rpm_pid(state["rpm"])
# print( print(
# "Throttle:", "Throttle:",
# throttle, throttle,
# "pid components:", "pid components:",
# rpm_pid.components, rpm_pid.components,
# "RPM:", "RPM:",
# state["rpm"], state["rpm"],
# ) )
if state["target_rpm"] == 0 and state["rpm"] < 1000: if state["target_rpm"] == 0 and state["rpm"] < 1000:
throttle = 0 throttle = 0
@ -244,13 +244,87 @@ async def update_motor():
dshot.set_throttle(throttle) dshot.set_throttle(throttle)
await uasyncio.sleep_ms(1) await uasyncio.sleep_ms(1)
def update_motor_pwm():
pwm = PWM(Pin(26))
rpm_pid = PID(
Kp=config["PID"]["Kp"],
Ki=config["PID"]["Ki"],
Kd=config["PID"]["Kd"],
setpoint=0,
sample_time=None,
output_limits=(0.0, 1.0),
# proportional_on_measurement=True,
)
pwm.freq(50)
# pwm.duty_u16(1638)
# pwm.duty_u16(8192)
# set_throttle(pwm,1055)
pwm.duty_ns(1055*10**3)
time.sleep(1)
pwm.duty_ns(1070*10**3)
time.sleep(10)
global rpm_counter
rpm_counter= 0
pwm.duty_ns(1200*10**3)
time.sleep(10)
global rpm_counter
rpm_counter= 0
pwm.duty_ns(1400*10**3)
time.sleep(60)
pwm.duty_ns(1055*10**3)
# time.sleep(10) # keep low signal to arm
# # for i in range(1060,1800):
# # pwm.duty_u16(i*3)
# # time.sleep(1)
# pwm.duty_ns(1070*10**3)
# pwm.duty_u16(1700)
# time.sleep(200)
while True:
rpm_pid.setpoint = state["target_rpm"]
# read ESC telemetry
if uart.any() >= 10:
telemetry = decode_ESC_telemetry(uart.read())
if telemetry is not None:
state["rpm"] = telemetry[5]
throttle = rpm_pid(state["rpm"])
print(
"Throttle:",
throttle,
"pid components:",
rpm_pid.components,
"RPM:",
state["rpm"],
)
if state["target_rpm"] == 0 and state["rpm"] < 1000:
throttle = 0
rpm_pid.reset()
def set_throttle(pwm,us):
hertz = 50
#we now have to calculate the duty_cycle!
# Period defined as 1/Hertz, we need to multiply by 1_000_000 to calculate to microseconds
period = (1/hertz)*1000000
# us = max(1060, min(1860, us))
#our thing has to be one for x microseconds during the period!
duty_cycle_percentage = (us/period)*100
duty = int((duty_cycle_percentage/100))*65535
print(duty)
pwm.duty_u16(duty)
def debounce_button(p): def debounce_button(p):
p.irq(trigger=Pin.IRQ_FALLING, handler=None) # remove irq p.irq(trigger=Pin.IRQ_FALLING, handler=None) # remove irq
timer0 = Timer(0) timer0 = Timer(0)
timer0.init(period=20, mode=Timer.ONE_SHOT, callback=lambda t: on_button_press(p)) timer0.init(period=20, mode=Timer.ONE_SHOT, callback=lambda t: on_button_press(p))
rpm_counter = 0
def rpm_count(p):
global rpm_counter
rpm_counter+=1
def on_button_press(p): def on_button_press(p):
p.irq(trigger=Pin.IRQ_FALLING, handler=debounce_button) # restore irq p.irq(trigger=Pin.IRQ_FALLING, handler=debounce_button) # restore irq
@ -264,7 +338,6 @@ def on_button_press(p):
state["view"] = edit_deposit_view state["view"] = edit_deposit_view
rotary.set( rotary.set(
min_val=0, min_val=0,
max_val=1000,
range_mode=RotaryIRQ.RANGE_BOUNDED, range_mode=RotaryIRQ.RANGE_BOUNDED,
value=int(0.01 * config["deposit_rpm"]), value=int(0.01 * config["deposit_rpm"]),
) )
@ -285,6 +358,7 @@ def on_button_press(p):
if state["view"] == edit_coating_rpm_view: if state["view"] == edit_coating_rpm_view:
state["view"] = edit_coating_time_view state["view"] = edit_coating_time_view
rotary.set( rotary.set(
max_val=1000,
min_val=0, min_val=0,
max_val=9999, max_val=9999,
range_mode=RotaryIRQ.RANGE_BOUNDED, range_mode=RotaryIRQ.RANGE_BOUNDED,
@ -295,8 +369,8 @@ def on_button_press(p):
save_config() save_config()
rotary.set(min_val=0, max_val=1, range_mode=RotaryIRQ.RANGE_BOUNDED, value=0) rotary.set(min_val=0, max_val=1, range_mode=RotaryIRQ.RANGE_BOUNDED, value=0)
state["view"] = start_view state["view"] = start_view
return
if state["view"] == deposit_view: if state["view"] == deposit_view:
return
state["view"] = coating_view state["view"] = coating_view
start_coating(state) start_coating(state)
return return
@ -363,7 +437,6 @@ timer2 = Timer(2)
# CS CS # CS CS
# GND GND # GND GND
# VCC VCC # VCC VCC
print("BOOOOOOTTT2T")
spi = SPI( spi = SPI(
2, 2,
baudrate=40000000, baudrate=40000000,
@ -384,7 +457,7 @@ display = tft
tft.initr() tft.initr()
tft.rgb(True) tft.rgb(True)
#tftprinttest() #tftprinttest()
uart = UART(1, baudrate=115200, rx=5) # to receive ESC telemetry
rotary = RotaryIRQ( rotary = RotaryIRQ(
pin_num_clk=25, pin_num_clk=25,
pin_num_dt=13, pin_num_dt=13,
@ -395,6 +468,10 @@ rotary = RotaryIRQ(
) )
button = Pin(15, Pin.IN, Pin.PULL_UP) button = Pin(15, Pin.IN, Pin.PULL_UP)
button.irq(trigger=Pin.IRQ_FALLING, handler=on_button_press) button.irq(trigger=Pin.IRQ_FALLING, handler=on_button_press)
#interrupt for rpm sensor!
rpm_pin = Pin(19, Pin.IN, Pin.PULL_UP)
rpm_pin.irq(trigger=Pin.IRQ_FALLING, handler=rpm_count)
state = { state = {
"view": start_view, "view": start_view,
"rpm": 0, "rpm": 0,
@ -410,13 +487,32 @@ with open("config.json", "r") as f:
tft.fill(TFT.BLACK) tft.fill(TFT.BLACK)
# splash() # splash()
fafo() #fafo()
# for ff in fonts: # for ff in fonts:
# display.set_font(ff) # display.set_font(ff)
# display.print(text) # display.print(text)
event_loop = uasyncio.get_event_loop() update_motor_pwm()
event_loop.create_task(update_display()) print(rpm_counter)
# event_loop = uasyncio.get_event_loop()
# event_loop.create_task(update_display())
#event_loop.create_task(update_motor()) # event_loop.create_task(update_motor_pwm())
event_loop.run_forever() # event_loop.run_forever()
# pwm = PWM(Pin(26))
# rpm_pid = PID(
# Kp=config["PID"]["Kp"],
# Ki=config["PID"]["Ki"],
# Kd=config["PID"]["Kd"],
# setpoint=0,
# sample_time=None,
# output_limits=(0.0, 1.0),
# # proportional_on_measurement=True,
# )
# pwm.freq(50)
# # pwm.duty_u16(1638)
# # pwm.duty_u16(8192)
# # set_throttle(pwm,1055)
# pwm.duty_ns(1055*10**3)
# time.sleep(3)
# pwm.duty_ns(1070*10**3)