Go Down

Topic: tester si arduino connecté à un pc ou à une alimentation via prise usb (Read 301 times) previous topic - next topic

jjnoui

Bonjour,
Je souhaite pouvoir envoyer des messages (logs) au bon endroit.

Si une connexion Telnet est en cours, j'envoie via Telnet.

Si l'arduino est connecté sur un pc via la prise usb et qu'un moniteur série est démarré, j'envoie sur le moniteur série.

Si aucun des 2 cas ci-dessus ne sont réalisés et si une carte SD est accessible, j'envoie sur un fichier de la carte SD.

Tout cela fonctionne bien lorsqu'il s'agit de tester l'état d'une connexion Telnet ou d'une carte SD;
par contre comment tester la présence d'un moniteur série sur le port SANS être obligé d'attendre qu'un caractère soit reçu via le port COM.

Imposer un délai au setup dans l'attente d'un caractère ne me satisfait pas : soit on met un délai important et cela retarde le setup, soit on met un petit délai et il faut alors frapper vite et bien ;)

Je peux toujours envoyer sur le port COM sans tester la connexion mais je ne peux pas n'envoyer dans un fichier de la carte SD le message que s'il n'y a pas de connexion série sur le port COM.

Je ne suis pas assez "grand" pour aller fouiller dans les internes de la classe Serial :( .

Si quelqu'un a déjà résolu ce problème je serais ravi de connaître sa solution.

Merci.

_pepe_

Bonsoir

Matériellement, rien ne permet à un Arduino Uno de savoir si quelque chose est branché sur la prise USB de son ATmega16U2, ni si un logiciel qui reste muet a pris le contrôle de l'interface série USB (CDC) sur le PC qui y serait éventuellement branché.

Il faudrait absolument que le logiciel de communication côté PC fasse quelque chose (autre que l'envoi d'une commande de RESET) pour manifester sa présence auprès de l'ATmega328P.

68tjs

Ce n'est pas totalement une réponse à ta question mais si la carte est connectée à un PC il est possible de détecter la présence su 5V en sortie de prise USB ou plutôt en sortie du polyfuse ( pour éviter de court-circuiter accidentellement le circuit USB/PC).
Un fer à souder, un fil soudé en sortie de polyfuse et connecté sur une entrée de microcrontroleur.

jjnoui

@ _pepe_ :
Merci de m'avoir répondu, même si cette réponse m'attriste :(

@ 68tjs :
Pareil pour le merci ;)
Je m'aperçois que j'ai omis une précision importante : lorsque l'arduino n'est pas connecté au pc il fonctionne de manière autonome avec une alimentation secteur branchée, elle aussi, sur le port usb, donc impossible de se baser sur la tension disponible aux bornes de cette prise usb.



En fait j'espérais naïvement que dans un "coin caché" du code se trouvais un indicateur de "présence" du  moniteur série.


_pepe_

Ce n'est pas totalement une réponse à ta question mais si la carte est connectée à un PC il est possible de détecter la présence su 5V en sortie de prise USB ou plutôt en sortie du polyfuse ( pour éviter de court-circuiter accidentellement le circuit USB/PC).
Un fer à souder, un fil soudé en sortie de polyfuse et connecté sur une entrée de microcrontroleur.
Le fil d'alimentation de la prise USB est toujours à un potentiel proche de 5V même lorsque rien n'est branché sur cette prise :
- lorsque la carte n'est pas alimentée par une tension suffisante sur VIN ou sur la prise Jack, le 5V de la carte et le fil d'alimentation USB sont court-circuités par un transistor MOSFET ;
- lorsque la carte est alimentée par une tension suffisante sur VIN ou sur la prise Jack, le fil d'alimentation USB est relié au 5V de la carte au travers de la diode drain-source inverse de ce même transistor.


La détection sans erreur d'une tension sur le fil d'alimentation de la prise USB nécessiterait par exemple de couper ou supprimer le polyfuse et de connecter ce fil :
- à GND au travers d'une résistance de rappel
- à une entrée du microcontrôleur au travers d'une résistance de protection
(deux résistances de 10kΩ devraient convenir).

_pepe_

Je m'aperçois que j'ai omis une précision importante : lorsque l'arduino n'est pas connecté au pc il fonctionne de manière autonome avec une alimentation secteur branchée, elle aussi, sur le port usb, donc impossible de se baser sur la tension disponible aux bornes de cette prise usb.



En fait j'espérais naïvement que dans un "coin caché" du code se trouvais un indicateur de "présence" du  moniteur série.
Il serait éventuellement envisageable de modifier le firmware de l'ATmega16U2 afin de positionner l'état de l'une des sorties accessibles (PB4 à PB7, sous le connecteur ICSP1) lorsqu'une énumération USB a été effectuée par le PC, ou bien de forcer à 0 l'entrée RX de l'ATmega328P tant que cette énumération n'a pas eu lieu.

jjnoui

@ _pepe_ : réponse à la réponse de 21h09

En fait l'Arduino (en réalité, un esp8266 wemos d1 pro) est toujours alimenté via la prise USB, que ce soit par la tension fournie par la prise usb du pc ou par une alimentation secteur, il est donc impossible de déterminer qui alimente cet 'Arduino'.

réponse à la réponse de 21h50

Je crois que j'aurais dû dire dès le début qu'il s'agissait d'un wemos, désolé, je pensais à une solution software commune aux Arduinos.

_pepe_

On a pris l'habitude de considérer qu'on parlait de l'Arduino Uno à défaut d'indication explicite du modèle de carte, car ici cette hypothèse se vérifie dans 95% des cas.


D'après le schéma du Wemos D1 mini Pro, l'interface USB est réalisée à l'aide d'un circuit CP2104. Or, il apparaît que ce circuit présente deux sorties non connectées SUSPEND (#17) et /SUSPEND (#15) qui pourraient être exploitées :

Quote
The USB Suspend and Resume signals are supported for power management of both the CP2104 device as well as external circuitry. The CP2104 will enter Suspend mode when Suspend signaling is detected on the bus. On entering Suspend mode, the CP2104 asserts the SUSPEND and SUSPEND signals. SUSPEND and /SUSPEND are also asserted after a CP2104 reset until device configuration during USB Enumeration is complete.
The CP2104 exits the Suspend mode when any of the following occur: Resume signaling is detected or generated, a USB Reset signal is detected, or a device reset occurs. On exit of Suspend mode, the SUSPEND and /SUSPEND signals are de-asserted.
Both SUSPEND and /SUSPEND temporarily float high during a CP2104 reset. If this behavior is undesirable, a strong pulldown (10 kΩ) can be used to ensure /SUSPEND remains low during reset.


Si j'ai bien compris (mais cela réclame confirmation), ces sorties indiquent quand la liaison USB est inactive, notamment quand aucun hôte USB n'est connecté à la prise.

3Sigma

Bonjour,

Le problème des solutions matérielles c'est que:

Si l'arduino est connecté sur un pc via la prise usb et qu'un moniteur série est démarré, j'envoie sur le moniteur série.
Rien ne va malgré tout indiquer si un moniteur série est démarré ou pas. A mon avis il faudrait quand même creuser ce qui est réalisable logiciellement avec un genre de "ping".

_pepe_

En effet, la seule détection matérielle de la connexion USB ne permet pas de régler le problème de manière satisfaisante, mais peut néanmoins rendre la solution d'un délai dans le setup plus acceptable :

Imposer un délai au setup dans l'attente d'un caractère ne me satisfait pas : soit on met un délai important et cela retarde le setup, soit on met un petit délai et il faut alors frapper vite et bien ;) 
On pourrait ainsi laisser un délai suffisant pour dérouler un protocole d'entrée en communication (attente d'une touche, ping automatique ou autre) quand la connexion est établie, et n'avoir aucun délai quand elle ne l'est pas.

3Sigma

Il faut aussi penser au cas de figure où le moniteur série se ferme alors que le programme a démarré.
Je pense qu'il faut un ping permanent. Après, je ne sais pas quelles sont les contraintes de l'application mais a priori la détection de communication perdue ou retrouvée via un système de ping peut largement se faire en moins d'une seconde. Même en 100 ms ça ne devrait pas poser de problème.

jjnoui

Bonsoir
 
@ _pepe_ :
Euh.. La panne de mon fer à souder qui pourtant est une pointe recouvre facilement 3 à 4 pins du circuit :)

@ 3Sigma :
J'avoue ne pas comprendre l'idée du ping sur un moniteur série.

S'agit-il d'un ping émis par le pc ou d'un ping émis par l'arduino/wemos

J'ai, en fouillant encore, trouvé une routine de traitement d'évènement sur le port Com
   
https://www.arduino.cc/en/Tutorial/SerialEvent

après avoir testé cette routine par un petit croquis de mon cru et ne rien avoir obtenu, j'ai copié-collé l'exemple du tutorial et là aussi aucune réaction.

Je pense, finalement insérer dans la boucle loop le code suivant

Code: [Select]

  while (Serial.available()) {
    char inChar = (char)Serial.read();
    if (inChar == '\n') {
        // la présence du moniteur série est activée dès le 1er message venant de celui-ci
        serialPresent = true;
      break;
    }
  }


Merci à tous

3Sigma

Tu dois aussi penser à la perte du moniteur série. Tu dois faire en sorte que si tu ne reçois pas de données, serialPresent soit à false.
Ca dépend de ton application, mais de deux choses l'une:
  • Tu reçois très régulièrement des données de le part du PC (par exemple, plusieurs fois par seconde). Dans ce cas, l'absence de données reçues te signifiera la perte de connexion. Pas besoin de "ping"
  • Tu reçois des données de temps en temps mais tu veux être sûr que ton programme soit averti rapidement d'une perte de connexion: dans ce cas, tu fais en sorte que ton PC envoie un "ping" (une donnée de test qui ne sert à rien) plusieurs fois par seconde. Si tu n'as rien reçu depuis plus d'une seconde, ça veut dire que tu as perdu la connexion

J-M-L

SerialEvent ne fait que regarder pour vous si le pc / quelque chose à envoyer un octet sur la,ligne série donc vous n'êtes pas plus avancé que si vous faisiez vous même un
Code: [Select]
if (Serial.available()) {...}

Sur un arduino où la liaison série s'etablit Séparément (32U4) vous pourriez tester
Code: [Select]
if (Serial) {...} après un petit délai dans le setup() car Serial sera NULL si pas de connexion physique établie (si la USB CDC serial connexion n'est pas là)... mais pas sur un wemos

Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

jjnoui

Un grand merci à tous

@ J-M-L
Effectivement j'ai testé if (Serial) qui ne fonctionne pas avec un wemos.

@ 3Sigma
J'ai vraiment l'impression de livrer mes informations au compte-gouttes.

Dans le cadre d'utilisation avec un moniteur série, celui-ci pourra être utilisé sur un pc ou sur un mac.
Il faudrait alors écrire un programme pour ces 2 machines.



Conclusion :

Ce qui me gènais le plus était purement théorique.

Il me paraissait inutile d'envoyer sur le port série un message si une connexion Telnet était en cours.

Il me paraissait inutile d'envoyer sur la connexion Telnet un message si aucune connexion Telnet n'était active.

Enfin il me paraissait inutile d'écrire dans un fichier log situé sur la carte SD si un moniteur série ou une connexion Telnet était disponible.

Un message envoyé sur le moniteur série inactif n'est pas bloquant et consomme peu (pour mes contraintes)

Un message envoyé sur une connexion Telnet absente aussi.

La consommation d'espace sur une carte SD n'est pas rédhibitoire (carte de 8Go, un message par seconde de 100 octets = 864 Ko par jour, soit 315,36 Mo par an ce qui laisse de la marge...)

A une prochaine fois.

Très cordialement, jjnoui


 

Go Up