Для подключения контроллера Arduino к персоналкам используется USB кабель.
Поскольку памяти в самом контроллере не слишком много, то основные алгоритмы работы можно переложить на Linux машинку. Для чего их нужно соединить по USB кабелю с разъемом MicroUSB.
Исходная задача что имеем:
Arduino Nano V.7 (Carduino).
сервер с Centos 6
Нужно подключить Arduinку и передавать-считывать данные при помощи PHP.
Подключение usb
Для работы с USB необходимо поставить lsusb
yum install usbutils
При прямом подключении к USB порту контроллер определился так
lsusb | grep -i ft
Bus 002 Device 003: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
ls /dev
не дает в списке порта ttyUSB0, как должен при нормальном раскладе.
Проверка
dmesg | tail
[root@proxy dev]# dmesg | tail
usb 2-4: device descriptor read/64, error -71
xhci_hcd 0000:00:14.0: Setup ERROR: setup context command for slot 1.
usb 2-4: new full speed USB device number 3 using xhci_hcd
usb 2-4: New USB device found, idVendor=0403, idProduct=6001
usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 2-4: Product: CarDuino Nano V.7
usb 2-4: Manufacturer: CarMonitor.ru
usb 2-4: SerialNumber: A9GJNP1H
usb 2-4: configuration #1 chosen from 1 choice
usb 2-4: can't set config #1, error -71
Похоже нет драйвера
Пробуем установить вручную при помощи modprobe (предварительно yum install modprobe)
lsusb | grep -i ft
Bus 001 Device 031: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
The VID is 0403 - the PID is 6001
modprobe ftdi_sio vendor=0x403 product=0x6001
# lsmod | grep ft
ftdi_sio 50508 0
usbserial 36296 1 ftdi_sio
usbcore 185584 8 ftdi_sio,usbserial,usb_storage,uhci_hcd,ohci_hcd,ehci_hcd,usbhid
# dmesg | tail
USB Serial support registered for FTDI USB Serial Device
ftdi_sio 2-4.4:1.0: FTDI USB Serial Device converter detected
usb 2-4.4: Detected FT232RL
usb 2-4.4: Number of endpoints 2
usb 2-4.4: Endpoint 1 MaxPacketSize 64
usb 2-4.4: Endpoint 2 MaxPacketSize 64
usb 2-4.4: Setting MaxPacketSize 64
usb 2-4.4: FTDI USB Serial Device converter now attached to ttyUSB0
usbcore: registered new interface driver ftdi_sio
ftdi_sio: v1.5.0:USB FTDI Serial Converters Driver
Если порт появился, а потом пропал, переподключаем через дополнительный USB hub, после этого работает стабильно.
Включение/отключение питания USB
Для удаленного включения -выключения можно использовать управление питанием
cd /sys/bus/usb/devices/
ls
[root@proxy devices]# ls
1-0:1.0 1-1 1-1:1.0 2-0:1.0 2-4 2-4:1.0 2-4.4 2-4.4:1.0 3-0:1.0 usb1 usb2 usb3
Устройство usb2 - это оно.
cat usb2/power/level
auto
выключаем питание
[root@proxy devices]# echo suspend > usb2/power/level
[root@proxy devices]# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8000 Intel Corp.
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Включаем питание
[root@proxy devices]# echo on > usb2/power/level
проверяем, устройство на месте
[root@proxy devices]# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8000 Intel Corp.
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 007: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Установка PHP
Нужен PHP как консольный клиент
yum install php
Используются функции dio, поэтому, если при запуске мы имеем это
PHP Fatal error: Call to undefined function dio_open()
Нужно ставить dio
для компиляции модуля
yum install gcc
wget https://pecl.php.net/get/dio-0.0.7.tgz
pecl install dio-0.0.7.tgz
PHP код функция send.php
<?php
function send($param){
$port = "/dev/ttyUSB0";
$command =`stty -F /dev/ttyUSB0 cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts -hupcl`;
print $command; // инициализация порта, главное, выключение DTR, иначе будет сбрасывать ардуинку при открытии порта
$fd = dio_open($port, O_RDWR | O_NOCTTY | O_NONBLOCK);
$delay = 0.1; //в течение 0.1 (или больше. ставить здесь) секунды ждем ответа
if (!$fd){
//print "Error open port $port";
$ret = "OPEN PORT $port ERR";
return $ret;
}
$fp = fopen('//www1//proto.txt', 'a+t'); // Текстовый режим
$test = fwrite($fp, "\nport opened\n");
$olddata="";
// $olddata= dio_read($fd,255); // если перед этим в порту были данные, то считаем предварительно
//print "data: $olddata";
$test = fwrite($fp, "data from port: $olddata\n");
$test = fwrite($fp, "$param");
dio_write($fd,"#$param\n"); // теперь запишем
$now = microtime(1); // получим время с микросекундами
$end = $now + $delay; // в течение $delay секунды ждем ответа
$result = '';
// printf ("> $now > $end");
while ($now < $end) {
$now = microtime(1);
}
$result=dio_read($fd,10); // быстренько считаем данные, например 10 байт
dio_close($fd); // что успели, то успели, если данных нет, то возможно $delay нужно увеличить
$test = fwrite($fp, "$result\n");
fclose($fp); //Закрытие файла
return $result;
}
?>
файл Test.php
<?php
include "send.php";
print send("MF:250#\n");
sleep(5);
?>