tariel.ge › Полезное: бесплатные книги › Программирование: от нулей и единиц до PythonБесплатно · автор Тариел Бежанидзе
← Учебник по программированию ЛИСТ 27БЛОК 5 — ФИНАЛ УЧЕБНИКАРЕВ. 1
Глава 27 · Финальный проект

Собираем рабочий CLI-инструмент — логгер показаний Arduino

Последняя глава — не новая тема, а сборка: полноценный инструмент командной строки, использующий практически каждую главу этой книги, от битов до Git.

Что собираем

Инструмент командной строки, который подключается к Arduino (глава 26), периодически читает показания датчика и записывает их в CSV-файл с меткой времени (глава 19) — но, в отличие от главы 26, теперь это настоящая программа с аргументами командной строки, структурой класса и обработкой ошибок, а не просто последовательность инструкций сверху вниз.

argparse — более надёжная замена сырому sys.argv

В главе 23 аргументы командной строки читались напрямую из sys.argv — рабочий, но хрупкий подход: нет проверки, что аргумент вообще передан, нет вывода подсказки по доступным опциям. Стандартный модуль argparse решает это:

import argparse

parser = argparse.ArgumentParser(description="Логгер показаний Arduino")
parser.add_argument("--port", required=True, help="Serial-порт, например /dev/tty.usbmodem1101")
parser.add_argument("--output", default="readings.csv", help="Файл для записи показаний")
parser.add_argument("--baudrate", type=int, default=9600)

args = parser.parse_args()

Запуск с --help автоматически покажет описание всех доступных опций — то, чего не было бы у самодельного разбора sys.argv без дополнительной ручной работы.

Полный код инструмента

# device_logger.py
import argparse
import time
import serial


class DeviceLogger: # класс, как в главе 24
    def __init__(self, port, output_path, baudrate=9600):
        self.port = port
        self.output_path = output_path
        self.baudrate = baudrate
        self.connection = None

    def connect(self):
        try: # обработка ошибок, глава 21
            self.connection = serial.Serial(self.port, self.baudrate)
            time.sleep(2)
        except serial.SerialException as e:
            print(f"Не удалось подключиться к {self.port}: {e}")
            raise # передаём ошибку выше, но сначала печатаем понятное сообщение

    def read_one_line(self):
        return self.connection.readline().decode("utf-8").strip() # глава 18

    def run(self):
        self.connect()
        print(f"Подключено к {self.port}. Запись в {self.output_path}. Ctrl+C для остановки.")

        try:
            with open(self.output_path, "a", encoding="utf-8") as f: # глава 19
                while True:
                    line = self.read_one_line()
                if not line:
                    continue
                timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
                f.write(f"{timestamp},{line}\n")
                f.flush()
                print(f"{timestamp}: {line}")
        except KeyboardInterrupt:
            print("\nОстановлено пользователем.")
        finally:
            if self.connection:
                self.connection.close()


if __name__ == "__main__": # глава 20
    parser = argparse.ArgumentParser(description="Логгер показаний Arduino")
    parser.add_argument("--port", required=True)
    parser.add_argument("--output", default="readings.csv")
    parser.add_argument("--baudrate", type=int, default=9600)
    args = parser.parse_args()

    logger = DeviceLogger(args.port, args.output, args.baudrate)
    logger.run()

Запуск

$ python3 device_logger.py --port /dev/tty.usbmodem1101 --output sensor_log.csv

Полноценная команда терминала (блок 2), с проверяемыми аргументами, понятными сообщениями об ошибках вместо сырого traceback (глава 21), корректным закрытием соединения даже при прерывании Ctrl+C, и записью, которую можно прервать и возобновить в любой момент — файл открыт в режиме дозаписи ("a", глава 19), а не перезаписи.

Последний штрих — сохранить в Git

$ git init
$ echo "*.csv" > .gitignore # данные логов — не исходный код, не коммитим их
$ git add device_logger.py .gitignore
$ git commit -m "Первая версия логгера показаний Arduino"

С этого момента любое изменение инструмента — новая опция, исправленная ошибка, поддержка другого формата вывода — фиксируется отдельным коммитом, с полной историей того, что и когда менялось (глава 25).

Куда развивать дальше — если появится желание

Итог всей книги

27 глав — от физического состояния транзистора (глава 01) до работающего инструмента командной строки, читающего реальные данные с реального устройства и надёжно сохраняющего их на диск. По пути встретились GOTO из BASIC, структурные блоки Pascal, три разные командные оболочки, полный базовый синтаксис Python, обработка ошибок, объекты, версии кода и, наконец, электроника снова — но теперь управляемая языком, а не паяльником. Каждая поздняя глава опиралась на более раннюю не для красоты, а потому что программирование и электроника — как ты уже знаешь по опыту предыдущих учебников — устроены одинаково: настоящее понимание строится слоями, и ни один слой не появляется просто так, из ниоткуда.

Глава27 — Финальный проект
Блок5 — Что добавили от себя — финал
Далее— (конец учебника)
СтатусГотово · рев. 1
Предыдущая глава ← 26 · Python и Arduino Учебник завершён К оглавлению →

Книга бесплатна для чтения. Автор — Тариел Бежанидзе, компьютерный мастер в Батуми · tariel.ge · все бесплатные книги. Копировать текст целиком на другие сайты — только со ссылкой на источник.