Умный Дом по Ethernet

Обсуждение статей, технологий домашней автоматизации, программных и аппаратных решений
Andrey_B
Администратор
Сообщения: 5327
Зарегистрирован: 18 мар 2011, 12:06

Re: Умный Дом по Ethernet

Сообщение Andrey_B » 04 сен 2013, 18:10

kID и Urbas81, давайте еще раз уточним. Если тип порта установить Dsen, но датчика на нем нет, то устройство у вас вешается.
Правка исходника (комментирование указанных мною строк) эту ситуацию исправляет. Так?

3.08b1 вы заливали уже скомпилированную прошивку или компилировали сами. Что будет, если залить готовую? Будет ли аналогичное поведение.
Если компилировали сами, то вылезали ли варнинги?

kID
Сообщения: 69
Зарегистрирован: 29 май 2013, 19:36
Откуда: Новосибирск

Re: Умный Дом по Ethernet

Сообщение kID » 04 сен 2013, 18:17

Andrey_B писал(а):kID и Urbas81, давайте еще раз уточним.
1. Если тип порта установить Dsen, но датчика на нем нет, то устройство у вас вешается.
Да
2. Правка исходника (комментирование указанных мною строк) эту ситуацию исправляет. Так?
Да
3. 3.08b1 вы заливали уже скомпилированную прошивку или компилировали сами.
Компилировал сам
4. Что будет, если залить готовую? Будет ли аналогичное поведение.
Если не сможет Urbas81, то попробую залить (просто живу в другой подсети и быстро перенастроить устройство немогу)
5. Если компилировали сами, то вылезали ли варнинги?
Без варнингов.

Urbas81
Сообщения: 313
Зарегистрирован: 28 авг 2012, 14:22

Re: Умный Дом по Ethernet

Сообщение Urbas81 » 05 сен 2013, 00:02

Докладываю:

-взял последний исходник 3.08b1 заменил ip, последовательность портов, и закоментил 2 строчки в hw_dht.c результат-ничего не зависает, даже без датчика, но при обновлении проскакивают нули.
-раскоментил 2 строчки в hw_dht.c, после назначения DSen при следующем открывании порта зависает даже когда датчик подключен. Готовую прошивку не заливал, т.к у меня подсеть 192.168.1. компиляция прошла без предуприждений, все чисто.

Andrey_B
Администратор
Сообщения: 5327
Зарегистрирован: 18 мар 2011, 12:06

Re: Умный Дом по Ethernet

Сообщение Andrey_B » 05 сен 2013, 00:13

Это хорошо, что зависает независимо от того, подключен ли датчик или нет, иначе это было совсем уж странно.
Есть подозрение, что это какие-то разночтения компиляторов. Очень любопытно было бы протестировать скомпилированную мною прошивку, так как у меня ничего подобного не наблюдается.
Сообщите, каким компилятором пользуетесь вы (ОС, версия и т.д.)

Urbas81
Сообщения: 313
Зарегистрирован: 28 авг 2012, 14:22

Re: Умный Дом по Ethernet

Сообщение Urbas81 » 05 сен 2013, 00:23

WXP, компилятор WinAVR-20100110, если скомпилируете с ip 192.168.1.14 смогу проверить.

alexsis_76

Re: Умный Дом по Ethernet

Сообщение alexsis_76 » 05 сен 2013, 01:37

перед этим
while (isr_flag == 0)
_delay_us(1);
есть
isr_flag = 0;
т е сначала мы присваиваем isr_flag = 0;а в следующей строчке сравниваем с 0 , while(пока)isr_flag == 0 цикл выполняется пока условие истинно а оно истинно всегда,устройство виснетне зависимо от того есть датчик или нет, по моему так
попробуйте объявить isr_flag volatile

Andrey_B
Администратор
Сообщения: 5327
Зарегистрирован: 18 мар 2011, 12:06

Re: Умный Дом по Ethernet

Сообщение Andrey_B » 05 сен 2013, 11:40

Виноват оптимизатор компилятора WinAVR. Последняя версия 4.3.3
Компилятор версии 4.7.2 в Debian 7 более корректно прочитал код. Кстати, и размер прошивки получается меньше.
alexsis_76 правильно подсказал - директива volatile для переменной isr_flag, дает понять компилятору, чтобы они не занимался самодеятельностью.

Пробуйте
http://ab-log.ru/files/File/ip_manager3 ... _beta2.zip

Urbas81
Сообщения: 313
Зарегистрирован: 28 авг 2012, 14:22

Re: Умный Дом по Ethernet

Сообщение Urbas81 » 05 сен 2013, 13:59

В железе пока проверить не могу, но в симуляторе не зависает, предыдущая версия висла. А по поводу чтения 0, я так понимаю теперь эта проблема решена, и вчера нули появлялись когда мы закоментили 2 строчки в hw_dht.c?

alexsis_76

Re: Умный Дом по Ethernet

Сообщение alexsis_76 » 05 сен 2013, 15:13

Виноват оптимизатор компилятора WinAVR
компилятор не в чем не виноват ,volatile обычная ошибка кодеров

Andrey_B
Администратор
Сообщения: 5327
Зарегистрирован: 18 мар 2011, 12:06

Re: Умный Дом по Ethernet

Сообщение Andrey_B » 05 сен 2013, 15:33

alexsis_76, во-первых, как я уже сказал, avr-gcc 4.7.2 прекрасно компилирует работающий код и без volatile. Последний добавлен только для обеспечения совместимости с устаревшим WinAVR, который в последний раз обновлялся в январе 2010 года. Очевидно, что его оптимизатор работает менее качественно и не видит, что значение isr_flag меняется в коде прерывания. Во-вторых, в данном случае и в контексте решаемой задачи это совершенно осознанное действие, которое я не считаю ошибкой. И, честно говоря, не горю желанием тратить время на эту полемику.

kID
Сообщения: 69
Зарегистрирован: 29 май 2013, 19:36
Откуда: Новосибирск

Re: Умный Дом по Ethernet

Сообщение kID » 05 сен 2013, 19:08

Andrey_B писал(а):Виноват оптимизатор компилятора WinAVR. Последняя версия 4.3.3
Пробуйте
http://ab-log.ru/files/File/ip_manager3 ... _beta2.zip
Попробовал
Собрал под winavr - варнингов нет.
При тестировании - зависаний нет ни на порту, где есть датчик, ни на пустом.
Только 1 раз из ~ 50 получил значения 0.

Urbas81
Сообщения: 313
Зарегистрирован: 28 авг 2012, 14:22

Re: Умный Дом по Ethernet

Сообщение Urbas81 » 06 сен 2013, 10:20

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

kID
Сообщения: 69
Зарегистрирован: 29 май 2013, 19:36
Откуда: Новосибирск

Re: Умный Дом по Ethernet

Сообщение kID » 06 сен 2013, 18:56

Andrey_B помогите пожалуйста.
У меня существует следующая ошибка в работе устройства
При работе с портом физически использующим порт B1 (у меня это P10) в режиме IN не происходит увеличения счетчика нажатий ни в одном из режимов. При этом индикация включенности порта на web странице работает нормально. Так же при назначении порту какого-то действия на другой порт (например 0:2) изменения состояния управляемого порта не происходит. Кроме этого при назначении аналогичного действия на другой порт IN (например P9 IN 0:2) при многократном включении порта P9 иногда происходит увеличение счетчика P10. Каких либо отклонений в работе B1 в режиме OUT не заметил.
Связывал это с вашим переходом на новую версию библиотек, однако вчера обновился до GCC 4.7.2. – проблема осталась.
Насколько я помню раньше порт B1 выполнял функцию индикации, поэтому бегло просмотрел исходники но хвостов оттуда не обнаружил.

DOCSIMUS
Сообщения: 184
Зарегистрирован: 07 сен 2013, 01:02

Re: Умный Дом по Ethernet

Сообщение DOCSIMUS » 07 сен 2013, 01:14

kID писал(а):Andrey_B помогите пожалуйста.
У меня существует следующая ошибка в работе устройства
При работе с портом физически использующим порт B1 (у меня это P10) в режиме IN не происходит увеличения счетчика нажатий ни в одном из режимов. При этом индикация включенности порта на web странице работает нормально. Так же при назначении порту какого-то действия на другой порт (например 0:2) изменения состояния управляемого порта не происходит. Кроме этого при назначении аналогичного действия на другой порт IN (например P9 IN 0:2) при многократном включении порта P9 иногда происходит увеличение счетчика P10. Каких либо отклонений в работе B1 в режиме OUT не заметил.
Связывал это с вашим переходом на новую версию библиотек, однако вчера обновился до GCC 4.7.2. – проблема осталась.
Насколько я помню раньше порт B1 выполнял функцию индикации, поэтому бегло просмотрел исходники но хвостов оттуда не обнаружил.
По-моему проблема в процедуре обработки прерывания по таймеру ISR(TIMER1_COMPA_vect). Только начал разбираться в прошивке. Но обратил внимание на следующее:
В этой процедуре производится чтение портов и установка различных переменных в зависимости от их состояния. Вижу только опрос двух портов D и C.

i = ~PIND;
...
i = ~PINC;

Порт B не опрашивается.

А далее в процедуре main в блоке где происходит обработка нажатия кнопки

if ( _port_type == 0 )
{
// Обработка нажатия кнопки.
if (port_letter == 'D')
{
my_mask = get_key_press(1 << port_num);
my_mask2 = get_key_release(1 << port_num);
}
else
{
my_mask = get_key_press2(1 << port_num);
my_mask2 = get_key_release2(1 << port_num);
}
}

тут вызываются процедуры нажатия/отпускания
причем если это порт D, то одни, а все остальные порты (куда входит и порт B) другие
в самих же процедурах обработки нажатия/отпускания используются переменные, которые изменяются как я уже и писал в обработчике прерывания таймера
но там порт B не опрашивается

ошибка?

Andrey_B
Администратор
Сообщения: 5327
Зарегистрирован: 18 мар 2011, 12:06

Re: Умный Дом по Ethernet

Сообщение Andrey_B » 07 сен 2013, 09:47

В целом DOCSIMUS правильно обозначил причину.
Попробуйте
http://ab-log.ru/files/File/ip_manager3 ... _beta1.zip

DOCSIMUS
Сообщения: 184
Зарегистрирован: 07 сен 2013, 01:02

Re: Умный Дом по Ethernet

Сообщение DOCSIMUS » 07 сен 2013, 19:46

Еще есть место в прошивке непонятное для меня:
в процедуре main

temp_check_flag = eeprom_read_byte(&ee_temp_check);
if ( temp_check_flag == 1 && _alarm_temp != 255 && _sip_addr[0] != 255 && _sip_addr[0] > 0 )
temp_check_flag = 1;

такое условие-действие не имеет смысла
т.к. ни при каких условиях temp_check_flag изменен не будет
это можно упростить до

if ( temp_check_flag == 1)
temp_check_flag = 1;

и станет понятно почему

kID
Сообщения: 69
Зарегистрирован: 29 май 2013, 19:36
Откуда: Новосибирск

Re: Умный Дом по Ethernet

Сообщение kID » 08 сен 2013, 07:57

Andrey_B писал(а): Попробуйте
http://ab-log.ru/files/File/ip_manager3 ... _beta1.zip
Да ошибка исправлена. Спасибо.

Andrey_B
Администратор
Сообщения: 5327
Зарегистрирован: 18 мар 2011, 12:06

Re: Умный Дом по Ethernet

Сообщение Andrey_B » 09 сен 2013, 00:47


DOCSIMUS
Сообщения: 184
Зарегистрирован: 07 сен 2013, 01:02

Re: Умный Дом по Ethernet

Сообщение DOCSIMUS » 10 сен 2013, 22:32

В main есть

Код: Выделить всё

input_state    = ~PIND;
то ли это не нужно (не уверен)
то ли надо добавить (не уверен также)

Код: Выделить всё

input_state2    = ~PINC;
input_state3    = ~PINB;
В main есть

Код: Выделить всё

if (port_letter == 'D')
{
	my_mask = get_key_press(1 << port_num);
	my_mask2 = get_key_release(1 << port_num);
}
else if (port_letter == 'C')
{
	my_mask = get_key_press2(1 << port_num);
	my_mask2 = get_key_release2(1 << port_num);
}
else
{
	my_mask = get_key_press3(1 << port_num);
	my_mask2 = get_key_release3(1 << port_num);
}
по-моему надо так

Код: Выделить всё

if (port_letter == 'D')
{
	my_mask = get_key_press(1 << port_num);
	my_mask2 = get_key_release(1 << port_num);
}
else if (port_letter == 'C')
{
	my_mask = get_key_press2(1 << port_num);
	my_mask2 = get_key_release2(1 << port_num);
}
else if (port_letter == 'B')
{
	my_mask = get_key_press3(1 << port_num);
	my_mask2 = get_key_release3(1 << port_num);
}

DOCSIMUS
Сообщения: 184
Зарегистрирован: 07 сен 2013, 01:02

Re: Умный Дом по Ethernet

Сообщение DOCSIMUS » 10 сен 2013, 22:46

Кстати, Андрей.
Можно немного соптимизировать код.

Вместо

Код: Выделить всё

char get_key_press( char input_mask )
char get_key_press2( char input_mask )
char get_key_press3( char input_mask )
char get_key_release( char input_mask )
char get_key_release2( char input_mask )
char get_key_release3( char input_mask )
использовать одну

Код: Выделить всё

char get_key_press_release( char* in_pr, char input_mask )
{
	cli();
	input_mask &= *in_pr;                // read key(s)
	*in_pr ^= input_mask;                // clear key(s)
	sei();
	return input_mask;
}
а в main вместо

Код: Выделить всё

char my_mask = '\0';
char my_mask2 = '\0';

if ( _port_type[i] == 0 )
{
if (port_letter == 'D')
					{
						my_mask = get_key_press(1 << port_num);
						my_mask2 = get_key_release(1 << port_num);
					}
					else if (port_letter == 'C')
					{
						my_mask = get_key_press2(1 << port_num);
						my_mask2 = get_key_release2(1 << port_num);
					}
					else if (port_letter == 'B')
					{
						my_mask = get_key_press3(1 << port_num);
						my_mask2 = get_key_release3(1 << port_num);
					}
...
использовать

Код: Выделить всё

char my_mask = '\0';
char my_mask2 = '\0';
char *in_p;
char *in_r;
if ( _port_type[i] == 0 )
{
    switch (port_letter)
					{
						case 'D':	in_p = &input_press; in_r = &input_release; break;
						case 'C':	in_p = &input_press2; in_r = &input_release2; break;
					     case 'B':	in_p = &input_press3; in_r = &input_release3; 
					}
					if (port_letter != 'A')
					{
						my_mask = get_key_press_release(in_p, 1 << port_num);
						my_mask2 = get_key_press_release(in_r, 1 << port_num);	
					}
...
у меня уменьшилось на около 160 байт

но это не принципиально
так... мысли вслух
Последний раз редактировалось DOCSIMUS 11 сен 2013, 09:58, всего редактировалось 2 раза.

Ответить