Страница 1 из 1

Помогите доработать прошивку

Добавлено: Пн янв 06, 2014 02:11:54
Popeye
Всем привет, и с Новым Годом!!!
При разработке девайса, состоящего из 4 передатчиков и приемника (передача данных через UART), столкнулся с проблемой выполнения задержки при поступлении сигнала на приемник.

В исходнике на приемник я пишу -

while (1)

{
PORTB=getchar();// берем данные из UART, кидаем их в порт B
// (там висят светодиоды, по одному на каждый канал)

if (PINB!=0x00)// Если хотя бы на одной ноге порта В есть "1"

{
PORTA.0=1;//Если пришел код одного из передатчиков,
// зажигаем светодиод на PORTA.0 (далее пищалка)

}
else
{
PORTA.0=0;// иначе не включаем пищалку
}
#asm("wdr")//сброс сторожевого таймера
};
}


В настоящий момент моя прошивка работает так. При поступлении кода от определенного передатчика в приемнике загорается определенный светодиод и одновременно с этим начинает вопить пищалка. Как только прекращается поступление кода - светодиод(ы) тухнет, и пищалка прекращает работать.

Задача - сделать так, чтобы при поступлении кода светодиод(ы) горел(и) еще 15 секунд после того, как код прекратил поступать. Пищалка же должна отключаться сразу по прекращению поступления кода, т.е пищалка должна работать только лишь во время передачи кода.

Как пример - что-то вроде этого:
http://www.youtube.com/watch?v=sueynEpo1YY

Помогите, пожалуйста, новичку :) :beer:[

Re: Помогите доработать прошивку

Добавлено: Пн янв 06, 2014 11:23:37
Alkul
Popeye писал(а):При поступлении кода от определенного передатчика в приемнике загорается определенный светодиод и одновременно с этим начинает вопить пищалка. Как только прекращается поступление кода - светодиод(ы) тухнет, и пищалка прекращает работать.
Что-то я не понял. Некорректно Вы ставите задачу.
Допустим, Вы передаете через UART 1 байт со скоростью 9600 бит/с.
Это значит, что один байт будет передан примерно за 1 миллисекунду. Ваша пищалка должна звучать ровно одну миллисекунду? Вы сможете это услышать? :)) Или Вы там "Войну и мир" в ASCII-кодах передаете по UART? :)

Но это еще не все. Дело в том, что распознать факт приема стартового бита (для включения пищалки в начале приема байта) возможно только в случае, если Вы пользуетесь программной реализацией UART. Если же Вы пользуетесь аппаратным UART, то у Вас нет возможности детектировать начало приема байта. Прочтите даташит на любой AVR-контроллер. Все флаги регистра статуса UART изменяют свое состояние после завершения приема или передачи байта:
Флаг RXC - "Прием байта завершен". Устанавливается при передаче принятого байта из сдвигового регистра в регистр UDR

Флаг TXC - "Передача байта завершена". Устанавливается, когда весь символ, включая стоповый бит, выведен из сдвигового регистра передачи и в UDR не записаны новые данные.

Флаг UDRE - "Регистр данных пуст". Устанавливается, когда байт, записанный в UDR, пересылается в сдвиговый регистр передачи, а передатчик готов к принятию следующего байта для передачи.

На мой взгляд, Вам следует ставить задачу так:
После получения байта по UART включить пищалку на время (допустим) 0,5 секунды. Одновременно с пищалкой включить светодиод на время 15 секунд.

Re: Помогите доработать прошивку

Добавлено: Пн янв 06, 2014 14:41:03
mrFox
Popeye писал(а): Задача - сделать так, чтобы при поступлении кода светодиод(ы) горел(и) еще 15 секунд после того, как код прекратил поступать. Пищалка же должна отключаться сразу по прекращению поступления кода, т.е пищалка должна работать только лишь во время передачи кода.
не нужно распознать факт приема стартового бита :shock:
нужно завести переменную
приняли байт - присвоить переменной 15 и включить светодиод
в таймере 1 раз в секунду эту переменную если она не ноль уменьшаем на 1
достигли 0 - отключаем светодиод
тоже самое с пищалкой, только у нее время до выключения 1 сек

Re: Помогите доработать прошивку

Добавлено: Пн янв 06, 2014 15:34:23
Alkul
mrFox писал(а):нужно завести переменную
приняли байт - присвоить переменной 15 и включить светодиод
Это уже детали реализации.
Главное, что включение пищалки и светодиода произойдет после того, как
mrFox писал(а):приняли байт
О чем я и сказал тредстартеру.
mrFox писал(а):не нужно распознать факт приема стартового бита
По условию, поставленному тредстартером - нужно:
Popeye писал(а):При поступлении кода от определенного передатчика в приемнике загорается определенный светодиод и одновременно с этим начинает вопить пищалка. Как только прекращается поступление кода - светодиод(ы) тухнет, и пищалка прекращает работать.
то есть, он подразумевает, что между событиями
Popeye писал(а):При поступлении кода
и
Popeye писал(а):Как только прекращается поступление кода
должно пройти какое-то время (а код ведь может быть и однобайтным), в течение которого должна быть включена пищалка, а светодиод, будучи включен одновременно с пищалкой, должен светиться еще 15 секунд после события
Popeye писал(а):Как только прекращается поступление кода
Если реализовывать прием байта по прерываниям (а это самый верный путь), то события
Popeye писал(а):При поступлении кода
Popeye писал(а):Как только прекращается поступление кода
происходят одновременно - код "поступает", когда устанавливается флаг RXC, в этот же момент (почти в этот же :) ) и "прекращается поступление" кода.

Вряд ли у тредстартера размер "поступающего кода" измеряется килобайтами. Если там пара-тройка байтов, то за 2-3 миллисекунды, отведенные на работу пищалки, ухо не успеет среагировать на этот звук.

Re: Помогите доработать прошивку

Добавлено: Пн янв 06, 2014 17:37:08
Popeye
Спасибо за советы.
Сейчас попытаюсь изобразить алгоритм приемного устройства (коды передатчиков следующие - 0x10 - "красный", 0х20 - "желтый", 0х40 - "зеленый", 0х80 - "синий"):
Посылка идет 8 бит (Communication Parameters: 8 Data, 1 Stop, No Parity) по состоянию порта В передатчиков. В состоянии покоя все ноги порта В находятся в логическом "0". При передаче на одной из ног появляется "1" и состояние порта В сбрасывается в UART (PD1/TXD). Скорость - 4800.

Итак,

1. Принять код.
2. Если код не равен 0х10 или 0х20 или 0х40 или 0х80 (чужой код или помеха)
3. Перейти на строку № 1.

4. Иначе

5. Если код = 0х10.
6. Запищать.
7. Сделать задержку 0.5 сек.
8. Зажечь светодиод "красный".
9. Сделать задержку 15 сек.

Далее проверка кода на совпадение с 0х20, 0х40, 0х80 по примеру строк №4-9.

Вопрос: как реализовать безусловный переход между строками № 7 и 8 на строку № 1, для того чтобы во время обработки одного сигнала приемник мог принимать и другие сигналы и синхронно обрабатывать их. Иначе, исходя из этого алгоритма, приемник не сможет принять и обработать другой код, пока не обработает первый, выполняя все задержки, т.е. до приема следующего кода надо будет ждать примерно 15.5 сек.
А хотелось бы синхронную обработку заданных кодов.

Если я все правильно пониМЯУ, то существует 6 циклов:
- цикл приема кода;
- цикл генерации звуковой частоты;
- 4 цикла горения светодиода на определенном канале (по количеству каналов).

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

Заранее спасибо.

Re: Помогите доработать прошивку

Добавлено: Пн янв 06, 2014 20:32:27
Alkul
Popeye писал(а):Вопрос: как реализовать безусловный переход между строками № 7 и 8 на строку № 1, для того чтобы во время обработки одного сигнала приемник мог принимать и другие сигналы и синхронно обрабатывать их.
Вопрос понятен. Обработку данных, получаемых по UART, надо реализовывать в прерываниях.

Нужно определить 4 переменных размерностью в 1 байт каждая, в которых будут храниться счетчики времени для ваших светодиодов. Назовем эти переменные условно RED, GRN, BLU и YEL
Алгоритм такой:
1. Сработало прерывание по приему байта
2. Вызывается обработчик этого прерывания, в котором из UDR читается полученный байт, сравнивается с допустимыми кодами (0x10, 0x20, 0x40, 0x80)
3. Подается лог.1 на пищалку, запускается таймер (допустим, таймер 0) на отсчет одномиллисекундных интервалов времени. По переполнению этого таймера в обработчике прерывания нужно вновь запускать этот таймер на отсчет одной миллисекунды и изменять состояние вывода, к которому подключена пищалка - если был лог.0, устанавливать линию в лог.1, а если была лог.1, то сбрасывать в лог.0. Это даст на пищалке генерацию звука с частотой 500 Гц.
4. В зависимости от полученного кода включается соответствующий светодиод и в соответствующую переменную заносится число 0x1F (31DEC), запускается таймер 1 на отсчет 0,5 секундных интервалов времени. При вызове обработчика остановить таймер 0 и обнулить состояние вывода, к которому подключена пищалка. Проверить состояние переменных RED, GRN, BLU и YEL если какая-то из них не равна нулю, то декрементировать её. Вновь запустить таймер 1 на 0,5 секундный интервал.
5. Когда какая-то из переменных при очередном входе в обработчик прерывания по переполнению таймера 1 окажется равной единице, то обнулить эту переменную и погасить соответствующий светодиод. Если при входе в обработчик прерывания таймера 1 все переменные равны нулю, то остановить таймер 1.

Вот примерно так. Большую часть времени программа будет "крутиться" в пустом цикле, изредка отвлекаясь на обработку прерываний.
Можно "бантиков" навешать. Например, ввести специальный бит, установка которого будет означать работу пищалки. Это для того, чтобы при обработке прерывания таймера 1 всякий раз не выполнять коды остановки "пищалочного" таймера 0, а делать это только в том случае, когда необходимо.

Могу набросать код на ассемблере. Скажите только, для какого контроллера.

Re: Помогите доработать прошивку

Добавлено: Вт янв 07, 2014 02:32:21
Popeye
Alkul, Спасибо за дельные советы. :beer:
Я так и подозревал, что через прерывания надо, только еще не дошел до этого.
Сами понимаете, только учиться начинаю.

Кстати, по поводу пищалки, вот набросал програмку, работает вполне зачетно -

#include <tiny2313.h>
#include <delay.h>

main ()
{
DDRA=0xFF;

while (1)
{
PORTA = 1;
delay_us(50);
PORTA = 0;
delay_us(100);
}
}

Т.е. если повесить пищалку на порт А, она в беконечном цикле (или через кнопку) в Proteus'e нормально вполне пищит.
Alkul писал(а): Могу набросать код на ассемблере. Скажите только, для какого контроллера.
Буду очень признателен, как уже наверное догадались, использую ATTiny2313 (думаю для этой задачи большего и не надо).

Еще раз спасибо :beer:
Всех поздравляю с Рождеством !!!!

Re: Помогите доработать прошивку

Добавлено: Вт янв 07, 2014 08:41:35
Alkul
Popeye писал(а):Т.е. если повесить пищалку на порт А, она в беконечном цикле (или через кнопку) в Proteus'e нормально вполне пищит.
На какой именно вывод порта А? Зачем весь порт-то задействовать... Нужно изменять состояние только того вывода (бита порта) к которому подключена пищалка.

Re: Помогите доработать прошивку

Добавлено: Вт янв 07, 2014 09:35:22
Popeye
Я делал так.

Изображение


Вот моя схема полностью
Изображение

Re: Помогите доработать прошивку

Добавлено: Вт янв 07, 2014 10:38:18
Alkul
Popeye писал(а):Я делал так.
Неправильно.
Вы подключаете пищалку к двум линиям порта, при этом одну линию заземляете, а затем на обе линии подаете лог.1. При этом подключенная к земле линия будет перегружаться по току. Протеусу на это, может быть, и пофиг, а в реальном устройстве возможен выход порта из строя.
Начать нужно с вопроса: "Какой ток потребляет пищалка?" Из ответа на вопрос следует, можно ли подключать пищалку непосредственно к порту или же нужно использовать ключевой транзистор. Контроллеры AVR могут выдать не более 40 мА на каждый вывод.
Вот две схемы подключения, вариант а) - напрямую к порту, вариант б) - через транзистор
Изображение

И вообще - я посмотрел на Вашу схему и ничего не понял. Зачем столько контроллеров? К верхним четырем контроллерам у Вас что - кнопки подключены? Тоже неправильно. Кнопка подключается вот так:
Изображение
При этом нужно активировать встроенный резистор подтяжки на данной линии

Если Вам нужна схема, принимающая код, зажигающая 4 светодиода и пищащая одной пищалкой, то для этого хватит одного контроллера.

Re: Помогите доработать прошивку

Добавлено: Вт янв 07, 2014 10:54:44
Soir
Alkul писал(а): Вот две схемы подключения, вариант а) - напрямую к порту, вариант б) - через транзистор
Изображение
Вариант б, во-первых, смысла не имеет включать пищалку через транзистор, ограничивая ток через нее резистором 1 кОм. А во-вторых, нелогично шунтировать пищалку транзистором. Получается в режиме молчания транзистор должен быть открытый и будет протекать бесполезный ток как через переход база-эмиттер транзистора, так и через резистор, переход коллектор-эмиттер. Поэтому лучше пищалку перенести вместо резистора, подключив одним выводом к +5V, а другим к коллектору транзистора. В зависимости от тока пищалки, как Вы правильно заметили, возможно надо установить ограничительный резистор последовательно с пищалкой. Это касается и варианта а.

Re: Помогите доработать прошивку

Добавлено: Вт янв 07, 2014 11:18:57
Alkul
Soir писал(а):
Alkul писал(а):ограничивая ток через нее резистором 1 кОм
Сопротивление этого резистора я не считал, просто скопипастил его с резистора, включенного в цепь базы. Для того, чтобы считать этот резистор, надо знать ток пищалки.
А в остальном Вы правы. Поторопился я.

Re: Помогите доработать прошивку

Добавлено: Вт янв 07, 2014 11:24:40
Soir
Я бы добавил еще вариант в. Это схема эмиттерного повторителя. В этом случае и ток базы не будет пропадать зря.

Re: Помогите доработать прошивку

Добавлено: Вт янв 07, 2014 19:44:30
Popeye
Спасибо за подсказку по поводу вариантов подключения пищалки. Изначально по схеме был вариант "б", но в Протеусе он почему-то не заработал. А так вроде работает в режиме эмуляции.
Alkul писал(а): И вообще - я посмотрел на Вашу схему и ничего не понял. Зачем столько контроллеров? К верхним четырем контроллерам у Вас что - кнопки подключены? Тоже неправильно. Кнопка подключается вот так:
Изображение
При этом нужно активировать встроенный резистор подтяжки на данной линии

Если Вам нужна схема, принимающая код, зажигающая 4 светодиода и пищащая одной пищалкой, то для этого хватит одного контроллера.
По поводу устройства:
В первом посте я давал ссылку на пример видео работы аналогичного устройства - http://www.youtube.com/watch?v=sueynEpo1YY
Только в видео на 3 передатчика, а у меня на 4.

Как видите, при сработке одного из сигнализаторов, пейджер дублирует звуковым сигналом факт сработки и зажигает определенный светодиод. В этом плане еще важно, чтобы на пейджере светодиод не сразу тух, а с определенной задержкой (15-25 сек.), а вот звуковая индикация должна быть в режиме realtime.

Таким образом у нас получается комплект из 5 отдельных устройств:
- 4 беспроводных сигнализатора, каждый из которых оснащен модулем передатчика (у меня RT-5 Telecontrolli 433.92 Mhz) и кодером на базе ATTiny2313;
- 1 беспроводной пейджер (приемник), оснащенный модулем приемника (у меня RR-6 Telecontrolli 433.92 Mhz) и декодером для 4 передающих устройств на базе того же МК.

Ну вот где-то так вроде.

По поводу подключения кнопок, спорить не буду, может и не правильно.
В Протеусе у меня работает так:
PORT В передатчика настроен на вход, при замыкании на "+" дает лог. "1" соответственно и скидывает состояние всего порта в UART, формируя таким образом кодовую посылку в 8 бит.
В кодовой посылке приемник распознает, какой из битов лог. "1" и на этом же выводе порта B приемника также дает лог. "1" (зажигает светодиод).

Если же исходить из схемы подключения кнопки, предложеной Вами, откуда тогда брать лог. "1"?

Кстати, еще попутно вопрос: хватит ли 8-битной кодовой посылки для корректного приема кода приемником, учитывая что передача ведется на 433.92Mhz (диапазон сами понимаете...).
Имеет ли смысл применять какое-либо кодирование или можно организовать передачу нескольких пакетов по 8 бит каждый, а приемник настроить таким образом, чтобы он распознавал не единичные пакеты данных, а серии пакетов (что-то типа 32-битной посылки, только из четырех 8-битных). Тут еще какой момент, в ATTiny2313 имеется возможность передачи только 8-битного пакета, после которого передается стоп бит (если я все правильно понял). Может тогда использовать МК с возможностью передачи более объемных пакетов данных?

Просто изначально я пробовал собрать этот комплект устройств из модулей приема-передачи + кодер/декодер MC145026/MC145027 + генератор звука на К561ЛА7. При этом остался не в восторге от результата такой реализации. Помех было множество (срабатывания на автосигналки, аналогичные устройства и т.д.). Плюс к этому МС145027 на выходе VT при появлении ошибки иногда выдавало лог. "1", что приводило в действие генератор звука.

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

Спасибо. :)

Re: Помогите доработать прошивку

Добавлено: Ср янв 08, 2014 14:26:53
Alkul
Popeye писал(а):Если же исходить из схемы подключения кнопки, предложеной Вами, откуда тогда брать лог. "1"?
Что касается кнопок. Я же написал ранее - нужно будет активировать на линии кнопки встроенный резистор подтяжки. В AVR'ах встроенные резисторы подтяжки подтягивают линию к Vcc. Таким образом, при разомкнутой кнопке из порта будет читаться лог.1, а при замкнутой кнопке - лог.0.
Popeye писал(а):Кстати, еще попутно вопрос: хватит ли 8-битной кодовой посылки для корректного приема кода приемником, учитывая что передача ведется на 433.92Mhz (диапазон сами понимаете...).
Я как-то ни разу не занимался беспроводными передачами, но думается мне, что какое-то помехоустойчивое кодирование применять нужно обязательно. Я бы подумал насчет избыточного кодирования Хэмминга, которое даст возможность исправлять некоторые виды ошибок.

Re: Помогите доработать прошивку

Добавлено: Ср янв 08, 2014 17:07:31
Popeye
После долгий размышлений, пришла мне одна идея.
А что если упростить задачу?
Как я писал ранее, устройство на данный момент уже собрано без применения МК, но работает некорректно.
К передающей части у меня притензий нет, а вот к приемной части есть вопросы и по большей мере это относится к выводу VT декодера МС145027, который может иногда выдавать всякий "мусор" из эфира. Выходы же декодера (D6-D9) работают исправно на прием кода (его хоть об стенку бей, чужой код не принимает, срабатывает только на свои, причем без применения дополнительного кодирования, CRC и т.д.).
Что если устройство сделать по такой схеме:

Передающая часть (без изменений):
- модуль RT-5 + кодер МС145026;

Приемная часть:
- модуль RR-6 + декодер МС145027 + ATTiny2313.

В приемной части выходы D6-D9 MC145027 сделать управляющими входами МК, также в функции МК добавить генератор звуковой частоты и фукцию сброса питания декодера.
Здесь еще отмечу, что MC145027 при поступлении кода к примеру на ногу D6 будет продолжать находиться в лог. "1" до тех пор, пока не прийдет другой код. Я боролся с этим путем кратковременного отключения питания декодера.

Т.е. если сделать примерно такой алгоритм работы МК:

1. Опрос выводов D6-D9;
2. Если есть лог. "1" идем дальше на обработку кода, иначе к строке № 1.
3. Обработка кода;
4. Включение пищалки с задержкой 0.5 сек.;
5. Кратковременное отключение питание МС145027;
6. Включение светодиода с задержкой 15 сек.;
7. Вернуться к строке № 1.

Ну или еще есть вариант обойтись вообще без МС145027 и реализовать декодер на МК. Тогда надо как-то "захватить" код четырех передатчиков и в прошивке МК забить эти коды.

Что скажете?

Re: Помогите доработать прошивку

Добавлено: Сб янв 11, 2014 00:49:36
Popeye
Получилось захватить код всех четырех передатчиков.

Изображение

Вроде получается так:

Кодирование ШИМ.
Если принять,что ноль - это более широкий импульс и передача младшим битом вперед(всего передается 17 бит последовательность, то имеем:

синий - 1000 0000 0000 0000 0
желтый - 0010 0000 0000 0000 0
зеленый - 0000 1000 0000 0000 0
красный - 0000 0010 0000 0000 0

Это если я правильно все понял.
Как теперь быть с приемом пакетов длиной в 17 бит? Вроде как буфер 8-битный.
Я так понимаю, надо создать массив данных с образцами кода.

Подскажите как?

Re: Помогите доработать прошивку

Добавлено: Сб янв 11, 2014 12:20:17
Alkul
Popeye писал(а):Получилось захватить код всех четырех передатчиков.
Зачем Вам код передатчиков? В каком именно месте Вы "захватили" код?
Popeye писал(а):Как теперь быть с приемом пакетов длиной в 17 бит? Вроде как буфер 8-битный.
Зачем Вам это, коль скоро Вы собираетесь использовать связку кодер MC145026 - декодер MC145027?
Для начала изучите вот это:
MC145026,MC145027,MC145028.pdf
(356.89 КБ) 558 скачиваний
Popeye писал(а):Как теперь быть с приемом пакетов длиной в 17 бит? Вроде как буфер 8-битный.
Если уж Вы решаете отказаться от декодера, тогда отказывайтесь и от кодера. На передающей стороне кодируйте в МК передатчика, а на приемной - декодируйте в МК приемника.
А для пакета в 17 бит придется самому писать программный аналог UART кодовой посылки нестандартной длины.

Re: Помогите доработать прошивку

Добавлено: Сб янв 11, 2014 19:54:10
NTXP
Может я скажу сейчас что-то не то, я сам новичок в этом деле...

А не может ли лишний бит быть стоп-битом, отделяющим два байта один от другого? Судя по даташиту на 26 и 27 Моторолу, оно передает кодовую посылку словом, т.е. двумя байтами? И их же надо как-то разделять, не может ли это быть стоп-битом?

Re: Помогите доработать прошивку

Добавлено: Сб янв 11, 2014 20:23:41
Alkul
NTXP писал(а):А не может ли лишний бит быть стоп-битом, отделяющим два байта один от другого?
Нет. Формат кадра всегда неизменен. Если есть стоп-бит после одного байта, то он должен быть и после другого. А стартовые биты тогда где?
В протоколе обмена этих кодеров-декодеров нет разбития на байты. Передается пакет нестандартной длины.