User Tools

Site Tools


tutorials:arduino:20_arduino_poo

Programació orientada a objectes

Podem distingir tres tipus de programació que han anat evolucionant al llarg del temps per buscar llenguatges de programació que ens donin programes més fàcils de entendre i que puguin créixer sense que sigui impossible trobar un pot estar el error, o com millorar una part del programa.

  1. Per salts, goto, JMP…
  2. Estructurada
  3. Orientada a objectes
  4. Funcional(està de moda, encara no acabe de comprendre-la).

La programació a evitar, la del goto, gosub… la dels salts es la primera programació que va haver, i que encara s'utilitza a sistemes com el Control Numerèric(GCODE), i en codi màquina que crea uns programes anomenats espagueti, com un plat d'espaguetis que no saps on comença, on acaba quants salts farà…

La programació orientada a objectes es un pas següent a la programació estructurada o script. La programació estructurada, que als autòmats es diu STL consisteix en:

  1. Sentències que es repeteixen una després de l'altra.
  2. Condicionals if, que fan la lògica del programa, decideixen el flux del programa.
  3. Funcions, subrutines, per subdividir el programa

(Als Autòmats tinguem el blocks(funcions) i el blocksFuncionals(Objectes, perquè tenen les seves dades), que converteix la programació d'autòmats es un sistema orientat a objectes

Per contra la programació orientada a objectes i la seva forma de treballar correctament, SOLID, perquè no només cal conèixer la sintaxis

A la programació orientada a objectes la classe es un on definim com seran els objectes. El objecte led1, led2… venen de la classe Led, les classes comencen per majuscula, i el objectes per minuscula, pot haver molts objectes d'una sola classe.

Quan definim una classe, aquesta ha de ser pensant en una maquina que compleix una funció. Per exemple un LED, i el seu control. Cal tenir sempre en compte quina funció fan els objectes d'aquesta classe.

Que volem fer? → Un LED intermitent 4._the_led_class_constructor---_coursemega.com_---.sub.en.vtt Quins atributs tindrà? → PIN per al LED

Quines funcions? → Inicialitzar-lo, on, off

Defincio

la classe es defineix com

class Led{

};

Atributs

La classe tindra un atributs, el que podriem dir com unes variables públiques, privades.

Es defineixen de la següent manera:

class Led{
private:
         byte _pin;
public:
         Led(byte pin){
         _pin=pin;
         }
};

Tinguem un variable privada, _pin, encara que no es cap norma a les variables locals solen posar la barra baixa al davant _pin.

Quan creem l'objecte passarem nombre de pin que utilitzarem, i això es una variable o atribut públic, i assigne la variable global a la local.

Com això es una cosa molt normal han creat el this, i pots posar el mateix nom a la variable local i publica. Així la variable pin, es publica en el moment que es passa i després passa a ser local.

class Led{
private:
         byte pin;
public:
         Led(byte pin){
         this->pin=pin;
         }
};

Podem fer tambè que si no posem cap pin per defecte agafi el 13.

class Led{
private:
         byte pin;
public:
         Led(){
         this->pin=13;
         }
         Led(byte pin){
         this->pin=pin;
         }
};

Aquest que hem fet també es diu el constructor, quan creen l'objecte led1 del tipus Led. Per fer una analogia, les classes son com el tipus de variable(int, byte) i el objecte es la variable en si mateix.

Led led1(5);

Ara farem les funcions on, off que en terminologia de objectes es diuen mètodes. Es a dir, les variables son atributs i les funcions son mètodes.

4._the_led_class_constructor---_coursemega.com_---.srt

Encara que més endavant veurem que les classes estan a arxius diferents si estan al mateix arxiu que el setup i loop cal que estigui al principi de tot en aquest cas compila sense cap error, si no et diu que la classe no està definida:

class Led{
private:
    byte _pin;
public:
    Led(){
    _pin=13;
    }
    
    Led(byte pin){
    _pin=pin;
	}
};

Led led1(5);
Led Led2();

void setup(){

}
void loop(){
}

Per cert a aquesta atribució de paràmetres al objecte també es diu construcció.

Mètodes

Ara afegirem el mètodes o funcions que son l'òrgan executiu del objecte-classe.

	void init(){
	pinMode(_pin,OUTPUT);
	}
	void init(byte defaultState){
	init();
	if (defaultState==HIGH) on();
	else off();
	}
	void on(){
	digitalWrite(_pin,HIGH);
	}
	void off(){
	digitalWrite(_pin,LOW);
	}

Podem veure que els mètodes son com les funcions, a més a més, funcions que poden tenir el mateix nom però diferents paràmetres com init() i init(HIGH), la primera només la inicialitza posant-la com entrada i la segona amb valor alt per defecte. La funció init, no confondre-la amb el constructor, el constructor es

Així quedaria la classe definida, amb atributs i mètodes.

Ara fare el blink amb aquesta classe Led

primer a partir de la classe Led creem l'objecte led1

 Led led1(5);
 

Després utilitzarem el mètode init() a dintre del setup(),

void setup(){
led1.init(LOW);
}

I al loop podem utilitzar els mètodes on i off

class Led{
private:
	byte _pin;
public:
    Led(){
    _pin=13;
    }

	Led(byte pin){
	_pin=pin;
	}

	void init(){
	pinMode(_pin,OUTPUT);
	}
	void init(byte defaultState){
	init();
	if (defaultState==HIGH) on();
	else off();
	}
	void on(){
	digitalWrite(_pin,HIGH);
	}
	void off(){
	digitalWrite(_pin,LOW);
	}
};


Led led1(13);


void setup(){
led1.init(LOW);

}
void loop(){
led1.on();
delay(500);
led1.off();
delay(500);
}

No funciona el init() sense cap valor, cal posar un valor encara que sigui el 13, a les solucions posa:

public:
  Led() {} // do not use

  Led(byte pin)
  {
    this->pin = pin;
  }

por ser no ho hagi entès be.

Organizacio en arxius .h .cpp

Les classes s'organitzen en arxius, un arxiu .h i un arxiu .cpp. El arxiu .h te el apartats private: i public: i aquí posem els atributs(variables), el constructor(valor per defecte de les variables), i les funcions(mètodes), Però les funcions o mètodes només els posem indicats, sense que tinguin res a dins, el contingut dels mètodes(funcions) van al .cpp, diguem-ne que el .h es el interface, entre la classe i la resta del programa.

El nom dels arxius es el mateix que el de la classe.

Creació del .h

Des de el mateix IDE d'Arduino podem crear un nou arxiu Led.h

Al tutorial comença amb

#ifndef LED_H
#define LED_H

#endif

El que fem es dir-li al precompilador que si no existeix LED_H aquesta es la classe Led, però si existeix…? es per no tindre dues classes amb el mateix nom.

Ara posarem el mateix que havíem posat abans, només que estarà al nou arxiu, normalment tallar-enganxar.

Però cal posar la llibreria interna <Arduino.h>, en main ja ho fa automàticament però en les classes no,

Recordem que les llibreries entre <> son del IDE i entre “” estan a la carpeta.

La idea es que el programa principal sigui el mes curt i clar possible i que tot el referent al Led quedi al objecte:

#include "Led.h"

#define LED_PIN 13

Led led1(LED_PIN);

void setup(){
led1.init(LOW);
}

void loop(){
led1.on();
delay(1000);
led1.off();
delay(500);
}

I al Led.h posarem la classe, que després veurem que es divideix en dos, la .h amb les declarasions i la cpp amb el algoritmes de les funcions o propietats.

#ifndef LED_H
#define LED_H
  
#endif
#include <Arduino.h> 


class Led{
private:
	byte pin;     //byte _pin;
public:
   	Led(byte pin){
	this->pin=pin; //_pin=pin;
	}

	void init(){
	pinMode(pin,OUTPUT);
	}
	void init(byte defaultState){
	init();
	if (defaultState==HIGH) on();
	else off();
	}
	void on(){
	digitalWrite(pin,HIGH);
	}
	void off(){
	digitalWrite(pin,LOW);
	}
};

Creació .cpp

Però el que hem fet no es correcte, l'arxiu .h es el que es coneix a la programació orientada a objectes l'interficie. Ha de contenir nomes la definició sense les {}, així quedaria:

Led.h
#ifndef LED_H
#define LED_H
 
#endif
#include <Arduino.h> 
 
 
class Led{
private:
	byte pin;     //byte _pin;
public:
        Led() {}      // dot not use
   	Led(byte pin);
	void init();  
	void init(byte defaultState);
	void on();
	void off();
};

El Led.cpp es el que te les funcions completes, Per dir que pertanyen a la classe Led:

Led.cpp
#include "Led.h"
 
Led::Led(byte pin){
  this->pin = pin;
}
 
void Led::init(){
  pinMode(pin, OUTPUT);
}
void Led::init(byte defaultState){
  init();
  if (defaultState==HIGH) on();
  else off();
  }
  void Led::on(){
  digitalWrite(pin,HIGH);
  }
  void Led::off(){
  digitalWrite(pin,LOW);
  }

I per últim el seria el main() de la programació tradicional, que aquí es el setup() i loop(), aquest arxiu ha de tenir el mateix nom que la carpeta.

Led_opp.ino
#include "Led.h"
 
#define LED_PIN 13
 
Led led1(LED_PIN);
 
 
void setup(){
led1.init(LOW);
}
 
void loop(){
led1.on();
delay(1000);
led1.off();
delay(500);
}
tutorials/arduino/20_arduino_poo.txt · Last modified: 2021/09/19 14:41 (external edit)