Ардуино не правильно вычисляет. (баг?)
- Войдите на сайт для отправки комментариев
Вс, 13/08/2017 - 12:02
Здравствуйте.
При расчете времени поворота синусоиды на 1гр. по формуле: ( t / f ) / 360, где t - 1 сек в микросекундах, f - задаваемая частота в Гц, 360 - период синуса в углах, столкнулся с интересным моментом:
если расчет вести по выделенной формуле, то при задаваемых частотах f < 185 ардуино вычисляет значения верно:
но, если значение задаваемых частот f > 185, то начинается что-то для меня не понятное (должно получиться 14,62, с округлением до 15):
если же расчет вести по формуле, которая закомментирована, то ардуино вычисляет все как положенно и таких глюков не наблюдаю.
Весь код скетча:
byte mask_p = (1 << 7) | (1 << 4) | (1 <<2); //маска пинов фаз 2, 4, 7 const uint8_t deg_max=90, //угол первого максимума deg=120, //угол сдвига фаз p_value=75, //длительность 1/4 периода фазы в эл.углах motor_deg=4;//4 периода синуса = 1 обороту const uint32_t sec=1000000;//сек в микросек unsigned long _time, //время работы ардуино p1_str, p1_stp, p2_str, //время начала и конца p2_stp, p3_str, p3_stp; //положительного полупериаода фаз uint16_t f, //частота фазы deg_val; //1 эл.гр. в мкс uint8_t p_rise, //угол начала фазы p_dawn; //угол конца фазы void setup() { Serial.begin(9600); DDRD |= mask_p; //пины 2, 4, 7 OUTPUT PORTD &= ~mask_p; //пины 2, 4, 7 LOW f = 190; _time = micros(); /*deg_val = (sec/f)/360;*/ deg_val = sec/(f*360); Serial.println(deg_val); p_rise = 90-p_value; p_dawn = 90+p_value; p1_str = _time + deg_val*p_rise; p1_stp = p1_str + deg_val*p_value*2; p2_str = _time + deg_val*(p_rise+120); p2_stp = p2_str + deg_val*p_value*2; p3_str = _time + deg_val*(p_rise+240); p3_stp = _time + deg_val*((330+p_value)-360); } void loop() { while (1) { _time = micros(); if (_time>=p1_str) { //ждем время нарастания фазы 1 PORTD |= (1<<2); p1_str = p3_str + deg_val*120;} else { if (_time>=p3_stp) { //ждем время спада фазы 3 PORTD &= ~(1<<7); p3_stp = p3_str + deg_val*p_value*2;} else { if (_time>=p2_str) { //ждем время нарастания фазы 2 PORTD |= (1<<4); p2_str = p1_str + deg_val*120;} else { if (_time>=p1_stp) { //ждем время спада фазы 1 PORTD &= ~(1<<2); p1_stp = p1_str + deg_val*p_value*2;} else { if (_time>=p3_str) { //ждем время нарастания фазы 3 PORTD |= (1<<7); p3_str = p2_str + deg_val*120;} else { if (_time>=p2_stp) { //ждем время спада фазы 2 PORTD &= ~(1<<4); p2_stp = p2_str + deg_val*p_value*2;} } } } } } } }
Ваша f имеет тип uint16_t, произведение f*360 будет такого же типа. Переполнение случилось, и Ваши секунды делятся уже совсем не на то, что Вы думаете.
Не знал о такой особенности, спасибо
Мне Ваш комментарий очень помог в дальнейших расчетах =) еще раз спасибо
Не по теме, но ник больно уж у автора прикольный.
https://ru.wikipedia.org/wiki/Викернес,_Варг
Я уже думал о манхейм забыли =) да и ссылку тогда уж на Эйстейна Ошета надо был давать ;-)