Изменения цвета ргб от частоты.
- Войдите на сайт для отправки комментариев
Всем здравия. Заранее извиняюсь, если сей вопрос уже был на данном форуме. Глазами пробежался, не узрел.
Суть в чем: вращается пропеллер с магнитом, датчик холла считывает, передает на плату, на экран компьютера выводится частота вращения. - Это был стандартный код, найденый мною в интернете.
// read RPM volatile int rpmcount = 0;//see http://arduino.cc/en/Reference/Volatile int rpm = 0; unsigned long lastmillis = 0; void setup(){ Serial.begin(9600); attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2). } void loop(){ if (millis() - lastmillis == 1000){ /*Uptade every one second, this will be equal to reading frecuency (Hz).*/ detachInterrupt(0); //Disable interrupt when calculating rpm = rpmcount * 60; /* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/ Serial.print("RPM =\t"); //print the word "RPM" and tab. Serial.print(rpm); // print the rpm value. Serial.print("\t Hz=\t"); //print the word "Hz". Serial.println(rpmcount); /*print revolutions per second or Hz. And print new line or enter.*/ rpmcount = 0; // Restart the RPM counter lastmillis = millis(); // Uptade lasmillis attachInterrupt(0, rpm_fan, FALLING); //enable interrupt } } void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/ rpmcount++; }
Что пытаюсь сделать я: три разных выхода с платы на три лапки ргб-диода, и что бы в разном диапазоне частот горели разные цвета. Диапазоны пока в качестве эксперемента 1-9; 10-16; 17-29 об/сек.
// read RPM volatile int rpmcount = 0;//see http://arduino.cc/en/Reference/Volatile int rpm = 0; unsigned long lastmillis = 0; void setup(){ Serial.begin(9600); attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2). } void loop(){ if (millis() - lastmillis == 1000){ /*Uptade every one second, this will be equal to reading frecuency (Hz).*/ detachInterrupt(0); //Disable interrupt when calculating rpm = rpmcount * 60; /* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/ Serial.print("RPM =\t"); //print the word "RPM" and tab. Serial.print(rpm); // print the rpm value. Serial.print("\t Hz=\t"); //print the word "Hz". Serial.println(rpmcount); /*print revolutions per second or Hz. And print new line or enter.*/ rpmcount = 0; // Restart the RPM counter lastmillis = millis(); // Uptade lasmillis attachInterrupt(0, rpm_fan, FALLING); //enable interrupt } int led1 = 8; int led2 = 9; int led3 = 10; pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); if ( rpmcount>1&&rpmcount<9 ) { digitalWrite(led1,HIGH); digitalWrite(led2,LOW); digitalWrite(led3,LOW); } else if ( rpmcount>10&&rpmcount<16 ) { digitalWrite(led1,LOW); digitalWrite(led2,HIGH); digitalWrite(led3,LOW); } else if ( rpmcount>17&&rpmcount<29 ) { digitalWrite(led1,LOW); digitalWrite(led2,LOW); digitalWrite(led3,HIGH); } else { digitalWrite(led1,LOW); digitalWrite(led2,LOW); digitalWrite(led3,LOW); } } } void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/ rpmcount++; }
Что выходит: диод загарается, всё вроде хорошо, но при переходе на следующий диапазон частоты просто добавляется второй цвет, а первый не тухнет, точно так же и при переходе на третий диапазон. При снижении оборотов и переходе на более низкий диапазон, диод продолжает гореть, как на максимуме.
Кто подскажет, в чем моя ошибка?
В том. что Вы не разобрались в найденном в сети коде (кстати, я не понял каким именно ГОСТом он утверждён в качестве "стандартного"?).
В строках 36, 42 и 48 Вы сравниваете rpmcount с Вашими границами. А кто Вам собственно сказал, что количество оборотов находится именно в переменной rpmcount? Вот с чего Вы это взяли? В комментариях к коду написано совсем другое. В rpmcount находится сырое количество прерываний, а количество оборотов (частота вращения) живёт в другой переменной.
Разберитесь в какой переменной у Вас частота вращения и используйте эту переменную.
Ну, про мелочи, типа строк 29-34 зачем-то всунутых в loop я молчу. Само по себе диковато, но работать должно и так.
Евгений, как всегда, пытается заставить шевелить извилинами топикстартера и только при обнаружении малейшего движения поделится своими гениальными соображениями ))
29-34, насколько я понимаю, хотя мне до Евгения далеко и безнадёжно - им место в начале программы, до Setup().
Насчет дикости, это, скорее всего, в огород кучи "if"-ов, которые вполне можно заменить на switch - case.
Насчет переменных: не скажу, потому что не пойму принципа работы операторов в цикле Void loop() пока что.))))
В защиту "swith-case": когда мучался с обработкой IR-кодов с пульта (те же условия перехода по конкретному коду или диапазрну что и здесь, собственно), if-ы глючили - конкретно. А вот swith-case - то что доктор прописал.
Пересмотрел уже тысячу раз. Вроде бы именно rpmcount выдает частоту вращения в сек. Так и не понял, какая ещё переменная может за это отвечать. У меня же там всего 2 переменных, судя по коментариям кода rpmcount отвечает за об/сек, а rpm за об/мин. Тем более rpmcount зажигает диод нужным цветом, при нужном диапазоне. Проблема в том, что не тушит предыдущий цвет при переходе на другой диапазон.
Где я запутался? Какую часть кода не понял? По логике вещей всё должно работать, ведь четко определил ифами границы и прописал когда и что должно гореть.
ну избыточность в ифа точно есть.
зачем писать больше 1 и меньше 9. если и так понятно что будет меньше 9.и
в остальных условиях также. надо оставить просто меньше 9 меньше 16 меньше 29 и больше 29 и все.
аха у него еще и значения 9 10 16 17 идут в иначе может ради этого разве что
больше 1 и меньше 9 - чтоб на нуле не горел.
Пересмотрел уже тысячу раз. Вроде бы именно rpmcount выдает частоту вращения в сек. Так и не понял, какая ещё переменная может за это отвечать.
Смотрите в тысячу первый. Что, по-Вашему означает комментарий "Convert frecuency to RPM" в строке 18?
Перевод частоты из герц в "об/мин"
Так, я уже эту мысль писал, но, видимо, как-то непонятно написал. Читайте внимательно
Что хранится в rpmcount? Там хранится количество пойманных прерываний. Это СЧЁТЧИК Оно накапливается в течение секунды и только тогда (раз в секунду) становится частотой. В строках 14-28, ОДИН раз в секунду, накопленное число обрабатывается и счётчик сбрасывается в ноль (строка 25).
Таким образом, rpmcount каждую секунду сбрасывается в ноль и начинает новое суммирование количества прерываний. По истечени секунды там оказывается частота (количествоо прерываний в секунду). Она тут же снова обрабатывается и опять сбрасывается в ноль.
Реальная частота (только не в герцах, а в оборотах в минуту) хранится в rpm. А rpmcount постоянно "гуляет" от 0 до частоты и тут же снова становится нулём.
Вместо того, чтобы пользоваться готовй rpm (ну или не делите на 60, просто сохраняйте, если Вам именно частот нужна) Вы используете переменную-счётчик rpmcount в качестве частоты. При этом Вы не знаете в какой момент Вы его (счётчик дернули). Может когда там уже готовая или почти готовая частота, а может как раз когда там свеженький нолик сидит. Вы попечатайте её в Serial уидите, что она постоянно плавает.
Так понятно?
Блин, даже я понял! Спасибо за разжовывание!