Всем привет! Благодаря полученной на форуме информации о работе COM порта в linux, я хочу поделиться ради чего все это. Решил связать Arduino UNO с моим игровым сервером, чтобы ардуино выводила количество игроков на сервере прямо передо мной, а то не очень удобно чекать информацию на сайте-мониторинге или специально в консоль входить и смотреть... Данный проект включал в себя 3 основные задачи: 1. Изучить php 2. Узнать, как через php узнать информацию о игровом сервере (в моем случае Counter-Strike 1.6, так же можно любые сервера на движке Source от компании Valve) 3. Изучить работу COM порта в linux (в моем случае Ubuntu) С первой задачей справился - помогли базовые знания кодинга. Со второй задачей помог google.ru, первая же ссылка Так же есть и на оф.сайте Steam Developer информация о том, какие пакеты слать на сервере и что получишь обратно. С третьей задачей мне помогли амперчане, ну и немножко гугл Не буду томить, выкладываю пару фотографий девайса: Решил для усложнения сделать показ через миллиамперметр, так выглядит более круче Осложнения были в том, что пришлось делать массив-маску для analogWrite(); т.к на экране 0 - это было 0, 1 - это 1, а 5 - это уже 3.5, пришлось муторно подбирать значения для 25 рисок на экране. Можно так же и через LCD(4х16) показывать имена серверов и кол-во игроков одновременно на 4х серверах Обновление информации сделал через cron, скрипт следующего содержания Код (Text): #!/bin/sh php /path/to/dir/index.php Исходники с комментами выкладываю: Если будут вопросы или предложения по оптимизации - пишите, отвечу
Хотел бы настоятельно попросить администрацию выложить в вики статью о возможности передачи данных через php в Serial порт на ардуино, было бы не лишним
Выкладываю MoniCOM ver.2 Что нового? Отдельно хочу рассказать о поддержки оповещения: Отправляемый пакет теперь представляет из себя $Player(0-N) + $arr_status(true или false) На стороне ардуино есть массив из 2х "ячеек" - в первую ячейку идет кол-во игроков, во вторую статус сервера (true или false). Отображение игроков на амперметре не будет пока этот массив не заполнится. Если 2я ячейка массива ровна false - идет исполнение функции void warmess(); Вы можете вписать туда что угодно, я сделал скачек стрелки у амперметра и один писк пьезо-элемента 500мс. P.S Не забываем, что мы не можем отправить ардуине двухзначное число от 10 до 99 - для ардуино это 1 и 0, 9 и 9 ... для этого нам помогает таблица ASCII, где 0 - это 48 для ардуино, 1 - это 49, 2 - это 50 etc... А благодаря rea[val] = Serial.read() - 48; ардуино понимает что мы отправили 1, а не 49; 0, а не 48 etc. Думаю фишку поняли
Скоро сделаю последнюю, ver.3 Там добавлю 5 кнопок, отвечающие за свой сервер и 5 лампочек, для отображения текущего сервера. При нажатии на 1ю, покажет кол-во игроков 1-го сервера При нажатии на 2ю кнопку, покажет кол-во игроков 2-го сервера etc... Ну и в final версии выложу фотки всего этого дела в красивом Box'e с размерами деталей. Было бы время
а зачем посылать число в десятичной системе? О_о И зачем помнить таблицу аски? к примеру 13 это вообще перевод каретки и не пичатамый символ, 0 тоже непечатаемый символ
Не, можно вообще boolean передавать, но я для простоты и понимания других использовал ASCII табличку. По хорошему бы в шестнадцатиричной системе передавать, но это так, на профи
ну не знаю, меня это только путает) а шестнадцатиричная то зачем? чем бинарная не устраивает? ASCII это всего лишь таблица соответствий <номер символа> => <картинка символа> чтобы передать значение надо просто его преобразовать в char* и толкнуть в интерфейс к примеру, надо переслать дробное число: Код (Text): float a = 12345.78; Serial.write((char*)(&a),sizeof(a));
получить так: Код (Text): float f; char *c; for(int i=0;i<sizeof(f);i++) { c = (char*)(&f) + i; *c = Serial.read(); }
Блин, не ловко, я просто не понимаю такой кодинг с указателями и дополнительными скобками В С++ не мастер( Не могли бы просветить меня?)
амперсант (&) - операция изъятия адреса, возвращает адрес в памяти предстоящей переменной в с я храню адрес ячейки памяти, char так-как я хочу перемещать указатель на 1 байт. т.е. в строке c = (char*)(&f) + i; я получаю сначала адрес переменной f, а затем сдвигаю его на i байт. float занимает 4 байта, таким образом, на первой итерации c указывает на нулевой байт переменной f, на следующей итерации с указывает на второй байт *с = означает, что значение будет записано не в переменную с, а по адресу, куда она указывает