Подскажите, как правильно сделать чтение данных с зашумленного входа
- Войдите на сайт для отправки комментариев
Вс, 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: а, заглянул в скетч, там все параметры. Кстати, нет смысла хранить все импульсы преамбулы, можно сразу считать. Хранить только данные
Спасибо, буду осмысливать.
А импульсы преамбулы храняться для отладки, чтобы знать их длительность