SVOYAK: PT. 1
Брейн-система
О том, как была сделана первая версия брейн-системы можно почитать тут. Если лень читать, то объясню тут вкратце:
- Микроконтроллер: Arduino Nano
- К нему было подведено 6 кнопок (5 игроков и 1 ведущий) и 6 лампочек.
- Контроллер был запрограммирован на опрос всех кнопок в бесконечном цикле
- Если кнопка нажата, то цикл останавливается и загорается лампочка игрока
Брейн-система SVOYAK
Принципиального отличия системы SVOYAK от предыдущей версии пользователь не заметит, ведь оно будет в том, что устройство теперь общается с компьютером. Итак, приступим.
Типы событий
Атеншон! Лучше сперва посмотреть тот говнокод, который я набросал на вентилятор(зачеркнуто) гитхабе.
Сперва, система будет разговаривать сама с собой. Пусть рассказывает о каждом важном действии. Я разделил события на 2 типа: системное и статусное.
Монолог
Пусть системное событие реагирует лишь на то, что происходит за пределами игрового процесса. Например, объявляет нам какие-нибудь системные параметры, вроде: значение таймера в миллисекундах. Добавлю в конец функции setup() следующие строчки:
Serial.print("system:timer_limit:");Serial.println(timeLimit);
Такой синтаксис сообщений я просто “взял с потолка”. Так как в дальнейшем на серверной части мне предстоит обрабатывать эти сообщения, то я выбрал в качестве сепаратора символ двоеточия “:”. То есть схема сообщений теперь приобретает следующий вид:
тип_сообщения:параметр:значение
Для статусных сообщений структура будет отличаться. Например, нам нужно сообщить о том, что первым был игрок с номером 4. Но добавим туда еще немного информации, например, о том, как быстро он это сделал. В функцию checkButtons(), в каждый if и else if я добавлю следующее логирование:
Serial.print("status:pressed:player1:");Serial.println((millis() - previousMillis));
Последней строчкой определяю, сколько времени прошло с момента старта таймера. То есть структура тут такая:
тип_сообщения:параметр:значение_1:значение_2
Добавлю аналогичные сообщения для таймера. На функции startTimer():
Serial.println("status:timer:started");
и stopTimer():
Serial.println("status:timer:stopped");
Теперь залью свежую версию кода на устройство и проверю, как оно работает. Запущу таймер и нажму кнопку второго игрока спустя примерно 2 секунды после старта. Что получится:
Все работает отлично. Теперь научу программу распознавать команды “со стороны” по USB.
Диалог
Для чтения данных с порта напишу отдельную функцию readSerial(). Сперва проверю, доступен ли порт с помощью Serial.available(). А так как я планирую общаться строками, то для чтения данных с порта буду использовать Serial.readString(). Также добавлю простейший обработчик полученной строки. Главное тут не забывать про символ переноса строки: “\n”. Итак, получилось что-то в этом духе:
Также я добавил вывод всего неподходящего под формат текста, и классифицировал его как системное сообщение.
Теперь попробую отправить поочередно команды включения и выключения на устройство, а также напишу что-нибудь “левое*”.
Всё работает, что не может не радовать.
Заключение
Теперь система умеет разговаривать, правда только на своем языке. Следующим шагом будет создание сервера и обучение его языку, на котором говорит брейн-система.
*
Фраза “Those who are afraid of rough work we don’t want” (Кто боится чёрной работы, тот нам не нужен) была произнесена Троцким в эмиграции (о чем я сказал в комментарии к картинке) и относилась к американским большевикам-ленинцам. Я же обещал написать что-то “левое”.