Файлы  •  Ссылки  •  Прошивки  •  Правила  •  Архив  •   FAQ  •  Участники  •  Поиск
Регистрация  •  Вход

AtTiny13 + DHT11 + TM1637. Странное поведение.

Список форумов » Разработка цифровых устройств
АвторСообщение
Kompas
Участник
Сообщения: 171




12-11-2016 08:06

Написал код для работы AtTiny13, DHT11, TM1637. Всё удачно уместилось в памяти микрухи. На первый взгляд всё работает. Данные передаются без сбоев, контрольная сумма в норме. Вот видео https://youtu.be/EhzBILnumkk, если кому интересно. Но обнаружилась проблема. Периодически, примерно каждые 5-6 запросов данных от датчика DHT11, показания влажности и температуры скачут. На 5 - 10 единиц могут прыгнуть. При этом рассогласования с контрольной суммой нет. Поначалу списал всё на "несерьезность" датчика, но... Залил тот же самый код в Ардуино Уно - нет никаких скачков. Цепляю датчик и дисплей обратно к тиньке - пляшут данные. Подключаю питание непосредственно от этой ардуинки - не помогает, скачут показания. Припаиваю непосредственно к датчику конденсатор по питанию 100 нФ, как рекомендуется в даташите, - бесполезно. Меняю на тиньке частоты: 1.2, 4.8, 9,6 Мгц - никакого результата. Кстати, по ходу дела, заметил еще одну странность: на 9.6 Мгц тинька в этой связке запускается только от 3 вольт, от пяти - не хочет. На дисплей при этом нужно подавать 5 вольт. В общем, у меня закончились предположения, пришел за помощью к вам. В чем подвох может быть, ведь на ардуинке с тем же питанием показания стабильны?
Код:
[SPOILER]
Код:

#define F_CPU 1200000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

unsigned char word_dht = 0x00;
unsigned char time_bit[40];
unsigned char data_dht[5];
unsigned char bit_dht;


#define Clkpin 3 //Clkpin TM1637
#define Datapin 2 // Datapin TM1637
#define PIN_DHT 0 //Пин датчика DHT

#define DispPort PORTB // обзываем порт

#define  BRIGHT_LCD 7  //Яркость дисплея от 0 до 7
      
      unsigned char _PointFlag;    //_PointFlag=1:the clock point on
      unsigned char _DispType;
      unsigned char DecPoint;
      unsigned char BlankingFlag;
   
      
static unsigned char TubeTab[10] = {0x3f,0x06,0x5b,0x4f,// знакогенератор
                           0x66,0x6d,0x7d,0x07,
                           0x7f,0x6f};//,0x77,0x7c,
                           //0x39,0x5e,0x79,0x71,
                          // 0x40,0x00};//0~9,A,b,C,d,E,F,"-"," " 

void TM1637_writeByte(char wr_data)// служебная функция записи данных по протоколу I2C, с подтверждением (ACK)
{
  unsigned char i;
    for(i=0;i<8;i++)       
  {
   DispPort &= ~(1<<Clkpin);
    if(wr_data & 0x01)
   { DispPort |= 1<<Datapin;}
    else {DispPort &= ~(1<<Datapin);}
   _delay_us(3);
    wr_data = wr_data>>1;     
    DispPort |= 1<<Clkpin;
   _delay_us(3); 
  } 
 
  DispPort &= ~(1<<Clkpin);
  _delay_us(5);
  DDRB &= ~(1<<Datapin);// если поменяете порт на какой-то другой кроме DispPort, то тут тоже все DDRB на другие DDRx менять надо будет
  while((PINB & (1<<Datapin)));
  DDRB |= (1<<Datapin);
  DispPort |= 1<<Clkpin;
  _delay_us(2);
  DispPort &= ~(1<<Clkpin); 
}

void TM1637_start(void) // просто функция "старт" для протокола I2C
{
   DispPort |= 1<<Clkpin;
   DispPort |= 1<<Datapin;
 _delay_us(2);
  DispPort &= ~(1<<Datapin);
}

void TM1637_stop(void) // просто функция "стоп" для протокола I2C
{
  DispPort &= ~(1<<Clkpin);
 _delay_us(2);
  DispPort &= ~(1<<Datapin);
_delay_us(2);
  DispPort |= 1<<Clkpin;;
_delay_us(2);
  DispPort |= 1<<Datapin;
}


void TM1637_init()// Инициализируем дисплей. Как оказалось, можно удалить из этого блока стандартной библиотеки практически всё, кроме инициализации пинов.
{
   DDRB |= (1<<Clkpin) | (1<<Datapin);
}

//---------------------------------------------------------------------
//Здесь код для датчика DHT11. Писал полностью сам.

void start_tmr_us()
{
TCNT0 = 0x00;
TCCR0B = 0x01; //Запускаем таймер0 с частотой 1,2 Мгц
}

void start_dht()                //Отправляем приветствие датчику
{
DDRB |= (1 << PIN_DHT);
DispPort |= (1 << PIN_DHT);
DispPort &= ~(1 << PIN_DHT);
_delay_ms(18);
DDRB &= ~(1 << PIN_DHT);
DispPort |= (1 << PIN_DHT);
while(PINB & (1 << PIN_DHT)){}
while(~PINB & (1 << PIN_DHT)){}
while(PINB & (1 << PIN_DHT)){}

}

void get_data()                            //Получаем 40 бит от датчика и записываем в массив
{
for(bit_dht = 0; bit_dht < 40; bit_dht++)
{
while(~PINB & (1 << PIN_DHT)){}
start_tmr_us();
while(PINB & (1 << PIN_DHT)){}
time_bit[bit_dht] = TCNT0;
}
}

void decoder_bit(){
unsigned char bit_number = 1;
unsigned char word_number = 0;
for(bit_dht = 0; bit_dht < 40; bit_dht++){  //дербаним наш массив из 40 бит (5 байтов), в котором записана длительность каждого полученного  бита

if(time_bit[bit_dht] > 50)                //Если длительность бита больше 28 мкс,
{
word_dht = word_dht << 1;            //сдвигаем байт влево и записываем в младший разряд 1
word_dht |= (1 << 0);
}else
{
word_dht = word_dht << 1;        //Если меньше 28 мкс, сдвигаем влево байт и записываем 0
word_dht &= ~(1 << 0);
}

if(bit_number == 8){                     //Если имеем дело с восьмым битом, записываем полученный байт в массив
data_dht[word_number] = word_dht;
word_number += 1;
bit_number = 0;       
}
bit_number +=1;
}
}



ISR (WDT_vect){
TM1637_writeByte(0x40);    //Выводим на дисплей Err1
TM1637_stop();
TM1637_start();
TM1637_writeByte(0xC0);
TM1637_writeByte(0x79);
TM1637_writeByte(0x50);
TM1637_writeByte(0x50);
TM1637_writeByte(0x06);
TM1637_stop();
TM1637_start();
TM1637_writeByte(0x8F);
TM1637_stop();
}




int main(void)
{
wdt_reset();            //Запускаем вотч дог
wdt_enable(WDTO_4S);
WDTCR |= (1 << WDTIE);
sei();
TM1637_init();
_delay_ms(1500);  //Зачем-то тупим немного. Иначе, вроде как, дисплей может не зажечься.
 
while(1)
{
start_dht();                         
get_data();
decoder_bit();
if((data_dht[0] + data_dht[1] + data_dht[2] + data_dht[3]) != data_dht[4])
{
   TM1637_writeByte(0x40);    //Выводим на дисплей Err0
   TM1637_stop();
   TM1637_start();
   TM1637_writeByte(0xC0);
   TM1637_writeByte(0x79);
   TM1637_writeByte(0x50);
   TM1637_writeByte(0x50);
   TM1637_writeByte(0x3f);
   TM1637_stop();
   TM1637_start();
   TM1637_writeByte(0x8F);
   TM1637_stop();
   _delay_ms(3500);
   wdt_reset();
   _delay_ms(3500);
   wdt_reset();   
}

TM1637_start();                     //Выводим на дисплей влажность. 
TM1637_writeByte(0x40);
TM1637_stop();
TM1637_start();
TM1637_writeByte(0xC0);
TM1637_writeByte(0x76);
TM1637_writeByte(0x00);
TM1637_writeByte(TubeTab[(data_dht[0] / 10) % 10]);
TM1637_writeByte(TubeTab[data_dht[0] % 10]);
TM1637_stop();
TM1637_start();
TM1637_writeByte(0x8F);
TM1637_stop();
_delay_ms(2000);
wdt_reset();

TM1637_start();                                    //Выводим на дисплей температуру
TM1637_writeByte(0x40);
TM1637_stop();
TM1637_start();
TM1637_writeByte(0xC0);
TM1637_writeByte(TubeTab[(data_dht[2] / 10) % 10]);
TM1637_writeByte(TubeTab[data_dht[2] % 10]);
TM1637_writeByte(0x63);
TM1637_writeByte(0x39);
TM1637_stop();
TM1637_start();
TM1637_writeByte(0x8F);
TM1637_stop();
_delay_ms(2000);
wdt_reset();
}
}

[/SPOILER]
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




12-11-2016 11:33

Пара вопросов:
1. Контрольная сумма чего имеется ввиду?
2. Как настроен и используется ли вач дог таймер?
Kompas
Участник
Сообщения: 171




12-11-2016 11:52

1. Датчик передает информацию следующим образом. Пять байтов. Первые четыре data_dht[0 - 3] - значение влажности и температуры. Последний пятый data_dht[4] - это сумма первых четырех для контроля ошибок передачи. На видео она высвечивается после влажности и температуры. В показанном здесь коде немного другой алгоритм, просто идет проверка контрольной суммы. Высвечивается ошибка, если сумма не совпадает с данными.
2. Вотч дог настроен на прерывания по переполнению. Если обрыв связи с датчиком, контроллер зависает в цикле ожидания, срабатывает программа обработки прерывания. На дисплей выводится Ошибка. Сброс.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




12-11-2016 12:45

Т.е. получается, что WDT не может быть причиной этих сбоев?

Более того! Получается, что те данные, которые выводятся на индикатор, это именно те самые данные, которые получаются с датчика т.к. сами данные и чексумм совпадает! Ну тогда надо смотреть на датчик! А не может ли быть такой вот сценарий... У датчика не может быть определено время преобразования? Я немного экспериментировал с преобразователями (АЦП) у которых в даташите указывается время преобразования и если при этом устроить им опрос раньше времени, то на выходе получаем кашу...
Kompas
Участник
Сообщения: 171




12-11-2016 13:04

Васисуалий писал:
Т.е. получается, что WDT не может быть причиной этих сбоев?

Более того! Получается, что те данные, которые выводятся на индикатор, это именно те самые данные, которые получаются с датчика т.к. сами данные и чексумм совпадает! Ну тогда надо смотреть на датчик! А не может ли быть такой вот сценарий... У датчика не может быть определено время преобразования? Я немного экспериментировал с преобразователями (АЦП) у которых в даташите указывается время преобразования и если при этом устроить им опрос раньше времени, то на выходе получаем кашу...

Да, я тоже предполагаю, что проблема кроется где-то непосредственно на этапе обработки параметров тока на измерительном элементе микросхемой датчика. Так как с передачей данных всё нормально. Но каким образом и что именно влияет на этот процесс - моих знаний не хватает.
В даташите датчика говорится, что запрашивать данные у датчика нужно не ранее одной секунды после подачи питания. В программе установлено 1,5 секунды. Интервалы запросов пробовал увеличивать вплоть до 20 секунд - не помогает. Да и на ардуинке то нет проблем. Наверное, нужно искать аппаратные отличия на портах Atmega328P и AtTiny13V. Но разве они есть?
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




12-11-2016 13:08

А чем тогда вообще отличается работа программы в "Дуньке" и в отдельном чипе "Тини"? Ведь по идее это практически одно и то же с точки зрения выполнения этой программы.?

Может стоит повергнуть эту алгебру осциллографом? помираю со смеху! Ну в смысле посмотреть, что происходит на линии передачи данных в одном и в другом случае? Да и по питанию глянуть... Ну вдруг?
Kompas
Участник
Сообщения: 171




12-11-2016 13:14

Отличие получается в частоте. Дунька на 16 МГц, Тинька проверялась максимум на 9,6 МГц. Ну и таймер считает на Дуньке с частотой 16/8 = 2 МГц. На тиньке 1,2 МГц. В остальном , вроде, все также. Имена битов в вотч доге только чуть отличаются. Осциллографа у меня нет. Если кто проверит - было бы хорошо)
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




12-11-2016 17:17

А если запихать тиньке кварц на 16 мег? Выпаять из дуньки на время, например? Ведь проц заработает, я практически уверен. Оставлять его там, конечно, не стОит, но попробовать можно?
Kompas
Участник
Сообщения: 171




12-11-2016 17:47

У меня есть такой кварц. Но, судя по даташиту, AtTiny13V максимум 10 МГц.



Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




12-11-2016 20:09

Есть? Ставь! Не сгорит, максимум, что плохого получится - не запустится ну или на границе реального предела будет глючить, но я почему то думаю, что реальный предел у него гораздо выше. Проверить хватит...
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




13-11-2016 00:56

Вьехал... Чет сразу не дошло... помираю со смеху! А ведь к тини13 не так то легко подключить внешний кварц?
Kompas
Участник
Сообщения: 171




13-11-2016 08:50

Собрал вчера снова макетку с тинькой. До сих пор ниодного скачка))) В чем была проблема , видимо, останется тайной. До этого ведь несколько раз все пересобирал. Проверял и дома, и на работе. Что еще заметил. На ардуинке стоит пальцем прижать контакты датчика, начинает выскакивать ошибка Err0 (ошибка контрольной суммы). На тиньке, как не прикасался, передача стабильно идет.
P.S. Зато после прикасаний скачки начались помираю со смеху!
Резистор подтяжки, может, внутренний убрать из программы.
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




13-11-2016 13:23

Осциллограф нужен категорически! Иначе любая подобная задача превращается в гадание на кофейной гуще! помираю со смеху!
Kompas
Участник
Сообщения: 171




14-11-2016 10:35

В общем, подключил датчик от другой линии питания. Стабильно поработал он у меня минут 15. Потом я нечаянно полярность перепутал и спалил микросхему датчика))) Ну... есть вероятность, что раздельное питание просто надо делать, чтобы не было проблем.
P.S. Если быть точнее, непосредственно с датчиком удар случился))
https://pp.vk.me/c638420/v638420594/cd9d/FmTYh21_C6s.jpg
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




14-11-2016 10:53

Бывает! Обидно, но так случается... Придется купить еще один! гы-гы

А вот с отдельным питанием вопрос - а почему? Категорически надо исследовать это дело осциллографом! Я уверен, что все грабли всплывут! стопудово
Kompas
Участник
Сообщения: 171




14-11-2016 10:58

Васисуалий писал:
Бывает! Обидно, но так случается... Придется купить еще один! гы-гы

А вот с отдельным питанием вопрос - а почему? Категорически надо исследовать это дело осциллографом! Я уверен, что все грабли всплывут! стопудово

Ну мне тут академики подсказывают, что разводка цифровой и аналоговой части всегда сложным процессом было)
Васисуалий
monitor.net.ru
monitor.net.ru
Сообщения: 5873




14-11-2016 11:06

На эту тему есть хорошая книжка -"Искусство схемотехники" (The art of electronics) , Авторы Пауль Оровиц и Уинфелд Хилл. Там в первом (если не ошибаюсь) томе есть на эту тему целый раздел Книжка переведена на Русский и свободно находится в сети...

Вот >> http://vk.com/doc9263425_153236430?hash...dl
Kompas
Участник
Сообщения: 171




14-11-2016 12:04

Спасибо!
Список форумов » Разработка цифровых устройств » AtTiny13 + DHT11 + TM1637. Странное поведение.
Перейти:  
Текущий раздел » Разработка цифровых устройств (FPGA, CPLD, PLD, ARM, AVR и т.д.)







Электроника
Прошивки и схемы на телевизоры, мониторы, dvd, телефоны. Schematic, Service Manual (mode), eeprom dumps Информация по ремонту для специалистов - справочники, инструкции, энциклопедия, советы и секреты ремонта,  настройка, сервисные режимы поиск и продажа электронных компонентов, магазины, datasheet, pdf, размещение в интернете рекламы на сайтах электронной тематики
Powered by phpBB 2.0.18 © 2001, 2002 phpBB Group!