Эт, каэшна, наша недоработка! Сорян!
Фсё патамушта еще не пятница. Погоди чутка. Нужно с мыслЯми собраццо.
Эт, каэшна, наша недоработка! Сорян!
Фсё патамушта еще не пятница. Погоди чутка. Нужно с мыслЯми собраццо.
А что же тогда в первом посте?
ага… только не работает.
На АВР любой IR приемник конфликтует с адресной лентой. Пока лента обновляется, ничего приниматся не будет.
Для более конкретного ответа нужно видеть полный код, причём не тот что по ссылке, а ваш - с добавленным ИК приемником.
Вечером выложу, но код большой пожалуй строк 400. Подскажите как сделать спойлер.
выделить текст и нажать шестерёнку
Это очень маленький
Большой код - это когда 400 файлов по 400 строк в каждом, а не 400 строк всего.
При использование кода указание авторства обязательно
****************************************************************/
[details="Спойлер"]
#include "Adafruit_NeoPixel.h"
#include <EEPROM.h>
#include "ffft.h"
//#include <avr/pgmspace.h>
//#include <math.h>
#include <NecDecoder.h>
NecDecoder ir;
typedef struct
{
uint8_t baseColor;
uint8_t age;
uint8_t magnitude;
uint8_t rnd;
} peak_t;
#define DEBUG false //false //режим отладки true
#define N_BANDS 8 //число светодиодов для индикации в режиме настройки яркости
#define N_FRAMES 5
#define N_PEAKS 25
#define N_MODES 18//9 //19 общее количество режимов!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define N_MODES_LS 9 // количество режимов цветомузыки
//---------------Световые алгоритмические схемы ---------------------
#define PATTERN_DANCE_PARTY 0
#define PATTERN_SINGLE_DIR_DANCE_PARTY 1
#define PATTERN_PULSE 2
#define PATTERN_LIGHT_BAR 3
#define PATTERN_COLOR_BARS 4
#define PATTERN_COLOR_BARS2 5
#define PATTERN_FLASHBULBS 6
#define PATTERN_FIREFLIES 7
#define PATTERN_RANDOM 8
//---------------Режимы эффектов бегущих огрней----------------------
#define PATTERN_RAINBOW 9
#define PATTERN_SPARKLE 10
#define PATTERN_COL_RANDOM 11
#define PATTERN_CYLON 12
#define PATTERN_STROBE 13
#define PATTERN_POLICE 14
#define PATTERN_BRIGHT 15
#define PATTERN_LAMP 16
#define PATTERN_FLAME 17
#define PATTERN_MATRIX 18
#define PATTERN_BALLS 19
#define PATTERN_FIRE 20
//---------------цветовые схемы---------------------
#define N_COLOR_MODES 3 //число режимов
#define COLOR_RANDOM 0 //Случайная двухцветная схема: выбраны два случайных цвета
#define COLOR_CYCLE 1 //меняется как радуга с течением времени
#define COLOR_BAND 2 //Цветные частоты. Самая низкая красного цвета, и т.д. вверх красный,оранжевый,желтый,зеленый,голубой,синий,фиолетовый,белый
//-----------------выбор конфигурации ленты--------------------------------
#define LEDCONFIG_60 0
#define LEDCONFIG_94 1//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define LEDCONFIG_120 2
//-------------------------------------------------
#define MAX_COLOR_BARS 22
#define MAXCOLORINDEX 256
#define EEPROM_MAGIC_NUMBER 0xbad1 //магическое число, для индетификации первого запуска
#define UNUSED 255
//Описание кнопок ИК пульта
#define IR_1 0xA2
#define IR_2 0x62
#define IR_3 0xE2
#define IR_4 0x22
#define IR_5 0x2
#define IR_6 0xC2
#define IR_7 0xE0
#define IR_8 0xA8
#define IR_9 0x90
#define IR_STAR 0x68
#define IR_0 0x98
#define IR_HASH 0xB0
#define IR_UP 0x18
#define IR_LEFT 0x10
#define IR_OK 0x38
#define IR_RIGHT 0x5A
#define IR_DOWN 0x4A
#define ADC_CHANNEL 0 // аналоговый вход, для аудио
#define PARM_POT 1 // аналоговый вход для потенциометрам PARAM
#define BACKGROUND ((uint32_t) 0x000006) // фоновая подсветка при тишине
#define Treshold_pot 9
#define PATTERN_BUTTON_PIN 4 // 2 Кнопка PATERN
#define COLOR_BUTTON_PIN 3 //кнопка COLOR
#define LED_PIN 13 //системный светодиод, нужно использовать выводы только с ШИМ
#define LED_STRIP_PIN 6 // пин подключения к LED ленте
#define N_LED_LAMP 50 // какое количество светодиодов использовать в светильнике
#define NUM_LED 94 //120 количество светодиодов в ленте по умолчанию !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
uint8_t N_LEDS = NUM_LED;
uint8_t MAX_AGE = 0;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LED, LED_STRIP_PIN, NEO_GRB + NEO_KHZ800);
peak_t peaks[N_PEAKS];
uint8_t peakIndex = 0;
uint8_t newPeakFlags = 0;
uint8_t mode = 0;
uint8_t pattern = 0;
uint8_t cutoffFreqBand = 7;
uint8_t colorMode = COLOR_BAND; //COLOR_CYCLE; //цветовая схема по умолчанию
uint8_t colorIndexIncFreq = 100;
uint8_t colorIndex = 0;
uint8_t randColor[] = {0, 0};
uint8_t randColorCount[] = {0, 0};
uint8_t randColorChangeParm = 10;
uint8_t ledConfig = LEDCONFIG_94;//120; //число светодиодов по умолчанию!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
uint16_t parm;
uint16_t lastParm;
uint8_t colorBars[MAX_COLOR_BARS];
uint16_t loopCounter = 0;
uint16_t loopCounterMax = 500;
boolean randomized = false;
uint8_t recentPatterns[3];
uint8_t recentPatternIndex = 0;
uint8_t transitionWaitTime = 0;
// FFT_N = 128
int16_t capture[FFT_N]; // Audio буфер захвата
complex_t bfly_buff[FFT_N]; // FFT "butterfly" buffer
uint16_t spectrum[FFT_N / 2]; // Spectrum output buffer
volatile uint8_t smp; //порог срабатывания, уровень шума NoiseThreshold=0,
volatile uint8_t samplePos = 0; // Начальнаячя позиция в буфере
uint8_t maxBrightness = 255; // яркость максимальная
float brightnessScale = 1.0; // коэффициент яркости
byte
bandPeakLevel[8], // Peak level of each band
bandPeakCounter = 0, // Frame counter for delaying the fall of the band peak
bandPeakDecay = 6, // peak decreases by 1 every bandPeakDecay frames. Larger value is slower decay
bandCount = 0; // Frame counter for storing past band data
int
band[8][N_FRAMES], // band levels for the prior N_FRAMES frames
minLvlAvg[8], // For dynamic adjustment of low & high ends of graph,
maxLvlAvg[8], // pseudo rolling averages for the prior few frames.
bandDiv[8]; // Used when filtering FFT output to 8 bands
// declare all control variables here so we can more easily measure memory consumption
uint8_t j, noiseThreshold, *data, nBins, binNum, c;
uint16_t minLvl, maxLvl;
int16_t level, sum;
const uint8_t PROGMEM noiseFloor[64] = {8, 6, 6, 5, 3, 4, 4, 4, 3, 4, 4, 3, 2, 3, 3, 4, 2, 1, 2, 1, 3, 2, 3, 2, 1, 2, 3, 1, 2, 3, 4, 4, 3, 2, 2, 2, 2, 2, 2, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4};
const uint8_t PROGMEM eq[64] = {255, 175, 218, 225, 220, 198, 147, 99, 68, 47, 33, 22, 14, 8, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const uint8_t PROGMEM bandBinCounts[] = {2, 4, 5, 8, 11, 17, 25, 37};
const uint8_t PROGMEM bandBinStarts[] = {1, 1, 2, 3, 5, 7, 11, 16};
const uint8_t PROGMEM band0weights[] = {181, 40};
const uint8_t PROGMEM band1weights[] = {19, 186, 38, 2};
const uint8_t PROGMEM band2weights[] = {11, 176, 118, 16, 1};
const uint8_t PROGMEM band3weights[] = {5, 55, 165, 164, 71, 18, 4, 1};
const uint8_t PROGMEM band4weights[] = {3, 24, 89, 139, 148, 118, 54, 20, 6, 2, 1};
const uint8_t PROGMEM band5weights[] = {2, 9, 29, 70, 125, 172, 185, 162, 118, 74, 41, 21, 10, 5, 2, 1, 1};
const uint8_t PROGMEM band6weights[] = {1, 4, 11, 25, 49, 83, 121, 156, 180, 185, 174, 149, 118, 87, 60, 40, 25, 16, 10, 6, 4, 2, 1, 1, 1};
const uint8_t PROGMEM band7weights[] = {1, 2, 5, 10, 18, 30, 46, 67, 92, 118, 143, 164, 179, 185, 184, 174, 158, 139, 118, 97, 77, 60, 45, 34, 25, 18, 13, 9, 7, 5, 3, 2, 2, 1, 1, 1, 1};
const uint8_t PROGMEM * const bandWeights[] = {band0weights, band1weights, band2weights, band3weights, band4weights, band5weights, band6weights, band7weights};
//*******************************************************************************************************
void setup() {
{ Serial.begin(9600);
attachInterrupt(0, irIsr, FALLING);}// подключил на D2, прерывание 0
strip.setBrightness(maxBrightness);
randomSeed(analogRead(2)); // получаем стартовое случайное значение
memset(bandPeakLevel, 0, sizeof(bandPeakLevel)); //создать буфер в RAM
memset(band, 0, sizeof(band));//создать буфер в RAM
for (uint8_t i = 0; i < N_BANDS; i++)
{
binNum = pgm_read_byte(&bandBinStarts[i]);
nBins = pgm_read_byte(&bandBinCounts[i]);
minLvlAvg[i] = 0;
maxLvlAvg[i] = 512;
data = (uint8_t *)pgm_read_word(&bandWeights[i]);
for (bandDiv[i] = 0, j = 0; j < nBins; j++)
{
bandDiv[i] += pgm_read_byte(&data[j]);
}
}
for (uint8_t i = 0; i < N_PEAKS; i++)
{
peaks[i].age = 0;
peaks[i].magnitude = 0;
}
for (uint8_t i = 0; i < MAX_COLOR_BARS; i++)
{
colorBars[i] = UNUSED;
}
for (uint8_t i = 0; i < 3; i++)
{
recentPatterns[i] = UNUSED;
}
lastParm = 0;
parm = map(analogRead(PARM_POT), 0, 1023, 0, 255); //прочитать положение потенциометра PARAM
setADCFreeRunning(); //запустить прерывание от АЦП
DIDR0 = 1 << ADC_CHANNEL; // Отключение цифрового входа для указанного вывода АЦП
pinMode(PATTERN_BUTTON_PIN, INPUT_PULLUP); //кнопка PATTERN
pinMode(COLOR_BUTTON_PIN, INPUT_PULLUP); //кнопка COLOR
/* pinMode(LED_PIN, OUTPUT); //системный светодиод
for (i = 0; i < 5; i++) //мигнуть 5 раз системным светодиодом
{
digitalWrite(LED_PIN, HIGH);//включить системный светодиод
delay(50);
digitalWrite(LED_PIN, LOW); //выключить системный светодиод
delay(50);
}*/
sei(); // разрешить все прерывания
strip.begin();
strip.show();
// проверяем, есть ли сохраненные настройки EEPROM?
// если да, то считываем их
if (EEPROMValid()) //проверяем на первое включение контролера
{
ledConfig = EEPROM.read(2); //конфигурация светодиодной ленты
if (ledConfig > LEDCONFIG_94) ledConfig = LEDCONFIG_94; // EEPROM.write(2, ledConfig);}//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mode = EEPROM.read(3); //последний выбраный режим световой схемы
if (mode > N_MODES) mode = 0; // EEPROM.write(3, mode);}
pattern = mode;
if (pattern == PATTERN_RANDOM)
{
randomized = true;
pattern = chooseRandomPattern();
loopCounter = 0;
} else { randomized = false; }
maxBrightness = EEPROM.read(4); //последние сохраненные настройки яркости ленты
brightnessScale = maxBrightness / 255.0;
colorMode = EEPROM.read(5); //режим цветовой схемы
if (colorMode > COLOR_BAND) {colorMode = COLOR_BAND; EEPROM.write(5, colorMode);}
cutoffFreqBand = EEPROM.read(6); //настройки частоты среза
if (cutoffFreqBand > 7) {cutoffFreqBand = 7; EEPROM.write(6, cutoffFreqBand);}
//NoiseThreshold = EEPROM.read(7);
}
else {
test(); // запуск диагностики при первом включении питания
ledConfig = LEDCONFIG_94;//120; // если EEPROM не записана, то по умолчанию 120 LEDs,!!!!!!!!!!!!
mode = 0; // первый режим
maxBrightness = 255; //яркость максимальная
colorMode = COLOR_BAND; //цветовая схема COLOR_BAND
cutoffFreqBand = 8; //частотный срез все 8 частот
// NoiseThreshold = 4; //уровень срабатывания АЦП
saveConfig();
}
configure();
setConfig();
setParameters();
TIMSK0 = 0; // Выключить Timer0
/*#if DEBUG //для отладки
Serial.begin(115200);
Serial.println(getMemory());
// Serial.println(NoiseThreshold);
#endif*/
}
//************************************Главный цикл программы*******************************************
void loop()
{
//Пока прерывание АЦП включено, ждем завершения
// Обработчик прерывания собирает аудио семплы в буфер захвата.
while (ADCSRA & _BV(ADIE));
strip.show(); //отправляем последние сформированые данные на светодиодную ленту.
fft_input(capture, bfly_buff);// Выполнить алгоритм FFT для преобразования выборок в сложные числа.
// Чтобы получить показания потенциометра, переводим АЦП в стандартный режим
// setADCDefault(); //переводим АЦП в стандартный режим
// lastParm = parm;
// parm = analogRead(PARM_POT); //прочитать состояние потенциометра
// if (parm != lastParm) // меняем настройки если положение потенциометра было изменено
// {
// setParameters();
// }
if ((colorMode == COLOR_CYCLE) && ((loopCounter % colorIndexIncFreq) == 0))
{
colorIndex++;
}
loopCounter++;
if ((randomized) && (loopCounter > loopCounterMax))
{
loopCounter = 0;
loopCounterMax = random(500, 1000);
transitionWaitTime = determineWaitTime();
}
if (transitionWaitTime > 0)
{
transitionWaitTime--;
if (transitionWaitTime == 0)
{
pattern = chooseRandomPattern();
setParameters();
reset();
}
}
setADCDefault(); //переводим АЦП в стандартный режим
button_pattern(); //проверяем нажатие кнопки PATTERN !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
strip.setBrightness(255);
// if (ir.available()) {button_pattern(); }
digitalWrite(LED_PIN, HIGH);//включить системный светодиод
// delay(50);
if (ir.available()) {
// вывести команду (8 бит)
Serial.print("0x");
Serial.println(ir.readCommand(), HEX);
}
digitalWrite(LED_PIN, LOW); //выключить системный светодиод
// delay(50);
// проверяем нажатие кнопки COLOR
if ((digitalRead(COLOR_BUTTON_PIN) == LOW) && (digitalRead(PATTERN_BUTTON_PIN) == HIGH))
{
//digitalWrite(LED_PIN, HIGH);//включить системный светодиод
setColorMode();
}
// Если кнопки COLOR и pattern нажаты, то меняем частотные срезы
if ((digitalRead(COLOR_BUTTON_PIN) == LOW) && (digitalRead(PATTERN_BUTTON_PIN) == LOW))
{
// Both buttons held. Set cutoff frequency band.
//digitalWrite(LED_PIN, HIGH);//включить системный светодиод
setCutoffFreqBand();
}
setADCFreeRunning(); // снова настраиваем АЦП на работу по прерыванию
// The rest of the FFT computation:
fft_execute(bfly_buff); // Process complex data
fft_output(bfly_buff, spectrum); // Complex -> spectrum
// Now call this to analyze the audio. See comments in this function for details.
analyzeAudioSamples();
if (transitionWaitTime == 0) // only do this if not waiting to transition to new mode
{
// The peak values for each of the 8 bands has been computed. A bit in the 8-bit
// value newPeakFlags indicates whether the analysis found a *new* peak in the band.
for (uint8_t i = 0; i <= cutoffFreqBand; i++)
{
// If a new peak was found in band i...
if (newPeakFlags & (1 << i)) {
// Map the peak value to a magnitude in range [0,255]. We pass in the band
// number because the mapping is different for different bands.
uint8_t magnitude = getMagnitude(i, bandPeakLevel[i]);
// A nonzero magnitude means that the peak value is large enough to do
// something visually with it. We ignore small peaks.
if (magnitude > 0)
{
// We want to store the information about the peak in a peak_t structure.
// When we actually draw a visualization, the peak_t structures in peaks[]
// represent the "visually active" band peaks.
if (pattern != PATTERN_PULSE)
{
// Look through the list of peak structures 'peaks' for an unused one.
for (j = 0; j < N_PEAKS; j++)
{
if (peaks[j].magnitude == 0)
{
// unused peak found
peakIndex = j;
break;
}
}
} else {
peakIndex = i; // для импульсного режима, просто используеся пик для каждой полосы частот
}
// Если не найден, мы используем последний используемый (peakIndex).
// Инициализация структуры
peaks[peakIndex].age = 0;
peaks[peakIndex].rnd = random(255); //случайное значение для визуализации
if (colorMode == COLOR_BAND)
{
peaks[peakIndex].baseColor = i * 32;
}
if (colorMode == COLOR_RANDOM)
{
peaks[peakIndex].baseColor = getRandomBaseColor(peaks[peakIndex].rnd);
}
if (colorMode == COLOR_CYCLE)
{
peaks[peakIndex].baseColor = colorIndex;
}
peaks[peakIndex].magnitude = magnitude;
}
}
}
}
if (pattern != PATTERN_LIGHT_BAR)
{
strip.clear(); // выключаем все светодиоды в ленте
}
doVisualization(); // визуализация
}
//***********************************************************************************
void irIsr() { ir.tick();} // в прерывании вызываем tick()
//************************проверяем нажатие кнопки PATTERN**************************
void button_pattern()
{
parm = analogRead(PARM_POT); //прочитать состояние потенциометра
parm = map(parm, 0, 1023, 0, 255);//уменьшить разрядность parm
if(abs(parm - lastParm) < Treshold_pot) parm=lastParm; //фильтр шумов
if (lastParm != parm) // если положение потенциометра было изменено
{
lastParm = parm;
strip.setBrightness(parm); //изменяем яркость
}
// if (ir.available()) {
// switch (ir.readCommand()) {
// case IR_LEFT: setMode(); break;
// case IR_RIGHT: setMode(); break;
// }
// }
if ((digitalRead(PATTERN_BUTTON_PIN) == LOW) && (digitalRead(COLOR_BUTTON_PIN) == HIGH)) // Если кнопка pattern нажата
{
//digitalWrite(LED_PIN, HIGH);
setMode();
}
}
[/details]
9.10.167.168.319-322.418. Строки которые я вставил.
скока же амбиций)
я авторства не нашел, если меня стукнет молния и придется использовать ваш код, так и укажу
“Автор - НеЯ”
Возникает догадка, что неопиксель или ffft отключают прерывания. Кто нить знает так оно или нет. Обновление ленты идет чаще 50Гц. Думаю без видимых проблем можно снизить скорость кадров вдвое, а то и до 10Гц. тогда команда будет помещаться между кадрами. Подскажите в какой строке указывается частота кадров.
Второй вариант. При появлении прерывания происходит переход на обработку сигнала. а потом возврат. На скриншоте видно, что команда попала между посылками в ленту, Даже если они совпадут, то посылка гораздо длиннее и все должно получиться.
Это не мой код, писал с самого начала, читай внимательнее, и авторов указал.
Э! У меня в фамилии бува Ё. Уважайте еЁ.
Серёгин чтоле?
Вот здесь о конфликте новых версий ик библиотеки - итог откат к старой.
https://mysku.club/blog/aliexpress/68990.html
Не угадал.Нанаец я.
bёzzon или bizzёn?
Я ж намекнул. Нанаец. Группа так называлась, Их начальник ещё шёлочь туалетную выпил.
Это квест.
Нанаёц?
Лёвкин.