Почему задержка (1000) нарушает мою последовательную связь?

У меня есть следующий скетч...

void setup() {
  // поместите сюда код установки для однократного запуска:
  Serial.begin(115200);
}

void loop() {
  if(Serial.available() > 0){
    Serial.println("Hello world from Ardunio!");
  }
}

Это прекрасно работает с моим клиентским кодом...

import SerialPort from 'serialport';
const port = new SerialPort('/dev/ttyACM0', {
  baudRate: 115200,
  autoOpen: false
})

port.open(function (err) {
  if (err) {
    return console.log('Error opening port: ', err.message)
  }

  // Поскольку обратного вызова для записи нет, на порт будут выдаваться ошибки записи:
  console.log("port opened");
  port.on('readable', function () {
    console.log('Data:', port.read())
  })
})

Теперь я хочу замедлить его, поэтому я изменяю скетч на...

void loop() {
  if(Serial.available() > 0){
    Serial.println("Hello world from Ardunio!");
  }
  delay(10000);
}

Я ожидаю, что это задержит каждое сообщение на 10 секунд, однако, похоже, оно никогда не запускается повторно, поэтому я не получаю никаких сообщений. Что мне не хватает? Почему задержка может разорвать цикл?

, 👍0

Обсуждение

Что, если вы удвоите строку Serial.println("Hello world from Ardunio!");?, @Brian Cannard

что будет если убрать задержку?, @jsotola

Я думал, что это работает нормально, но теперь я сомневаюсь в этом, так как у меня снова возникли проблемы после того, как я вернулся к нескольким другим вещам, которые я пробовал. Я не уверен, что, когда он работал, я все еще случайно использовал while. Я попробую добавить несколько записей с задержками и посмотрю, поможет ли это вообще. Конечной целью является запись в последовательный порт каждые n секунд., @Jackie

Просто не кажется, что цикл зацикливается. Если я удалю if и добавлю несколько отпечатков и задержек, это, похоже, сработает. Почему это не работает, если я использую оператор if?, @Jackie

Вы пишете что-нибудь в ардуино по последовательной линии?, @Sim Son

потому что проверка утверждения if не оценивается как true, @jsotola


2 ответа


2

НИКОГДА не используйте delay() в цикле - это плохая привычка, к которой вы привыкаете, а затем возвращаетесь позже со сложным кодом, спрашивающим, почему ничего не происходит или ваш веб-сервер не работает в течение 10 секунд каждый раз, когда вы получаете запрос.

Поэтому вместо

void loop() {
  if(Serial.available() > 0){
    Serial.println("Hello world from Ardunio!");
  }
  delay(10000);
 }

вы бы сделали

unsigned long timerStart = 0;
unsigned long myTimer = 10000;

setup(){....}

 void loop() {
  if(Serial.available() > 0 ){
     if(millis() - timerStart > myTimer){      // без блокировки
       Serial.println("Hello world from Ardunio!");
       timerStart = millis(); // сброс таймера
     }    
   }
 }

То, что делает ваш код на данный момент, - это ввод предложения IF, если буфер заполнен точно в этом миллисекунде, затем подождите десять секунд, игнорируя все, что вы делаете. Следующий шанс попасть и так далее. Delay() блокирует обработку => это не очень хорошо в сценариях связи,

,

Конечно имеет смысл спасибо, @Jackie


1

Избавьтесь от if(Serial.available() > 0). Этот оператор if нужен только в том случае, если вы ожидаете информацию от Serial, но, похоже, это не относится к вашему проекту.

Кроме того, используйте delay() только в том случае, если у вас есть действительно веская причина.

,

Итак, это следующий шаг. Так что срабатывает, когда вы пишете?, @Jackie

Также, вероятно, поэтому это сработало в первый раз, я попытался упростить код для SO и предположил, что удаление записи не будет проблемой. Я был неправ, @Jackie

if(Serial.available() > 0) срабатывает, когда что-то получено от ПК. Если у вас возникли проблемы с вашим кодом - опубликуйте весь код. Вы не знаете, где ошибка — она может быть в коде, который был упущен., @P_B