rpm sensor+pwm is working in a slightly cursed way
This commit is contained in:
parent
b8a7f23f30
commit
38ea428824
1 changed files with 122 additions and 26 deletions
148
src/main.py
148
src/main.py
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue