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

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

Всем привет!

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

Суть такова:

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

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

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

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

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

4-е - ВЫКЛ.

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

01int switchPin = 8;
02int pwmPin = 11;
03boolean lastButton = LOW;
04boolean currentButton = LOW;
05int pwmLevel = 0;
06int led1 = 5;
07int led2 = 6;
08int led3 = 7;
09 
10void setup()
11{
12  pinMode(switchPin, INPUT_PULLUP);
13  pinMode(pwmPin, OUTPUT);
14  pinMode(led1, OUTPUT);
15  pinMode(led2, OUTPUT);
16  pinMode(led3, OUTPUT);
17}
18 
19boolean debounce(boolean last)
20{
21  boolean current = digitalRead(switchPin);
22  if (last != current)
23  {
24    delay(5);
25    current = digitalRead(switchPin);
26  }
27  return current;
28}
29 
30void loop()
31{
32  currentButton = debounce(lastButton);
33  if (lastButton == HIGH && currentButton == LOW)
34  {
35 
36    pwmLevel = pwmLevel + 85;
37  }
38 
39  lastButton = currentButton;
40 
41  if (pwmLevel > 255) pwmLevel = 0;
42  analogWrite(pwmPin, pwmLevel);
43   
44  switch (pwmLevel)
45  {
46    case 85:
47      digitalWrite (led1, HIGH);
48      break;
49    case 170:
50      digitalWrite (led1, HIGH);
51      digitalWrite (led2, HIGH);
52      break;
53    case 255:
54      digitalWrite (led1, HIGH);
55      digitalWrite (led2, HIGH);
56      digitalWrite (led3, HIGH);
57      break;
58    default:
59      digitalWrite (led1, LOW);
60      digitalWrite (led2, LOW);
61      digitalWrite (led3, LOW);
62      break;
63  }
64}

В отличии от требуемого - порядок обратный 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

1// массив значений
2static const uint8_t values[] = {0, 255, 200, 170, 150};
3 
4// Количество элементов в массиве значений
5static const int totalValues =   sizoef(values) / sizepf(values[0]);

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

1// это глобально
2static int index = 0;
3 
4// а это по нажатию кнопки
5index = (index + 1) % totalValues;

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

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

1analogWrite(pin, values[index]);

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

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

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

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

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

01int switchPin = 8;
02int pwmPin = 11;
03boolean lastButton = LOW;
04boolean currentButton = LOW;
05int led1 = 5;
06int led2 = 6;
07int led3 = 7;
08static int pwmLevel = 0;
09// массив значений
10static const uint8_t values[] = {0, 255, 200, 120};
11 
12// Количество элементов в массиве значений
13static const int totalValues =   sizeof(values) / sizeof(values[0]);
14 
15void setup()
16{
17  Serial.begin(9600);
18  pinMode(switchPin, INPUT_PULLUP);
19  pinMode(pwmPin, OUTPUT);
20  pinMode(led1, OUTPUT);
21  pinMode(led2, OUTPUT);
22  pinMode(led3, OUTPUT);
23}
24 
25boolean debounce(boolean last)
26{
27  boolean current = digitalRead(switchPin);
28  if (last != current)
29  {
30    delay(5);
31    current = digitalRead(switchPin);
32  }
33  return current;
34}
35 
36void loop()
37{
38  currentButton = debounce(lastButton);
39  if (lastButton == HIGH && currentButton == LOW)
40  {
41 
42    pwmLevel = (pwmLevel + 1) % totalValues;
43 
44  }
45 
46  lastButton = currentButton;
47 
48  if (pwmLevel > 255) pwmLevel = 0;
49  analogWrite(pwmPin, values[pwmLevel]);
50  Serial.println (pwmLevel);
51 
52  switch (pwmLevel)
53  {
54    case 1:
55      digitalWrite (led1, HIGH);
56      digitalWrite (led2, HIGH);
57      digitalWrite (led3, HIGH);
58      break;
59    case 2:
60      digitalWrite (led1, HIGH);
61      digitalWrite (led2, HIGH);
62      break;
63    case 3:
64      digitalWrite (led1, HIGH);
65      break;
66    default:
67      digitalWrite (led1, LOW);
68      digitalWrite (led2, LOW);
69      digitalWrite (led3, LOW);
70      break;
71  }
72}

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

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

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

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

01int switchPin = 8;
02int pwmPin = 11;
03boolean lastButton = LOW;
04boolean currentButton = LOW;
05static int pwmLevel = 0;
06static const uint8_t values[] = {
07  0, // выключено
08  255, // нагрев 3
09  200, // нагрев 2
10  120 // нагрев 1
11};// массив значений
12 
13static const int totalValues =   sizeof(values) / sizeof(values[0]); // Количество элементов в массиве значений
14 
15void setup()
16{
17  Serial.begin(9600);
18  pinMode(switchPin, INPUT_PULLUP);
19  pinMode(pwmPin, OUTPUT);
20  pinMode(5, OUTPUT);
21  pinMode(6, OUTPUT);
22  pinMode(7, OUTPUT);
23}
24 
25boolean debounce(boolean last)
26{
27  boolean current = digitalRead(switchPin);
28  if (last != current)
29  {
30    delay(5);
31    current = digitalRead(switchPin);
32  }
33  return current;
34}
35 
36void loop()
37{
38  currentButton = debounce(lastButton);
39  if (lastButton == HIGH && currentButton == LOW)
40  {
41 
42    pwmLevel = (pwmLevel + 1) % totalValues;
43  }
44 
45  lastButton = currentButton;
46  analogWrite(pwmPin, values[pwmLevel]);
47  Serial.println (pwmLevel);
48 
49 
50  switch (pwmLevel)
51  {
52    case 1:
53      digitalWrite (5, HIGH);
54      digitalWrite (6, HIGH);
55      digitalWrite (7, HIGH);
56      break;
57    case 2:
58      digitalWrite (5, HIGH);
59      digitalWrite (6, HIGH);
60      digitalWrite (7, LOW);
61      break;
62    case 3:
63      digitalWrite (5, HIGH);
64      digitalWrite (6, LOW);
65      digitalWrite (7, LOW);
66      break;
67    default:
68      digitalWrite (5, LOW);
69      digitalWrite (6, LOW);
70      digitalWrite (7, LOW);
71      break;
72  }
73 
74}

 

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

CRJ пишет:

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

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

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

01switch (pwmLevel)
02{
03  case 1:
04    digitalWrite (5, HIGH);
05    digitalWrite (6, HIGH);
06    digitalWrite (7, HIGH);
07    break;
08  case 2:
09    digitalWrite (5, HIGH);
10    digitalWrite (6, HIGH);
11    digitalWrite (7, LOW);
12    break;
13  case 3:
14    digitalWrite (5, HIGH);
15    digitalWrite (6, LOW);
16    digitalWrite (7, LOW);
17    break;
18  default:
19    digitalWrite (5, LOW);
20    digitalWrite (6, LOW);
21    digitalWrite (7, LOW);
22    break;
23}

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

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

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

 

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

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

CRJ пишет:

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

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

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

01switch (pwmLevel)
02{
03  case 1:
04    digitalWrite (5, HIGH);
05    digitalWrite (6, HIGH);
06    digitalWrite (7, HIGH);
07    break;
08  case 2:
09    digitalWrite (5, HIGH);
10    digitalWrite (6, HIGH);
11    digitalWrite (7, LOW);
12    break;
13  case 3:
14    digitalWrite (5, HIGH);
15    digitalWrite (6, LOW);
16    digitalWrite (7, LOW);
17    break;
18  default:
19    digitalWrite (5, LOW);
20    digitalWrite (6, LOW);
21    digitalWrite (7, LOW);
22    break;
23}

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

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

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

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

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

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

Brat4791
Brat4791 аватар
Offline
Зарегистрирован: 13.02.2021

CRJ пишет:

Всем привет!

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

Суть такова:

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

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

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

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

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

4-е - ВЫКЛ.

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

01int switchPin = 8;
02int pwmPin = 11;
03boolean lastButton = LOW;
04boolean currentButton = LOW;
05int pwmLevel = 0;
06int led1 = 5;
07int led2 = 6;
08int led3 = 7;
09 
10void setup()
11{
12  pinMode(switchPin, INPUT_PULLUP);
13  pinMode(pwmPin, OUTPUT);
14  pinMode(led1, OUTPUT);
15  pinMode(led2, OUTPUT);
16  pinMode(led3, OUTPUT);
17}
18 
19boolean debounce(boolean last)
20{
21  boolean current = digitalRead(switchPin);
22  if (last != current)
23  {
24    delay(5);
25    current = digitalRead(switchPin);
26  }
27  return current;
28}
29 
30void loop()
31{
32  currentButton = debounce(lastButton);
33  if (lastButton == HIGH && currentButton == LOW)
34  {
35 
36    pwmLevel = pwmLevel + 85;
37  }
38 
39  lastButton = currentButton;
40 
41  if (pwmLevel > 255) pwmLevel = 0;
42  analogWrite(pwmPin, pwmLevel);
43   
44  switch (pwmLevel)
45  {
46    case 85:
47      digitalWrite (led1, HIGH);
48      break;
49    case 170:
50      digitalWrite (led1, HIGH);
51      digitalWrite (led2, HIGH);
52      break;
53    case 255:
54      digitalWrite (led1, HIGH);
55      digitalWrite (led2, HIGH);
56      digitalWrite (led3, HIGH);
57      break;
58    default:
59      digitalWrite (led1, LOW);
60      digitalWrite (led2, LOW);
61      digitalWrite (led3, LOW);
62      break;
63  }
64}

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

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

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

 

возможно подробнее ознакомиться с проектом?

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

Сейчас на больничном, выйду на работу - выложу окончательный скетч.