Код Arduino не работает должным образом (Пожалуйста, помогите)

Возникли некоторые проблемы с тем, чтобы заставить мою плату выполнять ту функцию, которую я хочу, чтобы она выполняла. Это проект, который я должен выполнить через несколько дней, и я наткнулся на стену, которую просто не могу преодолеть. Теперь я скажу, что проблема определенно заключается в том, как я закодировал программу, но на самом деле я недостаточно знаю об Arduino (и кодировании), чтобы понять, почему она не работает. Моя плата правильно подключена к использованию 3 светодиодов, динамика, фоторезистора и ультразвукового датчика (определяет расстояния). Моя программа Arduino принимает последовательный ввод из графического интерфейса, созданного мной в MATLAB. Я проверил, что код MATLAB хорош, и последовательный порт взаимодействует правильно. Я сделал будильник, который срабатывает при обнаружении света или движения. Он имеет 3 основные функции:

  1. Поставь будильник
  2. Выключите сигнализацию
  3. "повтор" , который просто задерживается на 5 минут, а затем будильник срабатывает

Повтор и выключение будильника в моем коде работают отлично, но вот с установленным будильником у меня возникли проблемы. Опция повтора выключает желтый светодиод, чтобы убедиться, что он включен "повтор". Красный светодиод загорается, когда сигнализация в данный момент выключена. Зеленый светодиод загорается, когда будильник установлен. Когда я пытаюсь активировать функцию "Set Alarm", которая является случаем " O " в случае переключателя, свет действительно загорается, но датчики не улавливают вход, насколько я могу судить. Снова я проверил контакты, и все настроено правильно, так как я изолировал их и проверил, что они работают. У меня есть подозрение, что проблема заключается в том, что у меня есть датчики, инициализированные в корпусе переключателя "Set Alarm" (случай "O", а не 0). Я действительно не знаю, как заставить датчики постоянно работать в этом корпусе выключателя, пока не будет активирован корпус "turn alarm off". Мне нужно, чтобы датчики были активированы/сброшены в случае "Set Alarm".

**Я тоже новичок на этом форуме, поэтому, пожалуйста, дайте мне знать, если я что-то упустил!

вот мой код:

void setup() 
{
  Serial.begin(115200);
  pinMode(12,OUTPUT); //RED
  pinMode(13,OUTPUT); //GREEN
  pinMode(14,OUTPUT); //YELLOW
  pinMode(16,OUTPUT); //SPEAKER
  pinMode(4,INPUT); //Echo
  pinMode(2,OUTPUT); //Trig
}

void loop() 
{
 if(Serial.available() >0)
 {
 char b = Serial.read();
    
  switch(b)
  {
    //Turn Alarm off
    case 'A' : 
    {
    digitalWrite(12,LOW);//red off
    digitalWrite(13,LOW); // green off
    digitalWrite(14,LOW); //yellow off
    noTone(16);
    delay(500);
    }
    break;
    
    // Set alarm
    case 'O' : 
    {
      int light;
  light = analogRead(0);
  unsigned long distance;
    digitalWrite(2,LOW);
  delayMicroseconds(2);
  digitalWrite(2,HIGH);
  delayMicroseconds(10);
  digitalWrite(2,LOW);
  distance = pulseIn(4,HIGH);
  distance = distance/58; //centimeters
  delay(500);
  
    digitalWrite(12,LOW); //red off
    digitalWrite(14,LOW); //yellow off
    digitalWrite(13,HIGH); //green on

  if (light < 400)
    {
     digitalWrite(12,HIGH);//red on
    digitalWrite(13,LOW); // green off
    digitalWrite(14,LOW); //yellow off
    tone(16,832);
    delay(500); 
    }

  if (distance < 50)
    {
     digitalWrite(12,HIGH);//red on
    digitalWrite(13,LOW); // green off
    digitalWrite(14,LOW); //yellow off
    tone(16,832);
    delay(500); 
    }

    }
    break;
    
    // snooze option
    case 'Z' : 
    {
    digitalWrite(14,HIGH); //yellow on
    digitalWrite(12,LOW); //red off
    digitalWrite(13,LOW); // green off
    noTone(16);
    delay(300000UL);
    digitalWrite(12,HIGH); //red on
    digitalWrite(13,LOW); // green off
    digitalWrite(14,LOW); //yellow off
    tone(16,832);
    delay(500); 
    }
    break;
   }

   
  }
}

Любая помощь будет очень ценна!

, 👍1

Обсуждение

Привет, Джеральдо, и добро пожаловать в Arduino Stack Excange. Пожалуйста, пройдите [экскурсию] и прочитайте все до конца, чтобы заработать свой первый значок. В вашем коде, похоже, отсутствует верхний раздел с вашим объявлением includes и глобальной переменной. Не могли бы вы, пожалуйста, проверить и добавить его., @sa_leinad

Пожалуйста, используйте Автоматический формат для форматирования вашего кода. В среде IDE Arduino перейдите в меню Инструменты > Автоматический формат или используйте сочетание клавиш Ctrl + T., @sa_leinad


2 ответа


Лучший ответ:

1

Самый простой способ устранить неполадки в программе-это добавить Serial.println(); операторы везде. Например, вы можете добавить Serial.println("Установка будильника"); в первой строке корпуса для установки будильника.

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

Сначала я бы создал переменную setAlarmMode и установил ее в false.

setAlarmMode = false;

Затем я бы удалил чтение датчиков из оператора case и вместо этого установил setAlarmMode в true.

// Set alarm
case 'O' :
  {
    Serial.println("Setting Alarm");

    // Set the LEDs for the mode
    digitalWrite(12, LOW); //red off
    digitalWrite(14, LOW); //yellow off
    digitalWrite(13, HIGH); //green on

    setAlarmMode = true;
  }
  break;

Теперь я бы вставил этот код вне блока if (Serial.available() > 0)> code:

// Read sensors
if (setAlarmMode == true)
  {
    Serial.println("Reading sensors");
    int light;
    light = analogRead(0);
    Serial.print("Light sensor value: ");
    Serial.print(light);
    
    unsigned long distance;
    
    // Do trigger pulse
    digitalWrite(2, LOW);
    delayMicroseconds(2);
    digitalWrite(2, HIGH);
    delayMicroseconds(10);
    digitalWrite(2, LOW);
    
    distance = pulseIn(4, HIGH);
    distance = distance / 58; //centimeters
    Serial.print("   Distance sensor value: ");
    Serial.println(distance);

    if (light < 400)
    {
      Serial.println("Light below threshold");
      setAlarmMode = false;
      activateAlarm();
    }

    if (distance < 50)
    {
      Serial.println("Distance below threshold");
      setAlarmMode = false;
      activateAlarm();
    }

    delay(500);
  }

Я также создал функцию для хранения общего кода отображения сигнала тревоги:

void activateAlarm(void)
{
  digitalWrite(12, HIGH); //red on
  digitalWrite(13, LOW); // green off
  digitalWrite(14, LOW); //yellow off
  tone(16, 832);
  delay(500);
}
,

Большое вам спасибо за вашу помощь! Я действительно ценю это. Сейчас программа отлично работает., @Geraldo


2

Проблема в том, что, если вы вводите "О", вы идете к установленному будильнику только один раз. Если сигнал тревоги не был вызван, он просто проходит через операторы if и затем возвращается в основной цикл. В этом основном цикле вы только проверяете свои датчики, если что-то было введено в последовательную консоль. Это означает, что если вы ничего не вводите во время цикла, ничего не происходит.

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

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

char state = 'A'; //initialize state in Off state
char b;          // make user input variable global
void setup()
{
  Serial.begin(115200);
  pinMode(12, OUTPUT); //RED
  pinMode(13, OUTPUT); //GREEN
  pinMode(14, OUTPUT); //YELLOW
  pinMode(16, OUTPUT); //SPEAKER
  pinMode(4, INPUT); //Echo
  pinMode(2, OUTPUT); //Trig
}

void loop()
{
  if (Serial.available() > 0)
  {
    b = Serial.read();
  }
  // закрыть раздел ввода пользователя

  switch (state) // run switch case every loop
  {
    //Выключить сигнализацию
    case 'A' :
      {
        digitalWrite(12, LOW); //red off
        digitalWrite(13, LOW); // green off
        digitalWrite(14, LOW); //yellow off
        noTone(16);

        delay(500);
      }
      break;

    // Установить сигнализацию
    case 'O' :
      {
        int light;
        light = analogRead(0);
        unsigned long distance;
        digitalWrite(2, LOW);
        delayMicroseconds(2);
        digitalWrite(2, HIGH);
        delayMicroseconds(10);
        digitalWrite(2, LOW);
        distance = pulseIn(4, HIGH);
        distance = distance / 58; //centimeters
        delay(500);

        digitalWrite(12, LOW); //red off
        digitalWrite(14, LOW); //yellow off
        digitalWrite(13, HIGH); //green on

        if (light < 400)
        {
          digitalWrite(12, HIGH); //red on
          digitalWrite(13, LOW); // green off
          digitalWrite(14, LOW); //yellow off
          tone(16, 832);
          delay(500);
        }

        if (distance < 50)
        {
          digitalWrite(12, HIGH); //red on
          digitalWrite(13, LOW); // green off
          digitalWrite(14, LOW); //yellow off
          tone(16, 832);
          delay(500);
        }

      }
      break;

    // snooze option
    case 'Z' :
      {
        digitalWrite(14, HIGH); //yellow on
        digitalWrite(12, LOW); //red off
        digitalWrite(13, LOW); // green off
        noTone(16);
        delay(300000UL);
        digitalWrite(12, HIGH); //red on
        digitalWrite(13, LOW); // green off
        digitalWrite(14, LOW); //yellow off
        tone(16, 832);
        delay(500);
      }
      break;
  }

  state = b; // обновление состояния на основе входных данных

}
,