генерация значений от 0 до 360 каждые 10 секунд
- Войдите на сайт для отправки комментариев
Ср, 28/05/2014 - 20:11
Есть необходимость в генерации значений от 0 до 360 за 10 секунд и заново. Задержки и ++ не вариант т.к. тормозится вся программа. пробовал с привязкой к переменной millis();
void loop() { time = millis(); if(time%100 == 0) { alfa_grad = alfa_grad + 3.6; } if( time%10000 == 0) alfa_grad = 0;
где альфа это угол. Не получается, значения плавают, через монитор порта видно что даже не от 0 до 9 значения в последовательностях. Что можно исправить, или другие способы реализации?
Не очень понял задачу, если нужно задать значение с высокой точностью интервала, можно воспользоваться прерыванием настроив соответствующий таймер, например:
Только нужно правильно установить регистр TCCR1B, и прескалер OCR1A, а то я сейчас на глаз посчитал
Не очень понял задачу, если нужно задать значение с высокой точностью интервала, можно воспользоваться прерыванием настроив соответствующий таймер, например:
Только нужно правильно установить регистр TCCR1B, и прескалер OCR1A, а то я сейчас на глаз посчитал
не могу найти понятного руководства по их настройке.
Вы взяли OCR1A = 15624 это столько отсчетов пройдет за 10 секунд и таймер обнулится, верно?
а растет tcnt1?
как проводить рассчеты?
15624 это 1 секунда, расчет: 16000000 (16MHz частота) / 1024 (прескалер)/ 15625 (размер счетчика)
TCNT1 это регистр счетчика - да.
Я так понял, что каждую секунду нужно увеличивать значение на +3.6 в течении 10 секунд, затем сбрасывать и по новой.
да, верно
Я там в первом сообщении допустил ошибку, нужно поменять местами слова "регистр" и "прескалер". Прескалер задается битами CS10,CS11,CS12 в регистре TCCR1B, а регистр OCR1A это значение по которому происходит прерывание.
спасибо, я догадался когда начал гуглить. Только что то не хочет обнуляться, дальше гонит за 360. Ошибок что-то не видно
alfa_grad у вас глобальная volatile?
весь код, даже когда исправил пишет значения выше 360
Условие сброса в прерывании нужно переписать, у вас в loop значние a_r меняется произвольно.
Или в loop не нужно переопределять a_r, а использовать для вычислений другую переменную.
И учтите, что loop будет выполнятся со скоростью исполнения кода, а прерывание вызываться строго каждую 1 секунду. То ли это, что вы хотели получить?
это как раз то, что надо. Этот код для эмуляции синусоиды. а так на вход напряжение приходит и оцифровывается и скорость там ни к чему.
не добился я пока эффекта
альфа нужен чтобы промодулировать синусоиду
Ага, я не увидел разницы между alfa_rad и alfa_grad. Теперь вижу что с этим все впорядке.
Думаю тут дело в типе float, который не будет равен точно 360. Попробуйте привести типы перед сравнением, если не поможет можно попробовать округлить или отбросить дробную часть или сравнить не точно а > или <.
никакими операторами не обнуляется, либо пишет нули вообще
Хмм, ну так то полюбому должно сработать: if(alfa_grad > 359 && alfa_grad < 361)... да и даже if(alfa_grad > 359) будет достаточно
а не может ли быть дело в том что обработчик запускается и выполняется бесконечно, не может снуляться? луп осуществляет циклы
Прерывание прерывает исполнение loop на время исполнения обработчика, т.е. если бы обработчки выполнялся бесконечно, то весь loop бы просто завис
отставить,
дало эффект.
Бесконечно благодарен за помощь. Знаний как видите маловато еще у меня)
не исключено что по времени это дольше чем 10 секунд, проверю завтра на реальном железе с осциллографом