Форум программистов, компьютерный форум, киберфорум
Наши страницы
КИП, датчики
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.72/60: Рейтинг темы: голосов - 60, средняя оценка - 4.72
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
#1

Отправка данных в STM32F407VG Discovery используя HID USB в C#

23.01.2014, 16:21. Просмотров 10903. Ответов 34
Метки нет (Все метки)

Здравствуйте киберфорумчане )
Недавно задался вопросом как управлять контроллером STM32F407VG Discovery через HID USB используя своё ПО написанное в С#.
Для простоты чтобы понять принцип в интернете нашёл прошивку hex для контроллера (чтобы точно быть уверенным, что со стороны МК прошивка рабочая) и проверил её для надёжности с помощью утилиты от ST под названием HID USB Demonstrator. Диоды весело зажигаются всё норм.
Затем нашёл библиотеку HID USB Library которая думаю многим хорошо известна и стал разбираться как же управляется МК через ПК.

Для простоты в С# сделал минимальный код, чтобы проверить работу подключения устройства и отправкой данных.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using USBHIDDRIVER;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //Подключаем библиотеку USBHIDDRIVER
            USBHIDDRIVER.USBInterface usb = new USBInterface("vid_0483","pid_5710"); 
           
         String[] list = usb.getDeviceList(); //Запрашиваем список устройств
           
 
           bool connect = usb.Connect(); // Устанавливаем соединение с устройством 
 
           if (connect == true) // выводим сообщение о состоянии подключения
           {
               Console.WriteLine(list[0]); //выводим данные об устройстве из первого знаечния в массиве
               Console.WriteLine();
               Console.WriteLine("USB Devise..On"); //пишем что устройство подключено (для удобства)
           }
            else
            {
                Console.WriteLine("USB Devise..Off"); // выводим сообщение если устройство откл. (тоже для удобства)
            }
 
 
 
           // а вот теперь самое непонятное, создаю массив из 2-х байт которые хочу отправить на МК
          // по идее должен загореться диод после запуска приложения
              
             byte[] data = { 1, 1 }; //создаём простой массив из 2-х байт
 
               usb.write(data); // отправляем массив (согласно описанию об этой команде, которая должна отправлять массив данных 
               Console.ReadLine();
           
        }
    }
}
В итоге что у меня получилось, прга увидела нужное устройство, (отображаются данные об устройстве)
Но по каким то причинам, не могу отправить команду на включение диода (МК работает исправно и в HID USB Demonstrator всё зажигается)

Вполне вероятно я тупо не так что-то делаю.

Если есть кто уже работал над похожей задачей?
Буду очень благодарен за любую подсказку))
0
Миниатюры
Отправка данных в STM32F407VG Discovery используя HID USB  в C#  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.01.2014, 16:21
Ответы с готовыми решениями:

Перехват данных USB сканнера Xenon 1900 в HID режиме
Как перехватить поток данных идущий со сканера в ПК через USB вход ?

Работа с USB HID из верхнего уровня
Всем привет, задумал сделать приложение для ПК которое будет общатся с PIC...

Raspberry Pi. Доступ к USB HID через libusb
Все привет. Есть устройство работающее как USB HID.Но не могу написать...

STM32F4 USB HID Host отправка данных в девайс
Здравствуйте. Кто нибудь пробовал подключить кастомный девайс к сабжу?...

USB HID на STM32F3 Discovery
Доброго времени суток! Народ, помогите поладить с USB-HID. Что-то совсем ничего...

34
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
23.01.2014, 16:45 #2
C#
1
byte[] data = { 0х01, 0х01 };
или дело в том, что:
согласно описанию об этой команде, которая должна отправлять массив данных
вы неправильно поняли описание данной команды из HID USB Demonstrator. Кстати, где оно, описание?

P.S.: и еще, метод write() класса USBInterface сам определяет размер массива? Лезть в кишки не очень хочется, чтобы это узнать ...почитал, сам определяет и делит.
0
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
23.01.2014, 16:52  [ТС] #3
Я брал описание работы с этой библиотекой вот отсюда http://microsin.net/programming/PC/h...et-csharp.html
Но там просто говорится про массив и отправку без примера.
В C# я пробовал по разному писать, но эксперименты не дали результата ))
Сейчас попробовал как вы предложили...но результат нулевой ))
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
23.01.2014, 16:56 #4
...мне не нужно описание библиотеки, уже и так посмотрел.

Что насчет:
согласно описанию об этой команде, которая должна отправлять массив данных
где оно?
0
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
23.01.2014, 16:59  [ТС] #5
Цитата Сообщение от raxp Посмотреть сообщение
...мне не нужно описание библиотеки, уже и так посмотрел.

Что насчет:
где оно?
К сожалению это всё что мне известно, ну может ещё что-то можно выудить из файла в самом C#
Но там тоже скудная сточка на англ про массив, мол если массив большем 64 то делиться на след массив

Сводка:
Writes the specified bytes to the USB device. If the array length exceeds 64, the array while be divided into several arrays with each containing 64 bytes. The 0-63 byte of the array is sent first, then the 64-127 byte and so on.

Параметры:
bytes: The bytes to send.

Возвращает:
Returns true if all bytes have been written successfully
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
23.01.2014, 17:39 #6
К сожалению это всё что мне известно
откуда это известно? Почему вывод о том, что два байта, а не один или пять? Все таки есть документация?

USB снифферами пробовали отследить обмен по шине?

Writes the specified bytes to the USB device. If the array length exceeds 64, the array while be divided into several arrays with each containing 64 bytes. The 0-63 byte of the array is sent first, then the 64-127 byte and so on.

Параметры:
bytes: The bytes to send.
отношения к делу не имеет, этот вопрос уже закрыт.
0
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
23.01.2014, 17:57  [ТС] #7
Цитата Сообщение от raxp Посмотреть сообщение
откуда это известно? Почему вывод о том, что два байта, а не один или пять? Все таки есть документация?

USB снифферами пробовали отследить обмен по шине?

отношения к делу не имеет, этот вопрос уже закрыт.
Я решил что 2 байта потому что HID USB Demonstrator пишет в сводке об устройстве, что приём\отправка данных 2 байта..
Снифер принимает сообщение (при нажатии кнопки на МК) в виде 005 001 и 005 000 (нажата\отжата)
Но при отправки подобного сообщения в виде 001 001 тоже ничего не происходит ..
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
23.01.2014, 20:22 #8
Я решил что 2 байта потому что HID USB Demonstrator пишет в сводке об устройстве, что приём\отправка данных 2 байта..
так и пишет? А может 1 байт отправил, 1 принял? Т.е. просто гадание.

Снифер принимает сообщение (при нажатии кнопки на МК) в виде 005 001 и 005 000 (нажата\отжата)
приведите отображение в сниффере в HEX/
0
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
23.01.2014, 21:03  [ТС] #9
Это отображение 2-х программ, в одной видно приём и отправка байтов и расшифровывется что и откуда, но она просто считывает всё что происходит с USB, это данные сичтаные при использовании HID USB Demonstrator т.е. рабочий вариант. Другая прога, где надписи 005 001, это программа из библиотеки к USB С# (я нашёл ещё одну библиотеку для C#) в ней данные не принимаются МК.
Думаю это скорее как-то связано параметрами самой библиотеки.
0
Миниатюры
Отправка данных в STM32F407VG Discovery используя HID USB  в C#   Отправка данных в STM32F407VG Discovery используя HID USB  в C#  
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
23.01.2014, 21:11  [ТС] #10
Это отображение 2-х программ, в одной видно приём и отправка байтов и расшифровывается, что и откуда, но она просто считывает всё что происходит с USB, это данные считанные при использовании HID USB Demonstrator т.е. рабочий вариант. Там видно Transfer Bufer 0000: 05 01 (это тоже едйствие что и в другой проге 005 001, те. нажатие кнопки), а вот 01 01 это посылка команды в МК.

Другая прога, где надписи 005 001, это программа из библиотеки к USB С# (я нашёл ещё одну библиотеку для C#) в ней данные не принимаются МК. Ответ 005 001 и 005 000 это ответ на нажетие кнопки на МК, а вот отправить данные не получается
Думаю это скорее как-то связано параметрами самой библиотеки.. т.е. мне надо как-то разобраться как она работает.
0
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
24.01.2014, 01:44  [ТС] #11
После долго разбора кода другой библиотеки HID USBLibraty в программе которая прилагалась к библиотеки в виде файлов C# наконец-то нашёл ошибку почему не отправлялись данные в виде 001 001.
В SpecifiedOutputReport.cs была допущена ошибка в которой массив начинался с единицы в то время как должна с нуля. После правки, байты стали отправлять команды.

Здесь я прикреплю эту библиотеку HID USB c рабочим кодом. Она может быть несколько поудобней чем ту которую я использовал в топике темы, но если я найду способ как отправлять данные на STM32F407VG с помощью той библиотеки, то отпишусь.

Так же в архиве приложил рабочую прошивку для МК STM32F407VG hex формата.

Но всё же, теперь надо это как-то прикрутить к своей программе C# )))
1
Вложения
Тип файла: zip UsbLibraryC#.zip (396.2 Кб, 129 просмотров)
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
24.01.2014, 02:23 #12
...из интересу, будет срабатывать репорт?
0
Вложения
Тип файла: zip test_hidout.zip (431.8 Кб, 77 просмотров)
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
24.01.2014, 02:37  [ТС] #13
Цитата Сообщение от raxp Посмотреть сообщение
...из интересу, будет срабатывать репорт?
Да, срабатывает ))) ..только там работает первая кнопка потому что первый байт определяет порт, а второй управляющий, ну т.е. 0 выкл/ 1 вкл )) ..типа (0х01, 0x01) (0x02, 0x01) или (0х01, 0x00) и т.д. .. а так всё отлично работает )))
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
24.01.2014, 10:07 #14
...а, ну так я ж приложил исходник и пример использования самой DLL с описанием. Вы можете ее использовать, через маршаллинг в C#.

работает первая кнопка потому что первый байт определяет порт, а второй управляющий
это уже так реализовано в прошивке дискавери. Первый байт в HID-обмене определяет - репорт устройства, второй - данные.
1
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
24.01.2014, 14:57  [ТС] #15
А кстати, меня удивило, что в вашем примере, у тестовой програмки совпал vid и pid устройства.
Вы что-то меняли или это просто случайное совпадение?
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
24.01.2014, 15:24 #16
...это демо-пример к моей библиотеке "HIDOUTEX.DLL" по работе с HID устройствами, я просто поменял vid/pid на ваше устройство
0
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
26.01.2014, 12:55  [ТС] #17
Уфф, долго я мучился соображая как вообще что-то подключить в C# в итоге получилось вот что:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace USB_Test
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Определяем USB устройство (oDev) нзначив VID/PID
            var USBDevise = UsbLibrary.SpecifiedDevice.FindSpecifiedDevice(vendor_id: 0483, product_id: 5710);
 
            //Вызываем функцию отправки 2-х байтов (SendData) нашему устройству (oDev: USBDevise) и возрщаем False/True
            var Senddata = new UsbLibrary.SpecifiedOutputReport(oDev: USBDevise).SendData(new byte[] { 1, 1 });
 
 
            Console.WriteLine(Senddata);//Выводим строчку возвращённого значения False/True
 
            Console.ReadKey();
        }
    }
}
Этот код для второй библиотеки которую выложил выше постом.
Тут я пытался просто понять минимум необходимый для работы с устройством, т.е. подключение и отправка байтов. К сожалению этот код всё ещё не работает, т.к. при компиляции ссылается на отсутствие значения

C#
1
SetBuffer(new byte[oDev.OutputReportLength]);
в:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class OutputReport : Report
    {
        /// <summary>
        /// Construction. Setup the buffer with the correct output report length dictated by the device
        /// </summary>
        /// <param name="oDev">Creating device</param>
        public OutputReport(HIDDevice oDev) : base(oDev)
        {
            SetBuffer(new byte[oDev.OutputReportLength]);
        }
    }
    /// <summary>
    /// Defines a base class for input reports. To use input reports, use the SetData method and override the 
    /// ProcessData method.
    /// </summary>
находящийся в Report.cs

Я пока не понял, где или как прописать это значение.
0
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
27.01.2014, 17:45  [ТС] #18
Что-то до сих пор не могу сообразить, как работает эта библиотека. Выше постом писал про ошибку возникающую в строчке
C#
1
SetBuffer(new byte[oDev.OutputReportLength]);
Есть люди кому интересно разобраться как работать с этой библиотекой?
0
Quadro-pro
4 / 4 / 0
Регистрация: 10.01.2014
Сообщений: 44
29.01.2014, 04:11  [ТС] #19
В общем повозившись с библиотекой и экспериментов, по каким то причинам библиотека не видит моё устройство.
Делаю консольное приложение, поэтому тупо взять код из прилагаемого приложения Sniffer (которое между прочем на этой библиотеке отлично работает) не получается.

Выше описанная мной ошибка решилась, она появлялась из-за отсутствия устройства.
Код получился следующим:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace USB_Test
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Определяем USB устройство (oDev) назначив VID/PID
            var USBDevice = UsbLibrary.SpecifiedDevice.FindSpecifiedDevice(vendor_id: 0483,product_id:5710);
 
            if (USBDevice != null)
            {
                //Вызываем функцию отправки 2-х байтов (SendData) нашему устройству (oDev: USBDevise) и возрщаем False/True
                var Senddata = new UsbLibrary.SpecifiedOutputReport(USBDevice).SendData(new byte[] { 1, 1 });
                //USBDevice.SendData(new byte[] { 1, 1 });
               Console.WriteLine(Senddata); //Выводим строчку возвращённого значения False/True
            }
            else
            {
                Console.WriteLine("Устройство не найдено");
            }
            Console.ReadKey();
        }
    }
}
Тут устройство вызывалось через
C#
1
 pecifiedDevice.FindSpecifiedDevice
Как я понял можно использовать и
C#
1
 var USBDevice = UsbLibrary.HIDDevice.FindDevice(0483, 5710, null);
где null позиционируется как oType: что именно это может быть я так и не понял.

Далее я пробовал иницировать устройство примерно как в Sniffer, через
C#
1
UsbHidPort
Код вышел примерно такой:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace USB_Test
{
    public class Program
    {
        public static void Main(string[] args)
        {      
            var usb = new UsbLibrary.UsbHidPort();
 
            Console.WriteLine();
 
            int Vid = 0483;
            int Pid = 5710;            
 
            try
            {
                usb.VendorId = Vid;
                usb.ProductId = Pid;                
                usb.CheckDevicePresent();                
            }
            catch (Exception ex)
            {
                Console.WriteLine("Устройство не найдено", ex);
            }
           
            if (usb.SpecifiedDevice != null)
                {
                    Console.WriteLine("Устройство найдено");
                }
                else
                {
                    Console.WriteLine("Устройство не подключено");
                }
            
            Console.ReadKey();
          
        }
    }
}
Добавлено через 4 часа 35 минут
Ответ нашёлся )))

Оказалось причина до безобразия простая ))) Чтобы устройство находилось успешно, необходимо Vid и Pid прописывать в hex формате ))
Меня с толку сбила предидущая библиотека, в которой vid/pid прописывались в виде string.
Я стал смотреть HIDDevice.cs как формируется параметр, обнаружил, что нужно прописывать в hex формате и после того как я поменял, всё стало работать.
Сами данные, прописываются в массиве не как hex, а в байтах вида {1,1..0 }

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

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace USB_Test
{
    public class Program
    {
        public static void Main(string[] args)
        {
 
            //Определяем USB устройство (oDev) назначив VID/PID
            var USBDevice = UsbLibrary.SpecifiedDevice.FindSpecifiedDevice(0x0483, 0x5710);
 
            if (USBDevice != null)
            {
                //Вызываем функцию отправки 2-х байтов (SendData) нашему устройству (oDev: USBDevise) и возрщаем False/True
                var Senddata = new UsbLibrary.SpecifiedOutputReport(USBDevice).SendData(new byte[] { 1, 1 });
                USBDevice.SendData(new byte[] { 1, 1 });
                Console.WriteLine(Senddata); //Выводим строчку возвращённого значения False/True
            }
            else
            {
                Console.WriteLine("Устройство не найдено");
            }
            Console.ReadKey();
 
        }
    }
}
Тут использовался метод SpecifiedDevice.FindSpecifiedDevice т.к. в нём ненужно указывать параметр Type.

Что касается первой библиотеки, которую выкладывал в самом начале.
Библиотека успешно находит устройство и пишет о нём необходимые данные, но она не отправляла репорты. Моё подозрение на то, что начальные и конечные точки равны 64 байту, а в прошивке устройства возможно меньше, отсюда МК просто не понимает, что ему приходит.

Добавлено через 43 минуты
Ещё хотелось бы добавить ссылку на официальную страницу HID USB на которой можно найти HID USBLibrary для С# 2012 (там предупреждают что работает только с Fraemwork 4.5), а также для ранних C#, Visual Basic, Visual C++, Linux.
Эта ссылка скорее всего вам уже известна, но на всякий ещё раз оставлю ещё раз т.к. по теме и может быть полезной.
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
29.01.2014, 08:58 #20
...вот сюда добавляйте Библиотеки для работы с USB. Нижний и верхний уровень

p.s.: мою либу подключить к прожекту пробовали?
0
29.01.2014, 08:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.01.2014, 08:58

STM32L-DISCOVERY + USB (HID)
1) Пытаюсь запустить демо-код из библиотеки STM32 USB FS Device Lib V3.3.0 для...

Прием\Отправка и обработка данных в USART STM32F407VG
Всем доброго времени суток Стоит такая задача:со считывателя RFID приходят...

Работа с USB HID используя библиотеку от Florian Leitner-Fischer
Добрый день. У меня возник вопрос по поводу работы с USB HID устройством...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru