Самодельная умная подсветка на квадрик

shura2000

Ставил на Гексу вот такую фиговину www.hobbyking.com/hobbyking/…/uh_viewItem.asp?idPr…
вместо RGB ленты припаял обычные одноцветные. Получилось как бы 3 канала. На гексе наклеил их на противоположные лучи. Эффекты переключаются с аппы, от строба до бегущих огней.

Dreadnought

Идея и реализация мне понравились. Пожалуйста, как будут видео полётов- покажите и сюда тоже.

Dreadnought

Очень занятно вышло! А частота моргания же зависит от величины отклонения стика? то есть - чем больше отклонение тем больше интервалы?

raefa

Спасибо. Зависимости нет. Специально не делал, т.к. с малой разницей особо заметно не будет, а если большую разницу, то луч будет почти гаснуть, а тут уже ИМХО непонятки читаемости могут быть.

shura2000

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

chanov

А исходный код глянуть то можно, или тайна за печатями? )
p/s себе решил такой огород не делать … смысла и информативности для меня в этой ёлке маловато, разве что для зевак хорошо ) …
p/p/s но включение по газу и просто мигание (затухание) перед-зад сделать конечно можно будет на гексу.

raefa

Вроде то ничего секретного нет. 😃
Если кто будет юзать код, то прошу все дополнения/изменения/предложения/улучшения/новые_идеи тоже выкладывать сюда.

#include <EEPROM.h> // подключить библиотеку
int a=100, b=100, t=0, y=0, r=0, p=0; // a= время включенного, b = время выключенного, t - throttle, y - yaw, r - roll, p - pitch
int jumper, writed=0, readed=0, temp, i; //джампер, записано в EEPROM, временная
int Tmin=20000, Tmax=0, Ymin=20000, Ymax=0, Rmin=20000, Rmax=0, Pmin=20000, Pmax=0; //Максимальные значения сигнала
int Tmi=0, Tma=0, Ymi=0, Yma=0, Rmi=0, Rma=0, Pmi=0, Pma=0; //Границы срабатывания
int Tinv=0,Pinv=0; //инвертирование Throttle и Pitch
//Tinv = 0 - газ не инвертирован; 1 - газ инвертирован
//Tinv = 0 - тангаж не инвертирован; 1 - тангаж инвертирован
//читается состояние перемычки после записи концов стиков

///////////////////////////////////////////////////////////////////////////
// подпрограммы записи и чтения Integer (2 байта) - указывать четные байты
///////////////////////////////////////////////////////////////////////////
void EW(int p_address, int p_value)
        {
        byte lowByte = ((p_value >> 0) & 0xFF);
        byte highByte = ((p_value >> 8) & 0xFF);
        EEPROM.write(p_address, lowByte);
        EEPROM.write(p_address + 1, highByte);
        }
unsigned int ER(int p_address)
        {
        byte lowByte = EEPROM.read(p_address);
        byte highByte = EEPROM.read(p_address + 1);
        return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
        }
///////////////////////////////////////////////////////////////////////////
void setup()
{
  delay(2000);
     digitalWrite(4, 1); digitalWrite(5, 1);
     delay(700);
     digitalWrite(4, 0); digitalWrite(5, 0);
     delay(100);
     digitalWrite(4, 1); digitalWrite(5, 1);
     delay(100);
     digitalWrite(4, 0); digitalWrite(5, 0);
     delay(100);
  pinMode(0, INPUT);    // вход throttle
  pinMode(1, INPUT);    // вход yaw
  pinMode(2, INPUT);    // вход roll
  pinMode(3, INPUT);    // вход pitch
  pinMode(4, OUTPUT);    // выход на подсветку FL
  pinMode(5, OUTPUT);    // выход на подсветку FR
  pinMode(6, OUTPUT);    // выход на подсветку RL
  pinMode(7, OUTPUT);    // выход на подсветку RR
  pinMode(8, INPUT);
  jumper=0;

jumper=digitalRead(8);
if (jumper==1) //если джампер установлен, то выполнять калибровку
{
for (int i=0; i <= 150; i++)//150 циклов для чтения отклонения стиков (15 секунд)
  {
  digitalWrite(4, 1); digitalWrite(5, 1); digitalWrite(6, 1); digitalWrite(7, 1);
  delay(10);
  t = pulseIn(0,HIGH,20000);
  y = pulseIn(1,HIGH,20000);
  r = pulseIn(2,HIGH,20000);
  p = pulseIn(3,HIGH,20000);
  if (t<Tmin) {Tmin=t;} //поиск минимальных/максимальных
  if (t>Tmax) {Tmax=t;}
  if (y<Ymin) {Ymin=y;}
  if (y>Ymax) {Ymax=y;}
  if (r<Rmin) {Rmin=r;}
  if (r>Rmax) {Rmax=r;}
  if (p<Pmin) {Pmin=p;}
  if (p>Pmax) {Pmax=p;}
  digitalWrite(4, 0); digitalWrite(5, 0); digitalWrite(6, 0); digitalWrite(7, 0);
  delay(10);
  }
  if (Tmin!=20000 && Tmax!=0 && Ymin!=20000 && Ymax!=0 && Rmin!=20000 && Rmax!=0 && Pmin!=20000 && Pmax!=0)
  {
  Tmi=Tmin+50; //граница начала срабатывания по газу
  Tma=Tmax-50;
  Ymi=(Ymin+Ymax)/2-40; Yma=(Ymin+Ymax)/2+40;//границы начал срабатываний
  Rmi=(Rmin+Rmax)/2-40; Rma=(Rmin+Rmax)/2+40;
  Pmi=(Pmin+Pmax)/2-40; Pma=(Pmin+Pmax)/2+40;
  if (writed==0)//если не записано, то писать
    {
      EW(0,Tmi);  delay(100); EW(2,Tma);  delay(100);
      EW(4,Ymi);  delay(100); EW(6,Yma);  delay(100);
      EW(8,Rmi);  delay(100); EW(10,Rma); delay(100);
      EW(12,Pmi); delay(100); EW(14,Pma); delay(100);
      EW(16,Tinv);delay(100); EW(18,Pinv);delay(100);
//запись минимума максимума для проверки
      EW(20,Tmin); delay(100); EW(22,Tmax); delay(100);
      EW(24,Ymin); delay(100); EW(26,Ymax); delay(100);
      EW(28,Rmin); delay(100); EW(30,Rmax); delay(100);
      EW(32,Pmin); delay(100); EW(34,Pmax); delay(100);
      EW(36,Tinv); delay(100); EW(38,Pinv); delay(100);
      writed=1;
    }//конец записи
  if (writed==1)//если записано, то мигнуть длинный и короткий
   {
     digitalWrite(6, 1); digitalWrite(7, 1);
     delay(700);
     digitalWrite(6, 0); digitalWrite(7, 0);
     delay(100);
     digitalWrite(6, 1); digitalWrite(7, 1);
     delay(100);
     digitalWrite(6, 0); digitalWrite(7, 0);
     delay(100);
     writed=2;
     jumper=0;
    } //конец мигания подтверждения конца

    for (i=0; i<=5000; i++)
    {
      Tinv=digitalRead(8); //проверка и запись состояния джампера инвертора газа
      delay(1);
    }
    EW(16,Tinv);delay(100);
     digitalWrite(4, 1); digitalWrite(6, 1);
     delay(700);
     digitalWrite(4, 0); digitalWrite(6, 0);
     delay(100);
     digitalWrite(4, 1); digitalWrite(6, 1);
     delay(100);
     digitalWrite(4, 0); digitalWrite(6, 0);
     delay(100);

    for (i=0; i<=5000; i++)
    {
      Pinv=digitalRead(8); //проверка и запись состояния джампера инвертора тангажа
      delay(1);
    }
    EW(18,Pinv);delay(100);
     digitalWrite(5, 1); digitalWrite(7, 1);
     delay(700);
     digitalWrite(5, 0); digitalWrite(7, 0);
     delay(100);
     digitalWrite(5, 1); digitalWrite(7, 1);
     delay(100);
     digitalWrite(5, 0); digitalWrite(7, 0);
     delay(100);
  } // конец сравнения всех
}


}
void loop ()
{
/////////////////////////////////////////////////////////////////////////////////////////
if (jumper==0)//если джампер снят, то выполнять программу
{
//считать с EEPROM
if (readed==0)//если не записано, то писать
  {
  Tmi=ER(0);   Tma=ER(2);
  Ymi=ER(4);   Yma=ER(6);
  Rmi=ER(8);   Rma=ER(10);
  Pmi=ER(12);  Pma=ER(14);
  Tinv=ER(16); Pinv=ER(18);
  readed=1;
  }
else if (readed==1)
{
//читать стики
t = pulseIn(0,HIGH,20000);
y = pulseIn(1,HIGH,20000);
r = pulseIn(2,HIGH,20000);
p = pulseIn(3,HIGH,20000);
if ((t<Tmi && Tinv==0) || (t>Tma && Tinv==1))    //Если газ низкий и нет инверсии, то выключить все (реверс)
  {
    digitalWrite(4, 0);
    digitalWrite(5, 0);
    digitalWrite(6, 0);
    digitalWrite(7, 0);
  }
  else
  if ((t>=Tmi && Tinv==0) || (t<=Tma && Tinv==1))  // При увеличении газа включить все
    {
      digitalWrite(4, 1);
      digitalWrite(5, 1);
      digitalWrite(6, 1);
      digitalWrite(7, 1);
      a=7, b=7;
      if (y<Ymi)    // YAW При развороте влево (ПРОВЕРИТЬ), иначе вправо
        {
        digitalWrite(4, 1); digitalWrite(5, 1); digitalWrite(6, 1); digitalWrite(7, 1);
        delay(a);
        digitalWrite(4, 0); digitalWrite(5, 0); digitalWrite(6, 0); digitalWrite(7, 0);
        delay(b);
        }
        else
        if (y>Yma)
          {
        digitalWrite(4, 1); digitalWrite(5, 1); digitalWrite(6, 1); digitalWrite(7, 1);
        delay(a);
        digitalWrite(4, 0); digitalWrite(5, 0); digitalWrite(6, 0); digitalWrite(7, 0);
        delay(b);
          }
          else
          {
      a=20, b=20;
          digitalWrite(4, 1);
      digitalWrite(5, 1);
      digitalWrite(6, 1);
      digitalWrite(7, 1);
        if (r<Rmi && (p>Pmi && p<Pma))    // ROLL При наклоне влево мигнуть, иначе вправо мигнуть (ПРОВЕРИТЬ)
      {
            digitalWrite(4, 0);
        digitalWrite(5, 1);
        digitalWrite(6, 0);
        digitalWrite(7, 1);
        digitalWrite(4, 1); digitalWrite(6, 1); delay(a);
        digitalWrite(4, 0); digitalWrite(6, 0); delay(a);
      }
      else if (r>Rma && (p>Pmi && p<Pma))
      {
          digitalWrite(4, 1);
          digitalWrite(5, 0);
          digitalWrite(6, 1);
          digitalWrite(7, 0);
          digitalWrite(5, 1); digitalWrite(7, 1); delay(a);
          digitalWrite(5, 0); digitalWrite(7, 0); delay(a);
      }
        if (((p<Pmi && Pinv==1) && (r>Rmi && r<Rma)) || ((p>Pma && Pinv==0) && (r>Rmi && r<Rma)))    // PITCH При наклоне назад мигнуть, иначе вперед мигнуть (ПРОВЕРИТЬ)
      {
        digitalWrite(4, 0);
        digitalWrite(5, 0);
        digitalWrite(6, 1);
        digitalWrite(7, 1);
        digitalWrite(4, 1); digitalWrite(5, 1); delay(a);
        digitalWrite(4, 0); digitalWrite(5, 0); delay(a);
      }
      else if (((p>Pma && Pinv==1) && (r>Rmi && r<Rma)) || ((p<Pmi && Pinv==0) && (r>Rmi && r<Rma)))
      {
          digitalWrite(4, 1);
          digitalWrite(5, 1);
          digitalWrite(6, 0);
          digitalWrite(7, 0);
          digitalWrite(6, 1); digitalWrite(7, 1); delay(a);
          digitalWrite(6, 0); digitalWrite(7, 0); delay(a);
      }
      if ((r<Rmi && (p<Pmi && Pinv==0)) || (r<Rmi && (p>Pma && Pinv==1))) //диагональ1, < - влево назад, > вправо вперед
        {
          digitalWrite(4, 1);
      digitalWrite(5, 1);
      digitalWrite(6, 0);
      digitalWrite(7, 1);
      digitalWrite(6, 1); delay(a);
      digitalWrite(6, 0); delay(a);
        }
        else if ((r>Rma && (p>Pma && Pinv==0)) || (r>Rma && (p<Pmi && Pinv==1)))
        {
          digitalWrite(4, 1);
      digitalWrite(5, 0);
      digitalWrite(6, 1);
      digitalWrite(7, 1);
      digitalWrite(5, 1); delay(a);
      digitalWrite(5, 0); delay(a);
        }
      if ((r<Rmi && (p>Pma && Pinv==0)) || (r<Rmi && (p<Pmi && Pinv==1)))//диагональ2, < - влево вперед, > вправо назад
        {
          digitalWrite(4, 0);
      digitalWrite(5, 1);
      digitalWrite(6, 1);
      digitalWrite(7, 1);
      digitalWrite(4, 1); delay(a);
      digitalWrite(4, 0); delay(a);
        }
        else if ((r>Rma && (p<Pmi && Pinv==0)) || (r>Rma && (p>Pma && Pinv==1)))
        {
          digitalWrite(4, 1);
      digitalWrite(5, 1);
      digitalWrite(6, 1);
      digitalWrite(7, 0);
      digitalWrite(7, 1); delay(a);
      digitalWrite(7, 0); delay(a);
        }
      } //YAW end
    } //throttle end
  } //readed end
} //jumper end
}
druksel
shura2000:

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

и на платке подсветки повесить 3 джампера - типа на 2 банки, на три и на четыре, и три режима работы подсветки - типа все нормально - просто светится, первый порог - редкие погасания подсветки и типа " бегом на посадку!" частые моргания

raefa

Можно и так. Надо только добраться. Пока куча других проектов в процессе. 😃

Dreadnought
druksel:

редкие погасания подсветки и типа " бегом на посадку!"

У назы контроль напряжения как-то так же показывает. Правда одним светодиодом.

shura2000

У Назы почти все в конце концов отключают контроль напряжения, и полагаются на внешние пищалки и тп.

Dreadnought
shura2000:

У Назы почти все в конце концов отключают

Да, солидарен.Я тоже отключил. Потому что они чтото с ним перемудрили. Почему-то глупая пищалка на 3.3 В на банку эффективнее. Что мешало сделать такое решение внутри назы? 😃
Я , собственно , по теме подсветки, скажу : сама идея о том, что подсветка может показывать больше, чем просто зад-перед коптера- очень хороша. Даже моргание при падении напруги на батарее - очень было бы полезно.