Нужна помощь с перепрограммированием без delay

Dlackjack

✩✩✩✩✩✩✩
17 Фев 2020
4
0
У меня есть код сирены, я использую переключатель что бы менять звук, но при переключении есть задержка, я использую Gyverbutton и в ролике было сказано что нужно убирать delay но я не умею.

Вот код:
C++:
#include <GyverButton.h>
GButton butt1(5);
GButton butt2(6);
GButton butt3(7);
GButton butt4(8);
GButton butt5(9);


int buzzer = 3;  //переменная с номером пина динамика
int pwm;
int i = 650;
float dy = 1;
void setup(){
  Serial.begin(9600);     
}
 
void loop() {
  butt1.tick();
  butt2.tick();
  butt3.tick();
  butt4.tick();

  if (butt1.isHold()){
    Serial.println("OFF");
    noTone(3);
  }
//            Tone 1
  if (butt2.isHold()){
    Serial.println("Code 1");
 
    for (i = 750; i < 1250; i++){
      tone(3,i);
      delay(4);
      
      }
    for (i = 1250; i > 750; i--){
      tone(3,i);
      delay(4);
      
      }
  }
//            Tone 2

  Serial.println("Code 2");
  if (butt3.isHold()){ 
    for (i = 900; i < 1600; i++){
    tone (3,i);
    delayMicroseconds(165);
   }
   for (i = 1600; i > 900; i--){
    tone (3,i);
    delayMicroseconds(15);
   }
  }
//            Tone 3

  Serial.println("Code 3");
  if (butt4.isHold()){
   for (i = 450; i < 750; i++){
    tone (3,i);
    delayMicroseconds(20);
   }
    for (i = 750; i > 450; i--){
    tone (3,i);
    delayMicroseconds(20);
   }
  }
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,302
Москва
тут проблема не в задержках. Сама по себе задержка в 20 микросекунд тьфу.
Проблема вот в чем:
for (i = 1250; i > 750; i--)
Циклы внутри loop зло. тут уже будет какая то ощутимая задержка и избавляться надо от циклов. Полупустой скетч крутиться 100-200 тысяч раз в секунду
 

Dlackjack

✩✩✩✩✩✩✩
17 Фев 2020
4
0
тут проблема не в задержках. Сама по себе задержка в 20 микросекунд тьфу.
Проблема вот в чем:
for (i = 1250; i > 750; i--)
Циклы внутри loop зло. тут уже будет какая то ощутимая задержка и избавляться надо от циклов. Полупустой скетч крутиться 100-200 тысяч раз в секунду
Тогда как сделать что бы повторялся звук без циклов?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,302
Москва
loop и есть цикл
вот код с циклом
C++:
void loop() {
int a=digitalRead(10);
for (in i=0;i<255;i++) Serial.println(i);
}
а вот тоже самое без цикла
C++:
int i = 255;
void loop()
{
  if (i == 255)
  {
    a = digitalRead(10);
    i = 0;
  }
  else i++;
Serial.println(i);
}
 

Dlackjack

✩✩✩✩✩✩✩
17 Фев 2020
4
0
loop и есть цикл
вот код с циклом
C++:
void loop() {
int a=digitalRead(10);
for (in i=0;i<255;i++) Serial.println(i);
}
а вот тоже самое без цикла
C++:
int i = 255;
void loop()
{
  if (i == 255)
  {
    a = digitalRead(10);
    i = 0;
  }
  else i++;
Serial.println(i);
}
Ааааа, понял спасибо) А что сделать с delay посоветуешь?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,302
Москва
такие мелкие не сильно повлияют, но если есть желание , то можно запоминать время последней проверки или выполнения и следующее выполнять после , посмотри

было:
проверяем кнопку,
если кнопка нажата то убавить громкость

стало
проверяем кнопку
если кнопка нажата и с последнего убавления громкости прошло пол секунды то убавить громкость и запомнить время убавления

На ардуинский переведи сам )
 
  • Лойс +1
Реакции: Dlackjack

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,302
Москва
Еще пример. Датчик температуры ds18b20 в самом точном режиме обрабатывает запрос 0,8 секунды. Можно написать delay(1000) а можно сделать такую конструкцию
Запрос на получение температуры отправлен ?
ДА
если время ожидания ответа больше 1000, то читать температуру и делать с ней что то, сбросить флаг отправки запроса, выставить флаг получения температуры
НЕТ
отправить запрос, сбросить флаг получения температуры, выставить флаг запроса температуры, запомнить время.
 
  • Лойс +1
Реакции: Dlackjack

Arhat109

★★★★✩✩✩
9 Июн 2019
473
203
Вместо того, чтобы по коду скетча равномерно размазывать эти самые "если время вышло, то делай это", сильно рекомендую макрос

C:
// вырезано из arhat/ka.h:
//
// Укорачиваем место хранения времени и экономим память:
// переопределение интервалов до 65535 мсек
typedef uint16_t KaTime;

// ****************** 1. Автоматы, управляемые временем ***************** //

// переопределяем функцию получения времени: укорачивем возвращаемое значение до 2 байт
// максимально допустимый интервал между исполнениями 65.535 сек.
#define kaMillis()   ((KaTime)millis())

// Простейший конечный автомат сначала(!) исполняющий действие command и
// затем ожидающий его повторения через interval тиков таймера кратно 1 миллисекунде.
// В качестве команды может быть даже последовательность команд через ; или прямой вызов функции!
// интервалы можно задавать константно и переменными (выражениями).
// При первом вызове сразу исполняет действие и настраивает интервал до следующего исполнения
//
// @example прямая вставка исполняемого кода в фигурных скобках:
//
// everyMillis(1000,
// {
//   digitalWrite(13, 1-digitalRead(13));
//   analogWrite(10, analogRead(A0)>>4);
// });
//
// @example или прямой вызов функции: everyMillis(1000, blink(); );
//
#define everyMillis(interval, action)         \
do{                                           \
  static KaTime t = 0U;                       \
  if( kaMillis() - t > ((KaTime)(interval)) ) \
  {                                           \
    t = kaMillis();                           \
    { action }                                \
  }                                           \
}while(0)
Можно переопределить тип времени и обратно на unsigned long, если реально нужны интервалы больше 65сек. с копейками..
Код опороса датчика D18b20 (и мн. иное) с таким макросом упрощается "до безобразия", а читабельность кода повышается существенно, кмк.
:)

C:
everyMillis(800, {
// тут вызываем опрос датчика каждые 800мс. и обновляем температуру.
// можно сразу сделать и "вывод" результата. Тоже будет исполняться "периодически".
});
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,302
Москва
так то я написал свою библиотеку и класс, который использует функцию обратного вызова, а тут объяснил логику построения задачи. а уж во что это выльется зависит от автора )
 
  • Лойс +1
Реакции: Dlackjack

AlexAS

✩✩✩✩✩✩✩
23 Фев 2020
8
1
Еще пример. Датчик температуры ds18b20 в самом точном режиме обрабатывает запрос 0,8 секунды. Можно написать delay(1000) а можно сделать такую конструкцию
Запрос на получение температуры отправлен ?
ДА
если время ожидания ответа больше 1000, то читать температуру и делать с ней что то, сбросить флаг отправки запроса, выставить флаг получения температуры
НЕТ
отправить запрос, сбросить флаг получения температуры, выставить флаг запроса температуры, запомнить время.
здравствуйте, только начинаю осваивать ардуино, покажите пожалуйста код для ds18b20, без delay, c точность 9 бид, очень интересно,
самому не получается такое сделать (((
 

AlexAS

✩✩✩✩✩✩✩
23 Фев 2020
8
1
спасибо! т.е. мне нужно использовать код под спойлером программа ?
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,410
976
58
Марий-Эл
ну извините... не так выразился, нужна точность 0.5 градусов..
Не принимайте близко к сердцу. Некоторые датчики вверх ногами ставят. Потом ракеты падают. Но это ничего. Ракету новую можно построить.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,302
Москва
@AlexAS,
Там есть класс, его надо записать в каталог скетча.
И есть скетч с примером работы для 3 датчиков, каждый из них по разному работает. в классе есть возможность изменять точность, а так же есть работать именно со своим датчиком , по его индивидуальному номеру.
 

AlexAS

✩✩✩✩✩✩✩
23 Фев 2020
8
1
@AlexAS,
Там есть класс, его надо записать в каталог скетча.
И есть скетч с примером работы для 3 датчиков, каждый из них по разному работает. в классе есть возможность изменять точность, а так же есть работать именно со своим датчиком , по его индивидуальному номеру.
потихоньку вникаю )))

изменил скетч под свои условия, пожалуйста посмотрите, все ли правильно ?

мне нужен термометр с минимальной нагрузкой на ардуино, и с минимум по объему кода...
Скетч использует 4976 байт (16%) памяти устройства. можно как то еще уменьшить этот объем ?

C++:
#include <OneWire.h>
#include "term18b20.h"

OneWire  ds(2); //пин куда полдключены термодатчики
byte TerAdr[] = {0x28, 0x30, 0xC5, 0xB8, 0x0, 0x0, 0x0, 0x8E};

OneTerm MyTerm(TerAdr);

void PrintBalcon(int16_t T) // тестовая функция обратного вызова, печатает только измененное значение
{
  static float oldtm;
  float tm = (float)T / 16.0;
  if (oldtm != tm)
  {
    Serial.print("Температура: ");
    Serial.println(tm);
    oldtm = tm;
  }
}

void setup() {
  Serial.begin(57600);

  delay(205);

  MyTerm.SetPrecession(ds, Max_Prec);
  MyTerm.func_callback = PrintBalcon;
  MyTerm.SetMode(3);
  MyTerm.SetFollow(true);
}

void loop() {
  MyTerm.Tick(ds);
}
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,302
Москва
Пробуйте, адрес датчика поменяли ? Он нужен верный. Сейчас стоит максимальное разрешение 0,25 градуса . У меня вывод значения происходит только если значение изменилось, и получает данные , если не ошибаюсь постоянно, по готовности. т.е. будет обновляться раз в секунду, то возможно надо выбрать другой режим работы. Например 2-ой. По таймеру запускать, повторы выключить, как готово - считать и обработать. А по таймеру будет новый запрос.
 

AlexAS

✩✩✩✩✩✩✩
23 Фев 2020
8
1
адрес правильный, все работает как мне нужно, именно индикация только в момент изменения,
только не могу понять где изменить разрешение в градусах ?
меня устроит и 0.5 или 1.0 градус, и есть ли возможность уменьшить объем кода в памяти ?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,302
Москва
По поводу объема не уверен, все более менее универсальные библиотеки занимают больше места, чем отдельный код
Это описаные точности:
#define Max_Prec 3
#define High_Prec 2
#define Low_Prec 1
#define Min_Prec 0
поменять в этом
MyTerm.SetPrecession(ds, Max_Prec);
А так, убрать все текстовые переменные, они память жрут, можно посмотреть, что не нужно в классе и порезать, но это надо с умом делать.
 

AlexAS

✩✩✩✩✩✩✩
23 Фев 2020
8
1
По поводу объема не уверен, все более менее универсальные библиотеки занимают больше места, чем отдельный код
Это описаные точности:

поменять в этом


А так, убрать все текстовые переменные, они память жрут, можно посмотреть, что не нужно в классе и порезать, но это надо с умом делать.
спасибо! я понял, а не сможете облегчить класс ? или вообще от него отказаться ?
готов к материальной благодарности !