Оптимизация опроса датчика

void loop() {
  for (byte i = 0; i < 100; i++) 
  {    
        DATA[i]    = analogRead(PIN_A0);
        delayMicroseconds(1399);       
  }
 ...
}

После опроса датчика, данные выводятся на экран в виде графика
Можно как-то отказаться от delayMicroseconds(1399); в пользу

micros() - TIME >= 1399

?

Я думаю, никто из коллег возражать не будет.

2 лайка

Да я и сам не против, только кнопки начинают срабатывать через раз.

а где тута кнопок видно?

unsigned long TIME_BUTTON = 0;
bool SELECT_BUTTON        = true;
bool BUTTON(byte PIN) {
  if (SELECT_BUTTON)                                                                //Очищаем все сохранённые значения
      if (!digitalRead(PIN) && millis() - TIME_BUTTON >= 400)
      {
        SELECT_BUTTON   = false;
        TIME_BUTTON    = millis(); 
        return true;
      }
    if (digitalRead(PIN))
        SELECT_BUTTON = true;

    return false;
}

byte SELECT_TIME = 0;
void loop() {
  for (byte i = 0; i < 100; i++) 
  {    
        DATA[i]    = analogRead(PIN_A0);
        delayMicroseconds(1399);       
  }
 
  if (BUTTON(2))
      ++SELECT_TIME;
}

@alechevichelov , если хотите получить не глум, а осмысленный ответ, нужно:

  1. Привести полный скетч.
  2. Привести подробную схему (с разводкой земли и питания).
  3. Задать вопрос, из которого понятно:
    3.1. Чего хочется добиться.
    3.2. Что вместо этого получается.
    3.3. Чем 3.1 отличается от 3.2.

А где функция setup() ? Опять код не полный.
Функция loop() и так цикл бесконечный. Зачем в ней еще один?

Усё равно фигня
unsigned long TIME_BUTTON = 0;
bool SELECT_BUTTON        = true;
byte SELECT_TIME = 0;
uint8_t i = 0;
uint16_t DATA[100];
uint32_t prevMicros, curMocros, interval = 1399;

bool BUTTON(byte PIN) {
  if (SELECT_BUTTON)                                                                //Очищаем все сохранённые значения
      if (!digitalRead(PIN) && millis() - TIME_BUTTON >= 400)
      {
        SELECT_BUTTON   = false;
        TIME_BUTTON    = millis(); 
        return true;
      }
    if (digitalRead(PIN))
        SELECT_BUTTON = true;

    return false;
}

void setup() {
   prevMicros = micros();
}

void loop() {
  curMicros = micros();

  if (curMicros - prevMicros >= interval) {
    DATA[i++] = analogRead(PIN_A0);
    prevMicros = curMicros;
  }
 
  if (BUTTON(2))
      ++SELECT_TIME;

  if (i == 99) {
    // Выполнить тут что там планировалось (усреднение?)
    i = 0;
  }
}

Это тебе нужно выкинуть цикл for и переписать заполнение массива

Вы имели ввиду это?

void setup() {
  // прерывание на D2 (UNO/NANO)
  attachInterrupt(0, isr, CHANGE);
}

void isr() {
 DATA[i]    = analogRead(PIN_A0);
}

Повесить какой ни будь таймер 555 на D2 и считывать показания в функции isr()?

Нет. Вам же выше ‘BOOM’ показал пример считывания без цикла. Выносите ‘i’ в глобальные. И последнее значение таймера туда же. И на каждый вызов ‘loop’ выполняете то, что у вас является одной итерацией цикла. Далее проверяете, если все данные считаны, то как-то их обрабатываете и куда-то выводите, после чего обнуляете ‘i’ для считывания следующей порции данных.

Я сообщение удалил, но думаю нужен програмный счетик и таймер в лупе короче вариантов есть, сейчас не очень могу

Получаешь говнокод.

Да ему сейчас и “так сойдеть”.

Да, у меня именно в скетчах для Ардуино маловато опыта, так что ориентировался на пример выше и на примеры из туториалов на англоязычном сайте Ардуино.

А как ещё, ну кроме вынесения в глобальные, сохранять состояние между вызовами ‘loop’? Ну т.е. можно буфер считываемых значений, текущую позицию и время последнего считывания оформить в виде отдельного класса с каким-то набором внешних методов и свойств. Но ссылку на экземпляр этого класса всё равно ведь придётся хранить глобально, чтобы оно было доступно между вызовами ‘loop’.

static

Типа такова
void setup() {

}

void loop() {
  static uint8_t i = 0;
  if (i++ > 99) {
    i = 0;
  }
}
2 лайка

Об оптимизации
http://codius.ru/articles/Arduino_ускоряем_работу_платы_Часть_2_Аналого_цифровой_преобразователь_АЦП_и_analogRead

На кнопки свой millis, на датчик свой и потом в loop оба проверять. Они у тебя не должны связаны друг с другом, и каждый срабатывать должен независимо. У гайвера про миллис вроде все доходчиво расписано

Я уже пробовал прерывания ISR

ISR(ADC_vect) {
  if (trueValue) {
    int result = ADCL | (ADCH << 8);  // ADLAR=1, Получаем 8-битный результат, остальными битами пренебрегаем
   
    ADMUX = analog_ref | (pin & 0x07);// Устанавливаем новый вход для преобразования
    trueValue = false;                // Устанавливаем флаг смены входного пина - следующее прерывание пропускаем
  }
  else {
    trueValue = true; // Первый раз пропускаем считывание и устанавливаем флаг на чтение в следующий раз
  }
}

Но они слишком медленные по сравнению с этим

for (byte i = 0; i < 100; i++) 
  {    
        DATA[i]    = analogRead(PIN_A0);
        delayMicroseconds(1399);       
  }

Если уж добрались до регистров , смотрите там уже ADC Prescaler Select Bits что бы выбрать частоту АЦП

А здесь получаем неверный результат