Go Down

Topic: Arduino UNO e protocollo HID: mi date una mano a capirci qualcosa? (Read 4040 times) previous topic - next topic

Dani88

Ciao :)
Avrei bisogno di un po di aiuto per un progetto che sto sviluppando, ovvero la realizzazione di un controller HID per del software che ho su pc.
Ho comprato la board UNO dato che avendo l'ATmega8U2 riprogrammabile è possibile, da quello che ho capito, far riconoscere il tutto come dispositivo HID.
Pensavo, per farlo di utilizzare il firmware LUFA presente su:
http://www.fourwalledcubicle.com/LUFA.php

Nell'attesa che mi arrivi la board sto cercando di capire un po come funziona il tutto. Vi descrivo brevemente le "specifiche" di progetto:

---- LATO PC ----
Il software usa un file xml di configurazione in cui viene specificato a quale bit, byte, word, ecc... associare un comando che verrà poi letto dal programma, ad esempio:
Code: [Select]
<button bit="0x08" name="PLAY" />

Facendo delle prove con il Wiimote e il pad Play Station 2 (gli unici dispositivi HID che avevo in casa tastiera a parte) e usando il programma HID Trace ottengo una cosa del tipo:


Quindi in questo caso quando cambia il bit 8 della prima riga da 0 a 1 (nella foto è già a 1) al programma verrà inviato il comando "PLAY".
Ovviamente per i pulsanti basta un bit, se devo leggere valori analogici il comando verrà associato ad 1 o 2 byte che contengono il valore letto.
es:
Code: [Select]
<slider word="2" name="VOLUME" />

---- LATO ARDUINO ----
A questo punto io devo poter inviare al pc una "matrice di bit" come quella che vedete in foto, giusto?
Da quello che ho capito in un dispositivo HID vi sono dei blocchi di memoria di grandezza (definita a scelta?) in cui vengono scritti dei valori.
Ogni volta che cambia anche solo un bit il tutto viene inviato al pc
Quote

Your firmware writes in a small block of memory (usually located in the HID chipset) bits and bytes corresponding to the state of your device (positions of sliders, state of buttons, etc).
When something changes in this memory block, the HID chipset will signal the computer to read it.
Then, as soon as the software on the computer is ready, it will read the memory block and react to the changes found within.
(it means that a slider can change several times while the computer is busy, the computer will read only the current position when it has time to do so).

The whole memory block is transmitted to the computer every times, even if only one bit changed.
But the memory blocks are small enough (usually 32 or 16 bytes), that the bandwidth used is not much more than sending a 4 bytes MIDI message.
In real-life situations, the extra 12 or 28 bytes per message are ridiculously small compared to the bandwidth of USB 1.0.

Mi pare di capire quindi che tali blocchi di memoria siano nell'ATmega8U2, giusto?
Come faccio però da Arduino a riempire questa "memoria" del chip 8u2?

Esempi:
- Premo il pulsante A e devo di conseguenza settare a 1 il bit 0x07 in modo che il pc sia accorga della pressione.
- Ruoto il trimmer, devo quindi assegnare il nuovo valore letto (supponiamo sia a 16 bit anche se poi sarà solo 10) dal bit 0x10 al bit 0x1F

Come si fa a fare tutto questo? :(
Un aiuto sarebbe veramente molto molto gradito perchè per quanto stia leggendo capisco poco smiley-sad

astrobeed


Un aiuto sarebbe veramente molto molto gradito perchè per quanto stia leggendo capisco poco :(


Mi sa tanto che hai le idee molto confuse, prima di tutto non si impara come funziona la USB in poche ore, servono molti giorni di studio e prove pratiche, in secondo luogo non è per niente semplice scrivere il software da mettere sul 8u2 per avere un device HID, e tieni presente che dal momento in cui lo fai perdi la possibilità di programmare Arduino tramite la USB.
Dopo le premesse e semplificando al massimo come funziona un device HID hai dei buffer, chiamati EndPoint, su i quali trovi i dati in arrivo, c'è un flag che ti avviso quando sono pronti, e per mettere i dati in uscita, anche in questo caso settando un flag vengono trasmessi verso il pc, quindi alla fine una volta che hai realizzato il device devi solo leggere e scrivere gli EndPoint per trasferire/ricevere i dati.
In tutti i casi la comunicazione tra Arduino e l'8u2 avviene via seriale, quindi tanto vale che mantieni il device CDC, porta seriale virtuale, di serie e dialoghi con il   pc tramite questo senza imbarcarti in una impresa tutt'altro che semplice anche per uno esperto, in pratica se non ti serve per forza un device HID particolare, p.e. una emulazione tastiera, non ha senso mettersi a modificare quello di serie sul 8u2.
Scientia potentia est

Dani88

Ho provato a spiegare nuovamente il progetto (ho modificato il primo post) sperando che ora sia un poco più chiaro cosa vorrei fare.
Spero che qualcuno riesca a darmi un paio di dritte, intanto ho trovato un libro sull'usb che potrebbe essere molto utile :)

bigjohnson

Guarda, non per scoraggiarti, che realizzare il tuo progetto è veramente molto complicato.
Il protocollo usb è un casino, anche se il sottoinsieme del Human Interface Devices è più gestibile.
L'implementazione del software lato computer è piuttosto laboriosa, la principale libreria multipiattaforma per la comunicazione usb è la libusb, di cui esiste anche una versione per java.
Per iniziare a sviluppare qualcosa temo sia essenziale un analizzatore di protocollo usb per fare il debug.

Alberto

Dani88


Guarda, non per scoraggiarti, che realizzare il tuo progetto è veramente molto complicato.
Il protocollo usb è un casino, anche se il sottoinsieme del Human Interface Devices è più gestibile.
L'implementazione del software lato computer è piuttosto laboriosa, la principale libreria multipiattaforma per la comunicazione usb è la libusb, di cui esiste anche una versione per java.
Per iniziare a sviluppare qualcosa temo sia essenziale un analizzatore di protocollo usb per fare il debug.

Alberto


No no ma il software è già fatto, mi ci devo solo interfacciare scrivendo il file xml come dicevo nel primo post.
Se proprio non riesco con un HID generico posso provare con un MIDI HID (il software accetta anche comandi MIDI configurando sempre un altro file xml, ma preferirei usare HID se riesco perchè è più versatile).
In giro ho letto di vari progetti di MIDI, tastiere, joystick, ecc... fatti usando LUFA e arduino UNO.
Quello che non ho capito però è: LUFA serve per scrivere un firmware giusto?
Quindi per evitare di doverne scrivere uno custom (che non avrei effettivamente idea di come si faccia) dovrei trovarne uno pronto (come il MocoLUFA per i MIDI --> http://arduino.cc/en/Hacking/MidiWith8U2Firmware) che gestisca un HID generico.
Sto dicendo cavolate immense o c'è qualcosa di giusto? xD xD

EDIT:
Se non ho capito male, se usassi ad esempio il MocoLUFA una volta caricato tale firmware sul 8u2 io da arduino poi lancio segnali midi sulla seriale come farei normalmente usando la libreria MIDI... si occupa poi il chip di tradurre tutto, corretto?
Ecco io vorrei trovare una cosa analoga...però non esclusivamente per MIDI

astrobeed


No no ma il software è già fatto, mi ci devo solo interfacciare scrivendo il file xml come dicevo nel primo post.


Forse è meglio che ti leggi attentamente la documentazione del software, non è così semplice come credi.
Scientia potentia est

Dani88

Ti assicuro che per quanto riguarda la parte software, con il programma HID trace che mostra i vari bit come cambiano a seconda degli input premuti (se guardi la foto del primo post capisci che intendo, ad es il bit 0x08 è a 1 dato che premevo ora non ricordo quale tasto del pad play station 2 che lo vede come hid ) è abbastanza semplice andare a creare il file xml.
Ho provato col wiimote premendo un tasto per volta, questo è quello che ho ottenuto:
### HID trace screen con tasto A del wiimote premuto###


### XML configuration file ###
(con molta fantasia i nomi dei comandi corrispondono a quelli dei pulsanti del wiimote  :smiley-yell:)
Code: [Select]

<device name="Wiimote" author="Dani" type="HID" vid="0x057e" pid="0x0306" reportsize="21" >
    <page type="in">
        <button bit="0x04" name="UP"/>
        <button bit="0x05" name="DOWN"/>
        <button bit="0x07" name="LEFT"/>
        <button bit="0x06" name="RIGHT"/>
        <button bit="0x0c" name="A"/>
        <button bit="0x0d" name="B"/>
        <button bit="0x0b" name="-"/>
        <button bit="0x08" name="HOME"/>
        <button bit="0x03" name="+"/>
        <button bit="0x0e" name="1"/>
        <button bit="0x0f" name="2"/>
    </page>
    <page type="out">
    </page>
</device>

e il tutto funziona tutto alla perfezione :) il programma riconosce quello che deve.

Il mio problema è appunto inviare al pc i vari comandi, ovvero la matrice di bit che vedi nello screen, che altro non è se non ho capito male, che il/i blocco/i di memoria di cui parla la parte inglese che ho riportato nel primo post.

astrobeed


Ti assicuro che per quanto riguarda la parte software, con il programma HID trace che mostra i vari bit come cambiano a seconda degli input premuti


Guarda che io sto parlando del lato Arduino, sul pc non c'è problema per leggere un device HID, esistono librerie per ogni linguaggio in grado di farlo.
Scientia potentia est

Dani88

Ah scusa avevo capito male :( :(
Cmq ho messo (nel post precedente) anche delle screen fatte sul momento utilizzando il wiimote. Ora io non so come lo veda il pc, mi dice semplicemente "Dispositivo HID installato", ne come come e cosa comunichi.

Fin'ora ho capito (sperando sia giusto) che quello che su HID trace viene riportato come "Size" sia la dimensione in byte del blocco di memoria, dico una cavolata?
Guardando quello del wiimote dice "Size 21/21" ed effettivamente ho 21 byte.

astrobeed


Usando il programma che analizza cosa arriva dal dispositivo hid io l'unica cosa che ho capito è che vengono inviati questi bit.


Ecco appunto, non hai la più pallida idea di come funziona l'USB  :)
Segui il mio consiglio, lascia perdere l'HID e dialoga con Arduino tramite la sua seriale virtuale, è tutto pronto e sicuramente funzionante.
Scientia potentia est

Dani88

#10
Jan 11, 2012, 06:56 pm Last Edit: Jan 11, 2012, 07:03 pm by Dani88 Reason: 1

Ecco appunto, non hai la più pallida idea di come funziona l'USB  :)
Segui il mio consiglio, lascia perdere l'HID e dialoga con Arduino tramite la sua seriale virtuale, è tutto pronto e sicuramente funzionante.

Se lascio perdere l'HID lascio perdere anche il progetto dato che NON posso comunicare via seriale (cosa che avevo già fatto con Arduino 2009 interfacciandomi poi ad un programma in Java scritto da me per fare qualche esperimento di domotica), ma qui il programma non l'ho scritto io...o uso HID o MIDI...
Il massimo che posso fare è usare MocoLUFA ed inviare segnali MIDI, ma sinceramente eviterei (uno dei tanti motivi è che lo stack MIDI di windows crasha se vengono inviati troppi comandi per unità di tempo)...
Non pretendo di conoscere a fondo l'USB, ne mi sembra che serva per quello che ho in mente.
Ripeto, usando un firmware già pronto per l'8u2 come quello per il MIDI, alla fine io devo solamente scrivere codice da mettere sul arduino, di cosa poi fa l'8u2 posso anche non andare più di tanto a fondo anche se sto leggendo un po di cose sull'usb...
Spero di essermi spiegato...io (se possibile) NON voglio scrivere il firmware per l'8u2... non intendevo quello come progetto...

Dani88

nessuno riesce a darmi una mano o ha utilizzato il framework LUFA? :(

Go Up