ABATAPA, спасибо за ответ, но хотелось бы чуть по развернутее, просто даже близко не представляю как написать такую программулину. Какие библиотеки есть для работы с USB в прошивке от Энтузиастов?
© 2008-2013 ABATAPA WL-500gP/128M / Asus RT-N16 / USB Flash / VLAN / PPPoE / VoIP / nShaper / NAS: iStor is607, Sarotech NAS-20, QNap 109 Pro / NFS / Принтер / etc
ABATAPA, спасибо за ответ, но хотелось бы чуть по развернутее, просто даже близко не представляю как написать такую программулину. Какие библиотеки есть для работы с USB в прошивке от Энтузиастов?
© 2008-2013 ABATAPA WL-500gP/128M / Asus RT-N16 / USB Flash / VLAN / PPPoE / VoIP / nShaper / NAS: iStor is607, Sarotech NAS-20, QNap 109 Pro / NFS / Принтер / etc
Позвольте высказать IMHO. Исходя из личного опыта я бы не советовал использовать USB реле от МастерКита. Скорее всего там на плате МК с проприетарным протоколом - гемор с реализацией со стороны рутера с большой вероятностью. Имею опыт сопряжения МастерКит'овского NM8036 с рутером. Обмен заработал, и все бы ничего, но NM8036 глючит страшно. Может я где накосячил, может так звезды сложились, но в автономном режиме эта связка работает отвратительно. NM8036 зависает, причем в сторону рутера может ответить - нагрузка такая-то включена, но реально нагрузка не работает. Перезагружаем - и все ок. На неконтакт в цепи нагрузки явно не похоже, скорее непонятки с ПО модуля. Еще раз, вполне допускаю, что у других пользователей продукции МастерКит такого не наблюдается. В итоге, поскольку на улице -20 а этот весь контруктив управляет в том числе котлом, в качестве срочной меры вывел канал управления прямо на маршрутизатор. У меня DIR-320, а в нем есть программно-управляемые светодиоды (red, blue). Вот к одному из них подпаял транзистор с релюхой и теперь все так работает. Так что поинтересуйтесь, есть ли управляемые светодиоды в Asus Wl500, если речь идет об одной-двух нагрузках - это был бы самый дешевый и простой вариант. Потому как подключение любых внешних устройств на МК через USB или даже UART требует наличия определенных навыков по отладке протокола обмена, и чем он сложнее, тем "толще грабли". Я для себя решил, что затяну всю периферию прямо в роутер через 1-Wire, благо owfs у нас уже имеется, и получу в итоге полностью управляемую архитектуру, а не набор коробочек с непредсказуемым поведением.
Программа для управления USB реле MP709
Выкладываю собственную реализацию программы для работы роутера с устройством MP709 - USB реле (http://www.masterkit.ru/main/set.php?code_id=579540)
Не судите строго это мой первый опыт написание программ под железо вооб-ще, да и о Си я имею весьма поверхностные знания. Если кто-то может улучшить и дополнить то вперед!
Программа написана с использованием библиотеке LibUSB (http://www.libusb.org/ брать здесь http://sourceforge.net/projects/libu...es/libusb-1.0/, на момент написания программы последняя версия была libusb-1.0.8) на роутере библиотека собралась без заминок (не забудьте поставить пакет optware-devel) как обычно configure, make, make install.
Проверялась работоспособность на asus rt-n16 и D-link DIR-320 оба с прошивкой от Энтузиастов.
исходный текст mp709.c
Code:/* Copyright (c) 2012, SgE All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the SgE nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SgE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //-------------------------------------------------------------------------------- MP 790 control use ./mp709 on or ./mp709 off to compel use command gcc mp709.c -o mp709_sge_mips -lusb-1.0 -lpthread */ #include <libusb-1.0/libusb.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #define DEV_VID 0x16C0 #define DEV_PID 0x05DF #define DEV_CONFIG 1 #define DEV_INTF 0 unsigned char COMMAND_1[8] = {0xE7,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; unsigned char COMMAND_2[8] = {0xE7,0x19,0x00,0x00,0x00,0x00,0x00,0x00}; int main(int argc, char * argv[]) { if (argc<2) { printf("Please use OFF or ON (no arg) \n"); return 0; } if ((strcasecmp(argv[1], "off")!=0)&&(strcasecmp(argv[1], "on")!=0)) { printf("Please use OFF or ON \n"); return 0; } libusb_device_handle * handle; int ret; unsigned char buf[8]; libusb_init(NULL); libusb_set_debug(NULL, 3); handle = libusb_open_device_with_vid_pid(NULL, DEV_VID, DEV_PID); if (handle == NULL) { printf("no USB DEV found _sge\n"); libusb_exit(NULL); return 0; } if (libusb_kernel_driver_active(handle,DEV_INTF)) libusb_detach_kernel_driver(handle, DEV_INTF); if ((ret = libusb_set_configuration(handle, DEV_CONFIG)) < 0) { printf("Config error\n"); libusb_close(handle); libusb_exit(NULL); if (ret == LIBUSB_ERROR_BUSY) printf("B\n"); printf("ret:%i\n", ret); return 0; } if (libusb_claim_interface(handle, DEV_INTF) < 0) { printf("Dev error\n"); libusb_close(handle); libusb_exit(NULL); return 0; } if(strcasecmp(argv[1], "on") == 0) { ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_1, 8, 100); //-- printf("ON\n"); } if(strcasecmp(argv[1], "off") == 0) { ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_2, 8, 100); //-- printf("OFF\n"); } libusb_attach_kernel_driver(handle, DEV_INTF); libusb_close(handle); libusb_exit(NULL); return 0; }
Buzya, собственно говоря здесь нет ничего сложного. Только нужно уметь пользоваться командной строкой.
Итак, приступим:
(Само собой заходим на роутер)
1. ipkg update # Обновляем базу данных приложений
2. ipkg install optware-devel # устанавливаем пакет optware-devel , в котором есть все необходимое для сборки программ
3. mkdir ./work # создаем директорию, в которой будем работать
4. cd ./work # переходим в нее
5. wget http://citylan.dl.sourceforge.net/pr...-1.0.8.tar.bz2 # загружаем исходные коды библиотеки libusb-1.0.8 (по окончании загрузки в директории должен оказаться файл libusb-1.0.8.tar.bz2)
6. tar -xf ./libusb-1.0.8.tar.bz2 # распаковываем скаченный нами архив
7. cd ./libusb-1.0.8 # переходим в директорию с исходным кодом
8. ./configure # конфигурируем
9. make # компилируем
10. make install # устанавливаем
Вот и все. Будет лучше если вы соберете libusb у себя на роутере по ряду причин.
Вместе с тем выкладываю собранную библиотеку libusb. Решать вам, что именно использовать. На мой взгляд, стоит один раз попробовать собрать самому из исходников и научиться делать это раз и навсегда. Не бойтесь и пробуйте, все когда-то происходит в первый раз и не всегда с первого раза.
P.S.
В архиве две директории, файлы из них должны попасть, как им и подобает, в соответствии со своим содержимым. То, что содержит директория ./include в /opt/include/. То, что содержит директория ./lib в /opt/lib/.
mr.magesty
Спасибо за подробную инструкцию!
Буду учиться!
mr.magesty, большое спасибо за проделанную работу! управление релюшкой работает превосходно.
слегка подкорректировал исходники: http://pastebin.com/1g6rbBMu. впрочем, и первоначальный вариант абсолютно работоспособен.
Code://-------------------------------------------------------------------------------- MP709 control use ./mp709 on or ./mp709 off to compile use command gcc mp709.c -o mp709_sge_mips -lusb-1.0 -lpthread */ #include <libusb-1.0/libusb.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #define DEV_VID 0x16C0 #define DEV_PID 0x05DF #define DEV_CONFIG 1 #define DEV_INTF 0 unsigned char COMMAND_1[8] = {0xE7,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; unsigned char COMMAND_2[8] = {0xE7,0x19,0x00,0x00,0x00,0x00,0x00,0x00}; int main(int argc, char * argv[]) { if (argc != 2 || argc == 2 && (strcasecmp(argv[1], "off") != 0) && (strcasecmp(argv[1], "on") != 0)) goto usage; libusb_device_handle *handle; int ret; unsigned char buf[8]; ret = libusb_init(NULL); if (ret < 0) { printf("failed to initialise libusb!\n"); goto exit; } libusb_set_debug(NULL, 3); handle = libusb_open_device_with_vid_pid(NULL, DEV_VID, DEV_PID); if (handle == NULL) { printf("no connected mp709 device found!\n"); libusb_exit(NULL); goto exit; } if (libusb_kernel_driver_active(handle,DEV_INTF)) libusb_detach_kernel_driver(handle, DEV_INTF); if ((ret = libusb_set_configuration(handle, DEV_CONFIG)) < 0) { printf("mp709 device configuration failed!\n"); goto done; } if (libusb_claim_interface(handle, DEV_INTF) < 0) { printf("mp709 device error!\n"); goto finish; } if (strcasecmp(argv[1], "on") == 0) { ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_1, 8, 1000); if (ret > 0) printf("Relay ON\n"); } if (strcasecmp(argv[1], "off") == 0) { ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_2, 8, 1000); if (ret > 0) printf("Relay OFF\n"); } finish: libusb_attach_kernel_driver(handle, DEV_INTF); done: libusb_close(handle); libusb_exit(NULL); if (ret > 0) exit(0); else { printf("mp709 device communication error!"); goto exit; } usage: printf("Invalid parameters!\n"); printf("Usage: mp709 <on|off>\n"); exit: exit(1); }
Last edited by Omega; 04-08-2013 at 15:15. Reason: fixed
К сведению пользователей Entware: пакет libusb-1.0 есть в репозитории
Также, если есть потребность, и если mr.magesty будет не против, можно будет добавить в репозиторий управляющий бинарник mp709 (оригинальную версию или вариант от oblikoamorale)Code:$ opkg list | grep libusb-1 libusb-1.0 - 1.0.9-1 - libusb is a C library that gives applications easy access to USB devices on
Самая любимая моя лицензия это BSD, так что я не могу быть против, как и любому автору мне будет приятно если мое или модифицированное из моего детище начнет двигаться дальше и кому-то принесет пользу.
Еще мне хочется реализовать где ни будь в Web-интерфейсе отдельную кно-почку (неудобно каждый раз лазить в консоль или писать команды из Web”a) для управления реле, но из-за своей лени никак не найду на это времени.
Last edited by mr.magesty; 19-09-2012 at 14:03.
Добавил пакет mp709 в репозиторий. Взял вариант с правками oblikoamorale.
В коде есть комментарий, предлагающий линковать бинарник с libpthread. Зачем?
Last edited by ryzhov_al; 23-09-2012 at 21:06. Reason: libpthread
Если кому интересно я все таки сломал себе мозг и откомпилировал программу для управления VM110
http://www.chipdip.ru/product/vm110.aspx
Теперь у меня 8 управляемых с роутера релюшек, 2 аналоговых входа, 2 аналоговых выхода (PWM+0-5В) и 5 дискретных входов. И все это удовольствие за 2крубля.
Всем хозяйством можно управлять из консоли (приложение с параметрами) или редактировать программку на си. Сейчас пытаюсь сделать из нее демона.
Пока рулит у меня дома освещением в прихожей (вкл.выкл.по датчику + диммирование по времени суток) и вентиляцией в туалете и ванной.
Если интересно выложу работающий вариант, откомпилированный для нашего устройства и исходники на си и pyton.
Я, кстати, релюшкой тоже заинтересовался. Пока цену не увидел.
Подсмотрел идею, не требующую микроконтроллеров: чип из дешёвой USB-клавиатуры:
- дискретные выходы на релюшки - три светодиода "Num lock", "Scroll Lock", "Caps Lock",
- дискретные входы - без счёта, путём замыкания "координат" матрицы контактов клавиатуры.
Всё управляется стандартными usb-hid драйверами Linux'а.
интересно!
поначалу так и делал, отлично работает! но геморно это. если релюшка нужна не одна, а несколько десятков, гораздо эффективнее взять готовое изделие, чем заниматься рукоприкладством. тем более, не так уж и дорого оно стоит, учитывая цену клавиатуры и потраченное на доработку время.
кроме этого, у клавиатурного варианта есть недостаток - светодиоды caps lock/scroll lock/num lock синхронно мигают при включении устройства.