шим и индикация

vankenshtein
Offline
Зарегистрирован: 15.04.2014

добрый день. вопрос в следующем

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

1, 0

2, 51

3, 102

4, 153

5, 204

6, 255

надо сделать индикацию, т.е. подключаем 5 светодоидов, если первое положение то не горят, если второе горит светик1, если третье горит светик2 и т.д.

подскажите как правильней реализовать

vankenshtein
Offline
Зарегистрирован: 15.04.2014

пока написал следущее


const int podPlus = 2;  
const int podMinus = 3;
const int lightbt = 4;
const int podogrPwm = 5;
const int lightPwm = 6;
const int ledpol1 = 9;  
const int ledpol2 = 10;
const int ledpol3 = 11;
const int ledpol4 = 12;
const int ledpol5 = 13;

int podPlusFl = 0;
int podMinusFl = 0;
int lightFl = 0;

int podPlusState = 0;        
int podMinusState = 0;  
int lightbtState = 0; 

int valLifht = 0; 
int valPodog = 0; 

void setup() {
Serial.begin(9600);

pinMode(podPlus, INPUT);
pinMode(podMinus, INPUT);
pinMode(lightbt, INPUT);
pinMode(podogrPwm, OUTPUT);
pinMode(lightPwm, OUTPUT);
pinMode(ledpol1, OUTPUT); 
pinMode(ledpol2, OUTPUT);
pinMode(ledpol3, OUTPUT);
pinMode(ledpol4, OUTPUT);
pinMode(ledpol5, OUTPUT);
   
}

void loop(){

podPlusState = digitalRead(podPlus);
podMinusState = digitalRead(podMinus);
lightbtState = digitalRead(lightbt);

  if(podPlusState == LOW && podPlusFl==0) { 
       podPlusFl=1;
       }
  if (podPlusState == HIGH && podPlusFl==1){
            if (valPodog < 255 && valPodog != 0){
              valPodog = valPodog + 51;
             }
             else{
            valPodog = 255;
             }
       podPlusFl=0;
       }
       
       if(podMinusState == LOW && podMinusFl==0) { 
       podMinusFl=1;
       }
  if (podMinusState == HIGH && podMinusFl==1){
            if (valPodog > 0){
              valPodog = valPodog - 51;
            }
       podMinusFl=0;
       }

 Serial.print("podog");
 Serial.print(valPodog);
}

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Задача абстрактная (в описании не хватает информации, домыслить можно что угодно) и решение аналогичное

#define MAX_LEVELS (5)

const byte levels[MAX_LEVELS] = {
  51,
  102,
  153,
  204,
  255
};

/* Массив номеров пинов для выходных светиков. первый - младший */
const byte leds[] = {
  3, 4, 5, 6, 7
};
/* Размер массива с номерами пинов */
const byte leds_size = sizeof(leds) / sizeof(byte);

/* Входной уровень, для тестирования */
byte global_level = 0;

void setup() {
  /* Инициализируем выходные пины */
  for (byte i = 0; i < leds_size; ++i) {
    pinMode(leds[i], OUTPUT);
  }
}

void clear_leds() {
  for (byte i = 0; i < leds_size; ++i) {
    digitalWrite(leds[i], LOW);
  }
}

void loop() {
  byte level = MAX_LEVELS;
  for (byte i = 0; i < MAX_LEVELS; ++i) {
    if (global_level <= levels[i]) {
      level = i;
      break;
    }
  }
  /* Гасим все светики, потому что уровень может измениться в любую сторону */
  clear_leds();
  if (global_level != 0) {
    /* Здесь чем выше уровень, тем больше светиков горят */
    /* Если раскомемнтарить break, то будет гореть только один светодиод, соответствующий своему уровню */
    switch (level) {
      case 4:
        digitalWrite(leds[4], HIGH);
      // break;
      case 3:
        digitalWrite(leds[3], HIGH);
      // break;
      case 2:
        digitalWrite(leds[2], HIGH);
      // break;
      case 1:
        digitalWrite(leds[1], HIGH);
      // break;
      case 0:
        digitalWrite(leds[0], HIGH);
        // break;
    }
  }
  delay(500);
  /* Меняем значение входного уровня. Только для тестирования */
  global_level += 47;
}

Вместо global_level подставляйте ваши входные данные.

В принципе дложно работать, но проверить сейчас не на чем. Читайте комментарии, там два варианта засветки светиков.

Разумеется скетч не для всех случаев, а для решения данной абстрактной задачи.

 

vankenshtein
Offline
Зарегистрирован: 15.04.2014

спасибо большое))) смотрел в сторону оператора switch. Проверю отпишксь

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Здесь switch только для "красоты" решения. Реально нужно думать, как сделать правильней, но это уже совсем другая история.

vankenshtein
Offline
Зарегистрирован: 15.04.2014

Попробую поподробнее обьяснить

Есть светодиодная лента отдельно покдлючена к пину 6(к примеру) и есть 5 светодиодов для индикации подключеных к пинам 9-13. При помощи ШИМ управляем яркостью светодиодной ленты(всего шесть положений 1, 0     2, 51     3, 102     4, 153    5, 204   6, 255). И в зависимости от положения горят светики

1положение ни один светодиод не горит

2положение горит светодиод1

3положение горят светодиоды 1 и 2

4положение горят светодиоды 1, 2 и 3

5положение горят светодиоды 1, 2, 3 и 4

5положение горят светодиоды 1, 2, 3, 4 и 5

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Значит я угадал алгоритм, break не нужно раскомментаривать.

Здесь еще одна неизвестная величина, кроме шести положений есть промежуточные и не описано, что включать, если, например, между 2 и 3 положением, например, значение 83. Его можно интерпретировать по-разному. Один из вариантов такой:

0-1-2-3-4-5-6           - положения
0011223344556          - кол-во горящих светодиодов

Впрочем это уже дело техники, мелочи.

 

vankenshtein
Offline
Зарегистрирован: 15.04.2014

нет там все просто, одна кнопка увеличивает переменную на 51

вторая уменьшает на 51

 if(podPlusState == LOW && podPlusFl==0) { 
       podPlusFl=1;
       }
  if (podPlusState == HIGH && podPlusFl==1){
            if (valPodog < 255 && valPodog != 0){
              valPodog = valPodog + 51;
             }
             else{
            valPodog = 255;
             }
       podPlusFl=0;
       }
       
       if(podMinusState == LOW && podMinusFl==0) { 
       podMinusFl=1;
       }
  if (podMinusState == HIGH && podMinusFl==1){
            if (valPodog > 0){
              valPodog = valPodog - 51;
            }
       podMinusFl=0;
       }

всего шесть значений 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Сдается мне, что задача решается значительно проще. Заводится счетчик текущего значения шим, например, current_pwm_index и кнопками это значение увеличивается или уменьшается на 1. Фактически у нас уже всегда есть нужный индекс шим. По этому индексу решаем как делать индикацию и по этому же индексу из массива уровней берем нужное значение шим и выводим в пин.

Т.е. танцуем от индекса, а не от значения. Тем более это выгодно, потому что сегодня значений шим 6, а завтра 7 или 8. Более того, чтобы было равномерней, в таблице уровней можно скоректировать значения шим, сделав эти значения неравномерными, фор икзэмпл 48, 102, 120, 198, 253. И тогда алгоритм не нужно менять, не нужно каждый раз отлаживать, достаточно просто поменять значения в массиве levels. И таки себе профит! :)

 

vankenshtein
Offline
Зарегистрирован: 15.04.2014

спасибо большое за советы, буду разбираться, закончу напишу

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Ну да, пнули в нужную сторону, дальше сам, а то по граблям не походишь, ничему не научишься :)

vankenshtein
Offline
Зарегистрирован: 15.04.2014

Спасибо большое вам kisoft


const int podPlus = 2;  
const int podMinus = 3;
const int lightbt = 4;
const int podogrPwm = 5;
const int lightPwm = 6;

/*
const int ledpol1 = 9;  
const int ledpol2 = 10;
const int ledpol3 = 11;
const int ledpol4 = 12;
const int ledpol5 = 13;
*/

/* Массив номеров пинов для выходных светиков. первый - младший */
const byte ledpol[] = {
  9, 10, 11, 12, 13
};
/* Размер массива с номерами пинов */
const byte leds_size = sizeof(ledpol) / sizeof(byte);

int podPlusFl = 0;
int podMinusFl = 0;
int lightFl = 0;

int podPlusState = 0;        
int podMinusState = 0;  
int lightbtState = 0; 

int valLight = 0; 
int valPodog = 0; 

void setup() {
Serial.begin(9600);

pinMode(podPlus, INPUT);
pinMode(podMinus, INPUT);
pinMode(lightbt, INPUT);
pinMode(podogrPwm, OUTPUT);
pinMode(lightPwm, OUTPUT);

/* Инициализируем выходные пины */
  for (byte i = 0; i < leds_size; ++i) {
    pinMode(ledpol[i], OUTPUT);
    }
 /*   
pinMode(ledpol1, OUTPUT); 
pinMode(ledpol2, OUTPUT);
pinMode(ledpol3, OUTPUT);
pinMode(ledpol4, OUTPUT);
pinMode(ledpol5, OUTPUT);
 */  
}
void clear_leds() {
  for (byte i = 0; i < leds_size; ++i) {
    digitalWrite(ledpol[i], LOW);
  }
}
void loop()
{
podPlusState = digitalRead(podPlus);
podMinusState = digitalRead(podMinus);
lightbtState = digitalRead(lightbt);
 clear_leds();
  if(podPlusState == LOW && podPlusFl==0) { 
       podPlusFl=1;
       }
  if (podPlusState == HIGH && podPlusFl==1){
            if (valPodog < 255 && valPodog != 0){
              valPodog = valPodog + 51;
             }
             else{
            valPodog = 255;
             }
       podPlusFl=0;
       }
       
       if(podMinusState == LOW && podMinusFl==0) { 
       podMinusFl=1;
       }
  if (podMinusState == HIGH && podMinusFl==1){
            if (valPodog > 0){
              valPodog = valPodog - 51;
            }
       podMinusFl=0;
       }
      if (valPodog != 0) {
    /* Здесь чем выше уровень, тем больше светиков горят */
    /* Если раскомемнтарить break, то будет гореть только один светодиод, соответствующий своему уровню */
     
       switch (valPodog) {
      case 255:
        digitalWrite(ledpol[4], HIGH);
      // break;
      case 204:
        digitalWrite(ledpol[3], HIGH);
      // break;
      case 153:
        digitalWrite(ledpol[2], HIGH);
      // break;
      case 102:
        digitalWrite(ledpol[1], HIGH);
      // break;
      case 51:
        digitalWrite(ledpol[0], HIGH);
        // break;
    }
    }   
analogWrite(podogrPwm, valPodog);
 Serial.print("podog");
 Serial.println(valPodog);
}