2017-10-13 13 views
1

Cela fonctionne bien sur le MCU ATMega32U4 cependant ..... lorsqu'il est alimenté par batterie, il ne peut pas détecter une déconnexion de l'USB. Il peut détecter une reconnexion (false) et après cela un état vrai, mais pas de déconnexion.AVR-C: la connexion USB peut être détectée avec succès, pas une déconnexion USB

Par exemple:

bool TEnjoyPad::isUSBConnected() 
{ 
#if defined(UDADDR) && defined(_BV) && defined(ADDEN) 

    //setDelay(1000); 
    Serial1.println("--------"); 
    Serial1.println(UDADDR & _BV(ADDEN), HEX); 
    //Serial1.println(UDADDR, HEX);  // 97 or 98 hex 
    //Serial1.println(_BV(ADDEN), HEX); 

    return (UDADDR & _BV(ADDEN)); 
#else 
    return false; 
#endif 
} 

Lorsque vous jetez un oeil à la ligne:

Serial1.println(UDADDR & _BV(ADDEN), HEX); 

Il imprime:

Connected: 0x80 (function result = true) 
Not connected: 0x00 (function result = false) 

Il peut détecter le changement de ne pas connecté à connecté mais pas connecté à NON connecté (déconnecté).

Existe-t-il une solution simple à cela?


EDIT 13 okt 2017:

Juste cette figure, cela fonctionne mais pas toujours. Trouvé ici: http://forum.arduino.cc/index.php?topic=28567.0

C'est le registre UDINT, il signale 16 décimal (0x10 hexadécimal) lorsqu'il est connecté.

Version modifiée de la première version de cette fonction ci-dessus:

bool TEnjoyPad::isUSBConnected() 
{ 
#if defined(UDADDR) && defined(_BV) && defined(ADDEN) && defined(UDINT) && defined(USBCON) 
    return ((UDADDR & _BV(ADDEN)) && (UDINT)); 
#else 
    return false; 
#endif 
} 

Il fonctionne cependant que lorsque ces conditions sont remplies:

- Device is connected to computer, phone etc 
- Device is disconnected from computer, phone etc 

Si vous utilisez un batterypack USB par exemple, rapports vrai et avec quelques batteries, l'état est toujours vrai lorsqu'il est déconnecté. Le bus est confus? Lorsque vous vous connectez à nouveau à l'ordinateur, au téléphone, etc., il signale false, puis true et lorsqu'il est déconnecté, il signale false (comme il se doit).

Des idées? A quelque chose à voir avec la construction USB datalines?

Dans l'exemple, ils utilisent cette ligne. Il ne fait pas de différence pour moi quand je l'ai ajouté:

USBCON = USBCON | B00010000; 

EDIT 14 okt 2017:

Merci à @ralph htp, voir ma réponse ci-dessous posté, peut-être qu'il peut aider les autres aussi.

Répondre

1

Enfin, fonctionne parfaitement, grâce à "@ralf htp". Il a raison les changements de registre USBSTA à 1 lorsqu'il est connecté à USB et 0 lorsqu'il n'est pas connecté. Vous devez include pins_arduino.h sinon le registre est inconnu. Cela rend très facile la détection du statut de l'alimentation USB.

Cependant, lorsque vous voulez connaître l'état du bus USB, les datalines sont connectées, une connexion est établie, c'est un peu plus compliqué. Vous devez savoir qu'une connexion USB est établie lorsque le MCU doit fonctionner en tant que périphérique HID USB.


Je ne sais pas que ce soit un bug ou tout simplement la façon dont fonctionne USB, l'adresse du périphérique USB est conservé par le MCU même lorsque l'appareil est déconnecté ou connecté à un batterypack USB. Certains registres conservent leurs valeurs même à l'état "invalide".

Toutefois, l'adresse change lorsqu'une connexion est établie. Il est donc possible de comprendre qu'il existe une connexion réelle, qu'une connexion est établie, le MCU est reconnu par l'hôte USB.


Dans mon code suivant je peux détecter:

  • Il est connecté à l'alimentation externe USB;
  • Une connexion de données est établie, le périphérique est reconnu ou non;
  • Avec une combinaison de ces éléments, il est facile de comprendre comment il est alimenté et/ou connecté.

Vous pouvez maintenant décider si une fonction de périphérique est possible ou non, ou signaler à l'utilisateur l'état du périphérique.


Mon code renouvelé ressemble à ceci:

// enjoypad.h 
#include <pins_arduino.h> // Required to access some register defines 
.......... 
.......... 
.......... 

// Via pins_arduino.h => defined in avr/iom32u4.h 
#ifdef USBSTA 
#define TEP_USB_VBUS_CONNECTED (USBSTA == 3) 
#define TEP_USB_VBUS_DISCONNECTED (USBSTA == 2) 
#endif 

#ifdef UDADDR 
#define TEP_USB_ADDRESS (isOnUSBPower()?UDADDR:0) 
#endif 

#if defined(ADDEN) && defined(UDINT) 
#define TEP_USB_ADDRESS_ESTABLISHED (_BV(ADDEN)== 0x80 && UDINT > 0) 
#endif 

.......... 
.......... 
.......... 

// enjoypad.cpp 

uint8_t TEnjoyPad::getUSBaddress() 
{ 
    #ifdef TEP_USB_ADDRESS 
    return TEP_USB_ADDRESS; 
    #else 
    return 0; 
    #endif 
} 

bool TEnjoyPad::isOnUSBPower() 
{ 
    #ifdef TEP_USB_VBUS_CONNECTED 
    return TEP_USB_VBUS_CONNECTED; 
    #else 
    return false; 
    #endif 
} 

bool TEnjoyPad::isUSBDataEstablished() 
{ 
#ifdef TEP_USB_ADDRESS_ESTABLISHED 
    static uint8_t iLastAddress = 0; 
    static uint8_t bUSBDataEstablished = false; 

    // The address changes from 0 to something (byte) or increases 
    // with one each time you plugin the device, when this is an USB host. 
    // If the VBUS not connected, it returns always 0 (zero) 
    uint8_t iAddress = getUSBaddress(); 
    if(iAddress > 0) 
    { 
    //Serial1.println(_BV(ADDEN), HEX); 
    //Serial1.println(UDINT, HEX); 

    if(TEP_USB_ADDRESS_ESTABLISHED) 
    { 
     //Serial1.println(iAddress); 
     // Need update? On USB Battery for example, address stays the same 
     // so it never perform an update and never reports there is a 
     // data connection established. 
     if(iAddress != iLastAddress) 
     { 
     bUSBDataEstablished = true; 
     iLastAddress = iAddress; 
     } 
    } 
    } 
    else { bUSBDataEstablished = false; } 

    return bUSBDataEstablished; 
#else 
    return false; 
#endif 
} 

bool TEnjoyPad::isOnUSBPowerBattery() // Or something else providing power 
{ return (isOnUSBPower() && !isUSBDataEstablished()); } 

bool TEnjoyPad::isOnBatteryPower() 
{ return !isOnUSBPower(); } 

Le code en action :-):

Code in action

0

à la page 261 et 279 de la feuille de données est dit qu'il ya VBUSTI interruption pour USB insérer une suppression.Il y a une mise en œuvre dans la pile APUL (EVENT_USB_Host_DeviceUnattached() si en mode hôte et EVENT_USB_Device_Disconnect() si en mode périphérique) code source

est également en http://caves.org/section/commelect/DUSI/openmag/src/myusb/MyUSB/MyUSB/Drivers/USB/HighLevel/USBInterrupt.h

modifier

valable uniquement en mode périphérique USB :

Si vous souhaitez détecter si une source de tension pure telle qu'un bloc de batterie est fixée ou détachée, vous pouvez utiliser le bloc VBUS (bus de tension). son état est accessible dans le USBSTA (état USB) dans le VBUS bit/drapeau, ceci est dans la feuille de données à la page 268.

pour ce faire capture l'interruption VBUSTI et chaque fois que l'interruption se produit vérifier le bit VBUS/drapeau dans USBSTA registre. si VBUS est élevé (1) la batterie est fixée (tension sur le patin VBUS est> 1,4 V, page Fiche 265) si elle est faible batterie est pas attaché (tension sur la plaquette de VBUS est < 1,4 V)

+0

Hai, merci pour la réponse, mais lien n » t travail: 404 l'erreur suivante s'est produite: L'URL demandée n'a pas été trouvée. n ce serveur. Veuillez vérifier l'URL ou contacter le webmaster. – Codebeat

+1

liaison fixe et dans la pile LUFA sont différentes fonctions en mode appareil et hôte ... –

+0

Merci, je le regarde mais ne mène pas à une solution, du moins pas pour moi. Voir aussi mon edit à ma question. – Codebeat