Arduino PLC?

algemene C code
Berichten: 147
Geregistreerd: 15 Dec 2012, 21:02
Woonplaats: Delfzijl

Arduino PLC?

Berichtdoor FPCUser » 07 Jan 2013, 23:40

Zoals reeds voorspeld zal m’n volgende bericht wel een vraag zijn en dat is het dus ook.
Microcontrollers zijn nieuw voor mij, PLC ’s echter niet. Zoals ik het nu kan bekijken zijn er echter veel overeenkomsten tussen beide. Daarom de vraag geteld, waarom een Arduino niet als een PLC te programmeren?
Nu kan je een PLC op diverse programmeren, zoals via een ladderdiagram (KOP/LD), functieblokken (FUP/FBD), AWL/ IL, SFC en Structured Text. Voor het maken van ladderdiagrammen voor microcontrollers heb ik het programma LDmicro gevonden. Deze kan een HEX file aanmaken om de controller te programmeren. Dit zou dan via de ICSP connector op de Arduino en een programmer te doen zijn. Dit is echter op dit moment veel te hoog gegrepen voor mij, afgezien de vraag of de gebruikte ATMega 328 chip van de UNO ook door het programma ondersteund wordt. Maar ik hou het programma in de gaten.
Mijn voorkeur gaat uit naar het programmeren via functieblokken. En dan op de manier van ArduBlock. Dat ziet er mooi uit. Gezocht op diverse manieren maar tot dusver geen geschikte bibliotheek gevonden voor de Arduino.
Maar als iemand wel wat weet……., ik hou me aanbevolen.

Maar goed, als je iets zoekt wat niet te vinden is moet je zelf maar aan de slag gaan.
Daarom een aantal C-classes gemaakt ( AND, NAND, OR, NOR, NOT, RS en SR-latch, enz)
Een mooie oefening voor een Pascal hobbyist om te programmeren in C!
Daarna een voorbeeld toepassing uit het Logo! Handboekje nagebouwd en…. het werkt warempel.

Mijn vraag is dan ook: is er een kant en klare bibliotheek voor de Arduino beschikbaar, om via functieblokjes de Arduino te programmeren, en zoja, waar?

Ik wil het in elkaar geprutst programma apart posten, in de hoop dat de meer geroutineerde C-programmeurs mij van nuttige tips voorzien.
Wellicht is dit dan niet de juiste rubriek hiervoor, maar dat kan de moderator beter bekijken.

Henk

Advertisement

Berichten: 147
Geregistreerd: 15 Dec 2012, 21:02
Woonplaats: Delfzijl

Re: Arduino PLC?

Berichtdoor FPCUser » 07 Jan 2013, 23:50

Hierbij het programma dat gebruikt maakt van functieblokjes.
Bovenin het programma zijn deze klassen aangemaakt, in het eigenlijke programma wordt een deel van deze functieblokjes als objecten gebruikt.
Het mij nog niet gelukt om een <naam>.h en <naam>.cpp bestand voor de klasse definities te maken, daarom is het programma relatief lang.
Dus hiervoor zijn tips welkom…

Het programma is een voorbeeldtoepassing uit LOGO! Handboek Siemens.

De toegang tot een fabrieksterrein wordt in vele gevallen met een poort afgesloten.
Die poort wordt alleen geopend wanneer voertuigen het terrein willen op- of afrijden.
De portier zorgt voor de bediening van de poort.
De poort wordt door het indrukken van een drukknop vanuit het portiershokje geopend en gesloten.
De portier kan daarbij de werking van poort controleren.
De poort wordt normaliter volledig geopend of volledig gesloten.
De beweging kan echter op elk ogenblik worden onderbroken.
Een waarschuwingsknipperlicht is 5 sec. voor het begin en tijdens de beweging van de poort ingeschakeld.
De veiligheidsdruklijst garandeert dat bij het sluiten van de poort niemand gewond wordt of geen zaken ingeklemd en beschadigd geraken.

Het logische schema zou ik als pdf file bijvoegen, maar dat mag blijkbaar niet.
Hiervoor nog een oplossing verzinnen.
Ik kan echter niet zo duidelijk tekenen als Rudi!


Henk


Code: Alles selecteren
//**************************************************************//
//  Naam        : Fabriekspoort
//  Auteur      : H. Heemstra
//  Datum       : 05-01-2013
//  Gewijzigd   :
//  Versie      : 0.1
//  Opmerkingen : test van een aantal functie's
//****************************************************************


/*****************************************************************
 LogicClasses
 Basis functies
 AND, NAND, OR, NOR met 4 ingangen
 XOR, XNOR met 2 ingangen
 NOT
 *****************************************************************/

/* Een algemene klasse v/e logische poort met 2 ingangen */
class T2InputGate {
protected:
  boolean _I1;
  boolean _I2;
public:
  void setI1(boolean Value) {
    if (Value != _I1)
      _I1 = Value;
  }
  void setI2(boolean Value) {
    if (Value != _I2)
      _I2 = Value;
  }
};

/* Een algemene klasse v/e logische poort met 4 ingangen
   Erft eerste 2 ingangen van bovenstaande
*/
class T4InputGate: public T2InputGate {
protected:
  boolean _I3;
  boolean _I4;
public:
  void setI3(boolean Value) {
    if (Value != _I3)
      _I3 = Value;
  }
  void setI4(boolean Value) {
    if (Value != _I4)
      _I4 = Value;
  }   
};

/* Samenvattng waarheidstabel poorten met 4 ingangen
        Ingangen                 Uitgang van elke poort
I1      I2      I3      I4     AND     NAND     OR     NOR
0       0       0       0       0       1       0       1
0       0       0       1       0       1       1       0
0       0       1       0       0       1       1       0
0       0       1       1       0       1       1       0
0       1       0       0       0       1       1       0
0       1       0       1       0       1       1       0
0       1       1       0       0       1       1       0
0       1       1       1       0       1       1       0
1       0       0       0       0       1       1       0
1       0       0       1       0       1       1       0
1       0       1       0       0       1       1       0
1       0       1       1       0       1       1       0
1       1       0       0       0       1       1       0
1       1       0       1       0       1       1       0
1       1       1       0       0       1       1       0
1       1       1       1       1       0       1       0
*/

/*////////////////////////////////////////////////////////////////////////////
/* De uitgang van AND gaat pas in stand 1 staan, als alle 4 ingangen
 de stand 1 hebben.
 Alle niet gebruikte ingangen worden standaard 'True' gezet.
*/
class TAND : public T4InputGate {
private:
  boolean _Q;
public:
  TAND() {
    _I1 = true;
    _I2 = true;
    _I3 = true;
    _I4 = true; 
  }
  boolean getQ() {
    return _Q = (_I1 && _I2 && _I3 && _I4);
  }
};

/*////////////////////////////////////////////////////////////////////////////
/* De uitgang van NAND krijgt slechts dan de stand 0, als alle 4 ingangen
 de stand 1 hebben.
 Een niet gebruikte ingang is standaard 'True' gezet.
 */
class TNAND : public T4InputGate {
private:
  boolean _Q;
public:
  TNAND() {
    _I1 = true;
    _I2 = true;
    _I3 = true;
    _I4 = true;
  }
  boolean getQ() {
    return _Q = !(_I1 && _I2 && _I3 && _I4);
  }   
};

/*////////////////////////////////////////////////////////////////////////////
/* De uitgang van de OR krijgt de stand 1, wanneer ten minste één ingang
 de stand 1 heeft.
 */
class TOR : public T4InputGate {
private:
  boolean _Q;
public:
  TOR() {
    _I1 = false;
    _I2 = false;
    _I3 = false;
    _I4 = false;   
  }
  boolean getQ() {
    return _Q = (_I1 || _I2 || _I3 || _I4);
  }
};

/*////////////////////////////////////////////////////////////////////////////
/* De uitgang van de NOR gaat pas in stand 1 staan, als alle 4 ingangen
   de stand 0 hebben.
*/
class TNOR : public T4InputGate {
private:
  boolean _Q;
public:
  TNOR() {
    _I1 = false;
    _I2 = false;
    _I3 = false;
    _I4 = false;   
  }   
  boolean getQ() {
    return _Q = !(_I1 || _I2 || _I3 || _I4);
  }
};

/*////////////////////////////////////////////////////////////////////////////
/* De uitgang van XOR gaat naar de stand 1 wanneer de ingangen
   verschillende standen hebben.
   
   I1      I2      Q
   0       0       0
   0       1       1
   1       0       1
   1       1       0
   
*/
class TXOR: public T2InputGate {
private:
  boolean _Q;
public:
  TXOR() {
  }
  boolean getQ() {
    return _Q = (_I1 && !_I2) || (_I2 && !_I1);     
  }
};

/*////////////////////////////////////////////////////////////////////////////
/* De uitgang van XNOR gaat naar de stand 0 wanneer de ingangen
   verschillende standen hebben.
   
   I1      I2      Q
   0       0       1
   0       1       0
   1       0       0
   1       1       1   
*/
class TXNOR: public T2InputGate {
private:
  boolean _Q;
public:
  TXNOR() {
  }
  boolean getQ() {
    return _Q = (_I1 || !_I2) && (_I2 || !_I1);     
  }
};

/*////////////////////////////////////////////////////////////////////////////
/* De uitgang gaat in stand 1 staan, als de ingang de stand 0 heeft.
   De NOT inverteert de stand van de ingang.

   I1      Q
   0       1
   1       0   
*/
class TNOT {
  private:
    boolean _I;
    boolean _Q;
  public:
    TNOT() {
    }
  void setI(boolean Value) {
    if (Value != _I)
      _I = Value;
  }
  boolean getQ() {
    return _Q = !_I;
  }     
};
/******************** Eind Basis functies **************************/



/*****************************************************************
 LogicClasses
 Speciale functies
 RS-Latch, SR-Latch, T-FF
 ODT (On delay timer), OFFDT (off-delay timer))
 *****************************************************************/

/*////////////////////////////////////////////////////////////////////////////
/* RS Latch
   Via een ingang S (Set) wordt de uitgang Q gezet.
   Via een andere ingang R (Reset) wordt de uitgang weer teruggezet.
   Bij gelijktijdig aanwezigheid van S en R is Reset dominand.
   
   S   R       Q
   0   0       -
   0   1       0
   1   0       1
   1   1       0
*/
class TRSFF {
  private:
    boolean _R;
    boolean _S;
    boolean _Q;
  public:
    TRSFF() {
    }
    void setR(boolean Value) {
      if (Value != _R)
        _R = Value;
    }
    void setS(boolean Value) {
      if (Value != _S)
        _S = Value;
    }
    boolean getQ() {
      return _Q = !_R && (_S || _Q);
    }
};

/*////////////////////////////////////////////////////////////////////////////
/* SR Latch
     Via een ingang S (Set) wordt de uitgang Q gezet.
     Via een andere ingang R (Reset) wordt de uitgang weer teruggezet.
     Bij gelijktijdig aanwezigheid van S en R is Set dominand.
 
      S  R       Q
      0  0       -
      0  1       0
      1  0       1
      1  1       1
*/
class TSRFF {
  private:
    boolean _R;
    boolean _S;
    boolean _Q;
  public:
    TSRFF() {
    }
    void setR(boolean Value) {
      if (Value != _R)
        _R = Value;
    }
    void setS(boolean Value) {
      if (Value != _S)
        _S = Value;
    }
    boolean getQ() {
      return _Q = (!_R && _Q) || _S;
    }
};

/*////////////////////////////////////////////////////////////////////////////
/* T-Flipflop (Pulse relais)
   Het instellen en terugzetten van de uitgang wordt bewerkstellgd door
   de ingang Trg gedurende een korte tijd 1 te maken.
   Ingang S (Set) zet de uitgang op 1. Ingang R (Reset) zet de uitgang op 0.
*/
class TTFF {
  private:
    boolean _Trg;
    boolean _R;
    boolean _S;
    boolean _Q;
  public:
    TTFF() {
    }
    void setTrg(boolean Value) {
      if (Value != _Trg)
        _Trg = Value;
    }
    void setR(boolean Value) {
      if (Value != _R)
        _R = Value;
    }
    void setS(boolean Value) {
      if (Value != _S)
        _S = Value;
    }
    boolean getQ() {
      return _Q = !_R &&  ((_Trg && !_Q) || (!_Trg && _Q) || _S);
    }
};

/*////////////////////////////////////////////////////////////////////////////
/* ODT (on-delay timer / vertraagd opkomend)
   Via de ingang Trg (Trigger) start de tijd voor de vertraagde inschakeling.
   Parameter T is de tijdsperiode in milliseconden, waarna de uitgang Q hoog wordt.
*/
class TODT {
  private:
    boolean _Trg;
    long _TimeValue;
    boolean _Q;
    long _previousMillis;
  public:
    TODT() {
    }
    void setTrg(boolean Value) {
      if (Value != _Trg) {
        _Trg = Value;
        _previousMillis = millis();
      }
    }
    void setTime(int Value) {
      if (Value != _TimeValue)
        _TimeValue = Value;     
    }
    boolean getQ() {
      unsigned long _currentMillis = millis();
      if (!_Trg)
        return _Q = false;
      else
        if(_currentMillis - _previousMillis >= _TimeValue)
          return _Q = true;
        else
          return _Q = false;
    }
};

/*////////////////////////////////////////////////////////////////////////////
/* OFFDT (off-delay timer / vertraagd afvallend)
   Via de ingang Trg (Trigger) start de tijd voor de vertraagde uitschakeling.
   Parameter T is de tijdsperiode in milliseconden, waarna de uitgang Q laag wordt.
*/
class TOFFDT {
  private:
    boolean _Trg;
    long _TimeValue;
    boolean _Q;
    long _previousMillis;
  public:
    TOFFDT() {
    }
    void setTrg(boolean Value) {
      if (Value != _Trg) {
        _Trg = Value;
        _previousMillis = millis();
      }
    }
    void setTime(int Value) {
      if (Value != _TimeValue)
        _TimeValue = Value;     
    }
    boolean getQ() {
      unsigned long _currentMillis = millis();
      if (!_Trg)
        return _Q = false;
      else
        if(_currentMillis - _previousMillis < _TimeValue)
          return _Q = true;
        else
          return _Q = false;
    }
};
/******************** Eind Speciale functies **************************/



/**************************** start programma fabriekspoort ************************/

// maak 6 ingangen en benoem deze
byte E00;  // Drukknop 'Openen'     NO = normaal open kontakt
byte E01;  // Drukknop 'Sluiten'    NO
byte E02;  // Drukknop 'Stop'       NC = normaal gesloten kotakt
byte E03;  // Eindschakelaar open   NC
byte E04;  // Eindschakelaar dicht  NC
byte E05;  // Veligheidsdruklijst   NC

// maak 3 uitgangen, benoem ze en koppel er een pin nummer aan
byte A00 = 11;  // Openen
byte A01 = 12;  // Sluiten
byte A02 = 13;  // Knipperlicht

// maak 11 objecten (functieblokjes) van het gewenste type
TNOT  B_01;
TNOT  B_02;
TAND  B_03;
TNAND B_04;
TAND  B_05;
TNAND B_06;
TRSFF B_07;
TRSFF B_08;
TODT  B_09;
TODT  B_10;
TOR   B_11;

void setup() {
  pinMode(A00, OUTPUT);
  pinMode(A01, OUTPUT);
  pinMode(A02, OUTPUT);
  B_09.setTime(5000);
  B_10.setTime(5000);
}

void loop() {
  // lees als eerste alle ingangen
  E00 = digitalRead(2);
  E01 = digitalRead(3);
  E02 = digitalRead(4);
  E03 = digitalRead(5); 
  E04 = digitalRead(6);
  E05 = digitalRead(7); 

  // Maak vervolgens het functiediagram.
  // Dit zijn de verbindingen tussen de functieblokjes onderling, en met de digitale in- en uitgangen
  B_01.setI(B_10.getQ());
 
  B_02.setI(B_09.getQ()); 
 
  B_03.setI1(B_01.getQ());
  B_03.setI2(E00);

  B_04.setI1(E02);
  B_04.setI2(E03);

  B_05.setI1(B_02.getQ());
  B_05.setI2(E01);

  B_06.setI1(E02);
  B_06.setI2(E04);
  B_06.setI3(E05);

  B_07.setS(B_03.getQ());
  B_07.setR(B_04.getQ());

  B_08.setS(B_05.getQ());
  B_08.setR(B_06.getQ());

  B_11.setI1(B_07.getQ());
  B_11.setI2(B_08.getQ());

  B_09.setTrg(B_07.getQ());

  B_10.setTrg(B_08.getQ());
 
  // stuur als laatste de uitgangen aan 
  digitalWrite(A00, B_09.getQ());
  digitalWrite(A01, B_10.getQ());
  digitalWrite(A02, B_11.getQ());
}

Gebruikers-avatar
Berichten: 698
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Arduino PLC?

Berichtdoor pjh » 08 Jan 2013, 00:36

Ik vind het een imposante 'vinger oefening'.
Wel grappig om in de Arduino IDE logische poorten te programmeren.
Wanneer je zo basaal bezig kunt zijn, dan zul je geen problemen hebben met C lijkt me.
Wat zou het grote voordeel van code blocken zijn? Eenvoud? Overzichtelijkheid?

Mij lijkt het ook voor de nieuwe generatie computeraars fijn als er betere grafische programmeeromgeveingen komen voor microcontrollers e.d. Wat dat betreft zijn mijn ogen op de raspberry pi gericht.

Berichten: 147
Geregistreerd: 15 Dec 2012, 21:02
Woonplaats: Delfzijl

Re: Arduino PLC?

Berichtdoor FPCUser » 08 Jan 2013, 10:17

Hierbij het beloofde functiediagram.
Dit zou het programma iets duidelijker moeten maken, alleen mijn afbeelding is nou niet je van het.

Henk
Bijlagen
img-0002.JPG
img-0002.JPG (32.65 KiB) 4724 keer bekeken

Gebruikers-avatar
Berichten: 698
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Arduino PLC?

Berichtdoor pjh » 08 Jan 2013, 22:37

wat is eigenlijk je doel / gedachte hiermee? Je kunt het zoveel eenvoudiger programmeren. Het is mooi, daar niet van, maar waar ligt een toepassing in het verschiet die kan "concurreren" met "normaal" programmeren?

Dit zou je in logische chips kunnen bouwen toch?

Berichten: 147
Geregistreerd: 15 Dec 2012, 21:02
Woonplaats: Delfzijl

Re: Arduino PLC?

Berichtdoor FPCUser » 09 Jan 2013, 13:32

@pjh (kan bijna zeggen: buurman, in woon in Delfzijl)

Je zou dit best in logische chips (b.v. CMOS) kunnen bouwen.
Nadeel zou zijn dat als je de schakeling wilt veranderen om wat voor redenen dan ook, je aan de slag moet met soldeerbout en draad. Je kunt je schakeling ook op een experimenteerbordje maken. Is eenvoudiger te wijzigen.
Maar het gaat softwarematig nog eenvoudiger, vrij programmeerbaar zeg maar.

Ook kan je een FPGA toepassen, deze zijn ook softwarematig aan te passen.

Het toepassen van logische poorten in een IDE om een programma te schrijven lijkt mij persoonlijk eenvoudiger dan in een programmeertaal. Hele volkstammen doen dit namelijk en niet voor niets. Je moet natuurlijk wel weten wat de functie van elk poortje is, maar een programmeertaal zoals C, C++ of Pascal moet je ook leren.

Ik vergelijk het wel eens met Lego blokjes. Om ze te maken heb je een grote fabriek nodig. Heb je ze eenmaal, dan kan een kind er mee spelen en complete miniatuurhuizen bouwen. Ze leren dan ook dat je ze op elkaar stapelt, het muurtje niet zo stevig is en makkelijk omvalt. Stapel je ze in een verband op, dan komt er stevigheid in. Met andere woorden, ze moet leren ze op een goede manier toe te passen. En dat geldt dus ook voor de logische poorten.

En er is in ieder geval al één grafische programmeer omgeving naar mijn weten: ArduBlock https://github.com/taweili/ardublock
Citaat website “ArduBlock is a Block Programming Language for Arduino. The language and functions model closely to Arduino Language Reference”. Het het is vol in ontwikkeling maar werkt heel behoorlijk. En als iets niet lukt dan ligt dat aan mij, ben tenslotte nog maar net bezig met de Arduino.

Tenslotte vraag je of er een concreet een toepassing in het verschiet ligt. Dat is niet het geval. Het was in de eerste plaats een oefening om de verschillen en overeenkomsten tussen C/C++ en Pascal te ontdekken. Ook was ik nieuwsgierig hoe een programma dat constant in een lus zit zich gedraagt ten opzichte van een z.g. 'event driven' programma.


Henk

Gebruikers-avatar
Berichten: 137
Geregistreerd: 06 Jun 2012, 15:45

Re: Arduino PLC?

Berichtdoor hmjswt » 09 Jan 2013, 14:54

Hallo Henk,

Het programma hoeft niet in een loop te zitten.
Je kunt ook buiten de loop programmeren.
En je kunt ook interrupts gebruiken om een event gedreven programma te maken.

Groet,
Henk Siewert
http://www.swtrocketry.com

Berichten: 147
Geregistreerd: 15 Dec 2012, 21:02
Woonplaats: Delfzijl

Re: Arduino PLC?

Berichtdoor FPCUser » 09 Jan 2013, 16:44

Henk,

Je hebt gelijk.
Je kunt inderdaad gebruik maken van Pin Change Interrupts om een 'event driven' programma te maken.
Daar had ik nog niet aangedacht.
Functies, procedures e.d. worden altijd al buiten de loop() geïmplementeerd maar je hoeft ze dus niet altijd vanuit de loop() aan te roepen zoals ik dacht.

Bedankt!

Op naar arduino-playground sectie

Henk

Gebruikers-avatar
Berichten: 698
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Arduino PLC?

Berichtdoor pjh » 12 Jan 2013, 21:29

Laat graag je vorderingen op dit terrein hier zien. Zag net een mooi filmpje op youtube van een dame die een 6510 chip (die van oa de commodore 64) van 0 opbouwt. Heel leerzaam. Die nu oude technieken combineren mooi met arduino's en ander laag frequente computers. Leuk allemaal. Paul

Berichten: 147
Geregistreerd: 15 Dec 2012, 21:02
Woonplaats: Delfzijl

Re: Arduino PLC?

Berichtdoor FPCUser » 13 Jan 2013, 11:54

Vorderingen gaan langzaam, maar gestaag. Ben er al in gelaagd de classes in z.g. Headerfiles buiten het programma te zetten, zodat het een stuk overzichtelijker uitziet. Ook zijn ze uitgebreid met een Up-Down counter.

Zojuist het boek “Microcontrollers en de taal C” van Wim Dolman aangeschaft. En daar gaat ook heel wat tijd inzitten, dus geduld a.u.b.

Henk

Volgende

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 0 gasten