шим и индикация
- Войдите на сайт для отправки комментариев
Чт, 06/08/2015 - 11:05
добрый день. вопрос в следующем
допустим управляем яркостью света, есть 6 положений
1, 0
2, 51
3, 102
4, 153
5, 204
6, 255
надо сделать индикацию, т.е. подключаем 5 светодоидов, если первое положение то не горят, если второе горит светик1, если третье горит светик2 и т.д.
подскажите как правильней реализовать
пока написал следущее
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); }Задача абстрактная (в описании не хватает информации, домыслить можно что угодно) и решение аналогичное
#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 подставляйте ваши входные данные.
В принципе дложно работать, но проверить сейчас не на чем. Читайте комментарии, там два варианта засветки светиков.
Разумеется скетч не для всех случаев, а для решения данной абстрактной задачи.
спасибо большое))) смотрел в сторону оператора switch. Проверю отпишксь
Здесь switch только для "красоты" решения. Реально нужно думать, как сделать правильней, но это уже совсем другая история.
Попробую поподробнее обьяснить
Есть светодиодная лента отдельно покдлючена к пину 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
Значит я угадал алгоритм, break не нужно раскомментаривать.
Здесь еще одна неизвестная величина, кроме шести положений есть промежуточные и не описано, что включать, если, например, между 2 и 3 положением, например, значение 83. Его можно интерпретировать по-разному. Один из вариантов такой:
Впрочем это уже дело техники, мелочи.
нет там все просто, одна кнопка увеличивает переменную на 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; }всего шесть значений
Сдается мне, что задача решается значительно проще. Заводится счетчик текущего значения шим, например, current_pwm_index и кнопками это значение увеличивается или уменьшается на 1. Фактически у нас уже всегда есть нужный индекс шим. По этому индексу решаем как делать индикацию и по этому же индексу из массива уровней берем нужное значение шим и выводим в пин.
Т.е. танцуем от индекса, а не от значения. Тем более это выгодно, потому что сегодня значений шим 6, а завтра 7 или 8. Более того, чтобы было равномерней, в таблице уровней можно скоректировать значения шим, сделав эти значения неравномерными, фор икзэмпл 48, 102, 120, 198, 253. И тогда алгоритм не нужно менять, не нужно каждый раз отлаживать, достаточно просто поменять значения в массиве levels. И таки себе профит! :)
спасибо большое за советы, буду разбираться, закончу напишу
Ну да, пнули в нужную сторону, дальше сам, а то по граблям не походишь, ничему не научишься :)
Спасибо большое вам 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); }