Перейти к содержанию
    

Контролер для 3-х двигателей.

А проблема в чем? В том что 16-битный таймер вылетит в оверфлоу не закончив хода двигателя? Так там прескейлер можно задать.

Вы попробуйте решить задачу для одного двигателя одним контроллером. Тогда и ясность появится.

А то сейчас не имея внятной постановки задачи, можно много чего нафантазировать.

 

Возможно проще будет поставить три простых контроллера, чем искать один супернавороченный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне нужно сделать драйвер для 3-х двигателей. Двигатели обычные DC Motors 24V. Двигатели имеют энкодеры для отслеживания позиции.

Хотелось чтоб энкодеры были апаратные. Обычно это делается на таймерах.

Вот задумался какой контроллер выбрать. PWM+Encoders требуют таймера. К тому же на мои нужды нужно еще 3 таймера.

У ST вроде нет контролеров заточенных под motion. У TI есть но что то не хочется связываться с TI. К тому же 3 двигателя. Есть контроллеры под такую задачу?

Основная проблема - аппаратно обработать 3 энкодера. На атмеловских AVRках я пользовался внешними интераптами но это, как мне кажется, не очень хороший способ.

так не проще сделать это на плис

программируемый PWM

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity pwm_prog is
generic(
  N                     : integer := 8);      -- number of bit of PWM counter
port (
  i_clk                       : in  std_logic;
  i_rstb                      : in  std_logic;
  i_sync_reset                : in  std_logic;
  i_pwm_module                : in  std_logic_vector(N-1 downto 0);  -- PWM Freq  = clock freq/ (i_pwm_module+1); max value = 2^N-1
  i_pwm_width                 : in  std_logic_vector(N-1 downto 0);  -- PWM width = (others=>0)=> OFF; i_pwm_module => MAX ON 
  o_pwm                       : out std_logic);
end pwm_prog;

architecture rtl of pwm_prog is

signal r_max_count                           : unsigned(N-1 downto 0);
signal r_pwm_counter                         : unsigned(N-1 downto 0);
signal r_pwm_width                           : unsigned(N-1 downto 0);
signal w_tc_pwm_counter                      : std_logic;


begin

w_tc_pwm_counter  <= '0' when(r_pwm_counter<r_max_count) else '1';  -- use to strobe new word
--------------------------------------------------------------------

p_state_out : process(i_clk,i_rstb)
begin
  if(i_rstb='0') then
    r_max_count     <= (others=>'0');
    r_pwm_width     <= (others=>'0');
    r_pwm_counter   <= (others=>'0');
    o_pwm           <= '0';
  elsif(rising_edge(i_clk)) then
    r_max_count     <= unsigned(i_pwm_module);
    if(i_sync_reset='1') then
      r_pwm_width     <= unsigned(i_pwm_width);
      r_pwm_counter   <= to_unsigned(0,N);
      o_pwm           <= '0';
    else
      if(r_pwm_counter=0) and (r_pwm_width/=r_max_count) then
        o_pwm           <= '0';
      elsif(r_pwm_counter<=r_pwm_width) then
        o_pwm           <= '1';
      else
        o_pwm           <= '0';
      end if;
      
      if(w_tc_pwm_counter='1') then
        r_pwm_width      <= unsigned(i_pwm_width);
      end if;
      
      if(r_pwm_counter=r_max_count) then
        r_pwm_counter   <= to_unsigned(0,N);
      else
        r_pwm_counter   <= r_pwm_counter + 1;
      end if;
    end if;
  end if;
end process p_state_out;

end rtl;

 

квадратурный декодер например (по ссылке можно купить для "тренировки") (реализация учитывает направление вращения):

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity QuadratureDecoder is
    Port ( QuadA : in  STD_LOGIC;
           QuadB : in  STD_LOGIC;
           Clk : in  STD_LOGIC;
           Position : out  STD_LOGIC_VECTOR (7 downto 0));
end QuadratureDecoder;

architecture Behavioral of QuadratureDecoder is

signal QuadA_Delayed: unsigned(2 downto 0) := "000";
signal QuadB_Delayed: unsigned(2 downto 0) := "000";

signal Count_Enable: STD_LOGIC;
signal Count_Direction: STD_LOGIC;

signal Count: unsigned(7 downto 0) := "00000000";

begin

process (Clk)
begin
    if Clk='1' and Clk'event then
        QuadA_Delayed <= (QuadA_Delayed(1), QuadA_Delayed(0), QuadA);
        QuadB_Delayed <= (QuadB_Delayed(1), QuadB_Delayed(0), QuadB);
        if Count_Enable='1' then
            if Count_Direction='1' then
                Count <= Count + 1;
                Position <= conv_std_logic_vector(Count, 8);
            else
                Count <= Count - 1;
                Position <= conv_std_logic_vector(Count, 8);
            end if;
        end if;
    end if;
end process;

Count_Enable <= QuadA_Delayed(1) xor QuadA_Delayed(2) xor QuadB_Delayed(1)
                xor QuadB_Delayed(2);
Count_Direction <= QuadA_Delayed(1) xor QuadB_Delayed(2);

end Behavioral;

или энкодер в плис это обычный счетчик импульсов...

 

Далее добавляем двупортовую память в которую будем писать данные для выполнения и конфигурирования PWM

В первый порт пишем принятые данные по UART (вы писали), я предлагаю SPI (не требуется синхронизации приемника и передатчика)

С второго порта читаем данные и выдаем на PWM - результат контролируем с помощью квадратурного декодера (в реализации обычный компаратор)

Вместо двупортовой памяти можно взять двуклоковое фифо

 

Как в плис сделать из одного модуля три думаю догадаетесь :)

Если хотите внешний MCU то предлагаю сделать соединение с ПЛИС с помощью external memory interfacе, т.е чтобы MCU видело ПЛИС как свою память ОЗУ + пару пинов для организации обмена прерываниями(окончанием работы(выполнения команды и др)) тогда в ПЛИС делаете двойной буфер и будет отличное решение Возможно не понадобится делать протокол обмена (парсер как Вы это назвали)

Как то так...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно проще будет поставить три простых контроллера, чем искать один супернавороченный.

Вот это, кстати, верно замечено. Я и сам предыдущей железяке (5 шаговиков, куча концевиков и Холлов, затвор на TLE5205 с контролем замыкания/обрыва, 8 платиновых термодатчиков, 8 DS18S20…) делал модуль управления на одном МК. Замучился, но работает. Но кабель получился жирным! Правда, там все механизмы внутри криостата — МК и силовые ключи туда не засунуть.

Но вот новые железки, которые при Н.У. работают, собираюсь все-таки модульными делать: проще по 1МК (+драйвер[ы]) на 1-2 ШД с концевиками сделать и связать их CAN-шиной, нежели городить жуткий жгут проводов и огромную плату-контроллер!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот это, кстати, верно замечено. Я и сам предыдущей железяке (5 шаговиков, куча концевиков и Холлов, затвор на TLE5205 с контролем замыкания/обрыва, 8 платиновых термодатчиков, 8 DS18S20…) делал модуль управления на одном МК. Замучился, но работает. Но кабель получился жирным! Правда, там все механизмы внутри криостата — МК и силовые ключи туда не засунуть.

Но вот новые железки, которые при Н.У. работают, собираюсь все-таки модульными делать: проще по 1МК (+драйвер[ы]) на 1-2 ШД с концевиками сделать и связать их CAN-шиной, нежели городить жуткий жгут проводов и огромную плату-контроллер!

Возможно я чего то не понимаю, зачем брать N микропроцессоров(соответственно плат) и делать сложный протокол обмена между ними и думать про псевдосинхронизацию процессов между ними. Почему не одна ПЛИС и внутренним или внешним одним MCU?

ПЛИС производит считывание с датчиков и управляет моторами. MCU производит управление ПЛИС и связь с внешним миром

Сейчас SoC относительно не дорогие

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

зачем брать N микропроцессоров(соответственно плат)

N микропроцессоров всё ещё гораздо дешевле, чем 1 fpga, проще, потому что абсолютно одинаковые, и могут быть пространственно разнесены, потому что на разных платах, и маленькие одинаковые платы дешевле в мелкой серии, даже при равной площади, чем одна большая

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно я чего то не понимаю, зачем брать N микропроцессоров(соответственно плат) и делать сложный протокол обмена между ними и думать про псевдосинхронизацию процессов между ними. Почему не одна ПЛИС и внутренним или внешним одним MCU?

Вы почитайте другие темы ТС - у него не хватает желания или знаний или еще чего разобраться с простейшими вещами, а вы ему ПЛИС предлагаете....

 

С другой стороны, откуда взялось несколько плат? Надо просто сделать одну плату на 3 микроконтроллера. Все контроллеры будут иметь одинаковую программу, а управляющие сигналы запараллелить(хотя если там будет протокол с ответами, то сложнее)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно я чего то не понимаю, зачем брать N микропроцессоров(соответственно плат) и делать сложный протокол обмена между ними и думать про псевдосинхронизацию процессов между ними. Почему не одна ПЛИС и внутренним или внешним одним MCU?

1. Цена: 20-ногие STM8S003 стоят рублей 15 за штучку, 32-ногие STM32F103 — не больше сотни.

2. Простота: ПЛИСину запрограммировать намного сложней. Я, например, ни разу не сталкивался с ПЛИС, и даже не представляю, как в линухе с ними работать!

3. Аппаратный CAN позволяет сильно упростить низкоуровневую составляющую протокола.

4. И самое главное — намного меньше проводов! Если двигатели разнесены по закоулкам прибора, а места там — хоть отбавляй, то куда как красивее и проще будет сделать распределенную систему. К тому же, ее будет проще чинить: легче заменить один выгоревший блок и в офлайне перепаять выгоревшую деталь, нежели выдирать целиком плату управления всем. Если же и в случае централизованной системы делать такой ЗИП, чтобы просто поменять плату, то будет намного дороже и сложней в изготовлении, чем в распределенном варианте.

 

И да, для совсем уж разовых штучек можно модуль МК делать съемным — берем на ибее "девборды" на STM32F103 по ~120р за штучку — вуаля! Не нужно паять МК (особенно это ценят люди с плохим зрением/моторикой) с обвязкой. Если ток небольшой, силовые ключи без радиаторов поместятся на плате прямо под МК — получится компактный "пирог" суммарной стоимостью максимум рублей в 500.

Изменено пользователем Эдди

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так не проще сделать это на плис

да я бы с превеликим удовольствием сделал на FPGA. У меня все модули уже реализованы на FPGA. Но я столкнулся с проблемой которую озвучил в теме - Строковый парсер на VHDL.

Это единственная проблема - сопряжение с РС (пользователем).

 

ставить CPU+FPGA это оверкил.

 

ставить несколько камней - не вижу смысла. STM32F3 имеет достаточно таймеров для 3-х энкодеров и 3-х PWM.

Хотя я думал сделать модулярно - один аксис мэнэджер и модули отдельно. Есть система с 2 моторами - поставил 2 модуля, с 3 - поставил 3 модуля. Но я отказался от этой затеи. Слишком громоздко.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для надежности как раз и применяют два STM32 - один занимается математикой и управлением, второй- управляет ШИМ и меряет токи по фазе. На начальной уровне так проще и надежнее. Запихнуть три канала по двигателям в один камень сложновато. Сами STM-ы максимум два двигателя на один контроллер сажали, но там было трехфазное векторное управление. Хотя по слухам были проблемы при большой разности скоростей или режимов двигателей.

Для движков постоянного тока вообще самых мелких STM достаточно, главное чтобы ног на управление ШИМом и энкодером хватило. Ну и система защиты ( датчики тока, температуры, напряжения питания итд).

Был еще вариант с обслуживанием аналоговых синус-косинусных линейных датчиков положения (оптических линеек) за счет АЦП STM32.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А ведь по ним придется принемать решения(т.е. обрабатывать их) вне зависимости от того будет ли там у вас таймер или не таймер....

Около 170кГц? Ну и что? А нужно-ли принимать решение на каждом импульсе от энкодера? :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А нужно-ли принимать решение на каждом импульсе от энкодера?
Ну учитывая, что по условию задачи энкодеры используются для отслеживания именно положения, то я думаю в том или ином виде обработать каждый импульс придется обязательно!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну учитывая, что по условию задачи энкодеры используются для отслеживания именно положения, то я думаю в том или ином виде обработать каждый импульс придется обязательно!

Что-то я не понимаю - зачем для определения положения ротора нужно на каждый импульс что-то делать?? :wacko:

Большое кол-во импульсов - это только для увеличения разрешения по углу. как я понимаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Большое кол-во импульсов - это только для увеличения разрешения по углу. как я понимаю.
Правильно. Но если начать их пропускать то о каком отслеживании положения тогда идет речь? Ну т.е. как минимум нужно крутить в программе какой-нибудь счётчик угла....

 

Именно поэтому я ТСу давно говорил, что исходя из требуемой точности нужно выбрать энкодер.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Правильно. Но если начать их пропускать то о каком отслеживании положения тогда идет речь? Ну т.е. как минимум нужно крутить в программе какой-нибудь счётчик угла....

А почему пропускать-то? Эти импульсы учитываются аппаратным счётчиком, процессор для этого не нужен.

Процессор только в какой-то момент времени считывает накопленное значение из счётчика. Вот такие чтения, как я понимаю, совсем не нужно делать каждый импульс. Таких чтений наверное всего нужно одно или несколько на один оборот вала.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Энкодер с аппаратным таймером считает все импульсы. Таймер генерит прерывание при переполнении и тогда программно учитываются старшие разряды счетчика положений. Другой таймер генерит прерывания с частотой петли ПИД по положения. Вот этот обработчик прерывания и берет текущее положение из энкодера и его старших битов и рассчитывает ошибку по положению. Вообще то в нормальном сервоприводе еще как минимум две петли ПИД будут- по току и по скорости. И петля по положению- самая медленная.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...