Различия

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

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

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
products:laboratory_iot_c:exp50 [2024/12/13 16:06] – [Класс Stopwatch] labuser30products:laboratory_iot_c:exp50 [2024/12/13 17:12] (текущий) – [Программный код эксперимента] labuser30
Строка 105: Строка 105:
     void startStop() {     void startStop() {
       state = !state; // Инвертируем состояние секундомера       state = !state; // Инвертируем состояние секундомера
-      if (state) start_time = millis(); // Если запущен схраняем время запуска секундомера  +      if (state) start_time = millis(); // Если запущен сохраняем время запуска секундомера  
     }     }
 }; };
 </code> </code>
  
-Класс содержит конструктор методы: +Класс содержит методы: 
-  ''draw_init'' +  * ''init'' — используется вместо конструктора и вызывается в функции  ''setup()''. 
-  * ''draw_init'' — отображает начальное значение таймера, нули, как в прошлом эксперименте. +  * ''drawInit'' — отображает начальное значение таймера, нули, как в прошлом эксперименте. 
-  * ''start_stop'' — запускает и останавливает секундомер.  +  * ''startStop'' — запускает и останавливает секундомер.  
-  * ''draw_value'' — выводит значение часов минут или секунд. В качестве параметров принимает координаты, размер шрифта и значение.+  * ''drawValue'' — выводит значение часов минут или секунд. В качестве параметров принимает координаты, размер шрифта и значение.
   * ''tick'' — системная функция секундомера. Она определяет сколько часов, минут и секунд прошло с момента его запуска. Эту функцию необходимо вызывать постоянно.   * ''tick'' — системная функция секундомера. Она определяет сколько часов, минут и секунд прошло с момента его запуска. Эту функцию необходимо вызывать постоянно.
  
 Код класса снабжен комментариями, подробно описывающими почти каждую строку. Кроме этого дадим несколько пояснений. Когда мы говорим "Сохраняем время запуска секундомера", то имеется в виду, что мы сохраняем значение количества миллисекунд с момента запуска микроконтроллера. И все упоминания времени следует читать в этом ключе. Код класса снабжен комментариями, подробно описывающими почти каждую строку. Кроме этого дадим несколько пояснений. Когда мы говорим "Сохраняем время запуска секундомера", то имеется в виду, что мы сохраняем значение количества миллисекунд с момента запуска микроконтроллера. И все упоминания времени следует читать в этом ключе.
- 
-Функция ''diff = time.ticks_diff(time.ticks_ms(), self.start_time)'' нужна для нахождения разницы между  количеством миллисекунд, прошедших со старта микроконтроллера при запуске секундомера и сейчас. Несмотря на то, что это есть обычное число, которое можно было бы вычесть обычным знаком минус, лучше это делать с помощью данной функции. Дело в том, что это значение может переполниться и обнулиться и начать считать "по второму кругу". Тогда простое вычитание даст ошибку. Только функция ''ticks_diff'' гарантирует правильное значение. 
  
 Заострим внимание на вычислении количества часов: Заострим внимание на вычислении количества часов:
-<code python+<code arduino
-hours = diff // (1000 * 60 * 60) +int hours_cur = diff / (1000 * 60 * 60); 
-diff = diff % (1000 * 60 * 60)+diff = diff % (1000 * 60 * 60);
 </code> </code>
  
-Оператор ''%%//%%'' — это оператор деления без остатка. Например 5 %%//%% 2 = 2. А остаток 0.5 был отброшен.+Оператор ''%%/%%'' — это оператор деления без остатка. Например 5 %%/%% 2 = 2. А остаток 0.5 был отброшен.
 А оператор ''%'' — напротив возвращает только остаток от деления. 5 % 2 = 0.5 А оператор ''%'' — напротив возвращает только остаток от деления. 5 % 2 = 0.5
  
 Сначала мы вычисляем целое количество часов, а потом мы вычисляем по сути сколько осталось после выделения целого количества часов. После этого там останется значение меньше одного часа. Его мы уже будем делить на минуты. А после вычитания минут будем определять сколько осталось секунд. Сначала мы вычисляем целое количество часов, а потом мы вычисляем по сути сколько осталось после выделения целого количества часов. После этого там останется значение меньше одного часа. Его мы уже будем делить на минуты. А после вычитания минут будем определять сколько осталось секунд.
  
-Теперь сделаем программу с использованием данного класса+Теперь сделаем программу с использованием данного класса.
  
 ==== Программный код эксперимента ==== ==== Программный код эксперимента ====
  
-<file python Exp50.py[enable_line_numbers="2", start_line_numbers_at="1"]> +<file arduino Exp50.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> 
-import font +#include "LittleFS_ImageReader.h" 
-import time +
-_init() +
-machine.freq(160000000)+
  
 +#define PIN_CS  2
 +#define PIN_DC  4
 +#define PIN_RST 5
  
-dc  Pin(4Pin.OUT)  +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) +class Stopwatch { 
-tft TFT_GREEN(128160spidccs, rst, rotate=0)+  private: 
 +    unsigned int hours 0;  
 +    unsigned int mins 0;  
 +    unsigned int secs = 0;   
 +    unsigned long start_time = 0; 
 +    bool state 0;  
 +    unsigned int backcolor = tft.color565(255251240);  
 +    unsigned int fontcolor = tft.color565(394051);   
  
-tft.initr(tft.BGRtft.initr(tft.RGB#Если вместо синего цвета отображается красный, а вместо красного синий +  public: 
-tft.clear(tft.rgbcolor(255,251,240))  +    void init() {   
-tft.draw_bmp(0,0,'time.bmp')+      tft.fillScreen(backcolor) 
 +      reader.drawBMP("/time.bmp"tft, 0, 0)
 +      drawInit();  
 +    } 
  
 +    void drawInit() {
 +      drawValue(8, 125, 3, 0);  
 +      drawValue(55, 125, 3, 0); 
 +      drawValue(98, 132, 2, 0);
  
-class Stopwatch: +      tft.setTextColor(fontcolor) 
-    def __init__(self): +       
-        self.hours = 0 +      tft.setCursor(41125) 
-        self.mins = 0 +      tft.setTextSize(3); 
-        self.secs = 0 +      tft.print(":");
-        self.start_time = 0 +
-        self.state = 0 +
-        self.backcolor = tft.rgbcolor(255,251,240+
-        self.fontcolor = tft.rgbcolor(39,40,51+
-        self.draw_init()+
  
 +      tft.setCursor(88, 132);  
 +      tft.setTextSize(2); 
 +      tft.print(":");
 +    }
  
-    def draw_init(self): +    void drawValue(int xint yint sizeint value{ 
-        self.draw_value(9813220+      tft.fillRect(xy6 * size * 28 * size -2backcolor);
-        self.draw_value(5512530) +
-        self.draw_value(5, 125, 30)+
  
-        tft.text(41125, ":", font.terminalfont, self.fontcolor, 3+      tft.setCursor(xy);   
-        tft.text(90, 130, ":", font.terminalfont, self.fontcolor, 2)+      tft.setTextColor(fontcolor); 
 +      tft.setTextSize(size);
  
 +      if (value < 10) tft.print(0);
 +      tft.print(value); 
 +    }
  
-    def tick(self): +    void tick() { 
-        if self.state: +      if (state) {  
-            diff = time.ticks_diff(time.ticks_ms(), self.start_time) +        unsigned long diff = millis() start_time; 
-            hours = diff // (1000 * 60 * 60) +        int hours_cur = diff / (1000 * 60 * 60) 
-            diff = diff % (1000 * 60 * 60) +        diff = diff % (1000 * 60 * 60) 
-            mins = diff // (1000 * 60) +        int mins_cur = diff / (1000 * 60) 
-            diff = diff % (1000 * 60) +        diff = diff % (1000 * 60) 
-            secs = diff // (1000)+        int secs_cur = diff / (1000)
  
-            if secs != self.secs: +        if (hours_cur != hours) { 
-                self.secs secs +            hours hours_cur;  
-                self.draw_value(981322secs)+            drawValue(81253hours)
 +        }
  
-            if mins != self.mins: +        if (mins_cur != mins) { 
-                self.mins = mins +          mins = mins_cur; 
-                self.draw_value(55, 125, 3, mins) +          drawValue(55, 125, 3, mins); 
- +        }
-            if hours != self.hours: +
-                self.hours = hours +
-                self.draw_value(5, 125, 3, hours)+
                  
 +        if (secs_cur != secs) {
 +          secs = secs_cur;
 +          drawValue(98, 132, 2, secs);
 +        }
 +      }
 +    }
  
-    def start_stop(self): +    void startStop() { 
-        if self.state: +      state = !state 
-            self.state = +      if (statestart_time millis() 
-        else: +    } 
-            self.state = 1 +};
-            self.start_time = time.ticks_ms() +
- +
- +
-    def draw_value(self, x, y, size, value): +
-        tft.rect(x+2, y, 6 * size * 2, 8 * size -2, self.backcolor) +
- +
-        if value < 10: +
-            value = '0' + str(value) +
-        else: +
-            value str(value) +
- +
-        tft.text(x, y, value, font.terminalfont, self.fontcolor, size) +
- +
- +
-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+
  
 +Stopwatch stopwatch;
  
-stopwatch = Stopwatch() +void setup() { 
-stopwatch.start_stop()+  os_update_cpu_frequency(160); 
 +  LittleFS.begin(); 
 +  tft.initR(INITR_BLACKTAB); 
 +  tft.setRotation(2);  
 +   
 +  stopwatch.init(); 
 +  stopwatch.startStop()
 +}
  
-while True: +void loop() { 
-    stopwatch.tick()+  stopwatch.tick()
 +}
 </file> </file>
  
-Код эксперимента должен быть понятен. Сначала как обычно подключаем библиотеки, настраиваем SPI и дисплей. Потом код класса секундомера и в конце мы создаем объект секундомера +Код эксперимента должен быть понятен. Сначала как обычно подключаем библиотеки и дисплей. Потом код класса секундомера и в конце мы создаем объект секундомера. 
-<code python[enable_line_numbers="2", start_line_numbers_at="98"]> +<code arduino[enable_line_numbers="2", start_line_numbers_at="88"]> 
-stopwatch = Stopwatch()+Stopwatch stopwatch;
 </code> </code>
  
-Запускаем его +Инициализируем и запускаем его. 
-<code python[enable_line_numbers="2", start_line_numbers_at="99"]> +<code arduino[enable_line_numbers="2", start_line_numbers_at="96"]> 
-stopwatch.start_stop()+  stopwatch.init(); 
 +  stopwatch.startStop();
 </code> </code>
  
-И в бесконечном цикле вызываем его метод ''tick()''. В нем он занимается отслеживаем времени и отображением изменений на дисплее +И в бесконечном цикле вызываем его метод ''tick()''. В нем он занимается отслеживаем времени и отображением изменений на дисплее. 
-<code python[enable_line_numbers="2", start_line_numbers_at="101"]> +<code arduino[enable_line_numbers="2", start_line_numbers_at="101"]> 
-while True: +  stopwatch.tick();
-    stopwatch.tick()+
 </code> </code>
  
 Теперь наш секундомер умеет считать время. Но еще не слушается управления. В следующем эксперименте мы добавим управление с помощью кнопки и получим полноценный секундомер. Теперь наш секундомер умеет считать время. Но еще не слушается управления. В следующем эксперименте мы добавим управление с помощью кнопки и получим полноценный секундомер.