Arduino code goed?

Evarist

Golden Member

ZIE ONDER.

Ik heb een schakeling met 4 schakelaars, 3 relais, en 3 analoge sensoren.
Ik wil hier een code voor schrijven en ben zo begonnen. Klopt dit?

code:

//CV. Caleffi kranen.
//
//

void setup() {
 pinMode(2, INPUT); // maak de 'pin' als ingang
 pinMode(3, INPUT); // maak de 'pin' als ingang
 pinMode(4, INPUT); // maak de 'pin' als ingang
 pinMode(5, INPUT); // maak de 'pin' als ingang
 pinMode(6, OUTPUT); // maak de 'pin' als uitgang
 pinMode(7, OUTPUT); // maak de 'pin' als uitgang
 pinMode(8, OUTPUT); // maak de 'pin' als uitgang
 int Buitensensor = 0;
 int Binnensensor = 0;
 int CVsensor = 0;

}

void loop() {
Buitensensor = analogread (0);
Binnensensor = analogread (1);
CVsensor = analogread (2);
Nihil est verum, quod non probatur primo.

Klopt zo te zien wel maar ik zou het als onderstaand beginnen, daar heb je verderop in je programma alleen maar gemak van omdat je dan niet iedere keer hoeft te kijken waar schakelaar 3 ook alweer aan vast hing. En als je de pinnen verandert, hoeft het nu nog maar op 1 plaats te gebeuren, anders zou je heel je programma weer door moeten spitten. Bovendien leest het makkelijker omdat je in 1 oogopslag ziet wat er gebeurt als je bv een analogRead doet:

c code:

#define BUTTON_1 2
#define BUTTON_2 3
#define BUTTON_3 4
#define BUTTON_4 5
#define REL_1 6
#define REL_2 7
#define REL_3 8
#define BUITEN_SENSOR 0
#define BINNEN_SENSOR 1
#define CV_SENSOR 2

int Buitensensor = 0;
int Binnensensor = 0;
int CVsensor = 0;

void setup() {
 pinMode(BUTTON_1, INPUT); // maak de 'pin' als ingang
 pinMode(BUTTON_2, INPUT); // maak de 'pin' als ingang
 pinMode(BUTTON_3, INPUT); // maak de 'pin' als ingang
 pinMode(BUTTON_4, INPUT); // maak de 'pin' als ingang
 pinMode(REL_1, OUTPUT); // maak de 'pin' als uitgang
 pinMode(REL_2, OUTPUT); // maak de 'pin' als uitgang
 pinMode(REL_3, OUTPUT); // maak de 'pin' als uitgang
}

void loop() {
Buitensensor = analogRead(BUITEN_SENSOR);
Binnensensor = analogRead(BINNEN_SENSOR);
CVsensor = analogRead(CV_SENSOR);

(NB: het is analogRead, met hoofdletter R erin)

Edit: Naar aanleiding van hieronder gelijk even de vars buiten setup{ } geplaatst.

Ik neem aan het programma nog niet voltooid is, maar er moet nog een sluitaccolade bij het einde van de loop.

De jacht is mooier dan de vangst....
Evarist

Golden Member

Klopt Vovpvi.

Bij het compileren is er een foutmelding.

code:

Arduino: 1.6.3 (Windows XP), Board:"Arduino Uno"


sketch_sep20a.ino: In function 'void loop()':

sketch_sep20a.ino:29:1: error: 'Buitensensor' was not declared in this scope

sketch_sep20a.ino:30:1: error: 'Binnensensor' was not declared in this scope

sketch_sep20a.ino:31:1: error: 'CVsensor' was not declared in this scope

Fout bij het compileren.

Moet er nergens aangegeven worden dat 'Buitensensor' een analoge input is en 'button_X' een digitale?

Nihil est verum, quod non probatur primo.

Dit heeft met de scope van je variabelen te maken.

Voorbeeld:

c code:


int a;

Functie1{

int b;

}

functie2{
int c;

}

De int a kun je in de beide functies gebruiken, omdat die in de bovenliggende functie is gedeclareerd. De b kun he niet uitlezen in functie 2, omdat hij lokaal aan functie 1 is, zelfde geld andersom met int c.

Daarom is de error ook dat hij de *sensor niet kan vinden in de scope. Je moet de int buiten,binnen,cvsensor dus voor de setup, of in de loop plaatsen.

Button_X is helemaal geen ingang, maar een define. Het is de plaatsvervanger voor het nummer van de ingang

[Bericht gewijzigd door Progger op zondag 20 september 2015 12:02:44 (15%)

GMT+1
Evarist

Golden Member

Dankje, Progger. Het zal nog wel even duren voor ik ook een progger wordt. :-)

Op 20 september 2015 10:44:27 schreef Evarist:

Moet er nergens aangegeven worden dat 'Buitensensor' een analoge input is en 'button_X' een digitale?

Blijft de vraag hoe de sketch onderscheid maakt tussen analoge ingang 2 en digitale input 2?

Nihil est verum, quod non probatur primo.

Dat onderscheid maak je zelf in je sketch. Jij vraagt namelijk digitalRead(2) wat gelijk is aan D2, of analogRead(2) en dat is dan weer vanzelf A2.

[Bericht gewijzigd door BVZ op zondag 20 september 2015 13:20:14 (18%)

Evarist

Golden Member

Dat is duidelijk, BVZ. Dankjewel.

Weer een vraagje.
Wat is hier fout?

code:

     if ( TheBo = HIGH && KraBo = HIGH){
    digitalWrite(REL_Ketel,HIGH) ;
}  

FOUT: error: lvalue required as left operand of assignment
in de regel met 'if'.

Nihil est verum, quod non probatur primo.

Typische instinker, heb er ook eens naar gezocht :)

Bij vergelijken moet je if(a==b) een dubbel is gelijk aan teken gebruiken.

Mijn thuis is waar mijn Weller staat
Evarist

Golden Member

De code werkt!! Bedankt.
Ik ben Basic gewoon. Dat is veel simpeler.
IF Thebo = 1 AND Krabo = 1 THEN RELKetel = 1

Nihil est verum, quod non probatur primo.

Voor mijn is basic lastiger dan C, ben bekend met C en niet met basic, kortom alles is makkelijk als je weet hoe het werkt.

Evarist

Golden Member

De code is inmiddels af, de bijbehorende print is gebouwd en op de testbank werkt de module.
Leuk, weer iets bijgeleerd.
-
-
Het betreft een sturing voor de CV. Er zijn 2 thermostaten en 2 zoneventielen, die gestuurd moeten worden.
De CV mag maar max 6x per uur aanslaan.
Er is een klimaatregeling voor de -nieuw aan te leggen- vloerverwarming.
Die laatste is nog niet in gebruik.

Ik wil iedereen bedanken die heeft meegedacht.

Nihil est verum, quod non probatur primo.
Evarist

Golden Member

Ik ben de code aan het uitbreiden voor de vloerverwarming en heb weer een fout, die ik niet begrijp.

code:

75  if ((StreefTemp - BuiTemp) * Stooklijn) + StreefTemp) > BinTemp - Hysterese
76   {(VV = 1);
77    digitalWrite(REL_VV,HIGH);
78    Value = 0;}

De fout code is

CV3.ino: In function 'void loop()':
CV3:75: error: expected ';' before ')' token
expected ';' before ')' token

Nihil est verum, quod non probatur primo.
Shiptronic

Overleden

aan begin maar 2x ( je eindigt met 3x) er mist dus een (

Dus:

code:



 if (((StreefTemp - BuiTemp) * Stooklijn) + StreefTemp) > BinTemp - Hysterese
     {(VV = 1);
      digitalWrite(REL_VV,HIGH);
      Value = 0;}

[Bericht gewijzigd door Shiptronic op maandag 12 oktober 2015 23:07:08 (61%)

Wie de vraag stelt, zal met het antwoord moeten leren leven.
Evarist

Golden Member

Dankje, Shiptronic, wat een stommiteit.

code:

   if (((StreefTemp - BuiTemp) * Stooklijn) + StreefTemp) > BinTemp - Hysterese
     {VV = 1;
      digitalWrite(REL_VV,HIGH);
      Value = 0;} 

Nu krijg ik als foutcode:

CV3.ino: In function 'void loop()':
CV3:75: error: expected primary-expression before '>' token
CV3:76: error: expected ';' before '{' token
expected primary-expression before '>' token

Nihil est verum, quod non probatur primo.
Shiptronic

Overleden

(bin temp -heytesese) , dus ook tussen haken ?

Wie de vraag stelt, zal met het antwoord moeten leren leven.
Evarist

Golden Member

code:

  if (((StreefTemp - BuiTemp) * Stooklijn) + StreefTemp) > (BinTemp - Hysterese)
     {VV = 1;
      digitalWrite(REL_VV,HIGH);
      Value = 0;}

Nog steeds foutcode.

CV3:81: error: expected primary-expression before '>' token

(regelnummers zijn anders door ingevoegde comment)

Edit// Zo heb ik geen foutcode meer.

code:

  if ((StreefTemp - BuiTemp) * Stooklijn) + StreefTemp > BinTemp - Hysterese;
     {VV = 1;
      digitalWrite(REL_VV,HIGH);
      Value = 0;}

[Bericht gewijzigd door Evarist op maandag 12 oktober 2015 23:27:50 (25%)

Nihil est verum, quod non probatur primo.
Shiptronic

Overleden

Wie de vraag stelt, zal met het antwoord moeten leren leven.
Evarist

Golden Member

Gratias tibi Domine Navistronic

[Bericht gewijzigd door Evarist op maandag 12 oktober 2015 23:44:46 (24%)

Nihil est verum, quod non probatur primo.

Ik vrees dat dat niet doet wat je wilt dat het doet.

Ik heb even geen Arduino omgeving bij de hand, maar ik lees:

c code:

if ( (StreefTemp - BuiTemp) * Stooklijn )
   +StreefTemp > BinTemp - Hysterese;
   {
   VV = 1;
   digitalWrite(REL_VV,HIGH);
   Value = 0; 
   }

Let op, in bovenstaande code heb ik precies staan wat je zelf zegt dat 'geen foutcode' geeft. Ik heb alleen de spatiëring gewijzigd.

Dus je doet een if op een berekening

c code:

 if ( (StreefTemp - BuiTemp) * Stooklijn )

en indien die berekening geen nul als uitkomst heeft (en alleen dan) voer je deze regel code uit:

c code:

+StreefTemp > BinTemp - Hysterese;

Dat is een unary + operator, die in de praktijk denk ik weinig zal doen, en dan blijft er een vergelijking over die ook weinig doet in z'n eentje.

Daarna komt een stuk code dat altijd wordt uitgevoerd, want de regel code direct na de if stond niet tussen blokhaken en nadat deze werd afgesloten met de puntkomma ; was de if-constructie dus klaar.
Dat je blokhaken gebruikt doet niet meer ter zake, die mag je volgens de syntax te pas en te onpas gebruiken maar impliceren niet zonder meer een afhankelijkheid van een if, while, etcetera.

Wat je lijkt te willen doen is dit:

c code:

if ( (((StreefTemp - BuiTemp) * Stooklijn) + StreefTemp) 
                                       > (BinTemp - Hysterese) ) 
{
     VV = 1;
     digitalWrite(REL_VV,HIGH);
     Value = 0;
}

Samenvatting van wat je hiervan op zou moeten steken:
De hele vergelijking van een if moet omvat worden door ronde haken.

Dus NIET:

c code:

if  (a-c)>(d*b)  //fout

maar:

c code:

if ((a-c)>(d*b)) //goed

Een vergelijking van een if-constructie moet niet afgesloten worden met een puntkomma. Alleen de regels die uitgevoerd moeten worden sluit je af met een puntkomma.

Door een combinatie van te weinig ronde haken viel een deel van jouw vergelijking buiten de te-evalueren-waarde van de if-constructie. Hier werd gelukkig een foutmelding door gecreëerd, maar doordat jij er al gokkend een puntkomma achter zette kon de compiler het deel van de vergelijking dat buiten de haken viel nu als een opdracht zien.

Accolades geven een blok code aan, maar als de voorgaande if (of while, for, etcetera) niet juist is geschreven, doen de accolades helemaal niets en worden ze genegeerd door de compiler.

If you want to succeed, double your failure rate.
Evarist

Golden Member

Op 13 oktober 2015 08:59:40 schreef Jochem: Heb geduld: alle dingen zijn moeilijk voordat ze gemakkelijk worden.

Dit is hier wel toepasselijk. Ik dacht dat ik nooit zou kunnen leren programmeren, maar het begint te gaan. Dank voor je uitgebreide uitleg.

~~~~~~~~~~~~

code:


  if ( TheBo == LOW && TheBe == LOW && VV == 0)
    {digitalWrite(REL_Ketel,LOW);

Voert deze code de opdracht "Rel_Ketel, Low" uit als aan alle 3 (en alleen dan) voorwaardes is voldaan?

Nihil est verum, quod non probatur primo.

Als je een accolade gebruikt moet je ze ook sluiten. Voor een IF-statement hoef je volgens arduino-reference geen accolades te gebruiken.

Met accolade

code:

if (TheBo == LOW && TheBe == LOW && VV == 0)
    {digitalWrite(REL_Ketel,LOW);}

Zonder accolade

code:

if (TheBo == LOW && TheBe == LOW && VV == 0)
    digitalWrite(REL_Ketel,LOW);
Depeet

Je code mist een accolade sluiten. Zorg dat je bij programmeren precies te werk gaat. Maak het jezelf gemakkelijk door haken en accolades mooi uit te lijnen.

c code:


  if ( TheBo == LOW && TheBe == LOW && VV == 0)
  {
    digitalWrite(REL_Ketel,LOW);
  }

Als je het zo schrijft, wordt digitalWrite uitgevoerd als de aan drie voorwaarden uit de if allemaal voldaan wordt.

edit: depeet typte net even sneller dan ik. Ik wil je aanraden de accolades altijd te gebruiken, OOK als het maar één instructie betreft. Zeker als beginnende programmeur is de kans om een instinker te maken groot:

c code:

  if ( TheBo == LOW && TheBe == LOW && VV == 0)
      digitalWrite(REL_Ketel,LOW);
      digitalWrite(Voorbeeld,HIGH);
      Serial.print("Het lijkt of deze regel alleen onder de if-voorwaarde wordt uitgevoerd");

  Serial.print("Deze regel is niet anders dan de twee code regels hierboven.");
If you want to succeed, double your failure rate.

Leer jezelf aan altijd accolades te gebruiken. Als je zonder accolades na bijvoorbeeld een if statement later nog een paar regels toevoegt gaat het mis, alleen de eerste regel wordt dan samen met de if gebruikt, de rest wordt gewoonweg altijd uitgevoerd.

Als je altijd de code netjes laat inspringen valt dat wel op maar ik ben van mening dat het een kleine moeite is om altijd accolades te gebruiken. Dat is ook duidelijker voor anderen die de code lezen.

Evarist

Golden Member

De accolade stond er, maar is weggevallen met de copy-paste.
Maar mijn vraag is beantwoord. Danku.

Nihil est verum, quod non probatur primo.