Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Создание надежных дальнобойных сетей Arduino с модулем HC-12

В этом уроке Arduino мы научимся использовать модуль беспроводной последовательной связи HC-12, способный обеспечивать дальнобойную беспроводную связь между несколькими платами Arduino на расстоянии до 1,8 км. Вы можете посмотреть следующее видео или прочитать письменное руководство ниже для получения более подробной информации.

Обзор

Для этого урока я подготовил два базовых примера, объясняющих, как подключить модуль HC-12 и организовать базовую связь между двумя Arduino, а также дополнительный пример, в котором с помощью акселерометра на первой Arduino осуществляется беспроводное управление положением шагового двигателя на второй Arduino.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Модуль беспроводной связи HC-12

Сначала рассмотрим модуль беспроводного последовательного порта HC-12 подробнее. Вот его основные характеристики:

  • Рабочий частотный диапазон: от 433,4 МГц до 473,0 МГц
  • Всего 100 каналов с шагом 400 кГц между каждым каналом
  • Мощность передачи: от -1 дБм (0,79 мВт) до 20 дБм (100 мВт)
  • Чувствительность приема: от -117 дБм (0,019 пВт) до -100 дБм (10 пВт)

Эти значения зависят от выбранных скоростей передачи по последовательному порту и по воздуху, как показано в таблице.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Модуль HC-12 имеет встроенный микроконтроллер, который не требует программирования пользователем. Для настройки модуля используются AT-команды, которые можно отправлять с Arduino, ПК или любого другого микроконтроллера через последовательный порт. Для входа в режим AT-команд достаточно установить на выводе «Set» низкий логический уровень.

Arduino и HC-12

Теперь подключим модуль HC-12 к Arduino и разберем первый пример. Вот схема подключения. Напряжение питания модуля составляет от 3,2 В до 5,5 В, для более стабильной работы рекомендуется использовать развязывающий конденсатор и внешнее питание. Однако я использовал питание от USB ПК для всех трех примеров в этом уроке и не имел никаких проблем.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Я подключил первый модуль к Arduino UNO, а второй — к Arduino MEGA, но بالطبع можно использовать любые платы.

Компоненты, необходимые для этого урока, можно найти по ссылкам ниже:

  • Модуль беспроводной связи HC-12 ………..
  • Плата Arduino ………………………………………………
  • Безпаечная макетная плата и перемычки …………………………

Пример 01 — Код Arduino


Ниже приведен код Arduino для первого примера — базовой связи между двумя модулями с использованием монитора последовательного порта.

/* Arduino Long Range Wireless Communication using HC-12 Example 01 by Dejan Nedelkovski, www.HowToMechatronics.com */
#include <SoftwareSerial.h>
SoftwareSerial HC12(10, 11); // TX Pin HC-12, RX Pin HC-12
void setup() {
  Serial.begin(9600); // Последовательный порт к компьютеру
  HC12.begin(9600);   // Последовательный порт к HC12
}
void loop() {
  while (HC12.available()) { // Если HC-12 имеет данные
    Serial.write(HC12.read()); // Отправляем данные в монитор последовательного порта
  }
  while (Serial.available()) { // Если монитор последовательного порта имеет данные
    HC12.write(Serial.read()); // Отправляем эти данные в HC-12
  }
}Язык кода: Arduino (arduino)

Один и тот же код используется для обеих Arduino. Мы можем подключить две Arduino к двум разным компьютерам, но также можно использовать один компьютер.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

В этом случае, после подключения первой Arduino к компьютеру, нужно выбрать модель и COM-порт, загрузить код в Arduino. Затем подключаем вторую Arduino и снова запускаем Arduino IDE, чтобы выбрать другой COM-порт, к которому подключена вторая Arduino, и загрузить тот же код.

После запуска двух экземпляров Arduino IDE можно открыть мониторы последовательного порта и проверить, работает ли связь правильно. Все, что мы вводим в мониторе последовательного порта, будет отправлено с одной Arduino на другую.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Как работает код: Когда мы вводим что-то в мониторе последовательного порта и нажимаем кнопку отправки, на первой Arduino цикл while с функцией Serial.available() становится истинным, и с помощью функции HC12.write() мы отправляем данные из монитора последовательного порта в модуль HC-12. Этот модуль передает данные беспроводно второму модулю HC-12, поэтому на второй Arduino цикл while с функцией HC12.available() становится истинным, и с помощью функции Serial.write() данные отправляются в монитор последовательного порта.

Этот же код можно использовать для отправки AT-команд и настройки параметров модуля. Для этого достаточно подключить вывод «Set» модуля к земле или к любому цифровому выводу Arduino и установить на нем низкий логический уровень.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Чтобы проверить, успешно ли мы вошли в режим, в мониторе последовательного порта можно ввести «AT» и мы должны получить ответное сообщение «OK». Всего 12 AT-команд, они используются для изменения различных параметров, таких как скорость передачи, канал, мощность передачи и т.д. Например, если ввести «AT+B38400», скорость передачи модуля будет установлена на 38400.

AT-команды:

1. AT — тестовая команда.

Пример: отправка «AT» модулю, модуль возвращает «OK».

2. AT+Bxxxx — изменение скорости последовательного порта.

Доступные скорости: 1200 бод, 2400 бод, 4800 бод, 9600 бод, 19200 бод, 38400 бод, 57600 бод и 115200 бод. По умолчанию: 9600 бод.

Пример: отправка «AT+B38400» модулю, модуль возвращает «OK+B19200».

3. AT+Cxxxx — изменение канала беспроводной связи, от 001 до 100.

По умолчанию: канал 001, рабочая частота 433,4 МГц. Каждый следующий канал на 400 кГц выше.

Пример: если мы хотим установить модуль на канал 006, нужно отправить команду «AT+C006», модуль вернет «OK+C006». Новая рабочая частота будет 435,4 МГц.

Пример 02


Теперь перейдем ко второму примеру. Здесь мы используем две кнопки для выбора разных каналов связи и рассмотрим другой метод хранения входящих данных.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Примечание: выводы «Set» обоих модулей HC-12 подключены к выводам №6 двух Arduino, а две кнопки на первой Arduino — к выводам 4 и 3.

Код для первой Arduino:

/* Arduino Long Range Wireless Communication using HC-12 Example 02 - Changing channels using push buttons - Buttons side by Dejan Nedelkovski, www.HowToMechatronics.com */
#include <SoftwareSerial.h>
#define setPin 6
#define button1 4
#define button2 3
SoftwareSerial HC12(10, 11); // TX Pin HC-12, RX Pin HC-12
byte incomingByte;
String readBuffer = "";
int button1State = 0;
int button1Pressed = 0;
int button2State = 0;
int button2Pressed = 0;
void setup() {
  Serial.begin(9600);
  HC12.begin(9600);
  pinMode(setPin, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  digitalWrite(setPin, HIGH); // HC-12 нормальный, прозрачный режим
}
void loop() {
  // ==== Сохранение входящих данных в строковую переменную
  while (HC12.available()) {
    incomingByte = HC12.read();
    readBuffer += char(incomingByte);
  }
  delay(100);
  // ==== Отправка данных с одного HC-12 на другой через монитор последовательного порта
  while (Serial.available()) {
    HC12.write(Serial.read());
  }
  // ==== Если нажата кнопка 1, установить канал 01
  button1State = digitalRead(button1);
  if (button1State == HIGH & button1Pressed == LOW) {
    button1Pressed = HIGH;
    delay(20);
  }
  if (button1Pressed == HIGH) {
    HC12.print("AT+C001");
    delay(100);
    digitalWrite(setPin, LOW);
    delay(100);
    HC12.print("AT+C001");
    delay(200);
    while (HC12.available()) {
      Serial.write(HC12.read());
    }
    Serial.println("Channel successfully changed");
    digitalWrite(setPin, HIGH);
    button1Pressed = LOW;
  }
  // ==== Если нажата кнопка 2, установить канал 02
  button2State = digitalRead(button2);
  if (button2State == HIGH & button2Pressed == LOW) {
    button2Pressed = HIGH;
    delay(100);
  }
  if (button2Pressed == HIGH) {
    HC12.print("AT+C002");
    delay(100);
    digitalWrite(setPin, LOW);
    delay(100);
    HC12.print("AT+C002");
    delay(200);
    while (HC12.available()) {
      Serial.write(HC12.read());
    }
    Serial.println("Channel successfully changed");
    digitalWrite(setPin, HIGH);
    button2Pressed = LOW;
  }
  checkATCommand();
  readBuffer = "";
}
void checkATCommand () {
  if (readBuffer.startsWith("AT")) {
    digitalWrite(setPin, LOW);
    delay(200);
    HC12.print(readBuffer);
    delay(200);
    while (HC12.available()) {
      Serial.write(HC12.read());
    }
    digitalWrite(setPin, HIGH);
  }
}Язык кода: Arduino (arduino)

Код для второй Arduino:

/* Arduino Long Range Wireless Communication using HC-12 Example 02 - Changing channels using push buttons by Dejan Nedelkovski, www.HowToMechatronics.com */
#include <SoftwareSerial.h>
#define setPin 6
SoftwareSerial HC12(10, 11);
byte incomingByte;
String readBuffer = "";
void setup() {
  Serial.begin(9600);
  HC12.begin(9600);
  pinMode(setPin, OUTPUT);
  digitalWrite(setPin, HIGH);
}
void loop() {
  while (HC12.available()) {
    incomingByte = HC12.read();
    readBuffer += char(incomingByte);
  }
  delay(100);
  while (Serial.available()) {
    HC12.write(Serial.read());
  }
  if (readBuffer == "AT+C001") {
    digitalWrite(setPin, LOW);
    delay(100);
    HC12.print(readBuffer);
    delay(200);
    while (HC12.available()) {
      Serial.write(HC12.read());
    }
    Serial.println("Channel successfully changed");
    digitalWrite(setPin, HIGH);
    readBuffer = "";
  }
  if (readBuffer == "AT+C002") {
    digitalWrite(setPin, LOW);
    delay(100);
    HC12.print(readBuffer);
    delay(200);
    while (HC12.available()) {
      Serial.write(HC12.read());
    }
    Serial.println("Channel successfully changed");
    digitalWrite(setPin, HIGH);
    readBuffer = "";
  }
  checkATCommand();
  readBuffer = "";
}
void checkATCommand () {
  if (readBuffer.startsWith("AT")) {
    digitalWrite(setPin, LOW);
    delay(100);
    HC12.print(readBuffer);
    delay(200);
    while (HC12.available()) {
      Serial.write(HC12.read());
    }
    digitalWrite(setPin, HIGH);
  }
}Язык кода: Arduino (arduino)

Описание кодов:

Сначала определяем выводы и устанавливаем вывод «Set» в высокий логический уровень, чтобы модуль работал в нормальном, прозрачном режиме. С помощью первого цикла while мы сохраняем входящие данные в строковую переменную для более удобной обработки.

// ==== Сохранение входящих данных в строковую переменную
while (HC12.available()) {
  incomingByte = HC12.read();
  readBuffer += char(incomingByte);
}Язык кода: Arduino (arduino)

Входящие данные всегда приходят по одному байту. Например, если мы отправляем строку «Test123» со второй Arduino, этот цикл while выполнит 7 итераций. Каждую итерацию, используя функцию HC12.read(), мы считываем каждый входящий байт или символ и добавляем его в строковую переменную «readBuffer».

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Теперь посмотрим, как изменить канал связи с помощью первой кнопки. Если нажать первую кнопку, с помощью функции HC12.print() мы отправим строку «AT+C001» в модуль HC-12 или во вторую Arduino.

if (button1Pressed == HIGH) {
  HC12.print("AT+C001");
  delay(100);
  digitalWrite(setPin, LOW);
  delay(100);
  HC12.print("AT+C001");
  delay(200);
  while (HC12.available()) {
    Serial.write(HC12.read());
  }
  Serial.println("Channel successfully changed");
  digitalWrite(setPin, HIGH);
  button1Pressed = LOW;
}Язык кода: Arduino (arduino)

Когда эта строка будет принята на второй Arduino, мы переведем модуль HC-12 в режим AT-команд, а затем запишем в него ту же строку «AT+C001», что установит модуль на канал связи номер один.

// На второй Arduino
if (readBuffer == "AT+C001") {
  digitalWrite(setPin, LOW);
  delay(100);
  HC12.print(readBuffer);
  delay(200);
  while (HC12.available()) {
    Serial.write(HC12.read());
  }
  Serial.println("Channel successfully changed");
  digitalWrite(setPin, HIGH);
  readBuffer = "";
}Язык кода: Arduino (arduino)

Мы используем следующий цикл while для вывода ответного сообщения от модуля HC-12 о том, успешно ли изменен канал.

while (HC12.available()) {
  Serial.write(HC12.read());
}Язык кода: Arduino (arduino)

Обратно на первой Arduino мы выполняем ту же процедуру отправки AT-команды первому модулю HC-12. Точно так же, нажав вторую кнопку, мы устанавливаем канал связи номер два. Таким образом, с помощью этого метода мы можем в любой момент выбирать, с каким модулем HC-12 будем общаться.

В конце пользовательская функция checkATCommand() проверяет, является ли полученное сообщение AT-командой, проверяя, начинается ли строка с «AT». Если да, модуль входит в режим AT-команд и выполняет команду.

void checkATCommand () {
  if (readBuffer.startsWith("AT")) {
    digitalWrite(setPin, LOW);
    delay(200);
    HC12.print(readBuffer);
    delay(200);
    while (HC12.available()) {
      Serial.write(HC12.read());
    }
    digitalWrite(setPin, HIGH);
  }
}Язык кода: Arduino (arduino)

Беспроводная связь HC-12: управление шаговым двигателем с помощью акселерометра

Теперь рассмотрим третий пример. Здесь мы управляем положением шагового двигателя на второй Arduino, используя модуль акселерометра на первой Arduino.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Схема также содержит микропереключатель для поиска начального положения шагового двигателя в 0 градусов.

Создание надежных дальнобойных сетей Arduino с модулем HC-12

Компоненты, необходимые для этого примера, можно найти по ссылкам ниже:

  • Модуль беспроводной связи HC-12 …………
  • Драйвер шагового двигателя A4988 …………………………..
  • Шаговый двигатель NEMA 17 …………………………………
  • Плата Arduino ………………………………………………..
  • Безпаечная макетная плата и перемычки …………………………..
  • Плата GY-80 с акселерометром ADXL345 ………

Обратите внимание, что у меня уже есть подробные уроки по подключению и использованию как акселерометра, так и шагового двигателя, поэтому для этого примера я объясню только часть кода, относящуюся к HC-12.

Первая Arduino — код передатчика:

/* Arduino Long Range Wireless Communication using HC-12 Example 03 - Stepper Motor Control using Accelerometer - Transmitter, Accelerometer by Dejan Nedelkovski, www.HowToMechatronics.com */
#include <SoftwareSerial.h>
#include <Wire.h>
SoftwareSerial HC12(10, 11);
float angle;
int lastAngle = 0;
int count = 0;
int angleSum = 0;
#define Power_Register 0x2D
#define X_Axis_Register_DATAX0 0x32
#define X_Axis_Register_DATAX1 0x33
#define Y_Axis_Register_DATAY0 0x34
#define Y_Axis_Register_DATAY1 0x35
#define Z_Axis_Register_DATAZ0 0x36
#define Z_Axis_Register_DATAZ1 0x37
int ADXAddress = 0x53;
int X0, X1, X_out;
int Y0, Y1, Y_out;
int Z1, Z0, Z_out;
float Xa, Ya, Za;
void setup() {
  HC12.begin(9600);
  Wire.begin();
  Serial.begin(9600);
  delay(100);
  Wire.beginTransmission(ADXAddress);
  Wire.write(Power_Register);
  Wire.write(8);
  Wire.endTransmission();
}
void loop() {
  Wire.beginTransmission(ADXAddress);
  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress, 2);
  if (Wire.available() <= 2) {
    X1 = Wire.read();
    X1 = X1 << 8;
    X_out = X0 + X1;
    Xa = X_out / 256.0;
  }
  Wire.beginTransmission(ADXAddress);
  Wire.write(Y_Axis_Register_DATAY0);
  Wire.write(Y_Axis_Register_DATAY1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress, 2);
  if (Wire.available() <= 2) {
    Y0 = Wire.read();
    Y1 = Wire.read();
    Y1 = Y1 << 8;
    Y_out = Y0 + Y1;
    Ya = Y_out / 256.0;
  }
  if (Y_out > 0) {
    angle = map(Y_out, 0, 256, 90, 0);
  } else if (Y_out < 0) {
    angle = map(Y_out, 256, 0, 90, 0);
    angle = 90 - angle;
  }
  if (X_out < 0 & Y_out < 0) {
    angle = 180;
  }
  if (X_out < 0 & Y_out >0) {
    angle = 0;
  }
  int angleInt = int(angle);
  angleSum = angleSum + angleInt;
  count++;
  if (count >= 100) {
    angleInt = angleSum / 100;
    angleSum = 0;
    count = 0;
    if (angleInt > lastAngle + 2 || angleInt < lastAngle - 2) {
      Serial.println(angleInt);
      String angleString = String(angleInt);
      HC12.print("s" + angleString + "e");
      delay(10);
      lastAngle = angleInt;
      angleSum = 0;
      count = 0;
    }
  }
}Язык кода: Arduino (arduino)

Вторая Arduino — код приемника:

/* Arduino Long Range Wireless Communication using HC-12 Example 03 - Stepper Motor Control using Accelerometer - Receiver, Stepper Motor by Dejan Nedelkovski, www.HowToMechatronics.com */
#include <SoftwareSerial.h>
SoftwareSerial HC12(10, 11);
char incomingByte;
String readBuffer = "";
const int dirPin = 4;
const int stepPin = 3;
const int button = 2;
int currentAngle = 0;
int lastAngle = 0;
int rotate = 0;
void setup() {
  Serial.begin(9600);
  HC12.begin(9600);
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  delay(10);
  digitalWrite(dirPin, HIGH);
  boolean startingPosition = true;
  while (startingPosition) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(200);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(200);
    if (digitalRead(button) == LOW) {
      startingPosition = false;
    }
  }
  delay(100);
}
void loop() {
  readBuffer = "";
  boolean start = false;
  while (HC12.available()) {
    incomingByte = HC12.read();
    delay(5);
    if (start == true) {
      if (incomingByte != 'e') {
        readBuffer += char(incomingByte);
      } else {
        start = false;
      }
    } else if (incomingByte == 's') {
      start = true;
    }
  }
  currentAngle = readBuffer.toInt();
  if (currentAngle > 0 && currentAngle < 180) {
    currentAngle = map(currentAngle, 0, 180, 0, 1600);
    digitalWrite(dirPin, LOW);
    if (currentAngle != lastAngle) {
      if (currentAngle > lastAngle) {
        rotate = currentAngle - lastAngle;
        for (int x = 0; x < rotate; x++) {
          digitalWrite(stepPin, HIGH);
          delayMicroseconds(400);
          digitalWrite(stepPin, LOW);
          delayMicroseconds(400);
        }
      }
      if (currentAngle < lastAngle) {
        rotate = lastAngle - currentAngle;
        digitalWrite(dirPin, HIGH);
        for (int x = 0; x < rotate; x++) {
          digitalWrite(stepPin, HIGH);
          delayMicroseconds(400);
          digitalWrite(stepPin, LOW);
          delayMicroseconds(400);
        }
      }
    }
    lastAngle = currentAngle;
  }
}Язык кода: Arduino (arduino)

Описание кодов:

Сначала определяем выводы и инициализируем модули в разделе setup. Затем считываем значения осей X и Y акселерометра и преобразуем их в значения от 0 до 180 градусов. Значения от акселерометра могут быть нестабильными, поэтому для сглаживания результата я использовал среднее значение из ста считываний.

angleSum = angleSum + angleInt;
count++;
if (count >= 100) {
  angleInt = angleSum / 100;
  angleSum = 0;
  count = 0;
  if (angleInt > lastAngle + 2 || angleInt < lastAngle - 2) {
    Serial.println(angleInt);
    String angleString = String(angleInt);
    HC12.print("s" + angleString + "e");
    delay(10);
    lastAngle = angleInt;
    angleSum = 0;
    count = 0;
  }
}Язык кода: Arduino (arduino)

Для еще большего сглаживания я отправляю новое значение угла только если оно отличается от предыдущего на 2.

Обратите внимание: при отправке угла в модуль HC-12 я также отправляю символ «s» в начале и символ «e» в конце, что помогает при приеме данных на второй Arduino.

На второй Arduino мы ждем, пока придет стартовый маркер «s», затем считываем значение угла до появления конечного маркера «e». Таким образом мы уверены, что получим только значение угла.

while (HC12.available()) {
  incomingByte = HC12.read();
  delay(5);
  if (start == true) {
    if (incomingByte != 'e') {
      readBuffer += char(incomingByte);
    } else {
      start = false;
    }
  } else if (incomingByte == 's') {
    start = true;
  }
}Язык кода: Arduino (arduino)

Затем преобразуем значение в целое число и сопоставляем значение от 0 до 1600 шагов, что соответствует выбранному шестнадцатеричному разрешению шага драйвера A4988. Затем поворачиваем шаговый двигатель на текущий угол.

Это всё для этого урока Arduino. Не стесняйтесь задавать любые вопросы в разделе комментариев ниже.


Производственный процесс

  1. Мастерство дальности беспроводной связи: как мощность, скорость данных и интерференции формируют связность
  2. Как батарейные дальнодействующие беспроводные сети трансформируют связь
  3. Создание анимации и игр на LCD 16×2 с Arduino UNO
  4. JX Wave Generator — Генератор сигналов на Arduino с DDS AD9833 и OLED-дисплеем
  5. Модуль GPS u-blox LEA-6H 02: Интеграция с Arduino и Python
  6. Беспроводной ИК-термометр на Arduino Nano с Bluetooth и MLX90614
  7. Управление Arduino Uno из Python 3: команды через последовательный порт и демонстрация с LED
  8. Сборка компактного FM-радио на Arduino Nano и RDA5807M
  9. Продвинутая система обнаружения падений: Arduino + Windows IoT + Azure Cloud
  10. ArduRadio: DIY-будильник с FM-радио на Arduino