Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
products:laboratory_iot:exp54 [2020/06/12 09:50] labuser29products:laboratory_iot:exp54 [2021/07/21 17:04] (текущий) – [Схема эксперимента] labuser29
Строка 1: Строка 1:
 ===== Эксперимент 54. Управление кладовщиком ===== ===== Эксперимент 54. Управление кладовщиком =====
  
-Научим кладовщика двигаться при нажатии на кнопки "вверх", "вниз", "влево" и "вправо". Кроме того добавим логику, обеспечивающую запрет прохождения кладовщика сквозь стены.+Научим кладовщика двигаться при нажатии на кнопки "вверх", "вниз", "влево" и "вправо"
  
-Подключим кнопки к микроконтроллеру. Три кнопки подтянуты к земле, а одна к питанию. Это сделано специально, чтобы обеспечить условия для правильной загрузки микроконтроллера. Микроконтроллер при включении проверяет состояние некоторых выводов и на соновании этого принимает решение о режиме работы — выполнение программы или переход в режим перепрошивки. Для нормального режима работы необходимо, чтобы уровень сигнала на выводе 15 был низким, а на 2 и 0 был высоким. Чтобы соблюсти эти условия и пришлось подключить кнопки по-разному.+Подключим кнопки к микроконтроллеру. Три кнопки подтянуты к земле, а одна к питанию. Это сделано специально, чтобы обеспечить условия для правильной загрузки микроконтроллера. Микроконтроллер при включении проверяет состояние некоторых выводов и на основании этого принимает решение о режиме работы — выполнение программы или переход в режим перепрошивки. Для нормального режима работы необходимо, чтобы уровень сигнала на выводе 15 был низким, а на 2 и 0 был высоким. Чтобы соблюсти эти условия и пришлось подключить кнопки по-разному
 + 
 +==== Схема эксперимента ==== 
 + 
 +{{ :products:esp-iot:exp27_mont.png?direct&600 |}} 
 +//Рисунок 1. Монтажная схема эксперимента с 8 выводами// 
 + 
 +{{ :products:esp-iot:exp27_mont_11pin.png?direct&600 |}} 
 +//Рисунок 2. Монтажная схема эксперимента с 11 выводами// 
 +==== Программный код эксперимента ==== 
 + 
 +<file python Exp54.py[enable_line_numbers="2", start_line_numbers_at="1"]> 
 +from machine import Pin, SPI 
 +from tft import TFT_GREEN 
 +_init() 
 +machine.freq(160000000) 
 + 
 + 
 +dc  = Pin(4, Pin.OUT) #a0 
 +cs  = Pin(2, Pin.OUT) 
 +rst = Pin(5, Pin.OUT) 
 +spi = SPI(1, baudrate=40000000, polarity=0, phase=0) 
 + 
 + 
 +# TFT object, this is ST7735R green tab version 
 +tft = TFT_GREEN(128, 160, spi, dc, cs, rst, rotate=0) 
 + 
 +Map = [ 
 +    [1,1,0,1,1,1,0,1], 
 +    [0,1,1,1,1,1,1,0], 
 +    [1,1,0,0,0,1,1,1], 
 +    [0,1,0,1,0,1,0,1], 
 +    [0,1,0,0,0,1,0,1], 
 +    [1,1,1,1,0,0,0,1], 
 +    [1,0,0,0,0,0,0,1], 
 +    [1,0,0,0,1,0,0,1], 
 +    [1,0,0,0,1,1,1,1], 
 +    [1,1,1,1,1,0,0,0] 
 +
 + 
 +Gates = [] 
 +Boxes = [] 
 + 
 +class Box: 
 +    def __init__(self, tft, x, y): 
 +        self.tft = tft 
 +        self.x = x 
 +        self.y = y 
 +        self.picture = 'box.bmp' 
 +        self.picture_onGate = 'boxngate.bmp' 
 +        self.onGate = False 
 +        self.draw() 
 + 
 +    def draw(self): 
 +        if (self.onGate): 
 +            self.tft.draw_bmp(self.x * 16,self.y * 16,  self.picture_onGate) 
 +        else: 
 +            self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture) 
 + 
 +    def setOnGate(self, state): 
 +        self.onGate = state 
 + 
 +    def getOnGate(self): 
 +        return self.onGate 
 + 
 +    def getPos(self): 
 +        return (self.x, self.y) 
 + 
 +    def setPos(self, x, y): 
 +        self.x = x 
 +        self.y = y 
 +        self.draw() 
 + 
 +class Gate: 
 +    def __init__(self, tft, x, y): 
 +        self.tft = tft 
 +        self.x = x 
 +        self.y = y 
 +        self.picture = 'gate.bmp' 
 +        self.draw() 
 + 
 +    def draw(self): 
 +        self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture) 
 + 
 +    def getPos(self): 
 +        return (self.x, self.y) 
 + 
 +class Man: 
 +    def __init__(self, tft, x, y): 
 +        self.tft = tft 
 +        self.x = x 
 +        self.y = y 
 +        self.picture = 'man.bmp' 
 +        self.draw() 
 + 
 +    def draw(self): 
 +        self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture) 
 + 
 +    def getPos(self): 
 +        return (self.x, self.y) 
 + 
 +    def setPos(self, x, y): 
 +        self.tft.rect(self.x * 16, self.y * 16, 16, 16, tft.COLOR_BLACK) 
 +        self.x = x 
 +        self.y = y 
 +        self.draw() 
 + 
 + 
 +class Button: 
 +    def __init__(self, p, pressSate): 
 +        self.pin = Pin(p, Pin.IN) 
 +        self.pressSate = pressSate 
 +        self.oldState = not pressSate 
 +     
 +    def onPress(self): 
 +        state = self.pin.value() 
 +        if state != self.oldState: 
 +            self.oldState = state 
 +            if state == self.pressSate: 
 +                return True 
 +        return False 
 + 
 + 
 +# init TFT 
 +tft.initr(tft.BGR) # tft.initr(tft.RGB) #Если вместо синего цвета отображается красный, а вместо красного синий 
 +tft.clear(tft.COLOR_BLACK) #b, g, r 
 + 
 +x = 0 
 +y = 0 
 + 
 +for row in Map: 
 +    for col in row: 
 +        if col: 
 +            tft.draw_bmp(x * 16, y * 16,'brick.bmp'
 +        x+=1 
 +    x=0 
 +    y+=1 
 + 
 +Boxes.append(Box(tft, 3,4)) 
 +Boxes.append(Box(tft, 4,6)) 
 +Boxes.append(Box(tft, 2,7)) 
 + 
 +Gates.append(Gate(tft, 6,3)) 
 +Gates.append(Gate(tft, 6,4)) 
 +Gates.append(Gate(tft, 6,5)) 
 + 
 +man = Man(tft, 5, 6) 
 + 
 +btnUp = Button(16, 1) 
 +btnDown = Button(15, 1) 
 +btnLeft = Button(12, 1) 
 +btnRight = Button(0, 0) 
 + 
 +while True: 
 +    mPos = man.getPos() 
 + 
 +    if btnUp.onPress(): 
 +        newPos = (mPos[0], mPos[1]-1) 
 +        man.setPos(newPos[0], newPos[1]) 
 + 
 +    if btnDown.onPress(): 
 +        newPos = (mPos[0], mPos[1]+1) 
 +        man.setPos(newPos[0], newPos[1]) 
 + 
 +    if btnLeft.onPress(): 
 +        newPos = (mPos[0]-1, mPos[1]) 
 +        man.setPos(newPos[0], newPos[1]) 
 + 
 +    if btnRight.onPress(): 
 +        newPos = (mPos[0]+1, mPos[1]) 
 +        man.setPos(newPos[0], newPos[1]) 
 +</file> 
 + 
 +В код прошлого эксперимента мы добавили класс кнопки, который уже использовали ранее, например в проекте секундомера. Объявили 4 кнопки, на выводах 16, 15, 12 и 0: 
 +<code python[enable_line_numbers="2", start_line_numbers_at="137"]> 
 +btnUp = Button(16, 1) 
 +btnDown = Button(15, 1) 
 +btnLeft = Button(12, 1) 
 +btnRight = Button(0, 0) 
 +</code> 
 + 
 +Добавили бесконечный цикл, в котором постоянно мониторим события нажатия на кнопки: 
 +<code python[enable_line_numbers="2", start_line_numbers_at="137"]> 
 +while True: 
 +    mPos = man.getPos() 
 + 
 +    if btnUp.onPress(): 
 +        newPos = (mPos[0], mPos[1]-1) 
 +        man.setPos(newPos[0], newPos[1]) 
 + 
 +    if btnDown.onPress(): 
 +        newPos = (mPos[0], mPos[1]+1) 
 +        man.setPos(newPos[0], newPos[1]) 
 + 
 +    if btnLeft.onPress(): 
 +        newPos = (mPos[0]-1, mPos[1]) 
 +        man.setPos(newPos[0], newPos[1]) 
 + 
 +    if btnRight.onPress(): 
 +        newPos = (mPos[0]+1, mPos[1]) 
 +        man.setPos(newPos[0], newPos[1]) 
 +</code> 
 + 
 +При нажатии на кнопку "вверх" уменьшаем координату Y и задаем новую координату кладовщику. Аналогичные действия производим при нажатии на другие кнопки. Теперь наш кладовщик может двигаться по экрану. Но сейчас нет никаких ограничений — он свободно проходит сквозь стены и ящики, никак на них не влияя. Теперь самое время реализовать логику игры, описать условия и взаимодействия. Этим займемся в следующем эксперименте