Различия

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

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

Следующая версия
Предыдущая версия
products:laboratory_iot_c:exp54 [2024/12/15 17:31] – создано labuser30products:laboratory_iot_c:exp54 [2024/12/15 17:38] (текущий) – [Программный код эксперимента] labuser30
Строка 14: Строка 14:
 ==== Программный код эксперимента ==== ==== Программный код эксперимента ====
  
-<file python Exp54.py[enable_line_numbers="2", start_line_numbers_at="1"]> +<file arduino Exp54.ino[enable_line_numbers="2", start_line_numbers_at="1"]> 
-from machine import Pin, SPI +#include <SPI.h> 
-from tft import TFT_GREEN +#include <Adafruit_ST7735.h> 
-_init() +#include "LittleFS_ImageReader.h" 
-machine.freq(160000000)+
  
 +#define PIN_CS  2
 +#define PIN_DC  4
 +#define PIN_RST 5
  
-dc  Pin(4Pin.OUT) #a0 +Adafruit_ST7735 tft Adafruit_ST7735(PIN_CS,  PIN_DCPIN_RST); 
-cs  = Pin(2Pin.OUT+LittleFS_ImageReader reader;
-rst = Pin(5, Pin.OUT) +
-spi = SPI(1, baudrate=40000000, polarity=0, phase=0)+
  
 +bool Map[10][8] = {
 +  {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}
 +};
  
-# TFT object, this is ST7735R green tab version +struct Pos { 
-tft TFT_GREEN(128, 160, spi, dc, cs, rst, rotate=0)+  int x 0; 
 +  int y = 0;
  
-Map [ +  bool operator == (const Pos &pos) const { 
-    [1,1,0,1,1,1,0,1], +    return x == pos.x && y == pos.y; 
-    [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 [] +class Box { 
-Boxes []+  private: 
 +    Adafruit_ST7735 *tft_ptr; 
 +    LittleFS_ImageReader *reader_ptr; 
 +    Pos pos; 
 +    String picture = "/box.bmp"; 
 +    String picture_on_gate "/boxngate.bmp"; 
 +    bool on_gate false;
  
-class Box+  public
-    def __init__(selftft, x, y): +    Box(Adafruit_ST7735 *_tft_ptrLittleFS_ImageReader *_reader_ptrint x, int y) { 
-        self.tft tft +      tft_ptr _tft_ptr; 
-        self.x = x +      reader_ptr = _reader_ptr; 
-        self.y = y +      pos.x = x; 
-        self.picture = 'box.bmp' +      pos.y = y; 
-        self.picture_onGate 'boxngate.bmp' +      
-        self.onGate False +     
-        self.draw()+    void draw() { 
 +      if (on_gate) reader_ptr->drawBMP(picture_on_gate, *tft_ptr, pos.x * 16, pos.y * 16); 
 +      else reader_ptr->drawBMP(picture, *tft_ptr, pos.x * 16, pos.y * 16);  
 +    } 
 +  
 +    void setOnGate(bool state) { 
 +      on_gate = state; 
 +    } 
 +         
 +    bool getOnGate() const { 
 +      return on_gate; 
 +    } 
 +  
 +    Pos getPos() const { 
 +      return pos; 
 +    } 
 +  
 +    void setPos(Pos _pos) {  
 +      pos._pos.x; 
 +      pos._pos.y; 
 +      draw()
 +    } 
 +};        
  
-    def draw(self): +class Gate { 
-        if (self.onGate)+  private
-            self.tft.draw_bmp(self.x 16,self.y 16,  self.picture_onGate) +    Adafruit_ST7735 *tft_ptr; 
-        else: +    LittleFS_ImageReader *reader_ptr; 
-            self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture)+    Pos pos; 
 +    String picture  = "/gate.bmp";
  
-    def setOnGate(selfstate): +  public: 
-        self.onGate state+    Gate(Adafruit_ST7735 *_tft_ptrLittleFS_ImageReader *_reader_ptr, int x, int y{ 
 +      tft_ptr = _tft_ptr; 
 +      reader_ptr = _reader_ptr; 
 +      pos.x; 
 +      pos.y = y; 
 +    } 
  
-    def getOnGate(self): +    void draw() const { 
-        return self.onGate+      reader_ptr->drawBMP(picture, *tft_ptr, pos.x * 16, pos.y * 16); 
 +    } 
  
-    def getPos(self): +    Pos getPos() const { 
-        return (self.x, self.y)+      return pos; 
 +    } 
 +};
  
-    def setPos(self, x, y)+class Man { 
-        self.x = x +  private
-        self.y +    Adafruit_ST7735 *tft_ptr; 
-        self.draw()+    LittleFS_ImageReader *reader_ptr; 
 +    Pos pos; 
 +    String picture  "/man.bmp";
  
-class Gate+  public
-    def __init__(selftft, x, y): +    Man(Adafruit_ST7735 *_tft_ptrLittleFS_ImageReader *_reader_ptrint x, int y) { 
-        self.tft tft +      Serial.println("Man constructor"); 
-        self.x = x +      tft_ptr _tft_ptr; 
-        self.y = y +      reader_ptr = _reader_ptr; 
-        self.picture = 'gate.bmp' +      pos.x = x; 
-        self.draw()+      pos.y = y; 
 +    
  
-    def draw(self): +    void draw() const { 
-        self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture)+      reader_ptr->drawBMP(picture, *tft_ptr, pos.x * 16, pos.y * 16)
 +    }
  
-    def getPos(self): +    Pos getPos() const { 
-        return (self.x, self.y)+      return pos; 
 +    }
  
-class Man: +    void setPos(Pos _pos) {  
-    def __init__(self, tft, x, y): +      tft_ptr->fillRect(pos.* 16pos.* 16, 16, 16, ST77XX_BLACK); 
-        self.tft tft +      pos._pos.x; 
-        self.x = x +      pos.y = _pos.y; 
-        self.y = y +      draw()
-        self.picture = 'man.bmp' +    } 
-        self.draw()+};
  
-    def draw(self): +class Button { 
-        self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture)+  private: 
 +    int pin; 
 +    bool pressState; 
 +    bool oldState; 
 +  
 +  public:  
 +    Button(int _pin, bool _pressState
 +      pin = _pin; 
 +      setPinMode(); 
 +      pressState = _pressState; 
 +      oldState = not _pressState; 
 +    } 
 +  
 +    bool onPress() { 
 +      bool state = digitalRead(pin); 
 +      if (state != oldState){ 
 +        oldState = state; 
 +        if (state == pressStatereturn true; 
 +      } 
 +      return false; 
 +    }
  
-    def getPos(self): +    void setPinMode() const { 
-        return (self.xself.y)+      pinMode(pinINPUT)
 +    } 
 +}; 
  
-    def setPos(selfxy): +const int boxes_number = 3; 
-        self.tft.rect(self.x * 16self.y * 161616tft.COLOR_BLACK) +Box boxes[boxes_number] = { 
-        self.x = x +  {&tft&reader, 3, 4}
-        self.y = y +  {&tft, &reader46}
-        self.draw()+  {&tft, &reader, 2, 7},   
 +};
  
 +const int gates_number = 3;
 +Gate gates[gates_number] = {
 +  {&tft, &reader, 6, 3},
 +  {&tft, &reader, 6, 4},
 +  {&tft, &reader, 6, 5},  
 +};
  
-class Button: +Man man(&tft&reader56);
-    def __init__(selfppressSate): +
-        self.pin = Pin(pPin.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+
  
 +Button btn_up(16, HIGH);
 +Button btn_down(15, HIGH);
 +Button btn_left(12, HIGH);
 +Button btn_right(0, LOW);
  
-# init TFT +void setup() { 
-tft.initr(tft.BGR# tft.initr(tft.RGB#Если вместо синего цвета отображается красный, а вместо красного синий +  Serial.begin(9600); 
-tft.clear(tft.COLOR_BLACK#b, g, r+  Serial.println()
 +  Serial.println("Setup"); 
 +  LittleFS.begin(); 
 +  tft.initR(INITR_BLACKTAB); 
 +  tft.setRotation(2); 
 +  tft.fillScreen(ST77XX_BLACK)
  
-= 0 +  for (int y = 0< 10; y++) { 
-y = 0+    for (int x = 0; x < 10; x++) { 
 +      if (Map[y][x]) reader.drawBMP("/brick.bmp", tft, x * 16, y * 16); 
 +    } 
 +  } 
  
-for row in Map: +  for (int i = 0; i < boxes_number; i++) { 
-    for col in row: +    boxes[i].draw(); 
-        if col: +  }
-            tft.draw_bmp(x * 16, y * 16,'brick.bmp'+
-        x+=1 +
-    x=0 +
-    y+=1+
  
-Boxes.append(Box(tft, 3,4)+  for (int i = 0; i < gates_number; i++{ 
-Boxes.append(Box(tft, 4,6)+    gates[i].draw(); 
-Boxes.append(Box(tft, 2,7))+  } 
 +   
 +  man.draw();
  
-Gates.append(Gate(tft, 6,3)+  btn_left.setPinMode(); 
-Gates.append(Gate(tft, 6,4)) +}
-Gates.append(Gate(tft, 6,5))+
  
-man Man(tft, 5, 6)+void loop() { 
 +  Pos man_pos man.getPos();
  
-btnUp = Button(16, 1) +  if (btn_up.onPress()) man.setPos({man_pos.xman_pos.y - 1}); 
-btnDown = Button(15, 1) +  if (btn_down.onPress()) man.setPos({man_pos.xman_pos.y + 1}); 
-btnLeft = Button(12, 1) +  if (btn_left.onPress()) man.setPos({man_pos.x - 1, man_pos.y}); 
-btnRight = Button(0, 0) +  if (btn_right.onPress()) man.setPos({man_pos.x + 1, man_pos.y})
- +}
-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> </file>
  
 В код прошлого эксперимента мы добавили класс кнопки, который уже использовали ранее, например в проекте секундомера. Объявили 4 кнопки, на выводах 16, 15, 12 и 0: В код прошлого эксперимента мы добавили класс кнопки, который уже использовали ранее, например в проекте секундомера. Объявили 4 кнопки, на выводах 16, 15, 12 и 0:
-<code python[enable_line_numbers="2", start_line_numbers_at="137"]> +<code arduino[enable_line_numbers="2", start_line_numbers_at="175"]> 
-btnUp = Button(16, 1+Button btn_up(16, HIGH); 
-btnDown = Button(15, 1+Button btn_down(15, HIGH); 
-btnLeft = Button(12, 1+Button btn_left(12, HIGH); 
-btnRight = Button(0, 0)+Button btn_right(0, LOW);
 </code> </code>
  
-Добавили бесконечный циклв котором постоянно мониторим события нажатия на кнопки: +В класс Button мы добавили метод ''setPinMode()'' и вызываем его для кнопки на 12 пине, хотя он уже вызывался в конструкторе. Это необходимотак как метод дисплея ''initR()'' вызывает переопределение режима пина 12. 
-<code python[enable_line_numbers="2", start_line_numbers_at="137"]> +<code arduino[enable_line_numbers="2", start_line_numbers_at="205"]> 
-while True: +btn_left.setPinMode(); 
-    mPos = man.getPos() +</code>
- +
-    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]-1mPos[1]) +<code arduino[enable_line_numbers="2"start_line_numbers_at="209"]> 
-        man.setPos(newPos[0], newPos[1])+  Pos man_pos = man.getPos();
  
-    if btnRight.onPress(): +  if (btn_up.onPress()) man.setPos({man_pos.x, man_pos.y - 1}); 
-        newPos = (mPos[0]+1, mPos[1]+  if (btn_down.onPress()) man.setPos({man_pos.x, man_pos.y + 1}); 
-        man.setPos(newPos[0]newPos[1])+  if (btn_left.onPress()) man.setPos({man_pos.x - 1man_pos.y}); 
 +  if (btn_right.onPress()) man.setPos({man_pos.x + 1, man_pos.y});
 </code> </code>
  
 При нажатии на кнопку "вверх" уменьшаем координату Y и задаем новую координату кладовщику. Аналогичные действия производим при нажатии на другие кнопки. Теперь наш кладовщик может двигаться по экрану. Но сейчас нет никаких ограничений — он свободно проходит сквозь стены и ящики, никак на них не влияя. Теперь самое время реализовать логику игры, описать условия и взаимодействия. Этим займемся в следующем эксперименте.  При нажатии на кнопку "вверх" уменьшаем координату Y и задаем новую координату кладовщику. Аналогичные действия производим при нажатии на другие кнопки. Теперь наш кладовщик может двигаться по экрану. Но сейчас нет никаких ограничений — он свободно проходит сквозь стены и ящики, никак на них не влияя. Теперь самое время реализовать логику игры, описать условия и взаимодействия. Этим займемся в следующем эксперименте.