Mais uma vez cerca de 433 MHz transmissores e receptores

O conjunto mais simples de receptor e transmissor ISM de 433 MHz ganhou popularidade merecida entre os amantes de eletrônicos. Os kits são baratos (mesmo no Chip-Deep você pode comprá-los por 300 rublos, e no Ali, dizem eles, geralmente por cinquenta dólares), são simples e confiáveis. Além disso (que você provavelmente não suspeita), este é o método mais abrangente e penetrante de troca de dados sem fio - um sinal a uma frequência de 433 MHz passa muito melhor por obstáculos e opera a uma distância maior do que na popular faixa de 2,4 GHz (433 O MHz é completamente atrasado por uma parede de meio metro de concreto e o Wi-Fi já está morrendo 10 centímetros). Eu admito que apareceu recentemente módulos MBee-868Por estarem equipados com uma antena (direcional) apropriada, eles “disparam” ainda mais, mas são pelo menos uma ordem de magnitude mais cara, mais difícil de conectar, exigem gerenciamento e pré-configuração de economia de energia. Além disso, a frequência de 868 MHz passa por obstáculos duas vezes mais ruins (embora, é claro, seja incomparavelmente melhor que a frequência de 2,4 GHz).



Muito foi escrito sobre transmissores e receptores de 433 MHz (inclusive no hub) , é claro. No entanto, parece que ninguém sabe como incluir corretamente este kit no circuito por algum motivo estranho. Quando mais uma vez li aqui que o kit “ tinha 8 metros dentro da linha de visão, o 9º metro não podia ser dominado", Minha paciência estalou. Que outros 8 metros ?! Aos 40-50, eu teria acreditado, embora, na realidade, provavelmente, o alcance seja ainda maior.

Vale a pena notar que eu resolvo ainda mais o problema de criar uma linha para transferência de dados arbitrários, e não apenas controlar quaisquer tomadas inteligentes ou modelos de barcos a motor. Minha tarefa é mais complicada, mas ainda assim a distância da operação confiável é muito maior. Além disso, em uma tarefa como essa, é importante não apenas e não tanto a distância dentro da linha de visão (pode servir apenas para comparação), mas a capacidade de penetrar em vários obstáculos.

Meu kit trabalha fora da cidade a uma distância de cerca de 25 a 30 metros em um ângulo agudo em relação à parede de toras, de modo que aproximadamente um metro (no total) de paredes e divisórias, parcialmente protegidas pelo isolamento da película, esteja no caminho do sinal. A uma distância muito menor, quase diretamente atrás da parede, o WiFi já está perdendo completamente o sinal. Na cidade, o sinal termina de uma extremidade a outra de um apartamento urbano de três quartos através de duas divisórias internas, bem como da varanda, onde em uma linha reta entre o transmissor e o receptor pelo menos 80 centímetros de alvenaria e uma partição de gesso. Não usei opções de kit mais caras mencionadas na análise acima.

Uma vantagem adicional do kit é que, em pausas, o transmissor não consome nada e sem modos especiais de suspensão, simplesmente pelo princípio de seu dispositivo (a corrente de consumo em repouso é comparável às correntes de fuga do coletor de um transistor bloqueado, ou seja, cerca de 100 nA).

Vamos ver quais são as armadilhas.

Conexão do transmissor


O transmissor (chamado FS1000A), como podemos ver no diagrama abaixo, é o gerador mais simples baseado em um ressonador SAW de 433 MHz. O gerador é montado no transistor Q1, e o transistor Q2, com base no qual os dados digitais são fornecidos, é simplesmente uma chave que conecta o gerador à energia (ao barramento GND) na presença de um nível alto (unidade lógica) na entrada. A energia pode variar de 5 a 12 volts e, de acordo com os fabricantes, quanto maior a energia, mais a conexão funciona.



Não notei as vantagens fundamentais do aumento da nutrição como parte da minha tarefa. No entanto, não se deve negligenciar o fato de que não há requisitos especiais de energia aqui e, com o aumento da tensão, o dispositivo só funcionará melhor. É conveniente conectar o transmissor diretamente à voltagem de um adaptador de 9-12 volts, bateria ou um conjunto de 6 baterias (pino Vin Arduino). Com uma fonte de alimentação não estabilizada, que pode exceder 12 volts (como, por exemplo, com baterias), costumo desacoplar o transmissor do circuito principal com um estabilizador de 9 volts separado (você pode usar o 78L09 mais simples) e não vejo diferença na operação entre os 9 e 12 volts. Com o Uno ou o Nano, você pode usar o estabilizador de 5 volts incorporado para alimentar o próprio controlador e outros circuitos (por exemplo, sensores)e para o Mini (especialmente seus clones baratos), aconselho a colocar um estabilizador de 5 volts separado, conectando-o ao pino de 5V.

Deve-se notar que recentemente surgiram transmissores que parecem um pouco fora do padrão (veja a Fig. Abaixo). Aconteceu que a ausência de um acelerador L1 (três voltas), do qual restavam apenas orifícios - uma ficção, foi simplesmente substituída pelo componente SMD correspondente. O pior nesta opção é diferente: a impressão superficial pode ser enganosa em relação à conexão dos pinos e da alimentação de dados. A conexão correta é mostrada na figura, é a mesma para todas as opções:



O mais impressionante nesse assunto é que, quando os dados e a energia são misturados, o transmissor continua a trabalhar em distâncias curtas! Se você olhar para o circuito, entenderá o que é: a base Q2 através do resistor está conectada à fonte de alimentação, o transistor está sempre aberto e não afeta a operação do circuito. Um nível lógico alto no barramento de força apenas liga o gerador no momento certo. Os absurdos começam a certa distância - é claro que, a partir de uma conclusão lógica, a fonte de energia é ruim.

Conexão do receptor


Ao comprar um receptor (pode ser chamado MX-RM-5V ou XD-RF-5V), preste atenção ao comprimento dos terminais - de alguma maneira encontrei um lote inteiro com pinos encurtados, o que fez com que o receptor caísse do conector PBS padrão com a menor distorção e sua Eu tive que me conectar especificamente ao quadro.

O circuito do receptor é muito mais complicado (não o reproduzirei, mas você pode encontrá-lo, por exemplo, aqui ). Ele deve receber e amplificar um sinal de alta frequência, filtrar a frequência de 433 MHz, isolar rajadas e convertê-las em níveis lógicos. O receptor possui um afunilamento de sintonia (no meio da placa), mas sem instrumentos precisos para medir as características de amplitude-frequência, eu não recomendo torcer - provavelmente, você não melhorará nada, mas apenas o estragará.

Como já a uma pequena distância o sinal terá muito menos interferência, é claro que devemos lidar com a interferência em todas as frentes: e métodos de circuitos e software. As bibliotecas fazem a última coisa para nós, mas não importa qual matemática seja usada no processamento de software, é aconselhável fazer tudo primeiro para que a unidade lógica na saída apareça apenas quando um sinal útil explodir e não aparecer na presença de interferência. Em outras palavras, seria bom sintonizar ao máximo antecipadamente as interferências durante a recepção.

O método padrão de redução de ruído, conhecido em minha época por todo aluno que montou pelo menos um rádio ou amplificador, é que, para os nós sensíveis à interferência, é necessário fazer uma fonte de alimentação separada, isolada ao máximo de outros circuitos. Você pode fazer isso de maneiras diferentes: depois de instalar um diodo zener separado, agora eles isolam a potência de um nó problemático com um filtro LC (isso é recomendado, por exemplo, para ADCs, consulte as fichas técnicas dos controladores AVR). Porém, em nossas condições, quando os componentes modernos são pequenos e baratos, é mais fácil colocar um estabilizador separado do restante no receptor.



Um estabilizador, por exemplo, do tipo LP2950-5.0 mais dois capacitores necessários para ele na opção mais barata (quando os dois capacitores são de cerâmica, na faixa de 1-3,3 microfarads), adicionará sessenta no máximo ao custo do seu circuito. Mas prefiro não economizar: na saída coloquei uma cerâmica comum e na entrada coloquei um eletrólito (10 a 100 microfarads), além disso, no estado sólido (polímero) ou tântalo. Os capacitores de cerâmica podem ser dispensados ​​lá e ali, se a tensão de entrada de 7 a 12 volts vier de baterias ou de outro estabilizador analógico. Fontes estabilizadas pulsadas e os retificadores não estabilizados mais simples requerem filtragem adicional. Você pode usar eletrólito de alumínio barato se colocar um micro-radar 0,1 de cerâmica paralelo a ele,é ainda melhor colocar uma indutância em série na entrada de várias frações ou unidades de miligenri.

O estabilizador deve ser instalado diretamente próximo ao receptor, o comprimento dos condutores deve ser mínimo. Em vez do LP2950, ​​você pode usar o LM2931 ou similar com uma pequena tensão de passagem (isso é especialmente importante se o circuito for alimentado por baterias - para um LM78L05 regular, a tensão de entrada deve ser de pelo menos 7,5 e, de preferência, de 8 a 9 volts).

Comparando com o caso de alimentar o receptor diretamente do Arduino, como recomendado em todas as publicações (não vi exceções), você ficará surpreso com o efeito obtido - o alcance e a capacidade de penetrar pelas paredes imediatamente aumentam significativamente. O receptor, juntamente com o estabilizador, pode ser realizado em uma pequena caixa separada por conveniência. Você pode conectar sua saída ao controlador no corpo principal com qualquer fio de três fios (duas fontes de alimentação e um condutor de sinal) de até 3 metros de comprimento e talvez mais. Isso é mais conveniente porque as antenas ainda são necessárias e, de acordo com as regras, será melhor que elas sejam paralelas uma à outra no espaço, e nem sempre é possível colocar caixas grandes para que as antenas fiquem na orientação correta.

Na versão mais simples, como antenas, você pode fazer com pedaços de fio de núcleo único com uma seção transversal de pelo menos 0,5 mm e comprimento de 17 cm ± 1-3 mm. Não use fios de montagem trançados! Antenas espirais mais compactas estão à venda, mas eu pessoalmente não testei sua eficácia. A ponta da antena do transmissor e do receptor é selada no orifício correspondente no canto da placa (não se engane na versão atualizada do transmissor - a palavra ANT também está fora do lugar, veja a fig. Acima).

Geração e processamento de dados transmitidos


Essa é a segunda grande desvantagem da maioria das revisões sobre o nosso tópico: os autores limitam-se a algum problema local, sem formulá-lo de uma maneira geral, como transferir dados arbitrários em um pacote. Como você entendeu a partir da descrição acima, apenas uma sequência simples de bits pode ser transmitida pelo nosso conjunto. A biblioteca padrão do VirtualWire os codifica de maneira especial (cada tetrad é codificado com 6 bits, um cabeçalho de sincronização é adicionado na frente e uma soma de verificação para todo o pacote é adicionada) e transforma a saída em uma seqüência de bytes mais familiar. Mas o programador já tem que lidar com isso sozinho.

Além disso, assumimos que o transmissor e o receptor estão conectados ao Arduino. Além do VirtualWire, em conexão com o boom das “casas inteligentes”, existem muitas outras coisas, como o RC-Switch ou o RemoteSwitch, mas eles estão focados em outras tarefas, e claramente não vale a pena usá-los para transferir dados arbitrários.

O comprimento máximo de uma única mensagem no VirtualWire é de 27 bytes (consulte a documentação ). A transmissão de uma mensagem completa (é complementada automaticamente com uma assinatura 0xb38, um valor de comprimento de mensagem e uma soma de verificação) na velocidade escolhida de 1200 bps é de 0,35 segundos.

Quanto mais, a propósito, a velocidade de transmissão selecionada, o alcance da transmissão será menor. Com a experiência de usar o RS-232, sabe-se que, com o alcance crescente, a velocidade de transmissão permitida diminui exponencialmente: a uma velocidade de 19.200, uma linha não blindada percorre 15 metros, 9600 - 150 metros e a uma velocidade de 1200 - mais de um quilômetro. Seria interessante descobrir experimentalmente a natureza dessa dependência para o nosso caso, porque muito aqui depende da matemática usada.

A inicialização do transmissor no VirtualWire é assim:

. . . . .
#include <VirtualWire.h>
. . . . .
void setup() {
  vw_setup(1200); //   VirtualWire
  vw_set_tx_pin(10);   //   VirtualWire D10
. . . . .
}

Analisaremos os princípios da geração de dados usando um exemplo específico. Vamos ter um sensor remoto de temperatura e umidade. Fornece valores (variáveis ​​de temperatura e umidade) na forma de um número real com um sinal (float). Para facilitar a compreensão no final de recebimento, todos reduziremos para um número inteiro positivo com o número de casas decimais de pelo menos 4, converteremos os bits individualmente em caracteres ASCII, transferiremos a string resultante e executaremos operações reversas no final de recebimento. Obviamente, você pode simplificar a tarefa (por exemplo, sem conversão para ASCII e encurtar os números), mas dessa forma acaba sendo o mesmo para quase todos os tipos de dados digitais, o que simplifica a desmontagem ao receber.

Na prática, é conveniente usar o tipo String para compor uma mensagem, algo como isto:

. . . . .
//    
#define ledPin 13 //  (D13,  19 ATmega) 
char msg[13];
volatile int tmpr=0;
volatile int hum=0;
. . . . .
void loop() {
  delay(1000); // 1 c
float temperature;
float humidity;
. . . . .  //   temperature  humidity  
//       4 :
  tmpr = temperature*10+2731; //2731 =     
//    4 :
  hum = humidity*10+1000; 
//  :
  digitalWrite (ledPin,HIGH); //  —  
  String strMsg="DAH"; // - 
  strMsg+=tmpr; //  
  strMsg+=hum; // 
  strMsg.toCharArray(msg,12); //   , 12 –  
//  :
  vw_send((uint8_t *)msg, strlen(msg)); //  
  vw_wait_tx(); //   
  delay(500); // 500 
  digitalWrite (ledPin, LOW); //  —  
}

Se você precisar transferir números mais precisos com um grande número de dígitos, basta aumentar o comprimento da matriz msg. As variáveis ​​globais “voláteis” tmpr e hum são necessárias se você calcular a média de várias leituras, caso contrário, elas também podem ser declaradas locais dentro da função loop (). A mensagem, como você vê, consiste nos valores convertidos de temperatura e umidade, em cadeias ASCII de quatro bytes cada, precedidas por uma cadeia de três caracteres “DAH” (os caracteres podem ser outros da tabela ASCII). Essa é uma assinatura que permitirá que você diferencie essa mensagem entre as possíveis outras enviadas por dispositivos semelhantes. Não negligencie a assinatura, mesmo se você acredita que outros dispositivos próximos a esse intervalo não são esperados, ao mesmo tempo em que serve como uma garantia adicional da integridade dos dados recebidos.

Observe também que, ao converter uma string em uma matriz, você deve especificar um caractere a mais que o comprimento total da mensagem (3 + 4 + 4 = 11), isso leva em consideração o caractere zero que fecha a string. E o tamanho da matriz msg [] deve ser especificado com uma margem e pode ser qualquer, neste caso de 13 a 27 bytes. Ao transferir, ele ainda será enviado exatamente como a função strlen (msg) retornará, ou seja, 11 bytes + um caractere nulo.

Na parte receptora, a matriz resultante de códigos ASCII deverá ser analisada. Mas primeiro você precisa aceitá-lo. Para inicializar a recepção, são executadas as seguintes ações:

#include <VirtualWire.h>
char str[5];     ASCII  
  uint8_t buf [VW_MAX_MESSAGE_LEN];  //    
  uint8_t buflen = VW_MAX_MESSAGE_LEN;  // max   
. . . . .

void setup() {
  vw_set_rx_pin(2); //D2   VirtualWire
  vw_setup(1200); //   VirtualWire
. . . . .
} 

Na verdade, a técnica para analisar uma linha é a seguinte:

void loop() {
  vw_rx_start();  //  
  buflen = VW_MAX_MESSAGE_LEN; //    
 if (vw_have_message()) { // 
 if (vw_get_message(buf, &buflen)) //   
  {
    vw_rx_stop(); //   :
        for (byte i=0; i<3; i++)  //    
                str[i]= buf[i]; // 
                str[3]='\0';
      if ((str[0]=='D')&&(str[1]=='A')&&(str[2]=='H')) {
// ,  
       for (byte i=3;i<7;i++)  //    
                str[i-3]= buf[i]; //    
      int tmpr=atoi(str); //   
      tmpr=tmpr-2731; // 2731,     
. . . . .//    10    float,  
. . . . . //    -
// :
      for (byte i=7;i<11;i++)  //    
                str[i-7]= buf[i]; //    
      int hh = atoi(str); //   
      hh=(hh-1000)/10;
      if (hh>99) hh=99; //   %,  
. . . . . // -
   } //end   DAT
  } //end  
 } // 
} // end loop

Espero que agora você tenha menos perguntas sobre o uso desses dispositivos baratos e fáceis de usar.

All Articles