abstracted Numberpicker

This commit is contained in:
Nils Schulte 2020-03-23 10:46:23 +01:00
parent ed30bf42d9
commit d5be06edcd
8 changed files with 333 additions and 103 deletions

View File

@ -24,13 +24,13 @@ ALARMTONES = (((300,1200),(100,None),(200,1200),(300,None),(None,10)),
((400,c),(100,None),(400,d),(100,None),(400,e),(100,None),(400,f),(100,None),\ ((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),\ (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),(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,a),(100,None),(400,a),(100,None),(400,a),(100,None),(1600,g),(100,None),\
(400,f),(100,None),(400,f),(100,None),(400,f),(100,None),(400,f),(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),\ (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)),) (400,d),(100,None),(400,d),(100,None),(1600,c)),)
class Buzzer(): class Buzzer():
def __init__(self,pin,duty = 100): def __init__(self,pin,duty = 1000):
self._pwm = machine.PWM(machine.Pin(2), freq=0, duty=0) self._pwm = machine.PWM(machine.Pin(2), freq=0, duty=0)
self.sound = None self.sound = None
self.duty = duty self.duty = duty
@ -46,7 +46,7 @@ class Buzzer():
else: else:
self.newSound = False self.newSound = False
timesPlayed = 0 timesPlayed = 0
print("Play sound!") #print("Play sound!")
for i in range(len(self.sound)): for i in range(len(self.sound)):
s = self.sound[i] s = self.sound[i]
if s[0] == None: if s[0] == None:
@ -56,8 +56,8 @@ class Buzzer():
i = 0 i = 0
timesPlayed += 1 timesPlayed += 1
if (s[1] != None): if (s[1] != None):
#self._pwm.freq(s[1]) self._pwm.freq(s[1])
#self._pwm.duty(self.duty) self._pwm.duty(self.duty)
pass pass
else: else:
self._pwm.duty(0) self._pwm.duty(0)

View File

@ -5,7 +5,7 @@ import StepperL298M
import HousingLEDs import HousingLEDs
import LED import LED
import Button import Button
import HousingCapButton
#Initialise the time module with the RTC #Initialise the time module with the RTC
try: try:
@ -34,6 +34,7 @@ leftButton = Button.Button(pin=34,inverted=True)
middleButton = Button.Button(pin=39,inverted=True) middleButton = Button.Button(pin=39,inverted=True)
rightButton = Button.Button(pin=36,inverted=True) rightButton = Button.Button(pin=36,inverted=True)
housingButton = HousingCapButton.HousingCapButton(pin=15)
buttons = (leftButton,middleButton,rightButton) buttons = (leftButton,middleButton,rightButton)
leds = (leftButtonLED,middleButtonLED,rightButtonLED) leds = (leftButtonLED,middleButtonLED,rightButtonLED)

23
HousingCapButton.py Normal file
View File

@ -0,0 +1,23 @@
import uasyncio as asyncio
import machine
import Hardware as HW
class HousingCapButton():
def __init__(self, pin):
self.tp = machine.TouchPad(machine.Pin(15))
reading = self.tp.read()
self.value_avrg = [reading]*3
self.value_avrg2 = [reading]*4
loop = asyncio.get_event_loop()
#loop.create_task(self._update_async())
async def _update_async(self):
while True:
await asyncio.sleep_ms(100)
reading = self.tp.read()
self.value_avrg = [reading*(10**-i) + (1-(10**-i))*v for i,v in enumerate(self.value_avrg)]
#self.value_avrg2 = [max(v,max(self.value_avrg[1:i])) for i,v in enumerate(self.value_avrg[1:])]
print("\t".join([str(v) for v in self.value_avrg]))
if self.value_avrg[1] <= 80: #and not HW.buzzer.isPlaying()
HW.buzzer.playSound(HW.Buzzer.BEEP)

View File

@ -2,6 +2,9 @@ import uasyncio as asyncio
import machine import machine
import neopixel import neopixel
WHITE = (140,70,255)
YELLOW = (127,0,255)
class LEDs(): class LEDs():
def __init__(self, pin): def __init__(self, pin):
self.neop = neopixel.NeoPixel(machine.Pin(pin, machine.Pin.OUT),5) self.neop = neopixel.NeoPixel(machine.Pin(pin, machine.Pin.OUT),5)
@ -26,7 +29,26 @@ class LEDs():
def clear(self): def clear(self):
self.fill((0,0,0)) self.fill((0,0,0))
def lower(self,color):
self.neop[1] = color
self.neop.write()
def right(self,color):
self.neop[2] = color
self.neop.write()
def upper(self,color): def upper(self,color):
self.neop[3] = color self.neop[3] = color
self.neop.write() self.neop.write()
def left(self,color):
self.neop[4] = color
self.neop.write()
def set(self,colors):
self.neop[0] = (0,0,0)
for i,c in enumerate(colors):
self.neop[i+1] = c
self.neop.write()

View File

@ -3,64 +3,8 @@ import uasyncio as asyncio
import Buzzer import Buzzer
import Settings import Settings
import Hardware as HW import Hardware as HW
import math
class InitHandsScreen(): import network
def __await__(self):
self.running = True
self.mode=0 # 0: Minutes, 1: Hours
HW.housingLEDs.fill((0,0,0))
HW.stepperminu.rotateTo(0)
HW.stepperhour.rotateTo(0)
HW.leds[1].flash(0.7)
for number,button in enumerate(HW.buttons):
button.setCallbacks(\
onPushDown=lambda i=number:self.onButtonPressed(i),\
onPushUp=lambda pushDownTime,button=number:self.onButtonReleased(button,pushDownTime))
# Wait for the Hands to move up
while not HW.stepperhour.isAtTarget() or not HW.stepperminu.isAtTarget():
await asyncio.sleep_ms(200)
HW.housingLEDs.upper((50,50,50))
while self.running:
await asyncio.sleep_ms(200)
HW.housingLEDs.fill((0,0,0))
self.cleanup()
__iter__ = __await__ # https://github.com/micropython/micropython/issues/2678
def finish(self):
self.running = False
for b in HW.buttons:
b.setCallbacks()#Clear Callbacks
for l in HW.leds:
l.off()
def __init__(self):
self.running = False
def onButtonPressed(self,button):
if button == 1:
HW.leds[button].on(overwriteFlashing=False)
else:
HW.leds[button].on()
if self.mode == 0:
HW.stepperminu.rotateTo(direction=(1 if button == 0 else -1))
elif self.mode == 1:
HW.stepperhour.rotateTo(direction=(1 if button == 0 else -1))
def onButtonReleased(self,button,time):
HW.leds[button].off(overwriteFlashing=(button!=1))
if button == 1:
self.mode+=1
if self.mode == 2:
self.finish()
else:
if self.mode == 0:
HW.stepperminu.stop()
else:
HW.stepperhour.stop()
def cleanup(self):
HW.stepperhour.reset() # Set the new Zero
HW.stepperminu.reset()
class ClockScreen(): class ClockScreen():
def __await__(self): def __await__(self):
@ -81,7 +25,7 @@ class ClockScreen():
self.light = False self.light = False
self.clock = StepperClock.StepperClock() self.clock = StepperClock.StepperClock()
COLORS = ((255,0,0),(255,0,127),(127,0,255),(0,0,255),(0,127,255),(0,255,127),(0,255,0),(127,255,0),(255,127,0)) COLORS = ((255,0,0),(255,0,127),(127,0,255),(0,0,255),(0,127,255),(140,70,255),(0,255,127),(0,255,0),(127,255,0),(255,127,0))
BRIGHTNESS = (5,10,50,100,160,255) BRIGHTNESS = (5,10,50,100,160,255)
def onButtonPressed(self,button): def onButtonPressed(self,button):
@ -93,7 +37,7 @@ class ClockScreen():
if button == 0: if button == 0:
Settings.selectedBrightness=(Settings.selectedBrightness+1)%len(ClockScreen.BRIGHTNESS) Settings.selectedBrightness=(Settings.selectedBrightness+1)%len(ClockScreen.BRIGHTNESS)
elif button == 1: elif button == 1:
if pushDownTime > 1100: if pushDownTime > 700:
self.finish() self.finish()
return return
self.light = not self.light self.light = not self.light
@ -111,48 +55,274 @@ class ClockScreen():
def cleanup(self): def cleanup(self):
self.clock.stop() self.clock.stop()
class InitHandsScreen():
def __iter__(self):
HW.stepperminu.rotateTo(0)
HW.stepperhour.rotateTo(0)
HW.housingLEDs.upper((50,50,50))
timeScreen = GetTimeScreen(\
startTime=(0,0),\
onStart=lambda _: HW.buzzer.playSound(HW.Buzzer.BEEP),\
onSelectedTimeChange=None,\
onPicked=lambda _: Settings.save())
await timeScreen
HW.stepperhour.reset() # Set the new Zero
HW.stepperminu.reset()
HW.housingLEDs.fill((0,0,0))
class SetAlarmTimeScreen():
def setAlarmTime(self,selectedTime):
Settings.alarmTime = selectedTime
def __iter__(self):
HW.housingLEDs.fill((255,0,0))
timeScreen = GetTimeScreen(\
startTime=Settings.alarmTime,\
onStart=lambda _: HW.buzzer.playSound(HW.Buzzer.BEEP),\
onSelectedTimeChange=self.setAlarmTime,\
onPicked=lambda _: Settings.save())
await timeScreen
HW.housingLEDs.fill((0,0,0))
class RingtoneSettingsScreen(): class RingtoneSettingsScreen():
def playAndSetSound(self,number):
Settings.selectedSound = number
HW.buzzer.playSound(HW.Buzzer.ALARMTONES[number])
def __iter__(self):
numberScreen = GetNumberScreen([i for i in range(len(HW.Buzzer.ALARMTONES))],\
startNumber=Settings.selectedSound,\
onStart=self.playAndSetSound,\
onNumberChange=self.playAndSetSound,\
onPicked=lambda _:Settings.save())
await numberScreen
class ShowIpScreen():
def __init__(self):
self.IP = "0"
async def beepAndWaitIP(self,digitShown):
HW.housingLEDs.fill(HW.HousingLEDs.WHITE)
ipdigit = digitShown+self.IP[:digitShown].count(".")
if (ipdigit >= len(self.IP) or self.IP[ipdigit] == "."):
HW.buzzer.playSound(HW.Buzzer.BEEPBEEP)
await asyncio.sleep_ms(1800)
else:
HW.buzzer.playSound(HW.Buzzer.BEEP)
await asyncio.sleep_ms(1100)
HW.housingLEDs.fill((0,0,0))
def __iter__(self):
sta_if = network.WLAN(network.STA_IF)
if sta_if.status() != network.STAT_GOT_IP:
HW.housingLEDs.fill((255,0,0))
HW.buzzer.playSound(HW.Buzzer.BEEP)
await asyncio.sleep_ms(1000)
else:
self.IP = sta_if.ifconfig()[0]
showNumberScreen = ShowNumberScreen(number=[int(i) for i in self.IP.replace(".","")],onDigitShown=self.beepAndWaitIP)
await showNumberScreen
HW.housingLEDs.fill((0,0,0))
class ShowNumberScreen():
def __init__(self,number,onDigitShown):
self.number = number
self.digit_shown = 0
self.onDigitShown = onDigitShown
self.running = False
def onButtonReleased(self,pushDownTime):
HW.leds[1].off()
if pushDownTime > 700:
self.running = False
def __await__(self):
self.running = True
HW.buttons[1].setCallbacks(onPushUp=self.onButtonReleased,onPushDown=lambda :HW.leds[1].on())
HW.stepperminu.rotateTo(0)
HW.stepperhour.rotateTo(0)
self.digit_shown = 0
await self.onDigitShown(self.digit_shown)
while self.digit_shown < len(self.number):
HW.stepperminu.rotateTo(-((self.number[self.digit_shown]%10)/12))
while self.running and (not HW.stepperminu.isAtTarget() or not HW.stepperhour.isAtTarget()):
await asyncio.sleep_ms(200)
if not self.running:
return
self.digit_shown=self.digit_shown+1
await self.onDigitShown(self.digit_shown)
HW.buttons[1].setCallbacks()
__iter__ = __await__ # https://github.com/micropython/micropython/issues/2678
class GetNumberScreen():
def __init__(self,acceptedInputNumbers,startNumber = None,onStart=None,onNumberChange = None,onPicked = None):
self.acceptedInputNumbers = acceptedInputNumbers
self.onStart = onStart
self.onNumberChange = onNumberChange
self.onPicked = onPicked
self.running = False
if startNumber:
self.number = startNumber
else:
self.number = acceptedInputNumbers[0]
def __await__(self): def __await__(self):
self.running = True self.running = True
for i,b in enumerate(HW.buttons): for i,b in enumerate(HW.buttons):
b.setCallbacks(onPushDown=lambda i=i:self.onButtonPressed(i),onPushUp=lambda pushDownTime,button=i:self.onButtonReleased(button,pushDownTime)) b.setCallbacks(onPushDown=lambda i=i:self.onButtonPressed(i),onPushUp=lambda pushDownTime,button=i:self.onButtonReleased(button,pushDownTime))
# Turn LEDs Red and play the selected Sound and turn the minute-hand to the selected sound HW.stepperminu.rotateTo(-(self.number/12))
HW.housingLEDs.fill((200,0,0))
HW.buzzer.playSound(HW.Buzzer.ALARMTONES[Settings.selectedSound])
HW.stepperminu.rotateTo(-Settings.selectedSound/12)
HW.stepperhour.rotateTo(0) HW.stepperhour.rotateTo(0)
while not HW.stepperhour.isAtTarget() or not HW.stepperminu.isAtTarget(): while not HW.stepperhour.isAtTarget() or not HW.stepperminu.isAtTarget():
await asyncio.sleep_ms(200) await asyncio.sleep_ms(200)
if self.onStart:
self.onStart(self.number)
while self.running: while self.running:
await asyncio.sleep_ms(200) await asyncio.sleep_ms(200)
HW.housingLEDs.fill((0,0,0)) if self.onPicked:
self.cleanup() self.onPicked(self.number)
return self.number
__iter__ = __await__ # https://github.com/micropython/micropython/issues/2678 __iter__ = __await__ # https://github.com/micropython/micropython/issues/2678
def __init__(self):
self.running = False
def finish(self):
self.running = False
for b in HW.buttons:
b.setCallbacks()#Clear Callbacks
def onButtonPressed(self,button): def onButtonPressed(self,button):
HW.leds[button].on() HW.leds[button].on()
def onButtonReleased(self,button,pushDownTime): def onButtonReleased(self,button,pushDownTime):
print("Ring Select push down",pushDownTime) print("NumberSel push down",pushDownTime)
HW.leds[button].off() HW.leds[button].off()
if button == 1: if button == 1:
if pushDownTime > 1100: if pushDownTime > 700:
Settings.save()
self.finish() self.finish()
return return
else: else:
if pushDownTime < 500: if pushDownTime < 500:
Settings.selectedSound=(Settings.selectedSound+ (1 if button == 2 else -1))%len(Buzzer.ALARMTONES) self.number=self.acceptedInputNumbers[(self.acceptedInputNumbers.index(self.number) + (1 if button == 2 else -1)) % len(self.acceptedInputNumbers)]
HW.stepperminu.rotateTo(-Settings.selectedSound/12) HW.stepperminu.rotateTo(-(self.number/12))
HW.buzzer.playSound(HW.Buzzer.ALARMTONES[Settings.selectedSound]) if self.onNumberChange:
self.onNumberChange(self.number)
def cleanup(self): def finish(self):
HW.housingLEDs.fill((0,0,0)) self.running = False
HW.buzzer.stop() for b in HW.buttons:
b.setCallbacks()#Clear Callbacks
class GetTimeScreen():
def __init__(self,startTime = (0,0),onStart=None,onSelectedTimeChange = None,onPicked = None):
self.onStart = onStart
self.onSelectedTimeChange = onSelectedTimeChange
self.onPicked = onPicked
self.running = False
self.pickedTime = startTime
self.mode = 0
def __await__(self):
self.running = True
self.mode=0 # 0: Minutes, 1: Hours
HW.stepperminu.rotateTo(-(self.pickedTime[1])/12)
HW.stepperhour.rotateTo(-(self.pickedTime[0])/12)
HW.leds[1].flash(1)
for number,button in enumerate(HW.buttons):
button.setCallbacks(\
onPushDown=lambda i=number:self.onButtonPressed(i),\
onPushUp=lambda pushDownTime,button=number:self.onButtonReleased(button,pushDownTime))
# Wait for the Hands to move up
while not HW.stepperhour.isAtTarget() or not HW.stepperminu.isAtTarget():
await asyncio.sleep_ms(200)
if self.onStart:
self.onStart(self.pickedTime)
while self.running:
await asyncio.sleep_ms(200)
if self.onPicked:
self.onPicked(self.pickedTime)
__iter__ = __await__ # https://github.com/micropython/micropython/issues/2678
def finish(self):
self.running = False
for b in HW.buttons:
b.setCallbacks()#Clear Callbacks
for l in HW.leds:
l.off()
def onButtonPressed(self,button):
if button == 1:
HW.leds[button].on(overwriteFlashing=False)
else:
HW.leds[button].on()
if self.mode == 0:
HW.stepperminu.rotateTo(direction=(1 if button == 0 else -1))
elif self.mode == 1:
HW.stepperhour.rotateTo(direction=(1 if button == 0 else -1))
def onButtonReleased(self,button,time):
HW.leds[button].off(overwriteFlashing=(button!=1))
if button == 1:
self.mode=(1+self.mode )% 2
if time > 700:
self.finish()
else:
if self.mode == 0:
HW.stepperminu.stop()
else:
HW.stepperhour.stop()
if self.onSelectedTimeChange:
# TODO This is probably not save as its super unstable around the hour-increments
minutes = (60-HW.stepperminu.getOrientation()*60)
hours = (12-HW.stepperminu.getOrientation()*12)
self.onSelectedTimeChange(self.pickedTime)
# TODO
class GetTimeOnePressScreen():
def __init__(self,startTime = (0,0),onStart=None,onSelectedTimeChange = None,onPicked = None):
self.onStart = onStart
self.onSelectedTimeChange = onSelectedTimeChange
self.onPicked = onPicked
self.running = False
self.pickedTime = startTime
def __await__(self):
self.running = True
HW.stepperminu.rotateTo(-(self.pickedTime[1])/12)
HW.stepperhour.rotateTo(-(self.pickedTime[0])/12)
HW.leds[1].flash(1)
for number,button in enumerate(HW.buttons):
button.setCallbacks(\
onPushDown=lambda i=number:self.onButtonPressed(i),\
onPushUp=lambda pushDownTime,button=number:self.onButtonReleased(button,pushDownTime))
# Wait for the Hands to move up
while not HW.stepperhour.isAtTarget() or not HW.stepperminu.isAtTarget():
await asyncio.sleep_ms(200)
if self.onStart:
self.onStart(self.pickedTime)
while self.running:
await asyncio.sleep_ms(200)
if self.onPicked:
self.onPicked(self.pickedTime)
__iter__ = __await__ # https://github.com/micropython/micropython/issues/2678
def finish(self):
self.running = False
for b in HW.buttons:
b.setCallbacks()#Clear Callbacks
for l in HW.leds:
l.off()
def onButtonPressed(self,button):
if button == 1:
HW.leds[button].on(overwriteFlashing=False)
else:
HW.leds[button].on()
if self.mode == 0:
HW.stepperminu.rotateTo(direction=(1 if button == 0 else -1))
elif self.mode == 1:
HW.stepperhour.rotateTo(direction=(1 if button == 0 else -1))
def onButtonReleased(self,button,time):
HW.leds[button].off(overwriteFlashing=(button!=1))
if button == 1:
self.mode=(1+self.mode )% 2
if time > 700:
self.finish()
else:
if self.mode == 0:
HW.stepperminu.stop()
else:
HW.stepperhour.stop()
if self.onSelectedTimeChange:
# TODO This is probably not save as its super unstable around the hour-increments
minutes = (60-HW.stepperminu.getOrientation()*60)
hours = (12-HW.stepperminu.getOrientation()*12)
self.onSelectedTimeChange(self.pickedTime)

View File

@ -1,8 +1,8 @@
selectedSound=0 selectedSound=0
selectedBrightness=0 selectedBrightness=0
selectedColor=0 selectedColor=0
alarmTime=((1,2,3,4),(8,),(0,)) alarmTime=(8,0)
alarmOn=False
def printState(): def printState():
print("selectedSound=",selectedSound) print("selectedSound=",selectedSound)

View File

@ -5,7 +5,7 @@ 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]] 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: class Stepper:
def __init__(self,pins,stepsPerRev=400,stepDurationMs=10,inverted=False): def __init__(self,pins,stepsPerRev=400,stepDurationMs=8,inverted=False):
self._pins = [Pin(p, Pin.OUT) for p in pins] self._pins = [Pin(p, Pin.OUT) for p in pins]
self.reset() self.reset()
self.stepDurationMs = stepDurationMs self.stepDurationMs = stepDurationMs

34
main.py
View File

@ -1,23 +1,37 @@
import time import time
import uasyncio as asyncio import uasyncio as asyncio
import Hardware as HW import Hardware as HW
import Settings
import Screens import Screens
#Async #Async
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
async def run_screens():
InitScreen = Screens.InitHandsScreen()
await InitScreen
modus = 0
screens = (Screens.ClockScreen(),\ async def run_screens():
Screens.RingtoneSettingsScreen()) screens = ( \
(Screens.ClockScreen(),(140,70,255)),\
(Screens.SetAlarmTimeScreen(),(255,0,0)),\
(Screens.RingtoneSettingsScreen(),(255,0,127)),\
(Screens.InitHandsScreen(),(0,0,255)),\
(Screens.ShowIpScreen(),HW.HousingLEDs.YELLOW),\
)
colorSet = lambda number: HW.housingLEDs.fill(screens[number][1])
selectScreen = Screens.GetNumberScreen([i for i in range(len(screens))],\
startNumber=0,\
onStart=colorSet,\
onNumberChange=colorSet,\
onPicked=lambda number: HW.housingLEDs.fill((0,0,0)))
initScreen = Screens.InitHandsScreen()
await initScreen
activeScreen = 0
while True: while True:
HW.buzzer.playSound(HW.Buzzer.BEEP) HW.buzzer.playSound(HW.Buzzer.BEEP)
await screens[modus] await screens[activeScreen][0]
for b in HW.buttons: # Get the new screen from the screen selection screen
b.setCallbacks()#Clear Callbacks activeScreen = await selectScreen
modus = (modus+1)%len(screens)
loop.run_until_complete(run_screens()) loop.run_until_complete(run_screens())