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

Как состряпать алгоритм синусоидального ШИМ?

Just now, Сергей Борщ said:

Все у вас правильно

Урааа!!! :dance3:

Спасибо Вам огромное! Особенно за  ангельское терпение в общении с таким тугим собеседником, как я)))

Это первый DDS, который я написал)

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


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

Позравляю. Можете еще попробовать использовать режим не простого ШИМ, а phase and frequency correct PWM. Частота ШИМ снизится почти вдвое, но вторая гармоника в спектре выходного сигнала будет существенно ниже. Не знаю, насколько для вас это критично. Возможно, двигатель станет чуть холоднее.

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


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

8 minutes ago, Сергей Борщ said:

Можете еще попробовать использовать режим не простого ШИМ, а phase and frequency correct PWM.

А в чём выгода? Каким образом этот режим ШИМ уменьшит вторую гармонику синуса?

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

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


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

17 минут назад, MPetrovich сказал:
num = akk/2048;//65536/32=2048

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

num = akk / (65536 / 32);

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

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


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

3 minutes ago, Сергей Борщ said:

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

Я об этом не знал. Благодарю за подсказку.

 

4 minutes ago, Сергей Борщ said:

перепишите эту строку от греха подальше в 

num = akk / (65536 / 32);

Ок. Переписал)

Кстати сказать, ни объём данных, ни объём программы не изменились после компиляции...

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


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

9 минут назад, MPetrovich сказал:

А в чём выгода? Каким образом этот режим ШИМ уменьшит вторую гармонику синуса?

Ой, вот этого не смогу объяснить. Но при создании передатчика убедился своими глазами.

9 минут назад, MPetrovich сказал:

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

Тогда надо не синус в таблицу заносить, а вот такой хитрый сигнал (нарисован черным):

post-53549-12536540738_thumb.jpg

Сейчас scilab скачается, покажу более полную картинку.

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


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

3 minutes ago, Сергей Борщ said:

Тогда надо не синус в таблицу заносить, а вот такой хитрый сигнал (нарисован черным):

Да, я в курсе. только пока не разобрался как получить эту кракозябру. Преобразованием Фурье не очень хочется заморачиваться)))

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


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

4 минуты назад, MPetrovich сказал:

только пока не разобрался как получить эту кракозябру.

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

 

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


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

Вот нашёл такую формулу: sin3(q) = sin(q)+1/6sin(3q). Она похоже иллюстрирует Ваш метод)

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


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

Запустил scilab:

image.thumb.png.7a7f0256a51bb76921ddfd1c7b89abc0.png

Спойлер
PERIOD = 2 * %pi;
POINTS = 120 * 3;

T = [1:POINTS];
Phase = (T - 1) / POINTS * PERIOD;

Sin1 = sin(Phase + 0 * PERIOD / 3) / 2 + 0.5;
Sin2 = sin(Phase - 1 * PERIOD / 3) / 2 + 0.5;
Sin3 = sin(Phase - 2 * PERIOD / 3) / 2 + 0.5;

function [y]=phase(x)
  y = (x - 1) / POINTS * PERIOD;
endfunction;

function [y]=envelope(x)
  y = [];

  for i = 1 + 0 * POINTS / 3 + POINTS / 12 : 1 * POINTS / 3 + POINTS / 12;
    y(i) = sin(phase(i) + 0 * PERIOD / 3) - sin(phase(i) + x * PERIOD / 3);
  end,
  for i = 1 + 1 * POINTS / 3 + POINTS / 12 : 2 * POINTS / 3 + POINTS / 12;
    y(i) = sin(phase(i) + 2 * PERIOD / 3) - sin(phase(i) + x * PERIOD / 3);
  end,
  for i = 1 + 2 * POINTS / 3 + POINTS / 12 : 3 * POINTS / 3;
    y(i) = sin(phase(i) + 1 * PERIOD / 3) - sin(phase(i) + x * PERIOD / 3);
  end,
  for i = 1  : POINTS / 12;
    y(i) = sin(phase(i) + 1 * PERIOD / 3) - sin(phase(i) + x * PERIOD / 3);
  end,
  y = y / max(y);
endfunction;
funcprot(0);

Out_A = envelope(0);
Out_B = envelope(1);
Out_C = envelope(2);

clf();
a=gca(); // Handle on current axes entity 
plot(T - 1, Sin1, ":r");
plot(T - 1, Sin2, ":g");
plot(T - 1, Sin3, ":b");
plot(T - 1, Out_A, "r");
plot(T - 1, Out_B, "g");
plot(T - 1, Out_C, "b");
plot(T - 1, Sin1 - Sin2, ":k");
plot(T - 1, Out_A - Out_B, "--k");

a.sub_ticks = [4, 1]; 

 

Выигрыш по амплитуде 15%

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


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

18 минут назад, MPetrovich сказал:

Вот нашёл такую формулу: sin3(q) = sin(q)+1/6sin(3q). Она похоже иллюстрирует Ваш метод)

Во всяком случае синус на выходе дает такой же:

image.thumb.png.df885fa5887585a1247fed2a5ab0caa6.png

Спойлер
PERIOD = 2 * %pi;
POINTS = 120 * 3;

T = [1:POINTS];
Phase = (T - 1) / POINTS * PERIOD;

Sin1 = sin(Phase + 0 * PERIOD / 3) / 2 + 0.5;
Sin2 = sin(Phase - 1 * PERIOD / 3) / 2 + 0.5;
Sin3 = sin(Phase - 2 * PERIOD / 3) / 2 + 0.5;

Out_A1 = sin(Phase + 0 * PERIOD / 3) + 1/6 * sin((Phase + 0 * PERIOD / 3) * 3);
Out_A1 = Out_A1 - min(Out_A1);
Out_A1 = Out_A1 / max(Out_A1);
Out_B1 = sin(Phase + 1 * PERIOD / 3) + 1/6 * sin((Phase + 1 * PERIOD / 3) * 3);
Out_B1 = Out_B1 - min(Out_B1);
Out_B1 = Out_B1 / max(Out_B1);
Out_C1 = sin(Phase + 2 * PERIOD / 3) + 1/6 * sin((Phase + 2 * PERIOD / 3) * 3);
Out_C1 = Out_C1 - min(Out_C1);
Out_C1 = Out_C1 / max(Out_C1);

clf();
a=gca(); // Handle on current axes entity 
plot(T - 1, Sin1, ":r");
plot(T - 1, Sin2, ":g");
plot(T - 1, Sin3, ":b");
plot(T - 1, Out_A1, "r");
plot(T - 1, Out_B1, "g");
plot(T - 1, Out_C1, "b");
plot(T - 1, Sin1 - Sin2, ":k");
plot(T - 1, Out_A1 - Out_B1, "--k");

a.sub_ticks = [4, 1]; 

 

Спасибо, пригодится.

image.png.fcfdefbad01cba5a0666701bb49ddee4.png

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


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

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

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

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

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

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

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

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

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

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