Создание собственной системы стабилизации

SergDoc

У 6050 нет SPI и логика запитывается от 1.8 В, а я хочу SPI…

igor_v_t
SergDoc:

У 6050 нет SPI и логика запитывается от 1.8 В, а я хочу SPI…

Это логично, но MPU6000 нашел я только в США с рассылкой по США и Канаде. Поэтому до появления MPU6000 и MPU9150 может играться с гироскопами STM ? У STM тоже будет девятиосевая микросхема. И у них она заявлена по 3,1 ам. руб. в партии 1000 шт. В принципе любые гироскопы нормально летают.

SergDoc

LSM330DL - но смущает одно - у гиры и акселя раздельные шины и если по SPI то дофига получается дорожек разводить, а i2c я уже рисовал но пока чёт нерешаюсь делать…

igor_v_t
SergDoc:

LSM330DL - но смущает одно - у гиры и акселя раздельные шины и если по SPI то дофига получается дорожек разводить, а i2c я уже рисовал но пока чёт нерешаюсь делать…

Да в принципе все это с SPI имеет смысл если повышать скорость считывания данных. При 200 Гц можно и I2C обойтись и по большому счету и 32 разряда не надо. Я на мультиВие упражнялся, так проблем особых нет. Мы тут какую то макетницу рисуем и будем делать . Посему могу выложить, когда чертежик будет и в принципе готовые платки тож будут заводские , но все это не очень быстро. Поскольку работать иногда надо.

HikeR

аксели в СС на 3.2кГц работают (6-7 чтений с усреднением за цикл). переводить алгоритм на 200Гц — слишком много где порыться придется.

igor_v_t:

У STM тоже будет девятиосевая микросхема. И у них она заявлена по 3,1 ам. руб.

если вы про INEMO-M1, то она заявлена в 30-40 баксов.

igor_v_t
HikeR:

если вы про INEMO-M1, то она заявлена в 30-40 баксов.

Не я про LSM333 .INEMO-M1 она с процессором а потом мне непонятно что делать. Обработку всю этот процессор потянет, а для вывода на моторы еще один ставить?

HikeR:

аксели в СС на 3.2кГц работают (6-7 чтений с усреднением за цикл). переводить алгоритм на 200Гц — слишком много где порыться придется.

По СС мнение у меня такое - с такими датчиками не стоило огород городить. Не стоят они того. По опыту играясь с MPU 6000 неправильно в программе подключил аксели и не заметил поначалу, так как гироскопы без них справлялись. С другой стороны что ни делай с акселерометрами на МультиВии ничего хорошего не получается. Поэтому усложнять алгоритмы смысл имеет при нормальных датчиках. А основная идея перехода у меня на 32 разряда - это нелинейное управление.

HikeR
igor_v_t:

Обработку всю этот процессор потянет, а для вывода на моторы еще один ставить?

ессно, это ведь прямая замена всяких 9DOF модулей без необходимости лишней обвязки. к ней так и просятся парочка дополнительных датчиков, если откроют исходники.

igor_v_t:

с такими датчиками не стоило огород городить

не, я имел ввиду то, что СС весь “погряз” в рилтайме. чтобы изменить частоту опроса датчиков нужно перелопатить все связанные таймауты, иначе вместо опроса плата будет слать только варнинги.
насколько я помню, OpenPilot единственный открытый проект завязанные на RTOS, отсюда и трудности.

SergDoc

А я чего-то недоганяю, удаляю папку build компилирую всё заново а изменений никаких, в часности уменьшил скорость i2c поправил коэффициент для своих гир , а он непоменялся

igor_v_t:

Не я про LSM333

ну почему они каждому датчику собственную шину прикручивают?

Drinker
Sir_Alex:

Я где то читал, что есть некоторые грабли у F103 процов с i2c шиной и эти грабли поправили в F4. Так что, как вариант сразу этот проц закладывать в новых проектах. Хотя кто то тут писал про свой проект построения своего софта и долгое отлавливания багов с i2c шиной, но поделится чем то полезным человек не захотел…

Нету у кортекса проблем с и2ц

igor_v_t
HikeR:

не, я имел ввиду то, что СС весь “погряз” в рилтайме. чтобы изменить частоту опроса датчиков нужно перелопатить все связанные таймауты, иначе вместо опроса плата будет слать только варнинги. насколько я помню, OpenPilot единственный открытый проект завязанные на RTOS, отсюда и трудности.

Ну в этом я пока не понимаю.
Я на Атмеге игрался с этим и понимаю так, что если повышение частоты опроса не уменьшает ошибку интегрирования не имеет смысла ее повышать частоту опроса гироскопа. То же с акселем. В MPU 6000 есть ФНЧ. И вполне может быть что повышение частоты эффекта просто не даст.
На MS5611 я эффект получил при повышении частоты до 100 Гц. Дальнейшее усреднение баро дает красивую картину. И смысла фильтровать с акселерометром нет.
При этом на плате МультиВии (SE) с Гудлака фильтрация баро с акселерометром эффекта не дала по причине медленного акселерометра.

SergDoc:

ну почему они каждому датчику собственную шину прикручивают?

А может люди не мучатся а суют два кристала в один корпус?

SergDoc

Я вобщем решил пока так - гибрид КК и СС пока останется как есть(через 2 недели будут новые движки -опробую), заказал LSM330DL сделаю что-то на подобии NAZE32…

rual
SergDoc:

почему они каждому датчику собственную шину прикручивают?

тут нет никакой проблемы, у меня одна шина, SCK, MISO, MOSI параллельно , CS и RDY индивидуально подключены. Чтение через ПДП, выбор кристала переключает диспетчер СПИ, он же выбирает обработчик данных (дус\аксель) по окончании ПДП.
Однозначно победить и2ц не смог, изредка вылетают ошибки.
код такой

/* ----------------- запрос обмена по I2C через перерывание -------------------------*/
void IMU_ReqI2C_Trans(uint8_t adr, uint8_t iadr, uint8_t cnt )
{
uint16_t time = micros();
IMU_I2C_ClrAllErr();
I2C_ClearFlag(I2C_IMU,I2C_FLAG_AF|I2C_FLAG_ARLO|I2C_FLAG_BERR);

/* ожидаем освобождения интерфейса */
while(I2C_GetFlagStatus(I2C_IMU, I2C_FLAG_BUSY)){
if (((micros()-time)&0xfff) > IMU_I2C_MAXTIM){
IMU_I2C_SetErr(LBSY);
return;
}
}
/* предварительная настройка переменных */
imu_i2c_dev_adr = adr;
imu_i2c_buf[0] = iadr;
imu_i2c_cnt = cnt;
imu_i2c_inx = 0;
I2C_AcknowledgeConfig(I2C_IMU, ENABLE);
/* передаем состояние START */
I2C_GenerateSTART(I2C_IMU, ENABLE);
}
/* обработчик прерывания по событиям и буферу и2ц ИНС
внутренний адрес размещаем в buf[0]*/
void I2C1_ISR(void)
{
switch(I2C_GetLastEvent(I2C_IMU)&(~I2C_FLAG_BTF))
{
case I2C_EVENT_MASTER_MODE_SELECT: /* EV5 */
if ((imu_i2c_inx == 0)/* передаём вынутренний адрес */
||(imu_i2c_dev_adr&0x01 == 0)) /* режим передачи */
I2C_Send7bitAddress(I2C_IMU,imu_i2c_dev_adr,I2C_Direction_Transmitter);
else /* запуск чтения после повторного старта */
I2C_Send7bitAddress(I2C_IMU,imu_i2c_dev_adr,I2C_Direction_Receiver);
break;
case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: /* EV6 */
case I2C_EVENT_MASTER_BYTE_TRANSMITTING: /* EV8 */
case I2C_EVENT_MASTER_BYTE_TRANSMITTED: /* EV8_2 */
if ((imu_i2c_inx == 1)&&(imu_i2c_dev_adr&0x01 != 0))
/* повторный старт для чтения */
I2C_GenerateSTART(I2C_IMU, ENABLE);
else { /* либо продолжаем писать */
if (imu_i2c_inx < imu_i2c_cnt+1)
/* передаём следующий байт */
I2C_SendData(I2C_IMU,imu_i2c_buf[imu_i2c_inx++]);
else /* передача буфера завершена */
I2C_GenerateSTOP(I2C_IMU, ENABLE);
}
break;

case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: /* EV6 */
case (uint32_t)(I2C_FLAG_BUSY|I2C_FLAG_MSL): /* состояние после сброса флага ADDR */
if (imu_i2c_cnt == 1) /* принимаем всего один байт */
I2C_AcknowledgeConfig(I2C_IMU, DISABLE);
break;

case I2C_EVENT_MASTER_BYTE_RECEIVED: /* EV7 */
if (imu_i2c_inx > imu_i2c_cnt) /* завершили чтение */
I2C_GenerateSTOP(I2C_IMU, ENABLE);
else {/* продолжаем чтение */
imu_i2c_buf[imu_i2c_inx++] = I2C_ReceiveData(I2C_IMU);
if (imu_i2c_inx == imu_i2c_cnt) /* будем принимать последний байт */
I2C_AcknowledgeConfig(I2C_IMU, DISABLE);
}
break;
default: /* не понятное состояние == ошибка интерфейса */
IMU_I2C_SetErr(IFERR);
I2C_GenerateSTOP(I2C_IMU, ENABLE);
I2C_SendData(I2C_IMU,I2C_GetLastEvent(I2C_IMU));
break;
}
/* проверим выход указателя за пределы буфера */
if (imu_i2c_inx > sizeof imu_i2c_buf)
{
imu_i2c_inx = sizeof imu_i2c_buf;
IMU_I2C_SetErr(OVBUF);
}

/* здесь вызов метода-заполнителя данных объекта ИНС */
switch(imu_i2c_dev_adr){
/* чтение магнитометра */
case MAG_I2C_DEV_ADR|0x01: MagmDataRdy(); break;
}
}
rual

выкладываю остатки, если вдруг затруднения возникнут

/// это в загловочном файле макросы для фиксации ошибок и2с
typedef enum _IMU_ERR{
LBSY = 0, /* длительная занятость */
OVBUF, /* выход за пределы буфера */
IFERR, /* ошибка интерфейса */
ACKF /* нет ответа ведомого */
}IMU_ERR;
#define IMU_I2C_MAXTIM 250*8 /* макс. занятость интерфейса в микросек. */
#define IMU_I2C_SetErr(Err) {imu_i2c_err|= (1<<Err);}
#define IMU_I2C_ClrErr(Err) {imu_i2c_err&= ~(1<<Err);}
#define IMU_I2C_ClrAllErr() {imu_i2c_err = 0;}
#define IMU_I2C_GetErr() (imu_i2c_err)

typedef enum _IMU_ERR{
LBSY = 0, /* длительная занятость */
OVBUF, /* выход за пределы буфера */
IFERR, /* ошибка интерфейса */
ACKF /* нет ответа ведомого */
}IMU_ERR;
#define IMU_I2C_MAXTIM 250*8 /* макс. занятость интерфейса в микросек. */
#define IMU_I2C_SetErr(Err) {imu_i2c_err|= (1<<Err);}
#define IMU_I2C_ClrErr(Err) {imu_i2c_err&= ~(1<<Err);}
#define IMU_I2C_ClrAllErr() {imu_i2c_err = 0;}
#define IMU_I2C_GetErr() (imu_i2c_err)

/// инициализация и2ц
/* настойка и2ц ИНС */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
/* Configure I2C1 pins: PB6->SCL and PB7->SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);

I2C_DeInit(I2C_IMU);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_16_9;
I2C_InitStructure.I2C_OwnAddress1 = 1;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000; /* 100kHz */
I2C_Cmd(I2C_IMU, ENABLE);
I2C_Init(I2C_IMU, &I2C_InitStructure);
/* настройка прерывания И2Ц ИНС */
NVIC_EnableIRQ(I2C1_ER_IRQn);
NVIC_EnableIRQ(I2C1_EV_IRQn);
NVIC_SetPriority(I2C1_EV_IRQn, 5);
/* разрешаем прерывание от и2ц */
I2C_ITConfig(I2C_IMU, I2C_IT_EVT|I2C_IT_BUF|I2C_IT_ERR, ENABLE);

всё это обращается к стандартным перефирийным библиотекам

RaJa
SergDoc:

STM32F103VET6, под него удобное IDE есть и ардупилот32 на нём легче организовать

Подскажите, Сергей, а что за IDE под него. У меня платка усть miniSTM32 STRIVE v2.1, там такой же проц, руки все до нее не доходят никак.

Dimm168pin:

я с орлом после sprint layout вообще не разобрался, в diptrace вроде понемногу освоился, смотрю что вроде такая же ерунда что и с мегами, кварц, пару емкостей и полетели)

А не поделитесь библиотеками компонентов для него? а то в нем даже элементарных вещей часто нет вроде светодиода SMD.

soliada
SergDoc:

Кто-нибудь под мультивий писал код под LSM330DL

Спросите Дмитрия, ник Омегапрайм,он таким датчиком давно пользуется.

rual
SergDoc:

У меня мама оттуда родом

если будете, в наших краях , ссобщите - пообщаемся

SergDoc:

Кто-нибудь под мультивий писал код под LSM330DL, нужен для портирования в NAZE32

я использую LSM330DL, правда у меня с ней глубоко аппаратный обмен, поэтому арду-подобные ИДЕ мне не идут. могу помочь с заголовочным файлом и данными инициализации.

/* умолчантельное заполнение настроечной структуры */
void Gyro::SetDefaultInitStruct(GYRO_CR* gyro_cr)
{
gyro_cr->CTRL_REG1_G = LSM330_G_DR400BW50
+ LSM330_G_PD
+ LSM330_Zen + LSM330_Yen + LSM330_Xen; /* Частота преобразования/ФНЧ1 400/50 Гц все оси вкл. */
gyro_cr->CTRL_REG2_G = LSM330_G_HPM0 + LSM330_G_HPC8; /* ФВЧ нижняя граница 0.1 Гц */
gyro_cr->CTRL_REG3_G = LSM330_G_I2_DRDY; /* вызвать прирывание по готовности данных на I2_DRDY */
gyro_cr->CTRL_REG4_G = LSM330_BDU /*+ LSM330_BLE*/ /* чтение блоком , первый мл.байт */
+ LSM330_G_FS2000; /* предел 2000 гр/с */
gyro_cr->CTRL_REG5_G = 0; /* буфер отключен, ФВЧ и ФНЧ2 отключены */
}
void Accel::SetDefaultInitStruct(ACC_CR* acc_cr)
{
acc_cr->CTRL_REG1_A = LSM330_A_ODR_50
+ LSM330_Zen + LSM330_Yen + LSM330_Xen; /* Частота преобразования 50 Гц все оси вкл.*/
acc_cr->CTRL_REG2_A = 0; /* ФВЧ отключен */
acc_cr->CTRL_REG3_A = LSM330_A_I1_DRDY1; /* прирывание по готовности данных */
acc_cr->CTRL_REG4_A = LSM330_BDU /*+ LSM330_A_HR*/ /* чтение блоком , первый мл.байт */
/*+ LSM330_BLE*/ + LSM330_A_FS16G; /* предел 16G */
acc_cr->CTRL_REG5_A = 0; /* буфер отключен, ФВЧ и ФНЧ2 отключены */
acc_cr->CTRL_REG6_A = 0; /* буфер отключен, ФВЧ и ФНЧ2 отключены */
}

LSM330def.rar