Связь двух микроконтроллеров AVR ATmega8 через радиочастотный модуль

Беспроводная связь может значительно расширить возможности микроконтроллеров по управлению какими либо процессами, поэтому изучение взаимодействия микроконтроллеров с радиочастотными модуля является весьма актуальной задачей для специалистов в этой области. В самом простом случае беспроводная связь на короткие расстояния организуется с помощью светодиодов, работающих в инфракрасном диапазоне, в более сложных случаях возможно использование ESP8266 для контроля по HTTP протоколу, но есть много и других возможностей по организации беспроводной связи. В данной статье мы рассмотрим вариант организации беспроводной связи между двумя микроконтроллерами ATmega8 (семейство AVR) с помощью радиочастотных модулей, работающих на частоте 433 МГц.

Связь двух микроконтроллеров AVR ATmega8 через радиочастотный модуль: внешний вид

В этом проекте мы рассмотрим следующие вещи:

  1. Мы будем использовать микроконтроллеры ATmega8 для управления радиочастотными модулями на стороне передачи и на стороне приема.
  2. Для старта передачи данных мы будем нажимать кнопку на стороне передачи, а после успешного приема данных мы будем зажигать светодиод.
  3. Мы будем использовать кодер и декодер на интегральной схеме чтобы передавать 4 битные данные.
  4. Мы будем использовать дешевые радиочастотные модули, работающие на частоте 433 МГц, которые можно легко купить в магазине.

Необходимые компоненты

Аппаратное обеспечение

Микроконтроллер ATmega8 (2 шт.)
Источник питания с напряжением 5 Вольт
Программатор AVR-ISP, USBASP или другой подобный
10-пиновый FRC кабель
Макетная плата (2 шт.)
Светодиод (2 шт.)
Кнопка
Микросхемы HT12D и HT12E
Радиочастотный модуль (передающая и приемная часть)
Резисторы 10 кОм, 47 кОм, 1 Мом
Соединительные провода

Программное обеспечение

CodeVisionAVR (или другое подобное, например, Atmel Studio)
SinaProg – для загрузки программы в микроконтроллер ATmega8 с помощью программатора USBASP

Скачать CodeVisionAVR — http://www.hpinfotech.ro/cvavr_download.html.

Общие принципы работы радиочастотных модулей на 433 МГц

Внешний вид передающей и приемной части радиочастотного модуля на 433 МГц

Это самые дешевые из существующих передающие и приемные модули, работающие на частоте 433 МГц. Эти модули передают/принимают данные в последовательном виде по одному радиоканалу.

В спецификации на эти модули указано, что передатчик работает при входном напряжении 3.5-12В и способен передавать данные на дистанцию 20-200 метров. Он использует амплитудную модуляцию (АМ) на частоте 433 МГц. С его помощью можно передавать данные со скоростью 4 Кбит/с с выходной мощностью 10 мВт.

Внешний вид передающей части радиочастотного модуля на 433 МГц

На рисунке выше представлена распиновка контактов передающего модуля. Слева направо мы видим такие контакты как VCC (питание), DATA (данные) and GND (земля). Мы также можем добавить антенну и присоединить (припаять) ее к точке крепления, обозначенной на рисунке.

Приемный модуль работает при напряжении питания 5В и имеет ток покоя 4 мА. Частота приема — 433.92 МГц, чувствительность – минус 105 дБ.

Внешний вид приемной части радиочастотного модуля на 433 МГц

На представленном рисунке можно увидеть распиновку контактов приемного модуля. Слева направо это такие контакты как VCC, DATA, DATA and GND. Средние два контакта (DATA) соединены внутри. Можно использовать только один из этих контактов или сразу два. Но лучше использовать сразу два чтобы уменьшить уровень шумов.

Катушка переменной индуктивности в центре модуля в центре приемного модуля используется для подстройки частоты. Если мы не можем принимать данные это может быть следствием того, что частоты передатчика и приемника не совпадают. Поэтому мы можем изменять частоту настройки приемника чтобы добиться полного соответствия частот. Также как и на передающем модуле, на приемном модуле есть точка для крепления антенны – мы можем прикрепить туда внешнюю антенну чтобы увеличить дальность связи.

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

Работа схемы

Схема для передающей стороны приведена на следующем рисунке.

Схема соединений микроконтроллера AVR ATmega8 с передающей частью радиочастотного модуля

В схеме необходимо сделать следующие соединения:

  • Pin D7 of atmega8 -> Pin13 HT12E.
  • Pin D6 of atmega8 -> Pin12 HT12E.
  • Pin D5 of atmega8 -> Pin11 HT12E.
  • Pin D4 of atmega8 -> Pin10 HT12E.
  • Кнопка to Pin B0 of Atmega.
  • Резистор 1 МОм между pin15 и 16 of HT12E.
  • Pin17 of HT12E к контакту данных передающего модуля.
  • Pin 18 of HT12E to 5V.
  • GND pin 1-9 and Pin 14 of HT12E and Pin 8 of Atmega.

Схема для приемной стороны приведена на следующем рисунке.

Схема соединений микроконтроллера AVR ATmega8 с приемной частью радиочастотного модуля

В схеме необходимо сделать следующие соединения:

  • Pin D7 of atmega8 -> Pin13 HT12D.
  • Pin D6 of atmega8 -> Pin12 HT12D.
  • Pin D5 of atmega8 -> Pin11 HT12D.
  • Pin D4 of atmega8 -> Pin10 HT12d.
  • LED to Pin B0 of Atmega.
  • Pin14 of HT12D к контакту данных приемного модуля.
  • Резистор 47 кОм между pin15 и 16 of HT12D.
  • GND pin 1-9 of HT12D and Pin 8 of Atmega.
  • Светодиод к pin 17 of HT12D.
  • 5V to pin 7 of Atmega and pin 18 of HT12D.

Общий вид конструкции приведен на следующем рисунке:

Схема для связи двух микроконтроллеров AVR ATmega8 через радиочастотный модуль

Создание проекта для Atmega8 в программной среде CodeVision

Необходимо выполнить следующую последовательность действий.

Шаг 1. Создайте новый проект в CodeVision, выбрав пункт меню File -> New -> Project. В появившемся диалогом окне нажмите Yes.

Создание нового проекта в CodeVision

Шаг 2. Откроется CodeWizard. Кликните в ней на первой опции, то есть AT90, затем нажмите OK.

Выбор первой опции в CodeVision

Шаг 3. Выберите свой микроконтроллер, в нашем случае им будет Atmega8.

Выбор модели микроконтроллера в CodeVision

Шаг 4. Кликните на Ports (порты). В нашем проекте на передающей стороне мы будем подсоединять кнопку на вход и 4 линии будем использовать на выход. То есть мы должны сконфигурировать 4 контакта Atmega8 на выход. Кликните на Port D, сконфигурируйте в нем биты 7, 6, 5 и 4 на выход.

Конфигурирование нужных нам портов

Шаг 5. Выберите Program -> Generate, Save and Exit. Теперь более половины вашей работы по программированию микроконтроллера Atmega8 можно считать выполненной.

Выбор опций сохранения в CodeVision

Шаг 6. Создайте новую папку на рабочем столе чтобы записывать туда наши файлы.

Выбор директория для сохранения проекта

У нас будет 3 диалоговых окна (будут появляться последовательно одно за другим) для сохранения наших файлов.

Сделайте то же самое (что и на представленном рисунке) с двумя другими диалоговыми окнами – то есть сохраните предлагаемые ими файлы.

После этого рабочая область программы будет выглядеть примерно следующим образом:

Фрагмент кода программы в CodeVision

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

Для приемной стороны повторите рассмотренные шаги, отличие будет состоять только в том, чтобы сконфигурировать контакт B0 PortB на выход потому что мы будем подключать к нему светодиод.

Пояснение части кода программы

Мы напишем программу для включения/выключения светодиода удаленно, использую связь через радиочастотные модули. В этой части статьи мы рассмотрим лишь ключевые особенности кода программы, текст всей программы будет приведен в конце статьи.

Код для передающей части

Первым делом подключите заголовочный файл delay.h чтобы использовать функции задержки в программе.

#include <io.h>
#include <delay.h>
void main(void)
{

Теперь рассмотрим главный цикл в конце тела программы. В этом цикле While мы будем передавать 0x10 байт на PORTD когда кнопка нажата и байт 0x20 когда кнопка не нажата. Можно использовать любые другие значения – но их необходимо будет изменить и на приемном конце.

while (1)
{
if(PINB.0 == 1) {
PORTD = 0x10;
}
if(PINB.0 == 0) {
PORTD = 0x20;
}
}
}

Код для приемной части

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

#include <io.h>
#include <stdio.h>
#include <delay.h>
unsigned char byte = 0;
void main(void)
{

Теперь рассмотрим главный цикл в конце программы. В этом цикле мы будем хранить принимаемые байты в переменной символьного типа (char) и сравнивать их с теми, которые мы передавали на передающей стороне. Если результат сравнения положительный, то мы в соответствии с их значениями будем включать/выключать светодиод, подключенный к PORTB.0.

while (1)
{
byte = PIND;
if(PIND.7==0 && PIND.6==0 && PIND.5==0 && PIND.4==1)
{
PORTB.0 = ~PORTB.0;
delay_ms(1000);
}
}
}

Компоновка проекта

Наш код закончен. Теперь нам необходимо скомпоновать (Build) наш проект. Для этого нажмите на кнопке Build как показано на рисунке.

Компоновка проекта

После компоновки проекта соответствующий HEX файл будет помещен в папку Debug-> Exe, которую можно найти в папке, которую вы создавали ранее для хранения проекта. Мы будем использовать этот HEX файл для загрузки в Atmega8 используя программу Sinaprog (можно использовать любую другую аналогичную программу, с которой вы привыкли работать).

Загрузка программы в Atmega8 с использованием Sinaprog

Подсоедините один конец FRC кабеля к программатору USBASP, а другой конец к контактам SPI микроконтроллера.

Схема соединений для FRC кабеля

Необходимо сделать следующие соединения:
1. Pin1 of FRC female connector -> Pin 17, MOSI of Atmega8
2. Pin 2 connected to Vcc of atmega8 i.e. Pin 7
3. Pin 5 connected to Reset of atmega8 i.e. Pin 1
4. Pin 7 connected to SCK of atmega8 i.e. Pin 19
5. Pin 9 connected to MISO of atmega8 i.e. Pin 18
6. Pin 8 connected to GND of atmega8 i.e. Pin 8

Соедините оставшиеся компоненты как показано на вышеприведенном рисунке макетной платы.

Мы будем загружать в микроконтроллер ранее сгенерированный Hex файл используя программу Sinaprog, поэтому мы должны открыть ее и выбрать в ней Atmega8 в выпадающем меню устройства (Device). Выберите HEX файл из папки Debug->Exe как показано на рисунке.

Выбор файла в Sinaprog

Теперь кликните на Program.

Запуск программирования микроконтроллера в Sinaprog

Ваш микроконтроллер запрограммирован. Повторите эти же самые шаги и для приемной части.

Исходный код программы на языке С (Си)

Программа для передающей части

#include <io.h>
#include <delay.h>
void main(void)
{
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// инициализация Port C
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
// инициализация Port D
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(1<<DDD7) | (1<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
while (1)
{
if(PINB.0 == 1) {
PORTD = 0x10;
}
if(PINB.0 == 0) {
PORTD = 0x20;
}
}
}

Программа для приемной части

#include <io.h>
#include <delay.h>
// объявляем глобальные переменные
unsigned char byte = 0;
unsigned char lightON = 0;//статус света
int LED_status = 0;
void main(void)
{
// инициализация Port B
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=Out Bit0=Out
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=0 Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// инициализация Port D
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
while (1)
{
byte = PIND;
if(PIND.7==0 && PIND.6==0 && PIND.5==0 && PIND.4==1 && LED_status==0)
{
PORTB.0 = ~PORTB.0;
delay_ms(1000);
}
}
}

Видео, демонстрирующее работу схемы



Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *