Interface do Módulo RF 433Mhz com STM32F103C8

Tempo de leitura: 8 minutes

Fazer projetos sem fio em eletrônicos embarcados torna-se muito importante e útil, pois não há fios desordenados por toda parte, o que torna o dispositivo mais prático e portátil. Existem várias tecnologias sem fio, como Bluetooth, WiFi, 433 MHz RF (radiofrequência) etc. Cada tecnologia tem suas próprias vantagens e desvantagens, como custo, distância ou transferência de alcance, velocidade ou taxa de transferência, etc. Hoje usaremos o módulo RF com STM32 para enviar e receber os dados sem fio. Se você é novo no microcontrolador STM32, comece com LED piscando com STM32 usando Arduino IDE e verifique todos os outros projetos STM32 aqui.

Aqui faremos a interface de um módulo sem fio RF de 433 MHz com o microcontrolador STM32F103C8. O projeto está dividido em duas partes. O transmissor terá interface com o STM32 e o receptor com o Arduino UNO. Haverá diferentes diagramas de circuito e sketch para a parte transmissora e receptora.

Neste tutorial, o transmissor de RF envia dois valores para o lado do receptor: a distância medida usando o sensor ultrassônico e o valor ADC do potenciômetro (0 a 4096) que é mapeado como um número de (0 a 100). O receptor RF do Arduino recebe ambos os valores e imprime esses valores de distância e número em um display LCD 16×2 sem fio.

 

Componentes necessários

  • Microcontrolador STM32F103C8
  • Arduino UNO
  • Transmissor e receptor RF 433Mhz
  • Sensor Ultrassônico (HC-SR04)
  • Display LCD 16×2
  • Potenciômetro de 10k
  • ProtoBoard
  • Fios de conexão

 

Módulo Receptor e Transmissor RF 433Mhz)

Pinagem do transmissor RF:

Transmissor RF 433MhzDescrição do pino
GNDGND
VDD3.3 a 5V
DATAOs dados a serem transmitidos ao receptor são fornecidos aqui

Pinagem do receptor RF:

Receptor RF 433MhzUSAR
GNDGND
VDD3.3 to 5V
DATADados a serem recebidos do transmissor
CE/DOÉ também um pino de dados

Especificações do módulo de 433 MHz:

  • Tensão de operação do receptor: 3V a 5V
  • Tensão de operação do transmissor: 3V a 5V
  • Freqüência de operação: 433 MHz
  • Distância de transmissão: 3 metros (sem antena) a 100 metros (máximo)
  • Técnica de modulação: ASK (manipulação de mudança de amplitude)
  • Velocidade de transmissão de dados: 10Kbps

 

Diagrama de Circuito do Transmissor RF com STM32F103C8

Conexões de circuito entre o transmissor de RF e STM32F103C8:

STM32F103C8Transmissor RF
5VVDD
GNDGND
PA10DATA

Conexões de circuito entre sensor ultrassônico e STM32F103C8:

STM32F103C8Ultrasonic Sensor (HC-SR04)
5VVCC
PB1Trig
PB0Echo
GNDGND

Um potenciômetro de 10k é conectado ao STM32F103C8 para fornecer valor analógico de entrada (0 a 3,3 V) para o pino ADC PA0 do STM32.

Diagrama de Circuito do Receptor RF com Arduino Uno

Conexões de circuito entre receptor de RF e Arduino UNO:

Arduino UNOReceptor RF
5VVDD
GNDGND
11DATA

Conexões de circuito entre LCD 16×2 e Arduino UNO:

Nome do pino LCDNome do Pin do Arduino UNO
Ground (Gnd)Ground (G)
VCC5V
VEEPin from Centre of Potentiometer for Contrast
Register Select (RS)2
Read/Write (RW)Ground (G)
Enable (EN)3
Data Bit 4 (DB4)4
Data Bit 5 (DB5)5
Data Bit 6 (DB6)6
Data Bit 7 (DB7)7
LED Positive5V
LED NegativeGround (G)

A codificação será explicada resumidamente a seguir. Haverá duas partes do esboço, onde a primeira parte será a seção do transmissor e a outra será a seção do receptor. Todos os arquivos de esboço e vídeo de trabalho serão fornecidos no final deste tutorial.

 

Programação STM32F103C8 para transmissão RF sem fio

STM32F103C8 pode ser programado usando Arduino IDE. Um programador FTDI ou ST-Link não é necessário para carregar o código para STM32F103C8. Basta conectar ao PC via porta USB do STM32 e começar a programar com ARDUINO IDE. Você pode aprender a programar seu STM32 no Arduino IDE seguindo o link.

Na seção do transmissor, a distância do objeto em ‘cm’ é medida usando o sensor ultrassônico e o valor numérico de (0 a 100) definido usando o potenciômetro que é transmitido via transmissor de RF com interface com STM32.

Primeiro, a biblioteca do Radiohead está incluída, ela pode ser baixada aqui. Como esta biblioteca usa o ASK (Amplitude Shift Keying Technique) para transmitir e receber dados. Isso torna a programação muito fácil. Você pode incluir a biblioteca no esboço acessando Sketch-> incluir biblioteca-> Adicionar biblioteca .zip.

#include <RH_ASK.h>

Como neste tutorial, no lado do transmissor, um sensor ultrassônico é usado para medir a distância para que os pinos de disparo e eco sejam definidos.

#define trigPin PB1                            
#define echoPin PB0

Em seguida, o nome do objeto para a biblioteca RH_ASK é definido como rf_driver com os parâmetros como velocidade (2000), pino RX (PA9) e pino TX (PA10).

RH_ASK rf_driver(2000, PA9, PA10);

Em seguida, as variáveis Strings necessárias neste programa são declaradas.

String transmit_number;                            
String transmit_distance;
String transmit;

Em seguida, no void setup(), o objeto para RH_ASK rf_driver é inicializado.

rf_driver.init();

Depois disso, o pino de disparo é definido como pino de SAÍDA e o PA0 (conectado ao potenciômetro) e o pino de eco são definidos como pino de ENTRADA. A comunicação serial é iniciada na taxa de transmissão de 9600.

Serial.begin(9600);
pinMode(PA0,INPUT);
pinMode(echoPin,INPUT);
pinMode(trigPin,OUTPUT);

Em seguida, no void loop(), primeiro o valor do potenciômetro que é a tensão analógica de entrada é convertido em valor digital (o valor ADC é encontrado). Já o ADC do STM32 tem resolução de 12 bits. Portanto, o valor digital varia de (0 a 4096) que é mapeado em (0 a 100).

int analoginput = analogRead(PA0);                  
int pwmvalue = map(analoginput,0,4095,0,100);

Em seguida, a distância é medida usando o sensor ultrassônico, definindo o gatilho alto e baixo com um atraso de 2 microssegundos.

digitalWrite(trigPin, LOW);                          
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);                          
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

O pino de eco detecta a onda refletida de volta, ou seja, o tempo durante o qual a onda disparada é refletida de volta é usado no cálculo da distância do objeto usando a fórmula.

long duration = pulseIn(echoPin, HIGH);              
float distance= duration*0.034/2;

Agora, tanto o número de dados quanto a distância medida são convertidos em dados de string e armazenados nas respectivas variáveis de string.

transmit_number= String(pwmvalue);                     
transmit_distance = String(distance);

A string é adicionada como uma linha e armazenada em uma string chamada transmit e a vírgula “,” é usada para separar duas strings.

transmit = transmit_pwm + "," + transmit_distance;

A sequência de transmissão é convertida em matriz de caracteres.

const char *msg = transmit.c_str();

Os dados são transmitidos e aguardam até que sejam enviados.

rf_driver.send((uint8_t *)msg, strlen(msg));         
rf_driver.waitPacketSent();

Os dados da string enviados também são exibidos no Monitor serial.

Serial.println(msg);

 

Programando Arduino UNO como receptor RF

O Arduino UNO é programado usando o IDE do Arduino. Na seção do receptor, os dados que são transmitidos da seção do transmissor e recebidos pelo módulo receptor de RF e os dados da string recebidos são divididos nos respectivos dados (distância e número) e exibidos no display LCD 16×2.

Vejamos a codificação do receptor resumidamente:

Como na seção do transmissor, primeiro a biblioteca RadiohHead está incluída. Como esta biblioteca usa o ASK (Amplitude Shift Keying Technique) para transmitir e receber dados. Isso torna a programação muito fácil.

#include <RH_ASK.h>

Como o display LCD é usado aqui, a liquidcrystal library também está incluída.

#include <LiquidCrystal.h>

E os pinos da tela LCD 16×2 conectados ao Arduino UNO são especificados e declarados usando lcd como objeto.

LiquidCrystal lcd(2,3,4,5,6,7);

Em seguida, as variáveis de dados String para armazenar dados de string são declaradas.

String str_receive;                
String str_number;
String str_distance;

O objeto para a biblioteca Radiohead é declarado.

RH_ASK rf;

Agora na configuração ‘void setup()’, o display LCD é definido no modo 16×2 e uma mensagem de boas-vindas é exibida e apagada.

lcd.begin(16,2);              
lcd.print("CapSistema");  
lcd.setCursor(0,1);
lcd.print("RF com STM32");
delay(5000);
lcd.clear();

Depois disso, o objeto rf é inicializado.

rf.init();

Agora, no ‘void loop()’, o Array buf[] é declarado com tamanho de 7. Como os dados enviados do transmissor têm 7 incluindo o “,”. Portanto, mude de acordo com os dados que serão transmitidos.

uint8_t buf[7];                       
uint8_t buflen = sizeof(buf);

Se a string estiver disponível no módulo receptor rf, a função if verifica o tamanho e executa. O rf.recv() é usado para receber dados.

if (rf.recv(buf, &buflen))

O buf tem a string recebida, então a string recebida é armazenada em uma variável de string str_receive.

str_receive = String((char*)buf);

Este loop for é usado para dividir a string recebida em duas se detectar o ‘,’ entre duas strings.

for (int i = 0; i < str_receive.length(); i++) {
    if (str_receive.substring(i, i+1) == ",") {
       str_number = str_receive.substring(0, i);
       str_distance = str_receive.substring(i+1);
       break;
    }

Duas matrizes de char para dois valores são declaradas e a String que é dividida em duas é armazenada em uma matriz respeitada, convertendo a string em uma matriz de caracteres.

char numberstring[4];
char distancestring[3];
str_distance.toCharArray(distancestring,3);             
str_number.toCharArray(numberstring,3);

Depois disso, converta a matriz de caracteres em inteiro usando atoi()

int distance = atoi(distancestring);                   
int number = atoi(numberstring);

Depois de converter em valores inteiros, os valores de distância e número são exibidos no display LCD 16×2

lcd.setCursor(0,0);
lcd.print("Number:");
lcd.print(number);                 
lcd.setCursor(0,1);
lcd.print("Distance :");
lcd.print(distance);                   
lcd.print(" cm");

Depois de fazer o upload de ambos os códigos, ou seja, transmissor e receptor no STM32 e no Arduino UNO, respectivamente, os dados como número e distância do objeto medidos usando o STM32 são transmitidos para o receptor de RF via Transmissor de RF e os valores recebidos são exibidos no display LCD sem fio.

 

Testando transmissor e receptor de RF baseado em STM 32

1. Quando o número é 0 e a distância do objeto é 6cm.

2. Quando o número 47 e a distância do objeto estiverem a 3 cm.

 

Código

Código do transmissor (STM32F103C8):

//Transmissor RF 433MHZ com STM32F103C8
//Código do Transmissor

#include <RH_ASK.h>                             //RadioHead library
#define trigPin PB1                             //Define o gatilho do sensor ultrassônico como PB1
#define echoPin PB0                             //Define o echoPin do sensor ultrassônico como PB0
RH_ASK rf_driver(2000, PA9, PA10);              //Define o pino PA9 como receptor e PA10 como transmissor e 2000 como velocidade
String transmit_pwm;                            //Strings para armazenar o valor da string
String transmit_distance;
String transmit;

void setup()
{

    // Initialize ASK Object
    rf_driver.init();
    Serial.begin(9600);
    pinMode(PA0,INPUT);
    pinMode(echoPin,INPUT);
    pinMode(trigPin,OUTPUT);
}

void loop()
{
    int analoginput = analogRead(PA0);                    //Valor ADC do pino PA0 conectado ao potenciômetro
    int pwmvalue = map(analoginput,0,4096,0,100);         //Converte 0 a 4096 em 0 a 100
    digitalWrite(trigPin, LOW);                           //Torna TrigPin de ultrassônico BAIXO
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);                          //Torna TrigPin de ultrassônico ALTO
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);                           //Torna TrigPin de ultrassônico BAIXO
    long duration = pulseIn(echoPin, HIGH);               //Recebe o sinal de eco refletido
    float distance= duration*0.034/2;                     //Calcula a distância em CM do objeto
    transmit_pwm = String(pwmvalue);                      //Converter valor em string
    transmit_distance = String(distance);                 //Converter valor em string
    transmit = transmit_pwm + "," + transmit_distance;    //Adiciona duas strings em uma linha
    const char *msg = transmit.c_str();                   //
    rf_driver.send((uint8_t *)msg, strlen(msg));          //Envia o String
    rf_driver.waitPacketSent();         
    Serial.println(msg);                                  //Valor de impressão serial para depuração
    delay(1000);
}

Código do receptor (Arduino UNO):

//Código Arduino do receptor
//433MHZ RF com STM32F103C8 como transmissor

#include <RH_ASK.h>                 //Inclui Biblioteca RadioHead
#include <LiquidCrystal.h>          //Inclui a biblioteca de display LCD
LiquidCrystal lcd(2,3,4,5,6,7);     //Inicializar lcd com pinos conectados ao Arduino
String str_receive;                 //Strings to Store Value
String str_number;
String str_distance;
RH_ASK rf;                          //rf como objeto para RG_ASK

void setup()
{
    lcd.begin(16,2);               //Lcd definido como modo 16x2
    lcd.print("CIRCUIT DIGEST");   //Exibir mensagem de boas-vindas
    lcd.setCursor(0,1);
    lcd.print("RF with STM32");
    delay(5000);
    lcd.clear();
    rf.init();                     //Inicializar objeto rf
}

void loop()
{
    uint8_t buf[7];                       
    uint8_t buflen = sizeof(buf);
    if (rf.recv(buf, &buflen))                                  
    {
      str_receive = String((char*)buf);                          // Receber String do Transmissor
      for (int i = 0; i < str_receive.length(); i++)             // Divida a corda em duas cordas
      {
        if (str_receive.substring(i, i+1) == ",")                 
        {
           str_number = str_receive.substring(0, i);
           str_distance = str_receive.substring(i+1);
           break;
        }
      }
      char numberstring[4];
      char distancestring[3];
      str_distance.toCharArray(distancestring,3);             //Converter String em Char Array
      str_number.toCharArray(numberstring,3);
      int distance = atoi(distancestring);                    //Converter Array em valor inteiro
      int number = atoi(numberstring);
      lcd.setCursor(0,0);
      lcd.print("Number:");
      lcd.print(number);                                      //Exibir valor numérico no display LCD
      lcd.setCursor(0,1);
      lcd.print("Distance :");
      lcd.print(distance);                                    //Exibir valor de distância no display LCD
      lcd.print(" cm");
      delay(1500);
      lcd.clear();
   }
}