Множество людей, почитав мое вступление и начальные уроки, так и не поняли
Что такое ШИМ?
ШИМ- Широтно-Импульсная Модуляция, проще говоря- это оцифрованный аналоговый сигнал. Применяется, например, для оцифровки звука, всем известный формат MP3 использует именно ШИМ для сжатия сигнала, например bitrate 256 kb/s означает что аналоговый сигнал переведен в цифровой (оцифрован) со значением 256 килобит, т.е. 256/8= 32 кБайта в секунду. Опять мало что говорит это значение? Представьте аналоговый сигнал длиной 1 секунду.

Вертикальные прямоугольники, идущие от 0 до уровня сигнала называются битами оцифровки. Они следуют точно от 0 до моментального значения сигнала. Паузы между ними нет, они следуют строго друг за другом. Что же означает, например 128 кБит/с- это значает что для оцифровки 1 секунды аналогового сигнала потребовалось 128*1024 (в цифровой технике приставка кило означает не 1000 а 1024)/8 (столько информации содержит 1 бит)= 16384, т.е. таких вот серых прямоугольников! Каждый прямоугольник содержит информацию об уровне сигнала относительно 0, например моментальное значение 4 бита равно 110, оно передается в бинарном (цифровом) коде как 01101110, число 200 передастся как 11001000, всегда передается 8 значений в каждом бите информации, максимальное значение -255, ему соответствует код 11111111. Обратите внимание на 3 группу с надписью 256 кБит/с. Вы можете заметить что прямоугольники в 2 раза уже чем 128 кБит/с. Что это означает? Это означает что для описания 1 секунды аналогового сигнала нужно передать в 2 раза больше информации, соответственно нужно уже 16384*2=32768 бита. Но в то же время более узкий прямоугольник описывает более точно аналоговый сигнал. В самом деле взгляните на рисунок-

там где при 128 битах расположен 1 прямоугольник, при 256 располагается уже 2, значит и форму сигнала он передаст более точно. Но одновременно с этим возрастает и поток данных. Именно таким образом происходит оцифровка аналогового сигнала. Существует еще так называемый «плавающий битрейт«, он работает по следующему принципу: АЦП определяет участки где сигнал не имеет резких перепадов и изменений, тогда он понижает степень сжатия на этом участке- соответственно понижается битрейт, при частых сменах уровня сигнала и его перепадах требуется больше информации чтобы описать более точно сигнал и АЦП повышает битрейт. Этот вид сжатия позволяет экономить информацию передаваемую АЦП. Да, внешний вид оцифрованного сигнала не имеет такой плавности, он, скорее, построен из отрезков, описывающих этот сигнал, но зато его уже можно передавать и восстанавливать при частичной утере битов! Существует теорема Котельникова которая звучит примерно так:-«Любой цифровой сигнал можно восстановить если частота преобразования выше частоты сигнала в 2 раза». Т.е. для восстановления аналогового сигнала в 20 кГц исходный сигнал должен быть не менее 40 кГц. Поэтому при качественных записях ставят качество 44кГц, а то и 96кГц! Это позволяет передавать более точно сигнал и, опять же , при утере битов восстанавливать потерянную информацию.
Как же все это относится к ARDUINO. Нам уже известно что цифровые входы/выходы работают в 8-битном режиме. Значит на порт постоянно передается информация из 8 сочетаний нолей и единиц, например число 110 из предыдущего примера передается как 01101110, МК сам расшифровывает его (если это необходимо) и получает точное значение. Предел 8 битных значений- от 0 до 255.
Аналоговые входы содержат 10- битный АЦП (Аналогово- Цифровой Преобразователь) и получается что любой поступающий аналоговый сигнал преобразуется в цифру но содержит уже не 8 сочетаний нолей и единиц а 10! Т.е. повышается точность получаемых данных! Предел 10-битных значений- от 0 до 1023.
Например, возьмем напряжение 5В и распределим его на 8 и на 10 бит. Значение 1 единицы 8-битных данных= 5/256=0,02В, 10-битное=5/1024=0,005В. Налицо более высокая точность 10-битных данных! Но в то же время просто соединить 10 и 8 битные данные нельзя из за их максимальных значений. 8-битный порт будет постоянно переполняться и вести себя крайне неадекватно, о чем было написано здесь. 10-битная шина будет оказываться постоянно недогруженная и будет работать с 8-битовыми значениями только в своем нижнем пределе. Преобразовывать можно несколькими способами. Чтобы преобразовать сигнал из 10- в 8-битное значение нужно просто разделить 10-битный сигнал на 4, как написано в примере здесь. Чтобы 8-битный сигнал привести к 10-битному нужно, соответственно, 8-битный сигнал умножить на 4. Кроме того в ARDUINO есть замечательная функция маппинга, т.е. можно растягивать/сжимать любое значение. Выглядит она так:
y = map(x, 1, 50, 25, 100); — где, х- значение которое нужно обработать, т.е. преобразовать из одного типа в другой, 1-нижний предел преобразуемого значения, 50- верхний предел преобразуемого значения, 25- нижний предел преобразованного значения, 100- верхний предел преобразованного значения.
Пример:
/* Map an analog value to 8 bits (0 to 255) */
void setup() {}
void loop()
{
int val = analogRead(0);
val = map(val, 0, 1023, 0, 255);
analogWrite(9, val);
}
Данный пример преобразует полученные данные с аналогового порта 0 (0-1023) в 8- битный цифровой сигнал (0-255), присваивает полученное значение в переменную val и передает его в 9 цифровой порт, который является ШИМ-портом. Т.е. эту функцию можно с успехом использовать здесь и не делить полученные данные на 4 для перевода из 10-битного значения в 8-битное (Хотя, если честно, получается совершенно такой же результат). Кроме того, данная функция позволяет более точно преобразовывать нужные участки данных и поэтому её использование более предпочтительно во всех случаях. Например вам не надо обрабатывать ВЕСЬ поток поступающих данных а ограничится значением до 511 по аналоговому входу. Тогда пример будет выглядеть так:
/* Map an analog value to 8 bits (0 to 255) */
void setup() {}
void loop()
{
int val = analogRead(0);
val = map(val, 0, 511, 0, 255);
analogWrite(9, val);
}
Заметьте что 10- битный сигнал от 0 до 511 преобразовался в 8- битный от 0 до 255 (По сравнению с предыдущим примером мы «сжали» аналоговый сигнал и теперь на 1 бит цифрового сигнала приходится 512/256=2 бита аналогового, в предыдущем примере на 1 цифровой бит приходилось 1024/256=4 бита аналогового сигнала ). Так же можно повышать/ понижать любые пределы, т.е. при записи val = map(val, 255, 768, 70, 198); мы сдвинули как диапазон по приему (255-768), так и ограничили значение val (70-198). Таким образом происходит преобразование аналогового сигнала в цифровой.
ШИМ выходы не могут быть «наполовину включенными», т.к. это все равно- цифровой выход и он может принимать только 2 значения- 0 (выключено) или 1 (включено). Поэтому последовательность нулей и единиц задает время включения нагрузки. Нагрузка не успевает за такое короткое время включиться на полную мощность (если конечно не передается значение 255 на 8 битном выходе). Покажу это на примере числа 110 из верхнего примера.

Как видно из рисунка выход не включен на полную мощность, он включен всего в 5 битах из 8. Последовательность битов и определяет на какое время включается нагрузка, которая за это время просто не успевает развить полную мощность и работает на такую мощность, которую предает МК. Выходит что МК просто очень быстро включает/выключает нагрузку и таким образом регулирует напряжение на нагрузке. Например, если бы это была нагрузка типа лампы накаливания на 220В или ТЭНа на 220В, в данном случае она работала бы так как будто на нее подали напряжение приблизительно 100В! А так как скорость переключения битов очень высокая мы даже не заметим мерцания лампы (она же то и дело включается/отключается). Получается что мы регулируем напряжение шириной и частотой импульсов. Это и есть ШИМ- модуляция.