светофор

berik
Offline
Зарегистрирован: 21.10.2014
const int r = 7;
const int y = 8;
const int g = 9;
int time;

void setup(){
  pinMode(r, OUTPUT);
  pinMode(y, OUTPUT);
  pinMode(g, OUTPUT);
}
void loop(){
  int mil = millis();
  
   if(mil - time == 0 ){
     digitalWrite(r, HIGH);}
   if(mil - time == 5000 ){
     digitalWrite(y, HIGH);}
   if(mil - time == 7000 ){
     digitalWrite(r, LOW); 
     digitalWrite(y, LOW); 
     digitalWrite(g, HIGH);}
   if(mil - time == 10000 ){
     digitalWrite(g, LOW);}
   if(mil - time == 10500 ){
     digitalWrite(g, HIGH);}
   if(mil - time == 11000 ){
     digitalWrite(g, LOW);}
   if(mil - time == 11500 ){
     digitalWrite(g, HIGH);}
   if(mil - time == 12000 ){
     digitalWrite(g, LOW);
     digitalWrite(y, HIGH);}
   if(mil - time == 14000){
     digitalWrite(y, LOW); 
     time = mil ;}
 }

 

berik
Offline
Зарегистрирован: 21.10.2014

Всем привет. Начинаю изучать arduino, да и программирование вообще. Написал вот такой простенький скетч для модели светофора. Хотелось бы получить оценку от гуру: на правильном ли я пути? Или это можно реализовать как-то попроще, или оптимизировать. Приветствуется любая конструктивная критика.

Zapek@n
Offline
Зарегистрирован: 16.02.2012

А если mil будет какое-нибудь неровное значение, например, 968. Код куда попадет? А какое значение  будет у time на первой итерации и далее если код не попадет под условие if(mil - time == 14000)

faraddin
Offline
Зарегистрирован: 11.08.2013

millis может проскочить ваши 500 и т.д. точнее в вашем случае не может, но будь программа сложнее, тогда запросто

berik
Offline
Зарегистрирован: 21.10.2014

ОК, буду грызть гранит дальше. Кто-нибудь даст пинка в нужном направлении?

faraddin
Offline
Зарегистрирован: 11.08.2013

Либо учится на чужих ошибках по книгам и статьям, либо на своих методом тыка. лучше всего конечно комплексный подход
 

в Вашем конкретном случае достаточно заменить код типа

если а=1 то;

если а=10 то; на код типа

если а<10 то

иначе если а< 20

std
Offline
Зарегистрирован: 05.01.2012

berik пишет:
Кто-нибудь даст пинка в нужном направлении?

Как вариант, читайте:

#include <avr\wdt.h>
const byte sv_a[120]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,4,0,4,2,2,2,2,2,2,2,2,2,2};
const byte sv_b[120]={4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,4,0,4,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3};

// 0 0 0 = 0
// R       1
//   Y     2
// R Y     3
//     G   4

#define RED 0
#define YELLOW 1
#define GREEN 2

unsigned long last; // last data change
byte pos;           // cycle position

void setup() {                
  wdt_enable(WDTO_2S);
  pinMode(0, OUTPUT);     
  pinMode(1, OUTPUT);     
  pinMode(2, OUTPUT);
  digitalWrite(RED,LOW);
  digitalWrite(YELLOW,LOW);
  digitalWrite(GREEN,LOW);
  pos=0;
  last=millis();
}

void loop() {
  wdt_reset();
  if(millis()-last>=500){
    if(pos<=118) pos+=1;
     else pos=0;
    last=millis();
  }
  switch(sv_a[pos]){
    case 0:
     digitalWrite(RED,LOW);
     digitalWrite(YELLOW,LOW);
     digitalWrite(GREEN,LOW);
    break;
    case 1:
     digitalWrite(RED,HIGH);
     digitalWrite(YELLOW,LOW);
     digitalWrite(GREEN,LOW);
    break;
    case 2:
     digitalWrite(RED,LOW);
     digitalWrite(YELLOW,HIGH);
     digitalWrite(GREEN,LOW);
    break;
    case 3:
     digitalWrite(RED,HIGH);
     digitalWrite(YELLOW,HIGH);
     digitalWrite(GREEN,LOW);
    break;
    case 4:
     digitalWrite(RED,LOW);
     digitalWrite(YELLOW,LOW);
     digitalWrite(GREEN,HIGH);
    break;
  }
}

 

berik
Offline
Зарегистрирован: 21.10.2014

std пишет:

Как вариант, читайте:

#include <avr\wdt.h>
const byte sv_a[120]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,4,0,4,2,2,2,2,2,2,2,2,2,2};
const byte sv_b[120]={4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,0,4,0,4,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3};

// 0 0 0 = 0
// R       1
//   Y     2
// R Y     3
//     G   4

#define RED 0
#define YELLOW 1
#define GREEN 2

unsigned long last; // last data change
byte pos;           // cycle position

void setup() {                
  wdt_enable(WDTO_2S);
  pinMode(0, OUTPUT);     
  pinMode(1, OUTPUT);     
  pinMode(2, OUTPUT);
  digitalWrite(RED,LOW);
  digitalWrite(YELLOW,LOW);
  digitalWrite(GREEN,LOW);
  pos=0;
  last=millis();
}

void loop() {
  wdt_reset();
  if(millis()-last>=500){
    if(pos<=118) pos+=1;
     else pos=0;
    last=millis();
  }
  switch(sv_a[pos]){
    case 0:
     digitalWrite(RED,LOW);
     digitalWrite(YELLOW,LOW);
     digitalWrite(GREEN,LOW);
    break;
    case 1:
     digitalWrite(RED,HIGH);
     digitalWrite(YELLOW,LOW);
     digitalWrite(GREEN,LOW);
    break;
    case 2:
     digitalWrite(RED,LOW);
     digitalWrite(YELLOW,HIGH);
     digitalWrite(GREEN,LOW);
    break;
    case 3:
     digitalWrite(RED,HIGH);
     digitalWrite(YELLOW,HIGH);
     digitalWrite(GREEN,LOW);
    break;
    case 4:
     digitalWrite(RED,LOW);
     digitalWrite(YELLOW,LOW);
     digitalWrite(GREEN,HIGH);
    break;
  }
}

 

Спасибо, помогло

berik
Offline
Зарегистрирован: 21.10.2014

faraddin пишет:

 

в Вашем конкретном случае достаточно заменить код типа

если а=1 то;

если а=10 то; на код типа

если а<10 то

иначе если а< 20

Сделал, в результате светодиоды переключаются рывками. Ну да ладно... А если вот такой вариант?

const int r = 7;
const int y = 8;
const int g = 9;

unsigned long current;
unsigned long looptime;
int x;

void setup(){
  pinMode(r, OUTPUT);
  pinMode(y, OUTPUT);
  pinMode(g, OUTPUT);
  
}
void loop(){
  
   current = millis();
   if(current >= (looptime + 1000)){
     ++x;
    looptime = current;}
    if (x==5){digitalWrite(r,HIGH);}
    if (x==10){digitalWrite(r,LOW);
    
    //и т.д. с остальными светодиодами...
    
    
  x=0;
}

 

faraddin
Offline
Зарегистрирован: 11.08.2013

berik пишет:

 

Сделал, в результате светодиоды переключаются рывками. Ну да ладно... 

 

Я Вам дал лишь один из вариантов, что же Вы его не проанализировали и не исправили? надо было разобраться почему у Вас рывками переключается. Для общего развития, так сказать. Второй и последующие коды анализировать уже не интересно, работает и ладно, а светофор и на delay() сделать можно.

berik
Offline
Зарегистрирован: 21.10.2014

Цель в-общем то и не светофор, а как раз общее развитие. На delay сделал в первую очередь. В любом случае спасибо за подсказки, сейчас ковыряюсь над вашим вариантом.