Arduino + нагреватель и термопара от 3d принтера

Тема в разделе "Arduino & Shields", создана пользователем GHEB, 10 мар 2022.

Метки:
  1. GHEB

    GHEB Нуб

    Добрый день
    Есть Arduino nano и экструдер от 3д принтера с нагревателем и термопарой (4 провода). Подскажите как всё это дело между собой подружить?

    Предположу что нужно реле для включения\отключения напряжения на нагреватель, но, как брать температуру с датчика. Наверное мне нужен
    MAX6675K?
     

    Вложения:

    • 66.jpg
      66.jpg
      Размер файла:
      81,7 КБ
      Просмотров:
      48
    Последнее редактирование: 10 мар 2022
  2. parovoZZ

    parovoZZ Гуру

    чо? Термопара? Там pt100 скорее всего.
     
  3. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Вооот. Коль не знаем точно, надо проверять. Красные - наверняка нагреватель. Белые - сенсор. Если термопара, между белыми сопротивление около нуля. Если терморезистор - около 100 ом. Модулек MAX6675 - только к термопаре ТХА(К). Понадобится
    протестировать сенсор на совместимость с модульком.
    Скачайте в Ардуино библу и пример под него.
     
    Последнее редактирование: 11 мар 2022
  4. GHEB

    GHEB Нуб

    Замерял сопротивление мультиметром, судя по тому что я вижу у меня вышло 67 килоом, что кажется много, но фото говорит за себя: фото[​IMG]

    Сам модуль выглядит так: фото
    [​IMG]


    Код (C++):
    // the value of the 'other' resistor
    #define SERIESRESISTOR 10000
    // What pin to connect the sensor to
    #define THERMISTORPIN A0
    void setup(void) {
      Serial.begin(9600);
    }
    void loop(void) {
      float reading;
      reading = analogRead(THERMISTORPIN);
      Serial.print("Analog reading ");
      Serial.println(reading);
      // convert the value to resistance
      reading = (1023 / reading)  - 1;     // (1023/ADC - 1)
      reading = SERIESRESISTOR / reading;  // 10K / (1023/ADC - 1)
      Serial.print("Thermistor resistance ");
      Serial.println(reading);
      delay(1000);
    }
    схема


    всё бы ничего, вот только судя по даным, у меня 3700 градусов в квартире :eek:
    попробовал поставить резистор другого номинала, такого же как термодатчик-ситуация та же(в скетче тоже изенения внёс)
    [​IMG]
    [​IMG]
     
    Последнее редактирование: 12 мар 2022
  5. parovoZZ

    parovoZZ Гуру

    Сперва надо научиться отличать термопару от термосопротивления. Затем научиться метрологии.
     
    Igor68 нравится это.
  6. GHEB

    GHEB Нуб

    Решение


    Код (C++):
    #define B 3950 // B-коэффициент
    #define SERIAL_R 100000 // сопротивление последовательного резистора, 102 кОм
    #define THERMISTOR_R 100000 // номинальное сопротивления термистора, 100 кОм
    #define NOMINAL_T 25 // номинальная температура (при которой TR = 100 кОм)HIGH

    const byte tempPin = A1;

    const int relPin = 3;

    void setup() {
        Serial.begin( 9600 );
        pinMode( tempPin, INPUT );
        pinMode(relPin, OUTPUT);
    }

    void loop() {
        int t = analogRead( tempPin );
        float tr = 1023.0 / t - 1;
        tr = SERIAL_R / tr;
        Serial.print("R=");
        Serial.print(tr);
        Serial.print(", t=");

        float steinhart;
        steinhart = tr / THERMISTOR_R; // (R/Ro)
        steinhart = log(steinhart); // ln(R/Ro)
        steinhart /= B; // 1/B * ln(R/Ro)
        steinhart += 1.0 / (NOMINAL_T + 273.15); // + (1/To)
        steinhart = 1.0 / steinhart; // Invert
        steinhart -= 273.15;
        Serial.println(steinhart);

        if(steinhart>211)
        {
          Serial.println("Hoot");
          digitalWrite(relPin, LOW);
        }
        if(steinhart<211)
        {
          Serial.println("Cold");
          digitalWrite(relPin, HIGH);
        }
     
        delay(500);
    }
    Данный термодатчик имеет следующие характеристики:
    Термистор NTC 100K 3950
    Схема подключения:


    Резистор нужно ставить тоже на 100К
     
  7. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Банальное рассуждение говорит, что если терморезистор стоит последовательно с обычным - будет нелинейность. И тем сильнее, чем ближе их сопротивления. Видимо под Steinhart у вас заложена линеаризация. Если все работает - удач.
    ПС. Обычно в таких случаях вместо постоянного резистора используют ИСТОЧНИК ТОКА. Этим избавляются от нелинейности в принципе..
     
    Последнее редактирование: 12 мар 2022
  8. Nekto_nikto

    Nekto_nikto Гик

    Снимал как то температуру с термистора сам термистор если правильно все помню нужно будет одним концом подключить к GND ардуинки, а другим концом к аналоговому входу, которому приравнять значение PELTIER_HOT_SENS из скрипта ниже
    Код (C++):
    #include <avr/pgmspace.h>    // для того чтоб хранить таблицы используют внутреннюю FLASH память контроллера и директиву PROGMEM
                              // которая без этого заголовочного файла не будет работать
                              // также для того чтоб обращаться к ячейкам FLASH памяти используют две функции
                              //displayInt = pgm_read_word_near(charSet + k)
                              //myChar = pgm_read_byte_near(signMessage + k);
    /*
    Таблицу значений АЦП для термистора можно рассчитать на этом сайте
    https://aterlux.ru/article/ntcresistor
    но я брал из прошивки для 3D принтера Marlin v1.5.x
    */


    #define OVERSAMPLENR 1     // Множитель для считанного значения сенсора, таблица рассчитана для множителя 16
    #define TNumElements 64          // Количество двойных элементов таблицы
    #define TEMPERATURE_TABLE_READ(i,j) pgm_read_word(&temptable[i][j])   // так читаем таблицу, потому что при простом обращении к элементам таблицы, будут левые значения

    // 100k thermistor
    // 64 элемента двойных элемента внутри таблицы
    const short temptable[][2] PROGMEM = {
      {   23 * OVERSAMPLENR, 300 },
      {   25 * OVERSAMPLENR, 295 },
      {   27 * OVERSAMPLENR, 290 },
      {   28 * OVERSAMPLENR, 285 },
      {   31 * OVERSAMPLENR, 280 },
      {   33 * OVERSAMPLENR, 275 },
      {   35 * OVERSAMPLENR, 270 },
      {   38 * OVERSAMPLENR, 265 },
      {   41 * OVERSAMPLENR, 260 },
      {   44 * OVERSAMPLENR, 255 },
      {   48 * OVERSAMPLENR, 250 },
      {   52 * OVERSAMPLENR, 245 },
      {   56 * OVERSAMPLENR, 240 },
      {   61 * OVERSAMPLENR, 235 },
      {   66 * OVERSAMPLENR, 230 },
      {   71 * OVERSAMPLENR, 225 },
      {   78 * OVERSAMPLENR, 220 },
      {   84 * OVERSAMPLENR, 215 },
      {   92 * OVERSAMPLENR, 210 },
      {  100 * OVERSAMPLENR, 205 },
      {  109 * OVERSAMPLENR, 200 },
      {  120 * OVERSAMPLENR, 195 },
      {  131 * OVERSAMPLENR, 190 },
      {  143 * OVERSAMPLENR, 185 },
      {  156 * OVERSAMPLENR, 180 },
      {  171 * OVERSAMPLENR, 175 },
      {  187 * OVERSAMPLENR, 170 },
      {  205 * OVERSAMPLENR, 165 },
      {  224 * OVERSAMPLENR, 160 },
      {  245 * OVERSAMPLENR, 155 },
      {  268 * OVERSAMPLENR, 150 },
      {  293 * OVERSAMPLENR, 145 },
      {  320 * OVERSAMPLENR, 140 },
      {  348 * OVERSAMPLENR, 135 },
      {  379 * OVERSAMPLENR, 130 },
      {  411 * OVERSAMPLENR, 125 },
      {  445 * OVERSAMPLENR, 120 },
      {  480 * OVERSAMPLENR, 115 },
      {  516 * OVERSAMPLENR, 110 },
      {  553 * OVERSAMPLENR, 105 },
      {  591 * OVERSAMPLENR, 100 },
      {  628 * OVERSAMPLENR,  95 },
      {  665 * OVERSAMPLENR,  90 },
      {  702 * OVERSAMPLENR,  85 },
      {  737 * OVERSAMPLENR,  80 },
      {  770 * OVERSAMPLENR,  75 },
      {  801 * OVERSAMPLENR,  70 },
      {  830 * OVERSAMPLENR,  65 },
      {  857 * OVERSAMPLENR,  60 },
      {  881 * OVERSAMPLENR,  55 },
      {  903 * OVERSAMPLENR,  50 },
      {  922 * OVERSAMPLENR,  45 },
      {  939 * OVERSAMPLENR,  40 },
      {  954 * OVERSAMPLENR,  35 },
      {  966 * OVERSAMPLENR,  30 },
      {  977 * OVERSAMPLENR,  25 },
      {  985 * OVERSAMPLENR,  20 },
      {  993 * OVERSAMPLENR,  15 },
      {  999 * OVERSAMPLENR,  10 },
      { 1004 * OVERSAMPLENR,   5 },
      { 1008 * OVERSAMPLENR,   0 },
      { 1012 * OVERSAMPLENR,  -5 },
      { 1016 * OVERSAMPLENR, -10 },
      { 1020 * OVERSAMPLENR, -15 }
    };

    float GetPeltierHotTemp()
    {
    word minElement[2],maxElement[2];
    word B=analogRead(PELTIER_HOT_SENS);
    //Serial.println("A13_VALUE="+(String)B);
    //Serial.println("A13_VALUE="+(String)temptable[3][1]); // выводит левые значения, не относящиеся к таблице

    // производим бинарный поиск минимального и максимального значения температур, подходящих под значение считанное с термистора
    int n=TNumElements/2;     // номер элемента таблицы, с которым работаем
    int i=2;                  // множитель, кратно которому увеличиваем, или уменьшаем номер элемента таблицы
    boolean flag=true;
    while(flag)
      {
      if(B>=TEMPERATURE_TABLE_READ(n,0))
        {
        if(B<=TEMPERATURE_TABLE_READ(n+1,0))
          {
          minElement[0]=TEMPERATURE_TABLE_READ(n,0);
          maxElement[0]=TEMPERATURE_TABLE_READ(n+1,0);
          minElement[1]=TEMPERATURE_TABLE_READ(n,1);
          maxElement[1]=TEMPERATURE_TABLE_READ(n+1,1);
          flag=false;
          }
        n=n+TNumElements/(i*2);
        }
      else
        {
        if(B>=TEMPERATURE_TABLE_READ(n-1,0))
          {
          minElement[0]=TEMPERATURE_TABLE_READ(n-1,0);
          maxElement[0]=TEMPERATURE_TABLE_READ(n,0);
          minElement[1]=TEMPERATURE_TABLE_READ(n-1,1);
          maxElement[1]=TEMPERATURE_TABLE_READ(n,1);
          flag=false;
          }
        n=n-TNumElements/(i*2);
        }
      i++;
      }

    // Вычисляем результат
    //Serial.println("minElement="+(String)minElement[0]);
    //Serial.println("maxElement="+(String)maxElement[0]);
    float result=map(B, minElement[0], maxElement[0], minElement[1]*100,  maxElement[1]*100);
    return result/100;
    }
     
     
  9. b707

    b707 Гуру

    неправильно помните
     
  10. Nekto_nikto

    Nekto_nikto Гик

    побольше конкретики пожалуйста :rolleyes: