Вопросы и замечания по статьям и схемам, представленным на нашем сайте

При поддержке РадиоКОТструктор.ру


Ответить

Двухканальный термометр на AtMega8

Ср май 16, 2012 15:05:33

Замечания, вопросы и пожелания по двухканальному термометру http://radiokot.ru/circuit/digital/home/128/ складывайте здесь.

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 16:56:03

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

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 17:17:39

Леонид Иванович, программа не знает, какой датчик внешний, а какой-внутренний. Ей все равно. С каждого датчика показания выводятся на свой дисплей. На нижнем дисплее у меня температура на улице, на верхнем-дома. Они местами не поменяются. По поводу того, что 2 датчика в параллель. В МК только одна ножка может быть запрограммирована на прием и передачу данных по интерфейсу 1-Wire. А опрос датчиков делается по его адресу, который программа узнает при инициализации датчиков. Программа знает, сколько датчиков подключено. А защита там и не нужна вовсе. Какая должна быть ее функция? От замыкания? Ну тогда можно предохранитель поставить....Привожу пример из даташита на датчик. Никакой защиты там не нужно.
Вложения
2012-05-16_181701.png
(19.15 KiB) Скачиваний: 2217

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 17:21:13

ELcat.

Вот пример для датчиков.
#asm("sei") //разрешаем прерывания

num_dat=w1_search(0xf0,rom_codes);//поиск датчиков
ds18b20_init( &rom_codes[0][0], 0, 0, DS18B20_12BIT_RES ); //инициализация первого датчика
ds18b20_init( &rom_codes[1][0], 0, 0, DS18B20_12BIT_RES ); //инициализация второго датчика

При обращении к конкретному датчику

tem1=ds18b20_temperature(&rom_codes[1][0]); // в переменную пишем значение, прочитанное из датчика

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 18:07:56

добрый день! Как проецируется отрицательные температуры?

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 18:10:45

При отрицательной температуре от -0,1 градуса до -9,9 градуса знак минус спереди. Один знак после запятой. Ниже -10 градусов только знак минуса без десятичного знака

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 18:13:29

Спасибо!!!!

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 18:31:45

Nusik1975 писал(а):Леонид Иванович, программа не знает, какой датчик внешний, а какой-внутренний.


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

Nusik1975 писал(а):В МК только одна ножка может быть запрограммирована на прием и передачу данных по интерфейсу 1-Wire.


Почему же? Портов 1-Wire можно сделать столько, сколько есть свободных ног. Например, вот здесь http://www.digit-el.com/files/products/ ... fn-603.jpg у меня их шесть.

Nusik1975 писал(а):А защита там и не нужна вовсе. Какая должна быть ее функция? От замыкания? Ну тогда можно предохранитель поставить....Привожу пример из даташита на датчик. Никакой защиты там не нужно.


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

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 18:34:45

Я же написал, что у меня верхний дисплей дом, нижний-улица. Четкая привязка!
Производитель не указывает, что нужна защита. Я не спорю, можно и поставить. Я не ставил.
В данном проекте не вижу смысла использовать несколько ножек процессора.

P.S. Я только начинаю делать первые шаги в программировании МК, поэтому рациональные предложения принимаю!

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 18:48:38

Nusik1975 писал(а):В данном проекте не вижу смысла использовать несколько ножек процессора.P.S. Я только начинаю делать первые шаги в программировании МК, поэтому рациональные предложения принимаю!

Скорее всего, вы так же как и я, просто не имеете примера как это реализуется в коде (похоже программа написани на С ?)
Я бы тоже с удовольствием посмотрел такой кусок кода где 1-Wire можно сделать столько, сколько есть свободных ног.....

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 18:50:48

Да, я начинающий. И тоже с удовольствием посмотрю, если Леонид Иванович покажет в коде, как это делать. Просим! Наверное там библиотека переделываться будет... И да, я пишу на Си. Асм не знаю

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 19:10:07

Если там переделывается библиотека, то мне тот кусок кода ничем не поможет, я например еще не на том уровне осмысления программирования :(

Re: Двухканальный термометр на AtMega8

Ср май 16, 2012 19:10:49

Да это практически то же самое.

Re: Двухканальный термометр на AtMega8

Чт май 17, 2012 11:47:22

Nusik1975 писал(а):Я же написал, что у меня верхний дисплей дом, нижний-улица. Четкая привязка!


Так как у Вас - неудобно. Нужно включить термометр, посмотреть, какой из датчиков отображается на нижнем дисплее, затем именно его вывести на улицу. А что будет, если датчик придется заменить? Серийный номер может оказаться как больше, так и меньше. Правильное решение - использовать две ножки контроллера для получения двух 1-Wire портов. Тогда один из них можно закрепить за улицей, второй - за помещением.

Nusik1975 писал(а):Производитель не указывает, что нужна защита.


Не там смотрите. Про защиту нужно смотреть не в даташитах по 1-Wire микросхемах, а в Application Notes по шине 1-Wire. Там много про защиту написано.

Пример организации 6-ти портов 1-Wire:

Код:
//----------
//---------- Цифровые датчики: ----------
//----------

//Используются термометры DS18B20 (S20), которые подключены к портам OWPn.
//Считанное значение температуры заносится в массив Temp[],
//температура представлена в десятых долях градуса.
//Диапазон возможных температур составляет от TEMP_MIN до TEMP_MAX
//градусов. При отсутствии термометра показания равны TEMP_MIN.

//---------- Константы: ----------

#define   FCLK     18.432 //тактовая частота, Мгц
  #define OWP0   (1 << PC0) //порт цифрового термометра 0
  #define OWP1   (1 << PC1) //порт цифрового термометра 1
  #define OWP2   (1 << PC2) //порт цифрового термометра 2
  #define OWP3   (1 << PC3) //порт цифрового термометра 3
  #define OWP4   (1 << PC4) //порт цифрового термометра 4
  #define OWP5   (1 << PC5) //порт цифрового термометра 5
//Маски термометров:
const __flash char Masks[CHANNELS] = {OWP0, OWP1, OWP2, OWP3, OWP4, OWP5};

//---------- Макросы: ----------

  //Макроопределения для работы с портами:
  #define Port_OWP_0(m)   (DDRC |= m)
  #define Port_OWP_Z(m)   (DDRC &= ~m)
  #define Pin_OWP(m)      (PINC & m)

#define WORD(b1,b0) ((unsigned int)(b1 << 8) | b0)
#define Delay_us(x) __delay_cycles((int)(x * FCLK + 0.5))

//---------- Переменные: ----------

static int Temp[CHANNELS];     //текущая температура
static bool Present[CHANNELS]; //флаги присутствия термометров

//---------- Прототипы функций: ----------

void Start(char n);         //старт термометра
void Read(char n);          //чтение термометра
void TReset(char n);        //генерация импульса сброса
char TByte(char n, char dat); //запись/чтение байта
bool TBit(char n, bool b);  //запись/чтение бита
void Do_Crc(char b, char *crc); //вычисление CRC

//---------- Инициализация измерителя температуры: ----------

void Therm_Init(void)
{
  for(char i = 0; i < CHANNELS; i++)
  {
    Temp[i] = TEMP_MIN;     //инициализация температуры
    Start(i);               //старт всех термометров
  }
}

//---------- Измерение температуры: ----------

void Therm_Exe(char n) //должна вызываться в основном цикле
//раз в 750 мс с интересующими значениями n
{
  Read(n);                  //чтение термометра - самое первое измерение
  Start(n);                 //старт термометра
}

//---------- Старт термометра: ----------

void Start(char n)
{
  TReset(n);                //импульс сброса
  if(Present[n])
  {
    TByte(n, 0xCC);         //skip ROM
    TByte(n, 0x44);         //convert T
  }
}

//---------- Чтение термометра: ----------

void Read(char n)
{
  if(Present[n])
  {
    TReset(n);              //импульс сброса
    if(Present[n])
    {
      TByte(n, 0xCC);       //skip ROM
      TByte(n, 0xBE);       //read scratchpad
      char Data[9];               //данные термометра
      char Crc = 0;               //инициализация CRC
      for(char i = 0; i < 9; i++)
      {
        char b = TByte(n, 0xFF);  //чтение данных
        Do_Crc(b, &Crc);          //обновление CRC
        Data[i] = b;              //сохранение данных
      }
      int t = TEMP_MIN;
      if(!Crc)
      {
#ifdef DS18B20     
        t = WORD(Data[1], Data[0]); //температура с дискретностью 0.0625°C
        t = (t * 10) / 16;    //температура с дискретностью 0.1°C
#else
        t = WORD(Data[1], Data[0]) / 2;
        t = (t * 20 - 5 + (int)(Data[7] - Data[6]) * 20 / Data[7]) / 2;
#endif     
      }
      Temp[n] = t;
      return;
    }
  }
  Temp[n] = TEMP_MIN;       //термометр отсутствует
  return;
}

//---------- Генерация импульса сброса: ----------

void TReset(char n)
{
  char m = Masks[n];
  char si;
  Present[n] = 0;              //сброс флага присутствия термометра
  Port_OWP_0(m);               //OWP <- 0
  Delay_us(500);               //delay 500 uS
  si = __save_interrupt();
  __disable_interrupt();       //запрещение прерываний
  Port_OWP_Z(m);               //OWP <- 1
  Delay_us(14);                //delay 14 uS
  if(Pin_OWP(m))               //если OWP = 0, то ошибка
  {
    Delay_us(52);              //delay 52 uS
    if(!Pin_OWP(m))            //если OWP = 1, то ошибка
    {
      __restore_interrupt(si); //восстанавление прерываний
      Delay_us(250);           //delay 250 uS
      if(Pin_OWP(m))           //если OWP = 0, то ошибка
      {
        Present[n] = 1;        //если ошибок нет, термометр присутствует
      }
    }
  }
  __restore_interrupt(si);     //восстанавление прерываний в случае ошибки
}

//---------- Запись/чтение байта по однопроводной шине: ----------

char TByte(char n, char dat)
{
  char res;
  char m = Masks[n];
  for(char i = 0; i < 8; i++)
  {
    res = res >> 1;
    if(TBit(m, dat & 1)) res |= 0x80;
     else res &= ~0x80;
    dat = dat >> 1;
  }
  return(res);
}

//---------- Запись/чтение бита по однопроводной шине: ----------

bool TBit(char m, bool b)
{
  char si;
  si = __save_interrupt();
  __disable_interrupt();       //запрещение прерываний
  Port_OWP_0(m);               //OWP <- 0
  Delay_us(2);                 //delay 2 uS
  if(b) Port_OWP_Z(m);         //bit = 1, OWP <- 1
  Delay_us(13);                //delay 13 uS
  bool owp = Pin_OWP(m);       //чтение порта
  Delay_us(45);                //delay 45 uS
  Port_OWP_Z(m);               //OWP <- 1
  __restore_interrupt(si);     //восстанавление прерываний
  Delay_us(2);                 //delay 2 uS
  return(owp);
}

//---------- Вычисление контрольной суммы: ----------

void Do_Crc(char b, char *crc)
{
  for(char i = 0; i < 8; b = b >> 1, i++)
    if((b ^ *crc) & 1) *crc = ((*crc ^ 0x18) >> 1) | 0x80;
     else *crc = (*crc >> 1) & ~0x80;
}

//---------- Чтение температуры: ----------

int Therm_GetT(char ch)
{
  if(ch < CHANNELS)
    return(Temp[ch]);
      else return(0);
}

Re: Двухканальный термометр на AtMega8

Чт май 17, 2012 17:01:30

О, Леонид Иванович , большое спасибо за ликбез! Буду знать!

Re: Двухканальный термометр на AtMega8

Сб май 19, 2012 23:22:27

В эту зиму был у меня установленный термометр измеряющий температуру в атомо и был такой мороз что жки, очевидно (как я понял-замерз). Девайс понравился, хочу собрать, но: 1-не могу считать печатную плату, 2-у меня куча индикаторов с общим катодом- возможно ли дополнить проект с индикатором с общим катодом?

Re: Двухканальный термометр на AtMega8

Вс май 20, 2012 00:04:21

Печатная плата дана в формате Sprint Layot. А для общих катодов может когда-нибудь и сделаю. Пока ничего не могу обещать.
Просто нет времени.

Re: Двухканальный термометр на AtMega8

Вс май 20, 2012 06:19:55

Доброе время суток.
Есть ли описание по работе с ошибками? У меня высвечивает Out и Err. Хотя последнее - это ошибка, но чего? Подскажите пожалуйста :?

Re: Двухканальный термометр на AtMega8

Вс май 20, 2012 07:40:19

Сообщение Err выводится при ошибке чтения датчика. Причин тут может быть несколько - низкое напряжение питания датчика, неправильно распаян датчик, обрыв проводов до датчика, неисправность датчика. Программа 40 раз пытается считать данные с датчика, и если безуспешно, то выводится Err.
Сообщение Out будет выводиться, если температура превысит порог +120 градусов.

Проверьте, действительно ли у Вас подключен датчик DS18B20, именно с такой маркировкой. Работу датчиков DS1820 и DS18S20 я не гарантирую на этом термометре, поскольку на эти датчики своя библиотека в программе.

Re: Двухканальный термометр на AtMega8

Вс май 20, 2012 14:39:42

Привет! Если это твой "первый шаг" в программировании, то, должен заметить, довольно-таки серьёзный :) Я, например до сих пор не решился поковырять 1-wire, хотя уже года 4 работаю с AVR. По поводу защиты - поставь супрессор 0.6KE6.8CA по питанию МК и какой-нибудь диод Шоттки 1N5817 или SS14 с линии 1-wire на линию +Vcc и на землю, далее выходящие с платы к датчикам линии через резисторы 22-33Ом. Это и будет лучшая защита.
Ответить