Счетчик на светодиод
- Войдите на сайт для отправки комментариев
Чт, 11/11/2021 - 11:27
Всем здравия! Есть поступающий периодический сигнал 5В на ногу ардуино-нано нужно включать светодиод при частоте сигнала больше 5 Гц
Всем здравия! Есть поступающий периодический сигнал 5В на ногу ардуино-нано нужно включать светодиод при частоте сигнала больше 5 Гц
Можете включать - разрешаем !
Курите в сторону pulseIn()
нужно включать светодиод при частоте сигнала больше 5 Гц
Ну, нужно, так включайте.
От нас-то чего надо?
Курите в сторону pulseIn()
Да, проще взять готовый частотомер от dimax, но ТС ведь не сказал ничего, так что ХЗ
Всем здравия! Есть поступающий периодический сигнал 5В на ногу ардуино-нано нужно включать светодиод при частоте сигнала больше 5 Гц
А выключать когда?
Всем здравия! Есть поступающий периодический сигнал 5В на ногу ардуино-нано нужно включать светодиод при частоте сигнала больше 5 Гц
А выключать когда?
когда меньше повидимому ...
С ТС 320,83= если всё по чесноку )))
volatile unsigned int int_tic = 0; volatile unsigned long tic; void setup() { TCCR1A = 0; TIMSK1 = 1 << TOIE1; //прерывание по переполнению pinMode (LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); pinMode (5, INPUT); // вход сигнала T1 (only для atmega328) } ISR (TIMER1_OVF_vect) { int_tic++; } void loop() { TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12); //тактировани от входа Т1 delay(1000); TCCR1B = 0; tic = ((uint32_t)int_tic << 16) | TCNT1; //сложить что натикало if (tic >= 5) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } int_tic = 0; TCNT1 = 0; }когда меньше повидимому ...
С ТС 320,83= если всё по чесноку )))
Что меньше понятно... непонятно чего меньше))
320 - водка чтоль по акции?))
320 - водка чтоль по акции?))
там и копейки, нет, это расчет по времени затраченном на скетч )))
PS подумалось, как Скиф за доширак работает? это надо быть очень крутым программистом видимо
А если он выставит вам счет по времени затраченному на понимание вашего скетча, то вы окажетесь в минусе. (Это шутка).
А если он выставит вам счет по времени затраченному на понимание вашего скетча, то вы окажетесь в минусе. (Это шутка).
разве кто-то ставил задачу понятности скетча? - еще и со штрафом? :)
А если он выставит вам счет по времени затраченному на понимание вашего скетча, то вы окажетесь в минусе. (Это шутка).
если он такой простой скетч не понимает то ардуино не его, пусть лучше четырёхцилиндровый двигатель на базе двух от Днепра делает...
Попытаюсь запустить может и получится но delay от туда нужно подстереть
Попытаюсь запустить может и получится но delay от туда нужно подстереть
если сможешь, это тайминг, если точность не нужна можно переделать в стиле ардуино, но не нужно
Попытаюсь запустить может и получится но delay от туда нужно подстереть
Зачем? Он же там время замера определяет.
... если точность не нужна ...
С точностью в приведенном в #5 алгоритме не все хорошо. Считаются передние фронты, и полагается, что количество фронтов равно количеству полных периодов, но это не так. Приведенный алгоритм будет в среднем выдавать признак превышения начиная от 4,5 Гц (в худшем теоретическом случае от чуть больше 4 Гц).
... если точность не нужна ...
С точностью в приведенном в #5 алгоритме не все хорошо. Считаются передние фронты, и полагается, что количество фронтов равно количеству полных периодов, но это не так. Приведенный алгоритм будет в среднем выдавать признак превышения начиная от 4,5 Гц (в худшем теоретическом случае от чуть больше 4 Гц).
для индикатора точность в 25 процентов не важна и то это только на низких частотах, на 50 герцах уже 2.5%, а на 500 - 0,25, что вполне, тут сам мерный отрезок неточен (да и зачем все эти точности индикатору)
PS да и ему надо индицировать превышение, то-есть мгновенную частоту, а с этим там как раз норм
PPS хотим точности - шестерня+ датчик ДПКВ, темы трутся тут уже много времени
Без delay()
PS не проверял
volatile unsigned int int_tic = 0; volatile unsigned long tic; volatile unsigned long old_millis; void setup() { TCCR1A = 0; TIMSK1 = 1 << TOIE1; //прерывание по переполнению pinMode (LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); pinMode (5, INPUT); // вход сигнала T1 (only для atmega328) old_millis = millis(); } ISR (TIMER1_OVF_vect) { int_tic++; } void loop() { if (millis() - old_millis >= 1000) { TCCR1B = 0; tic = ((uint32_t)int_tic << 16) | TCNT1; //сложить что натикало if (tic >= 5) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } int_tic = 0; TCNT1 = 0; TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12); //тактировани от входа Т1 old_millis = millis(); } // USER PROGRAM }ua6em а первую секунду по что обидели ?
ИМХО измеряя длительность импульса можно получать более отзывчивую систему
для индикатора точность в 25 процентов не важна и то это только на низких частотах, на 50 герцах уже 2.5%, а на 500 - 0,25, что вполне, тут сам мерный отрезок неточен (да и зачем все эти точности индикатору)
Ну, по-хорошему, прежде, чем приниматься за программирование, следует проанализировать задачу.
В данной задаче диапазон чисел, представляющих интерес, очень узок: от 5 Гц до 5 Гц. А говорить о какой-либо точности за пределами этого диапазона - нонсенс.
Далее: частоту можно измерить двумя способами:
1. Подсчитать количество импульсов за какой-либо интервал времени.
2. Измерить длительность периода.
При этом "какой-либо интервал" также должен быть оптимизирован под решаемую задачу. Если речь идет о цифровой индикации, этот интервал обычно берется 0.5 секунды. Если нам нужно индицировать пиковое значение - интервал существенно сокращается. Но выбор в качестве такого интервала 1 с представляется не очень удачным.
Теперь - что именно измерять? Для оценки берем допустимый интервал измерений (скажем, 0.5с, что соответствует 2 Гц) и максимальную частоту, которую позволяет измерить аппаратура (в данном случае 8 МГц - 125 нс), и берем от них среднее геометрическое, которое в данном случае составляет 4 кГц (250мкс). Если наш диапазон частот лежит ниже этого значения - целесообразнее измерять период, а если выше - количество импульсов. В приведенном случае, естественно, удобнее измерять период. Ну а дальше, исходя из конкретных потребностей (среднее или пиковое значение), мы либо должны усреднять по нескольким измерениям, либо нет.
Но, естественно, это все досужие рассуждения, т.к. цена за задачу в $5 предполагает, что полный цикл разработки (начиная с анализа и проектирования) не производится, а берется уже готовое решение, которое минимально удовлетворяет критериям задачи.
Но, естественно, это все досужие рассуждения, т.к. цена за задачу в $5 предполагает, что полный цикл разработки (начиная с анализа и проектирования) не производится, а берется уже готовое решение, которое минимально удовлетворяет критериям задачи.
А вот тут вы правы, решение подсказал ЕвгенийП, да и я этот код использую в качестве ИНДИКАТОРНОГО уже давно )))
ua6em а первую секунду по что обидели ?
ИМХО измеряя длительность импульса можно получать более отзывчивую систему
а это упрощения кода ради и дальнейшего разговора для, пятница жеж )))
Где ошибка незнаю.
void setup() { #include <TimerOne.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); //////////////////schetchik////////////////// volatile unsigned int int_tic = 0; volatile unsigned long tic; volatile unsigned long old_millis; //////////////////schetchik////////////////// void setup() { { TCCR1A = 0; TIMSK1 = 1 << TOIE1; //прерывание по переполнению pinMode (LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); pinMode (5, INPUT); // вход сигнала T1 (only для atmega328) old_millis = millis(); } ISR (TIMER1_OVF_vect) { int_tic++ ; } lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.print("Sr"); lcd.setCursor(0,1); lcd.print("Start"); delay (1000); lcd.setCursor(0,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" "); Serial.begin(9600); pinMode(10, OUTPUT); lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.print("Sr"); lcd.setCursor(0,1); lcd.print("Start"); delay (1000); lcd.setCursor(0,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" "); } void loop() { if (millis() - old_millis >= 1000) { TCCR1B = 0; tic = ((uint32_t)int_tic << 16) | TCNT1; //сложить что натикало if (tic >= 5) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } int_tic = 0; TCNT1 = 0; TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12); //тактировани от входа Т1 old_millis = millis(); } lcd.clear(); }Круто написано! Два сетапа!
и куча незакрытых скобок
да уж...дисплей то тебе зачем? в задании был светодиод
Хотел доброе дело сделать - отформатировать скетч, убрать все лишнее (не разбираясь в алгоритме) и понял что там еще очень дофига не хватает ))))
#include <TimerOne.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #define LED_BUILTIN 13 // ЭТО УЖЕ Я (BOOM) ДОБАВИЛ, ТАК КАК В КОДЕ ИСПОЛЬЗУЕТСЯ LiquidCrystal_I2C lcd(0x27, 16, 2); //////////////////schetchik////////////////// volatile unsigned int int_tic = 0; volatile unsigned long tic; volatile unsigned long old_millis; //////////////////schetchik////////////////// void setup() { TCCR1A = 0; TIMSK1 = 1 << TOIE1; //прерывание по переполнению pinMode (LED_BUILTIN, OUTPUT); pinMode (5, INPUT); // вход сигнала T1 (only для atmega328) pinMode (10, OUTPUT); digitalWrite(LED_BUILTIN, LOW); lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("Sr"); lcd.setCursor(0, 1); lcd.print("Start"); delay (1000); lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); } ISR (TIMER1_OVF_vect) { int_tic++ ; } void loop() { if (millis() - old_millis >= 1000) { TCCR1B = 0; tic = ((uint32_t)int_tic << 16) | TCNT1; //сложить что натикало if (tic >= 5) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } int_tic = 0; TCNT1 = 0; TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12); //тактировани от входа Т1 old_millis = millis(); } lcd.clear(); }Спи#енное - перепи#енное и хз кто и как "сращивал".... )))
За 3 года уж можно было бы и форматирование освоить, и копирование ошибок на форум... Ужос.(
Надеюсь ТС понимает, что представленный выше код делает задержку более 1 сек с момента начала измерения, до момента реакции на это измерение.
Почему просто не измерять период каждого импульса и тут же реагировать?
Надеюсь ТС понимает ...
По коду видно, что ТС почти не разбирается в предмете.
Хотел доброе дело сделать - отформатировать скетч, убрать все лишнее (не разбираясь в алгоритме) и понял что там еще очень дофига не хватает ))))
#include <TimerOne.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #define LED_BUILTIN 13 // ЭТО УЖЕ Я (BOOM) ДОБАВИЛ, ТАК КАК В КОДЕ ИСПОЛЬЗУЕТСЯ LiquidCrystal_I2C lcd(0x27, 16, 2); //////////////////schetchik////////////////// volatile unsigned int int_tic = 0; volatile unsigned long tic; volatile unsigned long old_millis; //////////////////schetchik////////////////// void setup() { TCCR1A = 0; TIMSK1 = 1 << TOIE1; //прерывание по переполнению pinMode (LED_BUILTIN, OUTPUT); pinMode (5, INPUT); // вход сигнала T1 (only для atmega328) pinMode (10, OUTPUT); digitalWrite(LED_BUILTIN, LOW); lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("Sr"); lcd.setCursor(0, 1); lcd.print("Start"); delay (1000); lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" "); } ISR (TIMER1_OVF_vect) { int_tic++ ; } void loop() { if (millis() - old_millis >= 1000) { TCCR1B = 0; tic = ((uint32_t)int_tic << 16) | TCNT1; //сложить что натикало if (tic >= 5) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } int_tic = 0; TCNT1 = 0; TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12); //тактировани от входа Т1 old_millis = millis(); } lcd.clear(); }Спи#енное - перепи#енное и хз кто и как "сращивал".... )))
Ардуино ИДЕ компиляторо выдает ошибку - Arduino: 1.8.13 , Плата:"Arduino Nano, ATmega168"
Ардуино ИДЕ компиляторо выдает ошибку - Arduino: 1.8.13 , Плата:"Arduino Nano, ATmega168"
libraries\TimerOne\TimerOne.cpp.o (symbol from plugin): In function `TimerOne::isrDefaultUnused()':
а это там зачем? - TimerOne, советская власть разрешила только одну жену )))
Круто написано! Два сетапа!
Да сам удивился)
Надеюсь ТС понимает, что представленный выше код делает задержку более 1 сек с момента начала измерения, до момента реакции на это измерение.
Почему просто не измерять период каждого импульса и тут же реагировать?
Вот только задумался если так то мне нужно идти другим путем задержки недопустимы а если "измерить период каждого импульса и тут же реагировать" это как написать в ардуиноиде?
Вот только задумался если так то мне нужно идти другим путем задержки недопустимы а если "измерить период каждого импульса и тут же реагировать" это как написать в ардуиноиде?
int pin = 7; unsigned long duration; unsigned long duration1; unsigned long duration2; void setup() { pinMode(pin, INPUT); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { duration1 = pulseIn(pin, HIGH); duration2 = pulseIn(pin, LOW); duration = (duration1 + duration2) / 2; if (duration <= 200000) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } }Терзают меня смутные сомнения...)
Мне конешн пока не ведомо состояние "скучающего пенсионера")), но пусть ТС хоть что-то сам напишет.
Почему просто не измерять период каждого импульса и тут же реагировать?
1. Ловим момент переднего фронта импульса и засекаем время_1 через micros()
2. Ловим передний фронт следующего импульса и засекаем время_2
3. Разность время_2 и время_1 сравниваем с 200 мс и управляем лед.
4. время_1 = время_2 и снова ловим передний фронт.
Вот подсказка. Можно и по другому
word tcnt1; void setup() { TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12); //тактировани от входа Т1 tcnt1 = TCNT1; while(tcnt1 == TCNT1); //ждем импульс time_1 = micros(); tcnt1 = TCNT1; } void loop() { if(tcnt1 != TCNT1){//если пришел импульс ...... } }Терзают меня смутные сомнения...)
Мне конешн пока не ведомо состояние "скучающего пенсионера")), но пусть ТС хоть что-то сам напишет.
да я IBUS два дня пытаю, надо жеж развеяться
Желающие помочь напишите ваши имейлы и стоимость за помощь
Вот только задумался если так то мне нужно идти другим путем задержки недопустимы а если "измерить период каждого импульса и тут же реагировать" это как написать в ардуиноиде?
int pin = 7; unsigned long duration; unsigned long duration1; unsigned long duration2; void setup() { pinMode(pin, INPUT); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { duration1 = pulseIn(pin, HIGH); duration2 = pulseIn(pin, LOW); duration = (duration1 + duration2) / 2; if (duration <= 200000) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } }if (duration <= 200000) {Будет ли это тормозить или влиять на остальную часть программы если дальше в void loop после данного счетчика будет код генерации шим сигнала?
if (duration <= 200000) {Будет ли это тормозить или влиять на остальную часть программы если дальше в void loop после данного счетчика будет код генерации шим сигнала?
не знаю, я pulsein не использовал никогда
int pin = 7;
unsigned long duration; unsigned long duration1; unsigned long duration2; void setup() { pinMode(pin, INPUT); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { duration1 = pulseIn(pin, HIGH); duration2 = pulseIn(pin, LOW); duration = (duration1 + duration2) / 2; if (duration <= 200000) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } }Вы не учли кое чего:
Возвращаемое значение
Длина сигнала в микросекундах или => 0 <=, если сигнал не получен до истечения таймаута.
Advan, что это за проект? или задание?
Желающие помочь напишите ваши имейлы и стоимость за помощь
Неадекватное место для таких просьб. Очень многие завсегдатаи коммерческого раздела в другие никогда не заглядывают. Разместите хотелку там - скорее ответ получите.
Возвращаемое значение
Длина сигнала в микросекундах или => 0 <=, если сигнал не получен до истечения таймаута.
таймаут 1 секунда, холостые порядка 800 -1000 об/сек, ТС говорит о 300, думаю пойдёт
порядка 800 -1000 об/сек,
Что, правда?
ua6em а при полном отсутствии оборотов ваш скетч что покажет на выходе ? - что их больше 5 !
порядка 800 -1000 об/сек,
Что, правда?
Никак не меньше)) иначе поршень на орбиту Земли не выйдет))
Почему просто не измерять период каждого импульса и тут же реагировать?
1. Ловим момент переднего фронта импульса и засекаем время_1 через micros()
2. Ловим передний фронт следующего импульса и засекаем время_2
3. Разность время_2 и время_1 сравниваем с 200 мс и управляем лед.
Время было <200, диод зажгли. Горит.
порядка 800 -1000 об/сек,
Что, правда?
нет конечно, последствия ковида однако...как там в анекдоте было, утром проснулся - алфавит подписал, в минуту естественно, но уже не
вырубишь топоромисправитьЛовим - а его нет, "что-то пошло не так". А диод продолжает нам светить частоту больше пороговой.
Задача для олимпиады по сути, (0+0)/2 будет ноль однако, то есть на
pulseIn();пойдёт, но надо поправить условие )))unsigned long duration; unsigned long duration1; unsigned long duration2; void setup() { pinMode(pin, INPUT); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { duration1 = pulseIn(pin, HIGH); duration2 = pulseIn(pin, LOW); duration = (duration1 + duration2) / 2; if (duration1>0&&duration2 >0&& duration<= 200000) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } }