Как избавиться от помех?
- Войдите на сайт для отправки комментариев
Чт, 17/01/2019 - 17:04
Всем привет! Пытаюсь написать управляющую программу для безщеточного мотора постоянный ток, вроде получилось но двигатель работает не чисто. Если прикоснуться к двигателю чувствуется вибрация. Когда устанавливаю на место оригинальный чип управляющий то все работает чисто. Думаю что дело в аналогврите но незнаю как сделать по другому что бы исключить эту проблему. А может дело в другом? Кто знает подскажите пожалуйста куда копать? Заранее благодарен!
Вот работа оригинальной программы:
а вот то что выдает моя программа:
красным я обозначил то что по моему мнению является помехами. (мож и ошибаюсь)
Вот сама программа (кое что взято из инета):
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 }Взять процессор в котором есть аппаратное управление бесщеточным мотором со всеми положенными плюхами. Например блюпилл.
это не по существу вопроса! Оригинал работает на атмега8 и хорошо с этим справляется! Да и мотор тут на 1000 ватт 6 ампер 230 вольт!
В песочнице была ссылка на книгу Симонка, может там есть, я так понимаю он автор прошивки СИМОНК
В песочнице была ссылка на книгу Симонка, может там есть, я так понимаю он автор прошивки СИМОНК
Не это не он....
Сделал шим без аналогврите
но ситуация не изменилась, все ровно есть помехи...

как это побороть, незнаю. Может где ошибка?
Помехи выглядят несистемно. Может дело не в таймерах?
А в чем?
Во-первых, причем тут analogWrite вообще? В оригинальном алгоритме там между выходами переключается компаратор - 'это средствами Ардуино вообще не делается, analogWrite в этом не поможет.
Во-вторых, Вы уверены, что условия в строках 63-69 правильно написаны?
И еще, интересно - если был код на атмега8 - нафига его в Ардуино перетаскивать?
Во-первых, причем тут analogWrite вообще? В оригинальном алгоритме там между выходами переключается компаратор - 'это средствами Ардуино вообще не делается, analogWrite в этом не поможет.
Во-вторых, Вы уверены, что условия в строках 63-69 правильно написаны?
И еще, интересно - если был код на атмега8 - нафига его в Ардуино перетаскивать?
по поводу компараторов спорить не буду.... без строк о которых вы написали делал об этом написал выше...
на атмеге8 у меня нет кода есть сама мега с кодом внутри оригинальным с завода но исходников нет. На ардуину я не перетаскиваю а пишу с нуля.
по поводу компараторов спорить не буду.... без строк о которых вы написали делал об этом написал выше...
на атмеге8 у меня нет кода есть сама мега с кодом внутри оригинальным с завода но исходников нет. На ардуину я не перетаскиваю а пишу с нуля.
разве с нуля? не похоже. Судя по именам функций, вы программу откуда-то отсюда переписывали, не уверен только, что правильно
https://simple-circuit.com/arduino-brushless-dc-motor-controller/
и про компараторы тут тоже обьяснено подробно, читайте
по поводу компараторов спорить не буду.... без строк о которых вы написали делал об этом написал выше...
на атмеге8 у меня нет кода есть сама мега с кодом внутри оригинальным с завода но исходников нет. На ардуину я не перетаскиваю а пишу с нуля.
разве с нуля? не похоже. Судя по именам функций, вы программу откуда-то отсюда переписывали, не уверен только, что правильно
https://simple-circuit.com/arduino-brushless-dc-motor-controller/
и про компараторы тут тоже обьяснено подробно, читайте
мы че будем тут перепираться?! я в самом начале написал конкретно для вас что код не мой!!!
мы че будем тут перепираться?! я в самом начале написал конкретно для вас что код не мой!!!
сорри если обидел, я не пытался препираться - просто дал вам ссылку из которой вы можете подчерпнуть массу полезного. Там и полностью готовый код есть.
мы че будем тут перепираться?! я в самом начале написал конкретно для вас что код не мой!!!
сорри если обидел, я не пытался препираться - просто дал вам ссылку из которой вы можете подчерпнуть массу полезного. Там и полностью готовый код есть.
да он может и готовый только схема подключения у меня немного сложнее и задача другая, но код я естесно посмотрел!
да он может и готовый только схема подключения у меня немного сложнее и задача другая, но код я естесно посмотрел!
а какая "другая задача"? BLDC мотор он и есть
да он может и готовый только схема подключения у меня немного сложнее и задача другая, но код я естесно посмотрел!
а какая "другая задача"? BLDC мотор он и есть
задающий частоту шим сигнал мне нужно подавать на один канал а управляющие АВС на шесть других. так как схема подключения работает на микросхеме HD74LS00P и на IR2110 ну и ключи FGL60N100BNTD вот такие сложности. Если для одного человека элементарно то это не значит что и другому все так легко. Зацепин А.Г (R)(C)
Просто для экперимента, попробуйте заткнуть глоку миллису. Вы же вроде не используете ни millis, ни delay. Попробуйте в сетапе написать первой строкой
TIMSK0 = 0;
и запустите. Не поможет и не надо - Вы ж ничем не рискуете. Сделайте и скажите как оно получилось.
Если не поможет, тогда я код повнимательнее посмотрю.
Просто для экперимента, попробуйте заткнуть глоку миллису. Вы же вроде не используете ни millis, ни delay. Попробуйте в сетапе написать первой строкой
TIMSK0 = 0;
и запустите. Не поможет и не надо - Вы ж ничем не рискуете. Сделайте и скажите как оно получилось.
Если не поможет, тогда я код повнимательнее посмотрю.
да нет проблем , мне не трудно :-) попробовал, ничего не поменялось...
:(
А вот в HA5 нет помех )) в последнем фото
А схему можно в студию?
Где мерятся сигналы в первом и втором случае?
На ногах МК и выходах ардуины?
А вот в HA5 нет помех )) в последнем фото
А схему можно в студию?
Где мерятся сигналы в первом и втором случае?
На ногах МК и выходах ардуины?
На НА5 нет т олько на этом куске это фрагмент, если прокрутить дальше то есть. Мерилось на ногах мк и выходах ардуины... (но какая разница? помехи ощутимы по работе мотора да и греется он... да и в оригинале же видно что все чисто и мотор работает ок,, замеры на тех же контактах!), схемы к сожелению нет есть только железка.
Не стоит вызывать функции из прерывания. Ставьте флаг в прерывании, а всё управление делайте в главном цикле.
Не стоит вызывать функции из прерывания. Ставьте флаг в прерывании, а всё управление делайте в главном цикле.
почему?
Потому, что так нужно. Прерывания должны быть короткими как выстрел, и менять только одну глобальную переменную, а лучше один бит. Поверьте моему 20-летнему опыту, и опыту многих до меня.
Это реально выстрадано, без всяких шуток. В прерывании - только флаг, мол байт пришёл, или интервал случился. Всё. Прерывание должно выйти как можно скорее. Если вам интересно - дизассемблируйте вашу программу и посмотрите сколько ваше прерывание пушит. Удивитесь, как минимум.
Потому, что так нужно. Прерывания должны быть короткими как выстрел, и менять только одну глобальную переменную, а лучше один бит. Поверьте моему 20-летнему опыту, и опыту многих до меня.
Это реально выстрадано, без всяких шуток. В прерывании - только флаг, мол байт пришёл, или интервал случился. Всё. Прерывание должно выйти как можно скорее. Если вам интересно - дизассемблируйте вашу программу и посмотрите сколько ваше прерывание пушит. Удивитесь, как минимум.
а как таймер завести на 4000 kHz? В оригинале вот так:

а как таймер завести на 4000 kHz?
Делителями.
а как таймер завести на 4000 kHz?
Делителями.
понятное дело что делителями но вот только что то не получается больше тысячи сделать, мож что не так?
понятное дело что делителями
Ну, а если понятное, то зачем такой большой делитель ставите?
понятное дело что делителями
Ну, а если понятное, то зачем такой большой делитель ставите?
В каком именно месте большой?
А в каком месте Вы устанавливаете делитель? (хотя бы комментарии прочитайте)
и зачем форумы в Росии... непонятно
и зачем форумы в Росии... непонятно
Ну, когда поймёте - возвращайтесь. А пока сходите на "форумы не в России".
Bldcstep волотилить не пробовали?
В каком именно месте большой?
вы что, код из сообщения №27 тоже где-то списали? нафига вообще тогда за дело взялись, если ничего в нем не смыслите?
Попробуйте взять словарик и хотя бы перевести комментарии в выложенном вами коде. Я уж не говорю о том, что можно было взять даташит и почитать, как устанавливаются делители для таймеров.
А что у вас делают строки 74, 75 в коде из первого поста?
Вы там двигаете единички-нолики по временной шкале, и зачем-то каждый раз до сдвига ставите их по умолчанию. Запись в порт происходит мгновенно, а не по выходу из функции. Вот они - ваши помехи, но возможно это вашу проблему и не решит.