Создание собственной системы стабилизации
Накати сперва все обновления и все решится скорее всего…
Я уже бубунту с wine накатил 😃 - теперь и мои дела работают и сына 😃
блин такое желание старый контроллер разобрать и собрать новый - нее подожду деталек…
MPU внутри работает на 1(8)КГц, а данные суммирует в зависимости от выходной частоты. Поэтому нету особой разницы где суммировать, на стороне CPU или MPU - результат один и тот же
Привет! А что означает суммирование в мпу?
тут мысли возникают направить мощь STM на предварительную фильтрацию данных
Смысла нет, лучше эту мощь в алгоритме использовать.
а надо ли гнаться за частотой ?
не надо, нет смыла задирать скорость выше скорости реакции приводов (серв, моторов и тп).
А что означает суммирование в мпу?
Вот это хз… но смысл такой, что ДУС там всегда работает на 1000Гц, а скорость выдачи данных, одновременно ДУС+аксель, получается делением на настраиваемый коэффициент K, дык вот за время dt = (к+1)/1000 отсчёты ДУС усредняются.
Очередной затык, теперь с 5611, “пихаю” 24-х битное число (из трех uint8_t) в uint32_t так:
D1=(uint32_t)((b1<<24)|(b2<<16)|(b3<<8)); - // по моему не правильно, но работает…
или
D1=(uint32_t)((b1<<16)|(b2<<8)|b3); -// по моему правильно но результат - не тот…
Где я туплю ??
Правильно так:
D1=(uint32_t)((b1<<16)|(b2<<8)|b3);
Правильно так:
D2=(uint32_t)((b1<<16)|(b2<<8)|b3);
Я тоже так думаю, но после нехитрых вычислений далее (расчет температуры 5611 по даташиту):
dT=(int32_t)(D2 -C5*256);
MS_temper=2000 + dT*C6/8388608;
, нужный результат почему то получается именно при “неправильном” способе присвоения…
если про это
static uint32_t ms5611_read_adc(void)
{
uint8_t rxbuf[3];
i2cRead(MS5611_ADDR, CMD_ADC_READ, 3, rxbuf); // read ADC
return (rxbuf[0] << 16) | (rxbuf[1] << 8) | rxbuf[2];
}
` int64_t dT = ms5611_ut - ((int32_t)ms5611_c[5] << 8);
int64_t off = ((uint32_t)ms5611_c[2] << 16) + ((dT * ms5611_c[4]) >> 7);
int64_t sens = ((uint32_t)ms5611_c[1] << 15) + ((dT * ms5611_c[3]) >> 8);
temp = 2000 + ((dT * ms5611_c[6]) >> 23);
драйвера есть все в открытом доступе, тут даже смысла не вижу изобретать?
тут даже смысла не вижу изобретать
Сам не хотел изобретать, сначала взял готовый кусок кода, но фиг там … Похоже надо с компилятором повнимательней разобраться (с указанием типов), где то переполнение вылазит., так что “скопипастить” не получилось…
Мда… Все ж компиллер как то теряет знаковый тип при сдвиге (делении) больших чисел, отсюда и косяк у меня,…
Не было печали…
Keil вроде с оффсайта качал, правда он с ограничениями… (не в этом ли дело?)…
Мда… Все ж компиллер как то теряет знаковый тип при сдвиге (делении) больших чисел, отсюда и косяк у меня,…
Не было печали…
Keil вроде с оффсайта качал, правда он с ограничениями… (не в этом ли дело?)…
кейл с ограничениями тут не причем, компилятор “считает” с права налево и выполняет действия согласно приоритетам операций. Может он что то не то сначала вычисляет.
эти формулы не правильно считаются?
dT=(int32_t)(D2 -C5*256);
MS_temper=2000 + dT*C6/8388608;
покажите кусок кода и какие типы переменных используются.
покажите кусок кода
Вот переменные:
int32_t dT,MS_temper;
uint32_t D2;
uint16_t C5,C6;
Вот расчет:
dT=D2 - (uint32_t)C5<<8; //( dT здесь получается 1700, проверял)
MS_temper=((int64_t)dT*28312)>>23;
MS_temper выходит -131, хотя должно быть 5…
Если пишу прям так: MS_temper=(1700*28312)>>23;
или присваиваю ранее dT=1700; - то как раз 5 и выходит…
Такое ощущение что c типом int64_t что то не так…
при умножении вылазит за 32 бита, попробуйте заменить на double, если заработает посмотрите как определен тип int64.
Возможно int64 определен как long, а компилятор его считает 32 битным, вспомнил (long long) 64 бита целочисленное.
Возможно int64 определен как long
Да, спасибо Вам за наводку, похоже где то здесь косяк… (первый признак, проверенные примеры из инета не работают…) буду копать.
Если “быстро” поправить то можно написать:
MS_temper=((long long)dT*28312)>>23;
Камрады, а зачем вы геммороитесь с такими операцыями типа <<8 и >>23? кто мешает нормально делить и перемножать числа как и указано в даташите? Сами себе проблемы ищете.
Или наносекунды экономите?
это касается и возведения в степень
заранее двойку в степень возведите и усе
Вот расчет:
dT=D2 - (uint32_t)C5<<8; //( dT здесь получается 1700, проверял)
вот здесь еще косяк, не хватает скобочек:
dT=D2 - ((uint32_t)C5<<8);
Камрады, а зачем вы геммороитесь с такими операцыями типа <<8 и >>23? кто мешает нормально делить и перемножать числа как и указано в даташите? Сами себе проблемы ищете.
Или наносекунды экономите?
это касается и возведения в степень
заранее двойку в степень возведите и усе
можно и без << >>, просто это пример из интернета, вот его и разбирали почему не работает
с такими операцыями типа <<8 и >>23
В моем случае деление на число=2^23 дает тот же результат…
Если “быстро” поправить то можно написать:
MS_temper=((long long)dT*28312)>>23;
К сожалению, Андрей, не прошло и так…
Тут я понял однозначно: компиллер отказывается (?) понимать беззнаковые переменные при операциях деления или сдвига вправо, … он их считает знаковыми, независимо от непосредственного указания типа…
Хотя на сам тип реагирует - “warning”, если ему подсунуть uint16_t на проверку на “<0”…
не знаю что может быть с кейлом, вроде не должно быть такого, сам пишу в иаре, попробовал в иаре все работает:
unsigned short int C5 = 33464;
unsigned short int C6 = 28312;
unsigned int D2 = 16777215;
signed int dT = D2 - ((unsigned int)C5<<8);
signed int TEMP = 2000 + (((long long)dT*C6)>>23);
под ARM пишете?
MS_temper=((int64_t)dT*28312)>>23; MS_temper выходит -131, хотя должно быть 5…
MS_temper ранее был объявлен как int32_t …почему он вдруг должен стать int64_t ?
И наверное MS_temper = 2000+dT*C6/2^23; Не?
не знаю что может быть с кейлом
Тут, скорее всего, ключ какой то нужен для компиллера, или еще какая “магия”…
Был удивлен, но : пишу
uint32_t K=57438; при компиляции он мне:
<main.c(78): warning: #68-D: integer conversion resulted in a change of sign>
т.е. он мне “великодушно” решил преобразовать беззнаковую в константу в знаковую (увидел старший бит)…
Не скажу что я программист, STM32 недавно только освоил, но ранее как то не сталкивался с этим (заморочки)…
почему он вдруг должен стать int64_t
произведение двух переменных в скобках больше 32-х разрядов, а они мне все нужны 😃…
напишите вот так, посчитает ли кейл:
unsigned short int C5 = 33464;
unsigned short int C6 = 28312;
unsigned int D2 = 16777216;
signed int dT = D2 - ((unsigned int)C5<<8);
signed int TEMP = 2000 + (((long long)dT*C6)>>23);