"Quais marinas?" ou controlamos o controlador via bluetooth usando um aplicativo móvel no Xamarin (Android)

Em um artigo anterior , prometi falar sobre como conectar o CANNY 3 tiny usando o UART ao bluetooth. E como você não pode andar por aí especialmente em maio, foi decidido gastar um tempo com benefícios e ainda manter a promessa. Mas apenas para conectar o controlador ao adaptador Bluetooth HC-06, seria muito fácil para Habr.

Portanto, não apenas conectamos tudo, mas também escrevemos para o nosso esquema o aplicativo Android mais primitivo usando C # e Xamarin.

Se você gosta de monitorar os "interruptores de limite" e os interruptores de palheta, como eu amo, você é bem-vindo sob cat.



Aqui está o que falaremos hoje:

Parte I: Introdução
Parte II: Conectando o circuito e o programa para o CANNY 3 tiny
Parte III: Escrevemos um aplicativo no Xamarin para Android
Parte IV: Conclusão

Parte I: Introdução


Começarei com o bom, exceto pelas inserções do código do programa em C #, desta vez o artigo será relativamente pequeno, porque examinamos as técnicas básicas de trabalho com o controlador anteriormente. Para não repetir novamente, aqui está uma lista de artigos nos quais já examinamos os métodos básicos de trabalho com o controlador CANNY:

  1. "Um, dois, três - queime a árvore de Natal!" ou meu primeiro olhar para o pequeno controlador CANNY 3 - neste artigo, analisamos o que é o controlador, bem como os conceitos básicos de trabalho no ambiente de desenvolvimento CannyLab.
  2. “O destino tem muitas formas ...” ou automatizamos o controle de uma lâmpada usando o CANNY 3 tiny e um fotorresistor - neste artigo, analisamos o trabalho com a porta COM virtual USB, conectando sensores ao ADC, bem como o PWM de alta frequência nas saídas do controlador.
  3. « ...» (CANNY Arduino) Raspberry PI — UART, .

Ao preparar este artigo, usei o seguinte hardware: controlador minúsculo CANNY 3, adaptador Bluetooth HC-06, chave final (módulo Trema), chave reed, fones de ouvido com fio antigos, placa de ensaio, fios, crocodilos.

Construiremos um sistema que, usando um aplicativo móvel, monitore o status de dois sensores e, se necessário, possa emitir um alarme manualmente.

Tudo o que será apresentado neste artigo foi inventado exclusivamente para fins educacionais e de demonstração. Eu só queria mostrar alguns truques para trabalhar com o controlador, bem como para os pedaços de ferro comprados de uma só vez, para determinar de alguma forma seu valor.

Apesar da natureza do problema que está sendo resolvido, que está longe da realidade, imaginaremos que estamos criando um sistema de monitoramento atrás da porta deslizante do compartimento. Quando começa a se mover, o interruptor reed funciona e, no final do caminho, dá um sinal ao trailer. Se precisarmos chamar atenção, por exemplo, para que a porta seja fechada novamente, emitiremos um sinal "estridente" através do alto-falante. É verdade que eu não tenho um alto-falante, mas existem fones de ouvido antigos.



Bem e, como sempre, uma nota. Eu não recomendo usar os materiais deste artigo como a verdade suprema. Fiz muitas coisas pela primeira vez, elas certamente podem ser feitas melhor.


Parte II: Conexão do circuito e programa do CANNY 3 tiny


Para começar, para não ofender ninguém com direitos autorais, peguei emprestado do fórum , mas por mim mesmo os adaptei para a idéia de conectar o controlador ao HC-06, controlando-o através do aplicativo "Serial bluetooth terminal" e alguns truques ao desenvolver o diagrama. sua tarefa.

O diagrama de conexão é o seguinte: A



chave limitadora e a chave reed estão conectadas aos terminais dos controladores nº 6 e nº 5, os fones de ouvido ao terminal nº 4 (possui um RF PWM), o UART RX é o terminal nº 1, o UART RX é o terminal nº 1, o UART TX é o terminal nº 2, o terminal nº 3 É usado para fornecer “+ 5V”, a saída “-” - para comunicação com o “terra”.

Aqui está o que parece na montagem:



Desenvolvi o diagrama (programa) para o CANNY 3 tiny no CannyLab versão 1.42, talvez em outras versões do ambiente de desenvolvimento e com outros controladores, seja necessário fazer alterações no diagrama.

Aqui está o que aconteceu: Os



blocos associados à configuração do controlador e ao envio de mensagens via UART foram desmontados em um artigo anterior .

Vamos examinar com mais detalhes os dois restantes.

O bloco " Receber mensagem UART " é responsável por ligar a sirene (fones de ouvido). Em princípio, é necessário analisar um exemplo de recebimento de uma mensagem via UART.

Primeiro, verificamos se os dados recebidos estão no UART; nesse caso, enviamos um para a entrada do acionador D "E"; nesse caso, o acionador copia o valor da entrada "D" na qual escreveremos os dois primeiros caracteres da mensagem recebida via UART. Como não queria complicar tudo, usaremos um esquema simples ainda mais. Assumimos que qualquer número de 00 a 99 chegará até nós pelo UART, traduziremos esse número de uma forma simbólica para uma numérica (eu recomendo a leitura de como o bloco conversor funciona , tive um pequeno "plug"). Além disso, qualquer valor "> 0" na entrada do detector de borda principal causa um único sinal, que liga a saída 5 por 5 segundos, operando no modo RF PWM.

Você pode tocar nas configurações com o período de preenchimento do RF PWM, o som dos fones de ouvido dependerá disso.

Vamos para o quarteirão"Formação da mensagem . " Sua implementação à primeira vista pode parecer incomum. Isso é explicado pelo fato de eu realmente não descobrir como trabalhar com o programa de terminal Bluetooth serial e com o mesmo protocolo bluetooth no Xamarin.

Vou um pouco à frente e digo que não aprendi como receber mensagens enviadas do controlador no meu smartphone. Se tudo ficou óbvio com o UART conectado no artigo anterior, com o Bluetooth, na prática, em vez da mensagem enviada, apenas sua parte pode ser lida e o significado do comando transmitido é violado.

Decidi que a solução mais simples é transmitir um único número, que é garantido para chegar ao destinatário sem perdas.

No nosso caso, monitoramos o estado discreto da chave reed e da chave limite. Ou seja, temos apenas 4 combinações possíveis: a chave reed e a chave limite estão desligadas, apenas uma está ligada, ambas estão ativadas.

Como a chave reed e a chave limitadora emitem um sinal discreto (0/1), é necessário distingui-las de alguma forma. Para fazer isso, multiplicamos o valor do sinal reed por 2. Agora, a soma dos sinais nos fornecerá valores de 0 a 3.

Agora, analisaremos uma opção não óbvia com cinquenta adicionadas a esse valor. O fato é que o CannyLab transfere alguns caracteres para o UART, ou seja, em vez de 3, digamos 03, mas, como eu disse, há o risco de perder algumas informações. Por exemplo, a partir do valor 01, o programa no smartphone pode ler apenas o primeiro “0”, e isso já será um erro.

Seria possível ficar confuso e transformar os dados, substituindo, por exemplo, o caractere “D1” do registro por alguma letra ou espaço, mas decidi facilitar. Eu converti o valor 01 para 51 (02 para 52, etc.). Os cinco não transmitem um sinal e eu o corto no nível do programa para um smartphone. Assim, sempre garantimos que a parte útil da mensagem permanece.

Carregamos o programa no controlador, clique em “executar”, se tudo funcionar como planejado, o HC-06 piscará periodicamente um LED vermelho.

Em seguida, emparelhamos o smartphone com o adaptador. Agora você pode verificar o desempenho no aplicativo “Terminal Bluetooth serial” ou em qualquer outro com funcionalidade semelhante.

Anote o endereço do adaptador Bluetooth, será útil para nós no próximo capítulo.



Como você pode ver, os dados são fornecidos, dependendo do estado dos sensores, e se você enviar "11", um chiado desagradável será ouvido nos fones de ouvido. Poderíamos parar por aqui, mas vamos esboçar uma aplicação primitiva.

O programa para o controlador e o código-fonte do programa para o smartphone podem ser baixados no GitHub

. Gostaria de observar que você não precisa implementar tudo no hardware especificamente nos controladores CANNY, você pode escrever um programa para o Arduino ou outro controlador que desejar. Inicialmente, eu também planejava escrever uma versão adicional do esboço para o Arduino, mas desde que matei quase todos os feriados de maio, simplesmente não tive forças para conectar o CANNY e o aplicativo para smartphone.

Parte III: Escrevendo um aplicativo Android Xamarin


Eu sei que o Xamarin, para dizer o mínimo, não é a solução mais popular para o desenvolvimento móvel. E talvez você já tenha uma pergunta: "Por que eu escolhi?" . Eu gostaria de responder com palavras da música de mesmo nome de Psoya Korolenko:



Honestamente, não há razões objetivas. Há alguns anos, aprendi o básico de C # e todos queriam ver o que é Xamarin. E agora, devido ao "auto-isolamento", as mãos finalmente chegaram.

Bem, deixe-me lembrá-lo novamente. Esta é a primeira vez que conheço o Xamarin e este é o meu primeiro aplicativo para Android. Não copie cegamente o código da minha curva; se de repente você encontrar uma solução mais bonita, use-a.

Ao desenvolver meu programa, contei com esse material. O artigo não é particularmente mastigado, e mesmo em espanhol, então ainda achei apropriado compartilhar com você minha variação sobre esse tópico.

Criei o programa na edição da comunidade do Visual studio 2019.

Primeiro, crie um novo projeto Android vazio (Xamarin), como na figura.



Fiz alterações em apenas três arquivos, eles podem ser visualizados inteiramente no GitHub , e aqui analisaremos apenas as partes importantes: permissões

AndroidManifest.xml

2 são adicionadas ao modelo padrão:

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

activity_main.xml O
contêiner padrão (RelativeLayout) foi removido. Em vez disso, o contêiner LinearLayout foi adicionado simplesmente por ser mais simples. Nesse contêiner, todos os elementos são alinhados verticalmente, estendendo-se por toda a largura da tela.

<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>

Qualquer pessoa familiarizada com o layout HTML ou XML pode entender facilmente a estrutura da interface do usuário. Temos três campos de texto somente leitura (TextView), um switch (Switch), que basicamente funciona como uma caixa de seleção e um botão comum (Button). Os elementos podem ser colocados no formulário arrastando e soltando do construtor e na janela de propriedades ou no código para defini-los como ID mais conveniente, stubs de texto e outros parâmetros.

Resta descrever a lógica do programa.

MainActivity.cs

Abaixo, abaixo do spoiler, todo o código é por conveniência

Código MainActivity.cs completo
// 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);
        }
    }
 }


Agora em partes.

Blocos com conexão de namespaces, declaração de classe, etc. Vou sentir falta.


Criamos variáveis ​​com as quais vincularemos posteriormente os elementos da interface do usuário:

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

Em seguida, vem o código do exemplo em que eu confiei. Variáveis ​​(campos) necessárias para a operação de certos métodos.

  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;

É importante para nós aqui conduzir o endereço do seu módulo HC-06 no campo de endereço.

Como esta é minha primeira experiência de desenvolvimento para smartphones, incluindo o trabalho com o Xamarin, decidi não complicar nada, portanto o endereço do dispositivo, como no exemplo original, é codificado. Se você quiser, pode ver este artigo , parece que foi implementada uma enumeração de dispositivos Bluetooth disponíveis.

Ir em frente.


        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();
        }

Esse método é criado automaticamente, nossa tarefa é associar objetos da interface do usuário aos campos da classe e também anexar manipuladores para reações a eventos ( startSiren.Click bltSwitch.CheckedChange).

Verificando a conexão 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();
            }
        }

Ligue a sirene. Essencialmente, basta enviar os caracteres "11" para o controlador:


   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";
        }

Verificando o status do comutador (se deslocado para a direita, significa que está ligado):

   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);
                    }
                }
            }
        }

Quando você liga, iniciamos a conexão com o Bluetooth.

A implementação da própria conexão:

   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();

        }

E aqui está um dos métodos mais importantes - a leitura direta de dados:


    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;
                    }
                }
            });
        }

Deixei muitos elementos do método, como no exemplo, como eu o entendo, primeiro é criada uma conexão com o fluxo de dados; se houver algo no buffer com os dados lidos, ele será lido em uma variável valor. Além disso, como prometi, simplesmente excluímos o número "5".

Em seguida, removemos todos os caracteres, exceto os números da mensagem string command = new string(valor.Where(char.IsDigit).ToArray());

lida.Depois disso tudo é simples, dependendo do número que chegou até nós, exibimos esse ou aquele status na interface do usuário.

Não mudei fundamentalmente esses dois métodos:

  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);
        }
    }
 }

Pelo que entendi, esse bloco de código implementa o envio de uma mensagem e um manipulador de eventos para aumentar demais a permissão para acessar o Bluetooth.

Bem, isso é tudo o que resta para configurar uma conexão de smartphone para depurar o aplicativo .

Estranhamente, mas funciona:



Parte IV: Conclusão


Veja como o programa funciona da mesma maneira:



Essa foi minha primeira experiência no desenvolvimento de aplicativos para um smartphone no Android.

Gostaria de observar que o VS 2019 e o Xamarin no meu computador antigo funcionam muito lentamente.

Na primeira montagem do projeto, eu realmente consegui comer esses pães franceses macios e beber chá. Além disso, o próprio aplicativo mostrou-se francamente miserável, o botão liga / desliga não funciona muito convenientemente, mas, por outro lado, dado que eu estou um pouco familiarizado com as técnicas básicas de desenvolvimento para .NET, além do fato de eu não ser um programador, eu poderia até sem passar por um único tutorial ou uma única lição, descreva seu primeiro aplicativo em um dia. Portanto, o limite de entrada para criar um aplicativo elementar é bastante baixo.

Pelo que entendi, os controladores CANNY podem ser usados ​​ao ajustar carros, especialmente os domésticos, para que seja possível criar algum tipo de "recurso" e escrever nele um aplicativo para smartphone. O principal a lembrar é que, quando alimentados a partir da rede de bordo do veículo, as saídas do controlador também terão a mesma tensão que a entrada (por exemplo, 12 V em vez de 5 V). Não se esqueça de proteger o adaptador Bluetooth para que ele não falhe inadvertidamente.

O artigo acabou sendo muito trabalhoso para mim, espero que tudo não tenha sido em vão e você goste.

All Articles