Статьи

Создайте автоматическое табло, которое оценивает ваш счет с Raspberry Pi

Импульс как раз перед Рождеством, я купил себе мини-баскетбольное кольцо NBA «поверх двери». Я не был уверен, что буду делать с этим, но баскетбольное кольцо для моего офиса показалось мне хорошим ходом. В конце концов я решил поэкспериментировать и привнести в него некоторые возможности подключения, подключив его к Raspberry Pi, чтобы получить отображение табло. Вот как это произошло, с пошаговыми инструкциями, если вы хотите попробовать адаптироваться и улучшить его!

Это руководство не предназначено для использования в качестве пошагового руководства по стилю «делай точно так, как я» — я надеюсь, что ты примешь эту концепцию и будешь использовать ее для любых других идей. Добавьте виртуальное табло, которое подсчитывает, как часто люди приходят в ваш офис. Или заняться другим видом спорта (может быть, мини-футбольный трекер ворот?). Или используйте совершенно другой датчик, но визуально отслеживайте его попадания с помощью Raspberry Pi! Есть так много потенциальных применений этой техники. Попробуйте вещи и дайте мне знать, как вы идете!

Что вам нужно

Чтобы быть в состоянии следовать и создать нечто подобное, вот список частей, которые я использовал (или их эквивалент для вещей, которые я уже имел в своей лаборатории):

Следует отметить одну вещь — если у вас нет 7-дюймового дисплея для вашего Pi, вы также можете отобразить счет на соседнем мониторе компьютера. Любое устройство в вашей локальной сети с веб-браузером и экраном будет работать!

Код

Хотите перейти к загрузке кода? Это доступно на GitHub здесь .

Что я собрал

Я повесил свое новое баскетбольное кольцо на дверь с ультразвуковым датчиком, прикрепленным к обручу, чтобы отслеживать, когда мяч попадает в обруч. Под ним — табло с питанием от Raspberry Pi — я бы порекомендовал найти более длинные кабели, чтобы вы могли подключать их за пределами баскетбольного диапазона.

Патрик Катандзарити, используя свою мини-баскетбольную петлю с табло

Я тестирую свое подключенное табло — с настроенным тематическим интерфейсом Suns!

Я расскажу, почему все так, как есть ниже, а также несколько советов для тех, кто хочет улучшить эту базу!

Языки, которые мы будем использовать

  • JavaScript — чтобы следовать, вам понадобится знание основ, но у нас не будет строк в строках кода, на самом деле все довольно просто в части JS.
  • Node.js — базовые знания о том, как запустить npm и Node, необходимы для запуска нашего сервера табло.

Настройка нашего Raspberry Pi

Если вы совершенно новичок в Raspberry Pi и еще ничего не настроили, не бойтесь! Существует множество руководств по настройке, и это приятно и просто. В Raspberry Pi есть пошаговое руководство по установке операционной системы Raspbian с помощью диспетчера операционной системы NOOBS. Вы должны убедиться, что операционная система запущена, прежде чем переходить к другим шагам.

Настройка сенсорного экрана

Я соединил свое подключенное табло, используя Raspberry Pi 3 с сенсорным экраном. Мой сенсорный экран и корпус были уже собраны и плотно завинчены, поскольку я использовал этот Pi 3 для других проектов, однако, если вы начинаете с нуля — это не так уж сложно подключить. Более новые поставки (как у меня) на самом деле уже собраны, а плата адаптера уже прикручена к ЖК-дисплею, в этом случае половина шагов уже завершена! Инструкции по сборке экрана доступны онлайн:

Настройка случая

Когда дело доходит до размещения корпуса вокруг ЖК-экрана и Raspberry Pi, этот процесс также довольно прост с имеющимся у меня чехлом. У меня уже была моя вместе, однако общие шаги для этого:

  • Убедитесь, что у вас уже есть карта microUSB внутри Raspberry Pi и вы довольны тем, как она работает! Досадно, что во многих случаях вы не сможете достать карту, как только дело будет на месте. Мой случай, указанный выше, является одним из таких … поэтому убедитесь, что с картой все в порядке, прежде чем потерять к ней доступ!
  • Поместите пи с экраном на место внутри корпуса
  • Расположите ленточные кабели и кабели, идущие от GPIO, чтобы они не мешали
  • Убедитесь, что отверстия для ваших USB-портов и тому подобное находятся на правильной стороне более объемной части корпуса и выстроены в линию.
  • Как только все выстроится в ряд, прикрутите четыре винта, чтобы сложить все вместе!
  • Включи это! Если вы обнаружите, что экран переворачивается вверх дном, не волнуйтесь, это побочный эффект от того, что производители чехлов выстраивают мощность, чтобы выйти из верха. Когда я установил свое табло, я установил его с силой, исходящей снизу, так что это не было проблемой для меня. Если это проблема для вас:
    • Запустите sudo nano /boot/config.txt чтобы открыть конфигурацию для Pi
    • Затем добавьте lcd_rotate=2 в конец, это будет вращать экран вокруг.
    • Нажмите Ctrl X и Ctrl Y, чтобы сохранить изменения.
    • Перезапустите свой Pi, и когда он снова загрузится, он должен быть правильным!

Запуск Node.js на нашем Raspberry Pi

Для удобства в Raspbian установлен Node по умолчанию! Тем не менее, это довольно старая версия Node. Вы можете проверить, какая версия установлена ​​на вашем Pi, открыв Терминал и введя:

node -v

У меня установлена ​​версия 8.15.0 на моем Pi. Вы можете обновить, выполнив следующие команды:

sudo su - apt-get remove nodered -y apt-get remove nodejs nodejs-legacy -y apt-get remove npm -y curl -sL https://deb.nodesource.com/setup_5.x | sudo bash - apt-get install nodejs -y

После запуска всех этих команд, если вы снова введете команду version, вы должны увидеть лучшую версию:

node -v

Вы также можете проверить правильность установки npm:

npm -v

С узлом, работающим на нашем устройстве, мы готовы к запуску сервера Node табло!

Наше табло Node.js

Целью нашего табло является следующее:

  • Установите ультразвуковой датчик, отслеживающий движение прямо внутри обруча.
  • Наш Node-сервер будет следить за показаниями расстояния от нашего ультразвукового датчика.
  • Мы запустим простую веб-страницу, которая отображает счет в ответ на наш сервер Node, чувствуя, что точка уже достигнута.
  • Отправьте триггеры оценки на нашу веб-страницу между нашим Node-сервером и веб-страницей, используя WebSockets.

Таким образом, роль нашего Node-сервера будет состоять в том, чтобы запускать веб-сервер для веб-страницы табло, пинговать наш ультразвуковой датчик и отправлять сообщения на нашу веб-страницу при обнаружении движения мяча.

Вот наш окончательный код для тех, кто просто хочет скопировать и вставить его, чтобы опробовать его (или увидеть его в целом, чтобы понять).

 const http = require('http'), express = require('express'), app = express(), server = require('http').Server(app), bodyParser = require('body-parser'), webpagePort = 8080, WebSocketServer = require('ws').Server, wss = new WebSocketServer({server: server}), Gpio = require('pigpio').Gpio, MICROSECONDS_PER_CM = 1e6/34321, // The number of microseconds it takes sound to travel 1cm at 20 degrees celsius trigger = new Gpio(23, {mode: Gpio.OUTPUT}), echo = new Gpio(24, {mode: Gpio.INPUT, alert: true}); let lastScoreTime = new Date(); app.use(bodyParser.json()); app.use(express.static(__dirname + '/public')); app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Error came '); }); server.listen(webpagePort, function() { console.log('Server is running on ' + webpagePort); }); wss.on('connection', function connection(ws) { console.log('WebSockets are ready!'); }); function broadcast(message) { if (message) { console.log('Broadcasting ' + message); wss.clients.forEach(function each(client) { client.send(message); }); } } trigger.digitalWrite(0); // Make sure trigger is low const watchHCSR04 = () => { let startTick; echo.on('alert', (level, tick) => { if (level == 1) { startTick = tick; } else { const endTick = tick; const diff = (endTick >> 0) - (startTick >> 0); let distance = diff / 2 / MICROSECONDS_PER_CM; let currentScoreTime = new Date(); console.log(distance); if (distance 1000)) { lastScoreTime = currentScoreTime; broadcast('SCORE:' + (diff / 2 / MICROSECONDS_PER_CM)); } } }); }; watchHCSR04(); setInterval(() => { trigger.trigger(10, 1); // Set trigger high for 10 microseconds }, 100); // Trigger every 100 milliseconds 

Сейчас мы пройдемся по каждой части и рассмотрим, что в ней происходит.

Мы начнем с типичного набора констант для запуска сервера Node Express. Это веб-сервер, который будет работать на порте 8080. Express — это фреймворк для Node.js, который мы используем, поскольку он делает работу веб-сервера простой и удобной!

 const http = require('http'), express = require('express'), app = express(), server = require('http').Server(app), bodyParser = require('body-parser'), webpagePort = 8080, 

Далее мы продолжаем определять константы, однако они предназначены для нашего сервера WebSocket. WebSockets — это то, как мы заканчиваем сообщения между нашим сервером и веб-страницей, показывающей наш счет. Используя WebSockets, мы можем открыть эту веб-страницу на многих мониторах, и она обновит их все. Я использую только экран Raspberry Pi, но вы можете сойти с ума и иметь большие мониторы по всему месту, чтобы сделать что-то довольно необычное, если хотите.

Для WebSockets существует несколько разных библиотек, но мне нравится использовать ws . Он сфокусирован на предоставлении WebSockets таким образом, чтобы современные браузеры могли понимать его непосредственно, используя стандарт WebSockets (поэтому нам не нужно запускать библиотеку JavaScript на стороне браузера).

В нашем коде мы определяем объект WebSocketServer для нашего сервера, а затем создаем новый WebSocketServer который мы выделяем для постоянной wss .

 WebSocketServer = require('ws').Server, wss = new WebSocketServer({server: server}), 

Наконец, последняя из наших констант — все, чтобы мы могли прослушивать показания нашего ультразвукового датчика. Для считывания данных с ультразвукового датчика мы используем библиотеку pigpio Node. Это позволяет нам получить доступ к контактам GPIO (универсальный вход / выход) вдоль верхнего края платы — именно здесь мы подключаем наш ультразвуковой датчик.

 Gpio = require('pigpio').Gpio, 

Затем мы добавляем расчет, который приводится на примере ультразвукового датчика PIGPIO, в их документах GitHub . Он вычисляет, сколько микросекунд потребуется звуку, чтобы пройти 1 см при 20 градусах Цельсия. Мы будем использовать этот расчет в качестве звукового сигнала ультразвукового датчика, а затем прислушиваемся к ответу — мы используем MICROSECONDS_PER_CM для вычисления расстояния ответа.

 MICROSECONDS_PER_CM = 1e6/34321, // The number of microseconds it takes sound to travel 1cm at 20 degrees celsius 

Затем две последние константы относятся к двум выводам GPIO, к которым будут подключены наши ультразвуковые датчики. У нас будет вывод 23 в качестве выходного вывода, называемого trigger и вывод 24 в качестве входного вывода, называемого echo .

 trigger = new Gpio(23, {mode: Gpio.OUTPUT}), echo = new Gpio(24, {mode: Gpio.INPUT, alert: true}); 

Следующая строка позволяет нам отправлять и интерпретировать строки JSON.

 app.use(bodyParser.json()); 

Затем мы настроили еще несколько вещей для нашего веб-сервера. Сначала мы устанавливаем, где будут находиться наши статические файлы HTML / CSS / JS. Вот где наш сервер Express будет выглядеть, когда мы попытаемся получить доступ к Raspberry Pi через порт, который мы перечислили ранее.

 app.use(express.static(__dirname + '/public')); 

Затем мы устанавливаем, что должно происходить при возникновении ошибки, говорим, чтобы она регистрировалась на консоли, а затем отправляла ошибку 500 обратно.

 app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Error came '); }); 

Чтобы запустить наш веб-сервер, мы вызываем следующий код. Он будет отображать консольное сообщение при успешном запуске.

 server.listen(webpagePort, function() { console.log('Server is running on ' + webpagePort); }); 

После того, как наш веб-сервер настроен, мы настраиваем наше соединение WebSocket. Сервер Node — это наш сервер WebSockets — он будет передавать сообщения подключенным клиентам (наш веб-браузер на Raspberry Pi). Следующий код устанавливает, что делать, когда наш сервер WebSocket готов. Это происходит, когда происходит событие «соединение». Когда это происходит, мы отправляем console.log , если мы не видим этого в консоли, мы знаем, что что-то пошло не так на стороне сервера WebSocket.

 wss.on('connection', function connection(ws) { console.log('WebSockets are ready!'); }); 

Мы следуем этому с помощью специальной функции, которую мы создаем, которая будет отправлять сообщение WebSocket всем подключенным клиентам. Непосредственно перед отправкой этого сообщения он регистрирует сообщение, чтобы показать, что сообщение передается с сервера.

 function broadcast(message) { if (message) { console.log('Broadcasting ' + message); wss.clients.forEach(function each(client) { client.send(message); }); } } 

Следующий код относится к нашему ультразвуковому датчику. Во многом это происходит прямо из примера с Pigpio GitHub . Мне не нужно было слишком много менять, чтобы он хорошо работал для этого сценария.

Мы начнем с того, что установим наш триггерный вывод на низкий (или 0 ) изначально (затем мы сработаем на высоком, когда захотим установить время).

 trigger.digitalWrite(0); // Make sure trigger is low 

Библиотека pigpio может реагировать на изменения состояния выводов GPIO с помощью так называемых «предупреждений». На странице npm библиотеки pigpio сказано, что она отслеживает эти «с точностью до нескольких микросекунд», чего нам достаточно. Мы установили функцию под названием watchHCSR04 которая будет следить за watchHCSR04 от выводов GPIO, и, если он его получит, мы проверяем, как долго он остается высоким (или включенным), затем мы работаем на основе этого времени и вычисления MICROSECONDS_PER_CM , сколько смс ближайшего пункта, который вызвал пинг обратно.

Если расстояние меньше 11 см, то мы запускаем трансляцию с нашего сервера WebSocket, которая сообщает клиентам нашего веб-браузера, что движение обнаружено. После нескольких проб и ошибок я выбрал 11 см, держа мяч в разных местах в пяльцах, пока мой console.log побежал посмотреть, какие значения сообщил ультразвуковой датчик, пока мяч был там.

Мы также проверяем, было ли текущее время по сравнению с последним разом, когда был прочитан счет — если это еще не было более 1000 миллисекунд, мы не запускаем новую точку (например, если мяч немного гремит в обруче, это не дает кому-то больше очков!). Это было то, что я добавил после обнаружения нескольких случаев двойного подсчета очков.

 const watchHCSR04 = () => { let startTick; echo.on('alert', (level, tick) => { if (level == 1) { startTick = tick; } else { const endTick = tick; const diff = (endTick >> 0) - (startTick >> 0); let distance = diff / 2 / MICROSECONDS_PER_CM; let currentScoreTime = new Date(); console.log(distance); if (distance 1000)) { lastScoreTime = currentScoreTime; broadcast('SCORE:' + (diff / 2 / MICROSECONDS_PER_CM)); } } }); }; watchHCSR04(); 

Чтобы фактически вызвать пинг, мы должны установить наш триггер на высокий уровень (или 1 ), чтобы дать исходный звук от нашего ультразвукового датчика для измерения. В последнем бите нашего серверного кода мы делаем это каждые 100 миллисекунд. Это гораздо чаще, чем в примере с Пигпио, поскольку я хотел, чтобы у меня было больше шансов обнаружить движение в обруче. Я отрегулировал это значение все ниже и ниже после нескольких тестов (оказывается, баскетбол может двигаться довольно быстро!)

 // Trigger a distance measurement once per second setInterval(() => { trigger.trigger(10, 1); // Set trigger high for 10 microseconds }, 100); 

Наш файл Package.json

Нам также понадобятся наши зависимости, перечисленные в нашем файле package.json, чтобы мы могли отслеживать, что нужно запустить нашему проекту! Мой файл package.json выглядит так:

 { "name": "hoopspi", "version": "0.0.1", "description": "A connected scoreboard for my basketball hoop", "main": "index.js", "dependencies": { "body-parser": "^1.15.2", "express": "^4.14.0", "gulp": "^3.9.1", "pigpio": "^1.2.1", "ws": "^1.1.1" }, "devDependencies": {}, "author": , "license": "MIT" } 

Это содержит все наши зависимости, используемые на Node-сервере выше. Я бы рекомендовал просто скопировать вышеуказанное в новый файл package.json в той же папке, что и ваш файл index.js . Как только вы это сделаете, запустите следующую команду в консоли, чтобы установить все необходимое:

npm install

Наш HTML

HTML-код очень прост:

 <!doctype html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="robots" content="no index, no follow"> <title>HoopsPi</title> <link href="/css/styles.css" rel="stylesheet" type="text/css"> <link href="https://fonts.googleapis.com/css?family=ZCOOL+QingKe+HuangYou" rel="stylesheet"> </head> <body> <div class="container"> <div id="score"></div> </div> <script src="js/scoreboard.js"></script> </body> </html> 

Наш интерфейс JavaScript

Наш внешний JavaScript-код выглядит так:

 (function() { var ws = new WebSocket('ws://192.168.1.133:8080', 'json'); var score = 0; ws.onopen = function () { console.log('Websocket is open'); ws.send('Hi from HoopPi!'); document.getElementById('score').innerHTML = score; }; ws.onmessage = function (event) { if (event.data.indexOf('SCORE:') != -1) { score++; document.getElementById('score').innerHTML = score; } console.log('Message was ', event.data); }; ws.onerror = function(error) { console.log('Error detected: ' + error.data); } }()); 

Давайте посмотрим, что происходит! Мы начнем с настройки WebSocket для отслеживания IP-адреса, на котором работает Raspberry Pi (чтобы узнать это, используйте команду ifconfig в консоли). Мы также устанавливаем нашу начальную оценку при загрузке страницы на 0.

 (function() { var ws = new WebSocket('ws://192.168.1.133:8080', 'json'); var score = 0; 

После этого мы открываем этот WebSocket, отправляем сообщение на консоль и на наш WebSocket (который отправится на сервер, но мы не будем использовать это сообщение!), И мы устанавливаем наш видимый счет на веб-странице в нашу переменную score :

 ws.onopen = function () { console.log('Websocket is open'); ws.send('Hi from HoopPi!'); document.getElementById('score').innerHTML = score; }; 

Когда наши WebSockets увидят сообщение (это будут сообщения от нашего Pi), мы проверяем, содержит ли оно содержимое "SCORE:" и, если это так, мы увеличиваем количество наших очков на единицу. Технически, в баскетболе вы получаете по крайней мере два очка … но у меня нет способа обнаружить выстрелы в три очка, поэтому я решил, что пока одно очко было достаточно простым. Когда-нибудь! Я также регистрирую данные, поступившие на консоль браузера, чтобы мы могли проверить их, если что-то кажется неправильным.

 ws.onmessage = function (event) { if (event.data.indexOf('SCORE:') != -1) { score++; document.getElementById('score').innerHTML = score; } console.log('Message was ', event.data); }; 

Наконец, если есть какие-либо ошибки, мы регистрируем их в консоли:

 ws.onerror = function(error) { console.log('Error detected: ' + error.data); } }()); 

Проводка Вещи

Чтобы все вышеперечисленное сработало, нам нужно все правильно подключить! Основная часть проводки, которую мы должны сделать, это подключить наш ультразвуковой датчик к выводам GPIO нашего Raspberry Pi, о которых мы упоминали выше.

В итоге мои выводы GPIO выглядели так:

Давайте посмотрим, что именно было связано, где.

Мы должны быть осторожны при подключении нашего ультразвукового датчика. Выход ультразвукового датчика составляет 5 В, но максимальное напряжение выводов GPIO Raspberry Pi составляет 3,3 В, поэтому нам необходимо включить некоторые резисторы, чтобы убедиться, что мы не повредим выводы GPIO. Я лично использовал резисторы 1 кОм и 2 кОм, однако в примере с библиотекой PIGPIO вместо этого используются резисторы на 330 и 470 Ом (у меня их просто не было, и с альтернативами резисторов все было в порядке, я бы рекомендовал следовать рекомендации PIGPIO).

Когда дело доходит до подключения ультразвукового датчика к макету, я подключил его с помощью нескольких белых соединительных кабелей, чтобы расстояние между макетом и нашим Пи было немного больше. Ультразвуковой датчик застрянет под обручем, поэтому для этого нам нужно освободить его от макета! Однако до того, как я подключил его таким образом, я подключил ультразвуковой датчик непосредственно к макету, просто чтобы проверить (было намного проще проверить, работает ли датчик, пока он находится в макете, прежде чем устанавливать его на обруч!) ,

После добавления к нему соединительных кабелей это выглядит примерно так:

Вся проводка показана на схеме ниже. Мы подключаем вывод VCC на нашем ультразвуковом датчике к нашему выводу 5 В (тот, который не используется на ЖК-экране), вывод GND на нашем ультразвуковом датчике подключается к заземлению на Pi, но мы также помещаем резистор на 470 Ом между ряд заземления и ряд подключен к контакту 24 на Pi. Резистор на 330 Ом идет от ряда, подключенного к нашему эхосигналу на ультразвуковом датчике, к тому ряду, подключенному к контакту 24.

Когда дело дошло до того, чтобы подключить это к баскетбольному кольцу, я пошел по пути использования полосок для картин, чтобы прикрепить мой Raspberry Pi кейс к стене. В частности, я использовал Command 5.45g White Medium Picture Hanging Strips . Я снял съемную заднюю часть корпуса Пи и приклеил к ней столько, сколько мог:

Затем я прикрепил его обратно к стене, выстроив Pi в футляр, чтобы убедиться, что он прямой. Я сунул свой прямо под обруч — что в ретроспективе было не лучшим местом для этого. Я бы порекомендовал отложить его в сторону в зависимости от длины соединительных кабелей, которые у вас есть. Я аккуратно отсоединил корпус Pi от задней части, как только выстроил его в линию, чтобы я мог надавить на заднюю часть корпуса, чтобы прикрепить его как можно крепче к стене.

Я так волновался о том, будет ли Пи придерживаться, что я положил мешочек с бобом под обруч, чтобы быть в безопасности! К счастью, после более чем недели, когда он там висел и несколько раз бил в баскетбол… он все еще висит! Эта лента волшебная.

Сначала я прикрепил датчик к той же ленте на обруче, но использование ленты означало, что я был ограничен где-то под обручем, достаточно плоским, чтобы его можно было прикрепить… это оказалось слишком низким, и баскетбольная сетка часто мешала трекингу , Вот как я бы рекомендовал вам не засовывать датчик!

Вместо этого я снял датчик с этого места и использовал blutack, чтобы вставить его прямо под обруч.

Ультразвуковой датчик застрял прямо под обручем

Мое более удачное размещение ультразвукового датчика!

Сеть все же удалось помешать, поэтому я использовал одну из кабельных стяжек из обручальной упаковки NBA, чтобы связать некоторые сети вместе, чтобы избежать помех:

Немного завязав сеть, чтобы избежать помех

Это все еще не идеально, но, казалось, немного помогло!

Я также использовал одну из этих кабельных стяжек, чтобы соединить вместе ультразвуковой датчик. Эти кабельные стяжки очень удобны.

В бою

Чтобы запустить все, нам нужно запустить сервер Node.js с помощью ключевого слова sudo как нашему приложению Node необходимы надежные разрешения для доступа к выводам GPIO. Чтобы запустить наш сервер Node.js, мы вводим следующее:

sudo node index.js

Это должно работать и выглядеть так в консоли:

Консоль успешно работает

Если мы откроем браузер нашего Raspberry Pi и перейдем по адресу http: // localhost: 8080, мы увидим, что наше табло готово к подсчету!

Я лично предпочитаю Chromium на моем Raspberry Pi, так как я предпочитаю его полноэкранный режим и более современный браузер. Если у вас нет Chromium на Raspberry Pi, его просто установить с помощью двух команд:

Обычно:

 sudo apt-get update 

С последующим:

 sudo apt-get install chromium-browser --yes 

Затем он должен быть виден в разделе «Интернет» меню вашего Pi:

Меню, Интернет, Chromium Web Browser

Где Chromium будет установлен

Самое приятное, что веб-страница — это то, что ее легко настроить! Я настроил свой, чтобы иметь тему Phoenix Suns:

Табло с тематической версией Патрика

Моя табло в тематическом варианте

Вывод

В конце концов, отслеживание результатов баскетбольного кольца работает хорошо, но определенно может быть принято на следующий уровень. Я испытываю желание приобрести ИК-датчик расстояния, чтобы увидеть, отслеживает ли он более точно. С табло на основе браузера можно сделать гораздо больше — вы можете добавить таймер обратного отсчета или режим двух игроков, чтобы вы могли по очереди пообщаться с другом!

Если вы создадите нечто подобное с моей первоначальной концепцией выше, я бы хотел услышать о том, что вы создали! Дайте мне знать в комментариях ниже или свяжитесь со мной в Твиттере по адресу @thatpatrickguy .

Другие руководства Raspberry Pi на SitePoint

Если вы заинтересованы в том, чтобы делать больше с вашим Raspberry Pi, у нас есть другие интересные статьи о Raspberry Pi, которые разрабатываются ниже!