Arduino драйвер мотора для робота

a5021
Offline
Зарегистрирован: 07.07.2013

jeka_tm пишет:
ширину  платы увеличил до 16.87мм. выводы для моторов вывел вбок

Какие-то ограничения на размеры вообще существуют? У меня получается 24мм на 17мм. Правда я развел там все, что на мой взгляд нужно: резисторы в затворах и измерительная схема.

UPD. Вобщем, пока суд да дело, собрал я его на скорую руку и протестировал.

Выглядит страшненько, но испытания прошли успешно. Управлял этим делом ардуино про мини, который слал ppm в виде импульсов случайной длительности от 1000 до 2000 миллисекунд через случайный промежуток времени от 0.5 до 4 секунд. Драйвер отработал час без всяких проблем. Питание моторной части -- 12 вольт, МК получал питание от программатора (st-link). В качестве нагрузки использовался мотор каретки C9058-60071 от хьюллетовского МФУ.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

В целом замечательно, плюсую.

1. У вас там нет "залипа" на левом полумосту между 2 и 3 ногой? А то выглядит сильно похоже.

2. Код .. планируете выкладывать? А то я уже собрался заказывать эти STM08.. :)

3. Или так, могу выступить Заказчиком первых 4-8 плат, в зависимости от цены с доставкой.. (самому паять практика показала, что все-таки руки - кривоваты) :)

4. Каков размер платы? Интересен размер не более 20х25мм

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

a5021
Offline
Зарегистрирован: 07.07.2013

Arhat109-2 пишет:
1. У вас там нет "залипа" на левом полумосту между 2 и 3 ногой? А то выглядит сильно похоже.

Нет, это бликует под вспышкой флюс, остающийся после оплавления паяльной пасты. Совершенно гадкая, надо сказать, субстанция. По консистенции похож на воск, только немного тверже и прозрачный. Блестит. Не растворяется ни одним из известных мне растворителей. При попытке оттереть спиртом, становится матовым и место пайки приобретает совершенно отстойный вид.

Вторая нога -- это затвор нижнего мосфета, а третья подключается к +12в. Если бы там было замыкание, то первое же открытие верхнего мосфета полумоста привело бы к "сквозняку", который скорее всего спалил бы оба мосфета полумоста, т.к. нижний в таком случае был бы открыт всегда.

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

Цитата:
2. Код .. планируете выкладывать? А то я уже собрался заказывать эти STM08..

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

Цитата:
3. Или так, могу выступить Заказчиком первых 4-8 плат, в зависимости от цены с доставкой.. (самому паять практика показала, что все-таки руки - кривоваты) :)

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

Цитата:
4. Каков размер платы? Интересен размер не более 20х25мм

Я размер выше указывал -- 17х24мм.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

О, это даже лучше чем я ожидал. 17х24 -- не просто хорошо, а вовсе и замечательно!

На радиокоте или где-то ещё, если решусь, то закажу сам, но все равно - спасибо. Если насчет "у меня работает, но ничего не дам" - камень в мой огород, то это тоже мимо. Просто, я выкладываю что-то больше "по запросу", чем "просто так". Кинул затравку - есть интерес? Можно и выложить... а если оно никому не надо, то какой в этом смысел? :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

спаял плату. нужна прошивка

https://yadi.sk/i/H2wlKZxoyTRcT

a5021
Offline
Зарегистрирован: 07.07.2013

Имеет смысл глянуть схему, вдруг какие расхождения закрались.

 

В картинке "зашит" файл IAR-проекта. Чтобы достать его оттуда, надо кликнуть по картинке, после чего случится переход на postimage.org. Там нажать на картинку еще раз для увеличения. Раскрывшееся изображение сохранить на диск, и уже сохраненное изображение открыть с помощью WinRAR-а. Арихватор покажет содержимое проекта. Разархивировать это дело в любое подходящее место и открыть IAR-ом.

В прошивке на данный момент реализован минимальный функционал: МК "слушает" PPM вход и по пришествии оттуда импульса задает коэффициент заполнения для ШИМ-сигнала пропорционально ширине полученного импульса. Импульс короче 1500 микросекунд крутит мотор в одну сторону, длиннее, в другую. Максимальный коэфф. заполнения ШИМ-сигнала получается при длительностях PPM-импульса 1000мкс и 2000мкс. Импульсы короче 1000мкс и длиннее 2000мкс игнорируются.

Защитный интервал в районе 1500 мкс для попадания в режим "останов" пришлось сделать величиной в 40 микросекунд, т.ч. Arhat109-2 оказался почти прав. Связано это с тем, что однопроцентная точность задающего генератора STM8S дает ощутимое смещение и при измерении импульса 1500мкс с кварцованного ардуины, STM8S "видит" 1487мкс. Так что набросил по 20мкс вниз и вверх от 1500мкс, на всякий случай.

В последовательный порт выводится некоторая отладочная информация о том, что МК видит на входе PPM. Можно подлючиться туда терминалом через TTL-USB адаптер. Скорость порта 115200 бод. Что-то вроде такого там можно увидеть:

Заодно прикладываю проверочный скетч для "про мини", который генерирует управляющие импульсы случайным образом. Выход № 9 ардуины (PORTB1) следует соединить со входом PPM вышеприведенной схемы.

void setup() {

  // Input/Output Ports initialization
  // Port B initialization
  // Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=Out Bit0=In 
  DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (1<<DDB1) | (0<<DDB0);
  // State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=0 Bit0=T 
  PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);  

  // Timer/Counter 1 initialization
  // Clock source: System Clock
  // Clock value: 16000,000 kHz
  // Mode: Fast PWM top=ICR1
  // OC1A output: Inverted PWM
  // OC1B output: Disconnected
  // Noise Canceler: Off
  // Input Capture on Falling Edge
  // Timer Period: 2 ms
  // Output Pulse(s):
  // OC1A Period: 2 ms Width: 1,5 ms
  // Timer1 Overflow Interrupt: On
  // Input Capture Interrupt: Off
  // Compare A Match Interrupt: Off
  // Compare B Match Interrupt: Off
  TCCR1A=(1<<COM1A1) | (1<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (0<<WGM10);
  TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
  TCNT1H=0x00;
  TCNT1L=0x00;
  ICR1H=0x7C;
  ICR1L=0xFF;
  OCR1AH=0x1F;
  OCR1AL=0x40;
  OCR1BH=0x00;
  OCR1BL=0x00;

  // Timer/Counter 1 Interrupt(s) initialization
  TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (1<<TOIE1);
}

void loop() {

  uint16_t a = random(0, 16000);

  OCR1AH = (uint8_t)(a >> 8);
  OCR1AL = (uint8_t)(a & 0xFF);
  
  TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);

  delay(random(500, 4000));

}

ISR(TIMER1_OVF_vect) {
  TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
  TCNT1H=0x00;
  TCNT1L=0x00;
}

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ошибки какие то выдает иар. я в нем очень мало работал. так что хз что делать

Building configuration: Project - Debug 
Updating build tree... 
main.c  
[Og007]: Assembler list file generation not allowed in this version of the compiler 
Error while running C/C++ Compiler 
 
Total number of errors: 1 
Total number of warnings: 0 

 

a5021
Offline
Зарегистрирован: 07.07.2013

Меню -> Project -> Options -> C/C++ Compiler -> Вкладка "List" -- поснимать все галки.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

спасибо. скомпилировалось) надо провода припаять. но это позже как ребенок уснет

a5021
Offline
Зарегистрирован: 07.07.2013

Еще момент: первое испытание имеет смысл производить при подаче на моторную часть какого-нибудь хилого напряжения, чтобы не спалить мосфеты, если что-то пойтет не так. Я использовал те же 5 вольт с программатора, от которых питался МК. Если по какой-то причине случится "сквозняк" или какой другой коротыш, то сработает защита по питанию на USB и ничего страшного не произойдет. Для того, чтобы увидеть, как мотор дергается, хватит и этих хилых пяти вольт.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

кстати вопрос. контроль тока реализован? какое то ограничение задано? i2c работает? uart какие функции выполняет? задать адрес перемычками работает?

a5021
Offline
Зарегистрирован: 07.07.2013

Кроме управления мотором и приема PPM-импульсов пока ничего больше не работает. В последовательный порт выдается информация о параметрах ШИМ и поступивших импульсах управления.

I2C функционал только сегодня начал писать. В этой связи хотелось бы услышать, чем и как с его помощью нужно управлять. Мне пока видится что-то такое:

reg. 0 -- региcтр управления вращением. Запись в этот регистр значения "0" вызывает останов, "1" -- включает вращение влево (против часовой стрелки), "2" -- вправо (по часовой стрелке).

reg. 1 -- регистр параметров ШИМ-сигнала (коэфф. заполнения) для вращения влево. 2 байта. Старший байт отправляется первым.

reg. 2 -- регистр параметров ШИМ-сигнала (коэфф. заполнения) для вращения вправо. 2 байта. Старший байт отправляется первым.

reg. 0xAA -- регистр смены I2C адреса. Записанное туда значение от 0 до 127 приводит к тому, что общение с драйвером становится возможным только при обращении по этому ардесу. Адрес запоминается в EEPROM.

регистры доступны, как для записи, так и для чтения.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

короче или плату переделывать, или код, или брать твою разводку

если я правильно понял нужно просто 0 на 1 поменять в этих функциях и все станет норм и с моей печаткой

void inline runCW(uint16_t dutyCycle) {
  if (PC_ODR_ODR5 != 0) {
    STOP_MOTOR();
    delay_ms(1);
    PC_ODR_ODR5 = 0; // поменять на 1
    delay_ms(1);
  }
  WRITE_REGISTER(TIM1_CCR3, dutyCycle);
  TIM1_CCER2_CC3E = 1;
  TIM1_BKR_MOE = 1;
}
                                 
void inline runCCW(uint16_t dutyCycle) {
  if (PC_ODR_ODR5 == 0) {
    STOP_MOTOR();
    delay_ms(1);
    PC_ODR_ODR5 = 1; // поменять на 0
    delay_ms(1);
  }
  WRITE_REGISTER(TIM1_CCR4, dutyCycle);
  TIM1_CCER2_CC4E = 1;
  TIM1_BKR_MOE = 1;
}

 

a5021
Offline
Зарегистрирован: 07.07.2013

Блин, мой косяк. Каналы поменял местами, когда свою схему рисовал. Рисовал по памяти и перепутал. Теперь, чтобы оно заработало и на оригинальной схеме нужно обе фукнции (runCW и runCCW) переписать в след. виде:

void inline runCW(uint16_t dutyCycle) {
  if (PC_ODR_ODR5 != 0) {
    STOP_MOTOR();
    delay_ms(1);
    PC_ODR_ODR5 = 0;
    delay_ms(1);
  }
  WRITE_REGISTER(TIM1_CCR4, dutyCycle);
  TIM1_CCER2_CC4E = 1;
  TIM1_BKR_MOE = 1;
}
void inline runCCW(uint16_t dutyCycle) {
  if (PC_ODR_ODR5 == 0) {
    STOP_MOTOR();
    delay_ms(1);
    PC_ODR_ODR5 = 1;
    delay_ms(1);
  }
  WRITE_REGISTER(TIM1_CCR3, dutyCycle);
  TIM1_CCER2_CC3E = 1;
  TIM1_BKR_MOE = 1;
}

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

Дифайнами в коде нарисую условную компиляцию, чтобы собиралось под нужную схему. Типа:

#define SWAP_PWM_CHANNELS 1

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

все работает. проверял на 5В и с маленьким мотором

+ насчет i2c вроде все правильно

контроль тока уже реализован? вот думаю может просто предохранитель восстанавливающийся поставить и не парится

из самых доступных на  думаю вполне хватит. 0,5а также можно, но уже мощнее мотор не поставишь

a5021
Offline
Зарегистрирован: 07.07.2013

I2C более-менее уже работает, кроме команды установки I2C адреса.

Из-за путаницы со схемами, сделал условную компиляцию под любую по выбору.

Для драйвера по моей схеме в начале программы должно присутствовать опеределение:

#define SWAP_PWM_CHANNELS       1

для оригинальной схемы данное определение нужно закомментировать (по умолчанию оно присутствует).

Контроль тока пока еще только в планах.

Прошивку в виде IAR-проекта в состоянии "на момент написания этого сообщения" можно взять здесь.

Немного изменил логику управления по I2C:

reg. 0 -- региcтр управления вращением. Запись в этот регистр значения "0" -- включает вращение вправо (по часовой стрелке), "1" -- влево (против часовой стрелки). Запись любого другого значения вызывает останов.

reg. 1 -- регистр параметров ШИМ-сигнала (коэфф. заполнения) для вращения вправо. 2 байта. Старший байт отправляется первым.

reg. 2 -- регистр параметров ШИМ-сигнала (коэфф. заполнения) для вращения влево. 2 байта. Старший байт отправляется первым.

Перечисленные регистры доступны, как для записи, так и для чтения. Адрес (I2C) драйвера 0x7A.

Управление работает, как через PPM, так и через I2C.

Демонстрационный скетч для про-мини:

#include "Wire.h"

#define STOP_MOTOR    0
#define RUN_CW        1
#define RUN_CCW       2
#define ISSUE_PPM     3

void setup() {

  // Input/Output Ports initialization
  // Port B initialization
  // Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=Out Bit0=In 
  DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (1<<DDB1) | (0<<DDB0);
  // State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=0 Bit0=T 
  PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);  

  // Timer/Counter 1 initialization
  // Clock source: System Clock
  // Clock value: 16000,000 kHz
  // Mode: Fast PWM top=ICR1
  // OC1A output: Inverted PWM
  // OC1B output: Disconnected
  // Noise Canceler: Off
  // Input Capture on Falling Edge
  // Timer Period: 2 ms
  // Output Pulse(s):
  // OC1A Period: 2 ms Width: 1,5 ms
  // Timer1 Overflow Interrupt: On
  // Input Capture Interrupt: Off
  // Compare A Match Interrupt: Off
  // Compare B Match Interrupt: Off
  TCCR1A=(1<<COM1A1) | (1<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (0<<WGM10);
  TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
  TCNT1H=0x00;
  TCNT1L=0x00;
  ICR1H=0x7C;
  ICR1L=0xFF;
  OCR1AH=0x1F;
  OCR1AL=0x40;
  OCR1BH=0x00;
  OCR1BL=0x00;

  // Timer/Counter 1 Interrupt(s) initialization
  TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (1<<TOIE1);

  Wire.begin();
}

void loop() {
  uint16_t dutyCycle;
  uint8_t m1, m2, dir;

    Wire.beginTransmission(0x7A);
    Wire.write(0);
    Wire.endTransmission();
    
    Wire.requestFrom(0x7A, 1);
    while (!Wire.available());
    dir = Wire.read();           // get dir

    if (dir < 2) {
      for (int i = 0; i < 10; i++) {
        Wire.beginTransmission(0x7A);
        Wire.write(dir + 1);
        Wire.endTransmission();
        
        Wire.requestFrom(0x7A, 2);
        while (!Wire.available());
        m1 = Wire.read();
        m2 = Wire.read();
      
        dutyCycle = ((uint16_t)(m1 << 8) | (m2 & 0xFF));
        dutyCycle += 1000;
        
        Wire.beginTransmission(0x7A);
        Wire.write(dir + 1);
        Wire.write(dutyCycle >> 8);
        Wire.write(dutyCycle & 0xFF);
        Wire.endTransmission();
        delay(500);
      }
      Wire.beginTransmission(0x7A);
      Wire.write(0);
      Wire.write(55);
      Wire.endTransmission();
      delay(500);
    }

  uint8_t cmd = random(0, 4);

  switch(cmd) {
    case STOP_MOTOR:
      Wire.beginTransmission(0x7A);
      Wire.write(0);
      Wire.write(2);
      Wire.endTransmission();
      break;
    case RUN_CW:
      Wire.beginTransmission(0x7A);
      Wire.write(1);
      Wire.write(random(0, 255));
      Wire.write(random(0, 255));
      Wire.endTransmission();
      
      Wire.beginTransmission(0x7A);
      Wire.write(0);
      Wire.write(0);
      Wire.endTransmission();
      break;
    case RUN_CCW:
      Wire.beginTransmission(0x7A);
      Wire.write(2);
      Wire.write(random(0, 255));
      Wire.write(random(0, 255));
      Wire.endTransmission();
      
      Wire.beginTransmission(0x7A);
      Wire.write(0);
      Wire.write(1);
      Wire.endTransmission();
      break;
    case ISSUE_PPM:
      PORTB |= (1 << PORTB5);
      uint16_t a = random(0, 16000);
    
      OCR1AH = (uint8_t)(a >> 8);
      OCR1AL = (uint8_t)(a & 0xFF);
      
      TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
      break;
  }

  delay(random(2000, 6000));

}

ISR(TIMER1_OVF_vect) {
  PORTB &= ~(1 << PORTB5);
  TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
  TCNT1H=0x00;
  TCNT1L=0x00;
}

Линии SDA и SCL должны быть подтянуты к +5в на стороне ардуины. Пин 9 ардуины соединен напрямую с входом PPM драйвера.

Скетч в начале каждого цикла запрашивает драйвер о направлении и скорости вращения двигателя. Если драйвер не в останове, то скетч десять раз запрашивает параметры скорости вращения для действующего направления, каждый раз плюсует к ним 1000 и отправляет обратно в драйвер. Потом выполняется останов, затем запуск мотора со случайными выбором канала управления, I2C или PPM, со случайными же направлением и скоростью.

В последовательный порт драйвера выводится отладочная информация о полученных командах и параметрах этих команд.

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а зачем шим сигнал по отдельности для право и лево? а если одновременно 2 сигнала у какого есть приоритет? защита от дурака присутствует?

что насчет предохранителя? или хочешь сделать измерение тока все таки?

a5021
Offline
Зарегистрирован: 07.07.2013

jeka_tm пишет:
а зачем шим сигнал по отдельности для право и лево?

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

Цитата:
а если одновременно 2 сигнала у какого есть приоритет? защита от дурака присутствует?

ШИМ по обоим каналам генерируется всегда, но на пины МК эти каналы подключаются по одному, в зависимости от необходимости. Для вращения в одну сторону, подключается один, в другую, другой, смотря в каком состоянии находится пин DIR. Все переключения производятся через останов. При переходе в останов, независимо ни от чего отключаются оба.

Смена направления вращения выглядит так: сначала останов, затем пауза в 1мс, потом меняется состоянии пина управления затворами верхних мосфетов (DIR), снова пауза в 1мс и только потом подключается один из ШИМ-каналов к пину МК.

Ситуацию, когда бы включились оба сразу, что по сути является аварией, я постарался исключить.

Цитата:
что насчет предохранителя? или хочешь сделать измерение тока все таки?

Предохранитель по любому не помешает. Измерение тока попробую сделать, но пока непонятно, насколько точно оно будет работать. Мотор же ШИМится и надо успеть измерить ток в момент, пока на ШИМ-выходе присутствует высокий уровень.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

я имел в виду одновременно ppm и i2c управление))

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

a5021
Offline
Зарегистрирован: 07.07.2013

jeka_tm пишет:
я имел в виду одновременно ppm и i2c управление))

Оба канала независимы. Можно управлять по любому. Если управляющие команды придут по обоим каналам одновременно, то тут возможны два варианта: либо сначала отработает PPM-команда, но ее тут же  перебьет I2C, либо отработает только I2C-команда, а PPM будет проигнорирован. Получается, что по любому, приоритет выше у I2C.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

понятно

a5021
Offline
Зарегистрирован: 07.07.2013

Добавил две I2C команды (регистра) быстрого управления мотором: "крутить на X процентов от полной мощности". Запись в регистр 10 (десятичн.) некоего числа запускает вращение двигателя по часовой стрелке с коэфф. заполнения ШИМ равном значению этого числа. Регистр 11 предназначен для того же самого, но с вращением против часовой стрелки. Значения больше 100 считаются  ста процентами.

Чтение регистров 10 и 11 возвращает коэфф. заполнения ШИМ-сигнала для каналов вращения по часовой и против часовой стрелки, соответственно.

Новый вариант выложу после того, как немного причешу.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

давай. а я пока плату переделываю под предохранитель. uart убрал

a5021
Offline
Зарегистрирован: 07.07.2013

А вот зря так с уартом. Под уарт планируется третий канал управления посредством АТ-команд.

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

a5021
Offline
Зарегистрирован: 07.07.2013

Вот просто картинка платы:

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

А насчет удовольствия от трассировки -- есть такое дело. Наверное чем-то похоже на собирание пазлов, только практический эффект намного более ощутим.

nevkon
Offline
Зарегистрирован: 20.01.2015

Мне интересно, не лучше ли было задавать вращение одним регистром? Скажем до 100 - обратное вращение, больше 100 - прямое.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

a5021
Offline
Зарегистрирован: 07.07.2013

nevkon пишет:
Мне интересно, не лучше ли было задавать вращение одним регистром? Скажем до 100 - обратное вращение, больше 100 - прямое.

Да как угодно можно сделать. Я вообще за разнообразие. У меня сложность только в одном -- я не очень хорошо знаю прикладной уровень, его требования и специфику. Мотор у меня просто лежит на столе и я кручу его разнообразными способами, насколько фантазии хватает.  Те моторизованные поделки, что мне приходилось делать раньше,  я сам полностью придумывал и реализоваывал без оглядки на существующие решения. При этом я абсолютно не уверен, что делал это лучше, чем то, что придумали до меня. Поэтому, если есть какие-то соображения, идеи, заимствования из похожих проектов, предлагайте. Если данному функционалу есть полезное применение, то чего бы и не сделать.

Насчет предложенной регулировки "вокруг ста": для цифр меньше ста мощность должна увеличиваться с уменьшением чисел или с увеличиением?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

я все таки за 3 регистра. 1 направление, второй скорость. третий адрес. причем регулировки скорости с 8 битной разрядностью достаточно. хотя 2 регистра тоже не проблема отправить

я вроде закончил. мне лично больше нравится

https://yadi.sk/i/DFYriOScybDqg

картинку не могу загрузить. лимит закончился. как с админом связаться?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Внесу свои соображения.

1. Управление по сигналу ppm (ШИМ) - должно имитировать работу серводвигателей и оно, как понял, так и сделано: 500..1500мсек - в одну сторону, 1500..2500 мсек в обратную. С защитным интервалом возле "90грд" в 12мксек. ШИМ, выходящий за пределы: >2500 и <500 -- отсекается и мотор останавливается. То есть, по включению питания, когда нога работает на вход и имеет высокий уровень "никто никуда не поедет" и даже не дернется.

2. Управление по I2C - "альтернативное", но при этом получается "основным": в случае комбинированного срабатывания - активен I2C. И это, как понимаю тоже верно: случайный импульс "пролетает мимо". С помощью I2C также можно делать настройку драйвера, а именно регулировать частоты ШИМ, причем раздельно "вперед" и "назад". Не знаю зачем раздельно, но пусть будет, может и пригодится.

А вот далее не очень понял: управление вращением по I2C - это запись в 2 разных регистра скорости для "вперед" и "назад" или в один знаковой константы? Если в два разных, то что будет если записано движение в оба регистра "подряд"? Если есть отдельная запись "направления", то это хуже - введение лишней сущности.

Предлагал? Не помню .. по шине I2C неплохо бы организовать "синхронное управление" несколькими моторами посылкой синхронных команд "всем стоять", "всем вперед/назад" .. а можно ещё "обнаглеть" и сделать команды "динамически формируемой группы моторов", типа так: "создать группу 1 из 1,3,5 моторов" и потом "группе 1 - стоять". Синхронное управление для, к примеру 4wd тележками, где команда отдается для пары моторов правого или левого борта .. различные многомоторные леталки, суда на воздушной подушке и т.д. Мало ли где несколько моторов тянут синхронно ..

a5021
Offline
Зарегистрирован: 07.07.2013

Я картинки храню на postimage.org. Простой и (пока еще?) бесплатный сервис.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а я тут))

a5021
Offline
Зарегистрирован: 07.07.2013

Arhat109-2 пишет:
1. Управление по сигналу ppm (ШИМ) - должно имитировать работу серводвигателей и оно, как понял, так и сделано: 500..1500мсек - в одну сторону, 1500..2500 мсек в обратную.

Сделано. Только на данный моммент границы такие: 1000..1500 и 1500..2000. За границы отвечают отдельные определения, т.ч. если у кого-то возникнет потребность в других границах, то нужно исправить эти несколько определений. Ширина защитного интервала тоже задается определением.

Цитата:
ШИМ, выходящий за пределы: >2500 и <500 -- отсекается и мотор останавливается.

Нет, импульсы шире и уже заданных границ просто игнорируются.

Цитата:
То есть, по включению питания, когда нога работает на вход и имеет высокий уровень "никто никуда не поедет" и даже не дернется.

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

Цитата:
А вот далее не очень понял: управление вращением по I2C - это запись в 2 разных регистра скорости для "вперед" и "назад" или в один знаковой константы?

Два шестнадцатиразрядных беззнаковых целых. Одно для "вперед" и одно для "назад".

Цитата:
Если в два разных, то что будет если записано движение в оба регистра "подряд"?

Ничего страшного не произойдет. К заметным изменениям приведет запись в регистр использующегося в текущий момент направления. То есть, если мотор крутит по часовой стрелке с мощностью 25% и в регистр этого направления записывается значение соответствующее 50%, то мотор ускорится. Если сразу же за записью в этот регистр, записать 100% в регистр противоположного направления, то увидеть этот "форсаж" можно будет только после того, как будет произведена смена направления вращения (запись в регистр 0).

Цитата:
Если есть отдельная запись "направления", то это хуже - введение лишней сущности.

Если смущает, что параметры для вперед-назад записываются каждый в свой регистр, то можно ввести еще один "знаковый" регистр, где значения от 1 до 127 будут соответствовать вращению вперед, а -1 .. -127 -- назад. Тогда одной записью можно будет менять и скорость и направление, если это требуется.

Цитата:
Предлагал? Не помню .. по шине I2C неплохо бы организовать "синхронное управление" несколькими моторами посылкой синхронных команд "всем стоять", "всем вперед/назад"

В I2C есть такое понятие -- General Call. Суть его как раз в обращении ко всем I2C устройствам сразу. Я его особо не копал, да и редко где это дело используется, но что-то похожее с его помощью изобразить возможно.

 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

А есть место в программной памяти изобразить групповые операции с моторами? Можно ввести "групповой адрес" и обращаться по нему к группе моторов..

a5021
Offline
Зарегистрирован: 07.07.2013

Места полно, но вот "ввести адрес" несколько затруднительно на F003/F103. Разве что отказаться от аппаратного I2C и реализовать слейва программно. К подобной жертвенности я как-то не готов и для "групповых операций", если в них возникнет нужда, нужно искать другой способ.

Как я уже говорил, в стандарте I2C есть General Call и выделенный для этих целей адрес 0x00. У STM8S есть возможность включить и использовать эту фишку, но нужно выяснить, как это дело можно употребить для целей группового управления.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Для целей группового управления оно не подойдет, только разве что для "спец. команд". Работает General Call точно также как и везде и у мег в частности: при передаче по этому адресу, все кто умеет его принимать - примут сообщение. Поэтому, для "групповой" команды разумно использовать только какую-то "перезагрузку", типа "все отменить".

Групповое управление я думал организовать на возможности изменять адрес мотора программно: включаем мотор в группу - просто всей группе моторов присваиваем один и тот же адрес на шине. Драйвер тупо запоминает свой "предыдущий" адрес шины и принимает команды по групповому адресу до тех пор, пока ему не прилетит GCALL или пока не придет "конец группе" и все моторы группы просто "вспоминают" предыдущий адрес и каждый работает по нему. Если организовать "стек" на несколько адресов (только вот нафига) - то можно динамически пересобирать группы моторов и возвращать их обратно.

С ходу динамическое назначение разных групп .. пока вижу как применение только в системах с глубоким резервированием. Ну типа марсоходов..

a5021
Offline
Зарегистрирован: 07.07.2013

Arhat109-2 пишет:
Групповое управление я думал организовать на возможности изменять адрес мотора программно: включаем мотор в группу - просто всей группе моторов присваиваем один и тот же адрес на шине.

Есть МК, которые могут слушать по двум I2C-адресам одновременно и эти адреса можно произвольно менять. Используя один адрес, как "индивидуальный", а другой, как "групповой", можно весьма гибко образовывать "группы", включать и исключать из них отдельные i2c устройства в нужном порядке и в любое время. Одно плохо -- STM8S003 к таким МК не относится.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

В данном применении одного I2C более чем достаточно. Я надеюсь, что у этого МК аппаратное решение - полноценное. В смысле поддерживает и прием и передачу и режимы мастер-слейв и диспетчеризацию нескольких мастеров и GCALL .. ну как у Мег.

a5021
Offline
Зарегистрирован: 07.07.2013

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

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

GCall - ловить умеет? Тогда на него надо "общий сброс" нацепить. Чтобы по прилету глобального оповещения все драйвера останавливались и сбрасывали свои настройки в исходное состояние "по умолчанию".

a5021
Offline
Зарегистрирован: 07.07.2013

Согласен. Смысл в этом есть. Осталось проверить, не вводит ли МК в какое уныние этот самый General Call.

a5021
Offline
Зарегистрирован: 07.07.2013

Два дня проковырялся с измерением тока через мост средствами МК, но ничего сколь-нибудь приемлемого так и не получил. Цифры скачут, как те блохи, даже если измерять запуская АЦП по таймеру, когда транзисторы гарантированно открыты. С расстройства взялся прикручивать Analog Watchdog и в этом случае результат оказался поинтересней. Попутно выяснилось, что моторчик, который в режиме монотонного кручения в среднем берет около 50ма, при старте или резкой смене направления вращения ухитряется кратковременно "хапнуть" до трех Ампер в пике. Выходит, чтобы мотор не выбивал защиту, порог ее включения должен больше чем в шестьдесят раз превышать средний рабочий ток. Озадачило.

Тем не менее, в части аналоговых измерений решил ватчдогом и ограничится. Использоваться он будет так: в EEPROM записывается двухбайтовая константа, значение которой представляет максимально-допустимый ток через мост в миллиамперах.  При старте МК считывает эту константу и заносит ее в регистр сравнения ватчдога. Если при работе драйвера ток через мост превысит значение константы, то драйвер закрывает мосфеты и уходит в аварийный останов.

Величину ограничения тока (константу) возможно считывать и устанавливать по I2C.

 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Какое сопротивление якоря того моторчика, который у Вас в пике хапнул больше 3А? С какой напругой производился замер? По идее мотор не может хапнуть больше чем позволит "ток козы". Попробуйте замерить сопротивление якоря если нет паспортных данных, несколько раз, слегка и медленно покрутив моторчик в обе стороны. Цифирьки верны, когда мотор остановлен (он может изображать из себя и генератор, не забываем).

a5021
Offline
Зарегистрирован: 07.07.2013

Сопротивление что-то в районе 5.6 ом, питающее напряжение моста 12 вольт. Хапнуть "до трех ампер", о чем говорил я, не есть  "больше 3А". С учетом, что измерения МК производит от опоры в виде питающего напряжения, которое подается к нему через программатор с юсб компа, вряд ли можно говорить о точности измерений лучше, чем "плюс-минус лапоть". В этом смысле мои "до 3А" следует воспринимать с некоторой долей условности, да и наблюдениями своими поделился я не в плане точности измерений, а касательно того, насколько границы пикового потребления оказались удалены от средних значений. Для меня это оказалось неожиданностью, т.к. измерив среднее, я было подумал, что умножу эту величину на два и выставлю в качестве предела, но не тут-то было. Умножить в конечном счете пришлось на шестьдесят.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Это нормальный разброс для хорошего движка. При небольшом трении (хорошая полировка вала, подшипников) и хорошей центровке мотор может разгоняться на холостых очень круто, практически полностью компенсируюя противоЭДС входящее напряжение и токи там 40-70мА для 130-х моторов - нормально. А вот жрать в режиме КЗ он будет столько сколько ему дадут согласно его сопротивлению якоря .. так что получить 3А в КЗ и 50мА на ХХ - вполне реально.

a5021
Offline
Зарегистрирован: 07.07.2013

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

a5021
Offline
Зарегистрирован: 07.07.2013

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

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

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