Подскажите, как правильно сделать чтение данных с зашумленного входа
- Войдите на сайт для отправки комментариев
Вс, 23/06/2013 - 11:15
Есть у меня код, который считывает с приемника 433 приходящий туда сигнал вот такого вида
Чтение организовано просто и дубово - в цикле опрашивается цифровой пин, на который заведен выход приемника и анализируется что пришло. Если "приход" составляет 12 импульсов примерно нужной длины, значит пришло то, что нужно
boolean HCS301_message::Read(){ int duration[12]; byte PreamblePulseCount; int rs = digitalRead(pin); if(rs == 0){ return false; } // что то поймали, будем анализировать //Serial.println("Ok"); unsigned long TimeStartReading = micros(); unsigned long PulseStart = TimeStartReading; unsigned long curpoz = TimeStartReading; int stat = 1; int tdur = 0; PreamblePulseCount = 0; int i,j; // ловим преамбулу ////////////////////////////////////////////////////////////////////// // Преамбула состоит из 12 импульсов, типичная длительность 9200 мкс // Длительность преамбулы 23 базовых импульсов Те, типичный импульс Те 400 мкс while((curpoz - TimeStartReading) < 20000){ rs = digitalRead(pin); if (stat != rs) { // состояние изменилось if(stat == 1 && rs == 0){ // окончание импульса tdur = curpoz - PulseStart; if(tdur < 300 || tdur > 600){ break; } duration[PreamblePulseCount] = tdur; PreamblePulseCount ++; stat = 0; if(PreamblePulseCount == 12){ break; } } else { // начало импульса stat = 1; PulseStart = curpoz; } } curpoz = micros(); } if(PreamblePulseCount != 12){ return false; } //Serial.println("Catch preamble"); // Найдена преамбула////////////////////////////////////////////////////////////////////// int PreambleDuration = micros() - TimeStartReading; int Te = PreambleDuration / 23; // Далее идет пустой хидер длительностью 10 TE int mass[66]; bool Reading; bool Success; int dur; // Начинаем читать данные for(i = 65;i >= 0; i--){ Reading = false; TimeStartReading = 0; Success = false; for(int j=0;j<1000;j++){ rs = digitalRead(pin); if (rs == 1 && Reading == false){ // начали чтение бита TimeStartReading = micros(); Reading = true; }; if (rs == 0 && Reading == true){ // окончили чтение бита dur = micros() - TimeStartReading; mass[i] = (dur > (Te / 2 * 3)) ? 0 : 1; Success = true; break; }; }; if(Success == false){ return false; }; }; Repeat = mass[0]; BattaryLow = mass[1]; BtnNoSound = mass[2]; BtnOpen = mass[3]; BtnClose = mass[4]; BtnRing = mass[5]; SerialNum = 0; for(i = 6; i < 34;i++){ SerialNum = (SerialNum << 1) + mass[i]; }; Encript = 0; for(i = 34; i < 66;i++){ Encript = (Encript << 1) + mass[i]; }; return true; }
Насколько я понимаю, так делать не очень красиво, по уму нужно это прерыванием сделать. Но есть вопрос - выход приемника очень шумный, туда постоянно всякое дерьмо сыпется, не помешает ли это работе прерываний ? И вообще как грамотно реализовать такую задачу ?
Я скорее по профански, но если есть шум на цифровом выходе (я правильно понял?), то нужно с ним бороться (с шумом), а не фильтровать на входе.
Использовать прерывания или нет, зависит от загруженности МК, лучше, конечно использовать прерывания, так более точное измерение, плюс у МК остается время на другие дела. Примеры есть, например, в книге Margolis M. "Arduino Cookbook", глава 18.2, да и в гугле наверняка море.
А как можно с этим шумом бороться ? Его приемник выдает
Никак.
Если не трудно, дайте ссылку на приемник, для себя посмотреть, что за зверь. Спасибо.
Помочь вряд ли смогу, для самообразования интересно.
Судя по картинке - это сигнал с энкодера? Там шум может быть только от силовой линии. Ложить сигнальную в экране значит надо или не вести параллельно силовой. И еще - подтяжки включены на входах?
Да приемники самые обычные
Так вы определитесь какой у вас приемник.
Если у вас приемник как на первой и второй картинке, то зачем вы вообще считываете сигнал с вывода DATA и сами его дешифруете, если у вас сам приемник может дешифровывать и выдавать сигналы нажатых кнопок на D1, D2, D3 и D4 ?
Так вы определитесь какой у вас приемник.
Если у вас приемник как на первой и второй картинке, то зачем вы вообще считываете сигнал с вывода DATA и сами его дешифруете, если у вас сам приемник может дешифровывать и выдавать сигналы нажатых кнопок на D1, D2, D3 и D4 ?
У меня и тот и другой применяются. Использую их как обычные приемники на 433 мгц
Дешифрация самим приемником мне не подходит, а где там искать чисто цифровой выход непонятно
Если не хватает мощьности передатчика или приемник некорректно настроен то естественно возникают шумы. Я бы предложил использовать аппаратные средства: другой тип приемника и передатчика адаптированные для передачи данных. Еще как вариант - экранировать приемник и передатчик, питать их от отдельного стабилизатора с фильтрами на питании.
Те приемники что у вас расчитанны максимум на 30 метров, по факту зависит от условий и может не превышать 10м - тоесть зона устойчивого приема(где шумов нет впринципе).
Те приемники что у вас расчитанны максимум на 30 метров, по факту зависит от условий и может не превышать 10м - тоесть зона устойчивого приема(где шумов нет впринципе).
Это часть системы контроля доступа. Передатчики - брелки, так что их не изменить. Расстояние в 10 метров абсолютно устраивает
Приемник покачественнее это конечно вариант, но думается мне помехи будут всегда, тем более в отсутствии передачи, это же наводки всякие от кабелей, работающих двигателей
если наводки от кабелей и т.п... уберите их...
Я не могу вонять вы о чем тут пишите? Какие еще помехи? ТС у вас данные не доходят от передатчика к приемнику?
То что на ноге постоянный шум - это нормальный фон в радиоэфире. Вы пробовали настраивать радио на несуществующую радиостанцию? Что вы слышали тишину что-ли? Почему тогда здесь у вас вдруг возник вопрос, а как сделать тишину... Нет никаких помех и ничего вы с этим не сделаете и не надо с этим ничего делать.
То что на ноге постоянный шум - это нормальный фон в радиоэфире. Вы пробовали настраивать радио на несуществующую радиостанцию? Что вы слышали тишину что-ли? Почему тогда здесь у вас вдруг возник вопрос, а как сделать тишину... Нет никаких помех и ничего вы с этим не сделаете и не надо с этим ничего делать.
У приемника цифровой выход "дата". Пока сигнала нет с него естественно идет шум в виде периодически случайно возникающих нулей и единичек. Вот это я и называю "шум". И видимо от него не избавится
Если прием завязать на прерывание, то оно видимо слишком часто будет вызываться, т.к. шум идет постоянно.
Вопрос - как сделать правильно прием такого сигнала
Так вы не стой стороны смотрите на проблему. Нужно не от "шума" избавляться, а грамотно сделать отслеживание преамбулы и прием команды. То есть сделать так что бы прием был не блокирующим. Если будете выжидать в прерывании следующего фронта сигнала, как в коде выше, то конечно ничего не выйдет.
Так вы не стой стороны смотрите на проблему. Нужно не от "шума" избавляться, а грамотно сделать отслеживание преамбулы и прием команды. То есть сделать так что бы прием был не блокирующим. Если будете выжидать в прерывании следующего фронта сигнала, как в коде выше, то конечно ничего не выйдет.
Так я как раз и спрашиваю, с какой стороны тут правильно подойти.
Мысль о том, чтобы ловить преамбулу прерываниями интересная, попробую. Спасибо
В таком случае это совсем не шум, полезный сигнал обрамлен преамбулой и заканчивается гардом. Как сказал максим тупо ждем преамбулу, вычитываем данные, если всё нормально, то считаем, что пакет принят. Тут "шум" не пролезет. Я думал у Вас шум типа иголок, а если это нули и единички, то всё намного проще
В том то и вопрос, как её ждать. Сейчас я в loop вызываю функцию, которая проверяет наличие преамбулы.
Но это видимо не лучший способ.
Преамбула - это N импульсов определенной длины. Это можно ловить в прерываниях. Затем пауза (как я понял, опять же определенной длины), возможно её придется ловить в loop, поскольку прерываний не будет, либо когда начнется посылка будет ясно, сколько времени прошло от преамбулы. Потом ловим данные.
Собственно это автомат с четырьмя-пятью состояниями. Например, ожидание, преамбула, пауза, данные, останов.
Эти состояния нужно отслеживать в прерывании, а в loop ловить флаг останова, который формируется в прерывании как последнее состояние. Потом декодировать в loop и сбрасывать автомат на начальное состояние. Типа так. К сожалению на картинке не видно временных параметров сигнала (преамбулы и т.п.)
UPD: а, заглянул в скетч, там все параметры. Кстати, нет смысла хранить все импульсы преамбулы, можно сразу считать. Хранить только данные
Преамбула - это N импульсов определенной длины. Это можно ловить в прерываниях. Затем пауза (как я понял, опять же определенной длины), возможно её придется ловить в loop, поскольку прерываний не будет, либо когда начнется посылка будет ясно, сколько времени прошло от преамбулы. Потом ловим данные.
Собственно это автомат с четырьмя-пятью состояниями. Например, ожидание, преамбула, пауза, данные, останов.
Эти состояния нужно отслеживать в прерывании, а в loop ловить флаг останова, который формируется в прерывании как последнее состояние. Потом декодировать в loop и сбрасывать автомат на начальное состояние. Типа так. К сожалению на картинке не видно временных параметров сигнала (преамбулы и т.п.)
UPD: а, заглянул в скетч, там все параметры. Кстати, нет смысла хранить все импульсы преамбулы, можно сразу считать. Хранить только данные
Спасибо, буду осмысливать.
А импульсы преамбулы храняться для отладки, чтобы знать их длительность