Прочитать байт с порта

iopq
Offline
Зарегистрирован: 05.07.2016

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

вот такой функцией

void writeByte(byte code) {
pinMode(2, OUTPUT);                    //DDRD |= _BV(2);      
for (int i = 0; i < 8; i++) {          
 digitalWrite(2, LOW);                  //PORTD &= ~_BV(2);
 delayMicroseconds(50);                
if (code >> i & 0b1){                 
 digitalWrite(2, HIGH);                 //PORTD |= _BV(2);
 delayMicroseconds(150);                
 }
else {                                  
 delayMicroseconds(100);                
 digitalWrite(2, HIGH);                 //PORTD |= _BV(2);
 delayMicroseconds(70);
 }
}
}

работает просто замечательно - сигнал очень ровный и красивый -

если после отправки установить порт на вход

 pinMode(2, INPUT);                        //DDRD &= ~_BV(2);

то можно увидеть ответные данные -

а вот как бы мне их прочитать и вывести допустим в консоль ардуины (Serial.print();)?

iopq
Offline
Зарегистрирован: 05.07.2016

я так понимаю что мне надо -

известно ожидаемое кол-во бит (8)

известны тайминги входящих данных

наверное мне нужно при помоши micros() измерять время нахождения порта в каком либо состоянии и согласно таймингам записывать единицу или ноль? так же? иначе зачем бы в даташите указывалось это время? можно конечно попробовать "синхронизироваться" при помощи задержек, но будут сбои? другого выхода я не вижу

Green
Offline
Зарегистрирован: 01.10.2015

Чё надо в конечном итоге?
Когда уже люди научатся излагать свои мысли....

iopq
Offline
Зарегистрирован: 05.07.2016

Интерпретировать ответ хотя бы в двоичный код и увидеть его в юарт 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

А что за микросхема? Как называется, даташит глянуть.

sadman41
Offline
Зарегистрирован: 19.10.2016

7-бит адрес с битом R/W... Не пахнет ли тут квадратной шиной...

iopq
Offline
Зарегистрирован: 05.07.2016

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

имеем - если логический 1 длится до 100 микросекунд это 0. если от 160 это 1

соответственно в цикле (while) хочу проверять условие

while((digitalRead(2) == 1) && (t <= 100)) result 0

else result 1

только не могу понять как измерять время

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

iopq пишет:

имеем - если логический 1 длится до 100 микросекунд это 0. если от 160 это 1

только не могу понять как измерять время

Ну вот тебе кусок кода чтения с DHT, по аналогии понятно, как сделать проверку на единичку или нолик:

	tmout_guard = ( F_CPU / 40000 ); // сторож таймаута
	uint32_t tMicros = micros();
	while ((*PIR & bit) != LOW )
	{
		if(!--tmout_guard)
			return false; // таймаут поймали
	} // while

	if(micros() - tMicros > 40) // единичка
	{
		bytes[idx] |= bitmask;
	}

 

iopq
Offline
Зарегистрирован: 05.07.2016

большое спасибо. значит мысли мои были правильные. все больше не подсказывайте ничего - я надеюсь разберусь дальше сам

iopq
Offline
Зарегистрирован: 05.07.2016

сделал так -

uint8_t readByte() {                  //надеюсь что она когда нибудь вернет 8 бит
 pinMode(2, INPUT);                   //DDRD &= ~_BV(2);     // Настроили пин на вход
for (int i = 0; i < 8; i++) {        // читаем 8 бит
uint32_t tmout_guard = 400;          // сторож таймаута
uint32_t tMicros = micros();

while (digitalRead(2) == 1 )        //ждем пока появится логическая 1
{
 if(!--tmout_guard){
 return false;                      // таймаут поймали 
 }
} 

if(micros() - tMicros > 30)          // единичка
{
 Serial.println(micros() - tMicros); //для отладки
}

}                                    //закончили чтение 8 бит
 Serial.println("end bit");          // для отладки сообщили об этом событии
}

получаю в консоль -

156
48
76
88
80
76
76
84
end bit
164
44
80
88
80
88
68
84
end bit

при том что данные выглядят так-

где я ошибся?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

digitalRead - медленная операция, лучше напрямую из порта читать, см. digitalPinToPort, digitalPinToBitmask, portInputRegister.

iopq
Offline
Зарегистрирован: 05.07.2016

изменил строчку 7 на while (PIND & _BV(2) == 1 )        //ждем пока появится логическая 1 на порте atmega 328 PD2 (2 нога ардуино UNO)

теперь в консоле

end bit

end bit

end bit
 
DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Таймаут пока уберите.

iopq
Offline
Зарегистрирован: 05.07.2016
uint8_t readByte() {                  //надеюсь что она когда нибудь вернет 8 бит
 pinMode(2, INPUT);                   //DDRD &= ~_BV(2);     // Настроили пин на вход
for (int i = 0; i < 8; i++) {        // читаем 8 бит
uint32_t tMicros = micros();

while (PIND & _BV(2) == 1 )        //ждем пока появится логическая 1
{

} 

if(micros() - tMicros > 30)          // единичка
{
 Serial.println(micros() - tMicros); //для отладки
}

}                                    //закончили чтение 8 бит
 Serial.println("end bit");          // для отладки сообщили об этом событии
}

ничего не изменилось

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Не сравнивайте с единицей результат побитового & ;)

iopq
Offline
Зарегистрирован: 05.07.2016

изменил while (PIND & _BV(2) !=LOW ) теперь в консоль ничего не выводится

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

iopq
Offline
Зарегистрирован: 05.07.2016

почему то у меня вот так while (PIND & _BV(2) != LOW ) не может выйти из цикла

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

iopq пишет:

почему то у меня вот так while (PIND & _BV(2) != LOW ) не может выйти из цикла

Потому что в PIND может быть выставлен другой бит, например, 5 & 4 != LOW == 4

iopq
Offline
Зарегистрирован: 05.07.2016

так. это уже интересно. я искренне верил в то что запись PIND & _BV(2) означает что мы хотим считать значение 0 или 1 с порта D вывода 2. если не сложно не могли бы вы обьяснить более подробно что за другой бит может быть выставлен?

получается что мое недопонимание мешает мне закончить функцию

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

_BV(2) это 0b00000100 когда нужный вам второй бит выставлен в 1 результатом побитового И будет 4, а если выставлен 0 то будет 0.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

iopq, вы не путайте лог.состояния и весовые значения. В  PIND & _BV(2)   может лежать либо 0 либо 4

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

iopq пишет:

так. это уже интересно. я искренне верил в то что запись PIND & _BV(2) означает что мы хотим считать значение 0 или 1 с порта D вывода 2. если не сложно не могли бы вы обьяснить более подробно что за другой бит может быть выставлен?

получается что мое недопонимание мешает мне закончить функцию

Порт PIND: b00000011 - выставлены два младших бита, в DEC это число 3. Вы проверяете второй бит, маска b00000010, в DEC это число 2. Конструкция if(3 & 2) == 1) никогда не сработает, т.к. результат вычислений будет равен 2. Так понятней ?

Более того: в PIND у нас b00000101, т.е. 5 DEC. Мы проверяем второй и третий бит: b00000110 (6 DEC). Результатом 5 & 6 будет 4.

Не запутал?

iopq
Offline
Зарегистрирован: 05.07.2016

не ну то что у портов есть регистры я конечно знаю, просто не ожидал что запись PIND & _BV(2) будет читать 3 регистра а не один. или не так? 

b00000000 = PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0

нам же нужен только PD2?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Смотрите: строго говоря, конструкция 

while((PIND & _BV(2)) != LOW)

совершенно валидная, т.к. LOW == 0, и эта конструкция означает ровно следующее: Ждать, пока бит 2 в  порту(байте) не будет сброшен. На примере: 3 (11 BIN) & 2 (10 BIN) == 2, бит 2 установлен. 4 (100 BIN) & 2 (10 BIN) == 0, бит 2 сброшен. 

Валидна и обратная конструкция:

while((PIND & _BV(2)) == LOW)

А вот сравнивать с HIGH, т.е. с 1, результат битового "и" - неверно ;) 

nik182
Offline
Зарегистрирован: 04.05.2015

И даже b11111111 = PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0 .  Регистры это ячейки памяти связанные с тем или иным устройством. У порта три регистра PIN*,PORT*,DDR* . Регистр как ячейка памяти состоит из бит.  Про конкретное назначение можно прочитать а даташите http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf

Запись PIND & _BV(2)  читает один регистр а потом выделяет один бит. Что бы не думать какой лучше сравнивать с нулём. Если не равен нулю ( PIND & _BV(2) !=0 ) то бит установлен. 

maksmkv
Offline
Зарегистрирован: 07.04.2013

iopq пишет:

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

вот такой функцией

void writeByte(byte code) {
pinMode(2, OUTPUT);                    //DDRD |= _BV(2);      
for (int i = 0; i < 8; i++) {          
 digitalWrite(2, LOW);                  //PORTD &= ~_BV(2);
 delayMicroseconds(50);                
if (code >> i & 0b1){                 
 digitalWrite(2, HIGH);                 //PORTD |= _BV(2);
 delayMicroseconds(150);                
 }
else {                                  
 delayMicroseconds(100);                
 digitalWrite(2, HIGH);                 //PORTD |= _BV(2);
 delayMicroseconds(70);
 }
}
}

работает просто замечательно - сигнал очень ровный и красивый -

если после отправки установить порт на вход

 pinMode(2, INPUT);                        //DDRD &= ~_BV(2);

то можно увидеть ответные данные -

а вот как бы мне их прочитать и вывести допустим в консоль ардуины (Serial.print();)?

 

 

Здравствуйте. Слежу за темой, очень  надеюс,  что у вас получиться прочитать все  верно. А,  что за  данные считываете, это  из общеизвестных устройств параметры??? 

Datak
Offline
Зарегистрирован: 09.10.2014

iopq пишет:

почему то у меня вот так while (PIND & _BV(2) != LOW ) не может выйти из цикла

Скобочки ещё одни добавьте: while ( ( PIND & _BV(2)  ) != LOW ).

Это обязательно. Насчёт остального - не вникал, но вроде да, всё правильно сказали. Как минимум, насчёт сравнения с единицей. ))

iopq
Offline
Зарегистрирован: 05.07.2016

да со скобочками хоть как то пошло. имею на данный момент вот такой код  -

uint8_t readByte() {                  //надеюсь что она когда нибудь вернет 8 бит
 pinMode(2, INPUT);                   //DDRD &= ~_BV(2);     // Настроили пин на вход
 byte b[] = {};                        //для отладки пишем в нее 0 или 1
for (int i = 0; i < 8; i++) {        // читаем 8 бит
 uint32_t tMicros = micros();
 uint32_t tmout_guard = 400;          // сторож таймаута
while((PIND & _BV(2)) != LOW)          //ждем пока появится логический 0
{
Serial.println("while");             //для отладки
if(!--tmout_guard)
 return false;                      // таймаут поймали
} 
if(micros() - tMicros < 50)          // 1
 b[i] =0;                           //записываем в переменную 0
else                                //иначе
 b[i] =1;                           //1
}                                    
 Serial.println(b[0]);              выводим в консоль что позаписывали
 Serial.println(b[1]);
 Serial.println(b[2]);
 Serial.println(b[3]);
 Serial.println(b[4]);
 Serial.println(b[5]);
 Serial.println(b[6]);
 Serial.println(b[7]);
 Serial.println("end bit");          // для отладки сообщили об этом событии
}

в консоль поступают следующие данные -

while
while
while
1
0
0
0
0
0
0
0
end bit
while
while
while
1
0
0
0
0
0
0
0
end bit

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Datak пишет:

Скобочки ещё одни добавьте: while ( ( PIND & _BV(2)  ) != LOW ).

Йоп, старею, про приоритет операций забыл, когда примеры писал :) Щас поправлю, чо уж там - дабы не вводить в заблуждение будущих читателей. Причём код, который давал, выдравши из проекта - оно со скобочками, как положено. Вот что значит в спешке писать :(

iopq
Offline
Зарегистрирован: 05.07.2016

я не понимаю почему она не хочет читать правильно тайминги. по логике все должно работать. если менее 50 мкс это единица а если более это 0

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

iopq пишет:

я не понимаю почему она не хочет читать правильно тайминги. по логике все должно работать. если менее 50 мкс это единица а если более это 0

Ну как минимум потому, что у вас внутри цикла - вывод в Serial, все тайминги херятся.

iopq
Offline
Зарегистрирован: 05.07.2016

я его убирал- ничего не меняется

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Да и вообще - там ещё ошибки:

byte b[] - это какая такая неизвестная размерность массива, с учётом того, что вы его не инициализируете даже? Вы куда-то пишете в память, а куда - хз.

Короче: 

uint8_t readByte() 
{
 pinMode(2, INPUT);
 byte result = 0;
 byte mask = 0x80;
 
	for (int i = 0; i < 8; i++) 
	{        // читаем 8 бит
		uint32_t tMicros = micros();
		uint32_t tmout_guard = 400;          // сторож таймаута
		
		while((PIND & _BV(2)) != LOW)          //ждем пока появится логический 0
		{
			if(!--tmout_guard)
				return false;                      // таймаут поймали
		} 
		
		if(micros() - tMicros < 50) // если менее 50 мкс - то единица
			result |= mask;
	
		mask >>= 1;
	
	}
	return result;
}  

 

iopq
Offline
Зарегистрирован: 05.07.2016

она мне возращает 127 что равно 01111111 которые я получал своим кодом

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

iopq пишет:

она мне возращает 127 что равно 01111111 которые я получал своим кодом

Ну допишите код, чтобы после выставления бита ждала смены уровня, не проблема же ж:

uint8_t readByte() 
{
 pinMode(2, INPUT);
 byte result = 0;
 byte mask = 0x80;
 
	for (int i = 0; i < 8; i++) 
	{        // читаем 8 бит
		uint32_t tMicros = micros();
		uint32_t tmout_guard = 400;          // сторож таймаута
		
		while((PIND & _BV(2)) != LOW)          //ждем пока появится логический 0
		{
			if(!--tmout_guard)
				return false;                      // таймаут поймали
		} 
		
		if(micros() - tMicros < 50) // если менее 50 мкс - то единица
			result |= mask;
	
		mask >>= 1;

        tmout_guard = 400;          // сторож таймаута
		
		while((PIND & _BV(2))  == LOW)          //ждем пока появится логический 1
		{
			if(!--tmout_guard)
				return false;                      // таймаут поймали
		} 
	
	}
	return result;
}  

Это как вариант, что называется, а конкретно - зависит от протокола общения. Например, у того же DHT надо ждать 50us, прежде чем пойдёт следующий бит - просто ждём, пока уровень не сменится.

iopq
Offline
Зарегистрирован: 05.07.2016

теперь возращает 0

Datak
Offline
Зарегистрирован: 09.10.2014
for (int i = 0; i < 8; i++) 
{
   // 1. Дождаться нулевого значения на входе
   
   // 2. Дождаться единичного значения на входе
   
   // 3. delayMicros( 50 );

   // 4. Прочитать со входа значение бита [ i ]
}

Вот, по-моему как-то так. Ну и проверку тайм-аутов конечно добавить.

А ещё, решите всё-таки, что функция возвращает - прочитанный байт, или признак ошибки/не_ошибки. И то и другое, одновременно, в результат типа uint8_t вряд ли уместится

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

iopq пишет:

теперь возращает 0

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

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Datak пишет:

for (int i = 0; i < 8; i++) 
{
   // 1. Дождаться нулевого значения на входе
   
   // 2. Дождаться единичного значения на входе
   
   // 3. delayMicros( 50 );

   // 4. Прочитать со входа значение бита [ i ]
}

Вот, по-моему как-то так. Ну и проверку тайм-аутов конечно добавить.

А ещё, решите всё-таки, что функция возвращает - прочитанный байт, или признак ошибки/не_ошибки. И то и другое, одновременно, в результат типа uint8_t вряд ли уместится

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

Datak
Offline
Зарегистрирован: 09.10.2014

DIYMan пишет:

В моём примере сверху просто переместить второй цикл ожидания наверх - и будет то, что вы описали

Да, смысл тот же - ожидания должно быть два - для фронта и для спада. Просто не успел прочитать то сообщение ))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

По одному фронту фиксируем micros, по другому сравниваем. Если и долго 1 или долго 0 то таймаут. 

функция должна возвращать ситуацию - байт принят правильно, или была ошибка.  Принятый байт должен быть в отдельной ячейке.

iopq
Offline
Зарегистрирован: 05.07.2016

http://www.ti.com/lit/an/slua408a/slua408a.pdf вот даташит. 

1. Прочитать высокий байт (H0)
2. Прочитать низкий байт (L0)
3. Снова прочитайте высокий байт (H1)
4. Если H1 = H0, то действительный 16-битный результат равен H0: L0
5. В противном случае снова прочитайте младший байт (L1), а действительный 16-битный результат - H1: L1.

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ясно же написано. Меряйте размеры ям. По свалу фиксируйте по подъему определяйте что у вас  0,1 или Break. точнее если появился Break, то у вас Адрес.

nik182
Offline
Зарегистрирован: 04.05.2015

А ещё написано: Выставляйте скорость UART 57600 и читайте 8 байт. Если байт больше 0xf8, то бит единица, если равен или меньше то 0. Посылать можнотакже.

iopq
Offline
Зарегистрирован: 05.07.2016

все что я понял я сделал вот так 

uint8_t readByte() {
 pinMode(2, INPUT);                        //DDRD &= ~_BV(2);     // Настроили пин на вход
 uint32_t byt_H0 =0, byt_L0 =0, byt_H1 =0;
////////////////////////////////////////////////////////////////////////////////////
 uint32_t tMicros = micros();
 uint32_t tmout_guard = 400;               // сторож таймаута
 while((PIND & _BV(2)) == LOW)          //ждем пока появится логический 1
{
if(!--tmout_guard)
 return false;                      // таймаут поймали
}
 byt_H0 = micros() - tMicros;      //запомнили время высокого байта (бита!)
 Serial.println("byt_H0");
 Serial.println(byt_H0);
/////////////////////////////////////////////////////////////////////////////////////
 tMicros = micros();
 tmout_guard = 400;               // сторож таймаута
 while((PIND & _BV(2)) != LOW)          //ждем пока появится логический 0
{
if(!--tmout_guard)
 return false;                      // таймаут поймали
}
 byt_L0 = micros() - tMicros;      //запомнили время низкого байта (бита!)
 Serial.println("byt_L0");
 Serial.println(byt_L0);
////////////////////////////////////////////////////////////////////////////////////////
 tMicros = micros();
 tmout_guard = 400;               // сторож таймаута
 while((PIND & _BV(2)) == LOW)          //ждем пока появится логический 1
{
if(!--tmout_guard)
 return false;                      // таймаут поймали
}
 byt_H1 = micros() - tMicros;   //запомнили время второго высокого байта (бита!)
 Serial.println("byt_H1");
 Serial.println(byt_H1);
///////////////////////////////////////////////////////////////////////////////////////// 
 Serial.println("END");
}

получаю 

byt_H0
4
byt_L0
12
byt_H1
48
END
byt_H0
0
byt_L0
8
byt_H1
4
END
byt_H0
0
byt_L0
8
byt_H1
4
END
byt_H0
4
byt_L0
4
byt_H1
4
END
byt_H0
4
byt_L0
12
byt_H1
64
END
byt_H0
4
byt_L0
12
byt_H1
56
END

 

iopq
Offline
Зарегистрирован: 05.07.2016
1. Прочитать высокий байт (H0)
2. Прочитать низкий байт (L0)
3. Снова прочитайте высокий байт (H1)
4. Если H1 = H0, то действительный 16-битный результат равен H0: L0
5. В противном случае снова прочитайте младший байт (L1), а действительный 16-битный результат - H1: L1.

как я это понимаю -

1. прочитать бит  1 (H0)

2. прочитать бит 0  (L0)

3. прочитать бит 1 (H1)

4. if (H1 == H0) result LOW;

else 

5. прочитать бит 0  (L1) result HIGH;

я на картинке обозначил все возможные 0 и 1 цифрами. подскажите - взглядом я вижу что там содержится 01011000 а преобразовать с помощью алгоритма не могу. чтение бита H0 начинается с цифры 1 на рисунке? допустим это так и читаем бит L0 под цифрой 2 и бит H1 под цифрой 3. допустим тайминги 1 и 3 цифры на картинке одинаковы следовательно пишем в переменную 0. а вот дальше мы запускаем инструкцию сначала т.е пропускаем бит под цифрой 4, читаем 5, 6, 7 - 5 и 7 не равны следовательно читаем 8 и записываем 1? вроде пока логично и совпадает с реальностью. далее опять сначала - читаем 9, 10, 11 => 9 и 11 равны записываем 0. снова пропускаем 12, читаем 13, 14, 15 => 13 и 15 равны записываем 1 ну а дальше уже и читать то нечего. хрень какая то. да и странно что в даташите описана процедура чтения для 16 бит а у меня все же 8 бит. а про 8 бит ничего и не сказано

iopq
Offline
Зарегистрирован: 05.07.2016

мне кажется я на верном пути 

uint8_t readByte() {
 pinMode(2, INPUT);                        //DDRD &= ~_BV(2);     // Настроили пин на вход
 int bittimeH[8]={};
 int bittimeL[8]={};
for (int i = 0; i < 8; i++) {
 uint32_t tMicros = micros();
 uint32_t tmout_guard = 400;               // сторож таймаута
 while((PIND & _BV(2)) != LOW)          //ждем пока появится логический 0
{
if(!--tmout_guard)
 return false;                      // таймаут поймали
}
 bittimeL[i] = micros() - tMicros;      //запомнили время низкого байта (бита!)

 tMicros = micros();
 tmout_guard = 400;               // сторож таймаута
 while(!(PIND & _BV(2)) != LOW)          //ждем пока появится логический 1
{
if(!--tmout_guard)
 return false;                      // таймаут поймали
}
 bittimeH[i] = micros() - tMicros;      //запомнили время высокого байта (бита!)

} 
 Serial.println("************Start**********");
 Serial.println(bittimeL[0]);
 Serial.println(bittimeH[0]); 
 Serial.println(bittimeL[1]);
 Serial.println(bittimeH[1]);
 Serial.println(bittimeL[2]);
 Serial.println(bittimeH[2]);
 Serial.println(bittimeL[3]);
 Serial.println(bittimeH[3]);
 Serial.println(bittimeL[4]);
 Serial.println(bittimeH[4]); 
 Serial.println(bittimeL[5]);
 Serial.println(bittimeH[5]);
 Serial.println(bittimeL[6]);
 Serial.println(bittimeH[6]);
 Serial.println(bittimeL[7]);
 Serial.println(bittimeH[7]);
 Serial.println("************END***********"); 
}
************Start**********
144 1
128 2
72  3
56  4
144 5
124 6
76  7
56  8
144 9
52  10
148 11
124 12
76  13
120 14
76  15
124 16
************END***********

iopq
Offline
Зарегистрирован: 05.07.2016

что-то опять не догоняю откуда берется бит 1 с картинки. ладно я опять напутал единицы и нули но поменяв их местами стало только хуже. 

************Start**********
bittimeL[0]: 4     - откуда это вообще взялось
bittimeH[0]: 136   - 1 на картинке и т.д
124
76
52
148
124
76
52
148
52
148
124
76
124
76
************END***********

мне ведь бит (на картинке 1) вообще не нужен. для меня гораздо ценнее 17ый бит. не понимаю ведь по условию функции 

 while((PIND & _BV(2)) == LOW)          //ждем пока появится логический 0
{
if(!--tmout_guard)
 return false;                      // таймаут поймали
}
 bittimeL[i] = micros() - tMicros;      //запомнили время низкого байта (бита!)

у меня должен прочитаться только второй бит с картинки и далее...

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

http://forum.arduino.cc/index.php?action=dlattach;topic=262365.0;attach=...
В последнем сообщении ссылка на зип с библиотекой и примером.
Поэтому я и спрашивал про даташит. Берете библиотеку и разбираетесь если Вам интересно.

iopq
Offline
Зарегистрирован: 05.07.2016

спасибо конечно но я что зря третью ночь сижу что бы вот так взять библиотеку? у меня не стоит задача "что бы работало". хочу понимать как оно работает и как подобное создавать не имея даташитов.