Подскажите, как правильно сделать чтение данных с зашумленного входа

vlkam
Offline
Зарегистрирован: 17.02.2013

 Есть у меня код, который считывает с приемника 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;
	
	}

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

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Я скорее по профански, но если есть шум на цифровом выходе (я правильно понял?), то нужно с ним бороться (с шумом), а не фильтровать на входе.

Использовать прерывания или нет, зависит от загруженности МК, лучше, конечно использовать прерывания, так более точное измерение, плюс у МК остается время на другие дела. Примеры есть, например, в книге Margolis M. "Arduino Cookbook", глава 18.2, да и в гугле наверняка море.

 

vlkam
Offline
Зарегистрирован: 17.02.2013

А как можно с этим шумом бороться ? Его приемник выдает

maksim
Offline
Зарегистрирован: 12.02.2012

Никак.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

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

Kislorof
Offline
Зарегистрирован: 30.10.2012

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

vlkam
Offline
Зарегистрирован: 17.02.2013

 Да приемники самые обычные

 

maksim
Offline
Зарегистрирован: 12.02.2012

Kislorof пишет:
Судя по картинке - это сигнал с энкодера?
Первое предложение первого поста
vlkam пишет:
Есть у меня код, который считывает с приемника 433 приходящий туда сигнал вот такого вида

maksim
Offline
Зарегистрирован: 12.02.2012

vlkam пишет:
Да приемники самые обычные

Так вы определитесь какой у вас приемник.

Если у вас приемник как на первой и второй картинке, то зачем вы вообще считываете сигнал с вывода DATA и сами его дешифруете, если у вас сам приемник может дешифровывать и выдавать сигналы нажатых кнопок на D1, D2, D3 и D4 ?

vlkam
Offline
Зарегистрирован: 17.02.2013

maksim пишет:

Так вы определитесь какой у вас приемник.

Если у вас приемник как на первой и второй картинке, то зачем вы вообще считываете сигнал с вывода DATA и сами его дешифруете, если у вас сам приемник может дешифровывать и выдавать сигналы нажатых кнопок на D1, D2, D3 и D4 ?

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

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Если не хватает мощьности передатчика или приемник некорректно настроен то естественно возникают шумы. Я бы предложил использовать аппаратные средства: другой тип приемника и передатчика адаптированные для передачи данных. Еще как вариант - экранировать приемник и передатчик, питать их от отдельного стабилизатора с фильтрами на питании.

Те приемники что у вас расчитанны максимум на 30 метров, по факту зависит от условий и может не превышать 10м - тоесть зона устойчивого приема(где шумов нет впринципе).

 

vlkam
Offline
Зарегистрирован: 17.02.2013

NeiroN пишет:
Если не хватает мощьности передатчика или приемник некорректно настроен то естественно возникают шумы. Я бы предложил использовать аппаратные средства: другой тип приемника и передатчика адаптированные для передачи данных. Еще как вариант - экранировать приемник и передатчик, питать их от отдельного стабилизатора с фильтрами на питании.

Те приемники что у вас расчитанны максимум на 30 метров, по факту зависит от условий и может не превышать 10м - тоесть зона устойчивого приема(где шумов нет впринципе).

Это часть системы контроля доступа. Передатчики - брелки, так что их не изменить. Расстояние в 10 метров абсолютно устраивает

Приемник покачественнее это конечно вариант, но думается мне помехи будут всегда, тем более в отсутствии передачи, это же наводки всякие от кабелей, работающих двигателей

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

если наводки от кабелей и т.п... уберите их...

maksim
Offline
Зарегистрирован: 12.02.2012

Я не могу вонять вы о чем тут пишите? Какие еще помехи? ТС у вас данные не доходят от передатчика к приемнику?

То что на ноге постоянный шум - это нормальный фон в радиоэфире. Вы пробовали настраивать радио на несуществующую радиостанцию? Что вы слышали тишину что-ли? Почему тогда здесь у вас вдруг возник вопрос, а как сделать тишину... Нет никаких помех и ничего вы с этим не сделаете и не надо с этим ничего делать.

vlkam
Offline
Зарегистрирован: 17.02.2013

maksim пишет:
Я не могу вонять вы о чем тут пишите? Какие еще помехи? ТС у вас данные не доходят от передатчика к приемнику?

То что на ноге постоянный шум - это нормальный фон в радиоэфире. Вы пробовали настраивать радио на несуществующую радиостанцию? Что вы слышали тишину что-ли? Почему тогда здесь у вас вдруг возник вопрос, а как сделать тишину... Нет никаких помех и ничего вы с этим не сделаете и не надо с этим ничего делать.

У приемника цифровой выход "дата". Пока сигнала нет с него естественно идет шум в виде периодически случайно возникающих нулей и единичек. Вот это я и называю "шум". И видимо от него не избавится

Если прием завязать на прерывание, то оно видимо слишком часто будет вызываться, т.к. шум идет постоянно.

Вопрос - как сделать правильно прием такого сигнала

maksim
Offline
Зарегистрирован: 12.02.2012

Так вы не стой стороны смотрите на проблему. Нужно не от "шума" избавляться, а грамотно сделать отслеживание преамбулы и прием команды. То есть сделать так что бы прием был не блокирующим. Если будете выжидать в прерывании следующего фронта сигнала, как в коде выше, то конечно ничего не выйдет.

vlkam
Offline
Зарегистрирован: 17.02.2013

maksim пишет:

Так вы не стой стороны смотрите на проблему. Нужно не от "шума" избавляться, а грамотно сделать отслеживание преамбулы и прием команды. То есть сделать так что бы прием был не блокирующим. Если будете выжидать в прерывании следующего фронта сигнала, как в коде выше, то конечно ничего не выйдет.

Так я как раз и спрашиваю, с какой стороны тут правильно подойти.

Мысль о том, чтобы ловить преамбулу прерываниями интересная, попробую. Спасибо

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

В таком случае это совсем не шум, полезный сигнал обрамлен преамбулой и заканчивается гардом. Как сказал максим тупо ждем преамбулу, вычитываем данные, если всё нормально, то считаем, что пакет принят. Тут "шум" не пролезет. Я думал у Вас шум типа иголок, а если это нули и единички, то всё намного проще

vlkam
Offline
Зарегистрирован: 17.02.2013

kisoft пишет:
тупо ждем преамбулу

В том то и вопрос, как её ждать. Сейчас я в loop вызываю функцию, которая проверяет наличие преамбулы.
Но это видимо не лучший способ.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Преамбула - это N импульсов определенной длины. Это можно ловить в прерываниях. Затем пауза (как я понял, опять же определенной длины), возможно её придется ловить в loop, поскольку прерываний не будет, либо когда начнется посылка будет ясно, сколько времени прошло от преамбулы. Потом ловим данные.

Собственно это автомат с четырьмя-пятью состояниями. Например, ожидание, преамбула, пауза, данные, останов.

Эти состояния нужно отслеживать в прерывании, а в loop ловить флаг останова, который формируется в прерывании как последнее состояние. Потом декодировать в loop и сбрасывать автомат на начальное состояние. Типа так. К сожалению на картинке не видно временных параметров сигнала (преамбулы и т.п.)

UPD: а, заглянул в скетч, там все параметры. Кстати, нет смысла хранить все импульсы преамбулы, можно сразу считать. Хранить только данные

vlkam
Offline
Зарегистрирован: 17.02.2013

kisoft пишет:

Преамбула - это N импульсов определенной длины. Это можно ловить в прерываниях. Затем пауза (как я понял, опять же определенной длины), возможно её придется ловить в loop, поскольку прерываний не будет, либо когда начнется посылка будет ясно, сколько времени прошло от преамбулы. Потом ловим данные.

Собственно это автомат с четырьмя-пятью состояниями. Например, ожидание, преамбула, пауза, данные, останов.

Эти состояния нужно отслеживать в прерывании, а в loop ловить флаг останова, который формируется в прерывании как последнее состояние. Потом декодировать в loop и сбрасывать автомат на начальное состояние. Типа так. К сожалению на картинке не видно временных параметров сигнала (преамбулы и т.п.)

UPD: а, заглянул в скетч, там все параметры. Кстати, нет смысла хранить все импульсы преамбулы, можно сразу считать. Хранить только данные

Спасибо, буду осмысливать.

А импульсы преамбулы храняться для отладки, чтобы знать их длительность