цикл while

Yer
Offline
Зарегистрирован: 12.02.2016
в скетче используется цикл while хотелось бы узнать можно ли одновременно считать и с других входов пока выполняется цикл while
 
uint32_t p_start;
void loop() {
 
  if(PINE & (1<<PE4))//вход Пин-2 на ардуино мега
 {
  p_start = millis(); 
  PORTE &=~(1<<PE5);}//выход пин-3
  while(PINE & (1<<PE4)) { 
  p_start=millis()-p_start;
  delayMicroseconds(p_start*WIDTH_MUL);
  PORTE |=(1<<PE5);
  }
}
 
заранее спасибо!
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Не навижу циклы. Циклы это "эгоисты".  Пока крутится цикл, все остальное стоит. Единственный приемлемый цикл это loop(){}

Yer
Offline
Зарегистрирован: 12.02.2016

спасибо за ответ а есть другие варианты при пропадании импульса выставлял выход на high как это делает while

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы тут уж почти год, поа бы и научиться код вствалять.

Можно-то оно, конечно, можно. Вопрос для чего? Что именно делать-то надо?

nik182
Offline
Зарегистрирован: 04.05.2015

Yer пишет:

спасибо за ответ а есть другие варианты при пропадании импульса выставлял выход на high как это делает while


Хочу заметить, что while ничего не делает, кроме проверки условия и ветвления программы в зависимости от результата. Все остальные действия пишете вы. Для ветвления можно использовать оператор if ... else. И тоже придётся написать самому те действия, которые вам нужны. В данном случае цикл while будет пинать пятый пин каждые p_start*WIDTH_MUL микросекунд, пока на четвёртой ноге будет единица. Сакральный смысл этого повторяющегося действия не понятен. Как и присутствие оператора while именно в этом месте программы. Считывать другие ноги я надеюсь Клапауций разрешит, если вы вставите операторы считывания внутрь цикла while.

Yer
Offline
Зарегистрирован: 12.02.2016
#define WIDTH_MUL   0.1
#define IN_1_PIN    2
#define IN_2_PIN    3
#define IN_3_PIN    4
#define IN_4_PIN    5
#define IN_5_PIN    6
#define IN_6_PIN    7

#define IN_MASK     ((1 << IN_1_PIN) | (1 << IN_2_PIN) | (1 << IN_3_PIN)|(1<<IN_4_PIN)|(1<<IN_5_PIN)|(1<<IN_6_PIN))

#define OUT_1_PIN   8
#define OUT_2_PIN   9
#define OUT_3_PIN   10
#define OUT_4_PIN   11
#define OUT_5_PIN   12
#define OUT_6_PIN   13
#define OUT_1_PORT  PORTB0
#define OUT_2_PORT  PORTB1
#define OUT_3_PORT  PORTB2
#define OUT_4_PORT  PORTB3
#define OUT_5_PORT  PORTB4
#define OUT_6_PORT  PORTB5

#define OUT_MASK    ((1 << OUT_1_PORT) | (1 << OUT_2_PORT) | (1 << OUT_3_PORT)| (1 << OUT_4_PORT)| (1 << OUT_5_PORT)|(1 << OUT_6_PORT))

void setup() {

// инициализируем входы
  for (int i = IN_1_PIN; i < IN_6_PIN + 1; i++) {
    pinMode(i, INPUT);
  }
      // инициализируем выходы
  for (int i = OUT_1_PIN; i < OUT_6_PIN + 1; i++) {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
}
uint32_t p_start, p_stop, p_width;
uint8_t in_state;

void loop() {
 
in_state = PIND & IN_MASK;                // берем состояние всех 3-х входов
  if ((in_state & IN_MASK) != IN_MASK) {    // есть ли хоть один вход в LOW
    p_start = micros();                     // запомнили время прихода имп.
      // состояние входов точно зеркалим на выходы
    in_state ^= IN_MASK;       
    PORTB |=(in_state >> 2);
    while((PIND & IN_MASK) != IN_MASK);     // ждем, пока имульс закончится
    //p_start = micros();                      // фиксируем время окончания
    p_start = micros() - p_start;             // вычисляем сколько длился вх. имп.
    delayMicroseconds(p_start * WIDTH_MUL); // добавляем к длит. вых. имп.
    PORTB &= ~OUT_MASK;                      // закончили, все выходы в LOW
 }
}

 

Yer
Offline
Зарегистрирован: 12.02.2016

скетч использовал для управления газовыми форсунками,ардуино берет сигналы с 2,3,4,5,6,7 входов и выдает с выходов 8,9,10,11,12,13

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

nik182
Offline
Зарегистрирован: 04.05.2015

Чтобы отзекалить порт нужно сдвинуть на 6, а не на 2. Это раз.
Вы добавляете к длительности импульса 10 процентов микросекунд. А можно 12% ? Мне кажется, если вместо
delayMicroseconds(p_start * WIDTH_MUL);
Написать
delayMicroseconds(p_start >> 8);
всё будет успевать отработать.

Yer
Offline
Зарегистрирован: 12.02.2016

оператор while и delay не задерживает цикл программы когда сразу на все 6 входов подается импулс  с большой частотой скажем как на графике 20Гц и больше

nik182
Offline
Зарегистрирован: 04.05.2015

Я сморю на программу и вижу задержку в строке 52. Она есть всегда. В независимости от скорости прихода импульсов. Судя по осцилограмме задержка реакции программы около 37 мс. Это ни как не соответствует приведенному алгоритму. Единственное место, где может тормозить программа - дробное умножение( но не верю что на столько). Поэтому предлагаю заменить на целочисленгое деление на 8 - сдвигом на 3 в право. Или просто целочисленным делением на 10. И посмотреть на осцилограмму изменится чтото или нет.

Yer
Offline
Зарегистрирован: 12.02.2016

Спасибо за совет я вообще убрал delayMicroseconds на 52 строке по пробую так запустит двигатель может повлияет 

Yer
Offline
Зарегистрирован: 12.02.2016

Правильно заметили как убрал delayMicroseconds ардуино успевает обработать сигнал и выдавать на  выходе точно так же

a5021
Offline
Зарегистрирован: 07.07.2013

nik182 пишет:
Чтобы отзекалить порт нужно сдвинуть на 6, а не на 2. Это раз.

Зеркалится там не порт, а входы/выходы -- это два.

Цитата:
Вы добавляете к длительности импульса 10 процентов микросекунд. А можно 12% ? Мне кажется, если вместо delayMicroseconds(p_start * WIDTH_MUL); Написать delayMicroseconds(p_start >> 8); всё будет успевать отработать.

Вам не правильно кажется.

ssss
Offline
Зарегистрирован: 01.07.2016

Yer пишет:

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