Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
416d9e7860 |
14
Buzzer.py
14
Buzzer.py
@ -15,9 +15,9 @@ C = 523 #Hz
|
||||
# (Duration,Freq)
|
||||
# If Last Duration is None play last Freq times (negative = infinite)
|
||||
|
||||
BEEP = ((100,1100),)
|
||||
BEEP = ((100,1100),(100,None))
|
||||
BEEPBEEP = ((700,1100),(100,None),(600,1100))
|
||||
BOOP = ((100,120),)
|
||||
BOOP = ((100,120),(100,None))
|
||||
|
||||
# 0: BEEEEP BEEEEP BEEEEEP
|
||||
# 1: Alle Meine Entchen
|
||||
@ -72,9 +72,17 @@ class Buzzer():
|
||||
if not self.newSound:
|
||||
self.newSound = False
|
||||
self.sound = None
|
||||
self._pwm.duty(0)
|
||||
|
||||
async def awaitFinish(self):
|
||||
while self.isPlaying():
|
||||
await asyncio.sleep_ms(50)
|
||||
|
||||
def awaitFinish_nonasync(self):
|
||||
asyncio.get_event_loop().run_until_complete(self.awaitFinish())
|
||||
|
||||
def playSound(self,sound):
|
||||
self.newSound = True
|
||||
self.newSound = sound != None
|
||||
self.sound = sound
|
||||
|
||||
def stop(self):
|
||||
|
@ -1,9 +1,9 @@
|
||||
import StepperL298M
|
||||
#import StepperL298M
|
||||
import time
|
||||
import Hardware as HW
|
||||
import uasyncio as asyncio
|
||||
|
||||
class StepperClock:
|
||||
class Clock:
|
||||
def __init__(self):
|
||||
self.started_async = False
|
||||
self._async_running = False
|
||||
@ -27,12 +27,12 @@ class StepperClock:
|
||||
def update(self):
|
||||
hour = time.localtime()[3]
|
||||
minute = time.localtime()[4]
|
||||
HW.stepperhour.rotateTo(1-((hour%12)/12+minute/(12*60)))
|
||||
HW.stepperminu.rotateTo(1-minute/60)
|
||||
HW.motorHour.rotateTo(1-((hour%12)/12+minute/(12*60)))
|
||||
HW.motorMinu.rotateTo(1-minute/60)
|
||||
|
||||
def disablePower(self):
|
||||
HW.stepperhour.disablePower()
|
||||
HW.stepperminu.disablePower()
|
||||
HW.motorHour.disablePower()
|
||||
HW.motorMinu.disablePower()
|
||||
#HW.stepperhour.disablePower()
|
||||
|
||||
def isRunning(self):
|
25
Hardware.py
25
Hardware.py
@ -3,12 +3,20 @@ import ntptime
|
||||
import time
|
||||
import DS3231
|
||||
import Buzzer
|
||||
import StepperL298M
|
||||
#import StepperL298M
|
||||
import MotorPot
|
||||
import HousingLEDs
|
||||
import LED
|
||||
import Button
|
||||
import HousingCapButton
|
||||
import Bme280
|
||||
import uasyncio as asyncio
|
||||
|
||||
#>>> pins = [machine.Pin(i,machine.Pin.OUT) for i in (12,27,26,25)]
|
||||
#>>> adcs = [machine.ADC(machine.Pin(i)) for i in (32,33)]
|
||||
#def f(t):
|
||||
#... pins[1].value(1);time.sleep(t);pins[1].value(0);
|
||||
#... print([ads.read() for ads in adcs])
|
||||
|
||||
#Init i2c Bus on 17,18
|
||||
i2cBus = machine.I2C(sda = machine.Pin(17), scl=machine.Pin(18))
|
||||
@ -29,21 +37,23 @@ except Exception as e:
|
||||
break
|
||||
except:
|
||||
print("timesync error trying again",i)
|
||||
time.sleep(0.5)
|
||||
asyncio.sleep_ms(500)
|
||||
|
||||
#Init Buzzer
|
||||
buzzer = Buzzer.Buzzer(pin=2)
|
||||
|
||||
#Initalise the Motors
|
||||
stepperminu = StepperL298M.Stepper((19,21,22,23),inverted=False)
|
||||
stepperhour = StepperL298M.Stepper((12,27,26,25),inverted=True)
|
||||
#stepperminu = StepperL298M.Stepper((19,21,22,23),inverted=False)
|
||||
#stepperhour = StepperL298M.Stepper((12,27,26,25),inverted=True)
|
||||
motorHour = MotorPot.MotorPot((12,27),33,steps_per_turn = 192)
|
||||
motorMinu = MotorPot.MotorPot((26,25),32,steps_per_turn = 192)
|
||||
|
||||
#Init LEDs
|
||||
housingLEDs = HousingLEDs.LEDs(pin=16)
|
||||
|
||||
leftButtonLED = LED.LED(13)
|
||||
middleButtonLED = LED.LED(33)
|
||||
rightButtonLED = LED.LED(32)
|
||||
middleButtonLED = LED.LED(22)
|
||||
rightButtonLED = LED.LED(23)
|
||||
|
||||
#Init Buttons
|
||||
leftButton = Button.Button(pin=34,inverted=True)
|
||||
@ -61,4 +71,5 @@ try:
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
def reset():
|
||||
machine.reset()
|
||||
|
307
MotorPot.py
Normal file
307
MotorPot.py
Normal file
@ -0,0 +1,307 @@
|
||||
from machine import Pin, ADC, PWM
|
||||
import time
|
||||
import uasyncio as asyncio
|
||||
import Hardware as HW
|
||||
import os
|
||||
# import PID
|
||||
# # [(0.0, 3071), (0.08333334, 2634), (0.1666667, 2286), (0.25, 1847),
|
||||
# # (0.3333333, 1453), (0.4166667, 1110), (0.5, 809), (0.5833333, 442),
|
||||
# # (0.6666667, 105), (0.75, 518), (0.8333333, 4095), (0.9166667, 3599)]
|
||||
|
||||
# # >>> m.pid.Ki
|
||||
# # -1
|
||||
# # >>> m.pid.Kd
|
||||
# # 10
|
||||
# # >>> m.pid.Kp
|
||||
# # -2
|
||||
# # >>> m.pid.windup_guard
|
||||
# # 200
|
||||
# # >>>
|
||||
|
||||
|
||||
# class MotorPot:
|
||||
# def __init__(self, pins, adcPin, updateRate=100, freq=40, inverted=False):
|
||||
# self._pins = [PWM(Pin(p, Pin.OUT), freq=freq, duty=0) for p in pins]
|
||||
# for p in self._pins:
|
||||
# p.freq(freq)
|
||||
# self._adc = ADC(Pin(adcPin))
|
||||
# self._adc.atten(ADC.ATTN_11DB) # Enable 3.6V Ranges
|
||||
# self.reset()
|
||||
# self.updateRate = updateRate
|
||||
# self.inverted = inverted
|
||||
# self._adcAngleMap = []
|
||||
# self._okTargetDiff = 0.1
|
||||
# self.pid = PID.PID(P=-2, D=10, I=-1)
|
||||
# self.pid.setWindup(200)
|
||||
# self.min_duty = 100
|
||||
# # self._maxSpeed = 1
|
||||
# self._duty = 500
|
||||
# self.calib_number = None
|
||||
# #loop = asyncio.get_event_loop()
|
||||
# #loop.create_task(self._update_async())
|
||||
|
||||
# def reset(self):
|
||||
# self._rotTarget = 0
|
||||
# self.rotDirection = 0
|
||||
|
||||
# def getStepsToTarget(self):
|
||||
# # return ((self._rotTarget - self.stepnum)
|
||||
# # *self.rotDirection)%self.stepsPerRev
|
||||
# return 0
|
||||
|
||||
# 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.
|
||||
# If target is None moves infinitely in direction
|
||||
# (if direction is 0 then hold position with power)."""
|
||||
# if target is None:
|
||||
# self._rotTarget = None
|
||||
# self.rotDirection = direction
|
||||
# else:
|
||||
# pass
|
||||
|
||||
# def stop(self):
|
||||
# for p in self._pins:
|
||||
# p.duty(0)
|
||||
# self.rotDirection = 0
|
||||
# self._rotTarget = None
|
||||
|
||||
# async def _update_async(self):
|
||||
# while(True):
|
||||
# await asyncio.sleep_ms(self.updateRate)
|
||||
# self._update()
|
||||
|
||||
# def _update_block(self):
|
||||
# while(self.isAtTarget()):
|
||||
# await asyncio.sleep_ms(self.updateRate)
|
||||
# self._update()
|
||||
|
||||
# def _update(self):
|
||||
# # duty = int(self._duty)
|
||||
# # if self._rotTarget is not None:
|
||||
# # targetDiff = self.getOrientation() - self._rotTarget
|
||||
# # if not self.isAtTarget():
|
||||
# # self.rotDirection = 1 if targetDiff > 0 else -1
|
||||
# # # TODO duty = min(abs(targetDiff)*kp,1)*duty
|
||||
# # else:
|
||||
# # self.rotDirection = 0
|
||||
# # self._pins[0].duty(duty if self.rotDirection < 0 else 0)
|
||||
# # self._pins[1].duty(duty if self.rotDirection > 0 else 0)
|
||||
# self.pid.SetPoint = self._rotTarget
|
||||
# self._adcValue = self._adc.read()
|
||||
# self.pid.update(self._adcValue)
|
||||
# v = int(self.pid.output)
|
||||
# print("target", self._rotTarget,
|
||||
# "adcValue", self._adcValue,
|
||||
# "output:", v)
|
||||
# self._pins[0].duty(-v if v < -self.min_duty else 0)
|
||||
# self._pins[1].duty(v if v > self.min_duty else 0)
|
||||
|
||||
# def getOrientation(self):
|
||||
# adcValueNow = self._adc.read()
|
||||
# for i in range(len(self._adcAngleMap)-1):
|
||||
# if(self._adcAngleMap[i][1] <= adcValueNow
|
||||
# and self._adcAngleMap[i+1][1] > adcValueNow):
|
||||
# r = (adcValueNow - self._adcAngleMap[i][0]) / (
|
||||
# self._adcAngleMap[i+1][0] - self._adcAngleMap[i][0])
|
||||
# r = self._adcAngleMap[i][1] + r * \
|
||||
# (self._adcAngleMap[i+1][1] - self._adcAngleMap[i][1])
|
||||
# return r
|
||||
# # return didn't trigger, so the pot is in the deadzone
|
||||
# # TODO Calc a possible orientation based on time of last duty command
|
||||
# return 0
|
||||
|
||||
# def getTarget(self):
|
||||
# return self._rotTarget
|
||||
|
||||
# def isAtTarget(self):
|
||||
# if self._rotTarget is None:
|
||||
# return self.rotDirection == 0
|
||||
# targetDiff = self.getOrientation() - self._rotTarget
|
||||
# return (abs(targetDiff) < self._okTargetDiff)
|
||||
|
||||
# def printAdcValues(self, duty=200, sleepTime=0.01, pin=0):
|
||||
# start = self._adc.read()
|
||||
# while abs(start - self._adc.read()) <= 30:
|
||||
# self._pins[pin].duty(duty)
|
||||
# time.sleep(sleepTime)
|
||||
# self._pins[pin].duty(0)
|
||||
# print(self._adc.read())
|
||||
# while abs(start - self._adc.read()) > 30:
|
||||
# self._pins[pin].duty(duty)
|
||||
# time.sleep(sleepTime)
|
||||
# self._pins[pin].duty(0)
|
||||
# print(self._adc.read())
|
||||
|
||||
class MotorPot:
|
||||
def __init__(self,pins, adcPin, stepTime=3, stepWait=130,steps_per_turn = None,adc_map = None,tolerance = 30,inverted=False):
|
||||
self._pins = [Pin(p,Pin.OUT) for p in pins]
|
||||
self._adc = ADC(Pin(adcPin))
|
||||
self._adc.atten(ADC.ATTN_11DB) # Enable 3.6V Ranges
|
||||
self.inverted = inverted
|
||||
self.stepTime = stepTime
|
||||
self.stepWait = stepWait
|
||||
self.steps_per_turn = steps_per_turn
|
||||
self.rotation_current = 0
|
||||
self.rotation_target = 0
|
||||
self.tolerance = tolerance
|
||||
self._adc_max_value = 4096
|
||||
self._adc_map = adc_map
|
||||
self.load_settings()
|
||||
self.calib_number = 1
|
||||
self._calibrating = False
|
||||
if(self._adc_map is None):
|
||||
self._adc_map = [(4095, 0.8333333-1-1/12), (3599, 0.9166667-1-1/12), (3071, 0.0-1/12), (2634, 0.08333334-1/12), (2286, 0.1666667-1/12), (1847, 0.25-1/12), (1453, 0.3333333-1/12), (1110, 0.4166667-1/12), (809, 0.5-1/12), (442, 0.5833333-1/12), (105, 0.6666667-1/12)]
|
||||
self.save_settings()
|
||||
#[(4095, 0.8333333-1-1/12), (3599, 0.9166667-1-1/12), (3071, 0.0-1/12), (2634, 0.08333334-1/12), (2286, 0.1666667-1/12), (1847, 0.25-1/12), (1453, 0.3333333-1/12), (1110, 0.4166667-1/12), (809, 0.5-1/12), (442, 0.5833333-1/12), (105, 0.6666667-1/12)]
|
||||
#self._adc_map = [(d[0],(d[1]+0.5)%1-0.5) for d in self._adc_map]
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(self._update_async())
|
||||
|
||||
async def _getStepsPerTurn_async(self,steps_dir = 1):
|
||||
startV = self._adc.read()
|
||||
while (startV == 0 or startV == self._adc_max_value):
|
||||
self._step(steps_dir)
|
||||
startV = self._adc.read()
|
||||
steps = 0
|
||||
while (startV - self.tolerance - self._adc.read())%self._adc_max_value > self.tolerance:
|
||||
self._step(steps_dir)
|
||||
await asyncio.sleep_ms(self.stepWait)
|
||||
steps += abs(steps_dir)
|
||||
print("waiting for:",(startV - self.tolerance - self._adc.read())%self._adc_max_value)
|
||||
self.steps_per_turn = steps
|
||||
#[(0.0, 3071), (0.08333334, 2634), (0.1666667, 2286), (0.25, 1847), (0.3333333, 1453), (0.4166667, 1110), (0.5, 809), (0.5833333, 442), (0.6666667, 105), (0.8333333, 4095), (0.9166667, 3599)]
|
||||
|
||||
def _getStepsPerTurn(self,steps_dir = 1):
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(self._getStepsPerTurn_async(steps_dir))
|
||||
return self.steps_per_turn
|
||||
|
||||
def _step(self,direc):
|
||||
direcBool = self.inverted != (direc>0)
|
||||
p = self._pins[1 if direcBool else 0]
|
||||
adc_before = self._adc.read()
|
||||
p.on()
|
||||
#await asyncio.sleep_ms(self.stepTime)
|
||||
time.sleep_ms(self.stepTime)
|
||||
p.off()
|
||||
if(self._calibrating):
|
||||
return
|
||||
oldR = self.rotation_current
|
||||
self.rotation_current = (self.rotation_current + direc / self.steps_per_turn)%1
|
||||
self.update_rotation_from_adc()
|
||||
#print("rotation updated:",oldR," -> ", self.rotation_current," t",self.rotation_target)
|
||||
def update_rotation_from_adc(self):
|
||||
adc_after = self._adc.read()
|
||||
if not (self._adc_map[0][1] > self.rotation_current > self._adc_map[-1][1]):
|
||||
i = 0
|
||||
for i in range(len(self._adc_map)-1):
|
||||
if (min(self._adc_map[i+1][0],self._adc_map[i][0]) < adc_after < max(self._adc_map[i+1][0],self._adc_map[i][0])):
|
||||
self.rotation_current = (self._adc_map[i+1][1]+((adc_after-self._adc_map[i][0])/(self._adc_map[i+1][0]-self._adc_map[i][0]))*(self._adc_map[i+1][1]-self._adc_map[i][1]))%1
|
||||
break
|
||||
|
||||
async def run_until_target_async(self):
|
||||
while(not self.isAtTarget()):
|
||||
self._step(1 if (self.rotation_current - self.rotation_target+0.5)%1<0.5 else -1)
|
||||
await asyncio.sleep_ms(self.stepWait)
|
||||
|
||||
def run_until_target_block(self,target):
|
||||
self.rotation_target = target
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(self.run_until_target_async())
|
||||
return self.steps_per_turn
|
||||
|
||||
async def _update_async(self):
|
||||
while(True):
|
||||
await self.run_until_target_async()
|
||||
await asyncio.sleep_ms(self.stepWait)
|
||||
#self.update_rotation_from_adc()
|
||||
|
||||
def set_current_rotation(self,curr):
|
||||
self._adc_map = [(a[0],(a[1]-self.rotation_current+curr+0.5)%1-0.5) for a in self._adc_map]
|
||||
|
||||
def get_filename(self):
|
||||
return (str(self._pins)+str(self._adc)).replace(" ","").replace("(","").replace(")","").replace(",","").replace("]","").replace("[","")
|
||||
|
||||
def save_settings(self):
|
||||
foldername = "/motor_settings"
|
||||
try:
|
||||
os.remove(foldername+"/"+self.get_filename())
|
||||
except Exception as e:
|
||||
print(e)
|
||||
try:
|
||||
os.mkdir(foldername)
|
||||
except:
|
||||
pass
|
||||
with open(foldername+"/"+self.get_filename(),'w') as f:
|
||||
f.write(str(self._adc_map)+"\n")
|
||||
f.write(str(self.steps_per_turn)+"\n")
|
||||
|
||||
def load_settings(self):
|
||||
foldername = "/motor_settings"+"/"+self.get_filename()
|
||||
|
||||
try:
|
||||
with open(foldername,'r') as f:
|
||||
s=f.readline()
|
||||
print(foldername,":\n"," _adc_map =",s)
|
||||
self._adc_map = eval(s)
|
||||
s=f.readline()
|
||||
print(" steps_per_turn =",s)
|
||||
self.steps_per_turn = eval(s)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def stop(self):
|
||||
for p in self._pins:
|
||||
p.off()
|
||||
|
||||
def calib_onButtonReleased(self, button, pushdown):
|
||||
HW.leds[button].off()
|
||||
if button == 1:
|
||||
if pushdown > 700:
|
||||
self._calibrating = False
|
||||
self.stop()
|
||||
else:
|
||||
self._adc_map.append(
|
||||
(self._adc.read(), (self.calib_number-1 % 12)/12))
|
||||
self._adc_map.sort(key=lambda x: -x[0])
|
||||
self.calib_number = (self.calib_number) % 12+1
|
||||
print(self._adc_map)
|
||||
self.stop()
|
||||
|
||||
def calib_onButtonPressed(self, button):
|
||||
HW.leds[button].on()
|
||||
self._step(button - 1)
|
||||
|
||||
def calibrate(self):
|
||||
self._adc_map = []
|
||||
self.calib_number = 1
|
||||
self._calibrating = True
|
||||
for i, b in enumerate(HW.buttons):
|
||||
b.setCallbacks(
|
||||
onPushDown=lambda i=i: self.calib_onButtonPressed(i),
|
||||
onPushUp=lambda pushDownTime, button=i:
|
||||
self.calib_onButtonReleased(button, pushDownTime))
|
||||
# await asyncio.sleep_ms(self.updateRate)
|
||||
self._rotTarget = None
|
||||
HW.buzzer.playSound(HW.Buzzer.BEEP*self.calib_number)
|
||||
HW.buzzer.awaitFinish_nonasync()
|
||||
currNum = self.calib_number
|
||||
while self._calibrating:
|
||||
while currNum == self.calib_number:
|
||||
time.sleep(0.1)
|
||||
currNum = self.calib_number
|
||||
HW.buzzer.playSound(HW.Buzzer.BEEP*self.calib_number)
|
||||
HW.buzzer.awaitFinish_nonasync()
|
||||
|
||||
def rotateTo(self,target):
|
||||
self.rotation_target = -target%1
|
||||
|
||||
def getOrientation(self):
|
||||
return self.rotation_current
|
||||
|
||||
def getTarget(self):
|
||||
return self.rotation_target
|
||||
|
||||
def isAtTarget(self):
|
||||
return abs(self.rotation_current - self.rotation_target)%1 < self.tolerance/self._adc_max_value
|
58
Screens.py
58
Screens.py
@ -1,4 +1,4 @@
|
||||
import StepperClock
|
||||
import Clock
|
||||
import uasyncio as asyncio
|
||||
import Buzzer
|
||||
import Settings
|
||||
@ -39,7 +39,7 @@ class ClockScreen():
|
||||
def __init__(self):
|
||||
self.running = False
|
||||
self.light = False
|
||||
self.clock = StepperClock.StepperClock()
|
||||
self.clock = Clock.Clock()
|
||||
self.alarmTrunedOff = False
|
||||
self.alarmPlaying = False
|
||||
|
||||
@ -91,8 +91,8 @@ class ClockScreen():
|
||||
|
||||
class InitHandsScreen():
|
||||
def __iter__(self):
|
||||
HW.stepperminu.rotateTo(0)
|
||||
HW.stepperhour.rotateTo(0)
|
||||
HW.motorHour.rotateTo(0)
|
||||
HW.motorMinu.rotateTo(0)
|
||||
HW.housingLEDs.upper((50,50,50))
|
||||
HW.leds[1].setOffState(pwmDuty=500,blinkRate=1.2)
|
||||
timeScreen = Get2PositionsScreen(\
|
||||
@ -101,8 +101,8 @@ class InitHandsScreen():
|
||||
onSelectedTimeChange=None,\
|
||||
onPicked=lambda _: Settings.save())
|
||||
await timeScreen
|
||||
HW.stepperhour.reset() # Set the new Zero
|
||||
HW.stepperminu.reset()
|
||||
HW.motorHour.reset() # Set the new Zero
|
||||
HW.motorMinu.reset()
|
||||
HW.housingLEDs.fill((0,0,0))
|
||||
HW.leds[1].setOffState()
|
||||
|
||||
@ -213,13 +213,13 @@ class ShowLongNumberScreen():
|
||||
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)
|
||||
HW.motorMinu.rotateTo(0)
|
||||
HW.motorHour.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()):
|
||||
HW.motorMinu.rotateTo(-((self.number[self.digit_shown]%10)/12))
|
||||
while self.running and (not HW.motorMinu.isAtTarget() or not HW.motorHour.isAtTarget()):
|
||||
await asyncio.sleep_ms(200)
|
||||
if not self.running:
|
||||
return
|
||||
@ -245,10 +245,10 @@ class ShowNumberScreen():
|
||||
while self.running:
|
||||
if self.update != None:
|
||||
self.number = self.update()
|
||||
while (not HW.stepperminu.isAtTarget() or not HW.stepperhour.isAtTarget()):
|
||||
while (not HW.motorMinu.isAtTarget() or not HW.motorHour.isAtTarget()):
|
||||
await asyncio.sleep_ms(200)
|
||||
HW.stepperminu.rotateTo(-((self.number%10)/12))
|
||||
HW.stepperhour.rotateTo(-((self.number//10)/12))
|
||||
HW.motorMinu.rotateTo(-((self.number%10)/12))
|
||||
HW.motorrHou.rotateTo(-((self.number//10)/12))
|
||||
await asyncio.sleep_ms(500)
|
||||
HW.buttons[1].setCallbacks()
|
||||
__iter__ = __await__ # https://github.com/micropython/micropython/issues/2678
|
||||
@ -269,9 +269,9 @@ class GetNumberScreen():
|
||||
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))
|
||||
HW.stepperminu.rotateTo(-(self.number/12))
|
||||
HW.stepperhour.rotateTo(0)
|
||||
while not HW.stepperhour.isAtTarget() or not HW.stepperminu.isAtTarget():
|
||||
HW.motorMinu.rotateTo(-(self.number/12))
|
||||
HW.motorHour.rotateTo(0)
|
||||
while not HW.motorHour.isAtTarget() or not HW.motorMinu.isAtTarget():
|
||||
await asyncio.sleep_ms(200)
|
||||
if self.onStart:
|
||||
self.onStart(self.number)
|
||||
@ -294,7 +294,7 @@ class GetNumberScreen():
|
||||
else:
|
||||
if pushDownTime < 500:
|
||||
self.number=self.acceptedInputNumbers[(self.acceptedInputNumbers.index(self.number) + (1 if button == 2 else -1)) % len(self.acceptedInputNumbers)]
|
||||
HW.stepperminu.rotateTo(-(self.number/12))
|
||||
HW.motorMinu.rotateTo(-(self.number/12))
|
||||
if self.onNumberChange:
|
||||
self.onNumberChange(self.number)
|
||||
|
||||
@ -315,14 +315,14 @@ class Get2PositionsScreen():
|
||||
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.motorMinu.rotateTo(-(self.pickedTime[1])/12)
|
||||
HW.motorHour.rotateTo(-(self.pickedTime[0])/12)
|
||||
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():
|
||||
while not HW.motorMinu.isAtTarget() or not HW.motorHour.isAtTarget():
|
||||
await asyncio.sleep_ms(200)
|
||||
if self.onStart:
|
||||
self.onStart(self.pickedTime)
|
||||
@ -344,9 +344,9 @@ class Get2PositionsScreen():
|
||||
HW.leds[button].on()
|
||||
if button != 1:
|
||||
if self.mode == 0:
|
||||
HW.stepperminu.rotateTo(direction=(1 if button == 0 else -1))
|
||||
HW.motorMinu.rotateTo(direction=(1 if button == 0 else -1))
|
||||
elif self.mode == 1:
|
||||
HW.stepperhour.rotateTo(direction=(1 if button == 0 else -1))
|
||||
HW.motorHour.rotateTo(direction=(1 if button == 0 else -1))
|
||||
|
||||
def onButtonReleased(self,button,time):
|
||||
HW.leds[button].off()
|
||||
@ -356,13 +356,13 @@ class Get2PositionsScreen():
|
||||
self.finish()
|
||||
else:
|
||||
if self.mode == 0:
|
||||
HW.stepperminu.stop()
|
||||
HW.motorMinu.stop()
|
||||
else:
|
||||
HW.stepperhour.stop()
|
||||
HW.motorHour.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)
|
||||
minutes = (60-HW.motorMinu.getOrientation()*60)
|
||||
hours = (12-HW.motorMinu.getOrientation()*12)
|
||||
self.pickedTime = (hours,minutes)
|
||||
self.onSelectedTimeChange(self.pickedTime)
|
||||
|
||||
@ -387,13 +387,13 @@ class GetTimeScreen():
|
||||
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():
|
||||
while not HW.motorMinu.isAtTarget() or not HW.motorHour.isAtTarget():
|
||||
await asyncio.sleep_ms(200)
|
||||
if self.onStart:
|
||||
self.onStart(self.calcTupleTime())
|
||||
while self.running:
|
||||
HW.stepperminu.rotateTo(-(self.pickedTime/60))
|
||||
HW.stepperhour.rotateTo(-(self.pickedTime/60/12))
|
||||
HW.motorMinu.rotateTo(-(self.pickedTime/60))
|
||||
HW.motorHour.rotateTo(-(self.pickedTime/60/12))
|
||||
# Color the Top LED to indikate AM or PM
|
||||
self.AM = (self.pickedTime < 12*60)
|
||||
HW.housingLEDs.upper(HW.HousingLEDs.BLUE if self.AM else HW.HousingLEDs.YELLOW)
|
||||
|
@ -27,7 +27,7 @@ class Stepper:
|
||||
self._pins[2].value(level[2])
|
||||
self._pins[3].value(level[3])
|
||||
|
||||
def getStepsToTarget(self):
|
||||
def _getStepsToTarget(self):
|
||||
#return ((self._rotTarget - self.stepnum)*self.rotDirection)%self.stepsPerRev
|
||||
return ((self._rotTarget - self.stepnum)*self.rotDirection)
|
||||
|
||||
@ -54,7 +54,7 @@ class Stepper:
|
||||
self.rotDirection = 1 if (self._rotTarget > self.stepnum) else -1
|
||||
else:
|
||||
self.rotDirection = direction
|
||||
self._speedMs = max(int(self.stepDurationMs),duration*1000/self.getStepsToTarget())
|
||||
self._speedMs = max(int(self.stepDurationMs),duration*1000/self._getStepsToTarget())
|
||||
|
||||
def stop(self):
|
||||
self._rotTarget = self.stepnum
|
||||
|
30
boot.py
30
boot.py
@ -1,14 +1,21 @@
|
||||
import network
|
||||
import webrepl
|
||||
import uasyncio as asyncio
|
||||
|
||||
import time
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
webrepl.start()
|
||||
|
||||
sta_if = network.WLAN(network.STA_IF)
|
||||
sta_if.active(False)
|
||||
time.sleep(0.1)
|
||||
sta_if.active(True)
|
||||
sta_if.config(dhcp_hostname="stepper-wecker")
|
||||
time.sleep(0.1)
|
||||
sta_if.config(dhcp_hostname="wecker")
|
||||
|
||||
#print("sta_if.config")
|
||||
|
||||
|
||||
async def connect():
|
||||
connectingFor = 0
|
||||
@ -22,21 +29,22 @@ async def connect():
|
||||
try:
|
||||
availableNetworkSSIDs = [s[0].decode() for s in sta_if.scan()]
|
||||
if len(availableNetworkSSIDs) > 0:
|
||||
print("availableNetworkSSIDs:\n",availableNetworkSSIDs)
|
||||
#load wifi credentials from file
|
||||
with open("wifi-credentials","r") as f:
|
||||
print("availableNetworkSSIDs:\n", availableNetworkSSIDs)
|
||||
# load wifi credentials from file
|
||||
with open("wifi-credentials", "r") as f:
|
||||
while sta_if.status() != network.STAT_GOT_IP:
|
||||
ssid = f.readline()
|
||||
password = f.readline()#
|
||||
password = f.readline()
|
||||
if not ssid or not password:
|
||||
break
|
||||
ssid = ssid.replace("\n","")
|
||||
password = password.replace("\n","")
|
||||
ssid = ssid.replace("\n", "")
|
||||
password = password.replace("\n", "")
|
||||
if ssid in availableNetworkSSIDs:
|
||||
print("Connecting to",ssid)
|
||||
sta_if.connect(ssid,password)
|
||||
print("Connecting to", ssid)
|
||||
sta_if.connect(ssid, password)
|
||||
break
|
||||
except:
|
||||
except Exception as e:
|
||||
print(e)
|
||||
pass
|
||||
finally:
|
||||
await asyncio.sleep(60*2)
|
||||
|
7
main.py
7
main.py
@ -17,9 +17,9 @@ async def run_screens():
|
||||
(Screens.TemperatureScreen(),(0,50,200)),\
|
||||
(Screens.HumidityScreen(),(0,50,200)),\
|
||||
(Screens.SetTimeScreen(),(100,200,50)),\
|
||||
(Screens.InitHandsScreen(),(0,0,255)),\
|
||||
(Screens.ShowIpScreen(),HW.HousingLEDs.YELLOW),\
|
||||
)
|
||||
#(Screens.InitHandsScreen(),(0,0,255)),\
|
||||
colorSet = lambda number: HW.housingLEDs.fill(screens[number][1])
|
||||
selectScreen = Screens.GetNumberScreen([i for i in range(len(screens))],\
|
||||
startNumber=0,\
|
||||
@ -27,8 +27,8 @@ async def run_screens():
|
||||
onNumberChange=colorSet,\
|
||||
onPicked=lambda number: HW.housingLEDs.fill((0,0,0)))
|
||||
|
||||
initScreen = Screens.InitHandsScreen()
|
||||
await initScreen
|
||||
#initScreen = Screens.InitHandsScreen()
|
||||
#await initScreen
|
||||
|
||||
activeScreen = 0
|
||||
while True:
|
||||
@ -38,3 +38,4 @@ async def run_screens():
|
||||
activeScreen = await selectScreen
|
||||
|
||||
loop.run_until_complete(run_screens())
|
||||
loop.run_forever()
|
Loading…
x
Reference in New Issue
Block a user