Печь сопротивления. Вторая итерация

Цель проекта достичь задачи:
Энкодер (KY-040) :

Используется для выбора целевой температуры.

Дисплеи TM1637 (x2) :

Первый дисплей показывает целевую температуру, выбранную с помощью энкодера.
Второй дисплей отображает текущую температуру, полученную с АЦП ADS1115.
АЦП ADS1115 :
Измеряет напряжение, соответствующее текущей температуре.
Arduino Nano :
Обрабатывает данные с энкодера, АЦП и передает информацию на дисплеи.
Сравнивает целевую температуру с текущей температурой и управляет реле для управления нагревом печки.
Реле :

Переключается для управления питанием печки.

#include <Wire.h>
#include <Arduino.h>
#include <Adafruit_ADS1X15.h>
#include <RotaryEncoder.h>
#include <TM1637Display.h>

#define ENCODER_DT_PIN 3 
#define ENCODER_CLK_PIN 2 
#define CLK_1 8
#define DIO_1 9
#define CLK_2 7
#define DIO_2 6
#define RELAY_PIN 7

RotaryEncoder myEnc(ENCODER_DT_PIN, ENCODER_CLK_PIN);
Adafruit_ADS1X15 ads;
TM1637Display display1(CLK_1, DIO_1);
TM1637Display display2(CLK_2, DIO_2); 

float multiplier = 0.0078125F;
float coldJunctionTemp = 0; // Температура холодного спая
int encoderValue = 0;
int targetTemperature = 20;
const int step = 5;

const float calibrationTableExtended[25][11] = {
    {0.000,  0.198,  0.397,  0.597,  0.798,  1.000,  1.203,  1.407,  1.612,  1.817,  2.023},  // 0-50
    {2.230,  2.436,  2.644,  2.851,  3.059,  3.267,  3.474,  3.682,  3.889,  4.096,  4.303},  // 55-105
    {4.509,  4.715,  4.920,  5.124,  5.328,  5.532,  5.735,  5.937,  6.138,  6.339,  6.540},  // 110-160
    {6.741,  6.941,  7.140,  7.340,  7.540,  7.739,  7.939,  8.138,  8.338,  8.539,  8.739}, // 165-215
    {8.940,  9.141,  9.343,  9.545,  9.747,  9.950,  10.153, 10.357, 10.561, 10.766, 10.971}, // 220-270
    {11.176, 11.382, 11.588, 11.795, 12.001, 12.209, 12.416, 12.624, 12.831, 13.040, 13.248}, // 275-325
    {13.457, 13.665, 13.874, 14.084, 14.293, 14.503, 14.713, 14.923, 15.133, 15.343, 15.554}, // 330-380
    {15.764, 15.975, 16.186, 16.397, 16.608, 16.820, 17.031, 17.243, 17.455, 17.667, 17.879}, // 385-435
    {18.091, 18.303, 18.516, 18.728, 18.941, 19.154, 19.366, 19.579, 19.792, 20.005, 20.218}, // 440-490
    {20.431, 20.644, 20.857, 21.071, 21.284, 21.497, 21.710, 21.924, 22.137, 22.350, 22.563}, // 495-545
    {22.776, 22.990, 23.203, 23.416, 23.629, 23.842, 24.055, 24.267, 24.480, 24.693, 24.905}, // 550-600
    {25.118, 25.330, 25.543, 25.755, 25.967, 26.179, 26.390, 26.602, 26.814, 27.025, 27.236}, // 605-655
    {27.447, 27.658, 27.869, 28.079, 28.289, 28.500, 28.710, 28.919, 29.129, 29.338, 29.548}, // 660-710
    {29.757, 29.965, 30.174, 30.382, 30.590, 30.798, 31.006, 31.213, 31.421, 31.628, 31.834}, // 715-765
    {32.041, 32.247, 32.453, 32.659, 32.865, 33.070, 33.275, 33.480, 33.685, 33.889, 34.093}, // 770-820
    {34.297, 34.501, 34.704, 34.908, 35.110, 35.313, 35.516, 35.718, 35.920, 36.121, 36.323}, // 825-875
    {36.524, 36.725, 36.925, 37.126, 37.326, 37.526, 37.725, 37.925, 38.124, 38.323, 38.522}, // 880-930
    {38.720, 38.918, 39.116, 39.314, 39.511, 39.708, 39.905, 40.101, 40.298, 40.494, 40.690}, // 935-985
    {40.885, 41.081, 41.276, 41.470, 41.665, 41.859, 42.053, 42.247, 42.440, 42.633, 42.826}, // 990-1040
    {43.019, 43.211, 43.403, 43.595, 43.787, 43.978, 44.169, 44.359, 44.550, 44.740, 44.929}, // 1045-1095
    {45.119, 45.308, 45.497, 45.685, 45.873, 46.061, 46.249, 46.436, 46.623, 46.809, 46.995}, // 1100-1150
    {47.181, 47.367, 47.552, 47.737, 47.921, 48.105, 48.289, 48.473, 48.656, 48.838, 49.021}, // 1155-1205
    {49.202, 49.384, 49.565, 49.746, 49.926, 50.106, 50.286, 50.465, 50.644, 50.822, 51.000}, // 1210-1260
    {51.178, 51.355, 51.532, 51.708, 51.885, 52.060, 52.235, 52.410, 52.585, 52.759, 52.932}, // 1265-1315
    {53.106, 53.279, 53.451, 53.623, 53.795, 53.967, 54.138, 54.308, 53.479, 54.649, 54.819}  // 1320-1370    
};

float getTemperatureFromTable(float voltage) {
    for (int row = 0; row < 25; row++) {
        for (int col = 0; col < 10; col++) {
            float v1 = calibrationTableExtended[row][col];
            float v2 = calibrationTableExtended[row][col + 1];

            // Проверяем, попадает ли напряжение между v1 и v2
            if (voltage >= v1 && voltage <= v2) {
                // Линейная интерполяция
                float temp1 = row * 10 + col;
                float temp2 = row * 10 + col + 1;
                return temp1 + (voltage - v1) * (temp2 - temp1) / (v2 - v1);
            }
        }
    }

    return -1; // Выход за границы таблицы
}

void setup() {
    Serial.begin(9600);
    display1.setBrightness(0x0f);
    display2.setBrightness(0x0f);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
    ads.setGain(GAIN_SIXTEEN);
    ads.begin();
}

void loop() {
    long newPosition = myEnc.read();
    if (newPosition != encoderValue) {
    encoderValue = newPosition;
    targetTemperature = 20 + encoderValue * step;
    targetTemperature = constrain(targetTemperature, 20, 1370);
    }
       
    int16_t adc0 = ads.readADC_Differential_0_1();
    thermocoupleVoltage = adc0 * multiplier; 
    float thermocoupleTemp = getTemperatureFromTable(thermocoupleVoltage);
    Ttp1 = thermocoupleTemp + coldJunctionTemp;
    
    Serial.print("Напряжение: ");
    Serial.print(thermocoupleVoltage);
    Serial.print("Target Temperature: ");
    Serial.println(targetTemperature);
    Serial.print("Current Temperature: ");
    Serial.println(Ttp1);
    
    display1.showNumberDec(targetTemperature);
    display2.showNumberDec(Ttp1);
    
    if (Ttp1 < Ttgt) {
      digitalWrite(RELAY_PIN, HIGH);
    }
    if (Ttp1 > Ttgt) {
      digitalWrite(RELAY_PIN, LOW);
    }
    
    if (temperature < targetTemperature) {
    digitalWrite(RELAY_PIN, HIGH);
    } else {
    digitalWrite(RELAY_PIN, LOW);
    }
    delay(1000);
}

Вы спалились )))
Это задача для учетного заведения.

Простите, в прошлой теме коллега сказал, что Вы не умеете читать и был прав. Я Вам уже ТРИЖДЫ писал, что

  1. в строках №106 и №109 используется переменная Ttgt нигде не описанная;
  2. в строке №113 используется переменная temperature нигде не описанная.

Этот код не может работать никак, ибо он не компилируется!

Пожалуйста, или выложите ТОТ код с которым у Вас проблемы, или перестаньте врать, что ЭТОТ код у Вас хоть как-то работает.

1 лайк

Вы правы. ну а как еще)

int Ttgt = targetTemperature;

на место 24 строки

#include <Wire.h>
#include <Arduino.h>
#include <Adafruit_ADS1X15.h>
#include <RotaryEncoder.h>
#include <TM1637Display.h>

#define ENCODER_DT_PIN 3 
#define ENCODER_CLK_PIN 2 
#define CLK_1 8
#define DIO_1 9
#define CLK_2 7
#define DIO_2 6
#define RELAY_PIN 7

RotaryEncoder myEnc(ENCODER_DT_PIN, ENCODER_CLK_PIN);
Adafruit_ADS1X15 ads;
TM1637Display display1(CLK_1, DIO_1);
TM1637Display display2(CLK_2, DIO_2); 

float multiplier = 0.0078125F;
float coldJunctionTemp = 0; // Температура холодного спая
float thermocoupleVoltage = 0.0;
int encoderValue = 0;
int targetTemperature = 20;
int Ttp1 = 0;
int Ttgt = targetTemperature;
const int step = 5;

const float calibrationTableExtended[25][11] = {
    {0.000,  0.198,  0.397,  0.597,  0.798,  1.000,  1.203,  1.407,  1.612,  1.817,  2.023},  // 0-50
    {2.230,  2.436,  2.644,  2.851,  3.059,  3.267,  3.474,  3.682,  3.889,  4.096,  4.303},  // 55-105
    {4.509,  4.715,  4.920,  5.124,  5.328,  5.532,  5.735,  5.937,  6.138,  6.339,  6.540},  // 110-160
    {6.741,  6.941,  7.140,  7.340,  7.540,  7.739,  7.939,  8.138,  8.338,  8.539,  8.739}, // 165-215
    {8.940,  9.141,  9.343,  9.545,  9.747,  9.950,  10.153, 10.357, 10.561, 10.766, 10.971}, // 220-270
    {11.176, 11.382, 11.588, 11.795, 12.001, 12.209, 12.416, 12.624, 12.831, 13.040, 13.248}, // 275-325
    {13.457, 13.665, 13.874, 14.084, 14.293, 14.503, 14.713, 14.923, 15.133, 15.343, 15.554}, // 330-380
    {15.764, 15.975, 16.186, 16.397, 16.608, 16.820, 17.031, 17.243, 17.455, 17.667, 17.879}, // 385-435
    {18.091, 18.303, 18.516, 18.728, 18.941, 19.154, 19.366, 19.579, 19.792, 20.005, 20.218}, // 440-490
    {20.431, 20.644, 20.857, 21.071, 21.284, 21.497, 21.710, 21.924, 22.137, 22.350, 22.563}, // 495-545
    {22.776, 22.990, 23.203, 23.416, 23.629, 23.842, 24.055, 24.267, 24.480, 24.693, 24.905}, // 550-600
    {25.118, 25.330, 25.543, 25.755, 25.967, 26.179, 26.390, 26.602, 26.814, 27.025, 27.236}, // 605-655
    {27.447, 27.658, 27.869, 28.079, 28.289, 28.500, 28.710, 28.919, 29.129, 29.338, 29.548}, // 660-710
    {29.757, 29.965, 30.174, 30.382, 30.590, 30.798, 31.006, 31.213, 31.421, 31.628, 31.834}, // 715-765
    {32.041, 32.247, 32.453, 32.659, 32.865, 33.070, 33.275, 33.480, 33.685, 33.889, 34.093}, // 770-820
    {34.297, 34.501, 34.704, 34.908, 35.110, 35.313, 35.516, 35.718, 35.920, 36.121, 36.323}, // 825-875
    {36.524, 36.725, 36.925, 37.126, 37.326, 37.526, 37.725, 37.925, 38.124, 38.323, 38.522}, // 880-930
    {38.720, 38.918, 39.116, 39.314, 39.511, 39.708, 39.905, 40.101, 40.298, 40.494, 40.690}, // 935-985
    {40.885, 41.081, 41.276, 41.470, 41.665, 41.859, 42.053, 42.247, 42.440, 42.633, 42.826}, // 990-1040
    {43.019, 43.211, 43.403, 43.595, 43.787, 43.978, 44.169, 44.359, 44.550, 44.740, 44.929}, // 1045-1095
    {45.119, 45.308, 45.497, 45.685, 45.873, 46.061, 46.249, 46.436, 46.623, 46.809, 46.995}, // 1100-1150
    {47.181, 47.367, 47.552, 47.737, 47.921, 48.105, 48.289, 48.473, 48.656, 48.838, 49.021}, // 1155-1205
    {49.202, 49.384, 49.565, 49.746, 49.926, 50.106, 50.286, 50.465, 50.644, 50.822, 51.000}, // 1210-1260
    {51.178, 51.355, 51.532, 51.708, 51.885, 52.060, 52.235, 52.410, 52.585, 52.759, 52.932}, // 1265-1315
    {53.106, 53.279, 53.451, 53.623, 53.795, 53.967, 54.138, 54.308, 53.479, 54.649, 54.819}  // 1320-1370    
};

float getTemperatureFromTable(float voltage) {
    for (int row = 0; row < 25; row++) {
        for (int col = 0; col < 10; col++) {
            float v1 = calibrationTableExtended[row][col];
            float v2 = calibrationTableExtended[row][col + 1];

            // Проверяем, попадает ли напряжение между v1 и v2
            if (voltage >= v1 && voltage <= v2) {
                // Линейная интерполяция
                float temp1 = row * 10 + col;
                float temp2 = row * 10 + col + 1;
                return temp1 + (voltage - v1) * (temp2 - temp1) / (v2 - v1);
            }
        }
    }

    return -1; // Выход за границы таблицы
}

void setup() {
    Serial.begin(9600);
    display1.setBrightness(0x0f);
    display2.setBrightness(0x0f);
    pinMode(RELAY_PIN, OUTPUT);
    digitalWrite(RELAY_PIN, LOW);
    ads.setGain(GAIN_SIXTEEN);
    ads.begin();
}

void loop() {
    myEnc.tick();
    long newPosition = myEnc.getPosition();
    Serial.print("Encoder Position: ");
    Serial.println(newPosition);
    if (newPosition != encoderValue) {
    encoderValue = newPosition;
    targetTemperature = 20 + encoderValue * step;
    targetTemperature = constrain(targetTemperature, 20, 1370);

    Serial.print("Encoder Value: ");
    Serial.println(encoderValue);
    Serial.print("Target Temperature: ");
    Serial.println(targetTemperature);
    }

    int16_t adc0 = ads.readADC_Differential_0_1();
    thermocoupleVoltage = adc0 * multiplier; 
    float thermocoupleTemp = getTemperatureFromTable(thermocoupleVoltage);
    Ttp1 = thermocoupleTemp + coldJunctionTemp;
    
    Serial.print("Напряжение: ");
    Serial.print(thermocoupleVoltage);
    Serial.print("Target Temperature: ");
    Serial.println(targetTemperature);
    Serial.print("Current Temperature: ");
    Serial.println(Ttp1);

    display1.clear();
    display2.clear();
    display1.showNumberDec(targetTemperature);
    display2.showNumberDec(Ttp1);
    
    display1.showNumberDec(targetTemperature);
    display2.showNumberDec(Ttp1);
    
    if (Ttp1 < Ttgt) {
      digitalWrite(RELAY_PIN, HIGH);
    }
    if (Ttp1 > Ttgt) {
      digitalWrite(RELAY_PIN, LOW);
    }
    
    if (Ttp1 < targetTemperature) {
    digitalWrite(RELAY_PIN, HIGH);
    } else {
    digitalWrite(RELAY_PIN, LOW);
    }
    delay(1000);
}

@ЕвгенийП , а когда мы задания из учебных заведений начали решать?)

Вы неправильно представляете себе “задание из учебного заведения”. Да, проект относится к научной работе в университете. Но его ведением занимаюсь исключительно я, так как это в моих интересах.

Ну и? Всё сходится.

Просто не вижу в этом ничего плохого.

И заодно temperature убрали. А чего было спорить?

Никогда. До сих поря я ничего не решал, просто пытался с огромным трудом заставить ТС выложить таки код (а не первые попавшиеся строки, как он выложил сначала).

А решать тут ничего не возможно, да и ТС не за этим пришёл.

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

А Вы перечитайте первый пост. Вы там видите хоть что-то похожее на вопрос? Или на объяснение, что именно идёт не так? Я не вижу…

В чём? В том, чтобы решать учебные задачи за ленивых задниц?

Ну, не видите и не видите, а вот @BOOM видит. И я вижу.

1 лайк