понедельник, 3 октября 2011 г.

Немного про радиоуправление

Какие слова впервые прозвучали в радиоэфире?
- Генрих Герц - отдыхает.

Сейчас речь пойдет не об управлении по сети чьим нибуль компьютером, а об управлении исполняющим механизмом (исполнителем) удаленно. Например, с использованием радиосвязи.

Для начала зададимся основным вопросом. Это вопрос жизни, вселенной и вообще "Зачем?". Действительно, зачем мы это делаем. Этот вопрос не подрузмевает под собой никаких споров о том, что, дескать, "фигли думать, все уже давно придумано". Мы это делаем затем, что бы уметь потом (то есть в будущем) управлять различными устройствами и не задумаваясь о том "Как должна быть организована передача команды".
Структурная схема канала передачи команды выглядит так:

Пульт управления - средство ввода информации. Вводить ее может человек с помощью, например, клавиатуры. Но она может поступать и с других источников данных.
Генератор команды - создает командную последовательность импульсов. Эта последовательность может быть как последовательной, так и параллельной. Например, мы имеем автомобиль. У него два двигателя - один тяговый, другой - поворотный. Тяговый двигатель имеет 2 состояния (вращается, стоит). Поворотный двигатель имеет 3 состояния (поворот влево, стоп, поворот вправо). Итого - всего 2x3 = 6 состояний. Мы будем создавать цифровое устройство, различающее только дихотомичные сигналы (цифры, биты). Это значит, что наши 6 команд описуемы тремя битами с 2-х командным запасом. Здесь мы назвали командой сборку из 3-х битов. Для последовательной команды все эти три бита должны быть переданы последовательно, то есть в строгой очередности одного за другим. В случае параллельной команды (то есть одновременной передачи как минимум 2-х битов) мы должны выделить две линии передачи данных, эти линии должны быть раздельными физически. Таковыми (из беспроводных) являются разночастотные каналы передачи данных. Частоты еще и кратными не должны оказаться. То есть - например мы передаем одновременно три бита. Это значит, что мы должны иметь три передатчика на различных частотах. Можно и на одной частоте, от одного генератора, но тогда в качестве разделителя каналов связи выступает фазовый сдвиг. На приемном конце (в случае разных частот) стоит несколько частотных фильтров от одной антенны, а в случае фазового сдвига - фазовый фильтр.
Модулятор - модулирует командной последовательностью несущую для передачи через эфир.
Передатчик - передает уже модулированные данные в эфир.
Эфир - место временного пребывания сигнала, используемое для передачи оного в виде энергии от передатчика к приемнику. Ну и хрень же я насобачил тут.
Приемник - принимает из эфира модулированный сигнал.
Демодулятор - извлекает полезную составляющую из модулированного сигнала. Его функция следует уже из самого названия. Скажем только, что модуляцию мы можем применить одну из трех:
  • амплитудную
  • частотную
  • фазовую
Дешифратор команды - по сути это элемент, для создания промежуточной команды, имеющей более удобный вид, чем команда в шифрованном виде.
Управляющее устройство - непосредственно управляющий (например, транзистор).
Исполнительный механизм - то, что воздействует на окружающую среду (например, двигатель).
Подробнее о формировании команды.
Параллельная команда сочетает в себе одновременную передачу данных по нескольким каналам и последовательную передачу данных внутри каждого канала. То есть она основывается на последовательной передаче данных.
Имея, для примера, три бита на указание команды мы получаем в распоряжение целых 8 команд. Для приведенного выше примера с автомобилем мы видим, что пульт управления удобнее сделать в виде двух джойстиков. Поскольку каждый бит имеет свое место, то мы не можем поменять никакие два бита местами (даже если они равны, хотя об этом речь сейчас не идет). Установим следующую последовательность битов - первый бит отвечает за тяговый двигатель, а второй и третий - за поворотный. Таким образом мы получаем всего 1 команду в запасе, да и ту - на поворотные двигатели. Если бы мы просто нумеровали команды, то получили бы двухкомандный запас. Вот возможная схема джойстика с одной степенью свободы для поворотного двигателя.

(На этой схеме все напряжения берутся относительно земли).
Аналогично будет выглядеть схема джойстика тягового двигателя, только на одном переключателе.
Назовем верхний пеерключатель двойстика поворотного двигателя - ПДА, нижний - ПДБ, переключатель тягового двигателя - ТДП.
Можно делать последовательное формирование команды и без микроконтроллера (МК), но схема будет громоздкая. Мы же сейчас рассмотрим формирование команды на примере МК из разряда Atmel AVR. Примем, что ПДА подсоединен к биту 2 порта A, ПДБ - бит 1 порт A, ТДП - бит 0 порта A. Здесь их порядок в порте A совпадает с их порядком в команде. Для нас это несколько... ...удобно! Для вывода последовательной информации мы будем использовать бит 0 порта B. Бит 1 порта B назначим управляющим питанием передатчика. Организуется это совсем несложно. Достаточно одного транзистора.
Для нашего же удобства будем использовать частотную модуляцию.
Предположим, что команды поступают с пульта управления не более чем с частотой f (Гц). Тогда минимальная частота несущей составит
F = 10*f (Гц)
Установим частоту работы МК на Fmcu = 4 МГц. Длительность одного бита мы установим равной двум тактам Это составит
Tb = 2*1/4e6 = 0.0000005 (с)
Отсюда имеем - команда занимает
n*Tb = 0.0000015 (с)
Это дает нам
f = 1/(n*Tb) = 666666,67 Гц = 666.7 кГц
Это соответствует ровно стольким же нажатиям в секунду. Довольно немало. Отсюда
F = f*10 = 6.67 МГц
И это только минимальная частота.
Можно идти наоборот. Требуем частоту ввода команд не более, чем по 3 команды в секунду. Это дает нам
n*Tb = 1/3 = 0.3 с
Соостветственно
Tb = n*Tb/n = 0.1 с
f = 1/(n*Tb) = 3 Гц; F = 10*f = 30 Гц.
Организация передачи данных.  Сначала идет кодовая, синхронизирующая последовательность. Это должны быть такая последовательность, какая не может быть никогда. И не важно почему она не может быть. Главное, что не может. В нашем случае - технически невозможно осуществить поворот одновременно в  две стороны, потому две последовательности 011 и 111 (Да, их две, а не одна. Одна - только при поворотном двигателе). Мы выбираем 111. После нее мы делаем паузу (неважно из чего, желательно из нулей если это критично) для того, что бы схема приемника приготовилась к приему команды. Затем идет сама команда и стоповые биты. В ииоге, получаем такой код для передатчика и приемника. (У приемника входной поток идет через порт C, бит 0, выходной - через порт B, биты 0-2).


--------------- Програма передатчика ---------------
.def r16 = temp
.def r17 = BOut

; Предварительная подготовка - порт А (весь) - на вход.
; порт B (биты 0, 1) - на выход.
ldi temp, 0b00000000
out DDRA, temp
ldi temp, 0b00000011
out DDRB, temp

MainCycle:
     ; Каждый бит будет наблюдаться в течении 4-х тактов.
     ; in temp, PinA

; Выделим команду 111 как служебную. Именно для этого нам и нужен запас команд.
; При передаче, эта команда будет стартовой.
; Передачу этой команды назовем Синхронизацией с приемником.

; Протокол будет выглядеть следующим образом.
; - Синхронизация
; - Промежуток (пауза, нулевые биты) - определиться с ее длительностью
; - Команда
; - Стоповые биты

Synchronize:
     ; Раз
     ldi BOut, 0b00000001
     nop
     nop
     nop
     out PortB, BOut

     ; Два
     ldi BOut, 0b00000001
     nop
     nop
     nop
     out PortB, BOut
     
     ; Три
     ldi BOut, 0b00000001
     nop
     nop
     nop
     out PortB, BOut

     ; Пауза
     ldi BOut, 0b00000000
     nop
     nop
     nop
     nop

     nop
     nop
     nop
     nop
     nop

     ; Первый бит
     ldi BOut, 0b00000000
     ; Эта команда присутствует только на первом бите!!
     in temp, PinA
     or BOut, temp
     andi BOut, 0b0000001
     out PortB, BOut

     ; Второй бит
     ldi BOut, 0b00000000
     lsr temp
     or BOut, temp
     andi BOut, 0b0000001
     out PortB, BOut

     ; Третий бит
     ldi BOut, 0b00000000
     lsr temp
     or BOut, temp
     andi BOut, 0b0000001
     out PortB, BOut

     ; Пауза перед первым битом
     ldi BOut, 0b00000000
     nop
     nop
     nop
     out PortB, BOut

     ; Таким образом - команда состоит из N битов.
     ; Первые три - синхронизирующие единицы
     ; После них пауза в течении k-битов
     ; Затем - три командных бита и последний стоповый
          rjmp MainCycle


--------------- Програма приемника ---------------
.def r16 = temp
.def r17 = CAnd
.def r18 = CSum
.def r19 = BOut
.def r20 = PreCom

; Предварительная подготовка - порт B - биты 0, 1, 2 - на выход.
;                              порт C - бит 0 - на вход.
ldi temp, 0b00000111
out DDRB, temp
ldi temp, 0b00000000
out DDRC, temp

MainCycle:
     CheckSynchro:
     ; Товсь!
          ldi temp, 0b00000000
          ldi CAnd, 0b00000001
     ; Пли!
          in temp, PinC
          and CAnd, temp
          nop
          nop

          in temp, PinC
          and CAnd, temp
          nop
          nop

          in temp, PinC
          and CAnd, temp
          nop
          nop

          nop                 ; 1
          sbrs CAnd, 0        ; 1
          rjmp CheckSynchro   ;    2 при переходе. ИТОГО 1+1+2 = 4 - ровно один бит!
          nop                 ; 1
          nop                 ; 1. Итого 1+1+1+1 = 4

          ldi BOut, 0b00000000
          nop
          nop
          nop

     ; Мы прождали паузу ровно в два бита!

; ---------- Начинаем прием команды ----------
     ; Первый Бит
          in temp, PinC
          or BOut, temp
          lsl BOut
          nop

     ; Второй Бит
          in temp, PinC
          or BOut, temp
          lsl BOut
          nop

     ; Третий Бит
          in temp, PinC
          or BOut, temp
          lsl BOut
     ; Это последний бит! Делаем вывод команды!
          out PortB, BOut
     ; Ожидаем синхронизации Вместе с переходом и первыми двумя командами "Товсь!"
     ; мы получим ровно один стоповый бит. Так что мы просто не успеваем проверить его на стоповость
               rjmp CheckSynchro

     
На этом пока все. Проверку данная програма еще не прошла. Это только макет.

P.S.: Выбран в качестве МК AVR потому, как у него все команды выполняются за 1 такт, а в случае перехода - 2 такта.