Перейти к содержимому

Как сделать delay меньше 1 на ардуино

  • автор:

Arduino.ru

Останавливает выполнение программы на заданное в параметре количество миллисекунд (1000 миллисекунд в 1 секунде).

Синтаксис
delay(ms)
Параметры

ms: количество миллисекунд, на которое приостанавливается выполнение программы. (unsigned long)

Возвращаемое значение
Пример
int ledPin = 13; // светодиод подключен на порт 13 void setup() < pinMode(ledPin, OUTPUT); // устанавливается режим порта - выход >void loop() < digitalWrite(ledPin, HIGH); // включаем светодиод delay(1000); // ожидаем секунду digitalWrite(ledPin, LOW); // выключаем светодиод delay(1000); // ожидаем секунду >
Замечания по использования функции

Не рекомендуется использовать эту функцию для событий длиннее 10 миллисекунд, т.к. во время останова, не могут быть произведены манипуляции с портам, не могут быть считаны сенсоры или произведены математические операции. В качестве альтернативного подхода возможно контролирование времени выполнения тех или иных функций с помощью millis().

Большинство активности платы останавливается функцией delay(). Тем не менее работа прерываний не останавливается, продолжается запись последовательно (serial) передаваемых данных на RX порту, ШИМ сигнал (analogWrite) продолжает генерироваться на портах.

Arduino UNO урок 3 — Тайминг

Обратимся к первому уроку, где мы управляли LED. Между включением и выключением которого была секундная задержка. В используемой там программе (см. код ниже) был один очень большой недостаток. Для выдержки паузы между вкл/выкл LED в 1 сек. нами была использована функция delay(). В это время контроллер не может выполнять другие команды в главной функции loop()

/* Мигание LED * ------------ * * Включает и выключает светодиод (LED) подсоединенный * к выходу 13, с интервалом в 2 секунды * */ int ledPin = 13; // LED подсоединен к выводу 13 void setup() < pinMode(ledPin, OUTPUT); // устанавливаем вывод 13 как выход >void loop() < digitalWrite(ledPin, HIGH); // включаем LED delay(1000); // пауза 1 секунда digitalWrite(ledPin, LOW); // выключаем LED delay(1000); // пауза 1 секунда >

Первое, что мы сделаем, это внесем небольшие корректировки в функцию loop(). Чтобы сделать код более компактным и изящным, заменим 2 пары строчек на одну пару. Вместо установки значения в HIGH, а затем обратно в LOW, мы получим текущее значение ledPin и проинвертируем его. Т.е. если оно было HIGH, то станет LOW и наоборот.

void loop() < digitalWrite(ledPin, !digitalRead(ledPin)); // включаем/выключаем LED delay(1000); // задержка 1 сек. >

Отлично! Теперь мы усовершенствуем функцию delay(). Взамен, мы будем использовать функцию millis(). Данная функция возвращает количество миллисекунд, прошедшее с момента запуска текущей программы. Функция переполнится (вернется в нуль) приблизительно через 50 суток работы программы. Альтернативной функцией является micros(), которая возвращает количество микросекунд, прошедшее с момента запуска текущей программы. Функция переполнится (вернется в нуль) приблизительно через 70 минут работы программы. В нашем уроке мы будем использовать функцию millis():

/* Мигание LED Версия 2 * ------------------------ * Включает и выключает светодиод (LED) подсоединенный * к выходу 13, с интервалом в 2 секунды используя функцию millis() * */ int ledPin = 13; // LED подсоединен к выводу 13 unsigned long currentTime; unsigned long loopTime; void setup() < pinMode(ledPin, OUTPUT); // устанавливаем вывод 13 как выход currentTime = millis(); // считываем время, прошедшее с момента запуска программы loopTime = currentTime; >void loop() < currentTime = millis(); // считываем время, прошедшее с момента запуска программы if(currentTime >= (loopTime + 1000)) < // сравниваем текущий таймер с переменной loopTime + 1 секунда digitalWrite(ledPin, !digitalRead(ledPin)); // включаем/выключаем LED loopTime = currentTime; // в loopTime записываем новое значение >// Здесь могут быть другие команды >

В данном примере мы ввели две дополнительные переменные currentTime и loopTime. В функции setup() обе переменные имеют одно и тоже значение. В функции loop(), переменная currentTime каждый раз обновляется в цикле. Когда currentTime больше чем loopTime на 1 секунду (loopTime + 1000), то LED меняет свое состояние, а переменной loopTime присваивается текущее значение currentTime. Обратите внимание, что в данном примере мы не использовали функцию delay() и процессор может выполнять другие операции. Оригинал статьи на английском языке (перевод Колтыков А.В. для сайта cxem.net) Оригинал статьи

Теги:

Колтыков А.В. Опубликована: 2011 г. 0 1

Вознаградить Я собрал 0 0

Оценить статью

  • Техническая грамотность

Замена delay() для неблокирующих задержек в Arduino IDE

Первое, с чем сталкивается осваивающий Arduino новичок, это неприятное свойство функции delay() — блокирование выполнения программы. Множество примеров в интернете используют эту функцию, но практическое применение как-то намекает, что лучше без неё обойтись.

Как и положено начинающему, я изобрёл велосипед сделал свою реализацию неблокирующей задержки. Задача стояла так:

  • Обеспечить псевдомногозадачность, чтобы разные события происходили в своё время, со своими интервалами и не блокировали друг-друга.
  • Было удобно этим пользоваться.
  • Можно было оформить как библиотеку и легко включать в другие проекты без копипастов.

В результате получилось вот такое.

#include SmartDelay foo(1000000UL); // в микросекундах void loop () < if (foo.Now()) < // Код здесь выполняется каждый интервал в микросекундах, указанный в конструкторе выше. >//Прочий код > 

Метод Now() возвращает true, если интервал прошёл. В этом случае отсчёт начинается снова на тот же интервал. То есть, Now() каждый раз «перезаряжается» автоматически.

Классическое мигание светодиодом можно сразу усложнить до мигания двумя. Например, лампочки подключены к ножкам 12 и 11, должны мигать с интервалом в 1с и 777мс соответственно.

#include SmartDelay led12(1000000UL); SmartDelay led11(777000UL); setup () < pinMode(12,OUTPUT); pinMode(11,OUTPUT); >byte led12state=0; byte led11state=0; void loop () < if (led12.Now()) < digitalWrite(12,led12state); led12state=!led12state; >if (led11.Now()) < digitalWrite(11,led11state); led11state=!led11state; >> 

В цикле можно выполнять ещё что-то, мигание светодиодов не будет блокировать выполнение этого кода.

Понятно, что это не полная замена delay(), который останавливает поток на заданное время, надо писать программу всегда как МКА (механизм конечных автоматов). То есть, хранить состояние и в зависимости от него переходить к нужному месту кода.

. action1(); delay(1000); action2(); delay(500); action3(); . 
byte state=0; SmartDelay d(); . switch (state) < case 0: action1(); d.Set(1000000UL); state=1; break; case 1: if (d.Now()) < action2(); d.Set(500000UL); state=2; >break; case 2: if (d.Now()) < action3(); d.Stop(); state=0; >break; > . 

Метод Set(интервал) устанавливает новый интервал и возвращает старый. Просто посмотреть на интервал можно методом Get();

Stop() останавливает обработку и Now() всегда возвращает false.

Start() возобновляет работу и Now() начинает работать как обычно.

Если надо притормозить подсчёт времени, но не останавливать совсем, то есть метод Wait(). Например, если мигает светодиод 12, а при нажатии кнопки не мигает, достаточно добавить вот такой код в loop() в примере с двумя диодами выше:

. if (digitalRead(9)) led12.Wait(); . 

Так, при высоком уровне сигнала на 9 ноге диод на 12 мигать не будет и продолжит, когда там появится 0.

Когда по такому «таймеру» отрисовывается экран, например, и параллельно обрабатываются кнопки, то бывает нужно перерисовать экран или часть сразу после нажатия на кнопку, а не ждать окончания интервала. Для этого служит метод Reset(), после которого следующий вызов Now() вернёт true. Например:

SmartDelay display(1000000UL); void loop() < if (btClick()) display.Reset(); // ткнул в кнопку, надо отрисовать экранчик. if (display.Now()) screenRedraw(); // отрисовка экранчика. >

Из багов я вижу только, что не учитывается переполнение счётчика микросекунд, а в остальном да, надо почистить код. Мне не нравится, как сделан Reset(), пока думаю.

Объектный подход мне понравился, позволяет спрятать весь код в библиотеку, в которую можно потом уже никогда не заглядывать. Теперь эта маленькая библиотечка живёт во всем моих проектах 🙂

Arduino.ru

Всем привет! Знаю что не кашерно задавать такие вопросы, когда есть интернет и все гуглится, поэтому пишу в песочнице.

Нет ничего беспощаднее и ужаснее delay в коде, это я уже понял)))

Вроде переечитал все, тыкался и так и так, получается ерунда, удалил все нафиг. Помогите кто советом, кто кодом избавиться от delay в двух частях кода.

// monitor switch //=============================================================================== if (key == 0) < digitalWrite(49,LOW); //отключаем YELLOW ARDUINO //delay(50); digitalWrite(47,LOW); //переключаем ORANGE SYNC //delay(50); digitalWrite(51,LOW); //включаем GREEN HONDA >if (key == 1) < digitalWrite(51,HIGH); //отключаем GREEN HONDA //delay(50); digitalWrite(47,HIGH); //переключаем ORANGE SYNC //delay(50); digitalWrite(49,HIGH); //включаем YELLOW ARDUINO >//===============================================================================

А вот вторая часть кода в которой даже я спусть день трудно разбираюсь

// Revers, Button //=============================================================================== if (digitalRead(53) == HIGH) < revers = 1; //Revers включен delay(700); key = 0; >else < revers = 0; //Revers отключен if (key==0) < key = beginkey; value = analogRead(3); if ( value < 1000) < button = 1; if(key == 0) < key = 1; beginkey = 1; >else < key = 0; beginkey = 0; >> > else < value = analogRead(3); if ( value < 1000) < button = 1; if(key == 0) < key = 1; beginkey = 1; >else < key = 0; beginkey = 0; >> > > //===============================================================================

заранее спасибо всем)

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 15:09
Зарегистрирован: 30.04.2012

вы можете словами описать чего вы хотите добиться (в целом) и как по вашему мнению это описывает код ?

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 15:14
Зарегистрирован: 23.03.2015
mixail844 пишет:

вы можете словами описать чего вы хотите добиться (в целом) и как по вашему мнению это описывает код ?

Ну чего я хочу добиться? избавиться от delay в коде в местах где он есть. пауза должна произайти но без delay.

Я могу выложить весь проэкт целиком и объяснять на три листа что к чему и как должно работать, но есть ли в этом смысл? Если есть я напишу, мне не сложно.

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 15:29

ЕвгенийП аватар

Зарегистрирован: 25.05.2015
damq1n пишет:

Нет ничего беспощаднее и ужаснее delay в коде

Что ж в нём такого ужасного и беспощадного?

damq1n пишет:

Ну чего я хочу добиться? избавиться от delay в коде в местах где он есть.

Т.е. delay в общем-то не мешает, а цель не достичь каких-то результатов, а просто избаиться от delay? Правильно? А для чего от него избавляться? Ради упражнения? Ну, тогда сами упражняйтесь, мы ты Вам зачем?

Или есть какая-то другая цель, которую Вы от нас скрываете?

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 15:33
Зарегистрирован: 23.03.2015
ЕвгенийП пишет:
damq1n пишет:

Нет ничего беспощаднее и ужаснее delay в коде

Что ж в нём такого ужасного и беспощадного?

damq1n пишет:

Ну чего я хочу добиться? избавиться от delay в коде в местах где он есть.

Т.е. delay в общем-то не мешает, а цель не достичь каких-то результатов, а просто избаиться от delay? Правильно? А для чего от него избавляться? Ради упражнения? Ну, тогда сами упражняйтесь, мы ты Вам зачем?

Или есть какая-то другая цель, которую Вы от нас скрываете?

Нет конечно не в упражнении:)) Цель избавления в том что, пока происходят эти delay замедляется работа программы. Остальной код стоит. А мне нужен мгновенный отклик программы на изменения в датчиках, что бы мгновенно их отобразить на дисплее.

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 15:41

wdrakula аватар

Зарегистрирован: 15.03.2016

Некомментированную протыню не нужно выкладывать и кусок кода, без объяснения что он должен делать и чего из задуманного не делает, тоже не надо.

«Избавиться от делей» — фраза бессодержательна вообще.

Потому, как делей не заменяется ни на что. Код без делей совершенно по другому проектируется. Посмотри на «блинк без делей». Тебе нужно понимать, что при проектировании коде без делей, твой МК совершает действия в РАЗНЫЕ входы в функцию loop(). Соответственно завершив одну активность ты должен запонить время и проверять его при каждом входе в loop(), как только прошло нужное — выполнить следующую активность и снова запомнить время. Если активностей много, то проще запомнить номер той, которую планируешь выполнить и время начала отсчета.

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 16:16

ЕвгенийП аватар

Зарегистрирован: 25.05.2015

Ну, тогда приведите маленький, но полный (чтобы запустить можно было) пример в котором была бы понятна проблема. А то из того, что Вы привели никак не следует наличие какого-то другого кода, и никак непонятно что там за код такой. А от этого во-многом зависит то, как следует поступить. Например, если там всё на прерываниях, то и плевать на делэй с высокого уровня.

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 16:10

wdrakula аватар

Зарегистрирован: 15.03.2016

Вот общий пример «Как избавиться от трупа delay()» :

//код с delay void loop() < < activity1; >delay(dly1); < activity2; >delay(dly2); < activity3; >delay(dly3); < activity4; >delay(dly4); < activity5; >delay(dly5); > =============================== //Для "избавления от delay" можно переделать в такое: void loop() < static byte activityCode = 1; //начальная активность static uint32_t currentDelay = 0; //начальная задержка static uint32_t oldMillis = millis(); uint32_t currentMillis = millis(); if (currentMillis - currentDelay >oldMillis) < switch (activityCode) < case 1: activity1; oldMillis = currentMillis; currentDelay = dly1; //следующая задержка activityCode = 2; //следующая активность break; case 2: activity2; oldMillis = currentMillis; currentDelay = dly2; activityCode = 3; break; case 3: activity3; oldMillis = currentMillis; currentDelay = dly3; activityCode = 4; break; case 4: activity4; oldMillis = currentMillis; currentDelay = dly4; activityCode = 5; break; case 5: activity5; oldMillis = currentMillis; currentDelay = dly5; activityCode = 1; break; >> >
  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 17:04

mykaida аватар

Зарегистрирован: 12.07.2018
Есть такой вариант — «костыли», конечно, но при определенных условиях (скажу позже) вполне рабочии.

Данная программа управляет 3 светодиодами без delay первый включается раз в секунду и горит секунду, второй раз в две секунды и тоже горит секунду, третий работает как первый, но при нажатой кнопке.

#define led1 3 #define led2 4 #define led3 5 #define button 2 const int TimeStrobe=1000; byte led1St; byte led2St; byte led3St; unsigned long lastMillis; void setup() < // put your setup code here, to run once: pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(button, INPUT); digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(button, HIGH); led1St=0; led2St=0; led3St=0; >void loop() < // put your main code here, to run repeatedly: if ((millis()-lastMillis)>= TimeStrobe) < //стробируем раз в секунду lastMillis=millis(); led1St++; led2St++; led3St++; >if (led1St==0)digitalWrite(led1, HIGH); if (led1St==1)digitalWrite(led1, LOW); if (led1St==1+1)led1St=0; if (led2St==0)digitalWrite(led2, HIGH); if (led2St==2)digitalWrite(led2, LOW); if (led1St==2+1)led2St=0; if(digitalRead(button)) < if (led3St==0)digitalWrite(led3, HIGH); if (led3St==1)digitalWrite(led3, LOW); if (led3St==1+1)led3St=0; >else < led3St=0; digitalWrite(led3, LOW); >>

Метод вполне рабочий при условии, что в программе нет обращений к тормозящим подпрограммам (как любые обращения по oneWare), да и вообще ко всему, что содержит delay.

Надо вовремя нулить счетчики.
Ну и процессы не должны быть микросекундными.

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 17:53
Зарегистрирован: 23.03.2015
wdrakula пишет:

Некомментированную протыню не нужно выкладывать и кусок кода, без объяснения что он должен делать и чего из задуманного не делает, тоже не надо.

Я не програмист и не имею опыта общения с програмистами, наверное просто не умею задавать корректно вопросы по этой теме.

Сейчас ниже выложу программу целиком

  • Войдите на сайт для отправки комментариев

Ср, 23/01/2019 — 18:10
Зарегистрирован: 23.03.2015

Одна из причин почему не стал выкладывать код целиком это то что, боюсь за такой код вы меня просто из интренета удалите)) Понимаю что код не грамотен, но пишу как получается.

Установлено в авто, подключено к штатному монитору.

// monitor switch //=============================================================================== if (key == 0) < digitalWrite(49,LOW); //отключаем YELLOW ARDUINO //delay(50); digitalWrite(47,LOW); //переключаем ORANGE SYNC //delay(50); digitalWrite(51,LOW); //включаем GREEN HONDA >if (key == 1) < digitalWrite(51,HIGH); //отключаем GREEN HONDA //delay(50); digitalWrite(47,HIGH); //переключаем ORANGE SYNC //delay(50); digitalWrite(49,HIGH); //включаем YELLOW ARDUINO >//===============================================================================

Контроллер переключает источник видео сигнала с помощью реле. Чтобы перключать без помех нужно сначало отключить сигнал, затем переключить сигнал синхронизации и только потом подключить другой сигнал.

Между этими действиями должна быть задержка в 50 милисекунд, обусловленна эта необходимость физической работой реле.

// Revers, Button //=============================================================================== if (digitalRead(53) == HIGH) < revers = 1; //Revers включен delay(700); key = 0; >else < revers = 0; //Revers отключен if (key==0) < key = beginkey; value = analogRead(3); if ( value < 1000) < button = 1; if(key == 0) < key = 1; beginkey = 1; >else < key = 0; beginkey = 0; >> > else < value = analogRead(3); if ( value < 1000) < button = 1; if(key == 0) < key = 1; beginkey = 1; >else < key = 0; beginkey = 0; >> > > //===============================================================================

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

Все так и работает, но мне просто нужно сменить источник сигнала не мгновенно, а пока запустится камера в авто, примерно 700 милисекунд.

Ниже код целиком и схема.

//=============================================================================== // Подключаем библиотеки //=============================================================================== #include //=============================================================================== // Константы //=============================================================================== // Связанные с термистором: /* Здесь у нас несколько констант, которые упрощают редактирование кода. Пройдемся по ним. Чтение из АЦП может дать одно значение при одной выборке, а затем немного отличающееся значение при следующей выборке. Чтобы избежать влияния шумов, мы можем считывать значения с вывода АЦП несколько раз, а затем усреднять значения, чтобы получить более постоянное значение. Эта константа используется в функции readThermistor. */ const int SAMPLE_NUMBER = 10; /* Чтобы использовать бета уравнение, мы должны знать номинал второго резистора в нашем делителе. Если вы используете резистор с большим допуском, например, 5% или даже 1%, измерьте его и поместите результат в омах сюда. */ const float SERIAL_R = 10300.0; // Это помогает вычислять сопротивление термистора (подробности смотрите в статье). const float MAX_ADC = 4095.0; /* Эта константа зависит от термистора и должна быть в техническом описании, или смотрите статью, как рассчитать ее, используя бета-уравнение. */ const float B = 3448.0; /* Необходима для уравнения преобразования в качестве "типовой" комнатной температуры. */ const float NOMINAL_T = 40; // комнатная температура в Кельвинах /* Термисторы обладают типовым сопротивлением при комнатной температуре, укажем его здесь. Опять же, необходимо для уравнения преобразования. */ const float THERMISTOR_R = 5760.0; //=============================================================================== // Переменные //=============================================================================== // Здесь мы будем хранить текущую температуру float currentTemperature = 0; float currentPressure = 0; float currentRTemperature = 0; float currentVPressure = 0; //=============================================================================== // Объявления выводов //=============================================================================== // Входы: int thermistorPin = 1; // Вход АЦП, выход делителя напряжения int pressurePin = 2; // Вход АЦП, выход делителя напряжения //определяем переменные для хранения измеряего значения int x, y, a, b, c, d; int button, keyv, value; int button_state, button_mem; int key = 1; int beginkey = 1; int revers = 0; //OBD int tmpVal = 0; int rpmVal = 0; int speedVal = 0; char rxData[20]; char rxIndex=0; char incomingbyte = '-'; //=============================================================================== // Инициализация //=============================================================================== void setup() < // Установить скорость порта для отправки сообщений SerialUSB.begin(9600); Serial3.begin(38400); analogReadResolution(12); VGA.setMonitorFreqRange(16100, 29700, 58, 62); //VGA.setMonitorFreqRange(16500, 30000, 60, 64); рабочий вариант 304 240 VGA.begin(320,238,VGA_COLOUR); delay(100); pinMode(51, OUTPUT); // GREEN HONDA sets the digital pin 51 as output pinMode(49, OUTPUT); // YELLOW ARDUINO sets the digital pin 49 as output pinMode(47, OUTPUT); // ORANGE SYNC sets the digital pin 47 as output pinMode(53, INPUT); // ------ ATPR sets the digital pin 53 as output Serial3.println("ATSP7"); //Serial3.println("ATZ"); delay(100); Serial3.flush(); >//=============================================================================== // Основной цикл //=============================================================================== void loop() < Serial3.flush(); // text colour VGA.setInk(255); //=============================================================================== // Revers, Button //=============================================================================== if (digitalRead(53) == HIGH) < revers = 1; //Revers включен delay(700); key = 0; >else < revers = 0; //Revers отключен if (key==0) < key = beginkey; value = analogRead(3); if ( value < 1000) < button = 1; if(key == 0) < key = 1; beginkey = 1; >else < key = 0; beginkey = 0; >> > else < value = analogRead(3); if ( value < 1000) < button = 1; if(key == 0) < key = 1; beginkey = 1; >else < key = 0; beginkey = 0; >> > > //=============================================================================== // monitor switch //=============================================================================== if (key == 0) < digitalWrite(49,LOW); //отключаем YELLOW ARDUINO //delay(50); digitalWrite(47,LOW); //переключаем ORANGE SYNC //delay(50); digitalWrite(51,LOW); //включаем GREEN HONDA >if (key == 1) < digitalWrite(51,HIGH); //отключаем GREEN HONDA //delay(50); digitalWrite(47,HIGH); //переключаем ORANGE SYNC //delay(50); digitalWrite(49,HIGH); //включаем YELLOW ARDUINO >//=============================================================================== // //=============================================================================== currentTemperature = readThermistor(); currentPressure = readPressure(); //Serial.print(", t="); //Serial.println(currentTemperature,0); //Serial.print(", p="); //Serial.println(currentPressure,1); //VGA.drawLine(int x0, int y0, int x1, int y1, int col); VGA.drawLine(0, 2, 312, 2, 90); //горизонтальная верхняя VGA.drawLine(0, 234, 312, 234, 90); // горизонтальная нижняя VGA.drawLine(0, 2, 0, 234, 90); //вертикальная левая VGA.drawLine(312, 0, 312, 234, 90); //вертикальная правая // text colour VGA.setInk(255); // VGA.moveCursor(int column, int line); VGA.moveCursor(6, 2); VGA.print("OIL"); VGA.moveCursor(2, 4); VGA.print("Press"); VGA.moveCursor(3, 6); VGA.print(" "); VGA.moveCursor(3, 6); VGA.print(currentPressure,1); VGA.moveCursor(9, 4); VGA.print("Temp"); VGA.moveCursor(10, 6); VGA.print(" "); VGA.moveCursor(10, 6); VGA.print(currentTemperature,0); //=============================================================================== // OIL Pressure //=============================================================================== VGA.drawLine(10, 200, 20, 200, 255); //0 VGA.drawLine(19, 195, 20, 195, 255); //0.25 VGA.drawLine(18, 190, 20, 190, 255); //0.5 VGA.drawLine(19, 185, 20, 185, 255); //0.75 VGA.drawLine(15, 180, 20, 180, 255); //1 VGA.drawLine(15, 162, 20, 162, 255); //2 VGA.drawLine(15, 143, 20, 143, 255); //3 VGA.drawLine(15, 124, 20, 124, 255); //4 VGA.drawLine(10, 104, 20, 104, 255); //5 VGA.drawLine(15, 86, 20, 86, 255); //6 VGA.drawLine(10, 65, 20, 65, 255); //7 VGA.drawLine(25, 85, 25, 200, 90); VGA.drawLine(45, 85, 45, 200, 90); VGA.drawLine(25, 65, 25, 85, 224); VGA.drawLine(45, 65, 45, 85, 224); VGA.drawLine(25, 64, 45, 64, 224); if (currentPressure>= 6) < VGA.fillRect(25, 86, 45, 200, 90); //green c = 200 - (currentPressure*19); if(c<=65) < VGA.fillRect(25, 65, 45, 85, 224); //red >else < VGA.fillRect(25, c, 45, 85, 224); //red VGA.fillRect(26, 65, 44, c, 0); // black >> else < c = 200 - (currentPressure*19); VGA.fillRect(25, c, 45, 200, 90); //green d = 199 - (currentPressure*19); VGA.fillRect(26, 65, 44, d, 0); // black >//=============================================================================== // OIL Temp //=============================================================================== VGA.drawLine(62, 200, 72, 200, 255); //0 VGA.drawLine(67, 188, 72, 188, 255); //10 VGA.drawLine(67, 177, 72, 177, 255); //20 VGA.drawLine(67, 166, 72, 166, 255); //30 VGA.drawLine(67, 155, 72, 155, 255); //40 VGA.drawLine(62, 144, 72, 144, 255); //50 VGA.drawLine(67, 133, 72, 133, 255); //60 VGA.drawLine(67, 122, 72, 122, 255); //70 VGA.drawLine(67, 111, 72, 111, 255); //80 VGA.drawLine(67, 100, 72, 100, 255); //90 VGA.drawLine(67, 90, 72, 90, 255); //100 VGA.drawLine(62, 84, 72, 84, 255); //105 VGA.drawLine(67, 78, 72, 78, 255); //110 VGA.drawLine(67, 72, 72, 72, 255); //115 VGA.drawLine(62, 65, 72, 65, 255); //120 VGA.drawLine(77, 85, 77, 200, 90); VGA.drawLine(97, 85, 97, 200, 90); VGA.drawLine(77, 65, 77, 85, 224); VGA.drawLine(97, 65, 97, 85, 224); VGA.drawLine(77, 64, 97, 64, 224); if (currentTemperature>= 105) < VGA.fillRect(77, 86, 97, 200, 90); //green c = 200 - (currentTemperature*1.1); VGA.moveCursor(20, 20); VGA.print(c,1); VGA.print(" "); if(c<=65) < VGA.fillRect(77, 65, 97, 85, 224); //red >else < VGA.fillRect(77, c, 97, 85, 224); //red VGA.fillRect(78, 65, 96, c, 0); // black >> else < c = 200 - (currentTemperature*1.1); if(c>=200) < VGA.drawLine(77, 200, 97, 200, 90); >else < VGA.fillRect(77, c, 97, 200, 90); //green d = 199 - (currentTemperature*1.1); VGA.fillRect(78, 65, 96, d, 0); // black >> //=============================================================================== VGA.moveCursor(20, 2); VGA.print("Wather"); VGA.moveCursor(21, 4); VGA.print("Temp"); VGA.moveCursor(22, 6); VGA.print(" "); VGA.moveCursor(22, 6); VGA.print(tmpVal); VGA.waitSync(); VGA.moveCursor(30, 2); VGA.print("Engine"); VGA.moveCursor(31, 4); VGA.print("RPM"); VGA.moveCursor(31, 6); VGA.print(" "); VGA.moveCursor(31, 6); VGA.print(rpmVal); VGA.waitSync(); VGA.moveCursor(31, 8); VGA.print("Speed"); VGA.moveCursor(31, 9); VGA.print(" "); VGA.moveCursor(31, 9); VGA.print(speedVal); VGA.waitSync(); //=============================================================================== // OBD Temp //=============================================================================== Serial3.flush(); if(Serial3.available() > 0) < incomingbyte =Serial3.read(); >if (incomingbyte== '>') < Serial3.println("0105"); getResponse(); getResponse(); tmpVal = (strtol(&rxData[6],0,16)-40); >//=============================================================================== VGA.waitSync(); > //=============================================================================== // Функции //=============================================================================== ///////////////////////////// ////// readThermistor /////// ///////////////////////////// /* Эта функция считывает значения с аналогового вывода, как показано ниже. Преобразует входное напряжение в цифровое представление с помощью аналого-цифрового преобразования. Однако, это выполняется несколько раз, чтобы мы могли усреднить значение, чтобы избежать ошибок измерения. Это усредненное значение затем используется для расчета сопротивления термистора. После этого сопротивление используется для расчета температуры термистора. Наконец, температура преобразуется в градусы Цельсия. */ float readThermistor() < // переменные float steinhart; // Хранит температуру в градусах Цельсия float adcAverage = 0; // Хранит среднее значение напряжения int adcSamples[SAMPLE_NUMBER]; // Массив для хранения отдельных результатов // измерений напряжения /* Рассчитать среднее сопротивление термистора: Как упоминалось выше, мы будем считывать значения АЦП несколько раз, чтобы получить массив выборок. Небольшая задержка используется для корректной работы функции analogRead. */ for (int i = 0; i < SAMPLE_NUMBER; i++) < adcSamples[i] = analogRead(thermistorPin); // прочитать значение на выводе и сохранить delay(3); // ждем 10 миллисекунд >/* Затем мы просто усредняем все эти выборки для "сглаживания" измерений. */ for (int i = 0; i < SAMPLE_NUMBER; i++) < adcAverage += adcSamples[i]; // складываем все выборки . . . >adcAverage /= SAMPLE_NUMBER; // . . . усредняем их с помощью деления /* Здесь мы рассчитываем сопротивление термистора, используя уравнение, описываемое в статье. */ int t = adcAverage; float tr = MAX_ADC / t - 1; tr = SERIAL_R / tr; /* Здесь используется бета-уравнение, но оно отличается от того, что описывалось в статье. Не беспокойтесь! Оно было перестроено, чтобы получить более "красивую" формулу. Попробуйте сами упростить уравнение, чтобы поупражняться в алгебре. Или просто используйте показанное здесь или то, что приведено в статье. В любом случае всё будет работать! */ steinhart = tr / THERMISTOR_R; // (R/Ro) steinhart = log(steinhart); // ln(R/Ro) steinhart /= B; // 1/B * ln(R/Ro) steinhart += 1.0 / (NOMINAL_T + 273.15); // + (1/To) steinhart = 1.0 / steinhart; // Invert /* Я буду использовать градусы Цельсия для отображения температуры. Я сделал это, чтобы увидеть типовую комнатную температуру, которая составляет 25 градусов Цельсия. */ steinhart -= 273.15; return steinhart; // вернуть температуру в градусах Цельсия > ///////////////////////////// ////// readPressure /////// ///////////////////////////// /* Эта функция считывает значения с аналогового вывода, как показано ниже. Преобразует входное напряжение в цифровое представление с помощью аналого-цифрового преобразования. Однако, это выполняется несколько раз, чтобы мы могли усреднить значение, чтобы избежать ошибок измерения. Это усредненное значение затем используется для расчета сопротивления термистора. После этого сопротивление используется для расчета температуры термистора. Наконец, температура преобразуется в градусы Цельсия. */ float readPressure() < // переменные float pressure; // Хранит температуру в градусах Цельсия float adcAverage = 0; // Хранит среднее значение напряжения int adcSamples[SAMPLE_NUMBER]; // Массив для хранения отдельных результатов // измерений напряжения /* Рассчитать среднее сопротивление термистора: Как упоминалось выше, мы будем считывать значения АЦП несколько раз, чтобы получить массив выборок. Небольшая задержка используется для корректной работы функции analogRead. */ for (int i = 0; i < SAMPLE_NUMBER; i++) < adcSamples[i] = analogRead(pressurePin); // прочитать значение на выводе и сохранить delay(3); // ждем 10 миллисекунд >/* Затем мы просто усредняем все эти выборки для "сглаживания" измерений. */ for (int i = 0; i < SAMPLE_NUMBER; i++) < adcAverage += adcSamples[i]; // складываем все выборки . . . >adcAverage /= SAMPLE_NUMBER; // . . . усредняем их с помощью деления /* Здесь мы рассчитываем давление, используя уравнение. */ pressure = adcAverage/4095.0*3300 ; pressure = (0.00386 * pressure)- 1.418; if (pressure return pressure; > ///////////////////////////// ////// readOBD /////// ///////////////////////////// void getResponse(void) < char inChar=0; while(inChar != '\r')< if(Serial3.available() >0) < if(Serial3.peek() == '\r')< inChar=Serial3.read(); rxData[rxIndex]='\0'; rxIndex=0; >else < inChar = Serial3.read(); rxData[rxIndex++]=inChar; //delay(100); //SerialUSB.print(inChar); //VGA.moveCursor(21, 19); //VGA.print(inChar); //incomingbyte ='-'; >> > >

  • Войдите на сайт для отправки комментариев

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *