Ардуино и импульсы по команде

Всем доброго времени суток. И снова я обращаюсь к вашим пытливым умам. Основная задача такая, по введенному в Matlab числу задать переменную ‘imp_l’, выдать импульс с пина длительностью в мкс как величина imp_l. Я решил начать издалека, пока просто когда самостоятельно ввожу единицу в порт, ардуинка должна выдавать одиночный импульс. Решил я эту задачу так:

#define PIN_laser 6
#define imp_l 400

uint32_t m1 = 0;
int a = 0;
int c = 1;
char value;

void setup()
{ Serial.begin(9600);
  pinMode(7, OUTPUT);
  }

void loop() {
  if (Serial.available() > 0) {
    value = Serial.read();
    Serial.write (value);
    if (c == 1 && value == '1') {
      m1 = micros();
      c = 0;
    }
  }
  //begin
  if (micros() - m1 <= imp_l && value == '1' && a == 0)
  {
    digitalWrite(PIN_laser, HIGH);
    Serial.print (2);
    a = 1;
  }
  //end
  if (micros() - m1 > imp_l && value == '1')
  { Serial.print (3);
    value = 0;
    c = 1;
    a = 0;
    digitalWrite(PIN_laser, LOW);
  }
} 

и все работает как нужно, в порт он мне выдал 1, потому что ее считал с порта, выдал 2, значит зашел в первый if и выдал 5V, выдал 3, значит зашел во второй if и подал на пин 0. Но как только я увеличиваю время импульса в 10 раз, т.е. imp_l = 4000, получаю на выходе “12”, т.е. во второй if не зашел и ардуинка выдает все время 5V, если я ещё раз напишу единицу в сериал порт, то только тогда я получу “13”, теперь уже первый if пролетает, попадаю во второй и выдается на пин 0.
Попробовал написать скетч с меньшим количеством millis(), вышло это:

#define PIN_laser 6
#define imp_l 4000

uint32_t m1 = 0;
char flag1 = '0';
bool flag2 = 0;
bool flag3 = 0;

void setup() {
  Serial.begin(9600);
  pinMode(7, OUTPUT);
}

void loop() {
  
  if (Serial.available() > 0)
  {
    flag1 = Serial.read();
    Serial.write (flag1);
  }
  if (flag1 == '1')
  {
    digitalWrite(PIN_laser, HIGH);
    Serial.print (2);
    flag2 = 1;
    flag1 = '0';
    m1 = millis();
  }
  if (millis - m1 >= imp_l && flag2 == 1) {
    flag3 = 1;
    flag2 = 0;
  }
  if (flag3 == 1)
  {
    flag3 = 0;
    digitalWrite(PIN_laser, LOW);
  }
}

но проблему это не решило, тоже при больших значениях imp_l выдает только “12”

Используй прерывания.

по идее так тоже должно работать, очень хотел бы узнать в чем причина) тут больше уже вопрос чести

Вангую, что у вас в Мониторе порта стоит завершение строки NL или CR/NL
Покажите скриншот окна Монитора порта, с которого вы посылаете свои управляющие символы

1 лайк

да, все верно! Спасибо! выбрал без конца строки и стало работать как часы)

@Nikita_H давайте есть слона по частям, а ошибки устранять по одной.

Скажите пожалуйста, на кой хрен Вы написали строки №№29-37?

Ведь как только отработает строка №30, а потом программа доберётся до строки №33, условие в последней выполнится обязательно.

Тогда получается, что вместе строк №№29-37 вполне можно было написать


  if (millis - m1 >= imp_l && flag2 == 1) {
    flag2 = 0;
    digitalWrite(PIN_laser, LOW);
  }


и это было бы ровно то же самое.

Вы именно так и хотели? Или тут ошибка?

я просто хотел отделить начало и конец импульса от millis(). Можно сделать и как Вы предложили.

Удалось?
(что бы это ни значило…)

да, получилось)