#1 Re: Проекти » Солнечный фонарь ATTiny85 & WS2812b + USB зарядка » 2021-05-04 08:14:36

YK

Это стандартный модуль питания. От USB можно заряжать разные гаджеты как Power Bank

#2 Проекти » Солнечный фонарь ATTiny85 & WS2812b + USB зарядка » 2021-04-23 17:31:26

YK
відповідей: 3

Солнечный фонарь ATTiny85 & WS2812b + USB зарядка



Снаружи

Изнутри


Возникла идея с сыном сделать простую и в тоже время непростую лампу. которая бы заряжалась от солнца и
автоматически включалась при наступлении темноты. Но чтобы имела 10 эффектов начиная от простого белого свечения ну так далее,
включая эффект свечи, конечно же с запоминанием режима.

Что понадобиться
1. Солнечная панель  https://arduino.ua/prod1353-solnechnaya-panel-6v-520-ma
2. Аккумулятор 18650.
3. Модуль питания https://arduino.ua/prod424-modyl-avtonomnogo-pitaniya-2a-na-18650-s-usb-vihodom
4. Attiny85, я брал Digispark. Так как стоимость не выше голого процессора https://arduino.ua/prod1985-plata-razrabotchika-attiny85-usb-ot-digispark
5. Кнопка включения выключения
6. Кольцо WS2812 на 12 или 16 светодиодов https://arduino.ua/prod1657-kryg-s-12-rgb-svetodiodami-ws2812-s-posledovatelnim-ypravleniem
7. Touch кнопка https://arduino.ua/prod264-ttp223-touch-key-sensornii-datchik-dlya-arduino

В качестве корпуса. Напечатали на 3d принтере след. модель https://www.thingiverse.com/thing:2966281



Схема соединения простая , паяем все к AtTiny


На PIN1 подключаем сигнальный вход ленты
На PIN4 подключаем сигнальный вход Touch
На PIN2 подключаем вход солнечной панели через резистор 1к и заземляем его резистором 6k (сопротивления можнов варьировать)

Подключаем питание и GND на все компоненты
Солнечную панель подключаем на вход модуля питания и GND
Следует уделить внимание модулю  питания, на его входе должен стоять диод шотки. Собственно я к нему и приваял провод.
Если его нет надо обязательно поставить

Все....

Основная фишка это прошивка. Задача след. пока светит солнце процессор спит и потребляет микроамперы. Вся энергия идет на заряд аккумулятора
Как только панель перестает выдавать энергию, процессор просыпаеться и запускает эффекты.
После нескольких дней экспериментов удалось все выжать по максиму.

Чтобы уменьшить энергопотребления были выаяны вся обвязка Digispark. Оставлены только конденсаторы по питанию .
Модуль Digispark был перепрошит обічной прошивкой через клипсу https://arduino.ua/prod2788-klipsa-dlya-programmatora-ch341a-sop8soic8-bios

Это было сделано по нескольким причинам,
1. Уже нет обвязки
2. MicroNucleus съедает более 2 кб памяти, а ее не хватило на все эфекты
3. MicroNucleus запускаеться 30 секунд. Соотв. лампа включаеться выключателе не сразу



Скетч

#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

//#define CFG_SLEEP_FIXEDBTN
//#define CFG_NO_SLEEP_SWITCHBTN
#define CFG_SLEEP_SWITCHBTN

#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

#define WDTO_INFINITE 255
#define SLEEP_PERIOD WDTO_8S
#define SKIP_WDT_WAKEUPS 14 // x SLEEP_PERIOD + SLEEP_PERIOD (14 ~= 120 sec)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
#ifdef CFG_SLEEP_FIXEDBTN
#define PIN 1
#define PIN_SOLAR 2
#define FIXED_BUTTON 4
#define PIN_BUTTON       -1
#define INCREASE_EFFECT_EVERY_SWITCH
#define FIXED_MODE 0
#elif defined(CFG_NO_SLEEP_SWITCHBTN)
#define PIN 1
#define PIN_SOLAR -1
#define FIXED_BUTTON -1
#define PIN_BUTTON       4

#elif  defined(CFG_SLEEP_SWITCHBTN)
#define PIN 1
#define PIN_SOLAR 2
#define FIXED_BUTTON -1
#define PIN_BUTTON       4
#endif

#ifndef NUM_PIXzs
#define NUM_PIX 12
#endif

#define EEPROM_ADDR_EFFECT_NUM 0x10


  
#define MODES_COUNT      11
#define SWITCH_MODE_DELAY_MS 5000
#define SOLAR_CHECK_DELAY_MS 1000
#define SWITCH_ON_BARIER 20




Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIX, PIN, NEO_GRB + NEO_KHZ800);

bool isOn=true;
bool isButtonPress=false;
int current_mode=0;
long next_switch_ms=0;
long next_checksolar_ms=SOLAR_CHECK_DELAY_MS;
bool isAutoModesSwitch=false;
#ifdef FIXED_MODE 
bool isFixedMode=false;
#endif
void showStrip() 
{

   strip.show();

 

}
//-----------------------------------------------------------------------------------------
void setAll(byte red, byte green, byte blue) 
{
  for(int i = 0; i < NUM_PIX; i++) 
  {
    setPixel(i, red, green, blue); 
  }
  showStrip();
}
//-----------------------------------------------------------------------------------------
void setPixel(int Pixel, byte red, byte green, byte blue) 
{
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));



}
void setup() 
{

  if(PIN_SOLAR>=0)
    pinMode(PIN_SOLAR,INPUT);
  if(PIN_BUTTON>=0)
    pinMode(PIN_BUTTON,INPUT);
#ifdef FIXED_MODE 
  if(FIXED_BUTTON>=0){
    pinMode(FIXED_BUTTON, INPUT_PULLUP);
    delay(20);
    isFixedMode=digitalRead(FIXED_BUTTON)==LOW;
    current_mode=FIXED_MODE;
  }
#endif
#ifdef FIXED_MODE 
if(!isFixedMode){
#endif
  byte state=eeprom_read_byte((uint8_t*)EEPROM_ADDR_EFFECT_NUM);
  if(state>0 && state<=MODES_COUNT){
   
    current_mode=state-1;
  }
  else{ 
    eeprom_write_byte((uint8_t*)EEPROM_ADDR_EFFECT_NUM, (uint8_t)(current_mode+1));
  }
#ifdef INCREASE_EFFECT_EVERY_SWITCH
   eeprom_write_byte((uint8_t*)EEPROM_ADDR_EFFECT_NUM, (uint8_t)(((current_mode-1)<MODES_COUNT?current_mode+1:0)+1));
#ifdef FIXED_MODE
}
#endif
#endif

  strip.begin();
  strip.setBrightness(255);
  strip.show(); 

 attachInterrupts();
 
}
ISR(PCINT0_vect)
{
  if(PIN_SOLAR>=0)
    isOn= (digitalRead(PIN_SOLAR)==LOW);
 if(PIN_BUTTON>=0 && !isButtonPress)  //give chance to process
   isButtonPress= (digitalRead(PIN_BUTTON)==HIGH);

//isButtonPress=!isOn;
}
ISR(WDT_vect)
{
  
}
void loop() 
{
 
  if(!isOn){
    setAll(0,0,0);
    delay(100);
 //   digitalWrite(PIN,LOW);
    sleep();
    return;
  }


  switch(current_mode){
    case 0:  Fire(40, 120, 200);break;
    case 1:  SnowSparkle(0x10, 0x10, 0x10, 20, random(100, 1000)); break;
    case 2:  RGBLoop(); break;
    case 3:   setAll(255,255,255); showStrip();delay(100); break;
    case 4:  Strobe(0x25, 0x20, 0x25, 10, 50, 1000); break; 
    case 5:  CylonBounce(0xff, 0, 0, 4, 10, 50); break;
    case 6:  Twinkle(0xff, 0, 0, 10, 100, false); break;
    case 7:  TwinkleRandom(20, 100, false); break;
    case 8:  RunningLights(0,0xFF, 0xFF, 50); break;
    case 9: rainbowCycle(20); break;
    case 10: theaterChase(0xff,0,0,50); break;
    default:
    break;
  }
  if(isButtonPress){
   // isAutoModesSwitch=!isAutoModesSwitch;
   current_mode++;
   if (current_mode >=MODES_COUNT) 
    current_mode = 0;
    eeprom_write_byte((uint8_t*)EEPROM_ADDR_EFFECT_NUM, (uint8_t)(current_mode+1));
    isButtonPress=false;
  }
  if(isAutoModesSwitch && next_switch_ms<millis()){
    current_mode++;
    if (current_mode > MODES_COUNT) current_mode = 0; 
    eeprom_write_byte((uint8_t*)EEPROM_ADDR_EFFECT_NUM, (uint8_t)(current_mode+1));
    next_switch_ms=millis()+SWITCH_MODE_DELAY_MS;
  }
 
  
}
void wakeUp(){

}
void attachInterrupts(){

    cli();
  // Disable interrupts during setup

  if(PIN_BUTTON>=0)
    PCMSK |= _BV( PIN_BUTTON);    // Enable interrupt handler (ISR) FOR BUTTON
  if(PIN_SOLAR>=0)
    PCMSK |= _BV(PIN_SOLAR);    // Enable interrupt handler (ISR) FOR SOLAR
  GIMSK |= _BV(PCIE);             // Enable PCINT interrupt in the general interrupt mask
 
  sei(); 
}
void detachInterupts(){
  if(PIN_BUTTON>=0)
    PCMSK &= ~_BV( PIN_BUTTON);    // Disable interrupt handler (ISR) FOR BUTTON
  if(PIN_SOLAR>=0)
    PCMSK &= ~_BV(PIN_SOLAR);    // Disable interrupt handler (ISR) FOR SOLAR
 
}
void sleep()
{
//  GIMSK = _BV(PCIE); // Включить Pin Change прерывания
//  if (SLEEP_PERIOD == WDTO_INFINITE )
//    PCMSK |= _BV(PIN_SOLAR); 
  
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    ACSR |= _BV(ACD); // Disable analog comparator
    /*
  if (SLEEP_PERIOD != WDTO_INFINITE) {
    wdt_enable(SLEEP_PERIOD); // установить таймер
    WDTCR |= _BV(WDIE); //switch on timer interrupts
  }
  */
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //  Power-down
  

  sleep_enable(); // 
 
  sleep_cpu();   
   cli();
    sleep_disable(); 
     ADCSRA &= _BV(ADEN); 
    ACSR |= _BV(ACD);
    attachInterrupts();
   sei();
 

  wakeUp();
 // ADCSRA |= _BV(ADEN); // on ADC
  
}

//-----------------------------------------------------------------------------------------

void SnowSparkle(byte red, byte green, byte blue, int SparkleDelay, int SpeedDelay) 
{
  setAll(red,green,blue);
 
  int Pixel = random(NUM_PIX);
  setPixel(Pixel,0xff,0xff,0xff);
  showStrip();
  delay(SparkleDelay);
  setPixel(Pixel,red,green,blue);
  showStrip();
  delay(SpeedDelay);
}
void Fire(int Cooling, int Sparking, int SpeedDelay) 
{
  static byte heat[NUM_PIX];
  int cooldown;
 
  // Step 1.  Cool down every cell a little
  for( int i = 0; i < NUM_PIX; i++) 
  {
    cooldown = random(0, ((Cooling * 10) / NUM_PIX) + 2);
   
    if(cooldown>heat[i]) 
    {
      heat[i]=0;
    } 
    else 
    {
      heat[i]=heat[i]-cooldown;
    }
  }
 
  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for( int k= NUM_PIX - 1; k >= 2; k--) 
  {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
   
  // Step 3.  Randomly ignite new 'sparks' near the bottom
  if( random(255) < Sparking ) 
  {
    int y = random(7);
    heat[y] = heat[y] + random(160,255);
    //heat[y] = random(160,255);
  }

  // Step 4.  Convert heat to LED colors
  for( int j = 0; j < NUM_PIX; j++) 
  {
    setPixelHeatColor(j, heat[j] );
  }

  showStrip();
  delay(SpeedDelay);
}
void RunningLights(byte red, byte green, byte blue, int WaveDelay) 
{
  int Position=0;
 
  for(int i=0; i<NUM_PIX*2; i++)
  {
      Position++; // = 0; //Position + Rate;
      for(int i=0; i<NUM_PIX; i++) 
      {
        // sine wave, 3 offset waves make a rainbow!
        //float level = sin(i+Position) * 127 + 128;
        //setPixel(i,level,0,0);
        //float level = sin(i+Position) * 127 + 128;
        setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
                   ((sin(i+Position) * 127 + 128)/255)*green,
                   ((sin(i+Position) * 127 + 128)/255)*blue);
      }
     
      showStrip();
      delay(WaveDelay);
  }
}
void CylonBounce(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay)
{
  for(int i = 0; i < NUM_PIX-EyeSize-2; i++) 
  {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) 
    {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }

  delay(ReturnDelay);

  for(int i = NUM_PIX-EyeSize-2; i > 0; i--) 
  {
    setAll(0,0,0);
    setPixel(i, red/10, green/10, blue/10);
    for(int j = 1; j <= EyeSize; j++) 
    {
      setPixel(i+j, red, green, blue);
    }
    setPixel(i+EyeSize+1, red/10, green/10, blue/10);
    showStrip();
    delay(SpeedDelay);
  }
 
  delay(ReturnDelay);
}
void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause)
{
  for(int j = 0; j < StrobeCount; j++) 
  {
    setAll(red,green,blue);
    showStrip();
    delay(FlashDelay);
    setAll(0,0,0);
    showStrip();
    delay(FlashDelay);
  }
 delay(EndPause);
}
void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) 
{
  setAll(0,0,0);
 
  for (int i=0; i<Count; i++) 
  {
     setPixel(random(NUM_PIX),red,green,blue);
     showStrip();
     delay(SpeedDelay);
     if(OnlyOne) 
     {
       setAll(0,0,0);
     }
   }
 
  delay(SpeedDelay);
}
byte * Wheel(byte WheelPos) 
{
  static byte c[3];
  if(WheelPos < 85) 
  {
   c[0]=WheelPos * 3;
   c[1]=255 - WheelPos * 3;
   c[2]=0;
  } else if(WheelPos < 170) 
  {
   WheelPos -= 85;
   c[0]=255 - WheelPos * 3;
   c[1]=0;
   c[2]=WheelPos * 3;
  } 
  else 
  {
   WheelPos -= 170;
   c[0]=0;
   c[1]=WheelPos * 3;
   c[2]=255 - WheelPos * 3;
  }
  return c;
}
void rainbowCycle(int SpeedDelay) 
{
  byte *c;
  uint16_t i, j;

  for(j=0; j<256*5; j++) 
  { // 5 cycles of all colors on wheel
    for(i=0; i< NUM_PIX; i++) 
    {
      c=Wheel(((i * 256 / NUM_PIX) + j) & 255);
      setPixel(i, *c, *(c+1), *(c+2));
    }
    showStrip();
    delay(SpeedDelay);
  }
}
void theaterChase(byte red, byte green, byte blue, int SpeedDelay) 
{
  for (int j=0; j<10; j++) 
  {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) 
    {
      for (int i=0; i < NUM_PIX; i=i+3) 
      {
        setPixel(i+q, red, green, blue);    //turn every third pixel on
      }
      showStrip();
     
      delay(SpeedDelay);
     
      for (int i=0; i < NUM_PIX; i=i+3) 
      {
        setPixel(i+q, 0,0,0);        //turn every third pixel off
      }
    }
  }
}
//-----------------------------------------------------------------------------------------
void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne) 
{
  setAll(0,0,0);
 
  for (int i=0; i<Count; i++) 
  {
     setPixel(random(NUM_PIX),random(0,255),random(0,255),random(0,255));
     showStrip();
     delay(SpeedDelay);
     if(OnlyOne) 
     {
       setAll(0,0,0);
     }
   }

  delay(SpeedDelay);
}
void RGBLoop()
{
  for(int j = 0; j < 3; j++ ) 
  {
    // Fade IN
    for(int k = 0; k < 256; k++) 
    {
      switch(j) 
      {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
    // Fade OUT
    for(int k = 255; k >= 0; k--) 
    {
      switch(j) 
      {
        case 0: setAll(k,0,0); break;
        case 1: setAll(0,k,0); break;
        case 2: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
  }
}
//-----------------------------------------------------------------------------------------
void setPixelHeatColor (int Pixel, byte temperature) 
{
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature/255.0)*191);
 
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
 // heatramp <<= 2; // scale up to 0..252
 setPixel(Pixel, 0, 0, 0);
  // figure out which third of the spectrum we're in:
  if( t192 > 0x80) 
  {                     // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) 
  {             // middle
    setPixel(Pixel, 255, heatramp, 0);
  } 
  else 
  {                               // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
}

#3 Re: Проекти » IOT, Умный дом на ESP32/ESP8266/ESP8255(Sonoff) » 2020-12-30 18:00:12

YK
АлЕксий_Духоборец пише:

Допустим у меня есть esp8266 node mcu. И мне надо фиксировать во времени геркон на двери и видеть эту историю через интернет. Сколько мне надо на это времени с закачкой json и т.д.

Ну насколько я понял вопрос, при срабатывании геркон, нужно отправлять данные в облако. Например ThingSpeak ?
Пакет в ThingSpeak  уходит за 50-100 мс. Дальше мы уже на зависим от esp и все данные смотрим в инете.
Либо не понял вопрос....

#4 Проекти » ESP32 Camera , что удалось выжать из модуля » 2020-12-30 17:56:13

YK
відповідей: 2

Решил выжать па максимуму из модуля ESP32 Cam.
Как известно, он построен на базе Wrower и имеет в отличие от обычного ESP32 дополнительную Flash память 4Мб (PSRAM)
Соответственно можно уже делать минимальную обработку снимков

Итак сначала:
За основу взять проект https://robotzero.one/esp32-face-door-entry/ , по этой ссылке детальная инструкция как прошивать ESP32 Camera
с помощью Arduino. Соответственно проект сохранил все свои особенности и может действительно открывать двери на определенные лица

Но я решил пойти дальше и использовать максимум возможностей
1. Управление Серво приводами по вертикали и горизонтали. Т.е. если на камеру навесить на серво приводы. Через встроенный Web интерфейс
можно управлять ими.

2. В случае если Лицо распознано, то модуль может поcсылать определённый RF 433. Через  подключенный RF433 Transmitter. Соотв. расширяются возможности интеграции с существующими замками. Уже не нужно управлять GPIO, достаточно послать сигнал. Также может быть удобно и для монтажа и развязки...

3. Пожалуй самое главное, научил камеру распознавать движение: Motion Detection. Это была пожалуй самая интересная часть как обойти все баги и лимитации предоставленного API. Решение оказалось интересное, в отличие от найденных аналогов в интернете.
Основной проблемой было то что, камеру можно инициализировать только один раз, и при  инициализации нужно задать желаемый формат. Для определения движения конечно надо сравнивать RAW data (BMP) и тут конечно вопрос. если постоянно получать данные RAW, то уже jpeg не получишь, соответственно отпадает возможность сделать нормальный capture и отправить его на e-mail
Поэтому попробовал и о чудо получилось быстро и изящно. Получаем с камеры данные в формате JPEG. Выигрываем в скорости. Т.к. обмен с камерой не очень быстрый, а данном случае модуль уже кодирует изображение и передает на ESP сжатое.
Далее конвертируем его в BMP, уже силами ESP32 ну и дальше техника сравнить два снимка и понять что было движение...
Вообщем встроенной PSRAM хватило вплоть до разрешений  FRAMESIZE_UXGA    // 1600x1200.
Т.е. можно уже жучков заметить....


4. Решил воспользоваться уже новыми свойствами и сделал интеграцию с Apple Home Kit. Apple теперь видит камеру как датчик движения и можно например с помощью встроенных сценариев уже включать свет в комнате в случае определения движения

5. Показалось мало и решил еще финально добавить отсылку почты со скриншотом, в случае определения движения. Здесь был очередной Challenge... Встроенные библиотеки WiFiClientSecure .При установлении SSL/TSL соединения требуют порядка 70-100 кб свободной памяти для handshake. С помощью ардуино ну никак не удалось заставить их использовать PSRAM. нашел много статей в инете, но все какие то WORKAROUND, и то для esp-idf. кстати параметры SDK и прекомпилинные библиотеки и содержат слово WORKAROUND в своих названиях.
Вообщем не получилось, да и бросил это, иначе проект тяжело переиспользовать. Проблема решилась путем остановки Apple Home Kit сервер и HTTP server, памяти хватило... Т.е. перед отсылкой все останавливаем. Отсылаем и заново запускаем.


Ну наверное уже все выжал из модуля. Вписался в OTA partition,и скетч занимает 99% из 100%.

Итак подводя итоги получилось наверное интересное устройство из разряда собери сам, ну и главное много наработок по работе с изображениями, почтой и т.п. и т..п

Кому интересно смотрите
https://github.com/Yurik72/ESPHap/tree/master/examples/ESPHAPCamera

#5 Re: Програмування Arduino » Помогите пожалуйста с кодом:светодиод и кнопки » 2020-12-15 11:28:59

YK

Когда то писалось на форуме что при все простоте, задача обработки нажатия кнопки может сильно усложниться, если учесть
дребезг, очередь нажатий и т.п.

Поэтому возьми готовую библиотеку в инете, для обработки кпопки и задача решиться сама собой

#6 Проекти » Sonoff PIR2 & Sonoff RF без доп. бриджей плюс интеграция с Apple Home » 2020-11-12 15:38:52

YK
відповідей: 0

Есть такой замечательный и простой датчик  Sonoff PIR2

Однако для использования его нужен RF приемник который принимает сигнал. Как советует производитель можно его совместно использовать с Sonoff RF Bridge 433.

Я решил обойти это дело и использовать RF приемник с другого Sonoff устройства Sonoff RF


Sonoff RF содержит уже самообучаемый RF receiver, который хранит до 15 кодов. В оригинальном исполнении предназначен для возможности включать и выключать реле с помощью RF брелка. Это lополнительно к  возможностям управления по WiFi.


Ближе к делу. Как всегда оригинальная прошивка с китайским облаком меня не интересует, поэтому выкидываем ее смело в форточку:)

Итак к делу.

На первом этапе надо перепрошить Sonoff. Берем скетч  EspHapSonoff_RFBridge  и делаем это c помощью Arduino.  Все инструкции можно найти там же на github. 

На втором этапе обучаем Sonoff RF коду передаваемому из Sonoff PIR2. Получилось все просто, код запомнился с первого раза.
Теперь при обнаружении движения Sonoff RF  принимает сигнал.

Благодаря прошивке в Apple Home Kit появилось 2 устройства  Switch (Light Bulb) Motion sensor.
Разместил устройства как мне удобно. Sonoff RF управляет включением торшера.  Sonoff PIR2 висит под потолком в гостиной.

В Apple Home добавил сценарий, что при обнаружении движения после заката солнца включать свет в гостиной на 30 мин.
Весь свет не только торшер. К слову есть другие устройства умного дома.

Вот дешево и сердито умный дом стал умнее.
Из плюсов Sonoff PIR2  питается от батареек и их надолго хватает. а главное можно разместить где угодно

#7 Re: Програмування Arduino » ESP8266 (ESP-12E) - Монитор порта: "rst cause:2, boot mode:(3,6))" » 2020-10-08 08:35:59

YK

Ну как 2 последних лекарства
1. попробуй поменять местами SDA <-> SLC
2. Подтянуть RST резистором 1-10 ком на 3.3v. Может он у тебя банально в reset висит.

#8 Re: Програмування Arduino » Не працює вкладена функція millis() » 2020-10-08 08:03:07

YK

У тебя при первом цикле previousMillis2=0 , соотв. первый цикл не дает никакую задержку
сделай  инициализацию previousMillis2  в начале loop например
if(previousMillis2  ==0)
   previousMillis2=millis();

Хотя конечно накручено но идея правильная уйти от delay()

#9 Re: Програмування Arduino » ESP8266 (ESP-12E) - Монитор порта: "rst cause:2, boot mode:(3,6))" » 2020-10-07 10:19:55

YK

Ну вначале я бы проверил. подключился ли у тебя датчик или нет
  if(!ccs.begin()){
    Serial.println("Failed to start sensor! Please check your wiring.");
    while(1);
  }

Следующее надо убедиться что нет проблем с питанием.
Датчик подключаеться напрямую к 3.3 соотв использует тот же стабилизатор что и само ядро. Я сталкивался не раз платами  когда его банально не хватало даже запустить Wifi. Ну для начала надо убедиться что у тебя хорошие 5 вольт, а потом уже експерементировать с 3.3. Попробовать отдельно его запитать. не забыв про общую землю

#10 Проекти » IOT, Умный дом на ESP32/ESP8266/ESP8255(Sonoff) » 2020-06-11 13:43:57

YK
відповідей: 2

И так пред история, увлекся собственным умным домом и в какой то момент понял, что невозможно поддерживать версии более 5 устройств, там улучшил там осталось, там протестировал, там нет,и бесконечный круг... И в итоге написал по моему мнению универсальную прошивку, которая покрыла все мой весь умный дом начиная от простых светильников и розеток и заканчивая погодными станциями и различными RF бриджами.

Ну и конечно же конек всего этого нативная интеграция в Apple Home Kit.  Все  устройства у меня интегрированы и управляются через Apple Home.  Но так как не все используют Apple в прошивке есть возможность использовать MQTT для интеграции с другими системами. Благо практически все продвинутые уже их поддерживают

Вот хорошо описанные примеры

Лампа
https://www.instructables.com/id/Bed-Room-Lamp-Ws2812/

[MEDIA=youtube]Ja1Og2USEgE[/MEDIA]


Погодная станция

https://www.instructables.com/id/ESP32-Weather-Station-Solar-Powered/



еще одна лампа с термометром

https://www.instructables.com/id/Accu-Multicololred-LED-Lamp-With-Weather/



Как написано на главной странице прошивка поддерживает след. устройства (на момент написания)

- обычные свитчи/реле

- диммируемые модули ШИМ, для управления яркостью

- Датчики температуры влажности и давления (BME180, Dallas)

- Кнопки, энкодеры

- Oled и e-paper дисплеи

- RF приемники и передатчики

- Датчики движения

- Серво двигатели

- IR приемники и передатчики

- различные LDR





Ну и собственно вокруг этого всего:



Встроенный WEB сайт. Написанный на React JS
OTA
Интеграция с умным домом через протокол MQTT
Нативная интеграция с Apple Home Kit
Web сервиса




Итак в двух словах, имеем единую прошивку для всех устройств, разница в поведении определяеться конфигурационными файлами JSON, которые храняться в корне SPIFFS системы ESP, этим и определяя поведение.... Т.е. прошивку можно смело менять, файлы остаються и устройство продолжает работать как хотели



Итак центральный файл config.json


{"localhost":"LampFire","mqtt_host":"","mqtt_port":"1883","mqtt_user":"homekit","mqtt_pass":"031-45-154"}




Содержит имя хоста, и параметры подключение к MQTT, если собираетесь использовать



След центральный файл services.json, содержит список и характеристики подключенных устройств .

Это массив след. вида

[{"service":"TimeController","name":"Time","enabled":true,"interval":1000,"timeoffs":7200,"dayloffs":3600,"server":"pool.ntp.org"},

{"enabled":true,"interval":1,"pin":23,"numleds":256,"service":"RGBStripController","name":"RGBStrip","issmooth":false,"manualtime":6000,"ismatrix":true,"matrixwidth":16,"matrixtype":8},

{"enabled":true,"interval":1,"pin":"","service":"ButtonController","name":"Button","defstate":false,"pins":[16]}

]


- service: базовый элемент который собственно и определяет тип устройства



- name : Имя устройства, важно, так как мы можем подключить несколько однотипных устройств



- interval: частота срабатывания или опроса в миллисекундах. например для управления светильниками нужно небольшое значение, а для отсылки данных в интернет, конечно побольше. Собственно можно тюнить и не перегружать процессор



pin: номер пина к которому подключено устройство/датчик, для некоторых устройств их конечно несколько с разными именами,



ну и далее разные параметры специфичные для сервиса, сам сервис умеет выдавать параметры по умолчанию и Web сайт позволяет их редактировать, т.е. не надо  смотреть в код



Опять же через Web сайт можно добавлять/удалять сервиса


Ну и следующий конфигурационный файл,  triggers.json, это собственно взаимодействие между сервисами, т.е. когда что то в одном происходит, можно передать команду другому сервису

Как пример:

- нажали кнопку
- уровень освещенности достиг чего то
- сработал таймер (о нем более детально будет позже)
- RF приемник получил какой то конкретный сигнал


Вот пример триггера:

[{"type":"TimeToRGBStrip","source":"Time","destination":"RGBStrip","value":[{"isOn":false,"isLdr":false,"time":2300,"bg":1,"color":3432432,"fadetm":1000,"wxmode":-1}]},{"type":"ButtonToRgbStripMode","source":"Button","destination":"RGBStrip","modes":[0,56,58],"idx":0}]

- type: тип триггера из имеющихся
- source: От какого сервиса (имя)
- destination: какому сервису (имя)
- value: специфические значение и пороговые значения для данного типа триггера

В описанном примере мы определили тип триггера таймер, который управляет RGB лентой (WS2812)
при наступлении 23:00 лампа будет переведена в яркость  "bg":10, статический режим "wxmode":-1, цвет "color":3432432

Конечно же через Web сайт это можно задать не углубляясь в название и список параметров

Ну отдельное упоминание "time":2300 , могут быть простые значение ЧЧММ, т.е. каждый день в заданное время что то происходит, а может быть cron expression, тут уж можно развернуться и по месяцам и по дням недели.

"fadetm":1000   плавность в миллисекундах перехода от текущего значения в заданное, т.е. например плавное повышение яркости

Ну и конечно, если вы используете нативный Apple Home Kit. он добавляет возможность определения сценариев с помощью внутренних средств, как пример из интересных  плюшек включение по закату солнца....

Как пример выше, еще один триггер  ButtonToRgbStripMode. Он реагирует на нажатии кнопки и переключает режимы лампы между

0,56,58. Собственно 0 выключено, 58  режим огня. Ну или определяйте сами

Итак все что остается сделать это собрать из кубиков готовое устройство

Шаги достаточно простые, после компиляции и залития прошивки (детально не описываю, все стандартно )

ESP запускается в известном режиме конфигурации соединения WiFi, все стандартно....

После подключения к сети , устройство само проверяет и докачивет файлы для встроенного Web сайта, беря последнюю версию с моей страницы Git Hub.

Далее запускаем встроенный файл менеджер (http://  ip address /browse) и можем залить  config.json, triggers.json и services.json. Ну или использую сайт (корневой адрес) можем сконфигурировать через User Interface

Перегружаем и устройство работает

Через (http://  ip address /update)  можем заливать новые версии прошивок

При сборке прошивки, собственно придется только один раз подправить config.h файл

а именно:



#define ENABLE_NATIVE_HAP

///#define ENABLE_HOMEBRIDGE



это выбрать режим интеграции с умным домом нативный Apple ENABLE_NATIVE_HAP   или MQTT ENABLE_HOMEBRIDGE

Все вместе , не тестировал, по отдельности все прекрасно работает. Ну странно иметь MQTT и еще нативный Apple



В принципе все для ESP32, для ESP8266 есть нюансы,  так как память ограничена не все сервиса "влазят" в одну прошивку, напомню если сервис и отключен его код есть в прошивке, соответственно надо будет подредактировать секцию ниже какие сервиса вы хотите оставить.



Теперь еще один пример об огненной лампе Gyver Lamp, она уже получила большое распространение и даже уже кажеться китайцы ее делают.
в примерах выше я привел конфигурационные файлы, ну можно смотреть здесь

По умолчанию сконфигурирована для нативной интеграции с Apple Home Kit. После подсоединения к сети вы сможете ее добавить в умный дом. Детали смотрите здесь

Ну и конечно описано все красиво, но в реалии есть баги, поэтому не судите, думаю идея понравилась

Ну а баги надо править и улучшать. надеюсь на понимание и поддержку smile

P.S. Если кому интересно могу на заказ доработать

#11 Re: Програмування Arduino » Помогите Пожалуйста Новичку » 2020-06-10 14:33:49

YK

Бегло просмтривая код, думаю проблема в рассинхронизации комманд.
Например ты отправляешь X1000 но по какой то причине Serial.parseint() не дочитывает данные.
Т.е. срабатывает time out 1 sec по умолчанию для parseint(). и Arduino вычитала только X100, соответсвенно все остальные команды уже сыпяться

Посмотри в отладчике порта, что ты получаешь в Arduino, ну и наверное надо команды терминировать новой строкой
Тогда ParseInt не будет ждать 1 sec, а для тебя это будет признак целостности команды, новый свой цикл всегда будет начинаться после получения новой строки
Код надо будет подправить что вычитать и проверить новую строку

#12 Re: Програмування Arduino » Цветовой круг » 2020-03-16 14:14:54

YK
Maximumdp пише:
YK пише:

http://jsfiddle.net/53JBM/

это просто круг, он не кликабельный, такие и я находил....


Уважаемый, просто никто наверное не понял ваш вопрос. Под какую платформу, какой язык вы хотите использовать
Ибо скриншот  ни о чем не говорит. Чего еще там должно быть ?

#14 Програмування Arduino » Программируем Sonoff B1 c интеграцией в Apple Home Kit вторая часть 2 » 2020-03-14 18:47:04

YK
відповідей: 0

Итак купил на днях лампу
https://arduino.ua/prod3217-ymnaya-lampa-sonoff-b1-e27-led-rgbw

И конечно же сразу написал  под нее скетч.
Кому интересно
https://github.com/Yurik72/ESPHap/tree/master/examples/Sonoff_B1_web

Как ни странно все заработало с первого раза, идею взял и портировал из https://github.com/xoseperez/espurna

Цвета пока не супер идеал, в принципе так и задумано в оригинале. если включаем полную яркость , включаються только белые каналы, если уменьшаем яркость хорошо работают RGB, в принципе наверное это  и не нужно. Приглушенный цвет любого цвета, либо что то среднее, либо просто лампочка диммированная
Лампа имеет
1. Светодиоды Warm
2. Светодиоды Cool
3. RGB светодиоды

Т.е. всего 5 каналов на контроллере MY9231 .

C телефона управляется отлично,сижу думаю над идеями как улучшить цвета (комбинация каналов).
С Apple мы получаем 3 параметра, Hue, Saturation, Brigthness, вот если цвет белый, все просто. врубаем все каналы и управляем яркостью, если нет. получается  надо правильно пригасить белые светодиоды, иначе они задавливают цвет

Может сделать два устройства в Apple Home . Одно для белого цвета, второе для RGB
Но наверное перебор, две иконки для одной лампы....

#15 Re: Програмування Arduino » энкодер это просто » 2020-03-05 12:13:34

YK
Watchdog пише:
YK пише:

... можно анализировать в loop

Можно если loop выполняется не дольше длительности импульсов энкодера. Эта штука называется квадратурный энкодер. Погуглите - полезно.

Принципиально не согласен.
Если правильно организовать loop c очисткой history из моего примера, то сам history ,будет выполнять роль очереди. и пусть
loop крутиться сколько надо

#16 Re: Програмування Arduino » энкодер это просто » 2020-03-05 10:37:23

YK

Я так понимаю что правильное определение вращения это последовательность замыкания и РАЗМЫКАНИЯ контактов
Почему бы не сделать что то  так (пример для первого кода от renoshnik)


unsigned long history=0;
void KY040() {

e_B = PIND&(1<<3);    e_A = PIND&(1<<2);

history=(history <<1) | e_A ;
history=(history <<1) | e_B ;

// теперь можно смотреть последовательности замыканий размыканий
//например для вращения по часовой маска =B0101, т.е.
if(history & (B0101)){ Serial.println(" counter-clockwise ");};
if(history & (B1010)){ Serial.println(" clockwise ");};

//ну и можно "усилить" несколькими щелчками , типа B01010101  - явно крутим против часовой

}
P.S. я код не тестировал, возможно в битах ошибся, просто идея.
Ну и конечно не писать длинных обработчиков в прерываниях, тот же Serial.print уже может быть проблемой, например историю можно анализировать в loop

#17 Програмування Arduino » Программируем Sonoff c интеграцией в Apple Home Kit » 2020-03-04 21:08:19

YK
відповідей: 1

Выдалось очередное свободное время и закончил прошивочку для Sonoff под Arduino с нативной интеграцией в Apple Home Kit

Из пред-истории, в виду достаточной дешевизны девайсов и отсутствия времени паять собственные, хотелось использовать линейку
Sonoff по максимуму для умного дома.

Как все знают стандартная прошивка лезет в китайское облако и плюс зависимость от приложения, а у меня все построено на Apple Home kit, поэтому хотелось бы управлять устройствами через одно приложение, да я яблочник smile

Где то полгода назад я уже научился это делать, но только в среде ESP-IDF, воощем целая история...
А для блага общества и самому хотелось сделать это из Arduino.

Ну и вот свершилось сегодня, первый девайс перепрошит и стабильно работает.
Пришлось конечно пойти на разные ухищрения наверное отдельный топик, ну а главное это найти память и процессорную мощность
для криптования и декриптования коммуникаций с Apple через wolfssl

На сегодняшний день из мелких недостатков замечен только процесс спаривания с Apple (выполняется один раз на устройство) бывает не с первого раза, тогда надо опять. Но после никаких глюков не замечено

Вообщем смотрите
библиотека

https://github.com/Yurik72/ESPHap

и собственно скетч

https://github.com/Yurik72/ESPHap/tree/master/examples/Sonoff_basic


Естественно можно поддерживать теперь всю линейку , вопрос распиновки, ну это уже просто и приятно smile


Инструкция:
1. Подготавливаем Arduino для работы c ESP8266, смотрим например здесь https://habr.com/ru/post/371853/
2. Качаем библиотеку  https://github.com/Yurik72/ESPHap и распаковываем в Arduino libraries folder. Для Windows это как правило
C:\Users\<username>\Documents\Arduino\libraries
3. Из вложенного архива https://github.com/Yurik72/ESPHap/tree/master/wolfssl  распаковываем wolfSSL_3_13_0.rar  в ту же папку библиотек Arduino. Лучше назвать ее wolfssl
4. Качаем или устанавливаем библиотеку https://github.com/tzapu/WiFiManager
4.1 Открываем скетч https://github.com/Yurik72/ESPHap/tree/master/examples/Sonoff_basic. Правим если нужно GPIO, у разных моделей и лампочек могут отличаться...

5. Далее готовим Sonoff можно например посмотреть здесь https://mysku.ru/blog/aliexpress/54424.html детально или погуглить
5.1. Паяем гребенку
5.2 Через USB UART переходник подключаем 3.3v->3.3v, GND->GND, RX->TX,TX->RX  . Sonoff должен быть отключен от 220v !
5.3  Подключаем USB UART  к компьютеру. В Arduino выбираем соотв. COM порт и плату ESP8285 (Не ошибся !!!!)
5.4 Если USB UART c кнопкой reset, то Нажимаем загрузить прошивку ждем сообщения о загрузке и жмем и держим кнопку на Sonoff и нажимаем кнопку Reset, ждем начала загрузки, после этого кнопку на Sonoff можно отпустить
Если без кнопки Reset, то вынимаем USB из компьютера , жмем и держим кнопку на Sonoff , вставляем USB и нажимаем "загрузка". После начала загрузки кнопку можно отпустить.
Все это нужно чтобы перевести Sonoff в режим загрузки (GPIO0 на GND в момент включения питания)

6. После завершения загрузки. Sonoff   стартует в режиме Access Point, найдите точку WiFi с именем ES и подключитесь
7. После подключение вероятно будете перенаправлены на стартовую страницу, если нет, в browser вводим 192.168.1.4   и  выбираем вашу Wifi, задаем пароль
8. Устройство перестартует
9. Открываем телефон -> Apple home - > добавить устройство.
10. Выбираем добавить вручную и видим доcтупное что то типа ES....... , выбираем его, соглашаемся конечно что оно не сертифицированное , вводим пароль 11111111 и поехали.....
11. Как правило все пройдет с первого раза и вы тут же увидите его в устройствах и можете включать выключать. Для проверки обратной реакции можно жать на кнопку Sonoff смотреть что статус обновляется..

12. Если что то пошло не так, (Pairing process самый капризный) лучше все удалить с устройства, перепрошить и попробовать опять
На моем опыте у меня было максимум 3 попытки. хотя в большинстве все проходит с первого раза
Для профессионалов, данные Pairing сохраняються в файловой системе SPIFFS  "/pair.dat". может быть что Sonoff уже успел сохранить  а Apple нет. Т.е. чтобы возобновить ошибку Pairing достаточно удалить этот файл и начать сначала.  В принципе можно раскоментировать длинное нажатие кнопки
//  SPIFFS.remove(pair_file_name);  //clean pairing data
         // WiFi.disconnect(true);   //lost saved wifi credentials

тогда при длинном нажатии утсройство забудет все на свете


Ну и все отключаем USB , подключаем Sonoff к 220 и балуемся..

#19 Re: Програмування Arduino » Изготовлю на заказ ! » 2020-02-28 13:33:08

YK
oyoy пише:

Потрібна допомога.

Є готовий проект (скетч), лінійка енкодер від принтера (все чудово працює) але, вивід інформації на LCD 1602 під'єднаний по I2C., потрібно перелопатить для під'єднання 6 розрядного семисегментного індикатра (ймовірно через ТМ1637?)

Вышли скетч в личку посмотреть

#20 Re: Програмування Arduino » Обработка кнопки, что может быть проще... » 2020-02-28 13:15:17

YK
Kaka пише:

Ещё как возможно! У 328 прерывания есть на всех пинах.


Да раззадорил ты меня, прочел доку по 328, действительно возможно
Пришлось сделать   roll     Пока прицепился к PORTB т.е. "аппаратные"  кнопки можно вешать на D8-D15

Код как всегда здесь
https://github.com/Yurik72/SimpleButton

Думаю пора остановиться big_smile

#21 Re: Програмування Arduino » Обработка кнопки, что может быть проще... » 2020-02-28 09:09:27

YK
Kaka пише:

Ну, очевидно, что на очереди следующий шаг - написать "почти собственный класс", чтобы на Нано и ей подобных стало можно обрабатывать прерывания от любого пина.

Пиши, останавливаться на полпути - нехорошо.

Это перебор, да и наверное аппаратно невозможно.
Лучше всегда использовать ESP32, чуть дороже зато все на борту и 2 ядра процессора и память и файловая система
А для Нано удел решать  простые задачки, думаю 2 кнопок всегда достаточно

#22 Re: Проекти » Автоматизация гидропоники, разработка контроллера » 2020-02-28 08:57:12

YK
Watchdog пише:

Альтернативная агрономия должна снабжаться энергией от альтернативной энергетики, и будет очень вкусно! lol

Так а здесь вообще вопросов нет. У меня уже 2 года в теплице стоит светильник (фито проектор)от солнечной батареи.
Все вместе обошлось почти копейки солнечная панелька , контроллер заряда и аккумулятор
Имеем бесплатные 12 Вольт питания и подключаем все что хотим...

#23 Re: Проекти » Автоматизация гидропоники, разработка контроллера » 2020-02-28 08:53:06

YK
Batu пише:

Интересная тема. Можно сделать вкусную систему. Надо пообщаться за подробности. Лучше скайп или вайбер. 0961135437

Это ответ кому ?
Как я писал софт без проблем, электронику разработать и соединить без проблем. Интересно ?

#24 Програмування Arduino » Обработка кнопки, что может быть проще... » 2020-02-27 18:25:35

YK
відповідей: 8

Стояла достаточно простая задача для школьного проекта, на одной стороне реализовать передатчик, чтобы он по нажатии кнопки кнопок отправлял команду на приемник. Как один из вариантов через Web  с использованием ESP32.
Но в данном случае не важно, пусть будет любое другое железо с Wifi , BLE или LAN.
Решил помочь в написании скетча и проще простого стал искать библиотеку для обычной кнопки, естественно, что то быстро нашел, работает... Но первая же нормальная интеграция показала, что если нажать на кнопку несколько раз быстро, часть команд теряется естественно. Ну в общем понятно... посмотрел код библиотеки, конечно пока   выполняется обработчик нажатия, все последующие нажатия теряются.
Да плюс к тому же отдельные библиотеки для обычной и Touch кнопки, а разница то всего в логическом уровне при нажатии...
Ладно, раззадорило, стал искать и ничего толкового не нашел потратил больше часа, думаю сам быстрее напишу.  Чего бы проще, все нажатия запоминаем в очередь и отдельно по одному обрабатываем очередь,  Принципиально то что запоминание в очереди и процессинг выполняется в разных потоках. Ну тут слово поток неуместно так как на ардуинах их нет , на прерываниях все. Ну да ладно псевдо параллельное выполнение устраивает
Назвал класс СSimpleButton и стал писать код  под ESP32. Решил пару задач попутно как сделать удобным класс , Как уйти в обработчике от ISR. Ну все классно заработало, Сделал еще пару  удобств чтобы вообще не писать и не интегрироваться в Loop. Ухожу от прерывания ISR в прерывание от Таймера и там выполняю обработчик

Т.е. например имеем несколько кнопок каждая посылает какую то длинную команду все работает как часы и все параллельно, да и писать просто смотрите сами
CSimpleButton btn;
void setup(){
btn.Create(0, button_callback);
}
void button_callback(uint8_t gpio, button_event_t event) {
    switch (event) {
    case button_event_single_press:
       
        hueClient.Toggle(0);
        break;
    case button_event_long_press:
       
        break;
    default:
       
    }
}
Больше никаких Loop и т.п.
В данном случае hueClient.Toggle(0);  Это WEB (HTTPClient) который отсылает команду на лампочку Philips Hue, включить выключить.
Дети довольны.
Но ту бац, решили Arduino использовать , Nano по моему. Ладно думаю за 3 минуты портирую код. Ага очередная неудача библиотеки от Arduino не поддерживают attachInterrupt    с возможностью callback с аргументами. Бред ну кому нужна чистая голая функция callback без единого параметра и понимание что произошло.....

Короче прошел еще час, отказался от идеи дописать стандартную библиотеку, тяжело поддерживать да и потеряются изменения. 
Порылся в интернете, все задают один и тот же вопрос и ответ нельзя.
Ну да ладно.... написал еще почти собственный класс, стало можно


Но тут опять бац.  Взяли Arduino Nano, а она цепляется к прерыванию только 2 пинами (2 и 3) остальные нет.
А класс удобный уже, ладно еще 15 минут   работы. Можем ставить сколько хотим кнопок, но уже не все правильно будут реагировать на очередь, те которые к прерыванию не цепляются
Думаю пока хватит 2 кнопок с возможностью нервно давить

Да вернулся к названию класса, он по прежнему называется Simple…
Наверное надо переименовать
В другой раз когда появиться желания дорешать проблемы переименую
Смотрите здесь
https://github.com/Yurik72/SimpleButton

Кому понравиться, поставьте хоть звездочку на погоны smile

#25 Re: Програмування Arduino » Ввод задержки с клавиатуры » 2020-02-27 15:35:12

YK

Ну так оно точно нормально работать не будет.
В коде не должно быть задержек delay()....
И не надо замораживать поток Serial.Read....

Почитай что то типа https://www.instructables.com/id/Coding-Timers-and-Delays-in-Arduino/


Ну или обратись к кому то чтобы нормально написали

Підвал форуму