Управление подогревом сидений

CRJ
Offline
Зарегистрирован: 22.09.2017

Всем привет!

Решил соорудить подогрев сидений на задний диван, но есть некоторые трудности, поэтому прошу помощи.

Суть такова:

Управление подогревом ШИМом через MOSFET.

Для повторения общей концепции подогрева в машине - кнопка с тремя светодиодами.

1-е нажатие - полный накал - горят все три диода.

2-е нажатие - скажем, 75% - горят 2 диода.

3-е нажатие - 50% - горит 1 диод.

4-е - ВЫКЛ.

На данный момент имею следующий скетч:



int switchPin = 8;
int pwmPin = 11;
boolean lastButton = LOW;
boolean currentButton = LOW;
int pwmLevel = 0;
int led1 = 5;
int led2 = 6;
int led3 = 7;

void setup()
{
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(pwmPin, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

boolean debounce(boolean last)
{
  boolean current = digitalRead(switchPin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(switchPin);
  }
  return current;
}

void loop()
{
  currentButton = debounce(lastButton);
  if (lastButton == HIGH && currentButton == LOW)
  {

    pwmLevel = pwmLevel + 85;
  }

  lastButton = currentButton;

  if (pwmLevel > 255) pwmLevel = 0;
  analogWrite(pwmPin, pwmLevel);
  
  switch (pwmLevel) 
  {
    case 85:
      digitalWrite (led1, HIGH);
      break;
    case 170:
      digitalWrite (led1, HIGH);
      digitalWrite (led2, HIGH);
      break;
    case 255:
      digitalWrite (led1, HIGH);
      digitalWrite (led2, HIGH);
      digitalWrite (led3, HIGH);
      break;
    default:
      digitalWrite (led1, LOW);
      digitalWrite (led2, LOW);
      digitalWrite (led3, LOW);
      break;
  }
}

В отличии от требуемого - порядок обратный 33-67-100%-выкл (85, 170, 255, 0.).

Плюс не могу въехать как сделать pwmLewel с настраиваемыми значениями т.е. 50, 75, 100% или любыми другими.

Сильно не пинайте, дилетант я еще.

 

CRJ
Offline
Зарегистрирован: 22.09.2017

И еще: можно ли все это дублировать, т.е. с одной Ардуины управлять двумя подогревами? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

CRJ пишет:

В отличии от требуемого - порядок обратный 33-67-100%-выкл (85, 170, 255, 0.).

Так у Вас ведь так и написано. Сначачала 0, после первого нажатия - 85, после второго 170 и т.д. Если нужно наоборот, так и делайте наоборот.

Да, конечно, можно, хоть два, хоть 4, хоть 6 (если у Вас UNO, на Меге и ольше можно).

CRJ
Offline
Зарегистрирован: 22.09.2017

ЕвгенийП пишет:

Так у Вас ведь так и написано. Сначачала 0, после первого нажатия - 85, после второго 170 и т.д. Если нужно наоборот, так и делайте наоборот.

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

05 int pwmLevel = 255;

а далее

36     pwmLevel = pwmLevel - 85;

То при подаче питания работает сразу на полную, а по нажатию уменьшается...

Не могу разобраться как сделать чтобы значения можно было менять на произвольные, ибо есть подозрение, что при 85/255 будет 4,7 в, которые дадут около 4 Вт, а это маловато.

Хотелось бы сделать что-то вроде 120, 200, 255...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

CRJ пишет:

Хотелось бы сделать что-то вроде 120, 200, 255...

Ну, так и делайте.

Я не пойиу, чего Вы не понимаете. Объясните толком.

CRJ
Offline
Зарегистрирован: 22.09.2017

Я не понимаю как присвоить значение для каждого конкретного нажатия, т.е. мне нужны 3 переменные, которые задаются в начале (и которые можно менять вручную), а так же, чтоб не включался подогрев при подаче питания - только при первом нажатии.

1 клик - ВКЛ 255

2 клик - 170 (или другое значение)

3 клик - 120 (или  др.)

4 клик - выкл 0.

Как-от так...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

НуЮ заведите массив в который напихайте Всё, что хотите. В самое начало поставьте 0

// массив значений
static const uint8_t values[] = {0, 255, 200, 170, 150};

// Количество элементов в массиве значений
static const int totalValues =   sizoef(values) / sizepf(values[0]);

Заведите переменную index там или ещё как и по нажатию кнопки меняйте её на 1.

// это глобально
static int index = 0;

// а это по нажатию кнопки
index = (index + 1) % totalValues;

Всё - она никуда не денется, будет доходить до последнего значения в массиве и сваливаться в 0.

Ну, а в analogWrite испольуйте значения из массива

analogWrite(pin, values[index]);

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

CRJ
Offline
Зарегистрирован: 22.09.2017

Проблема проста до абсурда - не хватает знаний!

Вроде все заработало, только вот диоды перестали светить как надо...

Вашу переменную index поменял на pwmLevel



int switchPin = 8;
int pwmPin = 11;
boolean lastButton = LOW;
boolean currentButton = LOW;
int led1 = 5;
int led2 = 6;
int led3 = 7;
static int pwmLevel = 0;
// массив значений
static const uint8_t values[] = {0, 255, 200, 120};

// Количество элементов в массиве значений
static const int totalValues =   sizeof(values) / sizeof(values[0]);

void setup()
{
  Serial.begin(9600);
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(pwmPin, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
}

boolean debounce(boolean last)
{
  boolean current = digitalRead(switchPin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(switchPin);
  }
  return current;
}

void loop()
{
  currentButton = debounce(lastButton);
  if (lastButton == HIGH && currentButton == LOW)
  {

    pwmLevel = (pwmLevel + 1) % totalValues;

  }

  lastButton = currentButton;

  if (pwmLevel > 255) pwmLevel = 0;
  analogWrite(pwmPin, values[pwmLevel]);
  Serial.println (pwmLevel);

  switch (pwmLevel)
  {
    case 1:
      digitalWrite (led1, HIGH);
      digitalWrite (led2, HIGH);
      digitalWrite (led3, HIGH);
      break;
    case 2:
      digitalWrite (led1, HIGH);
      digitalWrite (led2, HIGH);
      break;
    case 3:
      digitalWrite (led1, HIGH);
      break;
    default:
      digitalWrite (led1, LOW);
      digitalWrite (led2, LOW);
      digitalWrite (led3, LOW);
      break;
  }
}

Горят все три в рабочем режиме, выключаются в нерабочем.

CRJ
Offline
Зарегистрирован: 22.09.2017

Вылечил, не очень изящно, но работает.

Может кто подскажет как с диодами бороться, чтоб код уменьшить?


int switchPin = 8;
int pwmPin = 11;
boolean lastButton = LOW;
boolean currentButton = LOW;
static int pwmLevel = 0;
static const uint8_t values[] = {
  0, // выключено
  255, // нагрев 3
  200, // нагрев 2
  120 // нагрев 1
};// массив значений

static const int totalValues =   sizeof(values) / sizeof(values[0]); // Количество элементов в массиве значений

void setup()
{
  Serial.begin(9600);
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(pwmPin, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

boolean debounce(boolean last)
{
  boolean current = digitalRead(switchPin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(switchPin);
  }
  return current;
}

void loop()
{
  currentButton = debounce(lastButton);
  if (lastButton == HIGH && currentButton == LOW)
  {

    pwmLevel = (pwmLevel + 1) % totalValues;
  }

  lastButton = currentButton;
  analogWrite(pwmPin, values[pwmLevel]);
  Serial.println (pwmLevel);


  switch (pwmLevel)
  {
    case 1:
      digitalWrite (5, HIGH);
      digitalWrite (6, HIGH);
      digitalWrite (7, HIGH);
      break;
    case 2:
      digitalWrite (5, HIGH);
      digitalWrite (6, HIGH);
      digitalWrite (7, LOW);
      break;
    case 3:
      digitalWrite (5, HIGH);
      digitalWrite (6, LOW);
      digitalWrite (7, LOW);
      break;
    default:
      digitalWrite (5, LOW);
      digitalWrite (6, LOW);
      digitalWrite (7, LOW);
      break;
  }

}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

CRJ пишет:

Может кто подскажет как с диодами бороться, чтоб код уменьшить?

Да, чего его сокращать, код как код.

Ну, если уж сильно приспичило, так просто посмотрите на него внимательно. Вот смотрите:

  switch (pwmLevel)
  {
    case 1:
      digitalWrite (5, HIGH);
      digitalWrite (6, HIGH);
      digitalWrite (7, HIGH);
      break;
    case 2:
      digitalWrite (5, HIGH);
      digitalWrite (6, HIGH);
      digitalWrite (7, LOW);
      break;
    case 3:
      digitalWrite (5, HIGH);
      digitalWrite (6, LOW);
      digitalWrite (7, LOW);
      break;
    default:
      digitalWrite (5, LOW);
      digitalWrite (6, LOW);
      digitalWrite (7, LOW);
      break;
  }

5-ый должен быть HIGH при любом pwmLevel, кроме 0.
6-ой при 1 или 2
7-ой только при 1.

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

digitalWrite (5, pwmLevel);
digitalWrite (6, pwmLevel == 1 || pwmLevel == 2);
digitalWrite (7, pwmLevel == 1);

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ЕвгенийП пишет:

CRJ пишет:

Может кто подскажет как с диодами бороться, чтоб код уменьшить?

Да, чего его сокращать, код как код.

Ну, если уж сильно приспичило, так просто посмотрите на него внимательно. Вот смотрите:

  switch (pwmLevel)
  {
    case 1:
      digitalWrite (5, HIGH);
      digitalWrite (6, HIGH);
      digitalWrite (7, HIGH);
      break;
    case 2:
      digitalWrite (5, HIGH);
      digitalWrite (6, HIGH);
      digitalWrite (7, LOW);
      break;
    case 3:
      digitalWrite (5, HIGH);
      digitalWrite (6, LOW);
      digitalWrite (7, LOW);
      break;
    default:
      digitalWrite (5, LOW);
      digitalWrite (6, LOW);
      digitalWrite (7, LOW);
      break;
  }

5-ый должен быть HIGH при любом pwmLevel, кроме 0.
6-ой при 1 или 2
7-ой только при 1.

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

digitalWrite (5, pwmLevel);
digitalWrite (6, pwmLevel == 1 || pwmLevel == 2);
digitalWrite (7, pwmLevel == 1);

Если Вас по неопытности, смыщает строка "digitalWrite (5, pwmLevel);", ничуть не хуже будет написать дословно "при любом, кроме 0" - "digitalWrite (5, pwmLevel != 0);"

CRJ
Offline
Зарегистрирован: 22.09.2017

Спасибо, Евгений! Все работает, дальше буду мудрить с аппаратной частью.