Проблема с простым проектом

Я новичок в Arduino, и сегодня у меня проблема с этим кодом:

int led_1 = 10;
int led_2 = 11;
int led_3 = 12;
int button = 3;
int time = 0;
byte val = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(led_1, OUTPUT);
  pinMode(led_2, OUTPUT);
  pinMode(led_3, OUTPUT);
  pinMode(button, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  val = digitalRead(button);

  if (val == HIGH){
    time = millis();
    while (digitalRead(button) == HIGH) {
      if (millis() - time < 1000) {digitalWrite(led_1, HIGH);}
      else if (millis() -time > 1000 && millis()-time <2000) {digitalWrite(led_2, HIGH);}
      else if (millis()-time >2000) {digitalWrite(led_3, HIGH);}
    }
  } else { 
    time =0;
    digitalWrite(led_1, LOW);
    digitalWrite(led_2, LOW);
    digitalWrite(led_3, LOW);
    }
}

Код должен работать следующим образом: если я нажму кнопку менее чем за одну секунду, led_1 включится. Если я нажму его на одну или две секунды, led_2 включится; и если я нажму кнопку более 2 секунд, включится led_3. Если я не нажму кнопку, светодиоды останутся выключенными. Переменная time используется для определения времени, когда я начинаю нажимать кнопку, а затем для элемента управления millis()- time должно указывать, как долго я нажимаю кнопку.

Это работает какое-то время, затем после случайного времени (я думаю), если я нажимаю кнопку, включается только led_3 , Почему?

0 голосов | спросил linofex 6 SunEurope/Moscow2015-12-06T18:28:00+03:00Europe/Moscow12bEurope/MoscowSun, 06 Dec 2015 18:28:00 +0300 2015, 18:28:00

2 ответа


0

time должен быть unsigned int , Как только millis достигнет 32768, оно будет сохранено как -32768 в time, и ваши сравнения не будут работать. Это происходит через 32,768 секунд. Вот короткий эскиз, чтобы проиллюстрировать:

int time = 0;

void setup() {
  Serial.begin( 9600 );
}

void loop() {
    time = millis();
    if (time % 1000 == 0) {
      Serial.println( time );
      delay( 2 ); // let millis() increment
    }
}

Чтобы увидеть разницу, просто измените первую строку на

unsigned int time = 0;

Обратите внимание, как time переходит на 0 после 65535 (хорошо, печатается только 65000).

Я бы рекомендовал использовать константы без знака, добавив после цифр букву "U": 1000U. В ваших if вы должны привести millis к тому же (меньшему) типу: (unsigned int)millis(). Кроме того, круглые скобки делают выражение более понятным:

      else if (((unsigned int)millis() - time > 1000U) && ((unsigned int)millis() - tempo < 2000U)) {digitalWrite(led_2, HIGH);}
ответил slash-dev 6 SunEurope/Moscow2015-12-06T19:29:06+03:00Europe/Moscow12bEurope/MoscowSun, 06 Dec 2015 19:29:06 +0300 2015, 19:29:06
0

Ваш код кажется неэффективным, и есть переменная tempo, которая не отображается в других местах.

  if (val == HIGH) {
    time = millis();
    while (digitalRead(button) == HIGH) {
      int time0=millis();
      if (time0 - time < 1000) {
        digitalWrite(led_1, HIGH);
      } else if (time0 - time < 2000) {
        digitalWrite(led_2, HIGH);
      } else if (time0 - time > 2000) {
        digitalWrite(led_3, HIGH);
      }
    }
  }

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

ответил dda 6 SunEurope/Moscow2015-12-06T19:29:14+03:00Europe/Moscow12bEurope/MoscowSun, 06 Dec 2015 19:29:14 +0300 2015, 19:29:14

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132