Замена delay() на millis() в цикле for.

sersh4nt
Offline
Зарегистрирован: 22.04.2018

Уважаемые формучане! Имеется программа управления ргб светодиодом, которая по кругу выводит все цвета радуги. Необходимо заменить delay() внутри цикла for, ибо слишком большой отклик для моих целей (создание мини клавиатуры). Как это можно реализовать?

#define r 6                             // Пин подключения красного
#define g 5                             // Пин подключения зеленого
#define b 3                             // Пин подключения синего

int active_color;                       
boolean turn = true;                   

int invert(int value){                  
  return map(value, 0, 255 ,255, 0);    
}

void setup() {
  pinMode(r,OUTPUT);                   
  pinMode(g,OUTPUT);                   
  pinMode(b,OUTPUT);                    
  analogWrite(r,invert(255));           
  analogWrite(g,invert(0));             
  analogWrite(b,invert(0));            
  active_color = b;               
}

void loop() {
  switch (active_color) {               
    case r:                             
      active_color = b;                 
      break;                            
    case g:                           
      active_color = r;                
      break;                           
    case b:                             
      active_color = g;                 
      break;                            
  }
  if (!turn)                            
    for (int i=0; i<=255; i++) {       
      analogWrite(active_color,i);      
      delay(5);                        
    }
  else                                  
    for (int i=255; i>=0; i--) {        
      analogWrite(active_color,i);      
      delay(5);                        
    }
    turn = !turn;                       
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

Разными путями. Самый простой, после каждого delay вызвать подпрограмму опроса клавиатуры и реакции на действие. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

#27

MaksVV
Offline
Зарегистрирован: 06.08.2015

как вариант задать глобальную переменную для величины ШИМ,  убрать циклы for, а действия из них перенести в луп, выполняя раз в 5мс с помощью millis

sersh4nt
Offline
Зарегистрирован: 22.04.2018

Всем спасибо за идеи. Проблему решил. Для тех, кому нужен код, выкладываю.

#define r 6                             // Пин подключения красного
#define g 5                             // Пин подключения зеленого
#define b 3                             // Пин подключения синего

int active_color;                       
boolean turn = true;                   
int i;
unsigned long p_time=0,w_time;
int invert(int value){                  
  return map(value, 0, 255 ,255, 0);    
}

void setup() {
  pinMode(r,OUTPUT);                   
  pinMode(g,OUTPUT);                   
  pinMode(b,OUTPUT);                    
  analogWrite(r,invert(255));           
  analogWrite(g,invert(0));             
  analogWrite(b,invert(0));            
  active_color = b;               
}

void loop() {
  switch (active_color) {               
    case r:                             
      active_color = b;                 
      break;                            
    case g:                           
      active_color = r;                
      break;                           
    case b:                             
      active_color = g;                 
      break;                            
  }
  if (!turn)  {                          
    i=0;
    while(i<=255) {
      w_time=millis();
      if(w_time-p_time>=5) {
        analogWrite(active_color,i);
        i++;
        p_time=w_time;
      }
    }
  }
    else {
      i=255;
      while(i>=0) {
        w_time=millis();
        if(w_time-p_time>=5) {
          analogWrite(active_color,i);
          i--;
          p_time=w_time;
        }
      }
    }
    turn = !turn;                       
}

 

ven-til
Offline
Зарегистрирован: 13.02.2018

и в чем был смылс такого перехода на миллис? Глобально ничего не изменилось и программа работает точно так же как и с делей.

sersh4nt
Offline
Зарегистрирован: 22.04.2018

Уменьшить время отклика

ven-til
Offline
Зарегистрирован: 13.02.2018

И прям получилось то, что нужно? Можно полный код посмотреть с кнопками?

sersh4nt
Offline
Зарегистрирован: 22.04.2018

Не совсем то, но стало лучше

#define r 6                          
#define g 5                         
#define b 3                            
#include <Keyboard.h>
#include <CapacitiveSensor.h>
int active_color;                       
boolean turn = true;                   
int i;
unsigned long p_time=0,w_time;
int invert(int value){                  
  return map(value, 0, 255 ,255, 0);    
}
CapacitiveSensor   x = CapacitiveSensor(14,7);  
CapacitiveSensor   z = CapacitiveSensor(10,4);


void setup() {
  pinMode(r,OUTPUT);                   
  pinMode(g,OUTPUT);                   
  pinMode(b,OUTPUT);                    
  analogWrite(r,invert(255));           
  analogWrite(g,invert(0));             
  analogWrite(b,invert(0));            
  active_color = b;     
  Serial.begin(115200);
  Keyboard.begin();            
}

void loop() {
  long z1 =  z.capacitiveSensor(5);
  long x1 =  x.capacitiveSensor(5);
  if(z1>50) Keyboard.press('z');
  else Keyboard.release('z');
  if(x1>50) Keyboard.press('x');
  else Keyboard.release('x');
  switch (active_color) {               
    case r:                             
      active_color = b;                 
      break;                            
    case g:                           
      active_color = r;                
      break;                           
    case b:                             
      active_color = g;                 
      break;                            
  }
  if (!turn)  {                          
    i=0;
    while(i<=255) {
      w_time=millis();
      if(w_time-p_time>=5) {
        analogWrite(active_color,i);
        i++;
        p_time=w_time;
      }
    }
  }
    else {
      i=255;
      while(i>=0) {
        w_time=millis();
        if(w_time-p_time>=5) {
          analogWrite(active_color,i);
          i--;
          p_time=w_time;
        }
      }
    }
    turn = !turn;                       
}

 

fogary
Offline
Зарегистрирован: 05.03.2016

sersh4nt пишет:

int invert(int value){                  
  return map(value, 0, 255 ,255, 0);    
}

Сильно!!!

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

fogary пишет:
Сильно!!!

Это вопрос привычек. Мне в шараге тётка тоже грит: решаем уравнения, пишем real, потому что есть точка. Мотаем цыкал - int. А я вижу что цыкл от 1 до 8 (пизжю, от 0 до 7) - пишу byte.

<срыв покровов>

sersh4nt, он хотел сказать

  return 256-value;

</срыв покровов>

fogary
Offline
Зарегистрирован: 05.03.2016

Voodoo Doll пишет:

sersh4nt, он хотел сказать

  return 256-value;

Это-то понятно, только не 256, а 255.

Только зачем нужна эта функция?

analogWrite(r,invert(255));           
analogWrite(g,invert(0));             
analogWrite(b,invert(0)); 

Все, больше она нигде не используется.

MaksVV
Offline
Зарегистрирован: 06.08.2015

sersh4nt пишет:
Всем спасибо за идеи. Проблему решил. Для тех, кому нужен код, выкладываю.

я вообще-то имел ввиду по другому, потому как

ven-til пишет:

и в чем был смылс такого перехода на миллис? Глобально ничего не изменилось и программа работает точно так же как и с делей.

примерно так (в работе не проверял):

#define r 6                             // Пин подключения красного
#define g 5                             // Пин подключения зеленого
#define b 3                             // Пин подключения синего

int active_color;                       

#define UP   1                            
#define DOWN 2
byte turn = UP;                   
byte PWM  = 0;

unsigned long timer  = 0;


int invert(int value){                  
  return map(value, 0, 255 ,255, 0);    
}

void setup() {
  pinMode(r,OUTPUT);                   
  pinMode(g,OUTPUT);                   
  pinMode(b,OUTPUT);                    
  analogWrite(r,invert(255));           
  analogWrite(g,invert(0));             
  analogWrite(b,invert(0));            
  active_color = b;               
}

void loop() {
  switch (active_color) {               
    case r:                             
      active_color = b;                 
      break;                            
    case g:                           
      active_color = r;                
      break;                           
    case b:                             
      active_color = g;                 
      break;                            
  }
 
  if (turn!=0 && millis()-timer>5){
  if (turn==UP)                            
     {       
      PWM++;
      analogWrite(active_color, PWM);      
      if (PWM==255) turn = DOWN;
     }
  else if   (turn==DOWN)                                  
     {        
      PWM--;
      analogWrite(active_color,PWM);      
      if (PWM==0) turn = UP;
     }
  timer = millis();
  }
}