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

SergDoc

а просто ножку отогнуть не получится? или провод из разъёма дёрнуть (не знаю как сделано) для проверки, или оно всё вместе?
ftdi пусть питается от usb а на плату от usb уже не шло…

VitaliyRU
SergDoc:

напряжение на нём чуть меньше 5-ти вольт, получается ток от стаба течёт не туда куда надо

У меня там еще и DC-DC преобразователь, с дикой пилой на выходе(судя по помехам на FPV). Акк то 1S а ардуина 5V

SergDoc

пила может быть в двух случаях, либо фильтры (конденсаторы особенно) дохлые, либо стаб перегружен! …

VitaliyRU
SergDoc:

а просто ножку отогнуть не получится? или провод из разъёма дёрнуть (не знаю как сделано) для проверки, или оно всё вместе?
ftdi пусть питается от usb а на плату от usb уже не шло…

Да он мелколет же у меня, зато не страшно палцы сувать, если всбеситься 😃

Но спасибо за подсказку, значит я правильно думал. просто поставлю маленький разъем на 5V от FTDI

mataor

Хм… такой вопрос - колбасит на маховие рц3 а на рц1-2 (вий 2.1) все норм? Пиды менял или одинаковые пробовал? Просто уже не раз говорилось что там размерности разные - деление заменили сдвигом -> разные пиды нужно. У меня порт рц3 кстати на дефолтных пидах висит идеально (аппарат 1800, тестил без смены пидов с 3s акб 380г и с 4s весом около 600 + и на той и на другой добавлял еще ноги 200г. и подвес 400г.)

VitaliyRU
mataor:

Хм… такой вопрос - колбасит на маховие рц3 а на рц1-2 (вий 2.1) все норм? Пиды менял или одинаковые пробовал? Просто уже не раз говорилось что там размерности разные - деление заменили сдвигом -> разные пиды нужно. У меня порт рц3 кстати на дефолтных пидах висит идеально (аппарат 1800, тестил без смены пидов с 3s акб 380г и с 4s весом около 600 + и на той и на другой добавлял еще ноги 200г. и подвес 400г.)

Опять же по моему опыту все это особо не влияет. Невинно убиенный астависта как то очень верно заметил(свечку то держал, в отличии от нас), что MEMS дачики могут резонировать. Т.Е. от настроек должны меняться ньюансы поведения, глобально они не влияют.
Другими словами коряво настроенный PD это тупизм или расколбас, остальное вибрация на %%80 или проблемы в железе

mataor

Насчет вибраций полностью согласен! Пока не отбалансировал пропеллеры по лопасти и середине - даже и не пробовал летать (моторки саннискаевские 2216 сами оч неплохо отбалансированы…)

П.С. програмкой не поделитесь тоже? Тоже интересно… кстати писали на делфи или С++?

VitaliyRU
mataor:

Насчет вибраций полностью согласен! Пока не отбалансировал пропеллеры по лопасти и середине - даже и не пробовал летать (моторки саннискаевские 2216 сами оч неплохо отбалансированы…)

Тем не менее попробуй закрепить мозг через губку для мыться посуды. Тааакиииие “чудеса” бывают:)
Жосткость рамы и т.д.
у меня вообще на среднемелкий такая ибо нефиг 😃

SergDoc
mataor:

Хм… такой вопрос - колбасит на маховие рц3 а на рц1-2 (вий 2.1) все норм?

маховием я ещё не занимался, а запускал альтернативный ПИД #elif PID_CONTROLLER == 2 в самом низу… блиин, а помоему он как раз и работает только в акро и горизонт, а я его в angle запускал?

интересно китайцы что без выходных пашут? уже плату(верхнюю) сделали - готовят к отправке…
смотрю изменения у них, теперь ещё один гербер файл пришлось делать отдельный (габариты платы) в орле это слой dimension…
Top Layer: pcbname.GTL - верхний слой с площадками
Bottom Layer: pcbname.GBL - нижний слой с площадками
Solder Mask Top: pcbname.GTS - слой маски припоя верхний
Solder Mask Bottom: pcbname.GBS - слой маски припоя нижний
Silk Top: pcbname.GTO
Silk Bottom: pcbname.GBO - ну эти два шелкография (надписи и т.д.)
Drill Drawing: pcbname.TXT - это все отверстия, в орле drill и vias, у товаришей не подписано почему-то в каком формате - EXELLON должен быть(как я собственно и делал)
Board Outline:pcbname.GML/GKO - вот собственно и новый файл - внешние границы платы
все гербер файлы в формате GERBER_RS274X кроме файла Drill он в формате EXELLON

alexTAG

SergDoc скажите какое качество и какие сроки изготовления плат у Китайцев, и если можно - дайте пожалуйста адрес для заказа.( можно в личку )

SergDoc

Я сегодня уже обнаглел - подлетал к своему окну, жене с детьми показывал, чего добился…

SergDoc

Ну что, первые тесты как-то прошли - так плату снимать с коптера не хочется 😦
что в итоге:

  1. датчики отрабатывают, все таймеры кроме восьмого работают (первый глюк)
  2. уарт + дма = переполнение буфера дма, подставлен костыль (второй глюк)
  3. удержание высоты аксель плюс баро - плавает в пределах полуметра, mahowik ткнул носом куда смотреть.
  4. PID новый не пошел, оставил старый - почитаю, может вообще изменю…
  5. usb - надо сделать обязательно.
  6. прибраться в уартах
  7. сделать запуск петли по прерыванию готовности с гир - может повлечь за собой кучу переделок т.к. цикл изменится (возможно придётся менять ИМУ)
  8. сонар зацепить и добавить в imu
  9. перепроверить все порты, дабы не нарваться на какой косяк, т.к. летающую версию готовил в спешек можно сказать
  10. изменить светодиодную индикацию (зачем четыре светодиода если работают только два)
    ну вот вроде всё из текущего, может чё и забыл… О, навести порядок в cli, а то не всё есть, что может понадобиться…
    так что до mahowii как до Стамбула 😃
SergDoc

второй уарт тоже подцепить на ДМА, переделать драйвер SPI ( SPI+DMA ) …

SergDoc

нарисовал микшер под свою раму, надо будет проверить:

static const motorMixer_t mixerQuadXSerg[] = {
    { 0.87f, -1.0f,  1.0f, -1.0f },          // REAR_R
    { 1.0f, -0.47f, -1.32f,  0.75f },        // FRONT_R
    { 0.87f,  1.0f,  1.0f,  1.0f },          // REAR_L
    { 1.0f,  0.47f, -1.32f, -0.75f },        // FRONT_L
};
SergDoc

чёт опять туплю, это ссылки на адреса памяти?

#define U_ID_0 (*(uint32_t*)0x1FFFF7E8)
#define U_ID_1 (*(uint32_t*)0x1FFFF7EC)
#define U_ID_2 (*(uint32_t*)0x1FFFF7F0)

надо свои прописать, дабы ID писала, а не ffffff
вот где оно кроется если кому интересно:

// Chip Unique ID on F4xx
#define U_ID_0 (*(uint32_t*)0x1FFF7A10)
#define U_ID_1 (*(uint32_t*)0x1FFF7A14)
#define U_ID_2 (*(uint32_t*)0x1FFF7A18)
oleg70
SergDoc:

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

Огласите (если не секрет) какие общие мысли в этом плане по реализации…
Я тоже сейчас этим занят, пока нет стройной идеи как в реальном времени синхронизировать прерывания от гиры и акселя+маг, “тычу” осциллографом на ноги INT, меняю режимы… (думаю что задачка не из легких, но интересная)
Во всяком случае понятно почему особо ни кто это не делает-, нужно точно высчитывать время запроса/чтения и т.д.

SergDoc

ну вот петля:

currentTime = micros();
    if (mcfg.looptime == 0 || (int32_t)(currentTime - loopTime) >= 0) {
        loopTime = currentTime + mcfg.looptime;


        computeIMU();
        // Measure loop rate just afer reading the sensors
        currentTime = micros();
        cycleTime = (int32_t)(currentTime - previousTime);
        previousTime = currentTime;
#ifdef MPU6000_DMP
        mpu6000DmpLoop();
#endif


#ifdef MAG
        if (sensors(SENSOR_MAG)) {
            if (abs(rcCommand[YAW]) < 70 && f.MAG_MODE) {
                int16_t dif = heading - magHold;
                if (dif <= -180)
                    dif += 360;
                if (dif >= +180)
                    dif -= 360;
                if (f.SMALL_ANGLES_25)
                    rcCommand[YAW] -= dif * cfg.P8[PIDMAG] / 30;    // 18 deg
            } else
                magHold = heading;
        }
#endif


#ifdef BARO
        if (sensors(SENSOR_BARO)) {
            if (f.BARO_MODE) {
                static uint8_t isAltHoldChanged = 0;
                static int16_t AltHoldCorr = 0;
                if (cfg.alt_hold_fast_change) {
                    // rapid alt changes
                    if (abs(rcCommand[THROTTLE] - initialThrottleHold) > cfg.alt_hold_throttle_neutral) {
                        errorAltitudeI = 0;
                        isAltHoldChanged = 1;
                        rcCommand[THROTTLE] += (rcCommand[THROTTLE] > initialThrottleHold) ? -cfg.alt_hold_throttle_neutral : cfg.alt_hold_throttle_neutral;
                    } else {
                        if (isAltHoldChanged) {
                            AltHold = EstAlt;
                            isAltHoldChanged = 0;
                        }
                        rcCommand[THROTTLE] = initialThrottleHold + BaroPID;
                    }
                } else {
                    // slow alt changes for apfags
                    if (abs(rcCommand[THROTTLE] - initialThrottleHold) > cfg.alt_hold_throttle_neutral) {
                        // Slowly increase/decrease AltHold proportional to stick movement ( +100 throttle gives ~ +50 cm in 1 second with cycle time about 3-4ms)
                        AltHoldCorr += rcCommand[THROTTLE] - initialThrottleHold;
                        if (abs(AltHoldCorr) > 500) {
                            AltHold += AltHoldCorr / 500;
                            AltHoldCorr %= 500;
                        }
                        errorAltitudeI = 0;
                        isAltHoldChanged = 1;
                    } else if (isAltHoldChanged) {
                        AltHold = EstAlt;
                        isAltHoldChanged = 0;
                    }
                    rcCommand[THROTTLE] = initialThrottleHold + BaroPID;
                }
            }
        }
#endif


        if (sensors(SENSOR_GPS)) {
            if ((f.GPS_HOME_MODE || f.GPS_HOLD_MODE) && f.GPS_FIX_HOME) {
                float sin_yaw_y = sinf(heading * 0.0174532925f);
                float cos_yaw_x = cosf(heading * 0.0174532925f);
                if (cfg.nav_slew_rate) {
                    nav_rated[LON] += constrain(wrap_18000(nav[LON] - nav_rated[LON]), -cfg.nav_slew_rate, cfg.nav_slew_rate); // TODO check this on uint8
                    nav_rated[LAT] += constrain(wrap_18000(nav[LAT] - nav_rated[LAT]), -cfg.nav_slew_rate, cfg.nav_slew_rate);
                    GPS_angle[ROLL] = (nav_rated[LON] * cos_yaw_x - nav_rated[LAT] * sin_yaw_y) / 10;
                    GPS_angle[PITCH] = (nav_rated[LON] * sin_yaw_y + nav_rated[LAT] * cos_yaw_x) / 10;
                } else {
                    GPS_angle[ROLL] = (nav[LON] * cos_yaw_x - nav[LAT] * sin_yaw_y) / 10;
                    GPS_angle[PITCH] = (nav[LON] * sin_yaw_y + nav[LAT] * cos_yaw_x) / 10;
                }
            }
        }


       // PID - note this is function pointer set by setPIDController()
         pid_controller();


        mixTable();
        writeServos();
        writeMotors();
    }
}

в computeIMU(); за одно считываются данные с датчиков - это в imu.c
так вот вместо:

currentTime = micros();
    if (mcfg.looptime == 0 || (int32_t)(currentTime - loopTime) >= 0) {
        loopTime = currentTime + mcfg.looptime;

сделать запуск по прерыванию от гир, (это я так думаю) ну до этого ещё далеко ибо вожусь в 8-м таймером, не хочет запускаться…
в ардупилоте запуск цикла построен на прерывании от гир, если не ошибаюсь… да и у rual тоже…
но тут сразу поплывут фильтры, и PID надо добивать уже до времени цикла…

oleg70

Пока имею следующее: прерывания 250 (Гц) =0,004 (Сек) беру с DRDY LSM, при 72 Мгц на борту, в обработчике за половину периода (~0,002 сек.) успеваю три раза прочитать и усреднить гироскоп, прочитать 1 раз акс/маг, выполнить алгоритм ИМУ и даже можно ПИД впихнуть… Вроде все “красиво” и время на другие процессы остается но:
Не нравится - что нет проверки готовности гир при чтении (и похоже что косяки из за этого в данных вылазят)…
DMA к гире подцепил, но та же проблема: идут сбои… как проверить готовность?

SergDoc

готовность только по прерыванию, ибо если читать регистр готовности - пройдёт вечность…

oleg70
SergDoc:

вот петля:

Здесь везде привязка к currentTime = micros();, а мне хочется от нее избавиться

SergDoc:

готовность только по прерыванию

Вот здесь то и самое интересное… Например у LSM сигнал DRDY не зависит от установленного DATArate и всегда 250 Гц (?), а L3GD20 просто выставляет “1” на ноге когда можно прочитать данные и ждет пока их не прочитаешь (?)
Тут есть над чем поразмыслить…

rual
SergDoc:

чёт опять туплю, это ссылки на адреса памяти?

Да, там расположен уникальный номер проца. Для Ф4 надоть уточнить адрес.
Кста, это при работе УСБ активно используется при создании соединения. Разные дискавери у меня на разные виртуальные компорты садятся.

oleg70:

Например у LSM сигнал DRDY не зависит от установленного DATArate и всегда 250 Гц (?),

Нет, соответствует выставленной частоте отсчётов.

oleg70:

а L3GD20 просто выставляет “1” на ноге когда можно прочитать данные и ждет пока их не прочитаешь (?)

Да, после чтения снимает до очередной готовности (так все СТшные датчики работают и ХМЦ5883 тожа).

SergDoc
rual:

Да, там расположен уникальный номер проца. Для Ф4 надоть уточнить адрес.

я уже выковырял 😃 rcopen.com/forum/f134/topic224458/2240
на картинках что выше Unique devise ID в правом нижнем углу 😃

SergDoc

Может кто найдёт ошибку github.com/SergDoc/…/drv_pwm.c
восьмой таймер не запускается, первый такой-же, на нём у меня моторы - работает, а восьмой хоть застрелись…
тактирование таймеров и портов включено отдельно

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 | RCC_APB1Periph_TIM5 | RCC_APB1Periph_I2C2 | RCC_APB1Periph_SPI2 | RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3 , ENABLE);
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1 | RCC_APB2Periph_TIM8 | RCC_APB2Periph_ADC1 | RCC_APB2Periph_USART1 | RCC_APB2Periph_SPI1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_DMA2, ENABLE);
    RCC_ClearFlag();
SergDoc

затык у меня наверно здесь:

 setup = hardwareMaps[i];

    for (i = 0; i < MAX_PORTS; i++) {
        uint8_t port = setup[i] & 0x0F;
        uint8_t mask = setup[i] & 0xF0;

        if (setup[i] == 0xFF) // terminator
            break;

как этого избежать?

если так?

 setup = hardwareMaps[i];

    for (i = 0; i < MAX_PORTS; i++) {
        uint16_t port = setup[i] & 0x00FF;
        uint16_t mask = setup[i] & 0xFF00;

        if (setup[i] == 0xFFFF) // terminator
            break;

запустил все таймеры 😃