Нет.
Да.
Нужна , только руки кривые, самому не осилить
А я вот смотрю сюда и думаю, а стоит ли изобретать велосипед ?
https://github.com/adafruit/Adalight.../LEDstream.pde
может воспользоваться этим скетчем ? тем более поддержка АДА в LightPack'e уже есть.... А в АДА есть поддержка WS2801....
Тоже хорошее решение.
Только по скетчу пока не пойму как они определяют границы, кадров.
Вроде вижу синхросигнал "Ada" от контроллера в компьютер - запрос получения данных для очередного кадра.
Но как определяется конец данных для кадра, пока не пойму.
Вроде похоже на таймаут ожидания получения порции данных, но пока не уверен на 100%.
Кстати они у себя на странице ссылаются на использование LightPack, как на утилитку с дружественным GUI и хорошей производительностью
http://learn.adafruit.com/adalight-d...ftware-options
Ну в коде вроде все описали...
После magic word (Ada) идет 16битное значение количества светодиодов(только количество начинается с 0, т.е. для 120 светодиодов прилетает 119).....Код:immediately following the magic word // are three bytes: a 16-bit count of the number of LEDs (high byte // first) followed by a simple checksum value (high byte XOR low byte // XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B, // where 0 = off and 255 = max brightness.
далее чексум по формуле (high byte XOR low byte XOR 0x55). ну а далее цвета.... кстати в коде(во втором скетче ) написано, что у WS2801 цвета перепутаны. Кстати может добавить опцию порядка цветов на уровне Host'а ?
Ну а если я не ошибаюсь, то где-то тут весь буфер уходит в SPI:
Код:case MODE_DATA: while(spiFlag && !(SPSR & _BV(SPIF))); // Wait for prior byte if(bytesRemaining > 0) { if(bytesBuffered > 0) { SPDR = buffer[indexOut++]; // Issue next byte bytesBuffered--; bytesRemaining--; spiFlag = 1;
Не работает
Требует дополнительно к файлам из комплекта LightPack 5.8.6-1 библиотеку libstdc++-6.dll
После добавления ругается:
"Точка входа в процедуру _ZN6QMutex12lockInternalEv не найдена в библиотеке DLL QtCore4.dll"
Сама библиотека QtCore4.dll в каталоге с программой присутствует.
МАКС, во! У меня такая же была ошибка кода я пытался скомпилировать LightPack из свежих исходников
Для запуска тестовой версии, нужны файлы из архива с программой на 255 зон для ardulight
http://www.compcar.ru/forum/attachme...2&d=1344572460
MAKC, думал тут думал, а ведь все очень просто получается с кодом управления через SPI.. что то типа
на ошибки проверил, а вот как работает к сожалению пока не могу... так что тебе карты в руки... но по логике должно все работать....Код:#include <SPI.h> unsigned long LastByteTime, t; uint8_t data; void setup() { Serial.begin(115200); SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(SPI_CLOCK_DIV16); // 1 МГц //DDRB |= _BV(PORTB5); // Enable output for LED //PORTB &= ~_BV(PORTB5); // LED off //PORTB |= _BV(PORTB5); // LED on }//setup() void loop() { // for(;;){ t= millis(); if ((data = Serial.read()) >= 0) { LastByteTime = t; //if (data == 255){delay(1);continue;} //подождем 1мс для след кадра if (data == 255){delay(1);return;} //подождем 1мс для след кадра else{ while(!(SPSR & _BV(SPIF))); SPDR = data; } }else{ //гасим подсветку если нет потока более 10 сек if((t - LastByteTime) > 10000) { for(char i=0; i<255; i++) { SPDR = 0;while(!(SPSR & _BV(SPIF))); } delay(1); // подождем 1мс LastByteTime = t; // Reset counter } } // }//for }
Последний раз редактировалось HiddenPilot; 03.09.2012 в 22:13.
Очередная итерация скетча для работы с WS2801.
1. проверена работа в паре с другой Ардуиной в режиме SPI приемника, соотвественно исправлены все ошибки.
2. заменены библиотеки COM порта на более легкие и быстрые.
3. произведена оптимизация в сторону максимального отказа от Ардуиновских библиотек.
4. После оптимизаций прошивка на порядок полегчала , с 3.16кб до 0,85кб. Думаю, так же улучшилась отзывчивость кода.
Сам скетч:
(некоторые комментарии оставил для понимания кода)
Если кому-нибудь нужно, могу дополнительно выложить Скетч для Ардуино, который переводит мегу в режим приемника SPI и посылает принятые данные из шины SPI на COM порт. Очень удобно для отладки...Код:#include <util/delay.h> #include <smallUart.h> //#include <SPI.h> unsigned long LastByteTime, t; uint8_t data,byte_count = 0; void setup() { UART_Init(115200); //Заменяем команду SPI.begin(); //SPI.begin(); DDRB |= (1<<MOSI) | (1<< SCK) | (1<<SS); PORTB |= _BV(PORTB2); PORTB &= ~((1<<PORTB3)|(1<<PORTB5)); //SPI.setBitOrder(MSBFIRST); //SPI.setDataMode(SPI_MODE0); //SPI.setClockDivider(SPI_CLOCK_DIV16); // 1 МГц SPCR = 1; SPSR = 0; // 1 МГц; MSBFIRST; SPI_MODE0 //SPCR = 1; SPSR = 1; // 2 МГц; MSBFIRST; SPI_MODE0 //SPCR = 2; SPSR = 1; // 0.5 МГц; MSBFIRST; SPI_MODE0 }//setup() void loop() { //for(;;){ t= millis(); if (UART_ReadByte(data)){ LastByteTime = t; //if (data == 255){_delay_ms(1);continue;} //подождем 1мс для след кадра(for(;;)) if (data == 255){_delay_ms(1);return;} //подождем 1мс для след кадра(loop()) else{ // PORTB &= ~_BV(PORTB2); // для отладки: SS off, начинаем передачу SPDR = data;while(!(SPSR & _BV(SPIF))); //PORTB |= _BV(PORTB2); // для отладки: SS on, закончили передачу } }else{ //гасим подсветку если нет потока более 10 сек if((t - LastByteTime) > 10000) { for(int8_t i=0; i<255; i++) { SPDR = 0;while(!(SPSR & _BV(SPIF))); } _delay_ms(1); // подождем 1мс LastByteTime = t; } } //}//for }
PS: библиотеку SmallUart можно взять отсюда
Последний раз редактировалось HiddenPilot; 03.09.2012 в 22:17.
Продолжение темы/Очередная доработка:
Отказался от библиотеки SmallUart, так что теперь нет необходимости скачивать библиотеку SmallUart. Основные функции перенес в скетч.
После очередной оптимизации программа снова "похудела" почти на 200 байтКод:#include <util/delay.h> //#include <smallUart.h> //#include <SPI.h> unsigned long LastByteTime, t; uint8_t data; void setup() { //Инициализация UART UBRR0L = 16;UBRR0H = 0; //115200 //UBRR0L = 34;UBRR0H = 0; //57600 UCSR0A = ( 1<<U2X0 ); //UART_DOUBLESPEED UCSR0C=((1<<UCSZ01) | (1<<UCSZ00)); //Set Frame Format UCSR0B = ((1<<TXEN0) | (1<<RXEN0)); //Enable The receiver and transmitter //Инициализация SPI; //SPI.begin(); DDRB |= (1<<MOSI) | (1<< SCK) | (1<<SS); PORTB |= _BV(PORTB2); PORTB &= ~((1<<PORTB3)|(1<<PORTB5)); //SPI.setBitOrder(MSBFIRST); //SPI.setDataMode(SPI_MODE0); //SPI.setClockDivider(SPI_CLOCK_DIV16); // 1 МГц SPCR = 1; SPSR = 0; // 1 МГц; MSBFIRST; SPI_MODE0 //SPCR = 1; SPSR = 1; // 2 МГц; MSBFIRST; SPI_MODE0 //SPCR = 2; SPSR = 1; // 0.5 МГц; MSBFIRST; SPI_MODE0 }//setup() bool Read_Next_Byte(uint8_t& data) { if (_SFR_MEM8(0xC0) & (1<<7)) //(UCRA & (1<<UART_RXREADY)) { data = _SFR_MEM8(0xC6); //data = UDR; return true; } else return false; } void loop() { //for(;;){ t= millis(); if (Read_Next_Byte(data)){ //if (true){ LastByteTime = t; //if (data == 255){_delay_ms(1);continue;} //подождем 1мс для след кадра(for(;;)) if (data == 255){_delay_ms(1);return;} //подождем 1мс для след кадра(loop()) else{ // PORTB &= ~_BV(PORTB2); // для отладки: SS off, начинаем передачу SPDR = data;while(!(SPSR & _BV(SPIF))); //PORTB |= _BV(PORTB2); // для отладки: SS on, закончили передачу } }else{ //гасим подсветку если нет потока более 10 сек if((t - LastByteTime) > 10000) { for(int8_t i=0; i<255; i++) { SPDR = 0;while(!(SPSR & _BV(SPIF))); } _delay_ms(1); // подождем 1мс LastByteTime = t; } } //}//for }
Знаковое число получилось )))Размер скетча в двоичном коде: 666 байт
Последний раз редактировалось HiddenPilot; 03.09.2012 в 22:16.
Эту тему просматривают: 2 (пользователей: 0 , гостей: 2)