IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants FMX Delphi Discussion :

Bibliothèque pour communication serie via câble OTG (vers arduino, USB midi interface, autres)


Sujet :

Composants FMX Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut Bibliothèque pour communication serie via câble OTG (vers arduino, USB midi interface, autres)
    bonjour à tous,

    J'aimerai faire communiquer en série un Android avec des périphériques USB en passant par un câble OTG "On The Go"
    https://fr.wikipedia.org/wiki/USB_On-The-Go
    L'avantage est que le périphérique peut être alimenté par le smartphone lui-même, rendant l'ensemble portable et autonome sans avoir à recourir à un ordinateur PC.

    Nom : OTG.jpg
Affichages : 183
Taille : 68,0 Ko

    Il y a beaucoup d'exemples et de tuto Android en liaison Bluetooth
    mais personnellement, je voudrai éviter les aspects : manipulations supplémentaires, fiabilité, réactivité, ondes, conso électrique et pb d'alimentation du périphérique.

    Donc voici un exemple concret de ce que je souhaite faire
    https://www.instructables.com/Arduin...Communication/
    mais c'est sous Android Studio et avec une bibliothèque Java.

    J'ai essayé AndroidStudio (ignorant que Delphi pouvait désormais compiler des applis Android) mais j'ai été complètement dépassé par sa complexité.
    Je viens de découvrir la version Delphi CE 10.4 (venant de Delphi 4 puis 7 puis 2005) qui pourrait m'aider à atteindre mon but
    mais j'avoue être surpris devant l'absence de composant standard pour établir une communication série.

    J'ai cherché un peu d'aide par le biais d'une bibliothèque :
    ► je n'en ai trouvée qu'une seule gratuite en FireMonkey FMX !
    https://github.com/LongDirtyAnimAlf/...ndroid-USB-HID
    This is a simple clone of the Jedi JVCL library to access Hid devices on Android with Delphi. Not all functions fom the original JVCL library are available. But this simple clone will allow you to control most HID devices.
    j'ai réussi à compiler la démo mais je ne vois pas apparaître les infos textes envoyées par l'arduino... ni par l'interface USB Midi.

    => Si quelqu'un l'a déjà utilisée ou a envie de tester, ce serait super d'avoir votre retour !

    merci !

  2. #2
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Ensuite j'ai trouvé de nombreuses bibliothèques Java que je vous partage ci-dessous :
    ► aymenjegham / Android-to-Arduino-via-OTG
    https://github.com/aymenjegham/Andro...UsbHostArduino

    ► mik3y / usb-serial-for-android https://github.com/mik3y/usb-serial-for-android
    https://github.com/mik3y/usb-serial-for-android
    This is a driver library for communication with Arduinos and other USB serial hardware on Android, using the Android USB Host Mode (OTG) available since Android 3.1 and working reliably since Android 4.2.
    No root access, ADK, or special kernel drivers are required; all drivers are implemented in Java. You get a raw serial port with read(), write(), and other functions for use with your own protocols.

    ► omaraflak / Arduino-Library https://github.com/OmarAflak/Arduino-Library
    A lightweight Android library to communicate with Arduino through USB.
    example en AndroidStudio https://hingxyu.medium.com/arduino-a...n-b72b124142fb

    https://github.com/felHR85/UsbSerial
    Android serial
    example en Kotlin AndroidStudio
    https://www.digikey.fr/en/maker/proj...310c6b3b2a4364
    tuto vidéo www.youtube.com/watch?v=QHa6HWTmQFs

    ► Physicaloid https://github.com/ksksue/PhysicaloidLibrary

    Ma question est comment utiliser une bibliothèque java dans mon appli FMX s'il vous plaît ?
    j'ai trouvé quelques réponses mais j'aimerai bien un conseil pratique pour m'orienter vers une solution faisable par un amateur !
    merci !

    https://docwiki.embarcadero.com/RADS...o_Android_Apps

    https://aziga.x10.mx/delphi/index.ph...d=28&Itemid=33

    Using Java classes in Android apps with Java2OP (Java To Object Pascal). Java2OP.exe is a command-line tool that you can use to generate Delphi-native bridge files from Java libraries (JAR or class files). Once having generated the Object Pascal files describing the Java needed classes, you can then use them to provide your Delphi application's access to those Java libraries on Android.

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    8 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 8 761
    Points : 28 517
    Points
    28 517
    Par défaut
    alors, la grosse différence entre Android Studio et Delphi, c'est que le premier utilise Java (ou Kotlin) pour produire du DalvikCode qui est la version Android de la machine virtuelle Java, alors que Delphi produit une bibliothèque ARM (un .so).

    J'ai un projet (qui n'avance pas) d'un compilateur Pascal pour Dalvik

    tu as aussi du code Dalvik dans Delphi puisque c'est le point de départ d'une application Android, tu peux le personnaliser mais Delphi produit ce qu'il faut pour lancer le code ARM de FMX.

    donc, pour dialoguer avec le port USB tu as deux options

    1) utiliser l'API Linux (Android tourne sous Linux) si elle est disponible et que tu as les droits nécessaires pour le faire.

    2) utiliser un wrapper Java, c'est à dire que tu vas invoquer via JNI les classes Java de Android depuis ton code ARM.

    alors c'est "facilité" sous Delphi par des Interfaces, mais comme je ne fais pas ça tous les jours, je n'ai plus en tête les détails...voyons ce que ça donne avec un exemple.

    Dans un projet j'avais besoin de charger un certificat personnalisé (autosigné) pour une connexion TLS...ça passe par CertificatFactory

    je n'avais pas besoin de toute l'interface, je n'ai donc déclaré que les fonctions dont j'avais besoin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    type
      JCertificateFactory = interface;
     
      JCertificateFactoryClass = interface(IJavaClass)
        ['{3761CC34-CA45-4129-B30B-CDB493EC36A9}']
        {class functions}
        function getInstance(type_: JString): JCertificateFactory; cdecl;  // X.509
      end;
     
      [JavaSignature('java/security/cert/CertificateFactory')]
      JCertificateFactory = interface(JObject)
        ['{80947439-E9FB-4E38-AF04-C8AA7D68747A}']
        function generateCertificate(InputStream: JInputStream): JCertificate; cdecl;
        function generateCertificates(InputStream: JInputStream): JCollection; cdecl;
      end;
     
      TJCertificateFactory = class(TJavaGenericImport<JCertificateFactoryClass, JCertificateFactory>) end;
    tu déclares donc un J<MaClassJava> comme interface JObject ayant un attribut "JavaSignature" qui donne le nom de la classe Java. Le GUID est quelconque, et tu y colles les fonctions qui t'intéressent.
    tu déclares un FactoryClass pour les fonctions de classe (static en Java) comme ici le constructor getInstance()
    il ne reste plus qu'à déclare le wrapper de type JavaGenericImport.

    et à l'usage ça donne ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    procedure loadCA(const aCA: TBytes; keyStore: JKeyStore);
    var
      buf: TJavaArray<System.Byte>;
      stm: JByteArrayInputStream;
      cf : JCertificateFactory;
      col: JCollection;
      iter: JIterator;
      i: Integer;
      ca : JCertificate;
    begin
      buf := TJavaArray<System.Byte>.Create(Length(aCA));
      Move(aCA[0], buf.Data^, Length(aCA));
      stm := TJByteArrayInputStream.JavaClass.init(buf);
      cf := TJCertificateFactory.JavaClass.getInstance(StringToJString('X.509'));
      col := cf.generateCertificates(stm);
      iter := col.iterator;
      i := 1;
      while iter.hasNext do
      begin
        ca := TJCertificate.wrap(iter.next);
        keyStore.setCertificateEntry(StringToJString(IntToStr(i)), ca);
        Inc(i);
      end;
      stm.close;
      buf.Free;
    end;
    ça demande donc un peu de pratique mais c'est assez abordable malgré tout...attention, le String doivent passer par StringToJString
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    merci @paul

    depuis ton message, je lis et me documente sur l'approche JNI
    je regarde la vidéo de Brian Long :
    "How you can access the Android Java classes via the Java bridge, looking at classes that have Delphi representations and, perhaps more importantly, those which do not."

    sinon j'ai un peu du mal à faire la différence conceptuelle entre tes 2 propositions,
    c'est soit d'accéder aux fonctions java Android via le JavaBridge
    soit d'accéder directement à des fonctions bas niveau de l'OS Linux ?

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    8 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 8 761
    Points : 28 517
    Points
    28 517
    Par défaut
    Citation Envoyé par MatMagik Voir le message
    merci @paul

    depuis ton message, je lis et me documente sur l'approche JNI
    je regarde la vidéo de Brian Long :
    "How you can access the Android Java classes via the Java bridge, looking at classes that have Delphi representations and, perhaps more importantly, those which do not."

    sinon j'ai un peu du mal à faire la différence conceptuelle entre tes 2 propositions,
    c'est soit d'accéder aux fonctions java Android via le JavaBridge
    soit d'accéder directement à des fonctions bas niveau de l'OS Linux ?
    oui c'est ça...par exemple pour les sockets, tu peux utiliser l'API Socket de l'OS ou invoquer les classe Java de haut niveau.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    j'avance alors !

    j'ai trouvé la documentation me permettant d'identifier les fonctions natives android pour un port série ?!
    https://android.googlesource.com/pla...SerialPort.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    android_hardware_SerialPort_open(JNIEnv *env, jobject thiz, jobject fileDescriptor, jint speed)
    android_hardware_SerialPort_close(JNIEnv *env, jobject thiz)
    android_hardware_SerialPort_read_array(JNIEnv *env, jobject thiz, jbyteArray buffer, jint length)
    android_hardware_SerialPort_read_direct(JNIEnv *env, jobject thiz, jobject buffer, jint length)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    static const JNINativeMethod method_table[] = {
        {"native_open",             "(Ljava/io/FileDescriptor;I)V",
                                            (void *)android_hardware_SerialPort_open},
        {"native_close",            "()V",  (void *)android_hardware_SerialPort_close},
        {"native_read_array",       "([BI)I",
                                            (void *)android_hardware_SerialPort_read_array},
        {"native_read_direct",      "(Ljava/nio/ByteBuffer;I)I",
                                            (void *)android_hardware_SerialPort_read_direct},
        {"native_write_array",      "([BI)V",
                                            (void *)android_hardware_SerialPort_write_array},
        {"native_write_direct",     "(Ljava/nio/ByteBuffer;I)V",
                                            (void *)android_hardware_SerialPort_write_direct},
        {"native_send_break",       "()V",  (void *)android_hardware_SerialPort_send_break},
    };

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    8 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : novembre 2002
    Messages : 8 761
    Points : 28 517
    Points
    28 517
    Par défaut
    oui voilà, tu as là l'appel JNI dans l'autre sens de Java vers l'OS

    donc si tu invoques la classe Java depuis Delphi, elle va elle même appeler les fonctions natives que tu aurais pu invoquer directement puisque Delphi est compilé en natif ARM et non en Dalvik

    et quand tu recherches tcsetattr et Delphi, tu tombes sur Kylix Logique, on retombe sur du Linux
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    je galère un peu sur la conception et la détermination des fonctions nécessaires à importer...
    Avant d'ouvrir mon port série (mon précédent post), il faut gérer le périphérique : j'ai trouvé ces fonctions device et accessory

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function getAccessoryList : TJavaArray<JUsbAccessory>; cdecl;               // ()[Landroid/hardware/usb/UsbAccessory
    function getDeviceList : JHashMap; cdecl;                                   // ()Ljava/util/HashMap
    function hasPermission(accessory : JUsbAccessory) : boolean; cdecl; overload;// (Landroid/hardware/usb/UsbAccessory;)
    function hasPermission(device : JUsbDevice) : boolean; cdecl; overload;     // (Landroid/hardware/usb/UsbDevice;)
    function openAccessory(accessory : JUsbAccessory) : JParcelFileDescriptor; cdecl;// (Landroid/hardware/usb/UsbAccessory;)Landroid/os/ParcelFileDescriptor;
    function openDevice(device : JUsbDevice) : JUsbDeviceConnection; cdecl;     // (Landroid/hardware/usb/UsbDevice;)Landroid/hardware/usb/UsbDeviceConnection;
    procedure requestPermission(accessory : JUsbAccessory; pi : JPendingIntent) ; cdecl; overload;// (Landroid/hardware/usb/UsbAccessory;Landroid/app/PendingIntent;)
    procedure requestPermission(device : JUsbDevice; pi : JPendingIntent) ; cdecl; overload;// (Landroid/hardware/usb/UsbDevice;Landroid/app/PendingIntent;)
    mais je ne trouve pas d'infos sur la différence entre device et accessory : lequel dois-je utiliser ?
    sachant que l'Android est en mode Host car lorsque le câble USB OTG est branché sur l'Android, il fait basculer l'Android en mode Host (en mettant à la masse sa pin ID).
    merci

  9. #9
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Host/Accessory ? Device/Accessory ?
    j'ai trouvé une info explicite ici
    https://stuff.mit.edu/afs/sipb/proje...usb/index.html

    Nom : usb-host-accessory.png
Affichages : 92
Taille : 46,0 Ko

    Dans le cas d'un smartphone ANDROID et d'un périphérique branché en OTG : c'est le Host Mode.
    Donc si je veux détecter et identifier un périphérique, je dois utiliser les fonctions typées "device" et pas "accessory".
    J'ai bon ?

  10. #10
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Ok donc pour la structure du programme, j'envisage une machine d'état :

    INITIALISATION
    - rafraîchir la liste des devices connectés
    condition : si au moins un device est connecté alors passer à l'état "liaison"

    LIAISON
    - afficher la liste des devices connectés
    - sélectionner un device dans la liste
    condition : si le device attendu n'est pas présent, repasser à l'état "initialisation" par un bouton "rafraîchir"
    condition : lorsqu'un device est sélectionné, passer à l'état "connecté"

    CONNECTÉ
    - ouvrir le port série UART (Universal Asynchronous Receiver Transmitter) avec les paramètres nécessaires : baud rate, bit de start et de stop, parité...
    condition : passer à l'état "communication"

    COMMUNICATION
    - envoyer message
    - recevoir message et l'afficher
    condition : repasser à l'état "initialisation" par un bouton "terminer"

    Cela conviendrait-il ? Avez-vous des suggestions ?
    merci :-)

  11. #11
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    j'ai trouvé des informations intéressantes ici : https://sourceforge.net/p/libusb-win...Documentation/

    je rajoute donc une précision dans le bloc INITIALISATION
    - lister les bus USB avant de lister les devices
    - puis rafraîchir la liste des devices connectés


    Je peux aussi appliquer un filtre sur le type de device (imprimante : DeviceClass = 7) pour alléger la liste
    ou alors je peux compléter l'affichage de la liste avec la classe pour faciliter le choix par l'utilisateur !

  12. #12
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2005
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2005
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    d'autres infos intéressantes ici sur l'énumération :

    énumération USB et OTG (en français)
    https://learn.microsoft.com/fr-fr/wi...re/usb-support

    la doc FTDI sur l'énumération USB
    https://ftdichip.com/wp-content/uplo...numeration.pdf (en anglais)

    Detecting a Device has been Connected
    A USB interface consists of 4 wires. Power, Ground, Data Plus (USBDP) and Data Minus (USBDM). A USB
    host port with no devices connected uses 15kohm resistors to connect both USB DP and USB DM to GND.
    When a USB device (sometimes referred to as a slave) is plugged into a USB host there is a change on
    these USB data lines. It is this change that the USB host uses to detect a device has been connected.
    This change is also used to identify the speed of device attached
    A low speed USB device (1.5Mbps) uses a 1k5 pull-up resistor to VCC on the USB DM signal line.
    A full speed USB device (12Mbps) uses a 1k5 pull-up resistor to VCC on the USB DP signal line

    Loading the Driver
    When the USB device has been fully identified by the USB host, then the host PC needs a driver to
    control the USB device. Matching the USB device to the driver is usually done by matching up the VID
    and PID.
    With an FTDI USB device, the VID/PID are stored in the driver .inf files (Windows OS). If the VID/PID
    match, the host PC will know which driver to install for the specific device. (see AN_107 Advanced Driver
    Options for more information on driver inf files).
    After the initial installation the settings are saved in the PC registry so that on subsequent plug-ins of the
    USB device, the driver is automatically loaded.
    When the driver has been loaded, then the USB device is available for applications to access.

Discussions similaires

  1. [Embarqué] Communication avec le port série vers Arduino
    Par YannGTT dans le forum Plateformes
    Réponses: 0
    Dernier message: 05/04/2020, 05h45
  2. Réponses: 3
    Dernier message: 06/06/2016, 13h27
  3. [OL-2010] Help -> Bug pour envoi mail via vba access vers outlook
    Par Razielh dans le forum VBA Outlook
    Réponses: 2
    Dernier message: 03/01/2016, 12h50
  4. Réponses: 1
    Dernier message: 22/10/2010, 11h09
  5. Réponses: 2
    Dernier message: 18/08/2008, 18h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo