Заливаем шары к празднику

lilik
Offline
Зарегистрирован: 19.10.2017
//
int uploadpin=2;// вывод платы для осуществления аппаратной перезагрузки, соединён с RES

String inputString;// строки данных
int n=komanda;//переменная хранения команды-числа

 
/////////////////////////////////////////////////////////////////////////////////////////////////
//ФУНКЦИИ ПРИЁМА И ОБРАБОТКИ КОМАНД-ДАННЫХ
int CheckSerial()
{
  //////////////////////////////////////////////////////////////////////////////
  while (Serial.available())//считываем строку данных пока они поступают
  {
    char inChar = (char)Serial.read();
    if (inChar == '\n'||inChar == ' ')     //если окончание строки или запрос на загрузку
    {
      MakeCmd();//обрабатываем её данной функцией
      break;
    }
    else inputString += inChar;// иначе удлиняем строку на один символ
  }
 return n;// возвращаем значение переменной как значение всей функции 
}
/////////////////////////////////////////////////////////////////////////////////
void MakeCmd()
{
  int y = inputString.length(); // присваиваем переменной у число символов в строке
  if (y < 1 || y > 4){inputString = "";return;} //если их меньше 1 или больше 4, выходим из функции
  String cmd = inputString; // передаём строку другой переменной
  inputString = "";//"обнуляем переменную"
  //////
    
    //
   
    if (cmd == "0") {    //если получили ноль и выбрана данная плата
    Serial.write(0x14);               // ответить avrdude.exe
    Serial.write(0x10);               //  для синхронизации 
    delay(10); 
    pinMode(uploadpin,OUTPUT);        //ЭТО ВЫЗОВЕТ аппаратный РЕСЕТ
  }
  if (cmd != "0"){ n=cmd.toInt();}   // преобразуем строку в номер команды-число 
    
  //////
}

///////////////////////////////////////////////////////////////////////////////////////////////////////

Забыл, вот второй файл - скетч из 2 частей.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

lilik пишет:

Интересное явление, явно неземного происхождения мне приходиться наблюдать.

Так намедни ж полнолуние было, а в такое время и не то случается.

MaksVV
Offline
Зарегистрирован: 06.08.2015

ЕвгенийП пишет:

lilik пишет:

Интересное явление, явно неземного происхождения мне приходиться наблюдать.

Так намедни ж полнолуние было, а в такое время и не то случается.


Особенно при том, что шары все залиты)

lilik
Offline
Зарегистрирован: 19.10.2017

Явление осталось необъяснимым. Заменил на УНО, всё работает как надо, значит в платке дело.

/////////////////////////// тест цветов и эффектов для гирлянды ШАРИКОВ НА WS2812b с дистанционной заливкой скетчей на UNO
#include "Adafruit_NeoPixel.h"
#define LED_COUNT 5               //число пикселей в шаре
#define N 3                      // число шаров в гирлянде 
#define LED_COUNT_N  N*LED_COUNT   // число пикселей в ленте
#define LED_PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT_N, LED_PIN, NEO_GRB + NEO_KHZ800);// Создаем переменную strip для управления нашей лентой.
String gir="";// переменная задающая участие шара в текущем эффекте
int t=3000;// переменная задающая паузу между эффектами

long Y=0;//пременная хранения моментов времени
int komanda=1;// переменная хранения 

void setup()
{
  Serial.begin(115200);  // скорость 115200 для Arduino UNO
                         // может быть разная для разных моделей плат
 strip.begin();
 for (int i = 0; i < LED_COUNT_N; i++) {
   pixel_(i,0,0);// выключение пикселя 
  }
  strip.show();
  /////////////////////////////////////////////////
 
}

void loop()
{
//сценарий переключения шаров по командам
komanda=CheckSerial();
// если приходит команда 0 плата презагружается и переходит в режим команды 1
if(komanda==1){ for (int i = 0; i < LED_COUNT_N; i++) { pixel_(i,0,0);}strip.show();}//выключить гирлянду
if(komanda==2){gir="AAA";FUN_1("мятный","красный","оранжевый",25);}//
if(komanda==3){gir="AAA";FUN_1("малиновый","синий_2","синий_1",25);}//
if(komanda==4){gir="AAA";FUN_1("белый_1","синий_2","красный",25);}//
if(komanda==5){gir="AAA";FUN_1("розовый","зелёный_1","сиреневый",25);}//
if(komanda==6){gir="AAA";fun_2("мятный",40,50);fun_2("жёлтый",40,50);fun_2("оранжевый",40,50);fun_2("сиреневый",40,50);}//
if(komanda==7){gir="AAA";fun_2("сиреневый",40,50);fun_2("белый_1",40,50);  fun_2("синий_2",40,50);fun_2("красный",40,50);}// 
if(komanda==8){gir="AAA";FUN_3("синий_2",50,150);FUN_3("сиреневый",50,150);FUN_3("жёлтый",50,150);delay(t);} 
if(komanda==9){
gir="AAA";FUN_1("мятный","красный","оранжевый",25);//
gir="A*A";FUN_1("малиновый","синий_2","синий_1",25);//
gir="*A*";FUN_1("белый_1","голубой","чёрный",25);//
gir="A*A";FUN_1("белый_2","зелёный_1","жёлтый",25);//
delay(t);
gir="AAA";fun_2("мятный",40,50);//
fun_2("жёлтый",40,50);//  
fun_2("оранжевый",40,50);//
fun_2("сиреневый",40,50);// 
delay(t);
gir="A**";FUN_3("синий_2",50,150);//
gir="*A*";FUN_3("сиреневый",50,150);//
gir="**A";FUN_3("жёлтый",50,150);//
delay(t);
gir="AAA";FUN_3("зелёный_1",50,150);//
delay(t);
//
gir="AAA";FUN_1("белый_1","красный","синий_2",25);//
gir="A*A";FUN_1("сиреневый","синий_2","синий_2",25);//
gir="*A*";FUN_1("белый_1","белый_2","чёрный",25);//
gir="A*A";FUN_1("розовый","зелёный_1","сиреневый",25);// 
delay(t);
gir="AAA";fun_2("сиреневый",40,50);//
fun_2("белый_1",40,50);//  
fun_2("синий_2",40,50);//
fun_2("красный",40,50);// 
delay(t);
gir="A**";FUN_3("бежевый",50,150);//
gir="*A*";FUN_3("сиреневый",50,150);//
gir="**A";FUN_3("красный",50,150);//
delay(t);
gir="AAA";FUN_3("голубой",50,150);//
delay(t);
}
}
//////////////////////////////////////////////////
// цвет пикселя по номеру (1 уровень)
void pixel_(int num, byte cvet ,byte M){
if(num<LED_COUNT&&cvet<63&&M<86){
  int b=cvet/16;int g=(cvet%16)/4;int r=cvet-4*g-16*b;// цвета от 0 до 63
   for (int i = 0; i < N; i++) {
 if( gir.substring(i, i+1)=="A"){
  strip.setPixelColor(num+i*LED_COUNT, r*M, g*M, b*M);
   }
   }
 }
}
//////////////////////////////////////////////////
//цвет пикселя по названию (2 уровень)
void pixel_(int num, String CVET ,byte M){
byte cvet;
//набор цветов
if(CVET=="жёлтый"||CVET=="желтый"){cvet=11;pixel_( num,cvet,M);}
if(CVET=="зелёный_1"||CVET=="зеленый_1"){cvet=8;pixel_( num,cvet,M);} 
if(CVET=="зелёный_3"||CVET=="зеленый_3"){cvet=9;pixel_( num,cvet,M);}
if(CVET=="малиновый"){cvet=19;pixel_( num,cvet,M);} 
if(CVET=="голубой"){cvet=52;pixel_( num,cvet,M);} 
if(CVET=="розовый"){cvet=23;pixel_( num,cvet,M);} 
if(CVET=="бирюзовый"){cvet=24;pixel_( num,cvet,M);}
if(CVET=="мятный"){cvet=29;pixel_( num,cvet,M);} 
if(CVET=="синий_1"){cvet=37;pixel_( num,cvet,M);} 
if(CVET=="белый_1"){cvet=47;pixel_( num,cvet,M);} 
if(CVET=="синий_2"){cvet=48;pixel_( num,cvet,M);}
if(CVET=="сиреневый"){cvet=49;pixel_( num,cvet,M);} 
if(CVET=="красный"){cvet=3;pixel_( num,cvet,M);} 
if(CVET=="зелёный_2"||CVET=="зеленый_2"){cvet=4;pixel_( num,cvet,M);} 
if(CVET=="белый_2"){cvet=41;pixel_( num,cvet,M);}
if(CVET=="оранжевый"){cvet=7;pixel_( num,cvet,M);} 
if(CVET=="бежевый"){cvet=27;pixel_( num,cvet,M);} 
if(CVET=="чёрный"||CVET=="черный"){cvet=0;pixel_( num,cvet,M);}       
}
/////////////////////////////////////////////////
// бегущие 2 пикселя разных цветов по фоновому цвету (3 уровень)
void fun_1( String CVET_f ,String CVET_1,String CVET_2,byte M,int T){
 for (int i = 0; i < LED_COUNT; i++) {
  for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M);// фоновые пиксели
    }
    pixel_(i, CVET_2 ,M);// бегущий пиксель 2
    if (i != LED_COUNT - 1) {
      pixel_(i+1, CVET_1 ,M);// бегущий пиксель 1
    } else {
       pixel_(0, CVET_1 ,M);
    }
    strip.show(); delay_(T);
     }  
}
//////////////////////////////////////////////////
// вариации разных комбинаций цветов 2 бегущих пикселей (4 уровень)- 1 эффект
void FUN_1(String CVET_f ,String CVET_1,String CVET_2,byte M){
int K=1;//
byte k=1;//
byte st_=0;// 
 while(st_<=4){
 if(st_==0){fun_1(CVET_f,CVET_1,CVET_2,M,35*k);}//
 k=k+K;if(k==8){K=-1;}if(k==0){K=1;st_++;}
 }st_=0;  
}
/////////////////////////////////////////////////
// фоновая смена цвета свечения всего шара (3 уровень)
void fun_2( String CVET_f,byte M,int T){
 for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j,"чёрный",M/2);// фоновые пиксели последовательно выключаются
     strip.show(); delay_(T); 
     }
    
  for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M/2);// фоновые пиксели последовательно включаются и горят
     strip.show(); delay_(T);
     }
    delay_(40*T);
    for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M);// фоновые пиксели вспышка краткая
     }
    strip.show(); delay_(6*T); 
     for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M/2);// фоновые пиксели горят слабее некоторое время
    }
     strip.show(); delay_(40*T);  
  }
//////////////////////////////////////////////////
// смена фоновых цветов(4 уровень)- 2 эффект
void FUN_2(byte M,int T){
fun_2("красный",M,T);//
fun_2("мятный",M,T);//
fun_2("бежевый",M,T);//
fun_2("бирюзовый",M,T);//
fun_2("жёлтый",M,T);//  
fun_2("оранжевый",M,T);//
fun_2("белый_1",M,T);//    
}
//////////////////////////////////////////////////
// фоновая смена цвета свечения всего шара (3 уровень)
void fun_3( String CVET_f,byte M,int T){
 for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j,"чёрный",M/2);// фоновые пиксели последовательно выключаются
      }
      byte d;//
     for (int j = 0; j < LED_COUNT; j++) {
    d=random(1,10);//
    if(d==1){pixel_(j, CVET_f ,M);}// фоновые пиксели псевдослучайно включаются
    if(d==2){pixel_(j, CVET_f ,M);}
    if(d==3){pixel_(j, CVET_f ,M);}
    if(d==4){pixel_(j, CVET_f ,M/5);}
     if(d==5){pixel_(j, CVET_f ,M/5);}
    if(d==6){pixel_(j, CVET_f ,M/5);}
    if(d==7){pixel_(j,CVET_f   ,M/2);}
     if(d==8){pixel_(j,CVET_f  ,M/2);}
    if(d==9){pixel_(j, CVET_f  ,M/2);}
     }
    strip.show(); delay_(T/d);   
  }
//////////////////////////////////////////////////
// смена фоновых цветов(4 уровень)- 3 эффект
void FUN_3(String CVET_f,byte M,int T){
for (int i = 0; i < 100; i++) {fun_3( CVET_f,M,T);}//
for (int i = 0; i < 200; i++) {fun_3(CVET_f,M/8,T/2);}//
}
//////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// функция временной задержки с проверкой поступающих данных
void delay_(int T1)
{
Y=millis();  
while(millis()-Y<T1){komanda=CheckSerial();}//по поступившей команде выполняем действие

}



    

                           
 



 

lilik
Offline
Зарегистрирован: 19.10.2017

Параллельно выяснилось, что управлять шарами с ик пульта тоже фантастично, видимо библиотеки не совместимы меж собой ("неопиксель" и "иримото" ).

sadman41
Offline
Зарегистрирован: 19.10.2016

На небольших скоростях совместимы. А так да - битстрим блокирует прерывания.

Можно запытать фастлед в SPI mode.

lilik
Offline
Зарегистрирован: 19.10.2017

sadman41 пишет:
А так да - битстрим блокирует прерывания.

Странно, после обновления данных ленты идёт обычно пауза на многие миллисекунды. В это время можно считывать кнопки с пульта. Именно так я и пробовал - но нет, нажатия кнопок не фиксируются. В "ик библиотеке" явно не хватает функции :-) какой то. Вот тут была похожая тема с победой в конце (их много попадается), но для фастлед.

http://arduino.ru/forum/programmirovanie/upravlenie-pikselnoi-svetodiodn...

Пробовал под неопиксель - не работает. Тогда сделал грубо, добавил между УНО и ИК приёмником "шибанутую про мини 168". Такой вариант работает, то есть вместо блютуз модуля подключаем по ТХ, RX ещё один МК и в него простенький скетч.

/////////////////////////// тест с дистанционным управлением через ИК пульт на про мини 168
#include "IRremote.h"
int RECV_PIN = 2;        //Пин подключения выходного сигнала с ИК-приёмника
//Создаём экземпляр класса IRrecv, в качестве параметра передаём пин подключения сигнала ИК-приёмника
IRrecv irrecv(RECV_PIN);  
decode_results results;   //Переменная для сохранения полученного кода нажатой кнопки
void setup()
{
 Serial.begin(115200); 
 irrecv.enableIRIn(); //Включение ИК-приёмника в работу
///////////////////////////////////
}
void loop()
{
if (irrecv.decode(&results)) //Если произошло событие/кнопка была нажата
  {
    switch ( results.value )
    {
    case 0x830CF://кнопка 0
      Serial.print("0\n");
        break;
    case 0x8C03F://кнопка 1
      Serial.print("1\n");
        break;
    case 0x820DF://кнопка 2
      Serial.print("2\n");
        break;
    case 0x8A05F://кнопка 3
      Serial.print("3\n");
        break;
    case 0x8609F://кнопка 4
     Serial.print("4\n");
        break;
    case 0x8E01F://кнопка 5
      Serial.print("5\n");
        break;
    case 0x810EF://кнопка 6
     Serial.print("6\n");
        break;
    case 0x8906F://кнопка 7
      Serial.print("7\n");
        break;
   case 0x850AF://кнопка 8
      Serial.print("8\n");
        break;
   case 0x8D02F://кнопка 9
     Serial.print("9\n");
        break;
   case 0x8C837://кнопка OK
     Serial.print("10\n");
        break;              
    }
    irrecv.resume();//Считываем следующую значение/кнопку
   }   
}

 

lilik
Offline
Зарегистрирован: 19.10.2017

Фишка в том, что на УНО скетч под блютуз менять совсем не надо - можно выбирать хочешь блютуз модуль, хочешь ИК модуль на про мини, хочешь сразу оба подключаешь. Правда надо 2 развязывающих диода и резистор тогда. Но тогда гирлянда управляется с телефона, ПК, самодельного пульта, ИК пульта от чего нибудь и перепрошивается по воздуху.

sadman41
Offline
Зарегистрирован: 19.10.2016

У меня несколько лет был самопальный ящик на 328м МК с фастледом и ИК. Все заработало сразу, но реактивность сохраняется только до определённого FPS. Потом уже пропуски кнопок идут и пр.

resume() нужно сразу делать, не громоздить в свичах println. Выставил по кнопке номер эффекта в переменную, зарезюмировал и пошёл фонарики в неблокирующем стиле крутить.

lilik
Offline
Зарегистрирован: 19.10.2017

https://github.com/Arduino-IRremote/Arduino-IRremote

Это страничка библиотеки. Нашёл на ней вопрос конкретный и ответ конкретный. Нифига не работает (решил ещё раз проверить). Может конечно я не понял ответ.

IR не работает правильно, когда я использую Neopixels (также известный как WS2811 / WS2812 / WS2812B) или другие библиотеки, блокирующие прерывания на более длительное время (> 50 мкс).
Независимо от того, используете ли вы Adafruit Neopixel lib или FastLED, прерывания отключаются на многих младших процессорах, таких как базовый Arduinos, на время более 50 мкс. В свою очередь, это останавливает выполнение обработчика прерывания IR, когда это необходимо.
Вы можете попытаться подождать, пока ИК-приемник будет бездействовать, прежде чем отправлять данные Neopixel с помощью if (IrReceiver.isIdle()) { strip.show();}. Это предотвращает, по крайней мере, прерывание работающей ИК-передачи и, в зависимости от частоты обновления Neopixel, может работать достаточно хорошо.

Точнее можно включить только один раз выбранный эффект пультом, дальше пульт "не работает " до перезагрузки платы. На одном эффекте вообще идёт свистопляска - шары мигают кракозяброй, в мониторе порта якобы идёт нажатие кнопок сплошной лентой :-) Чёт автор явно не договаривает.

/////////////////////////// тест цветов и эффектов для гирлянды ШАРИКОВ НА WS2812b с дистанционным управлением через ИК пульт
#include "Adafruit_NeoPixel.h"
#define LED_COUNT 5               //число пикселей в шаре
#define N 3                      // число шаров в гирлянде 
#define LED_COUNT_N  N*LED_COUNT   // число пикселей в ленте
#define LED_PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT_N, LED_PIN, NEO_GRB + NEO_KHZ800);// Создаем переменную strip для управления нашей лентой.
//////////////////
//#include "boarddefs.h"   //Добавочная библиотека
#include "IRremote.h"
//#include "IRremoteInt.h" //Добавочная библиотека
int RECV_PIN = 2;        //Пин подключения выходного сигнала с ИК-приёмника
//Создаём экземпляр класса IRrecv, в качестве параметра передаём пин подключения сигнала ИК-приёмника
IRrecv irrecv(RECV_PIN);  
decode_results results;   //Переменная для сохранения полученного кода нажатой кнопки
//////////////////
String gir="";// переменная задающая участие шара в текущем эффекте
int t=3000;// переменная задающая паузу между эффектами

long Y=0;//пременная хранения моментов времени
int komanda=0;// переменная хранения 

void setup()
{
  Serial.begin(9600); 
 irrecv.enableIRIn();     //Включение ИК-приёмника в работу
 strip.begin();
 gir="AAA";
 for (int i = 0; i < LED_COUNT_N; i++) {
   pixel_(i,0,0);// выключение пикселя 
  }
strip.show();
  /////////////////////////////////////////////////
 
}

void loop()
{
//сценарий переключения шаров по командам
if(komanda==0){gir="AAA"; for (int i = 0; i < LED_COUNT_N; i++) { pixel_(i,0,0);}strip.show();}//выключить гирлянду
if(komanda==1){gir="AAA";FUN_1("мятный","красный","оранжевый",25);}//
if(komanda==2){gir="AAA";FUN_1("малиновый","синий_2","синий_1",25);}//
if(komanda==3){gir="AAA";FUN_1("белый_1","синий_2","красный",25);}//
if(komanda==4){gir="AAA";FUN_1("розовый","зелёный_1","сиреневый",25);}//
if(komanda==5){gir="AAA";fun_2("мятный",40,50);fun_2("жёлтый",40,50);fun_2("оранжевый",40,50);fun_2("сиреневый",40,50);}//
if(komanda==6){gir="AAA";fun_2("сиреневый",40,50);fun_2("белый_1",40,50);  fun_2("синий_2",40,50);fun_2("красный",40,50);}// 
if(komanda==7){gir="AAA";FUN_3("синий_2",50,150);FUN_3("сиреневый",50,150);FUN_3("жёлтый",50,150);delay(t);}
delay_(50);
}

//////////////////////////////////////////////////
// цвет пикселя по номеру (1 уровень)
void pixel_(int num, byte cvet ,byte M){
if(num<LED_COUNT&&cvet<63&&M<86){
  int b=cvet/16;int g=(cvet%16)/4;int r=cvet-4*g-16*b;// цвета от 0 до 63
   for (int i = 0; i < N; i++) {
 if( gir.substring(i, i+1)=="A"){
  strip.setPixelColor(num+i*LED_COUNT, r*M, g*M, b*M);
   }
   }
 }
}
//////////////////////////////////////////////////
//цвет пикселя по названию (2 уровень)
void pixel_(int num, String CVET ,byte M){
byte cvet;
//набор цветов
if(CVET=="жёлтый"||CVET=="желтый"){cvet=11;pixel_( num,cvet,M);}
if(CVET=="зелёный_1"||CVET=="зеленый_1"){cvet=8;pixel_( num,cvet,M);} 
if(CVET=="зелёный_3"||CVET=="зеленый_3"){cvet=9;pixel_( num,cvet,M);}
if(CVET=="малиновый"){cvet=19;pixel_( num,cvet,M);} 
if(CVET=="голубой"){cvet=52;pixel_( num,cvet,M);} 
if(CVET=="розовый"){cvet=23;pixel_( num,cvet,M);} 
if(CVET=="бирюзовый"){cvet=24;pixel_( num,cvet,M);}
if(CVET=="мятный"){cvet=29;pixel_( num,cvet,M);} 
if(CVET=="синий_1"){cvet=37;pixel_( num,cvet,M);} 
if(CVET=="белый_1"){cvet=47;pixel_( num,cvet,M);} 
if(CVET=="синий_2"){cvet=48;pixel_( num,cvet,M);}
if(CVET=="сиреневый"){cvet=49;pixel_( num,cvet,M);} 
if(CVET=="красный"){cvet=3;pixel_( num,cvet,M);} 
if(CVET=="зелёный_2"||CVET=="зеленый_2"){cvet=4;pixel_( num,cvet,M);} 
if(CVET=="белый_2"){cvet=41;pixel_( num,cvet,M);}
if(CVET=="оранжевый"){cvet=7;pixel_( num,cvet,M);} 
if(CVET=="бежевый"){cvet=27;pixel_( num,cvet,M);} 
if(CVET=="чёрный"||CVET=="черный"){cvet=0;pixel_( num,cvet,M);}       
}
/////////////////////////////////////////////////
// бегущие 2 пикселя разных цветов по фоновому цвету (3 уровень)
void fun_1( String CVET_f ,String CVET_1,String CVET_2,byte M,int T){
 for (int i = 0; i < LED_COUNT; i++) {
  for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M);// фоновые пиксели
    }
    pixel_(i, CVET_2 ,M);// бегущий пиксель 2
    if (i != LED_COUNT - 1) {
      pixel_(i+1, CVET_1 ,M);// бегущий пиксель 1
    } else {
       pixel_(0, CVET_1 ,M);
    }
 if ( irrecv.isIdle()) { strip.show();}delay_(T);
     }  
}
//////////////////////////////////////////////////
// вариации разных комбинаций цветов 2 бегущих пикселей (4 уровень)- 1 эффект
void FUN_1(String CVET_f ,String CVET_1,String CVET_2,byte M){
int K=1;//
byte k=1;//
byte st_=0;// 
 while(st_<=4){
 if(st_==0){fun_1(CVET_f,CVET_1,CVET_2,M,35*k);}//
 k=k+K;if(k==8){K=-1;}if(k==0){K=1;st_++;}
 }st_=0;  
}
/////////////////////////////////////////////////
// фоновая смена цвета свечения всего шара (3 уровень)
void fun_2( String CVET_f,byte M,int T){
 for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j,"чёрный",M/2);// фоновые пиксели последовательно выключаются
   if ( irrecv.isIdle()) { strip.show();} delay_(T); 
     }
    
  for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M/2);// фоновые пиксели последовательно включаются и горят
  if ( irrecv.isIdle()) { strip.show();} delay_(T);
     }
    delay_(40*T);
    for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M);// фоновые пиксели вспышка краткая
     }
 if ( irrecv.isIdle()) { strip.show();} delay_(6*T); 
     for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M/2);// фоновые пиксели горят слабее некоторое время
    }
   if ( irrecv.isIdle()) { strip.show();} delay_(40*T);  
  }
//////////////////////////////////////////////////
// смена фоновых цветов(4 уровень)- 2 эффект
void FUN_2(byte M,int T){
fun_2("красный",M,T);//
fun_2("мятный",M,T);//
fun_2("бежевый",M,T);//
fun_2("бирюзовый",M,T);//
fun_2("жёлтый",M,T);//  
fun_2("оранжевый",M,T);//
fun_2("белый_1",M,T);//    
}
//////////////////////////////////////////////////
// фоновая смена цвета свечения всего шара (3 уровень)
void fun_3( String CVET_f,byte M,int T){
 for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j,"чёрный",M/2);// фоновые пиксели последовательно выключаются
      }
      byte d;//
     for (int j = 0; j < LED_COUNT; j++) {
    d=random(1,10);//
    if(d==1){pixel_(j, CVET_f ,M);}// фоновые пиксели псевдослучайно включаются
    if(d==2){pixel_(j, CVET_f ,M);}
    if(d==3){pixel_(j, CVET_f ,M);}
    if(d==4){pixel_(j, CVET_f ,M/5);}
     if(d==5){pixel_(j, CVET_f ,M/5);}
    if(d==6){pixel_(j, CVET_f ,M/5);}
    if(d==7){pixel_(j,CVET_f   ,M/2);}
     if(d==8){pixel_(j,CVET_f  ,M/2);}
    if(d==9){pixel_(j, CVET_f  ,M/2);}
     }
 if ( irrecv.isIdle()) { strip.show();} delay_(T/d);   
  }
//////////////////////////////////////////////////
// смена фоновых цветов(4 уровень)- 3 эффект
void FUN_3(String CVET_f,byte M,int T){
for (int i = 0; i < 100; i++) {fun_3( CVET_f,M,T);}//
for (int i = 0; i < 200; i++) {fun_3(CVET_f,M/8,T/2);}//
}
//////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// функция временной задержки с проверкой поступающих данных
void delay_(int T1)
{
Y=millis();  
while(millis()-Y<T1){
  if (irrecv.decode(&results))   //Если произошло событие/кнопка была нажата
  {
    switch ( results.value )
    {
    case 0x830CF://кнопка 0
       komanda=0;
        break;
    case 0x8C03F://кнопка 1
       komanda=1;
        break;
    case 0x820DF://кнопка 2
       komanda=2;
        break;
    case 0x8A05F://кнопка 3
       komanda=3;
        break;
    case 0x8609F://кнопка 4
      komanda=4;
        break;
    case 0x8E01F://кнопка 5
      komanda=5;
        break;
    case 0x810EF://кнопка 6
      komanda=6;
        break;
    case 0x8906F://кнопка 7
      komanda=7;
        break;
   case 0x850AF://кнопка 8
      komanda=8;
        break;
   case 0x8D02F://кнопка 9
      komanda=9;
        break;
   case 0x8C837://кнопка OK
      komanda=10;
        break;              
    }
      Serial.println(results.value, HEX); 
     irrecv.resume();//Считываем следующую значение/кнопку
   }   
}
}

 

 
 
 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Опять println() до resume().

Где-то у меня набор ресивера-пульт валялся, найду попробую.

lilik
Offline
Зарегистрирован: 19.10.2017

Целый день глумления над платами и итог.

/////////////////////////// тест цветов и эффектов для гирлянды ШАРИКОВ НА WS2812b с дистанционным управлением через ИК пульт
#include "Adafruit_NeoPixel.h"
#define LED_COUNT 5               //число пикселей в шаре
#define N 3                      // число шаров в гирлянде 
#define LED_COUNT_N  N*LED_COUNT   // число пикселей в ленте
#define LED_PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT_N, LED_PIN, NEO_GRB + NEO_KHZ800);// Создаем переменную strip для управления нашей лентой.
//////////////////
//#include "boarddefs.h"   //Добавочная библиотека
#include "IRremote.h"
//#include "IRremoteInt.h" //Добавочная библиотека
int RECV_PIN = 14;        //Пин подключения выходного сигнала с ИК-приёмника
int uploadpin =2;        //вывод для аппаратного ресета
//Создаём экземпляр класса IRrecv, в качестве параметра передаём пин подключения сигнала ИК-приёмника
IRrecv irrecv(RECV_PIN);  
decode_results results;   //Переменная для сохранения полученного кода нажатой кнопки
//////////////////
String gir="";// переменная задающая участие шара в текущем эффекте
int t=3000;// переменная задающая паузу между эффектами

long Y=0;//пременная хранения моментов времени
int komanda=0;// переменная хранения 

void setup()
{
  //Serial.begin(9600); 
 irrecv.enableIRIn();     //Включение ИК-приёмника в работу
 strip.begin();
 gir="AAA";
 for (int i = 0; i < LED_COUNT_N; i++) {
   pixel_(i,0,0);// выключение пикселя 
  }
strip.show();
  /////////////////////////////////////////////////
 
}

void loop()
{
//сценарий переключения шаров по командам
if(komanda==1){gir="AAA"; for (int i = 0; i < LED_COUNT_N; i++) { pixel_(i,27,25);}strip.show();}//включить гирлянду бежевым цветом
if(komanda==2){gir="AAA";FUN_1("мятный","красный","оранжевый",25);FUN_1("малиновый","синий_2","синий_1",25);FUN_1("белый_1","синий_2","красный",25);}//
if(komanda==3){gir="AAA";fun_2("мятный",40,50);fun_2("жёлтый",40,50);fun_2("оранжевый",40,50);fun_2("сиреневый",40,50);fun_2("белый_1",40,50);  fun_2("синий_2",40,50);fun_2("красный",40,50);}//
if(komanda==4){gir="AAA";FUN_3("синий_2",50,150);delay_(t);FUN_3("сиреневый",50,150);delay_(t);FUN_3("жёлтый",50,150);delay_(t);} 
if(komanda==5){gir="AAA";FUN_1("мятный","красный","оранжевый",25);FUN_1("малиновый","синий_2","синий_1",25);FUN_1("белый_1","синий_2","красный",25);
fun_2("мятный",40,50);fun_2("жёлтый",40,50);fun_2("оранжевый",40,50);fun_2("сиреневый",40,50);fun_2("белый_1",40,50);  fun_2("синий_2",40,50);fun_2("красный",40,50);
FUN_3("синий_2",50,150);delay_(t);FUN_3("сиреневый",50,150);delay_(t);FUN_3("жёлтый",50,150);delay_(t);}
delay_(50);
}

//////////////////////////////////////////////////
// цвет пикселя по номеру (1 уровень)
void pixel_(int num, byte cvet ,byte M){
if(num<LED_COUNT&&cvet<63&&M<86){
  int b=cvet/16;int g=(cvet%16)/4;int r=cvet-4*g-16*b;// цвета от 0 до 63
   for (int i = 0; i < N; i++) {
 if( gir.substring(i, i+1)=="A"){
  strip.setPixelColor(num+i*LED_COUNT, r*M, g*M, b*M);
   }
   }
 }
}
//////////////////////////////////////////////////
//цвет пикселя по названию (2 уровень)
void pixel_(int num, String CVET ,byte M){
byte cvet;
//набор цветов
if(CVET=="жёлтый"||CVET=="желтый"){cvet=11;pixel_( num,cvet,M);}
if(CVET=="зелёный_1"||CVET=="зеленый_1"){cvet=8;pixel_( num,cvet,M);} 
if(CVET=="зелёный_3"||CVET=="зеленый_3"){cvet=9;pixel_( num,cvet,M);}
if(CVET=="малиновый"){cvet=19;pixel_( num,cvet,M);} 
if(CVET=="голубой"){cvet=52;pixel_( num,cvet,M);} 
if(CVET=="розовый"){cvet=23;pixel_( num,cvet,M);} 
if(CVET=="бирюзовый"){cvet=24;pixel_( num,cvet,M);}
if(CVET=="мятный"){cvet=29;pixel_( num,cvet,M);} 
if(CVET=="синий_1"){cvet=37;pixel_( num,cvet,M);} 
if(CVET=="белый_1"){cvet=47;pixel_( num,cvet,M);} 
if(CVET=="синий_2"){cvet=48;pixel_( num,cvet,M);}
if(CVET=="сиреневый"){cvet=49;pixel_( num,cvet,M);} 
if(CVET=="красный"){cvet=3;pixel_( num,cvet,M);} 
if(CVET=="зелёный_2"||CVET=="зеленый_2"){cvet=4;pixel_( num,cvet,M);} 
if(CVET=="белый_2"){cvet=41;pixel_( num,cvet,M);}
if(CVET=="оранжевый"){cvet=7;pixel_( num,cvet,M);} 
if(CVET=="бежевый"){cvet=27;pixel_( num,cvet,M);} 
if(CVET=="чёрный"||CVET=="черный"){cvet=0;pixel_( num,cvet,M);}       
}
/////////////////////////////////////////////////
// бегущие 2 пикселя разных цветов по фоновому цвету (3 уровень)
void fun_1( String CVET_f ,String CVET_1,String CVET_2,byte M,int T){
 for (int i = 0; i < LED_COUNT; i++) {
  for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M);// фоновые пиксели
    }
    pixel_(i, CVET_2 ,M);// бегущий пиксель 2
    if (i != LED_COUNT - 1) {
      pixel_(i+1, CVET_1 ,M);// бегущий пиксель 1
    } else {
       pixel_(0, CVET_1 ,M);
    }
 if ( irrecv.isIdle()) { strip.show();}delay_(T);
     }  
}
//////////////////////////////////////////////////
// вариации разных комбинаций цветов 2 бегущих пикселей (4 уровень)- 1 эффект
void FUN_1(String CVET_f ,String CVET_1,String CVET_2,byte M){
int K=1;//
byte k=1;//
byte st_=0;// 
 while(st_<=4){
 if(st_==0){fun_1(CVET_f,CVET_1,CVET_2,M,35*k);}//
 k=k+K;if(k==8){K=-1;}if(k==0){K=1;st_++;}
 }st_=0;  
}
/////////////////////////////////////////////////
// фоновая смена цвета свечения всего шара (3 уровень)
void fun_2( String CVET_f,byte M,int T){
 for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j,"чёрный",M/2);// фоновые пиксели последовательно выключаются
   if ( irrecv.isIdle()) { strip.show();} delay_(T); 
     }
    
  for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M/2);// фоновые пиксели последовательно включаются и горят
  if ( irrecv.isIdle()) { strip.show();} delay_(T);
     }
    delay_(40*T);
    for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M);// фоновые пиксели вспышка краткая
     }
 if ( irrecv.isIdle()) { strip.show();} delay_(6*T); 
     for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j, CVET_f ,M/2);// фоновые пиксели горят слабее некоторое время
    }
   if ( irrecv.isIdle()) { strip.show();} delay_(40*T);  
  }
//////////////////////////////////////////////////
// смена фоновых цветов(4 уровень)- 2 эффект
void FUN_2(byte M,int T){
fun_2("красный",M,T);//
fun_2("мятный",M,T);//
fun_2("бежевый",M,T);//
fun_2("бирюзовый",M,T);//
fun_2("жёлтый",M,T);//  
fun_2("оранжевый",M,T);//
fun_2("белый_1",M,T);//    
}
//////////////////////////////////////////////////
// фоновая смена цвета свечения всего шара (3 уровень)
void fun_3( String CVET_f,byte M,int T){
 for (int j = 0; j < LED_COUNT; j++) {
     pixel_(j,"чёрный",M/2);// фоновые пиксели последовательно выключаются
      }
      byte d;//
     for (int j = 0; j < LED_COUNT; j++) {
    d=random(1,10);//
    if(d==1){pixel_(j, CVET_f ,M);}// фоновые пиксели псевдослучайно включаются
    if(d==2){pixel_(j, CVET_f ,M);}
    if(d==3){pixel_(j, CVET_f ,M);}
    if(d==4){pixel_(j, CVET_f ,M/5);}
     if(d==5){pixel_(j, CVET_f ,M/5);}
    if(d==6){pixel_(j, CVET_f ,M/5);}
    if(d==7){pixel_(j,CVET_f   ,M/2);}
     if(d==8){pixel_(j,CVET_f  ,M/2);}
    if(d==9){pixel_(j, CVET_f  ,M/2);}
     }
 if ( irrecv.isIdle()) { strip.show();} delay_(T/d);   
  }
//////////////////////////////////////////////////
// смена фоновых цветов(4 уровень)- 3 эффект
void FUN_3(String CVET_f,byte M,int T){
for (int i = 0; i < 100; i++) {fun_3( CVET_f,M,T);}//
for (int i = 0; i < 200; i++) {fun_3(CVET_f,M/8,T/2);}//
}
//////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// функция временной задержки с проверкой поступающих данных
void delay_(int T1)
{
Y=millis();  
while(millis()-Y<T1){
  if (irrecv.decode(&results))   //Если произошло событие/кнопка была нажата
  {
    switch ( results.value )
    {
    case 0x830CF://кнопка 0
       komanda=0;
        break;
    case 0x8C03F://кнопка 1
       komanda=1;
        break;
    case 0x820DF://кнопка 2
       komanda=2;
        break;
    case 0x8A05F://кнопка 3
       komanda=3;
        break;
    case 0x8609F://кнопка 4
      komanda=4;
        break;
    case 0x8E01F://кнопка 5
      komanda=5;
        break;
    case 0x810EF://кнопка 6
      komanda=6;
        break;
    case 0x8906F://кнопка 7
      komanda=7;
        break;
   case 0x850AF://кнопка 8
      komanda=8;
        break;
   case 0x8D02F://кнопка 9
      komanda=9;
        break;
   case 0x8C837://кнопка OK
      komanda=10;pinMode(uploadpin,OUTPUT); //ЭТО ВЫЗОВЕТ аппаратный РЕСЕТ
        break;              
    }
    irrecv.resume();//Считываем следующую значение/кнопку
  // Serial.println(results.value, HEX); 
   }   
}
}

 

lilik
Offline
Зарегистрирован: 19.10.2017

Секрет открылся при прочтении темы:

https://mysku.ru/blog/aliexpress/68990.html

Среди описаний бесчисленных победных модернизаций изделия от Гайвера проскочила строка, что авторы библиотеки "ирремото" взяли и испортили её, исключив корректную работу с умными светодиодами. Благо у автора осталась старая версия.

Про мини 168 так и не заработала корректно (два эффекта не хочет воспроизводить), видимо ресурс ограничен (95 процентов использует скетч для неё и 62 по ОЗУ). Поэтому 328.

Чёт авторы библиотеки мудрят.

lilik
Offline
Зарегистрирован: 19.10.2017

Изменил концепт - каждый шар сам по себе,без гирлянды, управляется с пульта. Можно так группу сделать, с адресным управлением по ИК каналу.

MaksVV
Offline
Зарегистрирован: 06.08.2015

А питание все равно по проводам? Имхо таже гирлянда

lilik
Offline
Зарегистрирован: 19.10.2017

MaksVV пишет:

А питание все равно по проводам? 

Нет, внутри шара аккумулятор б/у на 800 мА. Схема потребляет (по микроамперметру, в разрыв плюса) - шар не светит 14 мА, ярко вспыхивает (в одном эффекте) 55 мА. Теоретически, на ёлке "должон мигаться"  сутки без подзарядки :-)  

lilik
Offline
Зарегистрирован: 19.10.2017

Добавил в схему динамик, мотор. Теперь шар мигает, крутится, исполняет мелодии. Можно оказывается управлять с телефона им.

lilik
Offline
Зарегистрирован: 19.10.2017

Один интересный вопрос возник у меня. Сделал для шарика голосовое управление через смартфон. В мит апп инверторе штатно нет возможности  управлять ИК сенсором. На другом форуме подсказали статью одного немецкого автора - он сделал расширение под сенсор (набор пазлов) для инвертора. Но приложение, написанное с его пазлами, не очень стабильно с кодами кнопок триколоровского ИК пульта. Мне пришлось воспользоваться пультом от детской игрушки. Всё заработало, но возник вопрос чисто на знание. Чуть упростил его скетч для получения кодов кнопок и их "тайминг-сигнатур".

 

#include <IRremote.h>
int RECV_PIN = 11;                // Pin, an den der Empf�nger angeschlossen ist
IRrecv irrecv(RECV_PIN);         // Instanz der Receiver-Klasse
decode_results results;          // Zur Aufnahme des ermittelsten Codes

void setup() {
   Serial.begin(9600);
   irrecv.enableIRIn(); // Startet den Receiver
  
}

// Gibt die Code-Sequenz auf der seriellen Schnittstelle aus
void printCode(decode_results *results) {
   int codeLen = results->rawlen - 1; // The length of the code
  for (int i = 1; i <= codeLen; i++) {
      unsigned int rawCode;
      if (i % 2) {
        // Mark
         rawCode = results->rawbuf[i] * USECPERTICK - MARK_EXCESS;

      }
      else {
        // Space
         rawCode = results->rawbuf[i] * USECPERTICK + MARK_EXCESS;

      }
      if (i > 1)
         Serial.print(",");
   Serial.print(rawCode, DEC);
   }
   Serial.println("");
}


void loop() {
   if (irrecv.decode(&results)) {
       printCode(&results);// вывод кода кнопки в "сигнатуре"
      Serial.println(results.value, HEX);//код кнопки в привычном нам виде
      irrecv.resume(); // resume receiver
     
   }
}

У меня для пульта получилось так:

3250,650,1000,750,1000,750,1000,1350,500,1350,500,1400,500,750,1000,750,1000,750,1000,1350,450
9F4FDCF9
3250,1300,450,800,1000,750,1000,750,1000,1350,450,1400,500,750,1000,800,900,850,900,1400,500
9E614B1D
3250,700,950,1350,500,750,1000,1400,450,1350,500,1400,450,800,1000,1350,500,750,1000,1350,450
9E1C511
3250,1300,450,800,1000,750,1000,750,1000,1400,400,1400,500,750,1000,800,950,800,950,1350,500
9E614B1D
3250,1300,500,750,1000,1400,400,850,950,1400,450,1400,450,800,950,1400,450,800,950,1400,450
9472DE25
3250,1300,450,800,1000,750,1000,750,1000,1350,450,1400,500,750,950,850,900,850,900,1400,500
9E614B1D
3250,650,1050,1350,500,1350,550,700,1050,1350,500,1350,550,750,950,1400,500,750,1000,1350,500
6567AC1
3250,1350,400,850,950,800,950,800,950,1400,450,1400,450,800,950,850,900,850,900,1400,500
9E614B1D 

В длинных строчках записаны 0 и 1 (как я понял из визуального анализа), их  10 штук с каждой кнопки (10 бит данных). В коротких строчках код кнопки. Есть ли связь между этими данными?, и какая? Просто на других пультах длинные строчки не менялись, а коды кнопок (для каждой) могли быть разные (связь неустойчивая видимо - данные терялись :-). Только вот какие и почему?

sadman41
Offline
Зарегистрирован: 19.10.2016

Конечно есть связь. См. например: https://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol