//
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();} // преобразуем строку в номер команды-число
//////
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
Странно, после обновления данных ленты идёт обычно пауза на многие миллисекунды. В это время можно считывать кнопки с пульта. Именно так я и пробовал - но нет, нажатия кнопок не фиксируются. В "ик библиотеке" явно не хватает функции :-) какой то. Вот тут была похожая тема с победой в конце (их много попадается), но для фастлед.
Пробовал под неопиксель - не работает. Тогда сделал грубо, добавил между УНО и ИК приёмником "шибанутую про мини 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();//Считываем следующую значение/кнопку
}
}
Фишка в том, что на УНО скетч под блютуз менять совсем не надо - можно выбирать хочешь блютуз модуль, хочешь ИК модуль на про мини, хочешь сразу оба подключаешь. Правда надо 2 развязывающих диода и резистор тогда. Но тогда гирлянда управляется с телефона, ПК, самодельного пульта, ИК пульта от чего нибудь и перепрошивается по воздуху.
У меня несколько лет был самопальный ящик на 328м МК с фастледом и ИК. Все заработало сразу, но реактивность сохраняется только до определённого FPS. Потом уже пропуски кнопок идут и пр.
resume() нужно сразу делать, не громоздить в свичах println. Выставил по кнопке номер эффекта в переменную, зарезюмировал и пошёл фонарики в неблокирующем стиле крутить.
Это страничка библиотеки. Нашёл на ней вопрос конкретный и ответ конкретный. Нифига не работает (решил ещё раз проверить). Может конечно я не понял ответ.
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();//Считываем следующую значение/кнопку
}
}
}
Среди описаний бесчисленных победных модернизаций изделия от Гайвера проскочила строка, что авторы библиотеки "ирремото" взяли и испортили её, исключив корректную работу с умными светодиодами. Благо у автора осталась старая версия.
Про мини 168 так и не заработала корректно (два эффекта не хочет воспроизводить), видимо ресурс ограничен (95 процентов использует скетч для неё и 62 по ОЗУ). Поэтому 328.
Нет, внутри шара аккумулятор б/у на 800 мА. Схема потребляет (по микроамперметру, в разрыв плюса) - шар не светит 14 мА, ярко вспыхивает (в одном эффекте) 55 мА. Теоретически, на ёлке "должон мигаться" сутки без подзарядки :-)
Один интересный вопрос возник у меня. Сделал для шарика голосовое управление через смартфон. В мит апп инверторе штатно нет возможности управлять ИК сенсором. На другом форуме подсказали статью одного немецкого автора - он сделал расширение под сенсор (набор пазлов) для инвертора. Но приложение, написанное с его пазлами, не очень стабильно с кодами кнопок триколоровского ИК пульта. Мне пришлось воспользоваться пультом от детской игрушки. Всё заработало, но возник вопрос чисто на знание. Чуть упростил его скетч для получения кодов кнопок и их "тайминг-сигнатур".
#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
}
}
В длинных строчках записаны 0 и 1 (как я понял из визуального анализа), их 10 штук с каждой кнопки (10 бит данных). В коротких строчках код кнопки. Есть ли связь между этими данными?, и какая? Просто на других пультах длинные строчки не менялись, а коды кнопок (для каждой) могли быть разные (связь неустойчивая видимо - данные терялись :-). Только вот какие и почему?
Забыл, вот второй файл - скетч из 2 частей.
Интересное явление, явно неземного происхождения мне приходиться наблюдать.
Так намедни ж полнолуние было, а в такое время и не то случается.
Интересное явление, явно неземного происхождения мне приходиться наблюдать.
Так намедни ж полнолуние было, а в такое время и не то случается.
Особенно при том, что шары все залиты)
Явление осталось необъяснимым. Заменил на УНО, всё работает как надо, значит в платке дело.
Параллельно выяснилось, что управлять шарами с ик пульта тоже фантастично, видимо библиотеки не совместимы меж собой ("неопиксель" и "иримото" ).
На небольших скоростях совместимы. А так да - битстрим блокирует прерывания.
Можно запытать фастлед в SPI mode.
Странно, после обновления данных ленты идёт обычно пауза на многие миллисекунды. В это время можно считывать кнопки с пульта. Именно так я и пробовал - но нет, нажатия кнопок не фиксируются. В "ик библиотеке" явно не хватает функции :-) какой то. Вот тут была похожая тема с победой в конце (их много попадается), но для фастлед.
http://arduino.ru/forum/programmirovanie/upravlenie-pikselnoi-svetodiodn...
Пробовал под неопиксель - не работает. Тогда сделал грубо, добавил между УНО и ИК приёмником "шибанутую про мини 168". Такой вариант работает, то есть вместо блютуз модуля подключаем по ТХ, RX ещё один МК и в него простенький скетч.
Фишка в том, что на УНО скетч под блютуз менять совсем не надо - можно выбирать хочешь блютуз модуль, хочешь ИК модуль на про мини, хочешь сразу оба подключаешь. Правда надо 2 развязывающих диода и резистор тогда. Но тогда гирлянда управляется с телефона, ПК, самодельного пульта, ИК пульта от чего нибудь и перепрошивается по воздуху.
У меня несколько лет был самопальный ящик на 328м МК с фастледом и ИК. Все заработало сразу, но реактивность сохраняется только до определённого FPS. Потом уже пропуски кнопок идут и пр.
resume() нужно сразу делать, не громоздить в свичах println. Выставил по кнопке номер эффекта в переменную, зарезюмировал и пошёл фонарики в неблокирующем стиле крутить.
https://github.com/Arduino-IRremote/Arduino-IRremote
Это страничка библиотеки. Нашёл на ней вопрос конкретный и ответ конкретный. Нифига не работает (решил ещё раз проверить). Может конечно я не понял ответ.
Точнее можно включить только один раз выбранный эффект пультом, дальше пульт "не работает " до перезагрузки платы. На одном эффекте вообще идёт свистопляска - шары мигают кракозяброй, в мониторе порта якобы идёт нажатие кнопок сплошной лентой :-) Чёт автор явно не договаривает.
Опять println() до resume().
Где-то у меня набор ресивера-пульт валялся, найду попробую.
Целый день глумления над платами и итог.
Секрет открылся при прочтении темы:
https://mysku.ru/blog/aliexpress/68990.html
Среди описаний бесчисленных победных модернизаций изделия от Гайвера проскочила строка, что авторы библиотеки "ирремото" взяли и испортили её, исключив корректную работу с умными светодиодами. Благо у автора осталась старая версия.
Про мини 168 так и не заработала корректно (два эффекта не хочет воспроизводить), видимо ресурс ограничен (95 процентов использует скетч для неё и 62 по ОЗУ). Поэтому 328.
Чёт авторы библиотеки мудрят.
Изменил концепт - каждый шар сам по себе,без гирлянды, управляется с пульта. Можно так группу сделать, с адресным управлением по ИК каналу.
А питание все равно по проводам? Имхо таже гирлянда
А питание все равно по проводам?
Нет, внутри шара аккумулятор б/у на 800 мА. Схема потребляет (по микроамперметру, в разрыв плюса) - шар не светит 14 мА, ярко вспыхивает (в одном эффекте) 55 мА. Теоретически, на ёлке "должон мигаться" сутки без подзарядки :-)
Добавил в схему динамик, мотор. Теперь шар мигает, крутится, исполняет мелодии. Можно оказывается управлять с телефона им.
Один интересный вопрос возник у меня. Сделал для шарика голосовое управление через смартфон. В мит апп инверторе штатно нет возможности управлять ИК сенсором. На другом форуме подсказали статью одного немецкого автора - он сделал расширение под сенсор (набор пазлов) для инвертора. Но приложение, написанное с его пазлами, не очень стабильно с кодами кнопок триколоровского ИК пульта. Мне пришлось воспользоваться пультом от детской игрушки. Всё заработало, но возник вопрос чисто на знание. Чуть упростил его скетч для получения кодов кнопок и их "тайминг-сигнатур".
У меня для пульта получилось так:
В длинных строчках записаны 0 и 1 (как я понял из визуального анализа), их 10 штук с каждой кнопки (10 бит данных). В коротких строчках код кнопки. Есть ли связь между этими данными?, и какая? Просто на других пультах длинные строчки не менялись, а коды кнопок (для каждой) могли быть разные (связь неустойчивая видимо - данные терялись :-). Только вот какие и почему?
Конечно есть связь. См. например: https://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol