Перейти к содержанию
    

Всем привет!

Я только начинаю свой путь. Пишу в Codevisionavr 3.12. В сети кое как нашёл пример по работе с dht11, но он на прерываниях. Вся система из-за этого висит т.к. постоянно генерирует прерывание датчик. Прошу тыкнуть меня что мне нужно исправить.

Большое спасибо

modul.txt

post-81348-1416849516_thumb.png

Изменено пользователем Stiner

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прошу тыкнуть меня что мне нужно исправить.

В вашем исходнике ни одного обработчика прерываний ... нет ! О каких прерываниях вы говорите ?

Если вы хотите работать по прерываниям с I2C на AVR, то сразу скажу, что это не так просто. У Атмела есть апп.ноуты на эту тему, поищите. О сложности я предупредил. Если нет острой необходимости в работе по прерываниям, то я бы вам посоветовал реализовать I2C чисто программно, а не использовать встроенный в АВР аппаратный модуль.

 

Да, подтяните линию данных датчика к его линии питания (резистором на 4.7КОм) ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если вы хотите работать по прерываниям с I2C на AVR, то сразу скажу, что это не так просто. У Атмела есть апп.ноуты на эту тему, поищите. О сложности я предупредил. Если нет острой необходимости в работе по прерываниям, то я бы вам посоветовал реализовать I2C чисто программно, а не использовать встроенный в АВР аппаратный модуль.

 

Насколько я поняла ситуацию, у датчика DHT11 интерфейс не I2C, а 1-Wire. Разница велика - у 1-Wire клока нет вообще.

 

P.S. Своими бы руками задушила тех, кто экономит провода за счет зверского усложнения протокола, делая его совсем уж заумным и ненадежным. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я поняла ситуацию, у датчика DHT11 интерфейс не I2C, а 1-Wire.

P.S. Своими бы руками задушила тех, кто экономит провода за счет зверского усложнения протокола, делая его совсем уж заумным и ненадежным. :)

Я тоже через какое-то время сообразил, что там не I2C (провод-то один), но уже не хотел редактировать сообщение.

Два слова о реализации 1-Wire в Codevision. Огромный недостаток - библиотечные функции, поставляемые с CV, нельзя прерывать, иначе собьется обмен. Для себя я эту проблему решил, написав свою реализацию 1-Wire для обмена с DS1820 ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там даже не 1-wire,а какой-то свой протокол в котором я не могу пока разобраться.

Вот описание. Вроде, все более-менее понятно и вполне можно написать свою реализацию:

http://www.micro4you.com/files/sensor/DHT11.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Stiner, поищите в инете библиотеки для Arduino по подключению к ней этого датчика. Некоторые снабжены хорошими комментариями.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Stiner, поищите в инете библиотеки для Arduino по подключению к ней этого датчика. Некоторые снабжены хорошими комментариями.

 

Так есть оно. Хотя бы это:

Подключение датчика температуры и влажности DHT11 к Arduino

Но что толку, если там все заточено под ардуинов "BIOS"? Т.е. это уже не программа, а скетч для Ардуины. Соответственно этому, он не в прошивку зашивается, а загружается через UART или USB. Да и собой представляет не код, а вызовы каких-то стандартных для Ардуино функций.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но что толку, если там все заточено под ардуинов "BIOS"? Т.е. это уже не программа, а скетч для Ардуины.

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Вообще-то не совсем к нулю. Вот тут нашла "библиотеку" (так называется у Ардуин уже скопилированный и загруженный в прошивку модуль, к которому в скетче обращаются, как к объекту), которая с этим DHT11 работает:

https://github.com/amperka/dht/tree/master/lib/dht

В принципе там не так-то сложно, т.к. язык С++, а кода мало.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Не люблю "черных ящиков" там, где они не оправданы. В данном случае задача обмена из разряда простейших и может быть решена без всяких высокоуровневых средств. Это даст понимание деталей того, как именно происходит обмен, повысит качество итогового продукта и упростит его сопровождение. А С++ и объекты в такой задаче - это как экскаватор в детской песочнице ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вод код позаимствованный именно из библиотеки для 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;
}

Изменено пользователем Dust112

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я находил сотни реализаций для Arduino, но у меня не arduino и код в codevisionavr. В связи с этим и есть проблемы. Я реализовал как смог, но не получается по этому и прошу помоши.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... но у меня не arduino и код в codevisionavr. В связи с этим и есть проблемы. Я реализовал как смог, но не получается по этому и прошу помоши.

Повторю два надоедливых совета:

1. Подтяните линию данных датчика к его линии питания (резистором на 4.7КОм).

2. Откройте даташит на датчик (выше я дал на него ссылку), изучите его и напишите свою реализацию. Там работы на день, от силы. Вы на общение на форуме гораздо больше времени потратите ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Повторю два надоедливых совета:

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];
}

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...