Показаны различия между двумя версиями страницы.
| Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия | ||
| products:laboratory_iot:exp50 [2020/06/01 18:42] – [Схема эксперимента] labuser29 | products:laboratory_iot:exp50 [2021/07/21 16:47] (текущий) – [Программный код эксперимента] labuser29 | ||
|---|---|---|---|
| Строка 14: | Строка 14: | ||
| {{ : | {{ : | ||
| - | // | + | // |
| + | {{ : | ||
| + | // | ||
| ==== Класс Stopwatch==== | ==== Класс Stopwatch==== | ||
| - | <code python | + | <code python |
| + | class Stopwatch: | ||
| + | def __init__(self): | ||
| + | self.hours = 0 # Значение часов | ||
| + | self.mins = 0 # Значение минут | ||
| + | self.secs = 0 # Значение секунд | ||
| + | self.start_time = 0 # Время запуска | ||
| + | self.state = 0 # Состояние. 0 - секундомер не запущен, | ||
| + | self.backcolor = tft.rgbcolor(255, | ||
| + | self.fontcolor = tft.rgbcolor(39, | ||
| + | self.draw_init() # Вызов функции отображения начального значения- нулей | ||
| + | |||
| + | # Функция вывода начального значения секундомера- нулей | ||
| + | def draw_init(self): | ||
| + | self.draw_value(98, | ||
| + | self.draw_value(55, | ||
| + | self.draw_value(5, | ||
| + | |||
| + | # Выводим разделитель часов и минут | ||
| + | tft.text(41, | ||
| + | # Выводим разделитель минут и секунд | ||
| + | tft.text(90, | ||
| + | |||
| + | |||
| + | # Основная функция секундомера, | ||
| + | def tick(self): | ||
| + | if self.state: # отсчет производим только, | ||
| + | # Находим разницу в миллисекундах между текущим временем и временем запуска | ||
| + | diff = time.ticks_diff(time.ticks_ms(), | ||
| + | hours = diff // (1000 * 60 * 60) # Деление без остатка. Находим сколько целых часов прошло | ||
| + | diff = diff % (1000 * 60 * 60) # Находим остаток после деления на часы и сохраняем в diff | ||
| + | mins = diff // (1000 * 60) # Деление без остатка. Находим сколько целых минут прошло | ||
| + | diff = diff % (1000 * 60) # Находим остаток после деления на минуты и сохраняем в diff | ||
| + | secs = diff // (1000) # Деление без остатка. Находим сколько целых секунд прошло | ||
| + | |||
| + | # Если сохраненное ранее значение секунд отличается от вычисленных- обновляем и выводим на дисплей | ||
| + | if secs != self.secs: | ||
| + | self.secs = secs | ||
| + | self.draw_value(98, | ||
| + | |||
| + | # Если сохраненное ранее значение минут отличается от вычисленных- обновляем и выводим на дисплей | ||
| + | if mins != self.mins: | ||
| + | self.mins = mins | ||
| + | self.draw_value(55, | ||
| + | |||
| + | # Если сохраненное ранее значение часов отличается от вычисленных- обновляем и выводим на дисплей | ||
| + | if hours != self.hours: | ||
| + | self.hours = hours | ||
| + | self.draw_value(5, | ||
| + | |||
| + | |||
| + | # Функция запуска и остановки секундомера | ||
| + | def start_stop(self): | ||
| + | if self.state: # Если секундомер запущен- останавливаем | ||
| + | self.state = 0 | ||
| + | else: # Иначе- запускаем | ||
| + | self.state = 1 | ||
| + | self.start_time = time.ticks_ms() # Сохраняем время запуска секундомера | ||
| + | |||
| + | |||
| + | # Функция отображения на дисплее значений | ||
| + | def draw_value(self, | ||
| + | # Перед выводом на дисплей новых данных закрашиваем старые прямоугольником с цветом фона | ||
| + | tft.rect(x+2, | ||
| + | |||
| + | # Если значение для вывода менее 10, то добавляем ведущий ноль, чтобы всегда было 2 знака | ||
| + | # конвертируем значение из числа в строку | ||
| + | if value < 10: | ||
| + | value = ' | ||
| + | else: | ||
| + | value = str(value) | ||
| + | |||
| + | # Выводим значение в виде строки на дисплей в нужном месте нужным цветом и размером | ||
| + | tft.text(x, y, value, font.terminalfont, | ||
| + | </ | ||
| + | |||
| + | Класс содержит конструктор '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Код класса снабжен комментариями, | ||
| + | |||
| + | Функция '' | ||
| + | |||
| + | Заострим внимание на вычислении количества часов: | ||
| + | <code python> | ||
| + | hours = diff // (1000 * 60 * 60) | ||
| + | diff = diff % (1000 * 60 * 60) | ||
| + | </ | ||
| + | |||
| + | Оператор '' | ||
| + | А оператор '' | ||
| + | |||
| + | Сначала мы вычисляем целое количество часов, а потом мы вычисляем по сути сколько осталось после выделения целого количества часов. После этого там останется значение меньше одного часа. Его мы уже будем делить на минуты. А после вычитания минут будем определять сколько осталось секунд. | ||
| + | |||
| + | Теперь сделаем программу с использованием данного класса | ||
| + | |||
| + | ==== Программный код эксперимента ==== | ||
| + | |||
| + | <file python Exp50.py[enable_line_numbers=" | ||
| + | from machine import Pin, SPI | ||
| + | from tft import TFT_GREEN | ||
| + | import font | ||
| + | import time | ||
| + | _init() | ||
| + | machine.freq(160000000) | ||
| + | |||
| + | |||
| + | dc = Pin(4, Pin.OUT) | ||
| + | cs = Pin(2, Pin.OUT) | ||
| + | rst = Pin(5, Pin.OUT) | ||
| + | |||
| + | spi = SPI(1, baudrate=40000000, | ||
| + | tft = TFT_GREEN(128, | ||
| + | |||
| + | tft.initr(tft.BGR) # tft.initr(tft.RGB) #Если вместо синего цвета отображается красный, | ||
| + | tft.clear(tft.rgbcolor(255, | ||
| + | tft.draw_bmp(0, | ||
| + | |||
| class Stopwatch: | class Stopwatch: | ||
| def __init__(self): | def __init__(self): | ||
| Строка 67: | Строка 190: | ||
| else: | else: | ||
| self.state = 1 | self.state = 1 | ||
| - | #if not self.start_time: | ||
| self.start_time = time.ticks_ms() | self.start_time = time.ticks_ms() | ||
| + | |||
| def draw_value(self, | def draw_value(self, | ||
| Строка 79: | Строка 202: | ||
| tft.text(x, y, value, font.terminalfont, | tft.text(x, y, value, font.terminalfont, | ||
| + | |||
| + | |||
| + | class Button: | ||
| + | def __init__(self, | ||
| + | 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.start_stop() | ||
| + | |||
| + | while True: | ||
| + | stopwatch.tick() | ||
| + | </ | ||
| + | |||
| + | Код эксперимента должен быть понятен. Сначала как обычно подключаем библиотеки, | ||
| + | <code python[enable_line_numbers=" | ||
| + | stopwatch = Stopwatch() | ||
| </ | </ | ||
| + | |||
| + | Запускаем его | ||
| + | <code python[enable_line_numbers=" | ||
| + | stopwatch.start_stop() | ||
| + | </ | ||
| + | |||
| + | И в бесконечном цикле вызываем его метод '' | ||
| + | <code python[enable_line_numbers=" | ||
| + | while True: | ||
| + | stopwatch.tick() | ||
| + | </ | ||
| + | |||
| + | Теперь наш секундомер умеет считать время. Но еще не слушается управления. В следующем эксперименте мы добавим управление с помощью кнопки и получим полноценный секундомер. | ||