«Вручную» генерация ШИМ-сигнала

Я пытался, просто из любопытства, написать свою собственную функцию, которая генерирует ШИМ-сигнал, точно так же, как analogWrite(), и зажигает светодиод. Вот моя попытка:

const int pin = 3;
int cycle = 2; // AnalogWrite() выводит сигнал частотой 498 Гц, поэтому каждый цикл занимает примерно 2 мс

int duty = 0.5; // для 50% рабочего цикла

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

void loop() {
  digitalWrite(pin,HIGH);
  delay(cycle*duty);
  digitalWrite(pin,LOW);
  delay(cycle*(1-duty));
}

Светодиод горит, но очень тускло, как показано ниже:

Яркость светодиода с моим кодом

Однако при использовании analogWrite() с рабочим циклом 50% для достижения того же результата светодиод светится намного ярче:

Яркость светодиода с аналоговой записью (контакт, 128)

Что-то не так с моим кодом или есть особая причина, по которой с помощью analogWrite() рассеивается больше энергии?

, 👍1

Обсуждение

Вы пробовали разные значения в цикле?, @jsotola

Я только что попробовал это, и действительно, яркость увеличивается по мере уменьшения значений цикла. Однако мне пришлось использовать значения цикла всего 2 микросекунды, чтобы получить яркость, сравнимую с яркостью, предоставляемой analogWrite(). Я действительно не могу понять, почему, поэтому я был бы очень признателен, если бы вы могли дать некоторые разъяснения. :), @Vinícius Peixoto

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


1 ответ


Лучший ответ:

4

Вам необходимо проверить свой код, а также возможности Arduino UNO.

  • int объявляет целое число. Таким образом, int duty = 0,5; будет округлен до 0 или 1.
  • delay(0); также не будет работать. Инструкция просто будет пропущена. Вероятно, причина, по которой вы получаете более яркий светодиод. Попробуйте использовать delayMicroseconds();, если вам нужно меньшее время, но минимальная задержка, которую вы можете иметь, составляет 4 мкс для Arduino UNO.
  • Если вы используете время всего 2 мкс, то из приведенного выше комментария функции delayMicroseconds(); будет недостаточно. Кроме того, следует учитывать накладные расходы цикла, которые составят несколько микросекунд.

В целом это не лучший метод. Если вы хотите создавать свои собственные сигналы ШИМ, гораздо лучше использовать аппаратные таймеры. Например, это руководство на веб-сайте Arduino. Вы также сможете найти сообщения об аппаратных таймерах на Arduino SE.

,