A tentativa do Arduino de realizar a comunicação serial por meio de mensagens simples——e o experimento de ajustar o brilho da luz por voz

    A chamada comunicação de porta serial consiste em dividir os dados em bits binários (bits) um a um em uma linha de dados e, em seguida, transmiti-los. Do ponto de vista do nível, geralmente a comunicação serial do nosso microcontrolador adota o padrão serial TTL. Na verdade, essas são as categorias de implementação de hardware.Do ponto de vista do programa, enviamos e recebemos dados na ordem byte a byte, ou seja, ainda processamos os dados em unidades de bytes. Portanto, de um ponto de vista superior, para padronizar o envio e recebimento correto de dados, geralmente enviamos e recebemos os dados em um conjunto de dados (quadro de dados) de acordo com determinados requisitos. Esse conjunto de dados é mais padronizado chamado de quadro de dados, é o que chamamos de mensagem. Para garantir que diferentes dispositivos de diferentes fabricantes possam trocar dados entre si, alguns protocolos padronizados para formatos de mensagem foram formulados. Atualmente, o mais comumente usado no campo de controle industrial é o protocolo Modbus. O protocolo Modbus é padrão e aberto, e pode suportar vários tipos de interface elétrica, o formato do quadro de dados é simples e compacto, o volume de transmissão de dados é grande e o desempenho em tempo real é bom. No entanto, devido à sua alta versatilidade e confiabilidade, seu formato é relativamente complicado, resultando em escrita de programas complicados. Quando usamos o Arduino para realizar alguns experimentos simples de transmissão de comandos e troca de dados de comunicação com outros dispositivos, se o protocolo Modbus for usado, a complexidade da programação aumentará bastante. Este artigo é apenas para realizar tais experimentos de forma conveniente e concisa e, ao mesmo tempo, para atender aos requisitos gerais de transmissão de dados, tente usar um formato de mensagem simples para atender a alguns experimentos simples de transmissão de comandos e troca de dados de comunicação entre o Arduino e outros dispositivos Requer .

    De acordo com os requisitos acima, primeiro determinamos que o comprimento da mensagem é fixo e tem uma especificação simples. Este experimento usa um comprimento de mensagem de 3 bytes sem CRC e outros códigos de verificação. Claro, em termos de confiabilidade, falta . O formato da mensagem é o seguinte:

        O primeiro byte: código de função (a faixa de valores recomendada é 1-254)

        O segundo byte: byte de dados 1 (intervalo de valores é 0-255)

        O terceiro byte: byte de dados 2 (intervalo de valores é 0-255)

    O código de função (ou número de comando) do primeiro byte pode ser definido de acordo com seus próprios requisitos, indicando que esta mensagem representa uma função especificada e o intervalo de valores recomendado é de 1 a 254. Os 2º e 3º bytes são os dados necessários para esta função. Se esta função não requer dados, os valores dos 2º e 3º bytes não podem ser atribuídos, mas eles ainda serão enviados durante a transmissão e o destinatário final também receberá este 2º e 3º bytes.

    Quando os dados de uma função excedem 2 bytes, você pode simplesmente usar diferentes códigos de função para representar mais dados. Por exemplo, os dados de uma função (assumindo que o código de função é 48 aqui) é um inteiro longo, podemos usar a função o código 48 envia os primeiros 2 bytes primeiro e, em seguida, usa o código de função 49 para enviar os últimos 2 bytes.

    Este experimento ainda é feito com um Arduino UNO e um LU-ASR01 (me perdoe, essas são as duas únicas placas com portas seriais TTL disponíveis). O experimento recebe nossos comandos de voz através do LU-ASR01: acende a luz, apaga a luz, aumenta a intensidade da luz, diminui a intensidade da luz e depois envia o código da função correspondente ao Arduino. Após receber o código da função, o Arduino se ajusta de acordo com o dados por trás da mensagem. O brilho do LED conectado ao Arduino pode ser comandado repetidamente para aumentar e diminuir a luz. Cada vez que a voz é emitida, o brilho total é ajustado em 10% até ficar totalmente claro ou completamente preto . Além disso, quando o LED estiver no estado ligado (ou seja, não totalmente preto) sem alterar o brilho da luz por mais de 1 minuto, o Arduino desliga o LED e envia uma mensagem para LU-ASR01, e após LU-ASR01 recebe esta mensagem e, em seguida, transmite "As luzes estão acesas há mais de um minuto e Adu apagou as luzes."

(Observação: em relação ao fato de que a comunicação serial bidirecional do LU-ASR01 usa uma porta serial flexível, você pode consultar a "Implementação de comunicação serial bidirecional entre o Arduino e o módulo de reconhecimento de fala LU-ASR01" que escrevi antes )

    Método de conexão de hardware: Arduino ainda usa comunicação serial de hardware, usando portas TX e RX, LU-ASR01 usa porta IO6 como soft TX para enviar dados e porta IO7 como soft RX para receber dados. O Arduino fornece alimentação de 5V para LU-ASR01 (2 fios vermelho e preto na figura abaixo), o TX do Arduino está conectado à porta IO7 do LU-ASR01 (soft RX), o RX do Arduino está conectado à porta IO6 do LU-ASR01 (soft TX ) , o ânodo do LED é ligado ao D11 do Arduino, o esquema de ligação é o seguinte:

 

    A seguir, uma breve introdução ao programa no lado do Arduino. Existem 2 sub-rotinas para enviar e receber mensagens no programa, uma é a sub-rotina para enviar mensagens void txmss(unsigned char txb[],int n), o parâmetro txb[] é para armazenar os dados da mensagem (incluindo códigos de função) para ser enviado , n é o comprimento da mensagem (o comprimento da mensagem pode ser definido pela constante MLEN no início do programa, basta preencher MLEN ao chamar). A outra é a sub-rotina bool rxmss(unsigned char rxb[], int n) que recebe a mensagem. Quando a mensagem completa é recebida com sucesso, a sub-rotina retorna true, caso contrário retorna false. O parâmetro rxb[] serve para armazenar o valor recebido Os dados da mensagem (incluindo código de função), n é o comprimento da mensagem.

    No loop do programa de loop principal, precisamos apenas julgar se há dados na porta serial e, em seguida, chamar rxmss para receber a mensagem de dados e, em seguida, executar as operações correspondentes de acordo com o código de função recebido Rxbyte[0]. Neste experimento, o código da função para ajustar o brilho da lâmpada é definido como 33 (ou seja, 0x21 em hexadecimal), o segundo byte não é usado e o terceiro byte é o valor do brilho. Quando a mensagem com o código da função igual a 33 for recebido, basta usar o terceiro byte como o valor de brilho e chamar a função analogWrite para definir o brilho do LED.

    Se precisar que LU-ASR01 execute uma determinada operação, você pode preencher Txbyte[0], Txbyte[1], Txbyte[2] e chamar txmss para enviar a mensagem para LU-ASR01. If(brightness>0){ no loop, ao final desta seção é julgar se há mais de 1 minuto e, em seguida, desligar o LED e, em seguida, enviar uma mensagem para LU-ASR01, dizendo para desligar o LED após mais de 1 minuto. O código de função da mensagem ainda é definido como 33 (pode ser personalizado para outros valores), enquanto o byte 3 é definido como 0.

    Aqui está o programa completo:

/*

   Este é um programa de mensagem de comunicação simples, o comprimento da mensagem é de 3 bytes e o formato da mensagem é:

   O primeiro byte: número do comando O segundo e terceiro bytes: dados

   Experimento de comunicação serial entre o Arduino e o módulo de reconhecimento de fala ASR01

   A mensagem do programa usa apenas um número de comando: 0x21 (byte 1), o byte 2 é inútil e o byte 3 é o brilho da lâmpada (faixa de valores 0-255)

   ASR01 enviará esta mensagem para a máquina e a máquina definirá o brilho do LED correspondente após receber a mensagem

   Quando a luz LED estiver acesa, após esperar 1 minuto, desligará automaticamente o LED e enviará uma mensagem de luz apagada para ASR01

*/

#define MLEN 3 //Define o comprimento da mensagem como 3

const int LedPin = 11; // Define o pino conectado ao led como D11 (pode ser usada porta IO com PWM), como o polo positivo da luz do LED

brilho int = 0; // brilho do LED, o valor é 0-255, 0 é completamente preto, 255 é totalmente brilhante

long PreviousMillis = 0; // armazena o último tempo de funcionamento da máquina quando o LED foi aceso

long interval = 60000; // O tempo de espera para as luzes se apagarem é de 1 minuto

unsigned char Txbyte[MLEN]; //Os dados de caracteres enviados pela porta serial, o comprimento é MLEN

unsigned char Rxbyte[MLEN]; //Os dados de caracteres lidos pela porta serial, o comprimento é MLEN

//inicialização

void setup() {

  Serial.begin(9600); //Configura a taxa de transmissão da porta serial para 9600

  pinMode(LedPin, OUTPUT); //Definir LedPin    

}

//Envia sub-rotina de mensagem

//O parâmetro txb são os dados da mensagem a serem enviados e n é o comprimento da mensagem

void txmss(unsigned char txb[],int n){

  int eu;

  for(i=0;i<n;++i){

    Serial.write(txb[i]);

    atraso(2);  

  }

}

//Recebe a sub-rotina da mensagem, o valor de retorno é verdadeiro se a mensagem for recebida com sucesso, caso contrário é falso

//O parâmetro rxb são os dados da mensagem retornados, n é o comprimento da mensagem

bool rxmss(unsigned char rxb[],int n){

int i,dn; //dn é o contador de timeout

  for (i=0; i<n; ++i) {

    dn=0; //redefinir a variável de contagem de tempo limite

    while(1){ //  

      if (dn<=50){ //Define o tempo máximo de espera para ler um byte em 50ms, se não houver timeout

        if(Serial.available() > 0){ //Quando o buffer serial tem dados

          rxb[i]=Serial.read(); //lê um byte

          break; //Quebra o loop while(1)

        }

        else{ //Se não houver dados no buffer da porta serial e não houver tempo limite, o contador de tempo limite será +1

          atraso(1);

          dn+=1; //contador de tempo limite +1

        }

      }

      else return false; //Ao receber timeout, a função rxmss sai e retorna false

    }

  }

  return true; // normalmente recebe n bytes, a função rxmss retorna true

}

//programa principal

loop void() {

  if (Serial.available() > 0){ //Quando o buffer serial tem dados

    if (rxmss(Rxbyte,MLEN)){ //Se uma mensagem for recebida com sucesso (ou seja, os dados de 3 bytes foram recebidos no array Rxbyte)

      if(Rxbyte[0]==0x21) { //Se o Rxbyte[0] recebido for 0x21, é um comando para ajustar o brilho da luz

        brilho = Rxbyte[2]; // valor de brilho é 0-255, 0 é todo preto, 255 é todo brilhante

        analogWrite(LedPin, brilho); //Use o método PWM, brilho para definir o brilho da luz

        if(brightness>0){ //Quando a luz estiver acesa, comece a cronometrar

          anteriorMillis = millis(); //função millis obtém o tempo de execução da máquina, em ms

        }

      }

    }

  }

  //O tempo de iluminação do LED excede o número de milissegundos especificado pelo intervalo, então desligue o LED e envie uma mensagem para ASR01

  if(brightness>0){ //se a luz for forte

    unsigned long currentMillis = millis(); //função millis obtém o tempo de execução da máquina, em ms

    if(currentMillis - previousMillis > interval) { // O tempo para ligar o LED excede o número de milissegundos especificado pelo intervalo

      //preenche a mensagem

      Txbyte[0]=0x21;

      Txbyte[1]=0x00;

      Txbyte[2]=0x00;

      txmss(Txbyte,MLEN); //envia mensagem

      brilho=0; //Grava o valor de brilho atual como 0

      analogWrite(LedPin, brilho); //Usando o modo PWM, o brilho define o brilho da luz para 0, ou seja, desliga a luz

    }

  }

}

    O LU-ASR01 ainda utiliza a plataforma de programação gráfica "bloco Tianwen". Para facilitar a análise do programa, adota a mesma estrutura de programa do Arduino, sendo que o nome da sub-rotina, nome da variável e nome do array também são exatamente os mesmos, portanto nenhuma análise adicional introduzida. O seguinte é o programa completo no "bloco Tianwen":

 

Meu nome online é "Mr. Unforgiveness". Os artigos publicados no CSDN são todos meus trabalhos originais e são publicados apenas no site do CSDN. As reimpressões em outros sites não foram autorizadas por mim.

Acho que você gosta

Origin blog.csdn.net/m0_61543203/article/details/126331582
Recomendado
Clasificación