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),\
(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,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),\
(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():
def __init__(self,pin,duty = 100):
def __init__(self,pin,duty = 1000):
self._pwm = machine.PWM(machine.Pin(2), freq=0, duty=0)
self.sound = None
self.duty = duty
@ -46,7 +46,7 @@ class Buzzer():
else:
self.newSound = False
timesPlayed = 0
print("Play sound!")
#print("Play sound!")
for i in range(len(self.sound)):
s = self.sound[i]
if s[0] == None:
@ -56,8 +56,8 @@ class Buzzer():
i = 0
timesPlayed += 1
if (s[1] != None):
#self._pwm.freq(s[1])
#self._pwm.duty(self.duty)
self._pwm.freq(s[1])
self._pwm.duty(self.duty)
pass
else:
self._pwm.duty(0)

View File

@ -5,7 +5,7 @@ import StepperL298M
import HousingLEDs
import LED
import Button
import HousingCapButton
#Initialise the time module with the RTC
try:
@ -34,6 +34,7 @@ leftButton = Button.Button(pin=34,inverted=True)
middleButton = Button.Button(pin=39,inverted=True)
rightButton = Button.Button(pin=36,inverted=True)
housingButton = HousingCapButton.HousingCapButton(pin=15)
buttons = (leftButton,middleButton,rightButton)
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 neopixel
WHITE = (140,70,255)
YELLOW = (127,0,255)
class LEDs():
def __init__(self, pin):
self.neop = neopixel.NeoPixel(machine.Pin(pin, machine.Pin.OUT),5)
@ -26,7 +29,26 @@ class LEDs():
def clear(self):
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):
self.neop[3] = color
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 Settings
import Hardware as HW
class InitHandsScreen():
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()
import math
import network
class ClockScreen():
def __await__(self):
@ -81,7 +25,7 @@ class ClockScreen():
self.light = False
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)
def onButtonPressed(self,button):
@ -93,7 +37,7 @@ class ClockScreen():
if button == 0:
Settings.selectedBrightness=(Settings.selectedBrightness+1)%len(ClockScreen.BRIGHTNESS)
elif button == 1:
if pushDownTime > 1100:
if pushDownTime > 700:
self.finish()
return
self.light = not self.light
@ -111,48 +55,274 @@ class ClockScreen():
def cleanup(self):
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():
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):
self.running = True
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))
# Turn LEDs Red and play the selected Sound and turn the minute-hand to the selected sound
HW.housingLEDs.fill((200,0,0))
HW.buzzer.playSound(HW.Buzzer.ALARMTONES[Settings.selectedSound])
HW.stepperminu.rotateTo(-Settings.selectedSound/12)
HW.stepperminu.rotateTo(-(self.number/12))
HW.stepperhour.rotateTo(0)
while not HW.stepperhour.isAtTarget() or not HW.stepperminu.isAtTarget():
await asyncio.sleep_ms(200)
if self.onStart:
self.onStart(self.number)
while self.running:
await asyncio.sleep_ms(200)
HW.housingLEDs.fill((0,0,0))
self.cleanup()
if self.onPicked:
self.onPicked(self.number)
return self.number
__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):
HW.leds[button].on()
def onButtonReleased(self,button,pushDownTime):
print("Ring Select push down",pushDownTime)
print("NumberSel push down",pushDownTime)
HW.leds[button].off()
if button == 1:
if pushDownTime > 1100:
Settings.save()
if pushDownTime > 700:
self.finish()
return
else:
if pushDownTime < 500:
Settings.selectedSound=(Settings.selectedSound+ (1 if button == 2 else -1))%len(Buzzer.ALARMTONES)
HW.stepperminu.rotateTo(-Settings.selectedSound/12)
HW.buzzer.playSound(HW.Buzzer.ALARMTONES[Settings.selectedSound])
self.number=self.acceptedInputNumbers[(self.acceptedInputNumbers.index(self.number) + (1 if button == 2 else -1)) % len(self.acceptedInputNumbers)]
HW.stepperminu.rotateTo(-(self.number/12))
if self.onNumberChange:
self.onNumberChange(self.number)
def cleanup(self):
HW.housingLEDs.fill((0,0,0))
HW.buzzer.stop()
def finish(self):
self.running = False
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
selectedBrightness=0
selectedColor=0
alarmTime=((1,2,3,4),(8,),(0,))
alarmTime=(8,0)
alarmOn=False
def printState():
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]]
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.reset()
self.stepDurationMs = stepDurationMs

34
main.py
View File

@ -1,23 +1,37 @@
import time
import uasyncio as asyncio
import Hardware as HW
import Settings
import Screens
#Async
loop = asyncio.get_event_loop()
async def run_screens():
InitScreen = Screens.InitHandsScreen()
await InitScreen
modus = 0
screens = (Screens.ClockScreen(),\
Screens.RingtoneSettingsScreen())
async def run_screens():
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:
HW.buzzer.playSound(HW.Buzzer.BEEP)
await screens[modus]
for b in HW.buttons:
b.setCallbacks()#Clear Callbacks
modus = (modus+1)%len(screens)
await screens[activeScreen][0]
# Get the new screen from the screen selection screen
activeScreen = await selectScreen
loop.run_until_complete(run_screens())