STM32F4 + MG995 = как подобрать ШИМ?

ARM7, ARM9, ARM11 etc.

STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 03 мар 2013, 20:32

Ребята помогите с MG995, как подобрать алгоритм поворота угла для MG995.
Не как не могу заставить её повернуться на 45, 60, 90, 180 градусов
Везде по разному... А нужно как на картинке:
как на картинке:
bdb7ffd975.jpg





Код: Выделить всё
#include <stdio.h>
#include <stm32f4xx.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_tim.h>

#include <stm32f4xx_exti.h>
#include <misc.h>
#include <stm32f4xx_syscfg.h>


volatile int servo_angle[4] = { 0, 0, 0, 0 }; // +/- 90 degrees, use floats for fractional

int main(void)
{   SystemInit(); // 25 MHz



// Servo min(1ms) = 1580
// Servo max(2ms) = 3160
//TIM_SetCompare1(TIM1, 1580);    // 1580 = 1.0ms
//TIM_SetCompare1(TIM1, 2370);    // 2370 = 1.5ms
//TIM_SetCompare1(TIM1, 3160);    // 3160 = 2.0ms



   GPIO_InitTypeDef GPIO_InitStructure;
   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
   TIM_OCInitTypeDef TIM_OCInitStructure;

   // TIM1 clock enable
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

   // GPIOE clock enable
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

   // TIM1 channel 2 pin (PE.9) configuration
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_Init(GPIOE, &GPIO_InitStructure);

   // Connect TIM pins to AF2
   GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1);

   TIM_TimeBaseStructInit (&TIM_TimeBaseStructure);

   //TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/5000000; // pers 33.6
   //TIM_TimeBaseStructure.TIM_Period = 31600; // 20ms for servo period

   //TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock / 100000 - 1;
   //TIM_TimeBaseStructure.TIM_Period = 2000;

   TIM_TimeBaseStructure.TIM_Prescaler = 24 - 1;  // 24 MHz / 24 = 1 MHz
    TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20 ms)

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseInit(TIM1 , &TIM_TimeBaseStructure);


   // PWM1 Mode configuration: Channel1
   // Edge -aligned; not single pulse mode
   TIM_OCStructInit (& TIM_OCInitStructure);
   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
   TIM_OCInitStructure.TIM_Pulse = 600 + 900;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

   TIM_OC1Init(TIM1 , &TIM_OCInitStructure);

   TIM_BDTRInitTypeDef bdtr;
   TIM_BDTRStructInit(&bdtr);
   bdtr.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
   TIM_BDTRConfig(TIM1, &bdtr);


   // Enable Timer Interrupt and Timer
   TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); //
   TIM_Cmd(TIM1 , ENABLE);




   //TIM_SetCompare1(TIM1, 1500);    // 1580 = 1.0ms = 0
   //delayMS(1*100);
   //TIM_SetCompare1(TIM1, 2160);    // 2370 = 1.5ms = 90
   //delayMS(1*100);
   //TIM_SetCompare1(TIM1, 3460);    // 3160 = 2.0ms = 180
   //delayMS(1*100);



     uint8_t i;
       for (i=0;i<=90;i++)
       {
         //delayMS(100);
         set_pos(i);
       }



   while (1)
   {
   }

   return 0;
}



#define SERVO_180 3160
#define SERVO_0 1500

// Функция устанавливает позицию вала (в градусах)
void set_pos(uint8_t pos)
{
  uint32_t tmp=(SERVO_180 - SERVO_0) / 90 ;
  uint32_t tmp2 = SERVO_0 + tmp * pos;
  TIM_SetCompare1(TIM1, tmp2);
}


void delayMS(uint32_t ms)
{
    ms *= 3360;
    while(ms--)
    {
        __NOP();
    }
}


// Функция задержки
void delay(void)
{
  volatile uint32_t i;
  for (i=1; i != 0xFFFF; i++);
}
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 03 мар 2013, 20:36

А в чем проблема? Ошибка на градус-два или вообще не работает?
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 03 мар 2013, 21:14

Работает, ошибка в градусах. Я уже разные алгоритмы перепробовал... но не один не дает точных (хотя бы с погрешностями) результаты.
К сожалению у меня нет осциллографа по этому точно не знаю как проходят импульсы.
Мне нужна функция, которой я буду задавать градусы а она будет крутить привод на необходимый угол. Как на картинке.

Сейчас же, я не знаю какие значения подобрать для TIM_SetCompare1(TIM1, tmp);
Как настроить таймер, есть примеры (ниже) но какой из нужен?
//TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/5000000; // pers 33.6
//TIM_TimeBaseStructure.TIM_Period = 31600; // 20ms for servo period
//TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock / 100000 - 1;
//TIM_TimeBaseStructure.TIM_Period = 2000;
TIM_TimeBaseStructure.TIM_Prescaler = 24 - 1; // 24 MHz / 24 = 1 MHz
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20 ms)

Добавлено спустя 1 минуту 50 секунд:
задаю 1500, он у меня крутится на 25 градусов, 2000 - на 45 градусов
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 03 мар 2013, 21:59

надо выяснить, на какой частоте шарашит камень. возможно на максимуме 168МГц

тебе надо сделать так, чтобы 16 битный таймер с максимальным разрешением работал с периодом 20 мс

я обычно считаю так:
20мс = 60000 (немного с запасом, 60 тысяч понятно откуда беруться?)
т.е. один тик должен быть 20000мкс/60000 ~= 0.33 мкс.
Тогда прескейлер должен быть 168*0.33 ~=56.

Уточняем, с прескейлером 56 частота клока таймера будет 3МГц, а длительность тика одного ~0.33мкс
Для того, чтобы получить период 20мс, устанавливаем период равным 20000/0.33 (или 3000000/50) = 60000
Теперь значения пульса у тебя будут от 3000 (1мс) до 6000(2мс)

Так понятно?
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 04 мар 2013, 06:03

Я посмотрел в даташит, там указано что таймер работает на 168, а ещё интерфейс счетчик работает на 84. А по другому можно узнать на какой частоте?

Откуда берутся 60 тыс? =)

Чу чуть понял, получается что бы мне провернуть на 90 градусов, я должен подать импульс длиной 4500?

А между сервами есть разница? т.е. если я скажем имею три разных серв (от разных производителей), они себя будут по разному ввести? т. е.
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 04 мар 2013, 06:57

Ничего ты не понял
Таймер 16-ти битный. т.е. он может досчитать до 65535, а потом переполнится (8-ми битный таймер, например, может досчитать только до 255, потом переполнение и снова с нуля начинает считать)
Тебе надо по-максимуму использовать высокое разрешение таймера, соответственно надо, чтобы за 20мс в идеале натикало 65535 тиков. Но предделители дробными не бывают, бывают только целыми, поэтому и надо взять достаточно большое число в диапазоне 0-65535, но чтобы предделитель был целым.
Пример: через 20мс значение таймера будет:
С предделителем 56: 20000*168/56 = 60000
С предделителем 55: 20000*168/55 = 61090
С предделителем 52: 64615
С предделителем 51: 65882 (а это уже больше, чем 65535, поэтому таймер никогда не сможет достигнуть этого значения)
Т.е. максимальный прескейлер, который ты можешь выбрать - 52 (ну, т.е. минимальный). Чем больше будет прескейлер, тем меньше тиков натикает за 20мс и тем меньше будет разрешение твоего таймера.
Это откуда беруться 60 тыс.

Дальше, на какой частоте работает таймер. Запускаешь отладку и смотришь значение переменной SystemCoreClock. Это и есть частота, на которой шарашит камень. Если она не 168, снова проводишь расчеты. Но это частота главной шины. Таймер сидит на какой-нибудь APB1(не помню). Эта другая шина может работать на более низкой частоте. Посмотреть, установлен ли делитель на эту шину. Хуже того, частота таймера может также делиться (т.е. для таймера устанавливается и делитель частоты, и предделитель). Тебе надо проверить все эти настройки, чтобы понять, на какой частоте шарашит таймер. После этого, если у тебя нет осцилла, я бы повесил на ногу светодиод, настроил переполнение таймера на (как мне кажется) 1с и проверил, что светодиод включается/выключается ровно раз в секунду. Если эжто происходит чаще/реже, какой-то из предделителей частоты пропущен.
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 04 мар 2013, 16:50

Установил вот эти параметры, вроде лучше стало... Но градусах все равно ошибки ~10-20
TIM_TimeBaseStructure.TIM_Prescaler = 56;
TIM_TimeBaseStructure.TIM_Period = 60000;

Вот так кручу:
TIM_SetCompare1(TIM1, 1000); // 0 результат 0 градусов
delayMS(1*1000);
TIM_SetCompare1(TIM1, 1250); // 45 результат 15
delayMS(1*1000);
TIM_SetCompare1(TIM1, 1500); // 90 результат 25
delayMS(1*1000);
TIM_SetCompare1(TIM1, 1750); // 120 результат 45
delayMS(1*1000);
TIM_SetCompare1(TIM1, 2000); // 180 результат 60
delayMS(1*1000);


Как вернуть серву на начальную позицию?
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение elmot » 04 мар 2013, 18:00

ошибка 5 град, там где 90
Какие претензии?
Что есть начальная позиция? снова на устовный 0? тогда:
TIM_SetCompare1(TIM1, 1000); // 0 результат 0 градусов
Аватара пользователя
elmot
 
Сообщения: 5691
Зарегистрирован: 10 ноя 2011, 12:02
Откуда: Turku, Finland
Skype: elmot73
прог. языки: Java и все-все=все
ФИО: Илья

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 04 мар 2013, 18:21

Почему ошибка?
Претензий не каких.
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 04 мар 2013, 22:33

Askar, a что такое '1000'?
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 05 мар 2013, 05:51

1000 ms. =)
Ребята у кого есть под рукой STM32F4, СЕРВА(MG995) и осциллограф...
Помогите... Кому не лень накидать несколько строчек коду...
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Angel71 » 05 мар 2013, 11:33

пока даже прошивку заливать бессмысленно. никто не обратил внимания, что тс считает за крайние положения 1000 и 2000?
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 05 мар 2013, 12:12

На картинке указано 1000 и 2000
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Angel71 » 05 мар 2013, 12:34

т.е. увидили в начеле статьи фотку сервы с наклейкой "mg995" и подумали "о! это про мою серву"? железная логика.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 05 мар 2013, 13:23

Неееееееее, просто прочитал пару десяток статей, и везде говорилось что стандарт 1000-2000.
Прошелся пару дней назад по данному форуму, заметил что у тебя тоже самая серва и боле того, тат же самый чип.
=)
По твоему сколько "мс" для левого и правого "мс"?

Если есть чем помочь,буду благодпрен>
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

След.

Вернуться в ARM

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6