Программирование светофоров

LDruyan
Offline
Зарегистрирован: 09.11.2016

Доброго времени суток! 

Мне было задано написать программу с двумя светофорами: пешеходный светофор (2 светодиода - красный и зелёный) и светофор для транспорта (3 светодиода - красный,жёлтый и зелёный).

задание является таковым:

Светофор для транспорта горит поочерёдно 3 светодиодами - красный, жёлтый и зелёный.

В свою очередь, светофор для пешеходов работает так:

Когда на светофоре для транспорта горит красный светодиод, на светофоре для пешеходов зажигается зелёный светодиод. 

Когда на светофоре для транспорта горит зелёный светодиод, на светофоре для пешеходов зажигается красный светодиод. 

Код надо написать при помощи комманд  for,while и if.

Я бился пару часов над кодом (я только начинаю познование программировая Arduino), но всё ровно так и не смог написать корректно робочий.

Буду очень благодарен если сможете помочь написать код.

 

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

LDruyan пишет:

Код надо написать при помощи комманд  for,while и if.

кому надо, тот пусть и пишет

bwn
Offline
Зарегистрирован: 25.08.2014

Нарисуйте на бумажке алгоритм, а после переведите его в нужные вам операторы. И где кстати избитый до полусмерти код?

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

bwn пишет:

Нарисуйте на бумажке алгоритм, а после переведите его в нужные вам операторы. И где кстати избитый до полусмерти код?

я запретил рисовать алгоритмы на бумажке

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

LDruyan пишет:

Я бился пару часов над кодом 

И где результат? Выкладывайте.

Клапауций 234
Offline
Зарегистрирован: 24.10.2016

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

LDruyan пишет:

Я бился пару часов над кодом 

И где результат? Выкладывайте.

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

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

Кстати, задача про светофор очень хорошо разложена вот здесь со стр. 8.

Stas046
Offline
Зарегистрирован: 10.12.2014

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

LDruyan пишет:

Я бился пару часов над кодом 

И где результат? Выкладывайте.

Сомневаюсь, что кто-то, бился хоть пару минут :)  Халява ищется :) Тут, дружок, твои задания никто за тебя выполнять не будет. Покажи в чем у тебя проблема - поможем. А так отсыпай $, будет тебе светофор )))

Logik
Offline
Зарегистрирован: 05.08.2014

Повезло те LDruyan повезло, если конечно не отчислили на сесии. Мне тоже вот светофор понадобился. Вчера час бился и сегодня тоже час.

Светофор понадобился на макет ЖД. Точней много светофоров, штук 5 для начала, а затем как пойдет. Потому их на 74HC595 вешать решено. Не буду расказывать как пилил, сверлил, паял и клеил. В светофоре установлено 2 светодиода, каждый из которых светит красным или зеленым в зависимости от полярности. Спаяны разноименными выводами вместе (в коде это SVET_PLS),  а на оставшихся 2-х выводах по 100Ом. Получается из светофора торчат 3 провода заведеные на D1-D3 у 74HC595. Изначально предполагалось только простенькое: нижний красный или верхний зеленый. Но  по ходу захотелось большего )) Реализованы 3 цвета (желтый как красный и зеленый сразу) для любого сигнала в произвольных сочитаниях и мигание в произвольном порядке. Пока для 1 светофора, остальные еще не готовы. Но код для них легко адаптировать.

// пины для SPI
#define PIN_DATA_SPI A0
#define PIN_CLK_SPI A4
#define PIN_SET_SPI A2

//логический порядок сигналов 
#define SVET_DONE 1 
#define SVET_PLS  2 
#define SVET_UP   4 
#define SV1(a) (a<<4) //сдвиг  SVET_хх для получения распайки на 74HC595 

void setup() 
{  
  Serial.begin(9600);
  pinMode(PIN_DATA_SPI, OUTPUT);
  pinMode(PIN_CLK_SPI, OUTPUT);
  pinMode(PIN_SET_SPI, OUTPUT);
  pinMode(13, OUTPUT);
}

void SetSPI(byte c)
{
  digitalWrite(PIN_SET_SPI, LOW);
  for(byte i=0;i<8;i++)
  {
    digitalWrite(PIN_DATA_SPI, c&_BV(i));
    digitalWrite(PIN_CLK_SPI, HIGH);
    digitalWrite(PIN_CLK_SPI, LOW);  
  }
  digitalWrite(PIN_SET_SPI, HIGH);
}

//этими макросами задаем цвета мигания
#define UP_RED     1
#define UP_GREEN   2
#define UP_YELLOW  3
#define DONE_RED     4
#define DONE_GREEN   8
#define DONE_YELLOW  12
#define BLINK_PHASE(a)  (a<<4)             //для смены фазы мигания
#define BLINK_NO(a)  (a |  BLINK_PHASE(a)) // для горения без мигания

byte t;  //храним время предыдущего реверса SVET_PLS

byte processSvetofor(byte mode)
{
  static byte T;
  static byte m;
  static byte bl;
  if(byte(t-T)>10) //пора реверса SVET_PLS
  {
    T=t;
    m++;
    if(m==50) //пора мигнуть
    {
      m=0;
      bl=!bl; //фаза мигания
    }
    if(bl)
      mode=mode>>4;
    byte p=m&1?SVET_PLS:0; //реверса SVET_PLS и остальных выводов
    if(p)
    {
      if(!(mode&UP_GREEN))p|=SVET_UP; //не UP_GREEN  или UP_YELLO
      if(!(mode&DONE_RED))p|=SVET_DONE;
    }
    else
    {
      if((mode&UP_RED))  p|=SVET_UP;
      if((mode&DONE_GREEN)) p|=SVET_DONE;
    }
    return p;
  }
  return 0xff;
}

// таблица режимов сменяющих друг друга по циклу
byte SV_cikle[]=
{
  UP_RED| BLINK_PHASE(DONE_YELLOW),
  BLINK_NO(UP_GREEN), 
  BLINK_NO(UP_RED),
  BLINK_NO(DONE_YELLOW),
  BLINK_NO(DONE_YELLOW)|UP_YELLOW,
  DONE_YELLOW|BLINK_PHASE(UP_YELLOW),
};


void loop()
{
  static byte c;
  static byte T;
  
  t=millis();
  if(byte(t-T)>250) //формируем 0,25сек для счета смены режима
  {
    T=t;
    static byte n;
    
    if(n) //не пора менять режим
     n--;
    else
    {    //пора менять режим
     n=10;
     static byte m;
     c=SV_cikle[m++];
     if(m==sizeof(SV_cikle)) //организовуем цикл
       m=0;
    }
  }
  
  byte p;
  
  if((p=processSvetofor(c))!=0xff)  SetSPI(SV1(p));
}

 

ПС. Не факт что проект будет управлятся атмеловским контроллером, скорей всего перейду на esp, потому не сильно с оптимизацией заиорачивался.

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

Повезло те LDruyan повезло, если конечно не отчислили на сесии. Мне тоже вот светофор понадобился. Вчера час бился и сегодня тоже час.

Светофор понадобился на макет ЖД. Точней много светофоров, штук 5 для начала, а затем как пойдет. Потому их на 74HC595 вешать решено. Не буду расказывать как пилил, сверлил, паял и клеил. В светофоре установлено 2 светодиода, каждый из которых светит красным или зеленым в зависимости от полярности. Спаяны разноименными выводами вместе (в коде это SVET_PLS),  а на оставшихся 2-х выводах по 100Ом. Получается из светофора торчат 3 провода заведеные на D1-D3 у 74HC595. Изначально предполагалось только простенькое: нижний красный или верхний зеленый. Но  по ходу захотелось большего )) Реализованы 3 цвета (желтый как красный и зеленый сразу) для любого сигнала в произвольных сочитаниях и мигание в произвольном порядке. Пока для 1 светофора, остальные еще не готовы. Но код для них легко адаптировать.

// пины для SPI
#define PIN_DATA_SPI A0
#define PIN_CLK_SPI A4
#define PIN_SET_SPI A2

//логический порядок сигналов 
#define SVET_DONE 1 
#define SVET_PLS  2 
#define SVET_UP   4 
#define SV1(a) (a<<4) //сдвиг  SVET_хх для получения распайки на 74HC595 

void setup() 
{  
  Serial.begin(9600);
  pinMode(PIN_DATA_SPI, OUTPUT);
  pinMode(PIN_CLK_SPI, OUTPUT);
  pinMode(PIN_SET_SPI, OUTPUT);
  pinMode(13, OUTPUT);
}

void SetSPI(byte c)
{
  digitalWrite(PIN_SET_SPI, LOW);
  for(byte i=0;i<8;i++)
  {
    digitalWrite(PIN_DATA_SPI, c&_BV(i));
    digitalWrite(PIN_CLK_SPI, HIGH);
    digitalWrite(PIN_CLK_SPI, LOW);  
  }
  digitalWrite(PIN_SET_SPI, HIGH);
}

//этими макросами задаем цвета мигания
#define UP_RED     1
#define UP_GREEN   2
#define UP_YELLOW  3
#define DONE_RED     4
#define DONE_GREEN   8
#define DONE_YELLOW  12
#define BLINK_PHASE(a)  (a<<4)             //для смены фазы мигания
#define BLINK_NO(a)  (a |  BLINK_PHASE(a)) // для горения без мигания

byte t;  //храним время предыдущего реверса SVET_PLS

byte processSvetofor(byte mode)
{
  static byte T;
  static byte m;
  static byte bl;
  if(byte(t-T)>10) //пора реверса SVET_PLS
  {
    T=t;
    m++;
    if(m==50) //пора мигнуть
    {
      m=0;
      bl=!bl; //фаза мигания
    }
    if(bl)
      mode=mode>>4;
    byte p=m&1?SVET_PLS:0; //реверса SVET_PLS и остальных выводов
    if(p)
    {
      if(!(mode&UP_GREEN))p|=SVET_UP; //не UP_GREEN  или UP_YELLO
      if(!(mode&DONE_RED))p|=SVET_DONE;
    }
    else
    {
      if((mode&UP_RED))  p|=SVET_UP;
      if((mode&DONE_GREEN)) p|=SVET_DONE;
    }
    return p;
  }
  return 0xff;
}

// таблица режимов сменяющих друг друга по циклу
byte SV_cikle[]=
{
  UP_RED| BLINK_PHASE(DONE_YELLOW),
  BLINK_NO(UP_GREEN), 
  BLINK_NO(UP_RED),
  BLINK_NO(DONE_YELLOW),
  BLINK_NO(DONE_YELLOW)|UP_YELLOW,
  DONE_YELLOW|BLINK_PHASE(UP_YELLOW),
};


void loop()
{
  static byte c;
  static byte T;
  
  t=millis();
  if(byte(t-T)>250) //формируем 0,25сек для счета смены режима
  {
    T=t;
    static byte n;
    
    if(n) //не пора менять режим
     n--;
    else
    {    //пора менять режим
     n=10;
     static byte m;
     c=SV_cikle[m++];
     if(m==sizeof(SV_cikle)) //организовуем цикл
       m=0;
    }
  }
  
  byte p;
  
  if((p=processSvetofor(c))!=0xff)  SetSPI(SV1(p));
}

 

ПС. Не факт что проект будет управлятся атмеловским контроллером, скорей всего перейду на esp, потому не сильно с оптимизацией заиорачивался.

 

А синий??? На ЖД вроде синий имеется?

Logik
Offline
Зарегистрирован: 05.08.2014

Синие уже купил. Но пока ставить не буду. На ЖД они для маневровых локомотивов и как правило в маленьких светофорах. Это пока не актуально, пока делаю мачтовые светофоры.  Но вобще на те же 74HC595 можна и их потом вешать.

negavoid
Offline
Зарегистрирован: 09.07.2016

А ещё бывает молочно-белый и два жёлтых :)

Logik
Offline
Зарегистрирован: 05.08.2014

Вот два желтых я делаю, и два желтых один из которых моргает тоже. Но не достоверно. На ЖД для этого светофоры с 4-я секциями две из которых желтые. Ну не умеют они цвет свечения секции менять ))) А я умею, но это не достоверно. Надеюсь ЖД перейдет на светодиодные светофоры с сменой цвета секции ;) Я уже перешел.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

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

LDruyan пишет:

Я бился пару часов над кодом 

И где результат? Выкладывайте.

1200 СТРОК КОДА, КТО ЕГО БУДЕТ ЧИТАТЬ )))

Logik
Offline
Зарегистрирован: 05.08.2014

Кстати, к холивару о формировании временных интервалы, как правильно: прибавлять к старому времени константу или заменять старое время на полученое из миллис. У меня в коде заменялось. Но через полчасика работы скетча моменты мигания и моменты смены режима свечения заметно расползлись по времени. В результате полезли артефакты типа очень быстрого промигивания при смене режима. Заменил на прибавление константы к старому времени. Теперь все ок. В данном случае очевидно так лучше.