Как избавиться от помех?

adruha
Offline
Зарегистрирован: 21.05.2013

Всем привет! Пытаюсь написать управляющую программу для безщеточного мотора постоянный ток, вроде получилось но двигатель работает не чисто. Если прикоснуться к двигателю чувствуется вибрация. Когда устанавливаю на место оригинальный чип управляющий то все работает чисто. Думаю что дело в аналогврите но незнаю как сделать по другому что бы исключить эту проблему. А может дело в другом? Кто знает подскажите пожалуйста куда копать? Заранее благодарен!

Вот работа оригинальной программы:

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

 

adruha
Offline
Зарегистрирован: 21.05.2013

Вот сама программа (кое что взято из инета):

byte bldc_step, pwm_pin = 9;

void setup()
{
  Serial.begin(9600);
  pinMode (pwm_pin, OUTPUT);

  pinMode(A5, INPUT);
  pinMode(A4, INPUT);
  pinMode(A3, INPUT);
  
  digitalWrite(A5,HIGH);
  digitalWrite(A4,HIGH);
  digitalWrite(A3,HIGH);

  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);

  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);

  // Set PWM for pins 9,10 to 32 kHz
  int prescalerVal = 0x07; //create a variable called prescalerVal and set it equal to the binary number "00000111"                                                       number "00000111"                                                      number "00000111"
  TCCR1B &= ~prescalerVal; //AND the value in TCCR0B with binary number "11111000"
  //Now set the appropriate prescaler bits:
  int prescalerVal2 = 1; //set prescalerVal equal to binary number "00000001"
  TCCR1B |= prescalerVal2; //OR the value in TCCR0B with binary number "00000001"
  // Set PWM for pins 3,11 to 32 kHz (Only pin 11 is used in this program)
  //First clear all three prescaler bits:
  TCCR2B &= ~prescalerVal; //AND the value in TCCR0B with binary number "11111000"
  //Now set the appropriate prescaler bits:
  TCCR2B |= prescalerVal2; //OR the value in TCCR0B with binary number "00000001"//First clear all three prescaler bits:
  // ADC module configuration
  ADMUX  = 0x60;                     // Configure ADC module and select channel 0
  ADCSRA = 0x84;                     // Enable ADC module with 16 division factor (ADC clock = 1MHz)
 
  pciSetup(A5);
  pciSetup(A4);
  pciSetup(A3);

  if(!(PINC & (1<<PC5)) && !(PINC & (1<<PC4)) && (PINC & (1<<PC3))){bldc_step=1; bldc_move();}//001
  if(!(PINC & (1<<PC5)) && (PINC & (1<<PC4)) && !(PINC & (1<<PC3))){bldc_step=2; bldc_move();}//010
  if(!(PINC & (1<<PC5)) && (PINC & (1<<PC4)) && (PINC & (1<<PC3))){bldc_step=3; bldc_move();}//011
  if((PINC & (1<<PC5)) && !(PINC & (1<<PC4)) && !(PINC & (1<<PC3))){bldc_step=4; bldc_move();}//100
  if((PINC & (1<<PC5)) && !(PINC & (1<<PC4)) && (PINC & (1<<PC3))){bldc_step=5; bldc_move();}//101
  if((PINC & (1<<PC5)) && (PINC & (1<<PC4)) && !(PINC & (1<<PC3))){bldc_step=6; bldc_move();}//110
  //Serial.print("-----");Serial.println(bldc_step);
}

void loop()
{
   ADCSRA |= 1 << ADSC; 
   while(ADCSRA & 0x40); 
   
  if(ADCH < 250){
    while(TCNT2 < ADCH) ;
    analogWrite(pwm_pin,ADCH/5);
  }
  if(ADCH > 0){
    while(TCNT2 >= ADCH) ;
    analogWrite(pwm_pin,ADCH/5);
  }
}

void bldc_move(){                    
  PORTD  &= B00000000;
  PORTD  |= B00011100;
  switch(bldc_step){
    case 1:
       PORTD |= 1<<5;
       PORTD &= ~(1<<4);
       break;
    case 2:
       PORTD &= ~(1<<3);
       PORTD |= 1<<7;     
       break;
    case 3:
       PORTD |= 1<<5;
       PORTD &= ~(1<<3);
       break;
    case 4:
       PORTD &= ~(1<<2);
       PORTD |= 1<<6;
       break;
    case 5:
       PORTD |= 1<<6;
       PORTD &= ~(1<<4);
       break;
    case 6:
       PORTD &= ~(1<<2);
       PORTD |= 1<<7;
       break;
    default:
      PORTD  &= B00000000;
      PORTD  |= B00011100;
      break;
  }
}

ISR(PCINT1_vect){

  if(!(PINC & (1<<PC5)) && !(PINC & (1<<PC4)) && (PINC & (1<<PC3))){bldc_step=1; bldc_move();}//001
  if(!(PINC & (1<<PC5)) && (PINC & (1<<PC4)) && !(PINC & (1<<PC3))){bldc_step=2; bldc_move();}//010
  if(!(PINC & (1<<PC5)) && (PINC & (1<<PC4)) && (PINC & (1<<PC3))){bldc_step=3; bldc_move();}//011
  if((PINC & (1<<PC5)) && !(PINC & (1<<PC4)) && !(PINC & (1<<PC3))){bldc_step=4; bldc_move();}//100
  if((PINC & (1<<PC5)) && !(PINC & (1<<PC4)) && (PINC & (1<<PC3))){bldc_step=5; bldc_move();}//101
  if((PINC & (1<<PC5)) && (PINC & (1<<PC4)) && !(PINC & (1<<PC3))){bldc_step=6; bldc_move();}//110
  //Serial.print("-----");Serial.println(bldc_step);
  
}

void pciSetup(byte pin)
{
    *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));  // enable pin
    PCIFR  |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
    PCICR  |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

Взять процессор в котором есть аппаратное управление бесщеточным мотором со всеми положенными плюхами. Например блюпилл. 

adruha
Offline
Зарегистрирован: 21.05.2013

это не по существу вопроса! Оригинал работает на атмега8 и хорошо с этим справляется! Да и мотор тут на 1000 ватт 6 ампер 230 вольт!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

В песочнице была ссылка на книгу Симонка, может там есть, я так понимаю он автор прошивки СИМОНК

adruha
Offline
Зарегистрирован: 21.05.2013

ua6em пишет:

В песочнице была ссылка на книгу Симонка, может там есть, я так понимаю он автор прошивки СИМОНК

Не это не он....

adruha
Offline
Зарегистрирован: 21.05.2013

Сделал шим без аналогврите

TCCR1A = _BV (WGM10) | _BV (WGM11) | _BV (COM1A1) | _BV (COM1B1);
OCR1A = 0;

ADCSRA |= 1 << ADSC; 
while(ADCSRA & 0x40); 
OCR1A=ADCH;

но ситуация не изменилась, все ровно есть помехи...

как это побороть, незнаю. Может где ошибка?

sadman41
Offline
Зарегистрирован: 19.10.2016

Помехи выглядят несистемно. Может дело не в таймерах?

adruha
Offline
Зарегистрирован: 21.05.2013

А в чем?

b707
Offline
Зарегистрирован: 26.05.2017

Во-первых,  причем тут analogWrite вообще? В оригинальном алгоритме там между выходами переключается компаратор - 'это средствами Ардуино вообще не делается, analogWrite в этом не поможет.

Во-вторых, Вы уверены, что условия в строках 63-69 правильно написаны?

И еще, интересно - если был код на атмега8 - нафига его в Ардуино перетаскивать?

adruha
Offline
Зарегистрирован: 21.05.2013

b707 пишет:

Во-первых,  причем тут analogWrite вообще? В оригинальном алгоритме там между выходами переключается компаратор - 'это средствами Ардуино вообще не делается, analogWrite в этом не поможет.

Во-вторых, Вы уверены, что условия в строках 63-69 правильно написаны?

И еще, интересно - если был код на атмега8 - нафига его в Ардуино перетаскивать?

по поводу компараторов спорить не буду.... без строк о которых вы написали делал об этом написал выше...

на атмеге8 у меня нет кода есть сама мега с кодом внутри оригинальным с завода но исходников нет. На ардуину я не перетаскиваю а пишу с нуля.

b707
Offline
Зарегистрирован: 26.05.2017

adruha пишет:

по поводу компараторов спорить не буду.... без строк о которых вы написали делал об этом написал выше...

на атмеге8 у меня нет кода есть сама мега с кодом внутри оригинальным с завода но исходников нет. На ардуину я не перетаскиваю а пишу с нуля.

разве с нуля? не похоже. Судя по именам функций, вы программу откуда-то отсюда переписывали, не уверен только, что правильно

https://simple-circuit.com/arduino-brushless-dc-motor-controller/

и про компараторы тут тоже обьяснено подробно, читайте

adruha
Offline
Зарегистрирован: 21.05.2013

b707 пишет:

adruha пишет:

по поводу компараторов спорить не буду.... без строк о которых вы написали делал об этом написал выше...

на атмеге8 у меня нет кода есть сама мега с кодом внутри оригинальным с завода но исходников нет. На ардуину я не перетаскиваю а пишу с нуля.

разве с нуля? не похоже. Судя по именам функций, вы программу откуда-то отсюда переписывали, не уверен только, что правильно

https://simple-circuit.com/arduino-brushless-dc-motor-controller/

и про компараторы тут тоже обьяснено подробно, читайте

мы че будем тут перепираться?! я в самом начале написал конкретно для вас что код не мой!!! 

b707
Offline
Зарегистрирован: 26.05.2017

adruha пишет:

мы че будем тут перепираться?! я в самом начале написал конкретно для вас что код не мой!!! 

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

adruha
Offline
Зарегистрирован: 21.05.2013

b707 пишет:

adruha пишет:

мы че будем тут перепираться?! я в самом начале написал конкретно для вас что код не мой!!! 

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

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

b707
Offline
Зарегистрирован: 26.05.2017

adruha пишет:

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

а какая "другая задача"? BLDC мотор он и есть

adruha
Offline
Зарегистрирован: 21.05.2013

b707 пишет:

adruha пишет:

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

а какая "другая задача"? BLDC мотор он и есть

задающий частоту шим сигнал мне нужно подавать на один канал а управляющие АВС на шесть других. так как схема подключения работает на микросхеме HD74LS00P и на IR2110 ну и ключи FGL60N100BNTD вот такие сложности. Если для одного человека элементарно то это не значит что и другому все так легко. Зацепин А.Г (R)(C)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Просто для экперимента, попробуйте заткнуть глоку миллису. Вы же вроде не используете ни millis, ни delay. Попробуйте в сетапе написать первой строкой 

TIMSK0 = 0;

и запустите. Не поможет и не надо - Вы ж ничем не рискуете. Сделайте и скажите как оно получилось.

Если не поможет, тогда я код повнимательнее посмотрю.

adruha
Offline
Зарегистрирован: 21.05.2013

ЕвгенийП пишет:

Просто для экперимента, попробуйте заткнуть глоку миллису. Вы же вроде не используете ни millis, ни delay. Попробуйте в сетапе написать первой строкой 

TIMSK0 = 0;

и запустите. Не поможет и не надо - Вы ж ничем не рискуете. Сделайте и скажите как оно получилось.

Если не поможет, тогда я код повнимательнее посмотрю.


да нет проблем , мне не трудно :-) попробовал, ничего не поменялось...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

:(

releyshic
Offline
Зарегистрирован: 20.11.2015

А вот в HA5 нет помех )) в последнем фото

А схему можно в студию?

Где мерятся сигналы в первом и втором случае?

На ногах МК и выходах ардуины?

 

adruha
Offline
Зарегистрирован: 21.05.2013

releyshic пишет:

А вот в HA5 нет помех )) в последнем фото

А схему можно в студию?

Где мерятся сигналы в первом и втором случае?

На ногах МК и выходах ардуины?

 

На НА5 нет т олько на этом куске это фрагмент, если прокрутить дальше то есть. Мерилось на ногах мк и выходах ардуины... (но какая разница? помехи ощутимы по работе мотора да и греется он... да и в оригинале же видно что все чисто и мотор работает ок,, замеры на тех же контактах!), схемы к сожелению нет есть только железка.

Schwarz78
Offline
Зарегистрирован: 19.01.2019

Не стоит вызывать функции из прерывания. Ставьте флаг в прерывании, а всё управление делайте в главном цикле.

adruha
Offline
Зарегистрирован: 21.05.2013

Schwarz78 пишет:

Не стоит вызывать функции из прерывания. Ставьте флаг в прерывании, а всё управление делайте в главном цикле.

почему?

Schwarz78
Offline
Зарегистрирован: 19.01.2019

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

Это реально выстрадано, без всяких шуток. В прерывании - только флаг, мол байт пришёл, или интервал случился. Всё. Прерывание должно выйти как можно скорее. Если вам интересно - дизассемблируйте вашу программу и посмотрите сколько ваше прерывание пушит. Удивитесь, как минимум.

adruha
Offline
Зарегистрирован: 21.05.2013

Schwarz78 пишет:

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

Это реально выстрадано, без всяких шуток. В прерывании - только флаг, мол байт пришёл, или интервал случился. Всё. Прерывание должно выйти как можно скорее. Если вам интересно - дизассемблируйте вашу программу и посмотрите сколько ваше прерывание пушит. Удивитесь, как минимум.

а как таймер завести на 4000 kHz? В оригинале вот так:

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

adruha пишет:

а как таймер завести на 4000 kHz?

Делителями. 

adruha
Offline
Зарегистрирован: 21.05.2013

DetSimen пишет:

adruha пишет:

а как таймер завести на 4000 kHz?

Делителями. 

понятное дело что делителями но вот только что то не получается больше тысячи сделать, мож что не так?

  uint16_t t1P = 3267;
  uint8_t sF = 20, sDC = 2;

  TCCR1A = 0;
  TCCR1B = 0;

  // Set non-inverting mode
  TCCR1A |= (1 << COM1A1);

  // Set fast PWM Mode 14
  TCCR1A |= (1 << WGM11);
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << WGM13);

  // Set prescaler to 64 and starts PWM
  TCCR1B |= (1 << CS10);
  TCCR1B |= (1 << CS11);

  // Set PWM frequency/top value
  ICR1 = (F_CPU / (t1P*sF)) - 1;
  OCR1A = ICR1 / (100 / sDC);

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

adruha пишет:

понятное дело что делителями 

Ну, а если понятное, то зачем такой большой делитель ставите?

adruha
Offline
Зарегистрирован: 21.05.2013

ЕвгенийП пишет:

adruha пишет:

понятное дело что делителями 

Ну, а если понятное, то зачем такой большой делитель ставите?

В каком именно месте большой?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А в каком месте Вы устанавливаете делитель? (хотя бы комментарии прочитайте)

adruha
Offline
Зарегистрирован: 21.05.2013

и зачем форумы в Росии... непонятно

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

adruha пишет:

и зачем форумы в Росии... непонятно

Ну, когда поймёте - возвращайтесь. А пока сходите на "форумы не в России".

nik182
Offline
Зарегистрирован: 04.05.2015

Bldcstep волотилить не пробовали? 

b707
Offline
Зарегистрирован: 26.05.2017

adruha пишет:

В каком именно месте большой?

вы что, код из сообщения №27 тоже где-то списали? нафига вообще тогда за дело взялись, если ничего в нем не смыслите?

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

 

Schwarz78
Offline
Зарегистрирован: 19.01.2019

А что у вас делают строки 74, 75 в коде из первого поста?

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