Базовая передача данных по LoRa

Базовая передача данных по LoRa

Я использовал два комплекта STM32 и UART LoRa-модулей Ebyte 433 МГц для передачи и приёма данных на большое расстояние.
Для этого LoRa-модуля не нужна библиотека: достаточно использовать HAL_UART_Transmit() и HAL_UART_Receive() для передачи и приёма.
При приёме нужно декодировать данные из символов в целые числа.

Производитель по умолчанию задаёт канал, адрес и ключ, поэтому ничего менять не нужно, пока вы не соберёте базовую схему и не сделаете тест дальности.
Модули работают «из коробки». Обязательно используйте два модуля с одинаковым парт-номером.
Модуль E220-400T22D рассчитан на дистанцию до 5 км.
Поскольку я использовал питание 3.3V, мне удалось уверенно получить около 500 м (полкилометра) без прямой видимости, используя мощность около 25 мВт.

Недорогие модули можно купить на Али или Озоне по этому я не буду приводить ссылки тут

Для тестов в помещении антенна не нужна.
Если вы не используете антенны, рекомендуется каждые несколько часов выключать питание на несколько минут, чтобы модуль остыл.
Причина в том, что при отсутствии антенны ВЧ-мощность возвращается обратно в модуль, что вызывает нагрев.

Хотя эти модули могут одновременно передавать и принимать, для простоты я использовал один модуль только как передатчик, а второй — только как приёмник.
Вы можете доработать схему, чтобы реализовать обратную передачу (например, подтверждение приёма).
В качестве источника данных я использовал потенциометр.
Вы можете передавать данные с любых датчиков или любые другие значения.
Принятые данные можно сохранять в базу данных или управлять нагрузкой через MOSFET/реле.

Что нужно заранее

Этот проект предполагает, что у вас уже установлены STM32CubeIDE и OpenOCD.
Также подразумевается, что вы уже делали простую прошивку мигания светодиодом на плате Blue Pill в STM32CubeIDE.


Перейдём к программной части.

Модуль-передатчик (Transmitter)

Схема: (вставьте изображение передатчика сюда)

Настройки STM32CubeIDE

  • Включите USART1 (Asynchronous)
  • Parameter Settings → Basic Parameters → Baud rate = 9600
  • ADC1 — IN9 (поставьте галочку)
  • Parameter Settings → ADC Settings → Continuous Conversion Mode (Enabled)
// Дополнительный код передатчика поверх кода, сгенерированного STM32CubeIDE

/* USER CODE BEGIN 0 */
uint16_t readValue;
uint8_t charToTransmit[1];
/* USER CODE END 0 */

  /* USER CODE BEGIN 2 */
  HAL_ADC_Start(&hadc1);
  /* USER CODE END 2 */

 /* USER CODE BEGIN WHILE */
  while (1)
  {
      HAL_ADC_PollForConversion(&hadc1, 1000);
      readValue = HAL_ADC_GetValue(&hadc1);

      // Делим на 800, чтобы преобразовать диапазон 0~4095 в 0~5
      // Прибавляем 48, чтобы преобразовать число 0~5 в символ '0' ~ '5'
      charToTransmit[0] = readValue / 800 + 48;

      HAL_UART_Transmit(&huart1, charToTransmit, 1, 100);
      HAL_Delay(500);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

Модуль-приёмник (Receiver)

Схема: (вставьте изображение приёмника сюда)

Настройки STM32CubeIDE

  • Включите USART1 (Asynchronous)
  • Parameter Settings → Basic Parameters → Baud rate = 9600
  • Настройте PA1, PA3, PA5, PA7 и PB1 как GPIO_Output
// Дополнительный код приёмника поверх кода, сгенерированного STM32CubeIDE

/* USER CODE BEGIN 0 */
uint8_t receivedData[1];
/* USER CODE END 0 */

  /* USER CODE BEGIN WHILE */
  while (1)
  {
      HAL_UART_Receive(&huart1, receivedData, 1, 100);

      if (receivedData[0] == '0') {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, 0);
      }
      else if (receivedData[0] == '1') {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 1);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, 0);
      }
      else if (receivedData[0] == '2') {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, 1);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, 0);
      }
      else if (receivedData[0] == '3') {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, 0);
      }
      else if (receivedData[0] == '4') {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 1);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, 0);
      }
      else if (receivedData[0] == '5') {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, 0);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, 1);
      }

      HAL_Delay(100);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

Расширенная настройка (необязательно)

Для данного модуля:

  • Address: 0 ~ 65535
  • Channel: 0 ~ 83
  • Key: 0 ~ 65535

Вы можете задавать различные комбинации адресов и ключей, чтобы повысить безопасность передачи.
Дополнительно можно использовать шифрование данных и/или контрольную сумму (checksum).