STM32 - приёмник 433 МГц





Библиотека для приёма и расшифровки сигналов от брелков работающих на частоте 433 МГц.


Для работы потребуется супергетеродинный приемник, например RXB6, вот такой…


Без антенны будет принимать метров с 10-15. Если прикрутить вот такую антенну (на али стоит 3 копейки)


… тогда будет принимать метров 50, ну а если использовать что-то подороже, то и вовсе метров на 250 будет работать.


Приёмник конечно можно использовать и попроще, типа такого…


… но приём будет хуже.


И вот такой брелок с плавающим кодом…


На али ищется как SMG-002, а стоит два доллара. Наверно и другие брелки будут работать.


Подключается всё просто, +5в, «земля», и вывод «DATA» (соединяется с каким-нибудь из пинов толлерантных к пяти вольтам, настроенным как внешнее прерывание). Вывод «DER» — это что-то связанное с измерением уровня сигнала, я не подключал. «ANT» — антенна.



Перейдём к настройкам:

В Кубе настраиваем какой-нибудь пин (у меня это будет PA15, к нему будет подключён вывод «DATA») на внешнее прерывание GPIO_EXTIx…


GPIO mode ⇨ Rising/Falling


И включаем прерывание…




В проект подключаем файлы rxb6.c и rxb6.h из скаченной библиотеки.

В main.c инклюдим заголовок…

/* USER CODE BEGIN Includes */
#include "rxb6.h"

#include "string.h"
#include "stdio.h"
/* USER CODE END Includes */



Объявляем глобальные переменные…

/* USER CODE BEGIN PV */
volatile uint8_t hcs_listening = 0;

extern uint8_t BitArray[SIZE_ARRAY];
extern uint8_t Repeat;
extern uint8_t BatteryLow;
//extern uint8_t Btn2;
//extern uint8_t Btn1;
//extern uint8_t Btn0;
//extern uint8_t Btn3;
extern uint32_t SerialNum;
extern uint32_t Encrypt;
extern uint8_t Button;
/* USER CODE END PV */



Добавляем колбек прерывания, вызывающий функцию обработки сигнала…

/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == SIGNAL_PIN)
	{
		RX433_Int();
	}
}
/* USER CODE END 0 */



Программа использует счётчик DWT для измерения времени в микросекундах, поэтому перед бесконечным циклом инициализируем его…

/* USER CODE BEGIN 2 */
DWT_Init();
  
HAL_UART_Transmit(&huart1, (uint8_t*)"START 433\n", 10, 1000);
/* USER CODE END 2 */

Код для счётчика встроен в rxb6.h.


Если вы выбрали другой пин для приёма сигнала, тогда измените его в файле rxb6.h

#define SIGNAL_PORT    GPIOA          // ваш порт
#define SIGNAL_PIN     GPIO_PIN_15    // ваш пин



В бесконечном цикле проверяем появился ли пакет и расшифровываем его…

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  //////////////////////////////// ЧТЕНИЕ ДАННЫХ ////////////////////////////////
	  if(hcs_listening == 1) // пришёл пакет
	  {
		  char sim = ' ';

		  switch(Button)
		  {
			  case 2:
				  sim = 'A';
			  break;

			  case 4:
				  sim = 'B';
			  break;

			  case 8:
				  sim = 'C';
			  break;

			  case 1:
				  sim = 'D';
			  break;

			  default:
			  break;
		  }

		  char str[64] = {0,};
		  snprintf(str, 64, "SN: 0x%lX, Cript: 0x%lX, Butt: %c, LowBat: %d, Rep: %d\n", SerialNum, Encrypt, sim, BatteryLow, Repeat);
		  HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), 1000);

		  memset(BitArray, 0x00, SIZE_ARRAY);
		  SerialNum = 0;
		  Encrypt = 0;
		  BatteryLow = 0;
		  Button = 0;
		  Repeat = 0;

		  hcs_listening = 0;

		  __HAL_GPIO_EXTI_CLEAR_IT(SIGNAL_PIN);  // очищаем бит EXTI_PR
		  NVIC_ClearPendingIRQ(EXTI15_10_IRQn); // очищаем бит NVIC_ICPRx
		  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);   // включаем прерывания 433
	  }
	  
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }


Если пакет пришёл, то определяется серийный номер брелка (на коробочке написан), плавающий код, какая именно кнопка нажата, уровень заряда батарейки в брелке (если 0, то всё нормально, если 1, то батарейку пора менять), и последнее это Repeat (если 0, то это новый сигнал, если 1, то это повтор предыдущего).




Этот приёмник постоянно сыплет прерываниями (ловит всякий шум, избавиться от этого нельзя) поэтому держите это в голове при проектировании программ. В функции RX433_Int() сделано так, что когда пакет получен, то прерывание отключается, а включается обратно в бесконечном цикле после чтения пакета.


Суть работы библиотеки очень простая: при каждом прерывании (импульсе) она измеряет время между этими импульсами, и если длина этих импульсов укладывается в диапазон определённый протоколом передачи, тогда считается что это действительно полезный пакет, а не шум. Пакет представляет из себя десять нулей идущих подряд, это расценивается как преамбула (по ней определяется что сейчас пойдут полезные данные), а следом идут 66 бит, которые и несут в себе нужную информацию.


Это всё, всем спасибо


Телеграм-чат istarik

Телеграм-чат STM32


  • 0
  • 17065
Поддержать автора


Telegram-чат istarik

Задать вопрос по статье
Telegram-канал istarik

Известит Вас о новых публикациях






Комментарии (0)

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.