Stiner 0 24 ноября, 2014 Опубликовано 24 ноября, 2014 (изменено) · Жалоба Всем привет! Я только начинаю свой путь. Пишу в Codevisionavr 3.12. В сети кое как нашёл пример по работе с dht11, но он на прерываниях. Вся система из-за этого висит т.к. постоянно генерирует прерывание датчик. Прошу тыкнуть меня что мне нужно исправить. Большое спасибо modul.txt Изменено 24 ноября, 2014 пользователем Stiner Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Прошу тыкнуть меня что мне нужно исправить. В вашем исходнике ни одного обработчика прерываний ... нет ! О каких прерываниях вы говорите ? Если вы хотите работать по прерываниям с I2C на AVR, то сразу скажу, что это не так просто. У Атмела есть апп.ноуты на эту тему, поищите. О сложности я предупредил. Если нет острой необходимости в работе по прерываниям, то я бы вам посоветовал реализовать I2C чисто программно, а не использовать встроенный в АВР аппаратный модуль. Да, подтяните линию данных датчика к его линии питания (резистором на 4.7КОм) ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 46 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Если вы хотите работать по прерываниям с I2C на AVR, то сразу скажу, что это не так просто. У Атмела есть апп.ноуты на эту тему, поищите. О сложности я предупредил. Если нет острой необходимости в работе по прерываниям, то я бы вам посоветовал реализовать I2C чисто программно, а не использовать встроенный в АВР аппаратный модуль. Насколько я поняла ситуацию, у датчика DHT11 интерфейс не I2C, а 1-Wire. Разница велика - у 1-Wire клока нет вообще. P.S. Своими бы руками задушила тех, кто экономит провода за счет зверского усложнения протокола, делая его совсем уж заумным и ненадежным. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Насколько я поняла ситуацию, у датчика DHT11 интерфейс не I2C, а 1-Wire. P.S. Своими бы руками задушила тех, кто экономит провода за счет зверского усложнения протокола, делая его совсем уж заумным и ненадежным. :) Я тоже через какое-то время сообразил, что там не I2C (провод-то один), но уже не хотел редактировать сообщение. Два слова о реализации 1-Wire в Codevision. Огромный недостаток - библиотечные функции, поставляемые с CV, нельзя прерывать, иначе собьется обмен. Для себя я эту проблему решил, написав свою реализацию 1-Wire для обмена с DS1820 ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stiner 0 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Там даже не 1-wire,а какой-то свой протокол в котором я не могу пока разобраться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Там даже не 1-wire,а какой-то свой протокол в котором я не могу пока разобраться. Вот описание. Вроде, все более-менее понятно и вполне можно написать свою реализацию: http://www.micro4you.com/files/sensor/DHT11.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dust112 0 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Stiner, поищите в инете библиотеки для Arduino по подключению к ней этого датчика. Некоторые снабжены хорошими комментариями. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 46 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Stiner, поищите в инете библиотеки для Arduino по подключению к ней этого датчика. Некоторые снабжены хорошими комментариями. Так есть оно. Хотя бы это: Подключение датчика температуры и влажности DHT11 к Arduino Но что толку, если там все заточено под ардуинов "BIOS"? Т.е. это уже не программа, а скетч для Ардуины. Соответственно этому, он не в прошивку зашивается, а загружается через UART или USB. Да и собой представляет не код, а вызовы каких-то стандартных для Ардуино функций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Но что толку, если там все заточено под ардуинов "BIOS"? Т.е. это уже не программа, а скетч для Ардуины. И учебная ценность такого решения близка к нулю. Вместо изучения протокола и его реализации предлагается использовать некие "черные ящики". Иногда, конечно, такой подход может быть оправдан, но не в таком же простейшем случае ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 46 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба И учебная ценность такого решения близка к нулю. Вместо изучения протокола и его реализации предлагается использовать некие "черные ящики". Иногда, конечно, такой подход может быть оправдан, но не в таком же простейшем случае ... Вообще-то не совсем к нулю. Вот тут нашла "библиотеку" (так называется у Ардуин уже скопилированный и загруженный в прошивку модуль, к которому в скетче обращаются, как к объекту), которая с этим DHT11 работает: https://github.com/amperka/dht/tree/master/lib/dht В принципе там не так-то сложно, т.к. язык С++, а кода мало. Конечно, он там зовет еще функции от других модулей, но в данном случае не так-то сложно догадаться, что они делают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 25 ноября, 2014 Опубликовано 25 ноября, 2014 · Жалоба Конечно, он там зовет еще функции от других модулей, но в данном случае не так-то сложно догадаться, что они делают. Не люблю "черных ящиков" там, где они не оправданы. В данном случае задача обмена из разряда простейших и может быть решена без всяких высокоуровневых средств. Это даст понимание деталей того, как именно происходит обмен, повысит качество итогового продукта и упростит его сопровождение. А С++ и объекты в такой задаче - это как экскаватор в детской песочнице ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dust112 0 26 ноября, 2014 Опубликовано 26 ноября, 2014 (изменено) · Жалоба Вод код позаимствованный именно из библиотеки для Arduino. Великолепно работающий в моем проекте. unsigned char DHT_Read(int *temperature, int *humidity, uint8_t *sign) { int temp; uint8_t data[5] = {0}; if (SENSOR_is_low) { // bus not free return 1; } SENSOR_sda_out; SENSOR_sda_low; // MCU start signal _delay_ms(20); // start signal (pull sda down for min 0.8ms and maximum 20ms) SENSOR_sda_in; // Bus master has released time min: 20us, typ: 30us, max: 200us uint8_t timeout = 200; while(SENSOR_is_hi) {_delay_us(1); if (!timeout--) {return 1;}} // AM2302 response signal min: 75us typ:80us max:85us timeout = 85; while(SENSOR_is_low) {_delay_us(1); if (!timeout--) {return 1;}} // response to low time timeout = 85; while(SENSOR_is_hi) {_delay_us(1); if (!timeout--) {return 1;}} // response to high time /* * time in us: min typ max * signal 0 high time: 22 26 30 (bit=0) * signal 1 high time: 68 70 75 (bit=1) * signal 0,1 down time: 48 50 55 */ // uint8_t data[5]={0}; for(uint8_t i = 0; i < 5; i++) { uint8_t sensor_byte = 0; for(uint8_t j = 1; j <= 8; j++) // get 8 bits from sensor { timeout = 55; while(SENSOR_is_low) {_delay_us(1); if (!timeout--) {return 1;}} // signal "0", "1" low time _delay_us(30); sensor_byte <<= 1; // add new lower byte if (SENSOR_is_hi) // if sda high after 30us => bit=1 else bit=0 { sensor_byte |= 1; timeout = 45; // 30us - 75us = 45us while(SENSOR_is_hi) {_delay_us(1); if (!timeout--) {return 1;}} } } data[i] = sensor_byte; } uint8_t sum = data[0] + data[1] + data[2] + data[3]; if(data[4] != sum) return DHT_ERROR; temp = data[2] & 0x7F; temp = (temp << 8)+data[3]; if (data[2] & 0x80) { // temp *= -1; *sign = 0; } else { *sign = 1; } *temperature = temp; temp = (data[0] << 8)+data[1]; *humidity = temp; return DHT_SUCCESS; } Изменено 26 ноября, 2014 пользователем Dust112 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stiner 0 26 ноября, 2014 Опубликовано 26 ноября, 2014 · Жалоба Я находил сотни реализаций для Arduino, но у меня не arduino и код в codevisionavr. В связи с этим и есть проблемы. Я реализовал как смог, но не получается по этому и прошу помоши. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 26 ноября, 2014 Опубликовано 26 ноября, 2014 · Жалоба ... но у меня не arduino и код в codevisionavr. В связи с этим и есть проблемы. Я реализовал как смог, но не получается по этому и прошу помоши. Повторю два надоедливых совета: 1. Подтяните линию данных датчика к его линии питания (резистором на 4.7КОм). 2. Откройте даташит на датчик (выше я дал на него ссылку), изучите его и напишите свою реализацию. Там работы на день, от силы. Вы на общение на форуме гораздо больше времени потратите ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stiner 0 26 ноября, 2014 Опубликовано 26 ноября, 2014 (изменено) · Жалоба Повторю два надоедливых совета: 1. Подтяните линию данных датчика к его линии питания (резистором на 4.7КОм). 2. Откройте даташит на датчик (выше я дал на него ссылку), изучите его и напишите свою реализацию. Там работы на день, от силы. Вы на общение на форуме гораздо больше времени потратите ... 1. Подтянул, просто в схеме не отразил 2. Я написал своюй реализацию, но датчик так и молчит, не отзываясь на запрос передачи... int data[5], counter = 0, sum = 0, i = 0; int D_1=123, D_2=456; void DHT_Read_Data(){ // Очистить массив контролльных сумм data[0] = data[1] = data[2] = data[3] = data[4] = 0; DDRD.7 = 0; // делаем вывод мк выходом // Подготока шины для передачи PORTD.7 = 1; delay_ms(250); // Инициализаруем передачу PORTD.7 = 0; // прижимаем к земле не менее чем на 18 мс delay_ms(25); PORTD.7 = 1; // поднимаем и ждём реакции датчика delay_ms(40); DDRD.7 = 1; // делаем выход мк входом delay_ms(60); // начинаем саму передачу if (PIND.7 ==1) { // если на выходе всё так же 1, значит датчик не ответил и мы выодим из процедуры return; } // если всё ок, идём дальше и ждём пока датчик не подымет до 1 и не начнет передачу while( PIND.7 == 1) { delay_ms(30); // ждём появления нуля на шине первый раз while (counter <= 40) // принимаем 40 бит данных { while( PIND.7 == 0) { // запускаем по битовый приём if( PIND.7 == 1) { data[i] <<= 0; } delay_ms(40); // если 1 держится более 28 мкс, то передаётся 1 if (PIND.7 == 1) { data[i] <<= 1; } } // подсчёт значения для числа CRC if (counter < 8) i = 0; else if (counter <16) i = 1; else if (counter < 24) i = 2; else if (counter < 32) i = 3; else i = 4; counter++; // увеличиваем счётчик на один delay_ms(30); // ждём появления нуля на шине } } // проверяем всё sum = data[0] + data[1] + data[2] + data[3]; if( sum != data[4]){ data[0] = 999; } D_1 = data[0]; D_2 = data[2]; } Изменено 26 ноября, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться