Arduino работает правильно, только когда я прикасаюсь к нему

Я работаю над проектом Arduino, но столкнулся с проблемой, которую не знаю, как решить.

Единственное, что я сделал в аппаратной части, — это подключил arduino nano к источнику питания (зарядному устройству телефона) через контакты 5 В и заземление, но встроенные светодиоды говорят мне, что код не работает, поскольку он должно быть.
Светодиод TX (последовательный выход) должен гореть постоянно (поскольку код всегда выводит данные на монитор), но вместо этого он включается и выключается с более длительным интервалом времени, код работает медленнее, чем должен быть.< бр> Это прекращается, когда я касаюсь земли пальцем или когда Arduino подключается к компьютеру.

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

Есть идеи, что происходит и как это решить?

Чтобы дать больше контекста, я пытаюсь сделать термостат, который может принимать значение температуры и времени и включать или выключать реле. Это реле размыкает или замыкает электрическую цепь лабораторной плиты в зависимости от температуры и времени.
Есть 4 кнопки:
AUMENTAR ("увеличение" на английском): увеличивает выбранное значение на 5 (при нажатии имеет задержку 0,5 секунды).
DISMINUIR ("уменьшение"): уменьшает значение, выбранное в 5 (при нажатии имеет задержку 0,5 секунды).
NEXT ("следующий"): изменение редактируемого значения (без задержки).
INI_DET ("старт/стоп"): запускает или останавливает машину (без задержки).

Код:

#include <max6675.h>
#include <LiquidCrystal.h>

//
// ПЕРЕМЕННЫЕ
//

// Физическое состояние машины
int temperatura = 0; // в °С
int temperatura_prev;
// инт влажность;
bool maquina_en_funcionamiento = false;

// Пользовательские переменные (при неработающей машине)
int array_de_valores[] = {20,10};     // редактируемые пользователем значения
int valor_seleccionado = 0;             // редактируемое значение (по умолчанию, температура): 0=температура, 1=время, 2=влажность
// Переменные, видимые пользователю (при работающей машине)
int array_de_opciones[] = {0, 0};       // параметры, видимые пользователю
int opcion_seleccionada = 0;            // видимая опция (по умолчанию, машина): 0=машина, 1=операция

// Переменные обработки
int temp_bus, tiempo_bus, hum_bus;  // копии array_of_values, которые останутся фиксированными до конца процесса
int reloj = 0;                      // прошедшее время в минутах с момента запуска процесса
int reloj_prev;
unsigned long reloj_milis;          // время, прошедшее в миллисекундах с момента запуска процесса
unsigned long inicio_milis;         // миллисекунды в начале операции
int tiempo_restante;
bool resistencia_en_funcionamiento = false; // текущее состояние резистора (по умолчанию, выключено)

// Физические компоненты
LiquidCrystal lcd(6,7, 2,3,4,5);
MAX6675 sensor_temp(16,15,14);
#define RELE 13
  // кнопки
#define AUMENTAR 8 // Увеличить значение
#define DISMINUIR 9 // Уменьшить значение
#define SIGUIENTE 10 // Изменить значение
bool sig_pres = false;
#define INI_DET 11 // Запустить или остановить машину
bool ini_det_pres = false;

//
// ФУНКЦИИ
//

// Функции управления ЖК-дисплеем
void actualizarLCD() {
  if (!maquina_en_funcionamiento) { // если машина не работает
    switch (valor_seleccionado){
      case 0: // температура
        lcd.home();
        lcd.print("»TEMP TIEMPO HUM");
        lcd.setCursor(5,1);
        lcd.print(array_de_valores[0]);
        lcd.setCursor(8,1);
        lcd.print("°C");
        break;
      case 1: // время
        lcd.home();
        lcd.print(" TEMP»TIEMPO HUM");
        lcd.setCursor(5,1);
        lcd.print(array_de_valores[1]);
        lcd.setCursor(8,1);
        lcd.print("min");
        break;
      case 2: // влажность
        lcd.home();
        lcd.print(" TEMP TIEMPO»HUM");
        lcd.setCursor(5,1);
        lcd.print(array_de_valores[2]);
        lcd.setCursor(8,1);
        lcd.print("%");
        break;
    }
  }
  else { // если машина работает
    switch (opcion_seleccionada){
      case 0:
        lcd.home();
        lcd.print("»MAQUINA  OPERAC");
        lcd.setCursor(0,1);
        lcd.print("TEMP");
        lcd.setCursor(5,1);
        lcd.print(temperatura);
        lcd.setCursor(9,1);
        lcd.print("TIE");
        lcd.setCursor(13,1);
        lcd.print(tiempo_restante);
        break;
      case 1:
        lcd.home();
        lcd.print(" MAQUINA »OPERAC");
        lcd.setCursor(0,1);
        lcd.print("TEMP");
        lcd.setCursor(5,1);
        lcd.print(temp_bus);
        lcd.setCursor(9,1);
        lcd.print("TIE");
        lcd.setCursor(13,1);
        lcd.print(tiempo_bus);
        break;
    }
  }
}

// Редактируемые пользователем переменные функции
void aumentarValor(int cantidad) {
  array_de_valores[valor_seleccionado] += cantidad;
  actualizarLCD();
}
void cambiarValor(){
  switch (valor_seleccionado){
    case 0:
      valor_seleccionado = 1;
      break;
    case 1:
      valor_seleccionado = 2;
      break;
    case 2:
      valor_seleccionado = 0;
      break;
  }
  actualizarLCD();
}

// Функции управления процессом
void iniciarResistencia() {
  digitalWrite(RELE, HIGH);
  resistencia_en_funcionamiento = true;
}
void detenerResistencia() {
  digitalWrite(RELE, LOW);
  resistencia_en_funcionamiento = false;
}

void iniciarProc() {
  // делаем копию значений в array_of_values
  temp_bus = array_de_valores[0];
  tiempo_bus = array_de_valores[1];
  inicio_milis = millis();

  // запускаем машину (когда цикл продолжается)
  maquina_en_funcionamiento = true;

  actualizarLCD();
}
void detenerProc() {
  detenerResistencia();

  // удалить переменные
  temp_bus = 0;
  tiempo_bus = 0;
  reloj_prev = 0;
  reloj_milis = 0;
  inicio_milis = 0;
  tiempo_restante = 0;

  maquina_en_funcionamiento = false;

  actualizarLCD();
}

//
// ГЛАВНАЯ ПРОГРАММА
//

void setup() {
  // код, который выполняется только один раз:
  Serial.begin(9600);
  Serial.println("INICIANDO PROGRAMA");

  // реле
  pinMode(RELE, OUTPUT);
  detenerResistencia();

  // кнопки
  pinMode(AUMENTAR, INPUT);
  pinMode(DISMINUIR, INPUT);
  pinMode(SIGUIENTE, INPUT);
  pinMode(INI_DET, INPUT);

  // запуск ЖК
  lcd.begin(16,2);
  actualizarLCD();
}

void loop() { // код, который будет выполняться в цикле:
  // кнопки
  if (digitalRead(AUMENTAR) == HIGH) { // если нажата кнопка UP
    if (!maquina_en_funcionamiento) {  // и машина не работает
      aumentarValor(5);                // увеличить значение
      delay(500);                      // и ждать
    }
  }
  else if (digitalRead(DISMINUIR) == HIGH) { // если нажата кнопка DECREASE
    if (!maquina_en_funcionamiento) {        // ИДЕМ УВЕЛИЧЕНИЕ
      aumentarValor(-5);
      delay(500);
    }
  }
  else if (digitalRead(SIGUIENTE) == HIGH) { // если нажата кнопка NEXT
    if (!sig_pres) {                         // проверяем, не нажал ли я ее раньше
      sig_pres = true;                       // устанавливаем для переменной sig_pres значение true, чтобы заблокировать кнопку
      cambiarValor();                        // и меняем переменную
    }
  }
  else if (digitalRead(INI_DET) == HIGH) {   // если нажата кнопка INI_DET
    if (!ini_det_pres) {                     // проверяем, не нажал ли я ее раньше
      ini_det_pres = true;                   // устанавливаем для переменной ini_det_pres значение true, чтобы заблокировать кнопку
      if (!maquina_en_funcionamiento) {
        iniciarProc();
      }
      else {
        detenerProc();
      }
    }
  }

  if (digitalRead(SIGUIENTE) == LOW) {    // если кнопка NEXT не нажата
    if (sig_pres) {
      sig_pres = false;                   // разблокировать кнопку
    }
  }
  if (digitalRead(INI_DET) == LOW) { // если кнопка INI_DET не нажата
    if (ini_det_pres) {
      ini_det_pres = false;               // разблокировать кнопку
    }
  }

  // Некоторый вывод данных в монитор Serial
  Serial.print("Valor seleccionado: ");
  Serial.println(valor_seleccionado);
  Serial.print(array_de_valores[0]);
  Serial.print(", ");
  Serial.println(array_de_valores[1]);
  Serial.print("Maquina en funcionamiento: ");
  Serial.println(maquina_en_funcionamiento);

  // КОНТРОЛЬ НАД ПРОЦЕССОМ
  if(maquina_en_funcionamiento) {

    // КОНТРОЛЬ ТЕМПЕРАТУРЫ
    temperatura_prev = temperatura;
    temperatura = sensor_temp.readCelsius();

    if (temperatura >= temp_bus) { // если температура равна или превышает желаемую
      detenerResistencia(); // выключаем резистор
    }
    else { // если температура ниже желаемой
      if (!resistencia_en_funcionamiento) { // и резистор выключен
        iniciarResistencia();
      }
    }

    if (temperatura_prev != temperatura) {
      actualizarLCD();
    }

    // КОНТРОЛЬ ВРЕМЕНИ
    unsigned long milis_ahora = millis();
    milis_ahora -= inicio_milis;
    if ( (milis_ahora - reloj_milis) >= 1000){
      reloj_milis = reloj_milis + 1000;
    }

    reloj_prev = reloj;
    reloj = reloj_milis/60000;

    tiempo_restante = tiempo_bus - reloj;
    /*
    Serial.print("Reloj de milisegundos=");
    Serial.println(reloj_milis);
    Serial.print("Reloj=");
    Serial.println(reloj);
    Serial.print("Tiempo restante=");
    Serial.println(tiempo_restante);
    */
    if (reloj >= tiempo_bus) { // если достигнуто желаемое время
      detenerProc(); // арест
    }

    if (reloj_prev != reloj) {
      actualizarLCD();
    }

  }
}

Заранее спасибо.

, 👍0

Обсуждение

Вы пробовали питаться через разъем USB? А можно попробовать скетч Blink из Arduino IDE? Если этот скетч работает, должно быть что-то не так с кодом, и в этом случае вам нужно добавить его к своему вопросу., @chrisl

если вы внимательно прочитаете свой пост, вы обнаружите, что использовали много слов, чтобы сказать не что иное, как то, что у вас есть arduino nano, работающий от зарядного устройства для телефона, запускающий какой-то неизвестный код, и что вы думаете, что это влияет на выполнение кода когда вы прикасаетесь к Arduino .... первое, что вам нужно сделать, это убедиться, что вы действительно влияете на выполнение программы, а не только на светодиоды, @jsotola

@chrisl У USB-разъема та же проблема, он работает только при подключении к ПК. Скетч Blink работает нормально. Добавлю код в пост., @Facundo Barrera

@jsotola Выполнение определенно страдает, оно работает медленнее, чем должно., @Facundo Barrera

Вы можете проверить эту ссылку https://store.arduino.cc/usa/arduino-uno-rev3. Откройте вкладку «Документация». 5V. Этот контакт выводит регулируемое напряжение 5V от регулятора на плате. Плата может питаться от разъема питания постоянного тока (7–12 В), разъема USB (5 В) или контакта VIN платы (7–12 В). Подача напряжения через контакты 5 В или 3,3 В обходит регулятор и может повредить вашу плату. Мы не советуем., @Amit Ray

@AmitRay, значит, я должен питать Arduino через контакт Vin с источником питания выше 7 В?, @Facundo Barrera

@FacundoBarrera Да, это может решить эту проблему. Вы пробовали это?, @Amit Ray

@AmitRay Я пытался, но было то же самое. Хотя теперь я знаю, что происходит, зарядное устройство телефона издает какой-то шум, который мешает работе Arduino, и когда я касаюсь земли, он разряжается на мне. Я опубликую это как ответ, когда проясню некоторые сомнения, которые у меня есть. Спасибо за помощь!, @Facundo Barrera


1 ответ


1

Это прекращается, когда я касаюсь земли пальцем или когда Arduino подключен через USB к компьютеру.

Это похоже на проблему с заземлением, вероятно, между ПК и Arduino. Попробуйте соединить землю Arduino и землю ПК — думаю, проблема исчезнет.

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

Подключен ли ПК или зарядное устройство к розетке с помощью адаптера, который подключается только к двум из трех проводов? Обычно каждый из них подключается к заземлению домашней цепи, но если один из них не...

,

Когда ардуино подключено к компьютеру, работает как положено, но я не могу так зависеть от компьютера. И я не знаю, что вы имеете в виду под двумя или тремя проводами, там всего два провода (5v и земля)., @Facundo Barrera

JRobert, вы прочитали вопрос? или событие той части, которую вы цитируете?, @Juraj