Реализация кнопок и потенциометра

hhobbitt
Offline
Зарегистрирован: 23.03.2012

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

Объясню, что хочу получить: есть две кнопки, потенциометр, 3 3w светодиода, подключённых через mosfet транзисторы, с логическим управлением, будут подключаться к шим.

Итак, хочется, чтобы первая кнопка регулировала кол-во включённых светодиодов, нажал один раз, загорелся один, ещё раз нажал, горят уже два, ещё раз, уже все горят, потом нажал, снова ничего не горит. Вторая кнопка чтобы регулировала режим работы светодиодов (режимы стробоскопа, что-то типа бегущей строки, только каждый светодиод мигает дважды), и потенциометр чтобы регулировал яркость.

Моя простейшая попытка, регулировка количества светодиодов, потенциометров...

//Reads the State of a Pot and displays on screen
int led1 = 2;
int led2 = 3;
int led3 = 4;
int potPin = 0;

void setup()
{
  //sets the button pin as an input
  pinMode(potPin, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);  
  
  //Allows us to listen to serial communications from the arduino

}

void loop()
{
  // print the button state to a serial terminal
  
 if (analogRead(potPin) <341)
{
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
} 
 if (analogRead(potPin) >=341 && analogRead(potPin) <682)
 {
  digitalWrite(led1, HIGH);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
 }
 if (analogRead(potPin) >=682 && analogRead(potPin) <1020)
 {
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, LOW);
 }
  if (analogRead(potPin) >=1020)
 {
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, HIGH);
 }
  delay(100);
  //wait one second, then print again.
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

В  10 строке функция pinMode(potPin, INPUT); настроит у вас нулевой цифровой вывод (т.е. RX) на вход, а не ANALOG IN, аналоговые входы (АЦП) всегда работают на вход, эту строчку удаляем и впредь никогда не используем. А так же все порты по умолчанию настроены на вход, так что в setup() не нужно их настраивать на вход.

Так же в строках 02, 03, 04, 05 для определения пинов лучше использовать не переменные int, а

#define led1 2

так как каждая int-овая переменная будет жрать 2 байта оперативы.

maksim
Offline
Зарегистрирован: 12.02.2012

 

#define led1 9
#define led2 10
#define led3 11
#define potPin 0
#define button1 2
#define button2 3

byte lighting = 0;
byte leds = 0;
byte mode = 0;
byte i = 1;

void setup() {                
  pinMode(9, OUTPUT); 
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  digitalWrite(button1, HIGH);// подтяжка button1
  digitalWrite(button2, HIGH);// подтяжка button2
  attachInterrupt(0, Leds, FALLING); // button1
  attachInterrupt(1, Modes, FALLING); // button2
}

void loop() {
  lighting = map(analogRead(potPin), 0, 1023, 0, 255);

  switch (leds) {
  case 0:
    analogWrite(led1, 0);
    analogWrite(led2, 0); 
    analogWrite(led3, 0); 
    break;
  case 1:
    analogWrite(led1, lighting);
    analogWrite(led2, 0); 
    analogWrite(led3, 0); 
    break;
  case 2:
    analogWrite(led1, lighting);
    analogWrite(led2, lighting); 
    analogWrite(led3, 0); 
    break;
  case 3:
    analogWrite(led1, lighting);
    analogWrite(led2, lighting); 
    analogWrite(led3, lighting); 
    break;
  }

  switch (mode) {
  case 1:
    delay(50);
    analogWrite(led1, 0);
    analogWrite(led2, 0); 
    analogWrite(led3, 0); 
    delay(350);
    break;
  case 2:
    analogWrite(led1, 0);
    analogWrite(led2, 0); 
    analogWrite(led3, 0);
    byte st = 0;
    switch (i){
    case 1:
      st = led1;
      break;
    case 2:
      st = led2;
      break;
    case 3:
      st = led3;
      break;
    }
    analogWrite(st, lighting);
    delay(50);
    analogWrite(st, 0);
    delay(50);
    analogWrite(st, lighting);
    delay(50);
    analogWrite(st, 0);
    delay(350);
    i++;
    if(i > leds){
      i = 1;
    }
    break;
  }

}

void Leds() {
  leds++;
  if(leds == 4){
    leds = 0;
  }
}

void Modes(){
  mode++;
  if(mode == 3){
    mode = 0;
  }
}

  про режимы не совсем понял, сделал так:

1. Просто горит;

2. Стробоскоп;

3. "Что-то типа бегущей строки, только каждый светодиод мигает дважды"

hhobbitt
Offline
Зарегистрирован: 23.03.2012

Спасибо огромное!)

Если стоит подтяжка кнопок, то получается 10 кОмные резисторы не нужны?

Буду разбираться! 

maksim
Offline
Зарегистрирован: 12.02.2012

Именно так, не нужны.

hhobbitt
Offline
Зарегистрирован: 23.03.2012

ещё вопрос, резисторы, которые ограничивают ток на светодиод, ставить до или после транзистора? 

maksim
Offline
Зарегистрирован: 12.02.2012

Конечно после 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

 >>Конечно после <<

Откуда такая категоричность? По вашему , через транзистор пойдет т ок источника а на светодиоды - пониженый резистором.

Не лучше ли снизить и ток транзистора ?

>>В 10 строке функция pinMode(potPin, INPUT); настроит у вас нулевой цифровой вывод (т.е. RX) на вход<<
 

14 ая нога дуины так же является нулевой ногой порта АЦП . Так что к ней можно обращаться analogRead(0);.

>>аналоговые входы (АЦП) всегда работают на вход<<

Вот это ваш основной перл. Вы это серьезно ?

Т.е по вашему digitalWrite(14,HIGH); ни к чему не приведет ?

Читайте документацию на МК AVR. Там ясно сказано "Все ноги МК могут быть сконфигурированы  как на вход , так и на ВЫХОД".

hhobbitt
Offline
Зарегистрирован: 23.03.2012

Ещё вопрос, как указать, если у меня будет задействован потенциометр на 3 ноге аналогового входа, а на 3 ноге цифрового пина будет светодиод? и там и там будет 3шка... ведь не напишешь

#define potPort 3
#define led 3

Как быть? 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Присваивайте номера самой дуины.

Т.е. 3 нога аналогового входа - нога 16. 3 нога цифрового так и будет - 3. 

hhobbitt
Offline
Зарегистрирован: 23.03.2012

Спасибо огромное!) Теперь более понятно!)

если делать плату на Микроконтроллере ATmega, там надо писать на СИ, синтаксис сильно отличается? Или какие-то компиляторы есть? Хочется просто всё отдельной платой сделать, а Ардуино оставить для макетов 

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>там надо писать на СИ, синтаксис сильно отличается?<<

Очень. 

Не проще ли сделать упрощенный вариант дуины (без ft232) ?

Там всего то 10 деталей. Но нужны МК с автозагрузчиком.

maksim
Offline
Зарегистрирован: 12.02.2012

Это вы читайте сами внимательнее - это ваш основной перл!

nestandart пишет:

 Откуда такая категоричность? По вашему , через транзистор пойдет ток источника а на светодиоды - пониженый резистором.

Не лучше ли снизить и ток транзистора ?

MOSFET Какой вы там ток хотите снижать?

nestandart пишет:

>>В 10 строке функция pinMode(potPin, INPUT); настроит у вас нулевой цифровой вывод (т.е. RX) на вход<<
 

14 ая нога дуины так же является нулевой ногой порта АЦП . Так что к ней можно обращаться analogRead(0);.

>>аналоговые входы (АЦП) всегда работают на вход<<

Вот это ваш основной перл. Вы это серьезно ?

Т.е по вашему digitalWrite(14,HIGH); ни к чему не приведет ?

Читайте документацию на МК AVR. Там ясно сказано "Все ноги МК могут быть сконфигурированы как на вход , так и на ВЫХОД".

Да, серьезно. Вот именно для вас уточнил АЦП , или по вашаму АЦП и на выход работает? Или pinMode() настраивает АЦП?
 

И я без вас знаю как могут работать порты у авров и именно порты могут быть сконфигурированы, а не АЦП и я специально опустил эти подробности, что бы человека не путать...

maksim
Offline
Зарегистрирован: 12.02.2012

hhobbitt пишет:

Ещё вопрос, как указать, если у меня будет задействован потенциометр на 3 ноге аналогового входа, а на 3 ноге цифрового пина будет светодиод? и там и там будет 3шка... ведь не напишешь

#define potPort 3
#define led 3

Как быть? 

Ничего в этом страшного нет, напишешь, #define не определяет какой где вывод, #define просто подставляет значение, т.е. в коде где вы используете "led" будет подставляться "3" и ничего больше.

и вы же не будете писать analogRead(led) или digitalWrite(potPort, 1)

maksim
Offline
Зарегистрирован: 12.02.2012

nestandart пишет:

Присваивайте номера самой дуины.

Т.е. 3 нога аналогового входа - нога 16. 3 нога цифрового так и будет - 3. 

Т.е. по вашему analogRead(3); тоже самое что и analogRead(16); ?

Вы зачем человека в заблуждение вводите?

analogRead(0); = analogRead(8); = analogRead(14);

analogRead(1); = analogRead(9); = analogRead(15);

analogRead(2); = analogRead(10); = analogRead(16);

analogRead(3); = analogRead(11); = analogRead(17);

.............

И кому это надо? Не проще ли в случае с analogRead() нумеровать с 0, хотя бы только потому, что на плате они так же пронумерованы.
 

maksim
Offline
Зарегистрирован: 12.02.2012

 

hhobbitt пишет:

если делать плату на Микроконтроллере ATmega, там надо писать на СИ, синтаксис сильно отличается? Или какие-то компиляторы есть? Хочется просто всё отдельной платой сделать, а Ардуино оставить для макетов

Почему же на СИ? пишите на чем пишите, у вас же в Ардуине ATmega стоит. Делайте отдельной платой, а что бы можно было прошивать не выпаивая и не вытаскивая есть ISP, через него и бутлоудер зальете и скейтч, а Ардуину для макетов.

 

hhobbitt
Offline
Зарегистрирован: 23.03.2012

maksim пишет:

Почему же на СИ? пишите на чем пишите, у вас же в Ардуине ATmega стоит. Делайте отдельной платой, а что бы можно было прошивать не выпаивая и не вытаскивая есть ISP, через него и бутлоудер зальете и скейтч, а Ардуину для макетов.

 

Спасибо!) буду паять без Ком порта) а МП у меня всегда будет сниматься)

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>И я без вас знаю как могут работать порты у авров и именно порты могут быть сконфигурированы, а не АЦП и я специально опустил эти подробности, что бы человека не путать...<<

По моему вы его только запутали. Лично я понял вас так что ноги , которые являются входами АЦП могут работать только на вход. 

>>Т.е. по вашему analogRead(3); тоже самое что и analogRead(16); ?<<

Вот здесь промахнулся. Да , действительно нога АЦП №3 - пин 17.

maksim
Offline
Зарегистрирован: 12.02.2012

Вы и про транзистор из-за невнимательности промахнулись... но не суть.

Для новичка, по-моему, излишняя инфа о том, что на тех же ногах, где аналоговые входы (а не ноги) стоит еще и порт. И я имел ввиду именно то, что когда обращаешься к АЦП, через analogRead() не нужно пытаться сконфигурировать порт, так как АЦП работает только на вход.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

 >>Вы и про транзистор промахнулись...<<

Почему вы так думаете ?

Докажите принципиальную разницу между установкой резистора до или после транзюка.

maksim
Offline
Зарегистрирован: 12.02.2012

 Мосфеты управляются не током, а напряжением, сопротивление управляющего канала мегаомы, так что от резистора между МК и  управляющим каналом не будет никакого толку.

maksim
Offline
Зарегистрирован: 12.02.2012

Да можно поставить делитель (т.е. два резистора) до транзистора.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

>>так что от резистора между МК и управляющим каналом не будет никакого толку<< 

Причем здесь МК ? МК управляет затвором , не более. Я говорю про ток исток-сток. Резистор нужен для ограничения тока проходящего через светодиод.

Включается резистор последовательно стоку/истоку. Какая разница между подключением его к стоку или истоку ?

maksim
Offline
Зарегистрирован: 12.02.2012

Мы опять не поняли друг друга, в этом случае никакой разницы нет. Или я изначально не так понял, если так то извиняюсь.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Изначально речь шла про один единственный резистор (ограничитель тока светодиода) . Вы сказали что его нужно ставить после транзюка. Я спросил "Откуда такая категоричность".

Вот и все. 

maksim
Offline
Зарегистрирован: 12.02.2012

Просто я понял так, что "до транзистора" значит до усиления сигнала транзистором, т.е. между МК и управляющим каналом.

nestandart
nestandart аватар
Offline
Зарегистрирован: 15.06.2011

Кстати ,  туда тоже не мешало бы поставить защитный резюк (100-200Ом). Чтобы быть увереным в том что ток , на выходе МК, не превышает 20мА. 

Если , например , затвор будет закорочен с истоком (недолго) это спасет ногу МК от выгорания.

maksim
Offline
Зарегистрирован: 12.02.2012

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

hhobbitt
Offline
Зарегистрирован: 23.03.2012

Ребят, а не объясните как работает функция attachInterrupt, а то справку почитал, не понял, желательно на моём примере... спасибо...

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

maksim
Offline
Зарегистрирован: 12.02.2012

Про прерывания здесь:www.youtube.com/watch и здесь www.youtube.com/watch