Transition to async

This commit is contained in:
Nils Schulte 2020-03-18 20:37:21 +01:00
parent cf44bc80f4
commit 78de42a4e2
5 changed files with 124 additions and 52 deletions

30
Button.py Normal file
View File

@ -0,0 +1,30 @@
import machine
import time
class Button():
def __init__(self,pin,onPushDown = None, onPushUp = None,debounceTimeMs = 50,inputMode = machine.Pin.IN,inverted = False):
self.pin = machine.Pin(pin,inputMode)
self.pressedTime = -debounceTimeMs
self.debounceTimeMs = int(debounceTimeMs)
self.onPushDown = onPushDown
self.onPushUp = onPushUp
self.pin.irq(trigger=machine.Pin.IRQ_RISING|machine.Pin.IRQ_FALLING , handler=self._IRQ)
self.value = self.pin.value()
self.inverted = inverted
def _IRQ(self,p):
new_value = self.pin.value()
if (self.value != new_value):
self.value = new_value
time_ms = time.ticks_ms()
if ((self.pressedTime+self.debounceTimeMs) < time_ms):
self.pressedTime = time_ms
if (new_value ^ self.inverted):
if (self.onPushUp != None):
self.onPushUp()
else:
if (self.onPushDown != None):
self.onPushDown()
else:
pass

View File

@ -22,6 +22,8 @@ Pin (ESP32)| Function
## Reference
[L298M H-Bridge](https://www.instructables.com/id/Control-DC-and-stepper-motors-with-L298N-Dual-Moto/)
[DS3231 RTC](https://github.com/micropython-Chinese-Community/mpy-lib/tree/master/misc/DS3231)
[NodeMCU-32S Pinout](https://www.shenzhen2u.com/NodeMCU-32S)
[ESP32 Usable Pins](https://randomnerdtutorials.com/esp32-pinout-reference-gpios/)

View File

@ -1,23 +1,31 @@
import StepperL298M
import time
import uasyncio as asyncio
class StepperClock:
def __init__(self,stepperHour,stepperMin):
self._stepperMinute = stepperMin
self._stepperHour = stepperHour
self.started_async = False
def start(self):
if not self.started_async:
self.started_async = True
self._stepperMinute.start()
self._stepperHour.start()
loop = asyncio.get_event_loop()
loop.create_task(self._update_async())
async def _update_async(self):
while(True):
await asyncio.sleep(1)
self.update()
def update(self):
hour = time.localtime()[3]
minute = time.localtime()[4]
self._stepperHour.rotateTo(hour/60)
self._stepperMinute.rotateTo(minute/60)
self._stepperHour.update()
self._stepperMinute.update()
def waitForStillstand(self):
while not (self._stepperHour.isAtTarget() or self._stepperMinute.isAtTarget()):
self._stepperHour.update()
self._stepperMinute.update()
time.sleep(0.1)
self._stepperHour.rotateTo(1-((hour%12)/12+minute/(12*60)))
self._stepperMinute.rotateTo(1-minute/60)
def disablePower(self):
self._stepperHour.disablePower()

View File

@ -1,16 +1,27 @@
from machine import Pin
import time
import uasyncio as asyncio
stepping = [[1,0,1,0],[1,0,0,0],[1,0,0,1],[0,0,0,1],[0,1,0,1],[0,1,0,0],[0,1,1,0],[0,0,1,0]]
class Stepper:
def __init__(self,pins,stepsPerRev=400):
def __init__(self,pins,stepsPerRev=400,stepDurationMs=50,inverted=False):
self._pins = [Pin(p, Pin.OUT) for p in pins]
self.stepnum = 0
self.rotDirection = 1
self.rotTarget = 0
self.stepDuration = 0.05
self._rotTarget = 0
self.stepDurationMs = stepDurationMs
self._speedMs = 0
self._lastStepTime = time.time()
self.stepsPerRev=stepsPerRev
self.started_async = False
self.inverted = inverted
def start(self):
if not self.started_async:
self.started_async = True
loop = asyncio.get_event_loop()
loop.create_task(self._update_async())
def _setPins(self,level):
self._pins[0].value(level[0])
@ -18,37 +29,41 @@ class Stepper:
self._pins[2].value(level[2])
self._pins[3].value(level[3])
def doSteppsBlock(self,num,speed=0.05):
for i in range(num):
self.stepnum = (self.stepnum + 1)
self._setPins(stepping[self.stepnum%8])
time.sleep(speed)
self.disablePower()
def getStepsToTarget(self):
return ((self._rotTarget - self.stepnum)*self.rotDirection)%self.stepsPerRev
def rotateTo(self, target,direction=0):
def rotateTo(self, target,duration=0,direction=0):
"""sets the rotation target and (if direction == 0) calculates if
it should rotate left or right"""
self.rotTarget = int(target*self.stepsPerRev) % self.stepsPerRev
self._rotTarget = int(target*self.stepsPerRev) % self.stepsPerRev
if not self.isAtTarget():
if (direction == 0):
self.rotDirection = 1 if (self.stepnum- self.rotTarget)%self.stepsPerRev \
> self.stepsPerRev/2 else 0
self.rotDirection = 1 if (self._rotTarget - self.stepnum)%self.stepsPerRev \
< self.stepsPerRev/2 else -1
else:
self.rotDirection = direction
self._speedMs = max(int(self.stepDurationMs),duration*1000/self.getStepsToTarget())
def update(self):
if (self.rotTarget%self.stepsPerRev != self.stepnum%self.stepsPerRev) \
and not self.isMoving():
self._lastStepTime = time.ticks_ms()
async def _update_async(self):
while(True):
await asyncio.sleep_ms(self.stepDurationMs)
if not self.isAtTarget():
self._update()
else:
self.disablePower()
def _update(self):
self.stepnum = (self.stepnum + self.rotDirection) % self.stepsPerRev
self._setPins(stepping[self.stepnum%8])
#time.sleep(speed)
self._setPins(stepping[(self.stepnum%8) if not self.inverted else ((8-self.stepnum)%8)])
def disablePower(self):
self._setPins([0,0,0,0])
def isMoving(self):
return time.ticks_diff(time.ticks_ms(), self._lastStepTime) <= self.stepDuration
def getOrientation(self):
return self.stepnum / self.stepsPerRev
def getTarget(self):
return (self._rotTarget / self.stepsPerRev)
def isAtTarget(self):
return (not self.isMoving()) \
and (self.rotTarget%self.stepsPerRev == self.stepnum%self.stepsPerRev)
return (self._rotTarget%self.stepsPerRev == self.stepnum%self.stepsPerRev)

47
main.py
View File

@ -1,24 +1,41 @@
import time
import machine
import DS3231
import Button
import uasyncio as asyncio
import StepperL298M
import StepperClock
#Async
loop = asyncio.get_event_loop()
#Initialise the time module with the RTC
dsRtc = DS3231.DS3231(machine.I2C(sda = machine.Pin(17), scl=machine.Pin(18)))
rtc = machine.RTC()
rtc.init(dsRtc.DateTime()+[0])
#while(True):
# print(rtc.DateTime())
# time.sleep(0.1)
# pass
#import StepperL298M
#import StepperClock
#stepperminu = StepperL298M.Stepper([12,27,26,25],stepsPerRev=408)
#stepperhour = StepperL298M.Stepper([19,21,22,23])
#clock = StepperClock.StepperClock(stepperhour,stepperminu)
#Initalise the Motors
stepperminu = StepperL298M.Stepper([19,21,22,23],inverted=False)
stepperhour = StepperL298M.Stepper([12,27,26,25],inverted=True)
clock = StepperClock.StepperClock(stepperhour,stepperminu)
#while(True):
# clock.update()
# clock.waitForStillstand()
# clock.disablePower()
# time.sleep(0.1)
LED = machine.Pin(32,machine.Pin.OUT)
def leftButtonClick():
global i
print("Down",LED.value())
LED.value(not LED.value())
stepperhour.rotateTo(stepperhour.getTarget()+0.1)
Button.Button(36,leftButtonClick,None,inverted=True)
def rightButtonClick():
global i
print("Down",LED.value())
LED.value(not LED.value())
stepperhour.rotateTo(stepperhour.getTarget()-0.2)
Button.Button(34,rightButtonClick,None,inverted=True)
clock.start()
loop.run_forever()