Проверка и небольшая помощь по коду.

Farmatsevt
Farmatsevt аватар
Offline
Зарегистрирован: 27.09.2018

Здравствуйте. Совсем недавно посетила меня идея сделать плавный автоматический свет для аквариума. Под рукой был какой-от таймер с али и маленькая на attiny85 ардуинка. Алгоритм работы программы таков:

Когда на timer_pin у нас 1 программа ничего не делает. Но вот таймер досчитывает до опр.  времени и опускает timer_pin в 0, начинается плавное наращивание якрости. После того как яркость достинает максимума, программа ничего не делает и ждет, когда таймер перестанет timer_pin укладывать в 0 и на нем снова появится 1. Когда это происходит, начинается плавное снижение яркости. 

Как сделать так, чтобы после того как яркость достигнет своего предела, ее можно бы было уменьшать и прибавлять с момощью двух кнопок? (одна, соответственно, на повышение, другая - на понижение). Также измененное значение ярксти должно сохранятся. 

В процессе проб и ошибок получилось аж два варианта кода. Какой из них более верный и в какой будет лучше внедрить вышеописанное? 

В программировании я, ну конечно же, новичок. Да и в целом гуманитарий. Меня в детстве математичка по голове транспортиром била. 

Вариант 1:

01#define led_pin 0
02#define timer_pin 4
03#define spd 20 //скорость наращивания яркости
04 
05float x;
06unsigned long timing;
07 
08void setup(){
09  pinMode(led_pin, OUTPUT);
10  pinMode(timer_pin, INPUT);
11  //Serial.begin(9600);
12}
13void loop(){
14  int y;
15  while((digitalRead(timer_pin) == 0) && (x < 255)){
16    if((millis() - timing) > spd){
17      x++;
18      y = 0.003921569 * pow(x, 2);
19      analogWrite(led_pin, y); //функция нелинейного наращивания яркости. Придумал не сам)
20      //Serial.println(y);
21      timing = millis();
22    }
23  }
24  while((digitalRead(timer_pin) == 1) && (x > 0)){
25    if((millis() - timing) > spd){
26      x--;
27      y = 0.003921569 * pow(x, 2);
28      analogWrite(led_pin, y);
29      //Serial.println(y);
30      timing = millis();
31    }
32  }
33}

Вариант 2: 

01#define led_pin 10
02#define timer_pin 7
03#define spd 20 //скорость наращивания яркости
04 
05float x;
06unsigned long timing;
07 
08void setup(){
09  pinMode(led_pin, OUTPUT);
10  pinMode(timer_pin, INPUT);
11  Serial.begin(9600);
12}
13void loop(){
14  int y;
15  while(1){
16    if((millis() - timing) > spd){
17      if((digitalRead(timer_pin) == 0) && (x < 255)){
18        x++;
19      }
20      else if((digitalRead(timer_pin) == 1) && (x > 0)){
21        x--;
22      }
23      y = 0.003921569 * pow(x, 2); //функция нелинейного наращивания яркости. Придумал не сам)
24      analogWrite(led_pin, y);
25      Serial.println(y);
26      timing = millis();
27    }
28  }
29}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Farmatsevt пишет:
Да и в целом гуманитарий. Меня в детстве математичка по голове транспортиром била.
И с чего вы решили, что если математичка вас была, то вы гуманитарий. Может Вы ,как его ,спортсмен- вас физрук пинками не загонял на турник.

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Код 2. while (строки 15 и 28) удалить. Вместо цифры 255 (максимум) сделать переменную, и её мотать кнопками.

Синтаксис записи:

1#include <EEPROM.h> // добавить наверху
2 
3byte x=EEPROM.read(addr); // чтение
4// addr = int, число не более размера EEPROM -1, можно просто 0
5 
6EEPROM.write(addr,x); // x = byte, запись

 

sadman41
Offline
Зарегистрирован: 19.10.2016

EEPROM.update() экономичней при верном использовании.

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

Farmatsevt пишет:
я, ну конечно же, новичок.
Не понимаю, почему "конечно", но у Вас вполне неплохо получается. Продолжайте работать и всё у Вас будет окей.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

я чутка придерусь ... :)

1if((digitalRead(timer_pin) == 0) && (x < 255))

зачем стока скобок ?

я не профи, может по стандартам чистого С оно так и надо, ЕвгенийП что скажите ?

SLKH
Offline
Зарегистрирован: 17.08.2015

xDriver пишет:

я чутка придерусь ... :)

1if((digitalRead(timer_pin) == 0) && (x < 255))

зачем стока скобок ?

я не профи, может по стандартам чистого С оно так и надо, ЕвгенийП что скажите ?

Чтобы ясно видеть, что написано именно то, что задумано. Для чайников вроде меня - вполне, на мой взгляд, приемлемо.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

SLKH пишет:
Чтобы ясно видеть, что написано именно то, что задумано. Для чайников вроде меня - вполне, на мой взгляд, приемлемо.

А теперь представим что существует замечательный отличный рабочий код под вашу задачу... на той же Ардуине и Вы в нем ничего не понимаете . А что делать? И как помогать Вам

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

xDriver пишет:

я чутка придерусь ... :)

1if((digitalRead(timer_pin) == 0) && (x < 255))

зачем стока скобок ?

я не профи, может по стандартам чистого С оно так и надо, ЕвгенийП что скажите ?

Лично я тоже так пишу. (разумеется, я бы написал if(!digitalRead(... - но это совсем другая история)

Хотя бы потому, что в различных языках установлен разный приоритет операций.

А скобки этот факт нивелируют.

И вообще, уж на что не следует скупиться, так это именно на скобки. Они снимают все возможные неоднозначности.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

ну не знаю, наверное дело привычки, но совсем параноидная запись

1if(((digitalRead(timer_pin) == 0) && (x < 255)))

для меня просто становится не читаемой.

b707
Offline
Зарегистрирован: 26.05.2017

xDriver пишет:

ну не знаю, наверное дело привычки, но совсем параноидная запись

1if(((digitalRead(timer_pin) == 0) && (x < 255)))

для меня просто становится не читаемой.

спор ни о чем

Я тоже пишу "совсем параноидально" - то есть в примере выше я именно так скобки и расставил бы.

На мой вгляд, если поставишь лишнюю пару скобок - это может кого-то насмешит, но ошибкой не станет. Недостаток скобок всегда хуже.

 

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

xDriver пишет:

ну не знаю, наверное дело привычки, но совсем параноидная запись

1if(((digitalRead(timer_pin) == 0) && (x < 255)))

для меня просто становится не читаемой.

Это Вы, наверное, на Лиспе не писали :)

sadman41
Offline
Зарегистрирован: 19.10.2016

Хакерам удалось украсть последние 50 МБ исходного кода программы на Lisp, которая управляет запуском баллистических ракет США. 
К счастью, там были только закрывающие скобки. (С)

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

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

Это Вы, наверное, на Лиспе не писали :)

нет, даже не "нюхал".

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

b707 пишет:

спор ни о чем

я не вижу ни малейшего намека на спор.

b707 пишет:

На мой вгляд, если поставишь лишнюю пару скобок - это может кого-то насмешит, но ошибкой не станет. 

так-же как и не станет ошибкой их отсутствие.

не исключаю, что это может кого-то расстроить.

Farmatsevt
Farmatsevt аватар
Offline
Зарегистрирован: 27.09.2018

Спасибо всем большое за ответы, не думал, что столько людей откликнется.

Вот что у меня получилось: 

01#define led_pin 10
02#define timer_pin 7
03#define spd 10
04 
05byte t = 255;
06float x;
07unsigned long timing;
08 
09void setup(){
10  pinMode(led_pin, OUTPUT);
11  pinMode(timer_pin, INPUT);
12  pinMode(3, INPUT);
13  pinMode(2, INPUT);
14  Serial.begin(9600);
15}
16void loop(){
17  byte y;
18  if(digitalRead(3) == 1){
19    delay(50);
20    t--;
21    x--;
22  }
23  else if((digitalRead(2) == 1) && (x < 255)){
24    delay(50);
25    t++;
26    x++;
27  }
28  if((millis() - timing) > spd){
29    if((digitalRead(timer_pin) == 0) && (x < t)){
30      x++;
31    }
32    else if((digitalRead(timer_pin) == 1) && (x > 0)){
33      x--;
34    }
35    y = 0.003921569 * pow(x, 2);
36    analogWrite(led_pin, y);
37    Serial.println(x);
38    timing = millis();
39  }
40}

Получилось примерно так. Теперь все как и положено: яркость можно регулировать кнопками. Но! Первый момент, как реализовать антидребезг и задержку (чтоб при малейшем нажатии у меня сразу в огромный минус переменные не уходили) у кнопок без delay? Я пытался туда millis заколхозить, но в итоге вышла ерунда полная и ничего не заработало. Второй момент, не получилось реализовать eeprom, так как при первом запуске программы t присваивется значение 255, а без этого, мне кажется, никак.

По поводу скобок. Я как-то недавно писал скрипт на php для вк (это был мой первый опыт в программировании) и меня по этому поводу один хороший человек консультировал, он-то как раз и порекомендовал мне эти скобки расставлять. С ними, на мой взгляд, код чуть лучше воспринимается на глаз, но тут уж кто как привык.

Farmatsevt
Farmatsevt аватар
Offline
Зарегистрирован: 27.09.2018

Эй, ну куда же вы все подевались( 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Программа у вас "не той системы". А все как реализовать уже написано мной не один раз и неоднократно. Просто повторяться надоедает.

Farmatsevt
Farmatsevt аватар
Offline
Зарегистрирован: 27.09.2018

Как понять "не той системы"? 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Написано на "кухаркином блинк программировании". Вот от туда и все проблемы растут. Зато код понятен как полено.

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

Farmatsevt пишет:

Как понять "не той системы"? 

Ну, как, так и понимать: https://www.youtube.com/watch?v=NHaPCiKwUq8

SLKH
Offline
Зарегистрирован: 17.08.2015

qwone пишет:

SLKH пишет:
Чтобы ясно видеть, что написано именно то, что задумано. Для чайников вроде меня - вполне, на мой взгляд, приемлемо.

А теперь представим что существует замечательный отличный рабочий код под вашу задачу... на той же Ардуине и Вы в нем ничего не понимаете . А что делать? И как помогать Вам

Если я ничего не понимаю в чужом отличном рабочем коде - Вы всё равно не сможете помочь, независимо от скобок. 

А в коде, написанный мной, в составных логических условиях будут "лишние" скобки - для наглядности и однозначности, ибо для моего уровня знакомства с языком такая запись надежнее

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

SLKH пишет:
ибо для моего уровня знакомства с языком такая запись надежнее.
И не только для Вашего - это просто надёжнее.