Попытка одолеть delay()
- Войдите на сайт для отправки комментариев
Всем привет! Столкнулся с типичной, как я понял проблемой для новичка - как обойтись без delay()?
Много есть в инете на эту тему, но в моём случае всё усложняет динамическая индикация, которой постоянно нужен ресурс МК. Вопрос показался интересным, ведь решив его, можно , по аналогии решать другие подобные. Итак, на преобразование температуры датчиком DS18B20 уходит 750мс, пусть 800мс с запасом.
Как сделать, чтобы индикация при этом не прекращалась?
Проблему-то я решил, всё работает, но сильно пришлось усложнить код.
От этого сомнения, и вопросы
//======== попытка избавится от delay =============
//==== с сохранением динамической индикации ))) ==
void loop() {
for (int i = 0; i < 8; i++) {
digitalWrite(RAZR[i], HIGH); // выбор разряда
PORTD = CIFRY[a[i]]; // вывод на индикатор цифры из таблицы CIFRY по адресу [a] в текущий разряд [i]
if (i == 2)
PORTD = PORTD | 0b10000000; // зажигаем точку
delayMicroseconds(500); // задержка для индикатора
digitalWrite(RAZR[i], LOW); // гасим разряд для динамической индикации
}
switch (key) { // key это ключ для выполнения выбранной части программы (одной из трёх)
case 0: // ключ в положении 0 (индикацию теряем только на время работы шины и расчёты)
if ((millis() - last_millis) >= 3200) { // частота измерений температуры 3200мс(задержка) + 800мс(конвертация) = 4сек
last_millis = millis(); // + 10мс обмен по шине и преобразование ( очень примерно )
w = 0; // при w = 0 передаём первые два байта команд датчику
start(); //
peredacha();
key = 1; // изменяем значение ключа
}
break;
case 1: // ключ в положении 1
if ((millis() - last2_millis) >= 800) { // ждём датчик
last2_millis = millis();
key = 2; // изменяем значение ключа
}
break;
case 2: // ключ в положении 2
w = 2; // при w = 2 (смещение цикла) передаём вторые два байта команд
start();
peredacha();
chtenie(); // читаем значение темп-ры
crc_8(); // проверяем контр.сумму
schet(); // преобразуем в значения десятичных разрядов
key = 0; // первоначальное значение ключа
break;
}
}
: это нормальное решение, или можно сделать лучше?
Или сойдёт для начала?
Прошу конструктивной критики и направления в нужную сторону...
Это первоначальный вариант, как видим, значительно проще
void loop() {
for (int i = 0; i < 8; i++) {
digitalWrite(RAZR[i], HIGH); // выбор разряда
PORTD = CIFRY[a[i]]; // вывод на индикатор цифры из таблицы CIFRY по адресу [a] в текущий разряд [i]
if (i == 2)
PORTD = PORTD | 0b10000000; // зажигаем точку
delayMicroseconds(500);
digitalWrite(RAZR[i], LOW); // гасим разряд для динамической индикации
}
if ((millis() - last_millis) >= 4000) { // частота измерений температуры 4сек
last_millis = millis();
start();
peredacha();
chtenie();
schet();
crc_8();
}
}
Задержка была в функции peredacha() просто delay(800)
Там же был и второй вызов функции start() после задержки
Логику работы разных вещей нужно разделять. У тебя должен быть класс-таймер. Класс для работы с дисплеем, к нему прикреплен экземпляр таймера. Класс для работы с датчиком, к нему тоже свой отдельный таймер.
А можно еще тот кусок глянуть, который датчик читает?
Логику работы разных вещей нужно разделять. У тебя должен быть класс-таймер. Класс для работы с дисплеем, к нему прикреплен экземпляр таймера. Класс для работы с датчиком, к нему тоже свой отдельный таймер.
Спасибо, пока не понятные для меня слова, но буду учиться.
А можно еще тот кусок глянуть, который датчик читает?
У меня отдельно передача и чтение. Всё пока сырое, не упакованное в циклы, но работает
//======= функция передачи команд датчику DS18B20 ================ //=========== попытка сохранить дин. индикацию на время измерения 800мс( запас 50мс ) void peredacha() { for (int i = w; i < (w + 2); i++) { // передача 4-х команд, 1 команда - 1 байт // с помощью выбора в loop() значения w = 0 или w = 2 // выбираем команды в массиве temp_tx if (temp_tx[i] & 0x01) { //0 // пока эта часть сырая, потом упакую в цикл peredacha_1bit(); // проверяем , начиная с младшего, биты в байте команды } else { // и устанавливаем соответствующее значение на шину peredacha_0bit(); } if (temp_tx[i] & 0b00000010) { //1 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b00000100) { //2 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b00001000) { //3 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b00010000) { //4 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b00100000) { //5 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b01000000) { //6 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b10000000 ) { //7 peredacha_1bit(); } else { peredacha_0bit(); } } }Это чтение из датчика
void chtenie() { for (int i = 0; i < 9; i++) { // читаем 9 байт из памяти датчика chtenie_byte(); temp_rx[i] = temp_0; } // temp_rx[3] = temp_rx[3] + 1; // раскоментировать для проверки crc low_byte = temp_rx[0]; high_byte = temp_rx[1];"закат Солнца вручную"
"закат Солнца вручную"
Точно! )))
Неблокирующий опрос ds18b20. Извиняюсь что без 100500 цифр "после запятой")) Лишнее сами уберете
#include <OneWire.h> const uint32_t msRepTime {10000}; // DS18b20 будем опрашивать каждые 10 секунд (по факту каждые 11) const uint8_t ds1Pin{7}; // DS18b20 будем подключать к пину D7 uint32_t msTemp {msRepTime}; // Объявляем счетчик для опроса DS18b20 и инициализируем его значением для моментального начала процедуры uint8_t ds1Qty {0}; // Количество датчиков DS18b20 на пине (не более 3-х). Если больше одного, значения будут усредняться int8_t ds1Temp {0}; // Собственно, значение температуры по Цельсию от DS18b20 uint8_t ds1DS[3][8]; // Адреса положу пока здесь. Если кому не лень, их нужно убрать из глобальной ОВ, как и количество датчиков void setup() { Serial.begin(115200); // Скорость должна соответствовать настройкам монитора порта searchSensors(); // Запускаем первоначальный поиск датчиков DS18b20 на пине } void loop() { if (millis() - msTemp > msRepTime) updateTemp(); // Опрашиваем температуру DS18b20 с частотой msRepTime } void updateTemp(){ // Основная процедура обновления температурных данных со всех датчиков static uint8_t stage {0}; // Первый этап. Отправка запросов на конвертацию if (stage == 0){ if (ds1Qty) requestSensor(ds1Pin); stage++; msTemp = millis() - msRepTime + 750; // 0.75 секунды требуется датчику для осуществления конвертации на максимальном разрешении return; } // Второй этап. Чтение показаний if (stage == 1){ if (ds1Qty) readSensor(&ds1Temp, ds1Pin, ds1DS, ds1Qty); msTemp = millis(); stage = 0; return; } } void readSensor(int8_t* t, uint8_t pin, void* buf, uint8_t qt){ // Чтение температуры с датчика ds18b20 OneWire ds(pin); uint8_t addr[8]; uint8_t data[9]; float temp[3]; uint8_t qty {0}; for (uint8_t c {0}; c < qt; c++){ for(uint8_t i {0}; i<8 ;i++) addr[i] = *((uint8_t*)buf+c*8+i); ds.reset(); ds.select(addr); ds.write(0xBE); for (uint8_t d {0}; d<9; d++) data[d] = ds.read(); int16_t raw = (data[1] << 8) | data[0]; raw = raw & ~1; temp[qty++] = raw / 16.0; } float tmp {0}; for (uint8_t i {0}; i<qty; i++) tmp+= temp[i]; *t = round(tmp/qty); Serial.print("Температура пин "); Serial.print(pin); Serial.print(" : "); Serial.println(*t); } void requestSensor(uint8_t pin){ // Отправка запроса на конвертацию ds18b20 OneWire ds(pin); ds.reset(); ds.skip(); ds.write(0x44,0); } void searchSensors(){ // Поиск датчиков на всех линиях ds1Qty = src(ds1DS, ds1Pin); } uint8_t src(void * adr, uint8_t pin){ // Вспомогательная функция для поиска на одной шине. Возвращает количество найденных датчиков if (pin == 0) return 0; OneWire ds(pin); uint8_t newAddr[8]{0}; uint8_t count {0}; ds.reset_search(); delay(5); while (ds.search(newAddr) && count <3){ if (ds.crc8(newAddr, 7) == newAddr[7]){ for (uint8_t i{0}; i<8; i++) *((uint8_t*)adr + count * 8 + i) = newAddr[i]; count++; } } return count; }Неблокирующий опрос ds18b20.
Спасибо, будем посмотреть!
Rumata, это читерство :) мало того что "точность теряется" - так вы еще и отправляете команды датчику целыми байтами, а не побитно, как уважаемый автор. А вдруг библиотека не каждый бит верно обрабатывает?? - это на самотек пускать нельзя!
Ведь если я не ошибаюсь, ТС не только для себя старается, он торит путь всем последующим новичкам. Ведь у него что не тема - так сразу замах на типовое решение вопроса, как было с цифрами после запятой. И тут тоже - он ведь не просто свою проблемку решает. он вопрос для общества разрабатывает:
он ведь не просто свою проблемку решает. он вопрос для общества разрабатывает:
Да нет же, пытаюсь сам пока разобраться, мне пока не до общества, сам мало-чего понимаю)))
Но процесс "разбирания" интересен, жаль маловато времени на хобби остаётся
//======= функция передачи команд датчику DS18B20 ================
//=========== попытка сохранить дин. индикацию на время измерения 800мс( запас 50мс ) void peredacha() { for (int i = w; i < (w + 2); i++) { // передача 4-х команд, 1 команда - 1 байт // с помощью выбора в loop() значения w = 0 или w = 2 // выбираем команды в массиве temp_tx if (temp_tx[i] & 0x01) { //0 // пока эта часть сырая, потом упакую в цикл peredacha_1bit(); // проверяем , начиная с младшего, биты в байте команды } else { // и устанавливаем соответствующее значение на шину peredacha_0bit(); } if (temp_tx[i] & 0b00000010) { //1 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b00000100) { //2 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b00001000) { //3 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b00010000) { //4 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b00100000) { //5 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b01000000) { //6 peredacha_1bit(); } else { peredacha_0bit(); } if (temp_tx[i] & 0b10000000 ) { //7 peredacha_1bit(); } else { peredacha_0bit(); } } }Только у меня ащющение, что ТС вырезан из цельного куска стоеросового дерева?
void peredacha() { for (int i = w; i < (w + 2); i++) { // передача 4-х команд, 1 команда - 1 байт // с помощью выбора в loop() значения w = 0 или w = 2 // выбираем команды в массиве temp_tx for(uint8_t mask=0x01; mask>0; mask<<=1) { if (temp_tx[i] & mask) peredacha_1bit(); else peredacha_0bit(); } } }Rumata , ещё раз спасибо, посмотрел, упростил, даже ещё проще , чем в примере получилось.
Вообще без флагов и ключей, только два счётчика. Зато работает!
void loop() { for (int i = 0; i < 8; i++) { digitalWrite(RAZR[i], HIGH); // выбор разряда PORTD = CIFRY[a[i]]; // вывод на индикатор цифры из таблицы CIFRY по адресу [a] в текущий разряд [i] if (i == 2) PORTD = PORTD | 0b10000000; // зажигаем точку delayMicroseconds(500); // задержка для индикатора digitalWrite(RAZR[i], LOW); // гасим разряд для динамической индикации } if ((millis() - last_millis) >= 3200){// частота измерений температуры 3200мс(задержка) + 800мс(конвертация) = 4сек last_millis = millis(); // + 10мс обмен по шине и преобразование ( очень примерно ) w = 0; // при w = 0 передаём первые два байта команд датчику start(); // сигнал RESET/PRESENT peredacha(); // if ((millis() - last2_millis) >= 800) { // ждём датчик 800мс last2_millis = millis(); w = 2; // при w = 2 (смещение цикла) передаём вторые два байта команд start(); peredacha(); chtenie(); // читаем значение темп-ры crc_8(); // проверяем контр.сумму schet(); // преобразуем в значения десятичных разрядов } }команды датчику целыми байтами, а не побитно, как уважаемый автор. А вдруг библиотека не каждый бит верно обрабатывает??
Я для целей надежности передачи после каждой команды использую макрос "КАК СЛЫШНО? ПРИЁМ!", просто вырезал из кода перед публикацией. Это мое секретное ноу-хау ))
упростил, даже ещё проще , чем в примере получилось.
Вообще без флагов и ключей, только два счётчика. Зато работает!
Как-то странно упростил... один счетчик в этом коде явно лишний - он вообще ничего не делает
Только у меня ащющение, что ТС вырезан из цельного куска стоеросового дерева?
Не!
Из цельного дуба вырезана вот эта лестница. Это ж скока, суки, древесины попортили!
Как-то странно упростил... один счетчик в этом коде явно лишний - он вообще ничего не делает
Спасибо за замечание! И правда, посмотрел ещё раз на свежую голову, и тоже это заметил.
Но больше всего смутило, что код работает! И долго бы я бился головой об стену, если бы не выяснил, что в
Proteus не требуется время для преобразования датчиком. Закоментировал delay() в старом варианте скетча, и всё равно, всё работает!
Так что приношу свои извинения. Вот последний вариант
void loop() { for (int i = 0; i < 8; i++) { digitalWrite(RAZR[i], HIGH); // выбор разряда PORTD = CIFRY[a[i]]; // вывод на индикатор цифры из таблицы CIFRY if (i == 2) // по адресу [a] в текущий разряд [i] PORTD = PORTD | 0b10000000; // зажигаем точку delayMicroseconds(500); // задержка для индикатора digitalWrite(RAZR[i], LOW); // гасим разряд для динамической индикации } if (((millis() - last_millis) >= 3200) && !key) { //пока не пройдёт 3200мс last_millis = millis(); // обнуляем таймер // выполняется только индикация // по прохождении 3200мс выполняем 1-ую часть работы с датчиком w = 0; // при w = 0 передаём первые два байта команд датчику start(); // сигнал RESET/PRESENT peredacha(); // передача команд key = true; // запрещаем выполнение 1-ой части } if (((millis() - last2_millis) >= 800) && key) { // ждём датчик 800мс last2_millis = millis(); // выполняем 2-ю часть работы с датчиком w = 2; // при w = 2 (смещение цикла) передаём вторые два байта команд start(); // сигнал RESET/PRESENT peredacha(); // передача 2-ой части команд chtenie(); // читаем значение темп-ры crc_8(); // проверяем контр.сумму schet(); // преобразуем в значения десятичных разрядов key = false; // сброс флага } }Осмелюсь предложить свой вариант избавления от делеев:
int i=0; int synchr=0; unsigned long time_r; void setup() { } void loop() { if(micros()-time_r>=500) {time_r=micros(); i++; if(i>7) { i=0; synchr++;// 4 ms } //------------> динамическая идикация с параметром i } switch(synchr) case 800// 800x4=3 200 ms //------------>запрос датчика break; case 1000//1000x4=4 000 ms synchr=0; // ------------>обработка ответа датчика break; }Осмелюсь предложить свой вариант избавления от делеев:
https://github.com/DetSimen/Arduino_TimerList
Спасибо за помощь! Разберусь, испытаю и обязательно отпишусь, когда позволит время.
Добрался пока только до первого варианта. Ещё раз спасибо Alexey_Rem. Думал о том, чтобы использовать задержки динамической индикации "для дела", но самому сделать пока показалось сложновато.
В общем всё работает отлично ,(проверяю в Proteus), но смущают данные датчика
похоже, команды повторяются 8раз подряд. Возможно в железе так работать не будет.Позже с этим разберусь.
Для сравнения выкладываю работу датчика в последнем варианте #17( это то, как я понял код , что дал Rumata)
По объёму, Ваш код ,вместе со всем скетчем, занимает 2314байт памяти устройств(7%) и 99байт(4%)динамической памяти
А предыдущий 2404(7%) и 100(4%) соответственно
int k = 0; int synchr=0; //объявил переменные unsigned long time_r = 0;//как глобальные //--------------------- void setup() {void loop() { if(micros()-time_r>=500) {time_r=micros(); digitalWrite(RAZR[k], LOW); // гасим разряд для динамической индикации k++; if(k>7) { k=0; synchr++;// 4 ms } //------------> динамическая идикация с параметром i digitalWrite(RAZR[k], HIGH); // выбор разряда PORTD = CIFRY[a[k]]; // вывод на индикатор цифры из таблицы CIFRY if (k == 2) // по адресу [a] в текущий разряд [i] PORTD = PORTD | 0b10000000; // зажигаем точку } switch (synchr) { case 800:// 800x4=3 200 ms //------------>запрос датчика start(); w = 0; peredacha(); break; case 1000://1000x4=4 000 ms synchr = 0; // ------------>обработка ответа датчика start(); w = 2; peredacha(); chtenie(); crc_8(); schet(); break; } }Так, что надо будет с этим ещё позаниматься, возможно я где-то накосячил...
P.S. Вариант от DetSimena пока только глянул, там мне много с чем разбираться ещё придётся,
не все сразу понятно. Позже отпишусь.
Рад помочь
В общем понял, почему датчик опрашивается по 8раз. Так и написано в коде. Переменная synchr изменится с 800 на 801 только после 8-ми проходов через case 800: и так же case 1000: Теперь дело за малым - найти решение)))
Добавил флаг, и всё за чих - пыхало!
void loop() { if(micros()-time_r>=500) {time_r=micros(); flg = false; digitalWrite(RAZR[k], LOW); // гасим разряд для динамической индикации k++; if(k>7) { k=0; synchr++;// 4 ms flg = true; } //------------> динамическая идикация с параметром i digitalWrite(RAZR[k], HIGH); // выбор разряда PORTD = CIFRY[a[k]]; // вывод на индикатор цифры из таблицы CIFRY if (k == 2) // по адресу [a] в текущий разряд [i] PORTD = PORTD | 0b10000000; // зажигаем точку } switch (synchr) { case 800:// 800x4=3 200 ms //------------>запрос датчика if(flg){ start(); w = 0; peredacha(); break; } case 1000://1000x4=4 000 ms if(flg){ synchr = 0; // ------------>обработка ответа датчика start(); w = 2; peredacha(); chtenie(); crc_8(); schet(); break; } } }Так что Proteus не проведёшь!)))
Получается, Alexey_Rem я тоже внёс свои 5копеек(может меньше) в Ваш код)))
Вместе и папу легче отметелить :)
Вот, наконец я разобрался, насколько смог конечно, самые азы, в "будильнике" от DetSimena.
Спасибо за помощь! Насколько я понял, это что-то вроде планировщика задач в windows. И это уже получается С++, язык высокого
уровня? Я так далеко ещё не заходил, читаю пока Кернигана и Ритчи, и то, в самом начале. Остальные знания беру в интернете, по ходу возникновения вопросов,там много есть про С.
Всё написано понятно, и даже я смог спокойно запустить. Индикация заработала от 4мс, ниже не получалось, но и этого в принципе достаточно. Код занял(в целом) 3336байт (10%) памяти устройств и 123байта(6%) дин. памяти, что очень неплохо, учитывая, что
можно запустить еще 3-4-ре датчика (а может и больше).
void setup() { pinMode(RELE, OUTPUT); digitalWrite(RELE, LOW); // настройка пина для управления внешним устройством (пока как возможность) high(); // настройка шины 1-wire for (int i = 0; i < 8; i++) { pinMode(DATASEG[i], OUTPUT); } for (int i = 0; i < 4; i++) { pinMode(RAZR[i], OUTPUT); // настройка выходов динамической индикации } IzmTimer = TimerList.Add(3200, tmrIzmTimer); // таймер 1-ой части // работы с датчиком KonvTimer = TimerList.Add(4000, tmrKonvTimer); //таймер 1-ой части IndTimer = TimerList.Add(4, tmrIndTimer); //таймер дин. индикации delay(300); // задержка для нормального запуска датчика } void tmrIzmTimer() { w = 0; start(); peredacha(); } void tmrKonvTimer() { w = 2; start(); peredacha(); chtenie(); crc_8(); schet(); } void tmrIndTimer() { for (int i = 0; i < 8; i++) { digitalWrite(RAZR[i], HIGH); // выбор разряда PORTD = CIFRY[a[i]]; // вывод на индикатор цифры из таблицы CIFRY if (i == 2) // по адресу [a] в текущий разряд [i] PORTD = PORTD | 0b10000000; // зажигаем точку delayMicroseconds(500); // задержка для индикатора digitalWrite(RAZR[i], LOW); // гасим разряд для динамической индикации } } void loop() { }Ещё раз спасибо DetSimen, и всем ответившим в теме.
Ну, нальёшь при случае.
Ну, нальёшь при случае.
Хорошо))))
Код занял(в целом) 3336байт (10%) памяти устройств и 123байта(6%) дин. памяти, что очень неплохо, учитывая, что можно запустить еще 3-4-ре датчика (а может и больше).
Вы думаете - если код опроса одного датчика занимает ХХХХ байт, то код опроса 4 датчиков займер 4 * ХХХХ байт? - большое заблуждение.
Не стоит рассуждать о размере кода в таком ключе
Вы думаете - если код опроса одного датчика занимает ХХХХ байт, то код опроса 4 датчиков займер 4 * ХХХХ байт? - большое заблуждение.
Не стоит рассуждать о размере кода в таком ключе
Вы правы, конечно же это не так прямолинейно, я и не говорил этого. Но всё же, думаю, что возможности контроля и размер кода взаимосвязаны. Как, например , сравнить Windows и CP/M
И снова делей:(. Даже два
И снова делей:(. Даже два
Точно! Но первый делей не опасен, т.к. работает один раз. А второго(в индикации) в этом варианте и не пробовал избегать, т.к. минимальный заявленный счётчик 1мс. Но теперь вижу, что всё равно индикация работает через 4мс.
Так что , спасибо за подсказку, попробую убрать и его.
Вот убрал, работает уже на 2мс. Это наверно потому, что убрал delay500мкс.
Добавил 1-ну глобальную переменную k.
void setup() { pinMode(RELE, OUTPUT); digitalWrite(RELE, LOW); // настройка пина для управления внешним устройством (пока как возможность) high(); // настройка шины 1-wire for (int i = 0; i < 8; i++) { pinMode(DATASEG[i], OUTPUT); } for (int i = 0; i < 4; i++) { pinMode(RAZR[i], OUTPUT); // настройка выходов динамической индикации } IzmTimer = TimerList.Add(3200, tmrIzmTimer); // таймер 1-ой части // работы с датчиком KonvTimer = TimerList.Add(4000, tmrKonvTimer); //таймер 1-ой части IndTimer = TimerList.Add(2, tmrIndTimer); //таймер дин. индикации delay(300); // задержка для нормального запуска датчика } void tmrIzmTimer() { w = 0; start(); peredacha(); } void tmrKonvTimer() { w = 2; start(); peredacha(); chtenie(); crc_8(); schet(); } void tmrIndTimer() { digitalWrite(RAZR[k], LOW); // гасим разряд для динамической индикации k++; if (k > 7) { k = 0; } digitalWrite(RAZR[k], HIGH); // выбор разряда PORTD = CIFRY[a[k]]; // вывод на индикатор цифры из таблицы CIFRY if (k == 2) // по адресу [a] в текущий разряд [i] PORTD = PORTD | 0b10000000; // зажигаем точку } void loop() { }Первый delay() как-бы и не вижу смысла убирать...
Может я туплю, но в сетапе у вас назначается 4 пина на разряды, а tmrIndTimer() считает их 8?
Может я туплю, но в сетапе у вас назначается 4 пина на разряды, а tmrIndTimer() считает их 8?
Точно, протупил здесь! Но всё работает, потому что в шапке всё правильно назначено. Просто сетап взял из старой версии)))
Спасибо за замечание
// программа для чтения данных из датчика ds18b20 с максимальным разрешением (12бит) и выводе на // 8-ми разрядный 7-сегментный индикатор с общим катодом // и инвертирующим буфером (транзистором) // Частота процессора 8 Мгц #include "TimerList.h" extern TTimerList TimerList; THandle IzmTimer; // таймер частоты измерений THandle KonvTimer; // таймер ожидания преобразования датчика THandle IndTimer; // const int DATASEG[] = {0, 1, 2, 3, 4, 5, 6, 7}; // пины для данных на 7 сегментов и точку const int RAZR[] = {A0, A1, A2, 13, 12, 11, 9, A3}; // пины для разряда индикатора const int WIRE = 8; // пин шины 1-wire const int RELE = 13; // управляющий выход на реле ( предусмотрен, но пока не задействован ))) const int CIFRY[] = { 0b00111111,//0В общем, для своей текущей задачи решил пока оставить вариант от Alexey_Rem, как самый " тонкий , звонкий и прозрачный".
(к тому же я там в соавторах))).
Т. к. датчиков добавлять больше не планировал. Другие варианты интересны на будущее.
Дальше по плану доделать шину и ещё думаю попробовать меню и eeprom сделать
Пока использовать сторонние библиотеки избегаю, они для меня пока как кот в мешке, смутно представляю ещё себе их работу.
Однако хочу понимать каждый цикл в своей программе.
Ещё раз всем спсб.
А где желогика.
просто другая логика!
Сравниваем показания таймера миллис с последним запомненным показанием онаго для СОБЫТИЯ/процесса (при этом можно добавлять дополнительные условия) и заданными в предыдущий раз , когда те звезды сошлись, интервалом и условиями. И вот тогда наступит новая реинкарнация типоПроцесса, в которой можно сделать всеЧто необходимо и задать условия( интервал, доп триггеры) для следующей реинкарнации.
и так для каждого процесса по-отдельности.
нужно только помнить, что это неНастоящщая мультизадачность, пока происходит каждая реинкарнация, остальные ждут ее завершения. И тайминги будуть съезжать. Я использую это для процессов типа померять температуру от 18b20 : В сетапе запустили преобразование, выставили переменную сравнения миллис на 3 минуты. Через примерно три минуты провалились в процесс, считали температуру, которая уже точно созрела, чтонить с этой температурой посчитали, выставили какиенить переменные для других проуессов, запустили новое преобразование, выставили новый интервал, через который надо опросить датчик(и) , и все, вернулись в лууп. А там другие, похожие процессы, прсыпаются периодически, смотрят свои переменные, что то делают и засыпают.
можно интервалы менять в зависимости от скорости изменения показаний датчиков, тоже весьма прикольно получается...
вот и сказочке конец, дочитал кто - молодец :)
ухты, публикация изменилась в кои то веки чтотто новое:)
можно интервалы менять в зависимости от скорости изменения показаний датчиков, тоже весьма прикольно получается...
Ну это уже следующая ступень для меня. Как говорится : бери ношу по себе, чтоб не падать при ходьбе)))
можно интервалы менять в зависимости от скорости изменения показаний датчиков, тоже весьма прикольно получается...
Ну это уже следующая ступень для меня. Как говорится : бери ношу по себе, чтоб не падать при ходьбе)))
это называется - развиваем свою логику (логическое мышление) и вникаем в причинно-следственные связи.
это называется - развиваем свою логику (логическое мышление) и вникаем в причинно-следственные связи.
У меня ещё куча делеев в шине. Вот где сложно победить. Скорее их лучше не трогать, пока думаю ещё об этом.
Я использую это для процессов типа померять температуру от 18b20 : В сетапе запустили преобразование, выставили переменную сравнения миллис на 3 минуты. Через примерно три минуты провалились в процесс, считали температуру, которая уже точно созрела, ...
За 3 минуты она и "протухнуть" может)))