Доброй ночи... Уже 2 дня пытаюсь сделать фоновую подсветку Эмбилайт на ArduinoMaga1280. С ардуино играюсь недавно...С электронной частью разобрался а вот с програмной.....беда. Вопщем нужно сделать выход на 30 ШИМ каналов... Стандартно (аппаратно) их 15 (12 справа и 3 снизу на большом разъёме). Я нарыл библиотеку softPWM которая вроде как делает софтово ШИМ. Но и она только на 16. Решил написать (спарить) оба варианта чтоб получить 30 ШИМов только что то не как не получается....ардуинка прошивается, запускаю программу эмбилайт...Светодиод моргает (tx-rx) но лампочки не горят.... видимо в коде что то не так или так реализовать не возможно? Код (Text): #define D2_High PORTE |=B00010000 //red line-1 on #define D2_LOW PORTE &= B11101111 //red line-1 off #define D3_High PORTE |=B00100000 //green line-1 on #define D3_LOW PORTE &= B11011111 //green line-1 off #define D4_High PORTG |=B00100000 //blue line-1 on #define D4_LOW PORTG &= B11011111 //blue line-1 off #define D5_High PORTE |=B00001000 //red line-2 on #define D5_LOW PORTE &= B11110111 //red line-2 off #define D6_High PORTH |=B00001000 //green line-2 on #define D6_LOW PORTH &= B11110111 //green line-2 off #define D7_High PORTH |=B00010000 //blue line-2 on #define D7_LOW PORTH &= B11101111 //blue line-2 off #define D8_High PORTH |=B00100000 //red line-3 on #define D8_LOW PORTH &= B11011111 //red line-3 off #define D9_High PORTH |=B01000000 //green line-3 on #define D9_LOW PORTH &= B10111111 //green line-3 off #define D10_High PORTB |=B00010000 //blue line-3 on #define D10_LOW PORTB &= B11101111 //blue line-3 off #define D11_High PORTB |=B00100000 //red line-4 on #define D11_LOW PORTB &= B11011111 //red line-4 off #define D12_High PORTB |=B01000000 //green line-4 on #define D12_LOW PORTB &= B10111111 //green line-4 off #define D13_High PORTB |=B10000000 //blue line-4 on #define D13_LOW PORTB &= B01111111 //blue line-4 off #define D44_High PORTL |=B00100000 //red line-4 on #define D44_LOW PORTL &= B11011111 //red line-4 off #define D45_High PORTL |=B01000000 //green line-4 on #define D45_LOW PORTL &= B10111111 //green line-4 off #define D46_High PORTL |=B10000000 //blue line-4 on #define D46_LOW PORTL &= B01111111 //blue line-4 off volatile unsigned int tcnt2; volatile byte pwm_time; unsigned long blank=0; #include <SoftPWM.h> uint8_t leds[15] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36}; byte volatile color[15]; unsigned long night=0; void setup() { Serial.begin(115200); for (int i=2; i < 15; i++){pinMode(i, OUTPUT);} TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2 TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора tcnt2 = 252; // 16000000/31000/64=8 tcnt2=256-8=248. TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2. SoftPWMBegin(); for (int n = 0; n < 15; n++) SoftPWMSet(leds[n], 0); SoftPWMSetFadeTime(ALL, 5, 5); } void loop() { if (Serial.available() > 15) { if (Serial.read() == 255) //проверка прификса { for (int i = 0; i < 15; i++) { color[i] = Serial.read(); // прочитать данные о цветах из порта в массив } // if (Red_R_Old == color[0] && Green_L_Old == color[4] && Blue_T_Old == color[8]) blank=0; } } else { if(blank>100000) { blank=0; for (byte i = 0; i < 15; i++) color[i] = 0;} blank++; } } //****************обработчик прерывания******************** ISR(TIMER2_OVF_vect) { TCNT2 = tcnt2; pwm_time++; if(color[0] > pwm_time ) D2_High; else D2_LOW; if(color[1] > pwm_time ) D3_High; else D3_LOW; if(color[2] > pwm_time ) D4_High; else D4_LOW; if(color[3] > pwm_time ) D5_High; else D5_LOW; if(color[4] > pwm_time ) D6_High; else D6_LOW; if(color[5] > pwm_time ) D7_High; else D7_LOW; if(color[6] > pwm_time ) D8_High; else D8_LOW; if(color[7] > pwm_time ) D9_High; else D9_LOW; if(color[8] > pwm_time ) D10_High; else D10_LOW; if(color[9] > pwm_time ) D11_High; else D11_LOW; if(color[10] > pwm_time) D12_High; else D12_LOW; if(color[11] > pwm_time) D13_High; else D13_LOW; if(color[12] > pwm_time ) D44_High; else D44_LOW; if(color[13] > pwm_time) D45_High; else D45_LOW; if(color[14] > pwm_time) D46_High; else D46_LOW; if (Serial.available() > 15) { if (Serial.read() == 255) { for (int n = 0; n < 15; n++) { color[n] = Serial.read(); } night=0; } } else { if(night>30000) { night=0; for (byte n = 0; n < 15; n++) color[n] = 0;} night++; } for (int n = 0; n < 15; n++) SoftPWMSet(leds[n], color[n]); }
Сложно что-то сказать, не имея конструкции перед собой. Но давайте по-порядку. Зачем нужно 30 PWM? Видимо, у лампы что-то около 7 мест свечения и для каждого места 3 PWM входа задают RGB-цвет свечения. Я правильно понимаю? То, что RX/TX мигает — это хороший знак, похоже, что что-то не то с аппаратным подключением. Вам удавалось, не используя SoftPWM, заставить светиться и менять свет хотя бы один кусочек лампы?
30 PWM нужно для 30 отдельных светящихся светодиодов тоесть для 10 RGB. По softPWM всё работает до 16 PWM и по Аппаратному до 15. межет каналы софт и аппаратные друг на друга накладываются...?
Отлично: поделил 30 на 3 в уме и получил 7,66 Код (Text): for (int i=2; i < 15; i++) {pinMode(i, OUTPUT);} Есть подозрение, что пины 2 и 3 нужны для работы прерываний. Можете попробовать их не трогать?
почему 7 то вроде 10... нет? Прилагаю 2 скейча один софтовый другой аналоговый. оба рабочие. Код (Text): #include <SoftPWM.h> uint8_t leds[15] = {22, 23, 24, 25, 26, 27, 28, 29, 30,31, 32, 33, 34, 35, 36}; byte volatile color[15]; unsigned long night=0; void setup() { Serial.begin(115200); SoftPWMBegin(); for (int i = 0; i < 15; i++) SoftPWMSet(leds[i], 0); SoftPWMSetFadeTime(ALL, 5, 5); } void loop() { if (Serial.available() > 15) { if (Serial.read() == 255) { for (int i = 0; i < 15; i++) { color[i] = Serial.read(); } night=0; } } else { if(night>30000) { night=0; for (byte i = 0; i < 15; i++) color[i] = 0;} night++; } for (int i = 0; i < 15; i++) SoftPWMSet(leds[i], color[i]); } и аналоговый Код (Text): #define D2_High PORTE |=B00010000 //red line-1 on #define D2_LOW PORTE &= B11101111 //red line-1 off #define D3_High PORTE |=B00100000 //green line-1 on #define D3_LOW PORTE &= B11011111 //green line-1 off #define D4_High PORTG |=B00100000 //blue line-1 on #define D4_LOW PORTG &= B11011111 //blue line-1 off #define D5_High PORTE |=B00001000 //red line-2 on #define D5_LOW PORTE &= B11110111 //red line-2 off #define D6_High PORTH |=B00001000 //green line-2 on #define D6_LOW PORTH &= B11110111 //green line-2 off #define D7_High PORTH |=B00010000 //blue line-2 on #define D7_LOW PORTH &= B11101111 //blue line-2 off #define D8_High PORTH |=B00100000 //red line-3 on #define D8_LOW PORTH &= B11011111 //red line-3 off #define D9_High PORTH |=B01000000 //green line-3 on #define D9_LOW PORTH &= B10111111 //green line-3 off #define D10_High PORTB |=B00010000 //blue line-3 on #define D10_LOW PORTB &= B11101111 //blue line-3 off #define D11_High PORTB |=B00100000 //red line-4 on #define D11_LOW PORTB &= B11011111 //red line-4 off #define D12_High PORTB |=B01000000 //green line-4 on #define D12_LOW PORTB &= B10111111 //green line-4 off #define D13_High PORTB |=B10000000 //blue line-4 on #define D13_LOW PORTB &= B01111111 //blue line-4 off #define D44_High PORTL |=B00100000 //red line-4 on #define D44_LOW PORTL &= B11011111 //red line-4 off #define D45_High PORTL |=B01000000 //green line-4 on #define D45_LOW PORTL &= B10111111 //green line-4 off #define D46_High PORTL |=B10000000 //blue line-4 on #define D46_LOW PORTL &= B01111111 //blue line-4 off volatile unsigned int tcnt2; volatile byte pwm_time; //byte pwm_time, Red_R_Old, Green_L_Old, Blue_T_Old; unsigned long blank=0; //таймер простоя byte volatile color[15]; //массив храннения цветов 12-ть каналов void setup() { for (int i=2; i < 14; i++){pinMode(i, OUTPUT);} Serial.begin(115200); TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2 TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора tcnt2 = 252; // 16000000/31000/64=8 tcnt2=256-8=248. TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2. } void loop() { if (Serial.available() > 15) { if (Serial.read() == 255) //проверка прификса { for (int i = 0; i < 15; i++) { color[i] = Serial.read(); // прочитать данные о цветах из порта в массив } // if (Red_R_Old == color[0] && Green_L_Old == color[4] && Blue_T_Old == color[8]) blank=0; } } else { if(blank>100000) { blank=0; for (byte i = 0; i < 15; i++) color[i] = 0;} blank++; } } //****************обработчик прерывания******************** ISR(TIMER2_OVF_vect) { TCNT2 = tcnt2; pwm_time++; if(color[0] > pwm_time ) D2_High; else D2_LOW; if(color[1] > pwm_time ) D3_High; else D3_LOW; if(color[2] > pwm_time ) D4_High; else D4_LOW; if(color[3] > pwm_time ) D5_High; else D5_LOW; if(color[4] > pwm_time ) D6_High; else D6_LOW; if(color[5] > pwm_time ) D7_High; else D7_LOW; if(color[6] > pwm_time ) D8_High; else D8_LOW; if(color[7] > pwm_time ) D9_High; else D9_LOW; if(color[8] > pwm_time ) D10_High; else D10_LOW; if(color[9] > pwm_time ) D11_High; else D11_LOW; if(color[10] > pwm_time) D12_High; else D12_LOW; if(color[11] > pwm_time) D13_High; else D13_LOW; if(color[12] > pwm_time ) D44_High; else D44_LOW; if(color[13] > pwm_time) D45_High; else D45_LOW; if(color[14] > pwm_time) D46_High; else D46_LOW; По отдельности великолепно работают. со 2 и 3 пином. Или всё таки убрать 2и3?