Динамическая скважность ШИМ в каждом ипульсе

Необходимо сформировать сигнал с переменной скважностью. Это для управления адресными диодами на чипе LPD1886, Библиотека FastLED теоретически должна ими управлять, но практически полная каша (((

Предположим мы хотим запулить цепочку байт 0xAAAAAAAAA - т.е. в бинарном виде это последовательно 1010101… и т.д.
Каждый бит в посылке это последовательно высокий и затем низкий уровень.
bit = 0 : High ~200 ns Low ~ 600 ns
bit =1 : High ~600 ns Low ~200 ns

Вот вроде бы ШИМ, но надо в каждом импульсе выставлять разную скважность (duty). Как??? Всю голову сломал…

Пробую сделать на Timer1. Если просто сформировать ШИМ без прерываний, то в тайминги укладываюсь. Все замечательно. По идее надо бы подключить прерывание и внутри него изменять динамически скважность. Вот только Arduino Nano сразу начинает виснуть (((( Пробовал разные комбинации, но как то не выходит. Если ширину импульса увеличить до нескольких ms , то получасется, но это слишком медленно и чип светодиода не воспринимает это как управляющую посылку.

Подскажите, как контроллировать скважность ШИМ в каждом импульсе?! Или может есть другие идеи?

Странный вывод

Приведите хоть один довод, почему Вы считаете, что это имеет хоть какое-то отношение к широтно-импульсной модуляции.
Ну, например, что именно Вы считаете модулирующим сигналом, и что - модулируемым?

1 лайк

Ассемблерная вставка кажется из-за “жестких таймингов”. Мне помогали, люди понимающие на форуме есть.
…ШИМ, видимо ошибочное представление передачи кодированных данных.

Нужно разобраться с этим

а не выносить мозг себе и людям ))

1 лайк

:slight_smile:
Амплитудная модуляция?

Никак. По крайней мере не на атмеге. Прерывания слишком медленный инструмент для этого.

Выше правильно написали - посмотрите как это сделано в либе Фастлед для обычной ленты и переделайте под свои тайминги.

Я не это имел в виду. Нужно заставить работать FastLED, она эти чипы поддерживает

Точно пробовал? А почему мы их не видим?

А так-то, всё правильно мужики сказали. Это не про ШИМ

Давайте уточню…

FastLED по факту не работает с этим чипом!

Почему я говорю о ШИМ. Да просто вот мои эксперименты:

#include <Arduino.h>
#include <util/atomic.h>

void setup() {
    Serial.begin(115200); //,SERIAL_8N1,SERIAL_TX_ONLY);
    while(!Serial) delay(0);

    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);

    ATOMIC_BLOCK(ATOMIC_FORCEON){ 
        TCCR1B = 0x18; // 0001 1000, Disable Timer 
        TCCR1A = 0xA2; // 1010 0010

        ICR1  = 14;
        OCR1A = (int) (ICR1 * 0.25);
        OCR1B = (int) (ICR1 * 0.70);
        TCNT1=0x0;

        TCCR1B |= 1; // Prescale=1, Enable Timer 
    }
}

void loop() {
}

Смотрим логическим анализатором на ноги 9 и 10

Верхний график - посылаем цепочки сплошных нулей - черный цвет.
Нижний - посылаем все единички - все каналы 0xFFF , т.е. белый цвет.

Никто не будет возражать, что это именно ШИМ ?! Для нулей заполнение (скважность) 25%, для единичек 75%.

Тыкаем управляющий провод от ленты диодов в ногу 9 - все диоды гаснут. Тыкаем в ногу 10 - все горят белым цветом.

И вот теперь вопрос - как эти 2 ШИМа объединить так, чтобы каждый такт выдавать либо 1 либо 0 ??!!!

Я пробовал включать в прерывания что-то вот такое в разных комбинациях:

ISR(TIMER1_OVF_vect){
    OCR1B = 10;
}
ISR(TIMER1_COMPB_vect) {
    OCR1B = 10;
}

void setup() {
    .....
    TIMSK1 = (1 << TOIE1) | (1 << OCIE1B);
    .....

МК виснет на такой конструкции и начинает дышать только если увеличить период ШИМа, но это уже совсем другие медленные тайминги , которые чип отказывается принимать ((( Повторюсь - комбинации прерываний делал разные!

В общем мозг кипит…

Пойду-ка я за попкорном схожу ))

1 лайк

Как уже сказали, нужный вам ШИМ невозможно реализовать на NANO через прерывания.
Если у вас есть логический анализатор, то методом осознанного тыка можно подобрать изменение алгоритма для FastLed. В последних версиях там не привычный синтаксис, но с анализатором наверно проще разобраться. Или изменить более легкие библиотеки - например Gyver microLED

Мдя… Печалька (((( Сейчас попробовал в лоб написать говнокод …

#include <Arduino.h>
#include <util/atomic.h>

#define D9_Low  PORTB &= B11111101
#define D9_High PORTB |= B00000010

void setup() {
  Serial.begin(115200); 
  while(!Serial) delay(0);

  pinMode(9, OUTPUT);
}

void loop() {
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
    for( int i=0; i < 36 * 5; i++ ){
      D9_High;D9_High;
      D9_Low;D9_Low;D9_Low;
    }
  }
  delay(150);
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
    for( int i=0; i < 36 * 5; i++ ){
      D9_High;D9_High;D9_High;D9_High;
      D9_Low;
    }
  }
  delay(150);
}

Работает. Ленточка весело моргает 5-ю диодами. Но как же это убого :frowning:

PS: i < 36 * 5 - один диод - это пачка из 36 бит. Да-да! У этого чипа 12 битная глубина цвета на каждый канал )))

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

Вау!!! И где купили?

Да это из старых запасов достал )))) Не знаю, продается ли сейчас такое - не смотрел. У меня просто 2000+ таких чипов в модуль запаянных вместе с диодами.

А тайминг у этого чипа конечно лютый -

И на меня захвати!

1 лайк

Да, ничего особо лютого. В полтора раза быстрее 2812. Так и битов надо в полтора раза больше пересылать.

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

Такая программа пишется несложно. Пишется (я писал на ассемблере) передача, при этом считается сколько тактов потрачено на накладные расходы, а остальные такты для тайминга добираются нопами. У меня есть такая программа для 8212. Тут также только тайминги другие и 36-бит.

И да, чуть не забыл.

Не разбирался, правда это или нет, но если бы мне нужно было бы, чтобы заработал, я бы заменил функцию showRGBInternal в файле clockless_trinket.h на вышеописанную свою и заработал бы, куда ему деваться.

1 лайк

sketch.ino - Wokwi ESP32, STM32, Arduino Simulator

Тут можно подкрутить …