Термопара и мультиметр

Я собрал этот скрипт, который должен позволить моему Arduino Mega отображать показания термопары на последовательном мониторе, а также отображать показания напряжения и сопротивления на данном компоненте. Буду признателен за любые советы по улучшению/оптимизации:

#include <SparkFun_MCP9600.h>
MCP9600 tempSensor;
int analogPin = 0;
int raw = 0;
int Vin = 5;
float Vout = 0;
float R1 = 220;
float R2 = 0;
float buffer = 0;
float volt = 0;
int input = 0;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(100000);
  tempSensor.begin();

  if (tempSensor.isConnected()) {
    Serial.println("Device will acknowledge!");
  }
  else {
    Serial.println("Device did not acknowledge! Freezing.");
    while (1); //висеть навсегда
  }

  if (tempSensor.checkDeviceID()) {
    Serial.println("Device ID is correct!");
  }
  else {
    Serial.println("Device ID is not correct! Freezing.");
    while (1);
  }

  pinMode(A4, INPUT);
}

void loop() {

  input = analogRead(A4); // функция AnalogRead используется для получения аналоговых данных
  volt = (input * 5.0) / 1024.0; //формула, используемая для выполнения действия

  if (tempSensor.available()) {
    Serial.print("Thermocouple: ");
    Serial.print(tempSensor.getThermocoupleTemp());
    Serial.print(" °C   Ambient: ");
    Serial.print(tempSensor.getAmbientTemp());
    Serial.print(" °C   Temperature Delta: ");
    Serial.print(tempSensor.getTempDelta());
    Serial.print(" °C");
    Serial.println();
  }

  raw = analogRead(analogPin);
  if (raw)
  {
    buffer = raw * Vin;
    Vout = (buffer) / 1024.0;
    buffer = (Vin / Vout) - 1;
    R2 = R1 * buffer;
    Serial.print("Vout: ");
    Serial.println(Vout);
    Serial.print("R2: ");
    Serial.println(R2);
    Serial.print("voltage is:");
    Serial.println(volt);
    Serial.print("current is:");
    Serial.println(volt / R2);
    delay(1000);
  }
}

, 👍2

Обсуждение

«должен позволять»: разрешает или не разрешает?, @Thomas Weller

Код работает как есть? Я вижу, вы определяете некоторые переменные (такие как Vin, R1, AnalogPin), которые никогда не изменяются и фактически используются только как константы. Вы должны определить их как «const» или использовать #define (например, для номеров аналоговых портов)., @StarCat


1 ответ


1

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

int analogPin = 0;
[...]
pinMode(A4, INPUT);

Эти способы использования булавок противоречивы. Я лично предпочитаю настройки в начале файла, поэтому я ожидаю

int analogPin = 0;
int whateverPin = A4;  // У меня пока нет хорошего имени

Пока у вас есть

pinMode(A4, INPUT);

нет

pinMode(analogPin, INPUT);

Основной цикл выполняет две функции: а) показывает показания температуры и б) показывает спецификации компонентов. Это было бы более очевидно, если бы было написано так:

void loop() {
  input = analogRead(A4); // функция AnalogRead используется для получения аналоговых данных
  volt = (input * 5.0) / 1024.0; //формула, используемая для выполнения действия

  showTemperatureReadings();
  showComponentReadings();    
}

Вы не находите, что это выглядит немного странно? А как насчет того, что было до этих двух больших методов show...()? Эти две строки явно принадлежат showComponentReadings().

Теперь многие переменные объявляются вне методов. Это делает их глобальными переменными. Их можно изменить из любого места в коде. Когда проект растет, побочные эффекты — это зло. Давайте удалим как можно больше из них.

Вы можете избавиться от:

int input = 0;
float volt = 0;
float buffer = 0;
float R2 = 0;
float Vout = 0;
int raw = 0;

Я думаю, что после этого изменения метод setup() мог бы быть более кратким. Многое связано только с датчиком температуры. Я бы тоже извлек метод.

Сообщения об ошибках, подобные

Устройство не подтвердило! Замораживание.

не может иметь большого значения для пользователя. Сообщение типа

Датчик температуры не подтвердился! Проверьте проводку и нажмите кнопку сброса, чтобы повторить попытку.

может дать более содержательные инструкции.

Окончательный код с этими предложениями:

#include <SparkFun_MCP9600.h>
MCP9600 tempSensor;
int analogPin = 0;
int whateverPin = A4;
float R1 = 220;
int Vin = 5;

void setupTemperatureSensor() {
  tempSensor.begin();
  if (tempSensor.isConnected()) {
    Serial.println("Temperature sensor acknowledged.");
  }
  else {
    Serial.println("Temperature sensor did not acknowledge! Check the wiring and press the reset button to retry.");
    while (1); //висеть навсегда
  }

  if (tempSensor.checkDeviceID()) {
    Serial.println("Temperature sensor ID is correct.");
  }
  else {
    Serial.println("The temperature sensor ID does not have the expected value. Do you use a different sensor type? Use a SparkFun MCP9600.");
    while (1);
  }
}

void setup() {
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(100000);

  setupTemperatureSensor();

  pinMode(whateverPin, INPUT);
  pinMode(analogPin, INPUT);
}

void showTemperatureReadings() {
    if (tempSensor.available()) {
    Serial.print("Thermocouple: ");
    Serial.print(tempSensor.getThermocoupleTemp());
    Serial.print(" °C   Ambient: ");
    Serial.print(tempSensor.getAmbientTemp());
    Serial.print(" °C   Temperature Delta: ");
    Serial.print(tempSensor.getTempDelta());
    Serial.print(" °C");
    Serial.println();
  }
}

void showComponentReadings() {
  int input = analogRead(whateverPin); // функция AnalogRead используется для получения аналоговых данных
  float volt = (input * 5.0) / 1024.0; //формула, используемая для выполнения действия
  int raw = analogRead(analogPin);
  if (raw)
  {
    float buffer = raw * Vin;
    float Vout = (buffer) / 1024.0;
    buffer = (Vin / Vout) - 1;    
    float R2 = R1 * buffer;
    Serial.print("Vout: ");
    Serial.println(Vout);
    Serial.print("R2: ");
    Serial.println(R2);
    Serial.print("voltage is:");
    Serial.println(volt);
    Serial.print("current is:");
    Serial.println(volt / R2);
    delay(1000);
  }
}

void loop() {
  showTemperatureReadings();
  showComponentReadings();
}

С активным свертыванием кода, я бы сказал, теперь очень просто получить представление о том, что делает код и что можно настроить:

Код свернут


Изменить:

После того, как вы дали ссылку на схему, я бы

  • переименуйте любой контакт в voltageDividerPin.
  • изменить вычисление float volt = (input * 5.0) / 1024.0; на сопоставление, поскольку оно сопоставляет 1024 входных значений с 5 В, поэтому float volt = map(voltageReading, 0 , 1024, 0, Вин);
  • полностью удалите analogPin, так как он также не используется в исходном коде.

Я также надеюсь, что прочитал статью и понял последствия использования резистора на 220 Ом.

,

Re «_Я не уверен, работает ли analogRead()0 в качестве аргумента]_»: работает. analogRead() обрабатывает A0 ([определяется как 54 на Mega](https://github.com/arduino/ArduinoCore-avr/blob/1.8.2/variants/mega/pins_arduino.h#L51 -L83)) как [эквивалентно 0](https://github.com/arduino/ArduinoCore-avr/blob/1.8.2/cores/arduino/wiring_analog.c#L42-L55)., @Edgar Bonet

Код омметра взят отсюда: http://www.circuitbasics.com/arduino-ohm-meter/ Я предполагаю, что схема схемы все еще в порядке?, @Chris

@Chris: я обновил ответ в соответствии со схемами., @Thomas Weller

В моем случае это будет 220 мОм, так как там должно быть неизвестное сопротивление. Еще раз спасибо!, @Chris

@ Крис: 5 В/440 мОм = 11 А. Arduino может обрабатывать максимум 500 мА на своем выводе 5V. Кроме того, вам нужен резистор на 28 Вт для управления питанием, иначе он сгорит. Все в порядке, если вы рассмотрели все электрические вещи. Я просто не считаю это «нормальным» использованием Arduino., @Thomas Weller

Я использую резисторы 1 кОм, чтобы снизить общее сопротивление цепи. Есть три подключения макетной платы к источнику 5 В, GND и контакту аналогового считывания. Но принципиально мне нужно, чтобы Arduino определял неизвестное сопротивление, которое в данном случае просто крошечное., @Chris