Ник Роулинсон показывает, как превратить дешевый маленький компьютер в таймер, который может повысить вашу производительность

BBC micro:bit — очень универсальный маленький компьютер. Хотя он разработан и продается с акцентом на знакомство детей с программированием, он способен на гораздо большее, чем просто упражнения по программированию. Аппаратное обеспечение второго поколения, выпущенное в октябре прошлого года, имеет впечатляющий набор встроенных датчиков, включая трехосный акселерометр для обнаружения движения, магнитометр для ориентации, датчик температуры, микрофон и динамик. Bluetooth также встроен, так что вы можете программировать его с помощью мобильных приложений и передавать свой код по беспроводной сети — и плату можно купить в Pimoroni всего за 13,50 фунтов стерлингов.

Со всем этим он может показаться конкурентом Raspberry Pi, но он недостаточно мощный для запуска графической операционной системы: он использует 32-разрядный процессор с частотой 64 МГц и имеет всего 128 КБ ОЗУ (такой же объем, как у система BBC Master, выпущенная в 1986 г.).

Что он может сделать, так это запустить MicroPython, что означает, что он может выполнять многие из тех же трюков, что и другие одноплатные компьютеры. Мы будем использовать MicroPython и 25 светодиодов, встроенных в плату, чтобы превратить micro:bit в вызывающий, но практичный таймер Pomodoro.

Что такое Помидор?

Техника Pomodoro — это рабочий метод, предназначенный для повышения вашей продуктивности за счет чередования 25-минутных кусков работы и пятиминутных перерывов. Он был разработан консультантом по менеджменту Франческо Чирилло в 1980-х годах; Pomodoro в переводе с итальянского означает «помидор», а техника названа в честь кухонного таймера в форме помидора, который он использовал для измерения своих рабочих сессий.

Нет необходимости использовать физический таймер для Pomodoro; есть много бесплатных приложений таймера. Однако для нас приложения — это отвлечение, без которого можно обойтись. Micro:bit — более чистый подход, и по счастливой случайности его 25 светодиодов идеально соответствуют продолжительности рабочего сеанса Pomodoro, поэтому мы можем использовать их в качестве визуального таймера обратного отсчета.

Для простоты наш код постоянно чередует циклы работы и отдыха. Первоначальная техника Pomodoro включает в себя более длительный перерыв после четырех циклов работы/отдыха, и было бы несложно добавить эту возможность в код — впрочем, мы оставляем это на ваше усмотрение.

Настройка вашего micro:bit

При первом включении micro:bit он запустит демонстрационную процедуру по умолчанию, которая демонстрирует прокручиваемый текст, изображения, шум и определение ориентации. Мы заменим это так, чтобы всякий раз, когда плата подключалась к источнику питания, она автоматически загружала нашу процедуру Pomodoro.

Как правило, мы рекомендуем программировать ваш micro:bit с помощью Thonny IDE, которую вы можете бесплатно скачать с thonny.org. Однако мы столкнулись с проблемами при использовании Thonny для перезаписи демо-кода micro:bit, поэтому для этого мы воспользуемся стандартным веб-редактором Python.

Чтобы получить к нему доступ, откройте браузер на ПК, к которому подключен micro:bit, и посетите python.microbit.org. Код примера в главном окне менять не нужно: достаточно нажать Подключиться (вторая кнопка на панели инструментов). Это загрузит код-заполнитель на доску; при первом подключении он также будет выполнять некоторые вспомогательные задачи, поэтому это займет несколько секунд.

Теперь вы можете установить Тонни. Запустите его, откройте меню «Инструменты», выберите «Параметры…» и перейдите на вкладку «Интерпретатор». Щелкните раскрывающийся список с надписью «Какой интерпретатор или устройство должен использовать Тонни для запуска вашего кода?» и выберите «MicroPython (BBC micro:bit)» из вариантов. Вы можете оставить настройку порта на «Попытаться определить порт автоматически»; если позже вы увидите какие-либо сообщения об ошибках о невозможности найти устройство, вернитесь на эту вкладку и выберите конкретный USB-порт.

Ввод и запуск кода

Теперь вы готовы поместить код в окно редактора (самое верхнее из двух окон в интерфейсе Thonny). Вы можете скачать код здесь с GitHub.

Сохраните файл — мы назвали его pomobit.py — и нажмите кнопку «Воспроизвести» на панели инструментов Тонни. Может показаться, что ничего не происходит, но это потому, что мы сказали Тонни, что хотим запускать код на micro:bit, а не на хост-компьютере.

На самом деле код уже запущен и ждет, когда вы запустите рабочий цикл. Для этого нажмите кнопку A на micro:bit. После обновления статуса, сообщающего вам о начале работы, все светодиоды micro:bit загорятся, а затем погаснут каждую минуту.

Когда все они погаснут, ваш рабочий цикл завершится. Вы увидите еще одно сообщение о состоянии, говорящее вам сделать перерыв, и на светодиодах появится цифра пять. Через минуту их становится четыре и так до конца цикла отдыха. Затем код возвращается к рабочему циклу, и процедура начинается снова.

Когда вы будете готовы опустить инструменты, вы можете снова нажать кнопку A. Независимо от того, находитесь ли вы в рабочем цикле или в цикле отдыха, экран очистится, а микробит вернется в свое спящее состояние. При следующем нажатии таймер начнет новый рабочий цикл. Если вы нажмете B во время рабочего цикла, вы немедленно переключитесь на цикл отдыха, а если вы нажмете ее во время цикла отдыха, вы переключитесь на рабочий цикл. Ниже вы можете увидеть схему работы программы.

Понимание кода

Первая строка кода — import microbit — импортирует библиотеки, которые нам нужны для использования функций micro:bit в MicroPython. После этого мы определяем нашу первую функцию, которую мы назвали workcycle(). Python использует уровни отступов для разграничения блоков кода, поэтому, если вы печатаете скрипт вручную, убедитесь, что ваши строки имеют отступ, как в нашем примере на обороте. Следующая строка без отступа должна быть той, в которой объявляется функция restcycle().

Эти две функции определяют ключевые процедуры для нашего таймера, но есть еще одно поведение, которое нам нужно настроить: когда micro:bit спокойно ждет, когда вы начнете работать. Это наша третья функция, называемая ожиданием().

Теперь у нас есть все наши функции, определенные и готовые к запуску, но мы не написали код для запуска какой-либо из них. Итак, мы создаем очень простой цикл на последних двух строках. Конструкция while True: — это способ, с помощью которого MicroPython сообщает программному обеспечению повторять то, что следует, вечно, а строка под ней вызывает функцию wait(). Если вы знакомы с другими языками, вы можете ожидать, что команда wend отметит конец основного цикла, но опять же в Python это передается просто через отступ.

Что делают функции

Первое, что делает функция await(), — это проверяет, нажал ли кто-нибудь кнопку A. Если нет, она возвращается назад и проверяет снова, и так до бесконечности.

Как только он обнаруживает нажатие кнопки, он входит в другой цикл. Он начинается с выключения всех светодиодов на micro:bit, затем проверяется, нажата ли кнопка B. Если это так, мы выходим из функции — мы объясним это ниже.

А пока предположим, что кнопка A была нажата, но кнопка B не нажата. В этом случае мы вызываем workcycle(), который обрабатывает 25-минутный обратный отсчет.

Как только workcycle() подходит к концу, выполнение возобновляется со следующей строки функции wait(). Это снова проверяет, удерживается ли нажатой кнопка B, и если да, то снова выходит из функции. В противном случае вызывается функция restcycle(), которая определяет время пятиминутного перерыва.

После завершения restcycle() интерпретатор возвращается к функции wait(). Поскольку мы достигли конца блока кода while True:, выполнение возвращается на десять строк назад, и начинается новый рабочий цикл — если снова не нажать кнопку B.

Так почему же мы продолжаем проверять кнопку B? Эта функция позволяет нам завершить сеанс Pomodoro в любое время и начать новый, когда мы будем готовы. Код постоянно проверяет, нажата ли кнопка B; если это так, micro:bit прекращает все, что он делал в данный момент, и возвращается к основному циклу, который ждет нажатия кнопки A, чтобы начать новый рабочий цикл.

Код, который это обрабатывает, показывает важное различие между was_pressed и is_pressed. Свойство was_pressed возвращает значение true, если кнопка была нажата в любой момент с момента последней проверки; затем он возвращается к значению false до тех пор, пока кнопка не будет нажата снова. Это означает, что мы можем использовать его для перехвата нажатия кнопки во время workcycle() и restcycle(), но мы не можем использовать тот же метод для повторного подтверждения нажатия кнопки в нашей функции wait().

Мы могли бы обойти это, возвращая значение из workcycle() и restcycle(), указывающее, была ли нажата кнопка. В этом случае мы использовали тест is_pressed, чтобы проверить, удерживается ли кнопка до сих пор. Это отлично справляется со своей задачей, потому что код работает достаточно быстро, чтобы уловить даже самый короткий результат.

Циклы работы и сна

Когда micro:bit начинает выполнять функцию workcycle(), он сначала прокручивает сообщение «Время работать» на светодиодах. Затем он отдыхает в течение 1000 миллисекунд; это не обязательно, но создает хороший визуальный разрыв между концом прокручиваемого сообщения и горящими всеми светодиодами.

Затем мы используем два вложенных цикла для перебора пяти рядов и столбцов светодиодов на micro:bit, включая каждый из них по очереди с помощью команды set_pixel:

microbit.display.set_pixel(x, y, 5)

Это устанавливает для пикселя в точке x,y яркость 5 (где 9 — максимум, а 0 — выключено). Обратите внимание, что строки и столбцы пикселей пронумерованы от 0 до 4, а не от 1 до 5, как можно было ожидать, поэтому верхний левый имеет координаты 0,0, а нижний правый — 4,4. Код работает, так как — вопреки здравому смыслу — это значения, сгенерированные функцией range(5).

Когда все лампочки включены, мы повторяем трюк с использованием вложенных циклов, чтобы по очереди выключать каждую лампочку. Чтобы создать естественный обратный отсчет, мы используем ключевое слово reversed, поэтому первый светодиод, который погаснет, будет 4,4, второй будет 4,3 и так далее.

Нужен последний бит кода. Когда мы использовали петли для подсветки наших светодиодов, код работал так быстро, что казалось, что все 25 ламп включаются мгновенно. Теперь мы хотим, чтобы каждую минуту выключался только один свет. Поэтому нам нужно вставить какую-то задержку.

Простой способ сделать это — перевести micro:bit в спящий режим на минуту, но это будет означать, что мы не сможем проверять нажатия кнопок, пока не истечет минута. Чтобы сделать наш код более чувствительным к действиям пользователя, нам нужно разбить задержку на более мелкие фрагменты и проверять кнопки между паузами.

Итак, давайте вставим новый цикл, называемый остановкой, который выполняется 6000 раз, прежде чем погаснет каждый светодиод. Каждый раз код будет останавливаться на десять миллисекунд (одну сотую секунды), а затем проверять, была ли нажата кнопка. Если это так, мы немедленно возвращаемся к wait(); если нет, код переходит к следующему запуску. Когда цикл завершается, это означает, что прошло 60 секунд. Следующий светодиод гаснет, и код продолжает работать.

В конце концов, и y, и x проделают свой путь от 4 до 0. Это означает, что прошло целых 25 минут, и рабочий цикл закончился. Выполнение возвращается к функции wait(), которая, обнаружив, что кнопка B не нажата, вызывает restcycle().

Эта функция начинается с секунды сна, просто как визуальный маркер для тех, кто смотрит micro:bit, а затем отображает сообщение «Сделайте перерыв», за которым следует еще одна секунда отдыха.

Для определения времени пятиминутного отдыха мы используем ту же базовую технику, что и в workcycle(), но чтобы различать циклы работы и отдыха, на этот раз мы будем использовать числовой обратный отсчет, используя способность micro:bit отображать один символ. на его светодиодах.

И снова мы используем цикл, который считает в обратном порядке пять цифр. Однако, как мы уже отмечали выше, функция range(5) возвращает ряд значений от 0 до 4, а не от 1 до 5. Мы не хотим, чтобы наш процесс считал от четырех до нуля, поэтому мы создали новую переменную с именем time, которая равна значению итерирующей переменной t плюс один. Затем мы отображаем это на светодиодах, используя строку:

microbit.display.show (время)

Как и в функции workcycle(), теперь мы хотим, чтобы micro:bit ждал минуту, проверяя нажатия кнопок, поэтому мы можем использовать тот же код для наблюдения за кнопками. Если ни одна кнопка не нажата, функция достигает своей конечной точки и возвращается к циклу while True: внутри процесса wait(), который запускает новый рабочий цикл.

Перенос вашего кода

Когда вы довольны кодом, последнее, что нужно сделать, это перенести его на ваш micro:bit. Это может показаться нелогичным: неужели micro:bit уже запускает код? Но на самом деле скрипт в настоящее время находится на вашем компьютере. Если бы вы сейчас отключили плату и снова включили ее, она запустила бы код Hello World, который мы запустили ранее из браузера.

Чтобы заменить его нашим скриптом таймера Pomodoro, нажмите кнопку «Стоп» на панели инструментов Thonny, а затем выберите «Файл», а затем «Сохранить как…» Затем вас спросят: «Куда сохранить?». Нажмите «micro:bit», затем нажмите main.py, а затем «ОК». main.py — это стандартное имя скрипта, который запускается, как только micro:bit подключается к питанию. Не поддавайтесь искушению использовать другое имя, иначе ваш код не запустится автоматически.