added Screens
This commit is contained in:
parent
d95bfb212d
commit
ca058725e8
@ -39,4 +39,4 @@ class Button():
|
||||
pass
|
||||
|
||||
def isPushed(self):
|
||||
return self.pin.value() ^ self.inverted
|
||||
return not (self.pin.value() ^ self.inverted)
|
69
Buzzer.py
Normal file
69
Buzzer.py
Normal file
@ -0,0 +1,69 @@
|
||||
import machine
|
||||
import uasyncio as asyncio
|
||||
|
||||
|
||||
c = 261 #Hz
|
||||
d = 294 #Hz
|
||||
e = 329 #Hz
|
||||
f = 349 #Hz
|
||||
g = 392 #Hz
|
||||
a = 440 #Hz
|
||||
b = 493 #Hz
|
||||
C = 523 #Hz
|
||||
|
||||
# (Duration,Freq)
|
||||
# If Last Duration is None play endlessly
|
||||
# 0: Silent
|
||||
# 1: BeepBeep
|
||||
# 2: Alle Meine Entchen
|
||||
SOUNDS = [((0,None),),\
|
||||
((700,1000),(100,None),(600,1000)),\
|
||||
((400,c),(100,None),(400,d),(100,None),(400,e),(100,None),(400,f),(100,None),\
|
||||
(900,g),(100,None),(900,g),(100,None),(400,a),(100,None),(400,a),(100,None),\
|
||||
(400,a),(100,None),(400,a),(100,None),(1900,g),(100,None),(400,a),(100,None),\
|
||||
(400,a),(100,None),(400,a),(100,None),(400,a),(100,None),(1900,g),(100,None),\
|
||||
(400,f),(100,None),(400,f),(100,None),(400,f),(100,None),(400,f),(100,None),\
|
||||
(900,e),(100,None),(900,e),(100,None),(400,d),(100,None),(400,d),(100,None),\
|
||||
(400,d),(100,None),(400,d),(100,None),(2000,c))]#,(None,None)
|
||||
|
||||
class Buzzer():
|
||||
def __init__(self,pin,duty = 100):
|
||||
self._pwm = machine.PWM(machine.Pin(2), freq=0, duty=0)
|
||||
self.sound = None
|
||||
self.duty = duty
|
||||
self.newSound = True
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(self._update_async())
|
||||
|
||||
async def _update_async(self):
|
||||
while True:
|
||||
if self.sound == None:
|
||||
await asyncio.sleep_ms(200)
|
||||
self._pwm.duty(0)
|
||||
else:
|
||||
self.newSound = False
|
||||
for i in range(len(self.sound)):
|
||||
s = self.sound[i]
|
||||
if s[0] == None:
|
||||
i = 0
|
||||
if (s[1] != None):
|
||||
self._pwm.freq(s[1])
|
||||
self._pwm.duty(self.duty)
|
||||
else:
|
||||
self._pwm.duty(0)
|
||||
await asyncio.sleep_ms(s[0])
|
||||
if self.newSound:
|
||||
break
|
||||
if (not self.newSound):
|
||||
self.sound = None
|
||||
self.newSound = False
|
||||
|
||||
def playSound(self,sound):
|
||||
self.newSound = True
|
||||
self.sound = sound
|
||||
|
||||
def stop(self):
|
||||
self.sound = None
|
||||
|
||||
def isPlaying(self):
|
||||
return self.sound == None
|
31
HousingLEDs.py
Normal file
31
HousingLEDs.py
Normal file
@ -0,0 +1,31 @@
|
||||
import uasyncio as asyncio
|
||||
import machine
|
||||
import neopixel
|
||||
|
||||
class LEDs():
|
||||
def __init__(self, pin):
|
||||
self.neop = neopixel.NeoPixel(machine.Pin(pin, machine.Pin.OUT),5)
|
||||
self.rate = 0
|
||||
self.clear()
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(self._update_async())
|
||||
|
||||
async def _update_async(self):
|
||||
while True:
|
||||
if self.rate <= 0:
|
||||
await asyncio.sleep_ms(200)
|
||||
else:
|
||||
self.toggle()
|
||||
await asyncio.sleep_ms(int(500 / self.rate))
|
||||
|
||||
def fill(self,color):
|
||||
self.neop.fill(color)
|
||||
self.neop.write()
|
||||
|
||||
def clear(self):
|
||||
self.fill((0,0,0))
|
||||
|
||||
def upper(self,color):
|
||||
self.neop[3] = color
|
||||
self.neop.write()
|
||||
|
40
LED.py
Normal file
40
LED.py
Normal file
@ -0,0 +1,40 @@
|
||||
import uasyncio as asyncio
|
||||
import machine
|
||||
|
||||
class LED():
|
||||
def __init__(self, pin):
|
||||
self.pin = machine.Pin(pin,machine.Pin.OUT)
|
||||
self.rate = 0
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(self._update_async())
|
||||
|
||||
async def _update_async(self):
|
||||
while True:
|
||||
if self.rate <= 0:
|
||||
await asyncio.sleep_ms(200)
|
||||
else:
|
||||
self.toggle()
|
||||
await asyncio.sleep_ms(int(500 / self.rate))
|
||||
|
||||
def toggle(self):
|
||||
self.pin.value(not self.pin.value())
|
||||
|
||||
def flash(self, rate):
|
||||
"""rate:\t flashing speed in Herz"""
|
||||
self.rate = rate
|
||||
|
||||
def on(self,overwriteFlashing=True):
|
||||
self.pin.on()
|
||||
if overwriteFlashing:
|
||||
self.rate = 0
|
||||
|
||||
def off(self,overwriteFlashing=True):
|
||||
self.pin.off()
|
||||
if overwriteFlashing:
|
||||
self.rate = 0
|
||||
|
||||
def value(self,value=None):
|
||||
if value!=None:
|
||||
self.pin.value(value)
|
||||
return self.pin.value()
|
||||
|
121
Screens.py
Normal file
121
Screens.py
Normal file
@ -0,0 +1,121 @@
|
||||
import StepperClock
|
||||
import uasyncio as asyncio
|
||||
import Buzzer
|
||||
import Settings
|
||||
|
||||
class ClockScreen():
|
||||
|
||||
def __init__(self,stepperhour,stepperminu,buttons,leds):
|
||||
self.clock = StepperClock.StepperClock(stepperhour,stepperminu)
|
||||
self.running = False
|
||||
self.buttons = buttons
|
||||
self.leds = leds
|
||||
|
||||
def stopIfAllPressed(self,button):
|
||||
self.leds[button].on()
|
||||
for b in self.buttons:
|
||||
if not b.isPushed():
|
||||
break
|
||||
else:
|
||||
self.running = False
|
||||
|
||||
def __await__(self):
|
||||
for i,b in enumerate(self.buttons):
|
||||
b.setCallbacks(onPushDown=lambda i=i:self.stopIfAllPressed(i),onPushUp=lambda i=i:self.leds[i].off())
|
||||
self.running = True
|
||||
self.clock.start()
|
||||
while self.running:
|
||||
await asyncio.sleep_ms(200)
|
||||
self.clock.stop()
|
||||
__iter__ = __await__ # https://github.com/micropython/micropython/issues/2678
|
||||
|
||||
class SettingsScreen():
|
||||
|
||||
def __init__(self,stepperhour,stepperminu,buttons,leds,housingLEDs,buzzer):
|
||||
self.stepperminu = stepperminu
|
||||
self.stepperhour = stepperhour
|
||||
self.running = False
|
||||
self.buttons = buttons
|
||||
self.leds = leds
|
||||
self.housingLEDs = housingLEDs
|
||||
self.buzzer = buzzer
|
||||
|
||||
# TODO load these form file
|
||||
|
||||
def onButtonPressed(self,button):
|
||||
self.leds[button].on(overwriteFlashing=False)
|
||||
for b in self.buttons:
|
||||
if not b.isPushed():
|
||||
break
|
||||
else:
|
||||
self.running = False
|
||||
return
|
||||
if not self.buttons[1].isPushed():
|
||||
if button == 0 :
|
||||
if self.mode == 0:
|
||||
self.stepperminu.rotateTo(direction=1)
|
||||
if self.mode == 1:
|
||||
self.stepperhour.rotateTo(direction=1)
|
||||
elif button == 2:
|
||||
if self.mode == 0:
|
||||
self.stepperminu.rotateTo(direction=-1)
|
||||
if self.mode == 1:
|
||||
self.stepperhour.rotateTo(direction=-1)
|
||||
|
||||
def onButtonReleased(self,button):
|
||||
self.leds[button].off(overwriteFlashing=False)
|
||||
if button == 0:#left
|
||||
if self.mode == 0 or self.mode == 1:
|
||||
self.stepperminu.stop()
|
||||
self.stepperhour.stop()
|
||||
if self.mode == 3:
|
||||
Settings.selectedSound =(Settings.selectedSound -1) % len(Buzzer.SOUNDS)
|
||||
self.buzzer.playSound(Buzzer.SOUNDS[Settings.selectedSound ])
|
||||
elif button == 2:#right
|
||||
if self.mode == 0 or self.mode == 1:
|
||||
self.stepperminu.stop()
|
||||
self.stepperhour.stop()
|
||||
if self.mode == 3:
|
||||
Settings.selectedSound =(Settings.selectedSound +1) % len(Buzzer.SOUNDS)
|
||||
self.buzzer.playSound(Buzzer.SOUNDS[Settings.selectedSound ])
|
||||
elif button == 1: #middle
|
||||
self.mode=(self.mode+1)%4
|
||||
if self.mode == 3:
|
||||
self.buzzer.playSound(Buzzer.SOUNDS[Settings.selectedSound ])
|
||||
else:
|
||||
self.buzzer.stop()
|
||||
|
||||
if self.mode == 2:
|
||||
self.leds[0].flash(0.7)
|
||||
self.leds[1].flash(0.7)
|
||||
self.leds[2].flash(0.7)
|
||||
else:
|
||||
self.leds[0].off()
|
||||
self.leds[1].off()
|
||||
self.leds[2].off()
|
||||
|
||||
if self.mode == 0 or self.mode == 1:
|
||||
self.housingLEDs.upper((50,50,50))
|
||||
else:
|
||||
self.housingLEDs.clear()
|
||||
|
||||
def __await__(self):
|
||||
self.mode = 0
|
||||
self.stepperminu.rotateTo(0)
|
||||
self.stepperhour.rotateTo(0)
|
||||
while not self.stepperhour.isAtTarget() or not self.stepperminu.isAtTarget():
|
||||
await asyncio.sleep_ms(200)
|
||||
self.housingLEDs.upper((50,50,50))
|
||||
for led in self.leds:
|
||||
led.off()
|
||||
for i,b in enumerate(self.buttons):
|
||||
b.setCallbacks(onPushDown=lambda i=i:self.onButtonPressed(i),onPushUp=lambda i=i:self.onButtonReleased(i))
|
||||
self.running = True
|
||||
while self.running:
|
||||
await asyncio.sleep_ms(200)
|
||||
for led in self.leds:
|
||||
led.off()
|
||||
self.housingLEDs.clear()
|
||||
self.stepperhour.reset()
|
||||
self.stepperminu.reset()
|
||||
__iter__ = __await__ # https://github.com/micropython/micropython/issues/2678
|
2
Settings.py
Normal file
2
Settings.py
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
selectedSound = 0
|
@ -12,8 +12,6 @@ class StepperClock:
|
||||
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())
|
||||
|
||||
|
@ -7,22 +7,20 @@ 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
|
||||
class Stepper:
|
||||
def __init__(self,pins,stepsPerRev=400,stepDurationMs=10,inverted=False):
|
||||
self._pins = [Pin(p, Pin.OUT) for p in pins]
|
||||
self.stepnum = 0
|
||||
self.rotDirection = 1
|
||||
self._rotTarget = 0
|
||||
self.reset()
|
||||
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 reset(self):
|
||||
self.stepnum = 0
|
||||
self._rotTarget = 0
|
||||
self.rotDirection = 0
|
||||
|
||||
def _setPins(self,level):
|
||||
self._pins[0].value(level[0])
|
||||
self._pins[1].value(level[1])
|
||||
@ -33,9 +31,15 @@ class Stepper:
|
||||
#return ((self._rotTarget - self.stepnum)*self.rotDirection)%self.stepsPerRev
|
||||
return ((self._rotTarget - self.stepnum)*self.rotDirection)
|
||||
|
||||
def rotateTo(self, target,duration=0,direction=0,normalise = True):
|
||||
def rotateTo(self, target=None,duration=0,direction=0,normalise = True):
|
||||
"""sets the rotation target and (if direction == 0) calculates if
|
||||
it should rotate left or right"""
|
||||
it should rotate left or right.
|
||||
If target is None moves infinitely in direction
|
||||
(if direction is 0 then hold position with power)."""
|
||||
if target == None:
|
||||
self._rotTarget = None
|
||||
self.rotDirection = direction
|
||||
else:
|
||||
self._rotTarget = int(target*self.stepsPerRev)
|
||||
if normalise:
|
||||
rotTargetNorm = self._rotTarget%self.stepsPerRev
|
||||
@ -45,7 +49,6 @@ class Stepper:
|
||||
self._rotTarget-=self.stepsPerRev
|
||||
elif(self._rotTarget-self.stepnum) < -self.stepsPerRev/2:
|
||||
self._rotTarget+=self.stepsPerRev
|
||||
|
||||
if not self.isAtTarget():
|
||||
if (direction == 0):
|
||||
self.rotDirection = 1 if (self._rotTarget > self.stepnum) else -1
|
||||
@ -53,12 +56,16 @@ class Stepper:
|
||||
self.rotDirection = direction
|
||||
self._speedMs = max(int(self.stepDurationMs),duration*1000/self.getStepsToTarget())
|
||||
|
||||
def stop(self):
|
||||
self._rotTarget = self.stepnum
|
||||
|
||||
async def _update_async(self):
|
||||
while(True):
|
||||
await asyncio.sleep_ms(self.stepDurationMs)
|
||||
if not self.isAtTarget():
|
||||
self._update()
|
||||
else:
|
||||
self.rotDirection = 0
|
||||
self.disablePower()
|
||||
|
||||
def _update(self):
|
||||
|
96
main.py
96
main.py
@ -1,11 +1,14 @@
|
||||
import time
|
||||
import machine
|
||||
import uasyncio as asyncio
|
||||
import DS3231
|
||||
import Button
|
||||
import uasyncio as asyncio
|
||||
import LED
|
||||
import HousingLEDs
|
||||
import Buzzer
|
||||
import StepperL298M
|
||||
import StepperClock
|
||||
import neopixel
|
||||
|
||||
import Screens
|
||||
|
||||
#Async
|
||||
loop = asyncio.get_event_loop()
|
||||
@ -18,69 +21,36 @@ try:
|
||||
except:
|
||||
print("Error on DS3231-Inititalisation")
|
||||
|
||||
housingLEDs = neopixel.NeoPixel(machine.Pin(16, machine.Pin.OUT),5)
|
||||
housingLEDs.fill((0,0,0))
|
||||
housingLEDs.write()
|
||||
|
||||
Buzzer = machine.PWM(machine.Pin(2), freq=10000, duty=0)
|
||||
#Init Buzzer
|
||||
buzzer = Buzzer.Buzzer(pin=2)
|
||||
|
||||
#Initalise the Motors
|
||||
stepDurationMs = 8
|
||||
stepperminu = StepperL298M.Stepper([19,21,22,23],inverted=False,stepDurationMs=stepDurationMs)
|
||||
stepperhour = StepperL298M.Stepper([12,27,26,25],inverted=True, stepDurationMs=stepDurationMs)
|
||||
stepperminu = StepperL298M.Stepper([19,21,22,23],inverted=False)
|
||||
stepperhour = StepperL298M.Stepper([12,27,26,25],inverted=True)
|
||||
|
||||
#Init LEDs
|
||||
housingLEDs = HousingLEDs.LEDs(pin=16)
|
||||
|
||||
leftButtonLED = LED.LED(13)
|
||||
middleButtonLED = LED.LED(33)
|
||||
rightButtonLED = LED.LED(32)
|
||||
|
||||
#Init Buttons
|
||||
leftButton = Button.Button(pin=34,inverted=True)
|
||||
middleButton = Button.Button(pin=39,inverted=True)
|
||||
rightButton = Button.Button(pin=36,inverted=True)
|
||||
|
||||
|
||||
leftButtonLED = machine.Pin(32,machine.Pin.OUT)
|
||||
middleButtonLED = machine.Pin(33,machine.Pin.OUT)
|
||||
rightButtonLED = machine.Pin(13,machine.Pin.OUT)
|
||||
buttons = (leftButton,middleButton,rightButton)
|
||||
leds = (leftButtonLED,middleButtonLED,rightButtonLED)
|
||||
|
||||
modus = 0
|
||||
screens = (Screens.ClockScreen(stepperhour,stepperminu,buttons,leds),\
|
||||
Screens.SettingsScreen(stepperhour,stepperminu,buttons,leds,housingLEDs,buzzer))
|
||||
async def run_screens():
|
||||
global modus,screens
|
||||
while True:
|
||||
await screens[modus%len(screens)]
|
||||
modus += 1
|
||||
|
||||
clock = StepperClock.StepperClock(stepperhour,stepperminu)
|
||||
|
||||
|
||||
def leftButtonClickDown():
|
||||
leftButtonLED.on()
|
||||
def leftButtonClickUp():
|
||||
leftButtonLED.off()
|
||||
def leftButtonClick():
|
||||
if(clock.isRunning()):
|
||||
stepperminu.stepnum = (stepperminu.stepnum+8)%stepperminu.stepsPerRev
|
||||
else:
|
||||
stepperminu.rotateTo(stepperminu.getOrientation()+0.25)
|
||||
leftButton = Button.Button(pin=36,onPushDown=leftButtonClickDown,onPushUp=leftButtonClickUp,onClick=leftButtonClick,inverted=True)
|
||||
|
||||
def rightButtonClickDown():
|
||||
rightButtonLED.on()
|
||||
def rightButtonClickUp():
|
||||
rightButtonLED.off()
|
||||
def rightButtonClick():
|
||||
if(clock.isRunning()):
|
||||
stepperminu.stepnum = (stepperminu.stepnum+8)%stepperminu.stepsPerRev
|
||||
else:
|
||||
stepperminu.rotateTo(stepperminu.getOrientation()-0.25)
|
||||
|
||||
rightButton = Button.Button(pin=34,onPushDown=rightButtonClickDown,onPushUp=rightButtonClickUp,onClick=rightButtonClick,inverted=True)
|
||||
|
||||
def middleButtonClickDown():
|
||||
pass
|
||||
def middleButtonClickUp():
|
||||
pass
|
||||
def middleButtonClick():
|
||||
middleButtonLED.value(not middleButtonLED.value())
|
||||
if middleButtonLED.value():
|
||||
clock.stop()
|
||||
stepperminu.rotateTo(0)
|
||||
stepperhour.rotateTo(0)
|
||||
housingLEDs.fill((255,0,255))
|
||||
housingLEDs.write()
|
||||
else:
|
||||
clock.start()
|
||||
housingLEDs.fill((0,0,0))
|
||||
housingLEDs.write()
|
||||
middleButton = Button.Button(pin=39,onPushDown=middleButtonClickDown,onPushUp=middleButtonClickUp,onClick=middleButtonClick,inverted=True)
|
||||
|
||||
|
||||
|
||||
clock.start()
|
||||
|
||||
loop.run_forever()
|
||||
loop.run_until_complete(run_screens())
|
Loading…
x
Reference in New Issue
Block a user