Эммитатор стробоскопа для фар головного света

deliter
Offline
Зарегистрирован: 18.06.2014

Всем привет! Идея воссоздать одно интересное устройство, но с возможность кастомизации.

Устройство вот это:

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

Есть тут похожие проекты, которые можно взять за основу? 

Совмещу все это с моим проектом http://arduino.ru/forum/programmirovanie/2-rele-vremeni-zaderzhka-vklyucheniya-i-vyklyucheniya?page=1 и с http://arduino.ru/forum/apparatnye-voprosy/pomogite-optimizirovat-skhemu

И будет такой универсальный котрллер мотоцикла =)

http://www.antixenon.ru - хардверный девайс. 

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

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

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

по первому фото: за основу берешь обычный Blink из примеров и добавляешь инвертирование для второго светодиода.

#define LED_LEFT 7
#define LED_RIGHT 8

void setup() {                
  pinMode(LED_LEFT , OUTPUT);     
  pinMode(LED_RIGHT , OUTPUT);     
}

void loop() {
  digitalWrite(LED_LEFT , HIGH);
  digitalWrite(LED_RIGHT , LOW);
  delay(250); 
  digitalWrite(LED_LEFT , LOW);
  digitalWrite(LED_RIGHT , HIGH);  
  delay(250);
}

Как освоишь, переходи к эффектам на втором фото, будет уже проще.

Главное - в темное время суток ими не пользоваться :)

deliter
Offline
Зарегистрирован: 18.06.2014

Всем привет!

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

+ С учетом того сколько всего контроллирует уже софт, пример с delay() уже явно не катит.

 

П.С. Для уважаемых хейторов: Стробоскопы, как написано выше, нужны на мотоцикл, чтобы когда пробираешся по рядам тебя видели водители, которые перестраиваются без зерка. Просто элемент безопасности... и сохранности бока вашего авто от 400кг мотоцикла.. и меня самого. 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Выбор режима кнопочкой, по нажатию на которую меняется переменная-флаг отвечающая за режим работы. Индикацию режима можно сделать, например, RGB светодиодом зеленый один режим, синий второй, а красный третий в красном режиме еще сирены включаются :) От делая лучше сразу уходить и делать через millis.

Если кто-то не смотрит по зеркалам он и стробоскопы не увидит :) Такие индивиды вообще отдельный класс им всё по барабану. Я иногда даже зеркала складываю в пробке когда вижу мотоциклиста пробирающегося между рядов :)

deliter
Offline
Зарегистрирован: 18.06.2014

Обожаю некропостинг.

Прошел почти год и я решил доделать проект. Благо сезон открылся..

Ну чтож, мигалка вот. 

Если идеи по оптимизации?

 


// устанавливаем пины ламп
const int LeftLamp =  9;      // левая
const int RightLamp = 10;      // правая


// переменные 


int lamp = 1; //правая или левая 1 левая 2 правая
int strob_step = 1;             // шаг мигания
long prestro1Millis = 0;        // до мигания ( в целом переменная времени)
long stro1interval1 = 150;           // интегвал когда фара включена (milliseconds)
long stro1interval2 = 300;           // интегвал когда фара выключена (milliseconds)
long stro1interval3 = 450;           // интегвал когда фара включена (milliseconds))
long stro1interval4 = 800;           // интегвал когда фара выключена (milliseconds)


void setup() {
  
 pinMode(LeftLamp, OUTPUT); 
 pinMode(RightLamp, OUTPUT);  
  //Serial.begin(9600);           // set up Serial library at 9600 bps
  //Serial.println("Initialized setup");
}

void loop()
{
// Serial.println(lamp);
  if (lamp == 1){ //мигание левой лампы
                unsigned long curstro1Millis = millis();  // устанавливаем время в сейчас
                if (strob_step == 1 && curstro1Millis - prestro1Millis > stro1interval1) {digitalWrite(LeftLamp, HIGH); strob_step = 2;}
                if (strob_step == 2 && curstro1Millis - prestro1Millis > stro1interval2) {digitalWrite(LeftLamp, LOW); strob_step = 3;}
                if (strob_step == 3 && curstro1Millis - prestro1Millis > stro1interval3) {digitalWrite(LeftLamp, HIGH); strob_step = 4;}
                if (strob_step == 4 && curstro1Millis - prestro1Millis > stro1interval4) {digitalWrite(LeftLamp, LOW); strob_step = 1;
                                                                                       prestro1Millis = curstro1Millis; lamp = 2; // а теперь передаем слово правой;   
                                                                                       }
               }
                                                                                     
  if (lamp == 2 ){//мигание правой лампы
                unsigned long curstro1Millis = millis();  // устанавливаем время в сейчас
                if (strob_step == 1 && curstro1Millis - prestro1Millis > stro1interval1) {digitalWrite(RightLamp, HIGH); strob_step = 2;}
                if (strob_step == 2 && curstro1Millis - prestro1Millis > stro1interval2) {digitalWrite(RightLamp, LOW); strob_step = 3;}
                if (strob_step == 3 && curstro1Millis - prestro1Millis > stro1interval3) {digitalWrite(RightLamp, HIGH); strob_step = 4;}
                if (strob_step == 4 && curstro1Millis - prestro1Millis > stro1interval4) {digitalWrite(RightLamp, LOW); strob_step = 1;
                                                                                       prestro1Millis = curstro1Millis;  lamp = 1; // а теперь передаем слово левой;
                                                                                       }
              }
  
}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

ну у тебя фактически 8 раз делается одно и то же, отличаются только параметры.

Поэтому можно так:

// устанавливаем пины ламп
#define LEFT_PIN 9      // левая
#define RIGHT_PIN 10      // правая

// переменные 
boolean lampIsLeft = true; // флаг, что активна левая
byte strob_step = 1;             // шаг мигания
long prestroMillis = 0;        // до мигания (в целом переменная времени)
int stroInterval[4]={150, 300, 450, 800};    // интервал включения/выключения лампы

void setup() 
{
  pinMode(LEFT_PIN, OUTPUT); 
  pinMode(RIGHT_PIN, OUTPUT);  
  Serial.begin(9600);
}

void loop()
{
  unsigned long curstroMillis = millis();  // запоминаем текущее время
  digitalWrite(lampIsLeft ? LEFT_PIN : RIGHT_PIN, strob_step & 1); // на текущий пин чередуем 1 и 0
  if (curstroMillis - prestroMillis > stroInterval[strob_step - 1]) // проверяем интервал
  {
    if (strob_step == 4)            // если конец цикла для текущей лампы
    {
      lampIsLeft = !lampIsLeft; // передаем слово другой лампе (меняем текущий пин);
      prestroMillis = curstroMillis; 
    }
    strob_step = strob_step + 1 - 4 * (strob_step > 3); // магия булевой математики: шаги от 1 до 4
  }
}

если непонятно как оно работает, вставь перед строкой 21 этот код:

  Serial.print(" Time ");  
  Serial.print(curstroMillis - prestroMillis);
  Serial.print("\tStep ");  
  Serial.print(strob_step);
  Serial.print("\tInterval ");  
  Serial.print(stroInterval[strob_step - 1]);
  Serial.print("\tLamp ");  
  Serial.print(lampIsLeft ? "Left":"Right");
  Serial.print("\tOdd ");  
  Serial.println(strob_step & 1);
  delay(100);

 

deliter
Offline
Зарегистрирован: 18.06.2014

Tomasina пишет:

если непонятно как оно работает, вставь перед строкой 21 этот код:

 

 

очень круто.. пошел учить матчать... а то не понял пару строк..

Спасибо! 

kuzen1109
Offline
Зарегистрирован: 02.03.2015

Tomasina, а вы не могли бы на основе вашего примера написать скетч для 4х бегущих огней?

немного подпортив ваш исходный код, для 4х диодов получилось нечто:

void strob1()
{ 

  unsigned long curstroMillis = millis();  // запоминаем текущее время
  digitalWrite(lampIsLeft ? LED_PIN1 : LED_PIN4, strob_step & 1); // на текущий пин чередуем 1 и 0
  digitalWrite(lampIsLeft ? LED_PIN3 : LED_PIN2 , strob_step & 1); // на текущий пин чередуем 1 и 0
  if (curstroMillis - prestroMillis > stroInterval[strob_step - 1]) // проверяем интервал
  {
    if (strob_step == 8)            // если конец цикла для текущей лампы
    {
      lampIsLeft = !lampIsLeft; // передаем слово другой лампе (меняем текущий пин);
      prestroMillis = curstroMillis; 
    }
    strob_step = strob_step + 1 - 8 * (strob_step > 7); // магия булевой математики: шаги от 1 до 4
  }
}
void strob2()
{
  unsigned long curstroMillis = millis();  // запоминаем текущее время
  digitalWrite(lampIsLeft ? LED_PIN1 : LED_PIN3, strob_step & 1); // на текущий пин чередуем 1 и 0
  digitalWrite(lampIsLeft ? LED_PIN4 : LED_PIN2 , strob_step & 1); // на текущий пин чередуем 1 и 0
  if (curstroMillis - prestroMillis > stroInterval[strob_step - 1]) // проверяем интервал
  {
    if (strob_step == 8)            // если конец цикла для текущей лампы
    {
      lampIsLeft = !lampIsLeft; // передаем слово другой лампе (меняем текущий пин);
      prestroMillis = curstroMillis; 
    }
    strob_step = strob_step + 1 - 8 * (strob_step > 7); // магия булевой математики: шаги от 1 до 4
  }
}

А вот с бегущими както не получается

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Всего 4, или две группы по 4?

kuzen1109
Offline
Зарегистрирован: 02.03.2015

всего четыре

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
boolean ledstate = HIGH;           // HIGH - это "бегущий свет", LOW - это "бегущая тень"
const byte LEDpins[] = {           // пины, к которым подключены светодиоды
  2, 4, 6, 8};     
const byte strobeCount = 3;        // число вспышек текущего светодиода, от 1 до 254
const byte strobePause = 150;      // пауза перед зажиганием следующего светодиода, мс (от 0 до 254)
const byte strobeDuration = 24;    // длительность включения текущего светодиода, мс (от 5 до 254)

byte leds = sizeof(LEDpins);       // число светодиодов

void setup()
{
  for(byte i = 0; i < leds; i++) 
  {
    pinMode(LEDpins[i], OUTPUT);          // устанавливаем пин как выход
    digitalWrite(LEDpins[i], !ledstate);  // выключаем все светодиоды
  }
}


void loop()
{
  byte n;
  for(n = 0; n < 10; n++) strobeRight(); // 10 раз эффект 1
  for(n = 0; n < 10; n++) strobeLeft();  // 10 раз эффект 2
  for(n = 0; n < 10; n++) strobeDash();  // 10 раз эффект 3
  for(n = 0; n < 10; n++) strobeFlash(); // 10 раз эффект 4
}

void strobeRight()  // слева направо
{
  for(byte i = 0; i < leds; i++)  // циклический перебор всех пинов (задаем текущий)
  {
    for(byte f = 0; f < strobeCount; f++) // циклические действия с текущим пином
    {
      digitalWrite(LEDpins[i], ledstate);          // включаем текущий LED
      delay(strobeDuration);                       // ждем пару мсек
      digitalWrite(LEDpins[i], !ledstate);         // выключаем текущий LED
      if (strobeCount > 1) delay(strobeDuration);  // ждем пару мсек, если надо повторно мигнуть
    }    
    //delay(strobePause);                          // ждем пару мсек перед следующим LED
  }
}

void strobeLeft()  // справа налево
{
  for(byte i = 0; i < leds; i++)  // циклический перебор всех пинов (задаем текущий)
  {
    for(byte f = 0; f < strobeCount; f++) // циклические действия с текущим пином
    {
      digitalWrite(LEDpins[leds - i - 1], ledstate);
      delay(strobeDuration);
      digitalWrite(LEDpins[leds - i - 1], !ledstate);
      if (strobeCount > 1) delay(strobeDuration);
    }    
    //delay(strobePause);
  }
}

void strobeDash()  // попеременно
{
  for(byte i = 0; i < (leds / 2); i++)  // задаем текущий,  с шагом через один
  {
    for(byte f = 0; f < strobeCount; f++) // циклические действия с текущим пином
    {
      digitalWrite(LEDpins[i], ledstate);
      digitalWrite(LEDpins[i+2], ledstate); 
      delay(strobeDuration); 
      digitalWrite(LEDpins[i], !ledstate);
      digitalWrite(LEDpins[i+2], !ledstate);
      if (strobeCount > 1) delay(strobeDuration);
    }    
    delay(strobePause);
  }
}

void strobeFlash()  // все вместе
{
  for(byte f = 0; f < strobeCount; f++)  // циклические действия с текущим пином (задаем текущий)
  {
    for(byte i = 0; i < leds; i++) digitalWrite(LEDpins[i], ledstate);  // включаем текущий LED
    delay(strobeDuration);
    for(byte i = 0; i < leds; i++) digitalWrite(LEDpins[i], !ledstate); // выключаем текущий LED
    delay(strobeDuration);
  }
  delay(strobePause); 
}

 

kuzen1109
Offline
Зарегистрирован: 02.03.2015

Спасибо огромное, прошу прощения за наглость, но не смог сам справиться, те же еффекты без delay, повторить. Просто хочу чтоб была реакция на кнопку а delay мешает, вы не могли бы помочь

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

А кнопка что делает?

kuzen1109
Offline
Зарегистрирован: 02.03.2015

на нажатие кнопки меняются эффекты

вот код для бегущих огней в одну сторону, но понять не могу где накосячил:

#define LED_PIN1 8      // левая1
#define LED_PIN2 9      // левая2
#define LED_PIN3 10     // правая1
#define LED_PIN4 11      // правая2
int value = LOW;           // предыдущее состояние светодиода
long previousMillis = 0;   // здесь будет храниться время последнего изменения состояния светодиода 

int index;
int LED_PIN[] = {8,9,10,11};

void setup()
{
  pinMode(LED_PIN1, OUTPUT); // устанавливаем порт, как выход
  pinMode(LED_PIN2, OUTPUT);
  pinMode(LED_PIN3, OUTPUT);
  pinMode(LED_PIN4, OUTPUT);
}

void loop()
{
 
  for(index = 0; index <= 4; index++)
  {
   if (millis() - previousMillis > 1000) 
   {
    previousMillis = millis();
    digitalWrite(LED_PIN[index], HIGH);
   }
   if (millis() - previousMillis > 1000)
   {
     previousMillis = millis();
     digitalWrite(LED_PIN[index], LOW);
   }
  }                 
  
}

вернее понимаю что косяк с условиями наступления момента времени, а как поправить не пойму

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

у тебя рандомно будет срабатывать либо строка 29, либо строка 24, т.к. условие одно и то же, поэтому моргать будет произвольно и с любой длительностью.

#define BUTTON_PIN 10              // пин для кнопки, подключена между GND и D10
boolean ledstate = HIGH;           // HIGH - это "бегущий свет", LOW - это "бегущая тень"
const byte LEDpins[] = {           // пины, к которым подключены светодиоды
  2, 4, 6, 8};     
const byte strobeCount = 3;        // число вспышек текущего светодиода, от 1 до 254
const byte strobePause = 150;      // пауза перед зажиганием следующего светодиода, мс (от 0 до 254)
const byte strobeDuration = 24;    // длительность включения текущего светодиода, мс (от 5 до 254)

byte numLeds = sizeof(LEDpins);    // число светодиодов
enum Effects{
  RIGHT, LEFT, DASH, FLASH, ENDLIST}; // именованные номера эффектов
byte currentEffect = DASH;  // первоначальный эффект


void setup()
{
  Serial.begin(9600);
    Serial.print("Effect:");
    Serial.println(currentEffect);
  pinMode(BUTTON_PIN, INPUT_PULLUP);      // устанавливаем пин как вход
  for(byte i = 0; i < numLeds; i++) 
  {
    pinMode(LEDpins[i], OUTPUT);          // устанавливаем пин как выход
    digitalWrite(LEDpins[i], !ledstate);  // выключаем все светодиоды
  }
}


void loop()
{
  if(!digitalRead(BUTTON_PIN))            // если нажали кнопку
  {
    currentEffect++;                      // записываем в переменную следующий эффект
    if(currentEffect == ENDLIST)          // если дошли до конца списка
    {
      currentEffect = 0;                  // то обнуляем переменную (переходим в начало списка)
    }
    Serial.print("Effect:");
    Serial.println(currentEffect);
    delay(100);                           // тупим 100 мкс (простейшая защита от дребезга)
  }

  switch(currentEffect)                   // переходим к выбранному эффекту
  {
  case RIGHT: 
    strobeRight();                        // когда переменная равна 0, то запускаем эффект №0
    break;

  case LEFT: 
    strobeLeft();                         // когда переменная равна 1, то запускаем эффект №1
    break;

  case DASH: 
    strobeDash();                         // когда переменная равна 2, то запускаем эффект №2
    break;

  case FLASH: 
    strobeFlash();                        // когда переменная равна 3, то запускаем эффект №3
    break;
  }
}


void strobeRight()  // слева направо
{
  for(byte i = 0; i < numLeds; i++)  // циклический перебор всех пинов (задаем текущий)
  {
    for(byte f = 0; f < strobeCount; f++) // циклические действия с текущим пином
    {
      digitalWrite(LEDpins[i], ledstate);          // включаем текущий LED
      delay(strobeDuration);                       // ждем пару мсек
      digitalWrite(LEDpins[i], !ledstate);         // выключаем текущий LED
      if (strobeCount > 1) delay(strobeDuration);  // ждем пару мсек, если надо повторно мигнуть
    }    
    //delay(strobePause);                          // ждем пару мсек перед следующим LED
  }
}

void strobeLeft()  // справа налево
{
  for(byte i = 0; i < numLeds; i++)  // циклический перебор всех пинов (задаем текущий)
  {
    for(byte f = 0; f < strobeCount; f++) // циклические действия с текущим пином
    {
      digitalWrite(LEDpins[numLeds - i - 1], ledstate);
      delay(strobeDuration);
      digitalWrite(LEDpins[numLeds - i - 1], !ledstate);
      if (strobeCount > 1) delay(strobeDuration);
    }    
    //delay(strobePause);
  }
}

void strobeDash()  // попеременно
{
  for(byte i = 0; i < (numLeds / 2); i++)  // задаем текущий,  с шагом через один
  {
    for(byte f = 0; f < strobeCount; f++) // циклические действия с текущим пином
    {
      digitalWrite(LEDpins[i], ledstate);
      digitalWrite(LEDpins[i+2], ledstate); 
      delay(strobeDuration); 
      digitalWrite(LEDpins[i], !ledstate);
      digitalWrite(LEDpins[i+2], !ledstate);
      if (strobeCount > 1) delay(strobeDuration);
    }    
    delay(strobePause);
  }
}

void strobeFlash()  // все вместе
{
  for(byte f = 0; f < strobeCount; f++)  // циклические действия с текущим пином (задаем текущий)
  {
    for(byte i = 0; i < numLeds; i++) digitalWrite(LEDpins[i], ledstate);  // включаем текущий LED
    delay(strobeDuration);
    for(byte i = 0; i < numLeds; i++) digitalWrite(LEDpins[i], !ledstate); // выключаем текущий LED
    delay(strobeDuration);
  }
  delay(strobePause); 
}