[DigiKey "Smart Manufacturing, Non-stop Happiness" Creative Competition] Simple Applications on MAIX BIT KIT
[Copy link]
Now that MCU computing power is getting stronger and stronger, micro python can also run very fast.
If the function is slightly more complex, multiple modules will coexist. For example, when module A is running, module B is called, and module A hands over control to module B.
I built a small framework for this purpose. This is not a system, but just a simple application:
class OneAppStats():# = ['init','running','sleep','restore','exit','kill','killed','back']
INIT = 0
RUNNING = 1
SLEEP = 2
RESTORE = 3
EXIT = 4
KILL = 5
KILLED = 6
BACK = 7
# One Application
class OneApp(object):
def __init__(self, name=None):
self.name = name
self.data = {}
self.stat = OneAppStats.INIT
self.childApps =[]
def setup(self, **kw):
for key in kw:
self.data[key]=kw[key]
self.stat = OneAppStats.RUNNING
def loop(self):
print('__getitem__', key)
return self.data[key] if key in self.data else None
def beforePaint(self):
pass
def rePaint(self):
pass
def afterPaint(self):
pass
def _paint(self):
self.beforePaint()
self.rePaint()
self.afterPaint()
def onEvent(self,evtName,*args,**kw):
print('x11',evtName,len(self.childApps))
for childrenApp in self.childApps:
if childrenApp.stat in (OneAppStats.RUNNING,OneAppStats.SLEEP,OneAppStats.RESTORE,OneAppStats.BACK):
childrenApp.onEvent(evtName,*args,**kw)
def _removeApp(self,app):
app.stat = OneAppStats.KILLED
self.childApps.remove(app)
del app
def _loop(self):
cntAliveChildren = 0
for childrenApp in self.childApps[::]:
if childrenApp.stat == OneAppStats.INIT :
cntAliveChildren = cntAliveChildren +1
elif childrenApp.stat == OneAppStats.RUNNING :
flag = childrenApp.loop()
if flag in (OneAppStats.EXIT,OneAppStats.KILL):
self._removeApp(childrenApp)
else:
cntAliveChildren = cntAliveChildren +1
elif childrenApp.stat in (OneAppStats.EXIT,OneAppStats.KILL):
self._removeApp(childrenApp)
print('_removeApp',childrenApp,len(self.childApps) )
return OneAppStats.BACK if cntAliveChildren>0 else OneAppStats.RUNNING
def loop(self):
return self._loop()
def _startChildApp(self,defClass,appName=None):
childrenApp = defClass(appName)
self.childApps.append(childrenApp)
return childrenApp
#attention : need do childrenApp.setup() by you self,and maybe change parent App to 7(back)
def doHideback(self):
self.stat = OneAppStats.RUNNING
return self.stat
def doSleep(self):
self.stat = OneAppStats.SLEEP
return self.stat
def doRestore(self):
self.stat = OneAppStats.RESTORE
#do some thing
# if sucess
self.stat = OneAppStats.RUNNING
#if not sucess
#self.stat = 2
return self.stat
def doKill(self):
self.stat = OneAppStats.KILL
return self.stat
def doStop(self):
#do some thing
# if sucess
self.stat = OneAppStats.EXIT
#if not sucess
#self.stat = 5
return self.stat
import time
DEBUG_DELAY = 0.5
################################################################################
# simple Application #
################################################################################
class appSimple(OneApp):
def loop(self):
OneApp.loop(self)
cnt = self.data['cnt']
if cnt<20:
print('app[',self.name,'] cnt:',cnt,self.name)
self.data['cnt']=cnt+1
time.sleep(DEBUG_DELAY)
return self.stat
elif 20==cnt:
print('app1 stop:',cnt)
return self.doStop()
def onEvent(self,evtName,*args,**kw):
print(102,self.name , 'onEvent:',evtName,*args,**kw)
################################################################################
# System Application #
################################################################################
class SysApp(OneApp):
def setup(self, **kw):
self.selIdx = 0
super().setup(**kw)
def loop(self):
if self.stat == OneAppStats.RUNNING:
#print( self.selIdx ,utime.ticks() )
self._paint()
print( OneApp.loop(self) )
return self.stat
def rePaint(self):
#import image
screen = self.data['screen']
img = image.Image()
img.clear()
img.draw_rectangle(0, 0, 320, 240 , color=lcd.WHITE, thickness=1 , fill=True )
l,t=100,60
img.draw_string(l , t + 0*60, "ONE", scale=2,color=lcd.BLACK)
img.draw_string(l , t + 1*60, "TWO", scale=2,color=lcd.BLACK)
img.draw_string(l , t + 2*60, "THREE", scale=2,color=lcd.BLACK)
img.draw_rectangle(l-15, t + self.selIdx * 60 -5 , 150 , 5+ 24 +5 , color=lcd.BLACK, thickness=1 , fill=False )
screen.display(img)
def onEvent(self,evtName,*args,**kw):
print(self.name , 'onEvent:',evtName,*args,**kw)
if len(self.childApps)>0:
print("super().onEvent(self,evtName,*args,**kw)")
super().onEvent(self,evtName,*args,**kw)
else:
if evtName=='btn2_pressed':
if self.selIdx == 0:# ONE PLAYER
app = self._startChildApp(appSimple,'ONE')
app.setup(**{'cnt':0,'screen':self.data['screen']})
print('start ONE')
#self.stat == OneAppStats.BACK
elif self.selIdx == 1:# TWO PLAYER
app = self._startChildApp(appSimple,'TWO')
app.setup(**{'cnt':0,'screen':self.data['screen']})
print('start TWO')
#self.stat == OneAppStats.BACK
elif self.selIdx == 2:# AI PLAYER
app = self._startChildApp(appSimple,'THREE')
app.setup(**{'cnt':0,'screen':self.data['screen']})
print('start THREE')
#self.stat == OneAppStats.BACK
else:
print('error idx',self.selIdx)
if evtName=='btn1_pressed':
if self.selIdx==2:
self.selIdx=0
else:
self.selIdx = self.selIdx +1
print('self.selIdx',self.selIdx)
utime.sleep_ms(300)
def call_object_method(obj,method_name,*args,**kv):
if method_name in dir(obj):
getattr(obj,method_name)(method_name,*args,**kv)
# 以下代码 在 sipeed Maix Bit 测试通过
import lcd,image
import utime
from Maix import GPIO
from fpioa_manager import fm
lcd.init(type=1, freq=15000000, color=lcd.BLACK, invert = 0, lcd_type = 0)
lcd.clear()
root = SysApp('root')
root.setup(**{'screen':lcd})
def test_irq22(pin_num):
key22.disirq() # 禁用中断
print("key", pin_num, '2at',utime.ticks(),"\n")
#call_object_method(root,'onEvent','btn1_pressed',pin_num)
root.onEvent('btn1_pressed',pin_num)
utime.sleep_ms(300)
key22.irq(test_irq22, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
def test_irq23(pin_num):
key23.disirq() # 禁用中断
print("key", pin_num, '3at',utime.ticks(),"\n")
#call_object_method(root,'onEvent','btn2_pressed',pin_num)
root.onEvent('btn2_pressed',pin_num)
utime.sleep_ms(300)
key23.irq(test_irq23, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
fm.register(22, fm.fpioa.GPIOHS0)
key22 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_NONE)
fm.register(23, fm.fpioa.GPIOHS1)
key23 = GPIO(GPIO.GPIOHS1, GPIO.IN, GPIO.PULL_NONE)
utime.sleep_ms(100)
key22.irq(test_irq22, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
key23.irq(test_irq23, GPIO.IRQ_FALLING, GPIO.WAKEUP_NOT_SUPPORT,7)
while root.stat==OneAppStats.RUNNING:
print('root loop',root.loop() )
time.sleep(DEBUG_DELAY)
print('1111')
This is how it works
The running effect is to press the green button to modify the selected item, press the red button to instantiate the class of the corresponding item and exit after executing 20 cycles.
During the execution phase, you can still respond to button interrupts.
|