"Quelles marinas?" ou nous contrôlons le contrôleur via Bluetooth en utilisant une application mobile sur Xamarin (Android)

Dans un article précédent , j'ai promis de parler de la façon de connecter CANNY 3 Tiny en utilisant UART à Bluetooth. Et comme vous ne vous promenez pas vraiment pendant ces vacances de mai, il a été décidé de passer du temps avec des avantages et de tenir la promesse. Mais juste pour connecter le contrôleur à l'adaptateur Bluetooth HC-06, ce serait trop facile pour Habr.

Par conséquent, nous ne nous contenterons pas de tout connecter, mais nous écrirons également une application Android primitive pour notre circuit en utilisant C # et Xamarin.

Si vous aimez surveiller les "fins de course" et les interrupteurs à lames, comme je l'adore, vous êtes les bienvenus sous cat.



Voici ce dont nous allons parler aujourd'hui:

Partie I: Introduction
Partie II: Connexion du circuit et du programme pour CANNY 3 minuscule
Partie III: Nous écrivons une application sur Xamarin pour Android
Partie IV: Conclusion

Partie I: Introduction


Je vais commencer par le bon, sauf pour les insertions du code du programme en C #, alors cette fois l'article sera relativement petit, car nous avons examiné les techniques de base de travailler avec le contrôleur plus tôt. Afin de ne pas répéter encore une fois, voici une liste d'articles dans lesquels nous avons déjà examiné les méthodes de base de travail avec le contrôleur CANNY:

  1. "Un, deux, trois - brûlez le sapin de Noël!" ou mon premier aperçu du petit contrôleur CANNY 3 - dans cet article, nous avons analysé ce qu'est le contrôleur, ainsi que les bases du travail dans l'environnement de développement CannyLab.
  2. `` La destination a beaucoup de formes ... '' ou nous automatisons le contrôle d'une lampe à l'aide de CANNY 3 Tiny et d'une photorésistance - dans cet article, nous avons examiné le travail avec le port COM virtuel USB, la connexion des capteurs à l'ADC, ainsi que le PWM haute fréquence aux sorties du contrôleur.
  3. « ...» (CANNY Arduino) Raspberry PI — UART, .

Pour préparer cet article, j'ai utilisé le matériel suivant: petit contrôleur CANNY 3, adaptateur Bluetooth HC-06, interrupteur de fin de course (module Trema), interrupteur à lames, vieux écouteurs filaires, planche à pain, fils, crocodiles.

Nous allons construire un système qui, à l'aide d'une application mobile, surveille l'état de deux capteurs et, si nécessaire, peut déclencher manuellement une alarme.

Tout ce qui sera présenté dans cet article est inventé uniquement à des fins éducatives et de démonstration. Je voulais juste montrer quelques astuces de travail avec le contrôleur, ainsi que pour les morceaux de fer achetés à un moment donné pour déterminer leur valeur.

Malgré la nature du problème en cours de résolution, loin de la réalité, nous imaginerons que nous réalisons un système de surveillance derrière la porte coulissante du compartiment. Quand il commence à bouger, le commutateur à lames fonctionnera et à la fin du chemin, il donnera un signal à la remorque. Si nous devons attirer l'attention, par exemple, pour que la porte soit refermée, nous émettrons un signal "grinçant" par le haut-parleur. C'est vrai, je n'ai pas de haut-parleur, mais il y a de vieux écouteurs.



Eh bien et, comme toujours, une note. Je ne recommande pas fortement d'utiliser les matériaux de cet article comme la vérité ultime. J'ai fait beaucoup de choses pour la première fois moi-même, elles peuvent certainement être mieux faites.


Partie II: Connexion du circuit et du programme pour CANNY 3 Tiny


Pour commencer, afin de ne pas offenser qui que ce soit en matière de droit d'auteur, j'ai emprunté au forum , mais moi-même je les ai adaptés pour l' idée de connecter le contrôleur au HC-06, en le contrôlant via l'application «Serial bluetooth terminal» et quelques astuces lors du développement du schéma ta tâche.

Le schéma de connexion est le suivant: l'



interrupteur de fin de course et l'interrupteur à lames sont connectés aux bornes du contrôleur n ° 6 et n ° 5, les écouteurs à la borne n ° 4 (il a un PWM RF), UART RX est la borne n ° 1, UART TX est la borne n ° 2, la borne n ° 3 Il est utilisé pour fournir «+ 5V», la sortie «-» - pour la communication avec la «masse».

Voici à quoi cela ressemble dans l'assemblage:



J'ai développé le diagramme (programme) pour CANNY 3 tiny dans CannyLab version 1.42, peut-être dans d'autres versions de l'environnement de développement et avec d'autres contrôleurs, il sera nécessaire d'apporter des modifications au diagramme.

Voici ce qui s'est passé: les



blocs associés à la configuration du contrôleur et à l'envoi de messages via UART ont été démontés dans un article précédent .

Examinons plus en détail les deux restants.

Le bloc « Recevoir le message UART » est chargé d'allumer la sirène (casque). En principe, il est nécessaire d'analyser un exemple de réception d'un message via UART.

Tout d'abord, nous vérifions si les données reçues sont dans l'UART, si c'est le cas, puis nous en envoyons une à l'entrée D-trigger "E", auquel cas le déclencheur copie la valeur de l'entrée "D" dans laquelle nous écrirons les deux premiers caractères du message reçu via UART. Je ne voulais pas tout compliquer, nous allons donc utiliser un schéma simple plus loin. Nous supposons que selon UART, n'importe quel nombre de 00 à 99 nous parviendra, nous convertirons ce nombre d'une forme symbolique en une forme numérique (je recommande de lire comment fonctionne le bloc convertisseur; j'avais une petite «prise» avec lui). En outre, toute valeur "> 0" à l'entrée du détecteur de front montant provoque un signal unique, qui active la sortie 5 pendant 5 secondes, fonctionnant en mode RF PWM.

Vous pouvez jouer dans les réglages avec la période de remplissage du RF PWM, le son dans le casque en dépendra.

Passons au bloc"Formation du message . " Sa mise en œuvre à première vue peut paraître inhabituelle. Cela s'explique par le fait que je n'ai pas vraiment compris comment travailler avec le programme de terminal Bluetooth série et avec le même protocole Bluetooth dans Xamarin.

Je vais courir un peu plus loin et dire que je n'ai pas appris à recevoir les messages envoyés par le contrôleur sur mon smartphone. Si tout était évident avec l'UART filaire dans le dernier article, alors avec Bluetooth, en pratique, au lieu du message envoyé, seule sa partie peut être lue et la signification de la commande transmise est violée.

J'ai décidé que la solution la plus simple est de transmettre un seul numéro, ce qui garantit d'atteindre le destinataire sans perte.

Dans notre cas, nous surveillons l'état discret du commutateur à lames et du fin de course. Autrement dit, nous n'avons que 4 combinaisons possibles: l'interrupteur à lames et l'interrupteur de fin de course sont désactivés, un seul est activé, les deux sont activés.

Étant donné que l'interrupteur à lames et l'interrupteur de fin de course donnent un signal discret (0/1), vous devez en quelque sorte les distinguer. Pour ce faire, nous multiplions la valeur du signal reed par 2. Maintenant, il s'avère que la somme des signaux nous donnera des valeurs de 0 à 3.

Nous allons maintenant analyser une option non évidente avec cinquante ajoutées à cette valeur. Le fait est que CannyLab transfère quelques caractères à UART, c'est-à-dire au lieu de 3, disons 03, mais comme je l'ai dit, il y a un risque de perdre certaines informations. Par exemple, à partir de la valeur 01, le programme sur le smartphone ne peut lire que le premier "0", et ce sera déjà une erreur.

Il serait possible de se confondre et de transformer les données, en remplaçant, par exemple, le caractère «D1» du registre par une lettre ou un espace, mais j'ai décidé de le rendre plus facile. J'ai converti la valeur 01 en 51 (02 en 52, etc.). Les cinq ne portent pas de signal et je l'ai coupé au niveau du programme pour un smartphone. Ainsi, nous garantissons toujours que la partie utile du message demeure.

Nous chargeons le programme dans le contrôleur, cliquez sur «Exécuter», si tout fonctionne comme prévu, le HC-06 clignotera périodiquement une LED rouge.

Ensuite, nous couplons le smartphone avec l'adaptateur. Vous pouvez maintenant vérifier les performances dans l'application «Terminal Bluetooth série» ou tout autre avec des fonctionnalités similaires.

Notez l'adresse de l'adaptateur Bluetooth, elle nous sera utile dans le chapitre suivant.



Comme vous pouvez le voir, les données arrivent, selon l'état des capteurs, et si vous envoyez "11", alors un méchant grincement se fait entendre dans les écouteurs. Nous pourrions nous arrêter ici, mais esquissons une application primitive.

Le programme pour le contrôleur et le code source du programme pour le smartphone peuvent être téléchargés depuis GitHub.Je

voudrais noter que vous n'avez pas à implémenter tout dans le matériel spécifiquement sur les contrôleurs CANNY, vous pouvez écrire un programme pour Arduino ou un autre contrôleur que vous aimez. Initialement, j'avais moi-même prévu d'écrire une version supplémentaire du croquis pour Arduino, mais depuis que j'ai tué presque toutes les vacances de mai, je n'avais tout simplement pas la force de connecter CANNY et l'application smartphone.

Partie III: Écriture d'une application Android Xamarin


Je sais que Xamarin, pour le moins, n'est pas la solution la plus populaire pour le développement mobile. Et vous avez peut-être déjà une question: "Pourquoi l'ai-je choisie?" . Je voudrais lui répondre avec des paroles de la chanson du même nom de Psoya Korolenko:



Honnêtement, il n'y a pas de raisons objectives. Il y a quelques années à peine, j'ai appris les bases du C # et tout le monde voulait voir ce qu'est Xamarin. Et maintenant, en raison de "l'auto-isolement", les mains ont finalement atteint.

Eh bien, permettez-moi de vous rappeler à nouveau. C'est ma première rencontre avec Xamarin et c'est ma première application Android. Ne copiez pas aveuglément mon code de courbe, si soudain vous pouvez trouver une plus belle solution, utilisez-la.

Lors du développement de mon programme, je me suis appuyé sur ce matériel. L'article n'est pas particulièrement mâché, et même en espagnol, j'ai donc jugé approprié de partager avec vous ma variation sur ce sujet.

J'ai créé le programme dans l'édition communautaire de Visual studio 2019.

Tout d'abord, créez un nouveau projet Android vide (Xamarin), comme dans l'image.



J'ai apporté des modifications à seulement trois fichiers, ils peuvent être affichés entièrement sur GitHub , et ici nous analyserons uniquement les parties importantes: les autorisations

AndroidManifest.xml

2 sont ajoutées au modèle standard:

  <uses-permission android:name="android.permission.BLUETOOTH"/>
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

activity_main.xml Le
conteneur par défaut (RelativeLayout) a été supprimé. Au lieu de cela, le conteneur LinearLayout a été ajouté simplement parce qu'il est plus simple. Dans ce conteneur, tous les éléments sont alignés verticalement, s'étendant sur toute la largeur de l'écran.

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:minWidth="25px"
    android:minHeight="25px"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/linearLayout1">
    <TextView
        android:text="Reed switch status - undefined"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/rSwitch"
        android:textSize="12pt" />
    <TextView
        android:text="End sensor status - undefined"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/EndSensor"
        android:textSize="12pt" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/startSiren"
        android:text="Send signal to siren" />
    <Switch
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/bltSwitch"
        android:checked="false"
        android:showText="true"
        android:text="Connect bluetooth" />
    <TextView
        android:text="status"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/status" />
</LinearLayout>

Quiconque connaît un peu la mise en page HTML ou XML peut facilement comprendre la structure de l'interface utilisateur. Nous avons trois champs de texte en lecture seule (TextView), un commutateur (Switch), qui fonctionne essentiellement comme une case à cocher et un bouton ordinaire (Button). Les éléments peuvent être placés sur le formulaire par glisser-déposer depuis le constructeur, et dans la fenêtre des propriétés ou dans le code pour les définir des ID plus pratiques, des talons de texte et d'autres paramètres.

Reste à décrire la logique du programme.

MainActivity.cs

Ci-dessous, sous le spoiler, le code entier est pour plus de commodité

Code MainActivity.cs complet
// based on http://alejandroruizvarela.blogspot.com/2014/01/bluetooth-arduino-xamarinandroid.html
// for this article https://habr.com/ru/post/500454/


// based on http://alejandroruizvarela.blogspot.com/2014/01/bluetooth-arduino-xamarinandroid.html
// for this article https://habr.com/ru/post/500454/


using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using System.Linq;
using System;
using System.IO;
using Java.Util;
using Android.Bluetooth;
using System.Threading.Tasks;

namespace _6.Canny_Xanarin_Bluetooth_Android
{
    [Activity(Label = "Control Canny 3 tiny via bluetooth", Theme = "@style/AppTheme", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {

        Button startSiren;
        TextView rSwitch;
        TextView EndSensor;
        Switch bltSwitch;
        TextView status;
        private Java.Lang.String dataToSend;
        private BluetoothAdapter mBluetoothAdapter = null;
        private BluetoothSocket btSocket = null;
        private Stream outStream = null;
        // don't forget change addres to your device:
        private static string address = "98:D3:91:F9:6C:F6";
        // MY_UUID can be saved as is
        private static UUID MY_UUID = UUID.FromString("00001101-0000-1000-8000-00805F9B34FB");
        private Stream inStream = null;


        protected override void OnCreate(Bundle savedInstanceState)
        {

            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);

            startSiren = FindViewById<Button>(Resource.Id.startSiren);
            rSwitch = FindViewById<TextView>(Resource.Id.rSwitch);
            EndSensor = FindViewById<TextView>(Resource.Id.EndSensor);
            status = FindViewById<TextView>(Resource.Id.status);
            bltSwitch = FindViewById<Switch>(Resource.Id.bltSwitch);


            startSiren.Click += startSiren_ClickOnButtonClicked;
            bltSwitch.CheckedChange += bltSwitch_HandleCheckedChange;
            CheckBt();
        }

        private void CheckBt()
        {
            mBluetoothAdapter = BluetoothAdapter.DefaultAdapter;

            if (!mBluetoothAdapter.Enable())
            {
                Toast.MakeText(this, "Bluetooth Off",
                    ToastLength.Short).Show();
            }

            if (mBluetoothAdapter == null)
            {
                Toast.MakeText(this,
                    "Bluetooth does not exist or is busy", ToastLength.Short)
                    .Show();
            }
        }

        void startSiren_ClickOnButtonClicked(object sender, EventArgs e)
        {
            if (bltSwitch.Checked)
            {
                try
                {
                    dataToSend = new Java.Lang.String("11");
                    writeData(dataToSend);
                    System.Console.WriteLine("Send signal to siren");
                }
                catch (System.Exception execept)
                {
                    System.Console.WriteLine("Error when send data" + execept.Message);
                }

            }
            else status.Text = "bluetooth not connected";
        }
        void bltSwitch_HandleCheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
        {
            if (e.IsChecked)
            {
                Connect();
            }
            else
            {
                status.Text = "bluetooth not connected";
                if (btSocket.IsConnected)
                {
                    try
                    {
                        btSocket.Close();
                        System.Console.WriteLine("Connection closed");
                    }
                    catch (System.Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }
        }

        public void Connect()
        {
            BluetoothDevice device = mBluetoothAdapter.GetRemoteDevice(address);
            System.Console.WriteLine("Connection in progress" + device);
            mBluetoothAdapter.CancelDiscovery();
            try
            {
                btSocket = device.CreateRfcommSocketToServiceRecord(MY_UUID);
                btSocket.Connect();
                System.Console.WriteLine("Correct Connection");
                status.Text = "Correct Connection to bluetooth";
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
                try
                {
                    btSocket.Close();
                    System.Console.WriteLine("Connection closed");
                }
                catch (System.Exception)
                {
                    System.Console.WriteLine("Impossible to connect");
                    status.Text = "Impossible to connect";
                }
                System.Console.WriteLine("Socket Created");
  
            }
            beginListenForData();

        }

        public void beginListenForData()
        {
            try
            {
                inStream = btSocket.InputStream;
            }
            catch (System.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            Task.Factory.StartNew(() => {
                byte[] buffer = new byte[1024];
                int bytes;
                
                while (true)
                {

                    try
                    {
                        bytes = inStream.Read(buffer, 0, 1024);
                        System.Console.WriteLine("bytes " + bytes.ToString());
                        if (bytes > 0)
                        {
                            
                            RunOnUiThread(() => {
                                string valor = System.Text.Encoding.ASCII.GetString(buffer).Replace("5",String.Empty);
                                // transform string for deleate all symbols except 1-4(command from canny).
                                string command = new string(valor.Where(char.IsDigit).ToArray());

                                if (command.Length > 0)
                                {
                                     status.Text="data successfully readed";
                                    System.Console.WriteLine("command  " + command);
                                    switch (Int32.Parse(command))
                                    {
                                        case 0:
                                            rSwitch.Text = "reed switch - disconnected ";
                                            EndSensor.Text = "end sensor - not pressed ";
                                            break;
                                        case 1:
                                            rSwitch.Text = "reed switch - disconnected ";
                                            EndSensor.Text = "end sensor - pressed ";
                                            break;
                                        case 2:
                                            rSwitch.Text = "reed switch - connected ";
                                            EndSensor.Text = "end sensor - not pressed ";
                                            break;
                                        case 3:
                                            rSwitch.Text = "reed switch - connected ";
                                            EndSensor.Text = "end sensor - pressed ";
                                        break;
                                    }
                                }
                            });
                        }
                    }
                    catch (Java.IO.IOException)
                    {
                        RunOnUiThread(() => {
                            EndSensor.Text = "End sensor status - undefined";
                            rSwitch.Text = "Reed switch status - undefined ";
                        });
                        break;
                    }
                }
            });
        }

        private void writeData(Java.Lang.String data)
        {
            try
            {
                outStream = btSocket.OutputStream;
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine("Error with OutputStream when write to Serial port" + e.Message);
            }

            Java.Lang.String message = data;

            byte[] msgBuffer = message.GetBytes();

            try
            {
                outStream.Write(msgBuffer, 0, msgBuffer.Length);
                System.Console.WriteLine("Message sent");
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine("Error with  when write message to Serial port" + e.Message);
                status.Text = "Error with  when write message to Serial port";
            }
        }


    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
 }


Maintenant en parties.

Blocs avec connexion d'espaces de noms, déclaration de classe, etc. Je vais manquer.


Nous créons des variables avec lesquelles nous lierons plus tard les éléments de l'interface utilisateur:

   Button startSiren;
   TextView rSwitch;
   TextView EndSensor;
   Switch bltSwitch;
   TextView status;

Vient ensuite le code de l'exemple sur lequel je me suis appuyé. Variables (champs) nécessaires au fonctionnement de certaines méthodes.

  private Java.Lang.String dataToSend;
        private BluetoothAdapter mBluetoothAdapter = null;
        private BluetoothSocket btSocket = null;
        private Stream outStream = null;
        // don't forget change addres to your device:
        private static string address = "98:D3:91:F9:6C:F6";
        // MY_UUID can be saved as is
        private static UUID MY_UUID = UUID.FromString("00001101-0000-1000-8000-00805F9B34FB");
        private Stream inStream = null;

Il est important pour nous ici de saisir l'adresse de votre module HC-06 dans le champ d'adresse.

Comme il s'agit de ma première expérience de développement pour smartphones, y compris en travaillant avec Xamarin, j'ai décidé de ne rien compliquer, donc l'adresse de l'appareil, comme dans l'exemple d'origine, est codée en dur. Si vous le souhaitez, vous pouvez voir cet article , il semble qu'il y ait une énumération des appareils Bluetooth disponibles.

Passez.


        protected override void OnCreate(Bundle savedInstanceState)
        {

            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);

            startSiren = FindViewById<Button>(Resource.Id.startSiren);
            rSwitch = FindViewById<TextView>(Resource.Id.rSwitch);
            EndSensor = FindViewById<TextView>(Resource.Id.EndSensor);
            status = FindViewById<TextView>(Resource.Id.status);
            bltSwitch = FindViewById<Switch>(Resource.Id.bltSwitch);


            startSiren.Click += startSiren_ClickOnButtonClicked;
            bltSwitch.CheckedChange += bltSwitch_HandleCheckedChange;
            CheckBt();
        }

Cette méthode est créée automatiquement, notre tâche consiste à associer des objets d'interface utilisateur avec les champs de la classe, et également attacher des gestionnaires pour les réactions aux événements ( startSiren.Click bltSwitch.CheckedChange).

Vérification de la connexion via Bluetooth:


        private void CheckBt()
        {
            mBluetoothAdapter = BluetoothAdapter.DefaultAdapter;

            if (!mBluetoothAdapter.Enable())
            {
                Toast.MakeText(this, "Bluetooth Off",
                    ToastLength.Short).Show();
            }

            if (mBluetoothAdapter == null)
            {
                Toast.MakeText(this,
                    "Bluetooth does not exist or is busy", ToastLength.Short)
                    .Show();
            }
        }

Allumez la sirène. Essentiellement, il suffit d'envoyer les caractères «11» au contrôleur:


   void startSiren_ClickOnButtonClicked(object sender, EventArgs e)
        {
            if (bltSwitch.Checked)
            {
                try
                {
                    dataToSend = new Java.Lang.String("11");
                    writeData(dataToSend);
                    System.Console.WriteLine("Send signal to siren");
                }
                catch (System.Exception execept)
                {
                    System.Console.WriteLine("Error when send data" + execept.Message);
                }

            }
            else status.Text = "bluetooth not connected";
        }

Vérification de l'état du commutateur (s'il est déplacé vers la droite, cela signifie qu'il est activé):

   void bltSwitch_HandleCheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
        {
            if (e.IsChecked)
            {
                Connect();
            }
            else
            {
                if (btSocket.IsConnected)
                {
                    try
                    {
                        btSocket.Close();
                        System.Console.WriteLine("Connection closed");
                    }
                    catch (System.Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }
        }

Lorsque vous allumez, nous commençons la connexion avec Bluetooth.

L'implémentation de la connexion elle-même:

   public void Connect()
        {
            BluetoothDevice device = mBluetoothAdapter.GetRemoteDevice(address);
            System.Console.WriteLine("Connection in progress" + device);
            mBluetoothAdapter.CancelDiscovery();
            try
            {
                btSocket = device.CreateRfcommSocketToServiceRecord(MY_UUID);
                btSocket.Connect();
                System.Console.WriteLine("Correct Connection");
                status.Text = "Correct Connection to bluetooth";
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
                try
                {
                    btSocket.Close();
                    System.Console.WriteLine("Connection closed");
                }
                catch (System.Exception)
                {
                    System.Console.WriteLine("Impossible to connect");
                    status.Text = "Impossible to connect";
                }
                System.Console.WriteLine("Socket Created");
  
            }
            beginListenForData();

        }

Et voici l'une des méthodes les plus importantes - lire directement les données:


    public void beginListenForData()
        {
            try
            {
                inStream = btSocket.InputStream;
            }
            catch (System.IO.IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
            Task.Factory.StartNew(() => {
                byte[] buffer = new byte[1024];
                int bytes;
                
                while (true)
                {

                    try
                    {
                        bytes = inStream.Read(buffer, 0, 1024);
                        System.Console.WriteLine("bytes " + bytes.ToString());
                        if (bytes > 0)
                        {
                            
                            RunOnUiThread(() => {
                                string valor = System.Text.Encoding.ASCII.GetString(buffer).Replace("5",String.Empty);
                                // transform string for deleate all symbols except 1-4(command from canny).
                                string command = new string(valor.Where(char.IsDigit).ToArray());

                                if (command.Length > 0)
                                {
                                     status.Text="data successfully readed";
                                    System.Console.WriteLine("command  " + command);
                                    switch (Int32.Parse(command))
                                    {
                                        case 0:
                                            rSwitch.Text = "reed switch - disconnected ";
                                            EndSensor.Text = "end sensor - not pressed ";
                                            break;
                                        case 1:
                                            rSwitch.Text = "reed switch - disconnected ";
                                            EndSensor.Text = "end sensor - pressed ";
                                            break;
                                        case 2:
                                            rSwitch.Text = "reed switch - connected ";
                                            EndSensor.Text = "end sensor - not pressed ";
                                            break;
                                        case 3:
                                            rSwitch.Text = "reed switch - connected ";
                                            EndSensor.Text = "end sensor - pressed ";
                                        break;
                                    }
                                }
                            });
                        }
                    }
                    catch (Java.IO.IOException)
                    {
                        RunOnUiThread(() => {
                            EndSensor.Text = "End sensor status - undefined";
                            rSwitch.Text = "Reed switch status - undefined ";
                        });
                        break;
                    }
                }
            });
        }

J'ai laissé de nombreux éléments de la méthode comme dans l'exemple, si je comprends bien, au début, une connexion au flux de données est créée, s'il y a quelque chose dans le tampon avec les données lues, puis il est lu dans une variable valor. De plus, comme je l'ai promis, nous supprimons simplement le chiffre «5».

Ensuite, nous supprimons tous les caractères à l'exception des chiffres du message lu. string command = new string(valor.Where(char.IsDigit).ToArray());

Eh bien, après cela, tout est simple, selon le nombre qui nous est parvenu, nous affichons tel ou tel état dans l'interface utilisateur.

Je n'ai pas fondamentalement changé ces deux méthodes:

  private void writeData(Java.Lang.String data)
        {
            try
            {
                outStream = btSocket.OutputStream;
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine("Error with OutputStream when write to Serial port" + e.Message);
            }

            Java.Lang.String message = data;

            byte[] msgBuffer = message.GetBytes();

            try
            {
                outStream.Write(msgBuffer, 0, msgBuffer.Length);
                System.Console.WriteLine("Message sent");
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine("Error with  when write message to Serial port" + e.Message);
                status.Text = "Error with  when write message to Serial port";
            }
        }


    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
 }

Si je comprends bien, ce bloc de code implémente l'envoi d'un message et un gestionnaire d'événements pour surcharger l'autorisation d'accès à Bluetooth.

Eh bien, il ne vous reste plus qu'à configurer une connexion smartphone pour déboguer l'application .

Curieusement, mais cela fonctionne:



Partie IV: Conclusion


Voici comment le programme fonctionne en nature:



C'était ma première expérience dans le développement d'applications pour un smartphone sur Android.

Je voudrais noter que VS 2019 et Xamarin sur mon ancien ordinateur fonctionnent très lentement.

Lors du premier montage du projet, j'ai vraiment réussi à manger ces petits pains français moelleux et à boire du thé. De plus, l'application elle-même s'est avérée franchement misérable, l'interrupteur marche / arrêt ne fonctionne pas très facilement, mais d'un autre côté, étant donné que je ne suis que peu familier avec les techniques de développement de base pour .NET, ainsi que le fait que je ne suis pas du tout programmeur, je pourrais même sans passer par un seul didacticiel ou une seule leçon, décrivez votre première application en une journée. Par conséquent, le seuil d'entrée pour créer une application élémentaire est assez bas.

Si je comprends bien, les contrôleurs CANNY peuvent être utilisés lors du réglage des voitures, en particulier les voitures domestiques, de sorte qu'il est tout à fait possible de créer une sorte de "fonctionnalité" et d'y écrire une application pour smartphone. La principale chose à retenir est que lorsqu'elles sont alimentées à partir du réseau de bord du véhicule, les sorties du contrôleur auront également la même tension que l'entrée (par exemple, 12 V au lieu de 5 V). N'oubliez pas de protéger l'adaptateur Bluetooth afin qu'il ne tombe pas en panne par inadvertance.

L'article s'est avéré très laborieux pour moi, j'espère que tout n'a pas été vain et que vous l'aimerez.

All Articles