Вопрос по синтаксису

freeman86
Offline
Зарегистрирован: 07.09.2016
#define PUMP 5
#define LED 13
#define HUMIDITY 10
#define WATER_SENS A0

#define WATERING_MILSEK 3000

#define STATE_STANDBY 0
#define STATE_WATERING 1
#define STATE_NOWATER 2

void Blink();
void watering();
void humid();
boolean checkWater();
int state = STATE_STANDBY;

void setup() {
  pinMode(PUMP, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(HUMIDITY, INPUT);
  pinMode(WATER_SENS, INPUT); 
}
void loop() {
   switch (state){
    case STATE_STANDBY:
    checkWater == true;
    if(humid, false)
    state = STATE_WATERING;
    if(checkWater, false)
    state = STATE_NOWATER;
    break;
    
    case STATE_WATERING:
    watering();
    state = STATE_STANDBY;
    break;

    case STATE_NOWATER:
    Blink();
    state = STATE_STANDBY;
    break;  
    }
}


   boolean checkWater(){
     if(analogRead(WATER_SENS) >= 30)
     return true;
     else
     return false;
   }

   void humid(){
    if(digitalRead(HUMIDITY)== LOW)
  return true;
  else 
  return false;
   }

   void watering(){
  digitalWrite(PUMP, HIGH);
  delay(WATERING_MILSEK);
  digitalWrite(PUMP, LOW);
   }

   void Blink(){
  if(checkWater() == false){
    digitalWrite(LED, HIGH);
    delay(500);
    digitalWrite(LED, LOW);
    delay(500);
  }
  else { 
    digitalWrite(LED, LOW);
  }
 }

Код компилируется на Arduino IDE. На железе в действии еще не пробовал.

Вопрос: почему  void humid(), но boolean checkWater()? Разве эти функции не одно и то же? hmm 
На попытку сделать void checkWater() (в глобальной переменной тоже меняю), выводится следующая ошибка:

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:24:0,

                 from sketch\pump1_1.ino.cpp:1:

C:\Users\Администратор\Documents\Arduino\pump\pump1_1\pump1_1.ino: In function 'void Blink()':

pump1_1:68: error: invalid operands of types 'void' and 'bool' to binary 'operator=='

exit status 1
invalid operands of types 'void' and 'bool' to binary 'operator=='

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

У вас что память напрочь отсутствует. Так есть такое понятие объявление и описание функций . У вас они находятся в разных местах. Компилятор вам и говорит, что определили, то и описываете. 

#define PUMP 5
#define LED 13
#define HUMIDITY 10
#define WATER_SENS A0

#define WATERING_MILSEK 3000

#define STATE_STANDBY 0
#define STATE_WATERING 1
#define STATE_NOWATER 2

void Blink();
void watering();
void humid();//  <--- здесь вы объявили void humid();
boolean checkWater();  //  <--- здесь вы объявили boolean checkWater(); 
int state = STATE_STANDBY;
void setup() {
  pinMode(PUMP, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(HUMIDITY, INPUT);
  pinMode(WATER_SENS, INPUT);
}
void loop() {
  switch (state) {
    case STATE_STANDBY:
      checkWater == true;
      if (humid, false)
        state = STATE_WATERING;
      if (checkWater, false)
        state = STATE_NOWATER;
      break;

    case STATE_WATERING:
      watering();
      state = STATE_STANDBY;
      break;

    case STATE_NOWATER:
      Blink();
      state = STATE_STANDBY;
      break;
  }
}


boolean checkWater() { //  <--- а здесь вы определили checkWater()
  if (analogRead(WATER_SENS) >= 30)
    return true;
  else
    return false;
}

void humid() {//  <--- а здесь вы определили void humid();
  if (digitalRead(HUMIDITY) == LOW)
    return true;
  else
    return false;
}

void watering() {
  digitalWrite(PUMP, HIGH);
  delay(WATERING_MILSEK);
  digitalWrite(PUMP, LOW);
}

void Blink() {
  if (checkWater() == false) {
    digitalWrite(LED, HIGH);
    delay(500);
    digitalWrite(LED, LOW);
    delay(500);
  }
  else {
    digitalWrite(LED, LOW);
  }
}

 

freeman86
Offline
Зарегистрирован: 07.09.2016

Спасибо! Я новичок, раньше никогда и ни на чем не писал, в принципе и этот код структурно взять у тех, кто умеет писать на C. :)

Объясните пожалуйста, что не так я сделал? Если я правильно понимаю, то объявление переменной нужно чтобы инициализировать ее, отвести память и т.д., о определение, это описание того, как должна вычисляться эта переменная. Так? 

 

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

Видишь ли. Есть язык Си и его синтаксис. А вот "БИБЛИЯ СИ"http://www.programming1189.ru/files/Kern_Ritch.pdf      Страница 32 прототип функции

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

qwone пишет:

Видишь ли. Есть язык Си и его синтаксис. А вот "БИБЛИЯ СИ"http://www.programming1189.ru/files/Kern_Ritch.pdf      Страница 32 прототип функции

Я ему тут начал объяснять http://arduino.ru/forum/proekty/avtomaticheskii-poliv-komnatnykh-tsvetov#comment-254836

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

там еще шедевр то в строках 27-30.

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

А что говорить, каждый новичок думает, что можно программировать можно наобум. А вот есть стандарт Си и нормы программирования. И любое отклонение от этого превращает программу если не в "говнокод", то в нерабочую малопонятную ересь.

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

freeman86 пишет:

Вопрос: почему  void humid(), но boolean checkWater()? Разве эти функции не одно и то же? hmm

https://www.youtube.com/watch?v=uF4cvLECgbA :)

freeman86
Offline
Зарегистрирован: 07.09.2016

Во-первых, я не наврал и этот скетч компилируется. Причем, на двух разных компах, один ХР, второй 10, и на обоих компилируется. Могу видео записать как я копирую отсюда скетч в IDE и он там откомпилируется. 

Во-вторых, вы наверное уже родились со знаниями языка С, но не всем так повезло в жизни. И я пытаюсь понять и разобраться, сделать работающую систему. Я задал вопрос почему: почему когда я объявляю checkWater(); как void и соответсвенно меняю в самой функции на void, то скетч не компилируется, а когда boolean, то все работает. При этом такая же на вид функция  humid(); объявлена как void и в описании тоже  void и на нее компилятор не ругается.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Вам надо почитать про функции
Обьявляя  функцию boolean checkWater()имеется в виду что она вернет значение типа boolean, что она и делает "return true;"
А когда обьявляем void humid() это значит что функция значений не возвращает "void" а Вы пытаетесь вернуть "return true;" отсюда и ошибка.
Но ошибки у Вас не только здесь!
Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

vosara пишет:

Вам надо почитать про функции

Ему в первую очередь надо почитать про типы данных. Не важно, функция это или переменная.

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

freeman86 пишет:

Объясните пожалуйста, что не так я сделал? 

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

Возьмите чужой текст на корейском и попытайтесь с его помощью объяснить корейцу что Вам от него нужно. Вот примерно этим Вы сейчас и занимаетесь.

freeman86
Offline
Зарегистрирован: 07.09.2016

Это я понимаю! Мне объяснили и потом я прочитал что Void - это функция которая ничего не возвращает.

Но в данном случае я не понимаю, почему тот код который в шапке компилируется, если void humid(), а не boolean, хотя должно быть именно так?

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

freeman86 пишет:

Это я понимаю! Мне объяснили и потом я прочитал что Void - это функция которая ничего не возвращает.

Из данной фразы следует, что Вы на самом деле ни хрена не понимаете.

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

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

freeman86 пишет:

Во-первых, я не наврал и этот скетч компилируется. Причем, на двух разных компах, один ХР, второй 10, и на обоих компилируется. Могу видео записать как я копирую отсюда скетч в IDE и он там откомпилируется. 

Версию IDE озвучте пожалуйста.

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

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

freeman86 пишет:

Это я понимаю! Мне объяснили и потом я прочитал что Void - это функция которая ничего не возвращает.

Из данной фразы следует, что Вы на самом деле ни хрена не понимаете.

мне кажется, что и я перестаю что то понимать

ВОТ ЭТО, действительно компилируется !

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  boolean b = false;
  if(b, false) {
    digitalWrite(LED_BUILTIN, HIGH);        
  } else {
    digitalWrite(LED_BUILTIN, LOW);    
  }
}

void loop() {
}

Хорошо хоть, что не работает !

 

freeman86
Offline
Зарегистрирован: 07.09.2016

Версие разные, 1.6.13 и последняя. Вот видите,  а говорили что я наврал!

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

freeman86 пишет:

Версие разные, 1.6.13 и последняя. Вот видите,  а говорили что я наврал!

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

И не важно, что вы там меняете, не ведая зачем это, void или boolean.

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

Хотя о чем я...

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

xDriver пишет:

мне кажется, что и я перестаю что то понимать

ВОТ ЭТО, действительно компилируется !

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  boolean b = false;
  if(b, false) {
    digitalWrite(LED_BUILTIN, HIGH);        
  } else {
    digitalWrite(LED_BUILTIN, LOW);    
  }
}

void loop() {
}

А почему нет? Что конкретно здесь не должно компилироваться? Это бессмыслица, но синтаксически правильная.

Да и, почему сосбственно не работает? Работает в точности как написано. Эквивалетно следующему:

void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
   digitalWrite(LED_BUILTIN, LOW);    
}

void loop() {
}

 

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

Да, нет, xDriver, нормально всё в первом посте. Бред, конечно, но синтаксически правильный бред, а потому совершенно спокойно компилируется. С ворнингом, но компилируется. Вы слишком высокого мнения о строгости этого языка. тут и не такое компилируется.

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

Я щас, для себя, опять Америку открою !

то есть в операторе if, через запятую, можно условия писать ?

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

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

Да, нет, xDriver, нормально всё в первом посте. Бред, конечно, но синтаксически правильный бред, а потому совершенно спокойно компилируется. С ворнингом, но компилируется. Вы слишком высокого мнения о строгости этого языка. тут и не такое компилируется.

и строка 27 тоже норма ?

У меня 1.8.0 не компилит.

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

xDriver пишет:

и строка 27 тоже норма ?

У меня 1.8.0 не компилит.

Значит у Вас там стоит опция "считать предупреждения ошибками". У меня (1.8.1) выдаёт предупреждение

C:\Users\Admin\Google Диск\Soft\kaka1\kaka1.ino:27:16: warning: statement has no effect [-Wunused-value]

Но компиляцию доводит до конца.

-------------------------

Про условия.

Нет, конечно, через запятую условия не пишутся, но здесь это рвссматривается как "операция запятая".  Операнды вычисляются слева направо. Результатом операции является результат самого правого из операднов. Любой операнд, кроме самого правого имеет право быть чем угодно, хоть void, т.к. результаты всех операндов, кроме самого правого игнорируются, а выполняются они исключительно для побочного эффекта. Например,

а = (100500 + 2 , 10 > 3);

В скобках "операция запятая". Первый операнд "100500+5" выполнится, и его результат будет выброшен. а переменная a получит значение - результат выполнения второго операнда "10 > 3", т.е. true.

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

Поставил 1.8.1 - скетч скомпилировался 0_0.

Я просто в шоке, ТС прошу прощения за необоснованное обвинение.

Евгений, Вам огромное спасибо за лекбез, сижу на Дельфях, С использую только для микроконтролеров.

ну знаете, волосы дыбом встают от того, что этот "компилятор" пропускает такое

void humid(){
  if(digitalRead(HUMIDITY)== LOW)
    return true;
  else 
    return false;
}

как это дело стек не рушит ?

 

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

А он результат через регистры передаёт. Т.е. эта функция пихает свой результат в регистры. Внешней (вызывающей) функции это пох, т.к. она не ждёт никакого результат от void-функции. Ну а этой функции пох, что той (вызывающей) пох - она кладёт себе и кладёт. Вот так и живём :)

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

Нет, это шедевр !

void setup() {
  Serial.begin(9600);
  int i = f1();
  boolean b = f2();

  Serial.println(i);
  Serial.println(b);

  
}
void loop() {
                
}
int f1() {
  return "Hello";
}

boolean f2() {
  return "Hello";
}


Компилируется и работает ! 

i=275, b=1 не зависимо что писать в return.

но на такое объявление ругается

float f3() {
  return "Hello";
}

где логика ? я х.з.

 

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Поэтому когда у меня сомнения возникают в синтаксисе, я пытаюсь подобную конструкцию в MS Visual Studio проверить, там компилятор строгий, он все ошибки вылавливает. Те, которые Ардуино пропускает.

А вообще грустно это. Не научится начинающие на Ардуино хорошему стилю программирования при таком количестве ошибок, которые компилятор пропускает. Взять хоть простеюшую = вместо == в условиях If. Visual Studio ругается, а Ардуино берет и даже не возмущается. А начинающему программисту и невдомек, что он вместо того, чтобы сравнить, он просто присвоил значение переменной и получил результатом true. Особенно если до этого он Бейсик или Паскаль изучал.

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

AlexeySh пишет:

Поэтому когда у меня сомнения возникают в синтаксисе, я пытаюсь подобную конструкцию в MS Visual Studio проверить, там компилятор строгий, он все ошибки вылавливает. Те, которые Ардуино пропускает.

Си вырос из ассембера. В некотором смысле это и есть ассемблер, который не заточен под процессор и платформу.Да к нему добавили элементы языка высокого уровня. И как ни странно такая кострукция не умерла. Да же больше всего ей стали "подражать". Потом к этой куче добавили элементы ООП. Но теперешнее поколение программистов шокирует, что и как. Это же великий язык, а не какой-то нафиг "ассембер". И компилятор языка Си работает как компилятор ассемблера. Хотя бы потому что это и есть компилятор ассемблера, только развившийся немножко.

И конструкция #define это конструкция из ассемблера.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

xDriver пишет:

Нет, это шедевр !


int f1() {
  return "Hello";
}

boolean f2() {
  return "Hello";
}

А Вы думали чо, в Дельфийскую сказку попали?  Это Си (Спарта). 

В первом случае отдается адрес строки, где компилятор расположил "Hello" (274). Потому что строка в Си - указатель (адрес) её первого символа.  

Во втором тот же адрес неявно преобразуется в bool  0 или 1.  Так как адрес не нулевой, то b=1, потому что в Сишном bool  true (1) - это всё что не ноль. 

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

AlexeySh пишет:

Поэтому когда у меня сомнения возникают в синтаксисе, я пытаюсь подобную конструкцию в MS Visual Studio проверить, там компилятор строгий, он все ошибки вылавливает. Те, которые Ардуино пропускает.

А вообще грустно это. Не научится начинающие на Ардуино хорошему стилю программирования при таком количестве ошибок, которые компилятор пропускает. Взять хоть простеюшую = вместо == в условиях If. Visual Studio ругается, а Ардуино берет и даже не возмущается. А начинающему программисту и невдомек, что он вместо того, чтобы сравнить, он просто присвоил значение переменной и получил результатом true. Особенно если до этого он Бейсик или Паскаль изучал.

А пишите  if (5==i) например.  Присвоить не удасться, если одно '=' забыл.  

У мня такая привычка вбилась в мосх со времен Turbo C++ 5.0.  Правда, я с тех пор в С и не программировал.  

До Ардуино. 

 

AlexeySh
Offline
Зарегистрирован: 16.01.2017

А если нужно две переменные сравнить? Мне такая запись не нравится. Привык слева переменную, а справа число писать. И начинающим программистам это точно не поможет.

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

Ну, вообще-то стандарт Си требует такую конструкцию пропускать, так что Visual Studio здесь не права.

В этом смысле несколько удивляет выбор языка Си для Ардуино. Си - язык в принципе не для начинающих, как об этом заявляют и сами разработчики языка.

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

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

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

qwone пишет:

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

Динозавры не динозавры, я не берусь судить, но коль делаете "мутантов", хоть генетичекий код оставте в покое, с точки зрения медицины, я понимаю, звучит чудовищно, но тут коль "наследуете" не "перезагружайте".

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

надо Паскаль к AVR присобачить.  Для начинающих - самое то. 

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

DetSimen пишет:

надо Паскаль к AVR присобачить.  Для начинающих - самое то. 

Точно, и еще Jav-у и HTML, и ...

И, да, мне еще "голосовое"  управление, на pin13.

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

DetSimen пишет:

надо Паскаль к AVR присобачить.  Для начинающих - самое то. 

Таки есть.

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

andriano пишет:

Ну, вообще-то стандарт Си требует такую конструкцию пропускать, так что Visual Studio здесь не права.

Так он вроде пропускает, только с предупреждением. Не удивлюсь, если и местный gcc поступает также, просто в IDE по умолчанию предупреждения выключены, чтобы чайников не пугать - здоров им помогли :)

freeman86
Offline
Зарегистрирован: 07.09.2016

Прислушался к советам и стал изучать С. В том числе и взялся за что-то по-проще, прежде чем доделывать поливалку. 

Поскольку я могу тут задавать вопросы по синтаксису, то это и сделаю )

if(analogRead(R) <= 340){
  digitalWrite(LED_1, HIGH);
  }
  else{
    digitalWrite(LED_1, LOW);
  }
if(analogRead(R) >= 341 ){     // начало
  digitalWrite(LED_2, HIGH);
  }
   else if(analogRead(R) <= 681){
    digitalWrite(LED_2, LOW);   // конец
    }
if(analogRead(R) >= 682){
  digitalWrite(LED_3, HIGH);
}
else{
  digitalWrite(LED_3, LOW);
}

Вопрос такой. Правильно ли я реализовал напротив меток "начало" и "конец" диапазон в котором должен зажигаться и гаснуть светодиод, или есть другой, более правильный способ? Цифры 341 и 681 показания с потенциометра, при которых должен гореть светодиод, а вне их гаснуть. 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

if(analogRead(R) >= 341 && analogRead(R) <= 681 ) { 
  что то делаем
  }

 

freeman86
Offline
Зарегистрирован: 07.09.2016

Спасибо. Я чувствовал что тут нужно что-то хитрое типа "и"-"или", но думал что они работают только с 0 или 1 :)

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

Есть различие в & и &&  , а так же |  и || . Так что в if ставьте удвоенное .

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

Valera19701 пишет:


if(analogRead(R) >= 341 && analogRead(R) <= 681 ) { 
  что то делаем
  }


int val = analogRead(R); // один раз считываем напряжение медленной функцией  analogRead()

if(val ....) // а теперь вешаем сколько нужно проверок/сравнений/обработок 
freeman86
Offline
Зарегистрирован: 07.09.2016

А в чем различие на практике?

В смысле, &, && и |, || это не одно и тоже? 

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

Нет, не одно. Вы, что сами не видите? До двух считать не можете? Разумеется, это разные вещи.

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

freeman86 пишет:

А в чем различие на практике?

В смысле, &, && и |, || это не одно и тоже? 

"Важно различать логический оператор "И" - && и битовый оператор "И" - &. Тоже самое относится к логическому оператору "ИЛИ" - || и битовому оператору "ИЛИ" - |."

http://arduino.ru/Reference/Boolean

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

И что бы запутать ТС полностью  есть & var ,  var1 & var2. так первое это не побитная операция.

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

Ну, блин, набросились. Ну тогда ещё расскажите про ленивую логику и различие в порядке вычисления операндов :)

freeman86
Offline
Зарегистрирован: 07.09.2016

Что окончательно запутать ТС, расскажите  чем в ардуино отличается bool и boolean? :) 

Прежде чем я задал этот вопрос, я погуглил, и там в основном говорят что это одно и то же.

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

Не знаю. Но пользуюсь bool он короче.:)

AlexeySh
Offline
Зарегистрирован: 16.01.2017

bool и boolean

Не помню точно какого, но переменная одного из этих типов может быть неопреденной null, а другого только true и false. В описании Ардуино упоминается только boolean. bool Ардуино унаследовал от языка C, там и ищите описание различий.