Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Re: Программа для PIC12F629, подогреватель кессона.

Пт май 18, 2018 23:59:53

...Самое главное, чтобы нагреватель не оставался включенным. Иначе он поджарит что-нибудь ненароком :))
Так же, желательно продублировать защиту от перегрева термовыключателем типа такого:
СпойлерИзображение
Всякое может быть... Датчик физически отвалился от точки контроля температуры, недочёт в программе контроллера и т.д..

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 06:58:32

Здравствуйте! :) В очередной раз смею обратиться за помощью в написании простейшей программки...

А я вот не очень понял, о какой помощи вы говорите? Программировать Вы не умеете и учиться не собираетесь, даже современный Basic для Вас сложен, 600р. за DS1821 для Вас дорого, предложение wws63 за условные 1000р. для Вас также неприемлемо. Чем тут можно "помочь"? Какой будет Ваш вклад в данное? Отрисовка "желаемой" типовой схемы и работа девайса по "желаемому" Вами алгоритму? Или сколько Вы готовы за решение доплатить? Давайте посмеемся все вместе, если вышеуказанные суммы являются для Вас запредельными. Вот Вам самому халявщики нравятся?

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 07:34:33

попробуйте пару экспериментов...

попробовал, плохо - при обрывах и к.з. нагрев включен. Но в ТЗ (первом посте) об этом ни слова - может наоборот без нагрева все замерзнет. Можно и CRC - но пока по простецки, теперь при к.з. и обрыве нагрев не включается:
Спойлер
Код:
#include <xc.h>

#pragma config MCLRE=OFF
#pragma config CP=ON
#pragma config CPD=OFF
#pragma config BOREN=ON
#pragma config WDTE=OFF
#pragma config PWRTE=ON
#pragma config FOSC=INTRCIO

#ifndef _XTAL_FREQ
// Unless already defined assume 4MHz system frequency
// This definition is required to calibrate __delay_us() and __delay_ms()
#define _XTAL_FREQ 4000000U
#endif
#define ONE_WIRE_PORTIN      GP1
#define ONE_WIRE_PORT      GP1
#define ONE_WIRE_DDR      TRISIO1
#define CONVERT_TEMP        0x44
#define WRITE_SCRATCHPAD    0x4E
#define READ_SCRATCHPAD     0xBE
#define COPY_SCRATCHPAD     0x48
#define RECALL_E2           0xB8
#define READ_POWER_SUPPLY   0xB4
#define SKIP_ROM          0xCC

int temperature;
unsigned char ds18b20[9];

unsigned char OneWire_Init()
{
   ONE_WIRE_DDR = 0; //Low LINE
    ONE_WIRE_PORT = 0;
    __delay_us(485);
    ONE_WIRE_DDR = 1; //Hi LINE
    __delay_us(70);
 
   if (ONE_WIRE_PORTIN == 0) //Если ведомое уст-во ответило (PRESENCE PULSE) - заканчиваем этот тайм-слот (480мкс).
   {
        __delay_us(480);
      if (ONE_WIRE_PORTIN == 0)    //Если линия так и продолжает быть в низком уровне - значит это либо ошибка,
         return 0;    //либо на линии нет устр-в, а PRESENCE был ложным и вызван просто низким уровнем на линии.
      else         //В таком случае естественно возвращаем 0 (ошибка / нет устр-в на шине),
         return 1;    //либо 1 если все в порядке и это был "настоящий" PRESENCE PULSE.
   }
   else
      //Возвращаем 0 если отсутствовал вообще какой-либо намек на PRESENCE.
      return 0;
}

void OneWire_WriteByte(unsigned char data)
{
    unsigned char i;
    unsigned char data_bit;

    for (i = 0; i < 8; i++)
    {
        data_bit = data;
        data_bit = (data >> i) & 1;
        ONE_WIRE_DDR = 0; //Low LINE
        ONE_WIRE_PORT = 0;
 
        if (data_bit == 1)
            __delay_us(1);
        else
            __delay_us(90);

        ONE_WIRE_DDR = 1;

        if (data_bit == 1)
            __delay_us(90);
        else
            __delay_us(1);

        ONE_WIRE_DDR = 1;
 
        __delay_us(1);
    }
}

unsigned char OneWire_ReadByte(void)
{
    char i;
    unsigned char data = 0;

    for (i = 0; i < 8; i++)
    {
        __delay_us(1);
        ONE_WIRE_DDR = 0; //Low LINE
        ONE_WIRE_PORT = 0;
        __delay_us(5);
        ONE_WIRE_DDR = 1;
        __delay_us(15);
        if (ONE_WIRE_PORTIN == 1)
            data |= (1 << i);
        __delay_us(55);
    }
    return data;
}

void main(void)
 {
   unsigned char presence;   
   GPIO   = 0x00;
   CMCON   = 0x07;
   TRISIO   = 0x00;
   while (1)
   {
      presence = OneWire_Init();
      OneWire_WriteByte(SKIP_ROM);
      OneWire_WriteByte(CONVERT_TEMP);
      __delay_ms(1000);
      presence = OneWire_Init();
      OneWire_WriteByte(SKIP_ROM);
      OneWire_WriteByte(READ_SCRATCHPAD);
      ds18b20[0] = OneWire_ReadByte();
      ds18b20[1] = OneWire_ReadByte();
      ds18b20[2] = OneWire_ReadByte();
      ds18b20[3] = OneWire_ReadByte();
      ds18b20[4] = OneWire_ReadByte();
      temperature = ((unsigned int)ds18b20[1] << 8 | (unsigned int)ds18b20[0]);
      if((ds18b20[1] & (1<<7))==0)
      {
         temperature*=5;
         temperature>>=3;
      }
      else
      {
         temperature=-temperature;
         temperature*=5;
         temperature>>=3;
         temperature=-temperature;
      }
      if(presence)
      {
         if(temperature >= 40) GP2=0;
         if(temperature <= 20) GP2=1;
      }
      else
         GP2=0;
   }
}

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

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 07:54:21

Что? одни "коммерсанты" на форуме? Работы мизер. korob сейчас лень писать прожку, да и вам не горит. если не опередят - осенью в личку. тему отслеживать не буду - поэтому напомните.

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 08:07:28

попробую опередить :)) - добавил минутную задержку и питание через GP0 (по алгоритму ТС)
Спойлер
Код:
#include <xc.h>

#pragma config MCLRE=OFF
#pragma config CP=ON
#pragma config CPD=OFF
#pragma config BOREN=ON
#pragma config WDTE=OFF
#pragma config PWRTE=ON
#pragma config FOSC=INTRCIO

#ifndef _XTAL_FREQ
// Unless already defined assume 4MHz system frequency
// This definition is required to calibrate __delay_us() and __delay_ms()
#define _XTAL_FREQ 4000000U
#endif
#define ONE_WIRE_PORTIN      GP1
#define ONE_WIRE_PORT      GP1
#define ONE_WIRE_DDR      TRISIO1
#define CONVERT_TEMP        0x44
#define WRITE_SCRATCHPAD    0x4E
#define READ_SCRATCHPAD     0xBE
#define COPY_SCRATCHPAD     0x48
#define RECALL_E2           0xB8
#define READ_POWER_SUPPLY   0xB4
#define SKIP_ROM          0xCC

int temperature;
unsigned char ds18b20[9];

unsigned char OneWire_Init()
{
   ONE_WIRE_DDR = 0; //Low LINE
    ONE_WIRE_PORT = 0;
    __delay_us(485);
    ONE_WIRE_DDR = 1; //Hi LINE
    __delay_us(70);
 
   if (ONE_WIRE_PORTIN == 0) //Если ведомое уст-во ответило (PRESENCE PULSE) - заканчиваем этот тайм-слот (480мкс).
   {
        __delay_us(480);
      if (ONE_WIRE_PORTIN == 0)    //Если линия так и продолжает быть в низком уровне - значит это либо ошибка,
         return 0;    //либо на линии нет устр-в, а PRESENCE был ложным и вызван просто низким уровнем на линии.
      else         //В таком случае естественно возвращаем 0 (ошибка / нет устр-в на шине),
         return 1;    //либо 1 если все в порядке и это был "настоящий" PRESENCE PULSE.
   }
   else
      //Возвращаем 0 если отсутствовал вообще какой-либо намек на PRESENCE.
      return 0;
}

void OneWire_WriteByte(unsigned char data)
{
    unsigned char i;
    unsigned char data_bit;

    for (i = 0; i < 8; i++)
    {
        data_bit = data;
        data_bit = (data >> i) & 1;
        ONE_WIRE_DDR = 0; //Low LINE
        ONE_WIRE_PORT = 0;
 
        if (data_bit == 1)
            __delay_us(1);
        else
            __delay_us(90);

        ONE_WIRE_DDR = 1;

        if (data_bit == 1)
            __delay_us(90);
        else
            __delay_us(1);

        ONE_WIRE_DDR = 1;
 
        __delay_us(1);
    }
}

unsigned char OneWire_ReadByte(void)
{
    char i;
    unsigned char data = 0;

    for (i = 0; i < 8; i++)
    {
        __delay_us(1);
        ONE_WIRE_DDR = 0; //Low LINE
        ONE_WIRE_PORT = 0;
        __delay_us(5);
        ONE_WIRE_DDR = 1;
        __delay_us(15);
        if (ONE_WIRE_PORTIN == 1)
            data |= (1 << i);
        __delay_us(55);
    }
    return data;
}

void main(void)
 {
   unsigned char presence, i;   
   GPIO   = 0x00;
   CMCON   = 0x07;
   TRISIO   = 0x00;
   while (1)
   {
      GP0=1;
      __delay_ms(300);
      presence = OneWire_Init();
      OneWire_WriteByte(SKIP_ROM);
      OneWire_WriteByte(CONVERT_TEMP);
      __delay_ms(1000);
      presence = OneWire_Init();
      OneWire_WriteByte(SKIP_ROM);
      OneWire_WriteByte(READ_SCRATCHPAD);
      ds18b20[0] = OneWire_ReadByte();
      ds18b20[1] = OneWire_ReadByte();
      ds18b20[2] = OneWire_ReadByte();
      ds18b20[3] = OneWire_ReadByte();
      ds18b20[4] = OneWire_ReadByte();
      temperature = ((unsigned int)ds18b20[1] << 8 | (unsigned int)ds18b20[0]);
      if((ds18b20[1] & (1<<7))==0)
      {
         temperature*=5;
         temperature>>=3;
      }
      else
      {
         temperature=-temperature;
         temperature*=5;
         temperature>>=3;
         temperature=-temperature;
      }
      GP0=0;
      if(presence)
      {
         if(temperature >= 40) GP2=0;
         if(temperature <= 20) GP2=1;
      }
      else
         GP2=0;
      for (i = 0; i < 60; i++)
      {
         __delay_ms(1000);
      }
   }
}

не проверял, hex и протеус:
PIC12F629.zip
(20 KiB) Скачиваний: 248

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 10:00:49

Что? одни "коммерсанты" на форуме? Работы мизер...

Ну так сделайте, раз мизер. И дело не в деньгах вовсе, хотя время - самое ценное, что есть у человека. Сам подход порочный. Человек не просит научить его рыбачить, человек просит сразу рыбу. Причем не абы какую, а нужного ему сорта, веса и свежести. При наличии наработок, тут делов на полчаса. Если у Вас времени до хрена, то делайте. Я этого делать не стану из педагогических соображений.

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 10:22:43

oleg110592, "собаку" активируй на всякий случай и сброс ее в цикле программы.
Код:
#pragma config WDTE=OFF

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 10:30:56

oleg110592 писал(а):попробую опередить - добавил минутную задержку и питание через GP0 (по алгоритму ТС)
То, что доктор прописал. :beer: :beer: :beer:

"Низкий поклон тебе боярин"©

P.S Никаких защит от обрывов и КЗ не нужно (датчик будет на плате с МК), а вот в процедуре опроса желательна защита от считывания ложных данных (проверка CRC). Хотя... :roll: В данном случае от неё тоже будет мало толку.

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 17:02:55

вариант CRC и "собака":
Спойлер
Код:
#include <xc.h>

#pragma config MCLRE=OFF
#pragma config CP=ON
#pragma config CPD=OFF
#pragma config BOREN=ON
#pragma config WDTE=ON
#pragma config PWRTE=ON
#pragma config FOSC=INTRCIO

#ifndef _XTAL_FREQ
// Unless already defined assume 4MHz system frequency
// This definition is required to calibrate __delay_us() and __delay_ms()
#define _XTAL_FREQ 4000000U
#endif
#define ONE_WIRE_PORTIN      GP1
#define ONE_WIRE_PORT      GP1
#define ONE_WIRE_DDR      TRISIO1
#define CONVERT_TEMP        0x44
#define WRITE_SCRATCHPAD    0x4E
#define READ_SCRATCHPAD     0xBE
#define COPY_SCRATCHPAD     0x48
#define RECALL_E2           0xB8
#define READ_POWER_SUPPLY   0xB4
#define SKIP_ROM          0xCC

int temperature;
unsigned char ds18b20[9], crc;

const unsigned char crc_array[256] =
{
 
    0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
    0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
    0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
    0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
    0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
    0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
    0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
    0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
    0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
    0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
    0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
    0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
    0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,
    0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
    0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
    0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
    0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,
    0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
    0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
    0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
    0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
    0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
    0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,
    0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
    0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
    0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
    0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
    0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
    0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,
    0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
    0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
    0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
};
 
unsigned char Count_crc_dallas(unsigned char *buf, unsigned char size)
{
    unsigned char crc = 0;
 
    for (; size > 0; size--)
    {
        crc = crc_array[(*buf) ^ crc];
        buf++;
    }
     return (crc);
}

unsigned char OneWire_Init()
{
   ONE_WIRE_DDR = 0; //Low LINE
    ONE_WIRE_PORT = 0;
    __delay_us(485);
    ONE_WIRE_DDR = 1; //Hi LINE
    __delay_us(70);
 
   if (ONE_WIRE_PORTIN == 0) //Если ведомое уст-во ответило (PRESENCE PULSE) - заканчиваем этот тайм-слот (480мкс).
   {
        __delay_us(480);
      if (ONE_WIRE_PORTIN == 0)    //Если линия так и продолжает быть в низком уровне - значит это либо ошибка,
         return 0;    //либо на линии нет устр-в, а PRESENCE был ложным и вызван просто низким уровнем на линии.
      else         //В таком случае естественно возвращаем 0 (ошибка / нет устр-в на шине),
         return 1;    //либо 1 если все в порядке и это был "настоящий" PRESENCE PULSE.
   }
   else
      //Возвращаем 0 если отсутствовал вообще какой-либо намек на PRESENCE.
      return 0;
}

void OneWire_WriteByte(unsigned char data)
{
    unsigned char i;
    unsigned char data_bit;

    for (i = 0; i < 8; i++)
    {
        data_bit = data;
        data_bit = (data >> i) & 1;
        ONE_WIRE_DDR = 0; //Low LINE
        ONE_WIRE_PORT = 0;
 
        if (data_bit == 1)
            __delay_us(1);
        else
            __delay_us(90);

        ONE_WIRE_DDR = 1;

        if (data_bit == 1)
            __delay_us(90);
        else
            __delay_us(1);

        ONE_WIRE_DDR = 1;
 
        __delay_us(1);
    }
}

unsigned char OneWire_ReadByte(void)
{
    char i;
    unsigned char data = 0;

    for (i = 0; i < 8; i++)
    {
        __delay_us(1);
        ONE_WIRE_DDR = 0; //Low LINE
        ONE_WIRE_PORT = 0;
        __delay_us(5);
        ONE_WIRE_DDR = 1;
        __delay_us(15);
        if (ONE_WIRE_PORTIN == 1)
            data |= (1 << i);
        __delay_us(55);
    }
    return data;
}

void main(void)
 {
   unsigned char presence, i;   
   GPIO   = 0x00;
   CMCON   = 0x07;
   TRISIO   = 0x00;
   CLRWDT();
   PS0 = 1; // :128 – 2.3 sec
   PS1 = 1;
   PS2 = 1;
   PSA = 1; // WDT
   while (1)
   {
      CLRWDT();
      GP0=1;
      __delay_ms(300);
      presence = OneWire_Init();
      OneWire_WriteByte(SKIP_ROM);
      OneWire_WriteByte(CONVERT_TEMP);
      __delay_ms(1000);
      presence = OneWire_Init();
      OneWire_WriteByte(SKIP_ROM);
      OneWire_WriteByte(READ_SCRATCHPAD);
      ds18b20[0] = OneWire_ReadByte();
      ds18b20[1] = OneWire_ReadByte();
      ds18b20[2] = OneWire_ReadByte();
      ds18b20[3] = OneWire_ReadByte();
      ds18b20[4] = OneWire_ReadByte();
      ds18b20[5] = OneWire_ReadByte();
      ds18b20[6] = OneWire_ReadByte();
      ds18b20[7] = OneWire_ReadByte();
      ds18b20[8] = OneWire_ReadByte();
      temperature = ((unsigned int)ds18b20[1] << 8 | (unsigned int)ds18b20[0]);
      if((ds18b20[1] & (1<<7))==0)
      {
         temperature*=5;
         temperature>>=3;
      }
      else
      {
         temperature=-temperature;
         temperature*=5;
         temperature>>=3;
         temperature=-temperature;
      }
      GP0=0;
      crc=Count_crc_dallas(ds18b20, 8);
      if(crc != ds18b20[8])
         presence=0;
      if(presence)
      {
         if(temperature >= 40) GP2=0;
         if(temperature <= 20) GP2=1;
      }
      else
         GP2=0;
      for (i = 0; i < 60; i++)
      {
         CLRWDT();
         __delay_ms(1000);
      }
   }
}

CRC табличный, отжирает, но в Протеусе работает:
Изображение
Memory Summary:
Program space used 277h ( 631) of 3FFh words ( 61.7%)
Data space used 19h ( 25) of 3Eh bytes ( 40.3%)

PIC12F629.zip
(21.65 KiB) Скачиваний: 251

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 19:47:35

Значит отчитываюсь: с моими DS18B20 работает со сдвигом температуры, включает нагрев примерно при 28...30°С и выключает при 32...34°С. :? Где то в формуле перевода температуры ошибка. :dont_know: Прошивка с проверкой CRC вообще не работает. :(

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 20:44:58

Может данные некорректно читаются, отсюда и прошивка с CRC не работает :(
Попробуйте подтягивающее сопротивление уменьшить. Как вариант...

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 20:52:34

Да нет, работает чётко, только не в том диапазоне. Если бы что не так - то отключался бы нагрев, собственно так и происходит если коротнуть или отключить датчик.

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 20:55:38

А датчик точно с буквой 'B' ?

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 20:57:23

датчик случайно не DS18S20?
этот вариант попробовать:
PIC12F629.zip
(1010 байт) Скачиваний: 277

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 20:58:57

Нет именно DS18B20.

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 21:04:11

еще такой вариант:
PIC12F629.zip
(1010 байт) Скачиваний: 244

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 21:16:14

Ничего не меняется. :(

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 21:22:56

завтра в личке продолжим

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 23:08:13

Ну вот... Только началось самое интересное ... :)
Я даже на тему подписался :))

Добавлено after 1 hour 40 minutes 4 seconds:
korob, попробуйте на досуге :
DS1820_Termostat.hex
(4.17 KiB) Скачиваний: 288

Re: Программа для PIC12F629, подогреватель кессона.

Сб май 19, 2018 23:50:58

Аlex писал(а):попробуйте на досуге
Заработало как надо. :beer: :beer: :beer: Опрос только слишком часто.

Что не так было? Формула пересчёта, или битность на датчике неверная была выставлена?
Последний раз редактировалось korob Сб май 19, 2018 23:55:25, всего редактировалось 1 раз.
Ответить