ARDUINO ™ "HACK" PLC SIEMENS ™ LAN / WIFI INDUSTRIAL ETHERNET HÁLÓZAT: 10 lépés (képekkel)

ARDUINO ™ "HACK" PLC SIEMENS ™ LAN / WIFI INDUSTRIAL ETHERNET HÁLÓZAT: 10 lépés (képekkel)

Tartalomjegyzék:

Anonim

Ma megosztom veled, hogyan csatlakoztassa az Arduino-t PLC S7-300-mal Etherneten keresztül. Internetről is tanulmányoztam néhány olyan könyvtárat, amely képes kezelni ezt a kommunikációt, például:

  • MQTT-Siemens-S7-300
  • Settimino Könyvtár

A „settimino” könyvtárat választottam az Arduino és a PLC közötti kommunikáció tesztelésére, mivel profi és könnyen érthető. Ahhoz, hogy ezt a tesztet megkapjuk, bizonyos ismeretekkel kell rendelkeznie a PLC Siemens-ről, és természetesen elég pénzt kell költenie.

Vigyázat:

A projekt VIDEO alatt, a NODEMCU + MPU6050 közölni a PLC-n keresztül a WIFI-n keresztül, hogy szabályozza a sebesség / egyenáramú motor irányát.

kellékek:

1. lépés: ARDUINO LIBRARY & PLC SIEMENS

Dave Nardella - olasz - az ARM Linux / MIPS mikroprocesszorok és a PLC Siemens S7 ™ közötti két nagykönyvtár szerzője:

  • Snap7: A Snap7 egy cross-platform, nyílt forráskódú Ethernet kommunikációs könyvtár a Siemens PLC számára (LOGO 0BA7 / 0BA8, S7-200 / 300/400 és CPU 1200/1500) és a málna PI (1 és 2), BeagleBone Black … Link:

snap7.sourceforge.net/

  • Settimino: A Snap7-ről átírták, hogy kompatibilis legyen az Arduino platformtal.

settimino.sourceforge.net/

A PLC-ről a Siemens hivatalos honlapján olvashat:

  • A Siemens Global honlapja
  • SIMATIC S7-300 CPU 31xC technológiai funkciók
  • Az S7 CPU 31xC integrált funkciója "Impulzusszélesség moduláció"

2. lépés: B.O.M

A Bill Of Material az alábbi:

Fontos megjegyzés az Ethernet Shield-ről: A piros téglalap ellenállási értéke 49R9 vagy 510 (kb. 50 ~ 51 ohm), néhány Ethernet Shield esetén ez az érték 511 (510 ohm). Problémám van az 511 ellenállással, így nem tudok csatlakozni a PLC-hez, és végül R510-el kell vásárolnom egy újat, akkor a kapcsolat sikeres.

Két lehetőséggel teszteltem a PLC & Arduino kommunikációt:

  • ARDUINO UNO R3 ARDUINO Ethernet Shield R3-val felszerelt.
  • NodeMCU ESP 12-E V1.0 önálló és wifi útválasztón keresztül történő csatlakozás.

3. lépés: HARDWARE CONFIGURATION - ETHERNET SHIELD

Hardver konfiguráció - ARDUINO UNO R3, ARDUINO Ethernet Shield R3-val

Hardverkonfiguráció magyarázata:

  • Ezzel a konfigurációval szabadon módosíthatja mind a PLC programot, mind az adatokat és az Arduino vázlatot. A Snap7 ClientDemo opcionális.
  • Az Arduino IDE-ben a ConnectTo-t () használtuk az IP_Address, Rack, Slot az első kapcsolathoz, amely beállította a belső paramétereket és csatlakozik a PLC-hez.
  • A STEP 7 programban a PLC IP-címének (CP343-1) kell lennie az Arduino programban megadott címnek: 192.168.0.71. A részleteket lásd a képen.

Hardver konfiguráció a SIMATIC MANAGER-ben

Aktuális hardver demo készlet:

A fenti konfigurációval két vezérlő könnyen cserélhet adatokat egymással, például:

  • A PLC oldal az MPU-6050 adatait, a HC-SR05 olvasási távolságát vagy az RC-SERVO vezérlést kapja.
  • Az Arduino oldala a PT100 / termoelemek hőmérsékletét tudja olvasni, 24V-os közelségkapcsolók állapotát, vagy 220VAC lámpák be- és kikapcsolását.

4. lépés: PROGRAM - ETHERNET SHIELD

1. SETTIMINO LIBRARY

A linket letöltheti a következő helyen: Settimino Library, amely tartalmazza: könyvtár, részletes utasítások a settiminno könyvtár és a mintaprogramok használatára.

A kézikönyvben vegye figyelembe a "Big-Endian" és a "Little-Endian" kifejezéseket az ARDUINO ™ (Little -Endian) és a PLC Siemens S7 ™ (Big -Endian) közötti adatok olvasási és írási különbségeinek leírására.

  • Nagy –Egyes: MSB (bal oldali bit) -> LSB (jobb oldali bit), például DWORD 0x4C21112F a PLC Siemens S7 ™ készülékben a következőképpen tárolódik:

  • Kis Endian: LSB (bal oldali bit) -> MSB (jobb oldali bit), ugyanazzal a DWORD-szal, de az ARDUINO ™ a PLC-vel ellentétes módon tárolódik

2. PLC PROGRAM

A STEP 7 Professional 2010 V5.5 programot használtam a PLC hardver és írási programjának konfigurálásához. Ha Ön automata mérnök, akkor nagyon jól fog tudni róla …

A SIMATIC WinCC-t HMI / SCADA rendszerként is használhatja a Siemens S7 ™ PLC-k vagy az ARDUINO ™ vezérlésére.

A Settimino közvetlenül hozzáférhet a Siemens PLC-hez a beépített Ethernet formával (mint például a CPU 315-2PN / DP, CPU412-2PN / DP, CPU414-3PN / DP …) vagy egy különálló Ethernet kártya segítségével (például CP343 CPU S7 -300), vagy CP733 CPU S7-400 esetén). Az S7-300 CPU + CP343 esetében teszteltem.

3. ARDUINO PROGRAM

3.1. Arduino olvasott DB értékeket a PLC-től - „DBGetDemo”

  • A PLC programban létrehoztam a DB2-t, amely 100 bájtot tartalmazott, kezdeti értékekkel 0 ~ 99-ben rendezve.
  • A „DBGetDemo” 100 bájt értéket olvasott a DB2-ből, és megjelenítette az Arduino IDE soros monitorján.
  • Míg Arduino a DB2-t a PLC-ről olvasta, a "FORCE" funkciót használtam két DB2DBB0 & DB2.DBB1 bájt értékének megváltoztatására annak ellenőrzésére, hogy Arduino helyesen olvas-e.

A részleteket lásd:

3.2. Írjon a PLC adatblokkjába a 3. biztonsági szinten

Program áttekintés:

  • Engedélyezze a 3. biztonsági szintet (olvasás / írásvédelem) a CPU300 konfigurációban - majd fordítsa és töltse le a modult.
  • A PLC-ben létrehoztuk az 1 090 bájtnyi DB1-et (Data Block) KNOW_HOW_PROTECT (általánosságban ez a DB zárva van a Siemens terminológiájában).
  • A „WriteDemo” program írja be a kívánt értéket Arduino-ból a PLC-ben tárolt DB1.DBB0 & DB1.DBB1-be.
  • Változtassa meg a DB1 értékeket az Arduino program segítségével, és ellenőrizze a PLC DB1 online felügyeletét.

A részleteket ellenőrizheti:

5. lépés: HARDWARE CONFIGURATION - NODEMCU ESP 12-E V1.0

Hardverdiagram:

Aktuális rendszerkép:

A vezeték nélküli útválasztó az otthonomban helyezkedik el, körülbelül 15m távolságban, és nem jelenik meg a képen.

NodeMCU intergate MPU6050 képként:

Hardverkonfiguráció magyarázata:

  • A fenti képen 24VDC PLC kimenet kapcsolódik a "24V-tól 5V-os átalakítóhoz"a feszültségszint megváltoztatása és az egyenáramú motor vezérlése az L298N-en keresztül a PLC 314C-2DP PWM integrált funkciójával.
  • A NodeMCU + MPU6050-et wifi útválasztó csatlakoztatja a PLC rendszerhez tekercsérték az MPU6050-től az egyenáramú motor irányának és sebességének beállításához.
  • Ez a demo a CPU314C-2DP integrált PWM funkcióján alapul. Az impulzusszélesség-moduláció felhasználói programon keresztüli vezérléséhez SFB 49 "PULSE" -t használunk. A következő műveletek állnak rendelkezésre:
    • * SW_EN szoftverkapu indítása / leállítása.
    • * A kimenet DO engedélyezése / vezérlése.
    • * STS_EN, STS_STRT és STS_DO állapotbitek lekérése.
    • * A kimeneti érték bevitele.
    • * A regiszterek olvasására / írására szolgáló munkák.
  • E projekt kezdetétől az a célom, hogy egy olyan rezgésérzékelőt hozzunk létre, amely integrálható az ipari hálózatba, mint például: http://www.dytran.com/Series-7556A-Analog-6D-Sen… olcsó és hasznos vibrációs védelem vagy rezgéselemzéshez. A nagy teljesítményű motorral például a sebességváltóhoz csatlakoztatható, és 6DOF rezgési adatokat készíthet elemzéshez vagy felugró riasztáshoz a PLC rendszerhez, ha a rezgés magasabb, mint a határérték. Vagy használhatjuk azt hordozható elemző eszközként a megakadályozott karbantartáshoz. Ezzel a bemutatóval csak kezdőpont és elfogadható mintavételi idővel valósulhat meg.

6. lépés: ARDUINO PROGRAM - NODEMCU ESP 12-E V1.0

NodeMCU vezérlő PLC a Wifi hálózaton keresztül

  • /*----------------------------------------------------------------------
    Köszönöm Davide Nardellának
    ----------------------------------------------------------------------*/
    // Wifi -> #define S7WIFI
    // Kábel -> #Sefin S7WIRED
    #define S7WIFI
    #include
    #include
    #ifdef S7WIFI
    #include
    #endif
    #include "Settimino.h"
    #include
    // MPU6050 slave eszköz címe
    const uint8_t MPU6050SlaveAddress = 0x68;
    // Válassza ki az SDA és SCL csapokat az I2C kommunikációhoz
    const uint8_t scl = D1;
    const uint8_t sda = D2;
    // érzékenység skála tényező az adatlapon megadott teljes skála beállításnak megfelelően
    const uint16_t AccelScaleFactor = 16384;
    const uint16_t GyroScaleFactor = 131;
    // MPU6050 néhány konfigurációs regiszter-cím
    const uint8_t MPU6050_REGISTER_SMPLRT_DIV = 0x19;
    const uint8_t MPU6050_REGISTER_USER_CTRL = 0x6A;
    const uint8_t MPU6050_REGISTER_PWR_MGMT_1 = 0x6B;
    const uint8_t MPU6050_REGISTER_PWR_MGMT_2 = 0x6C;
    const uint8_t MPU6050_REGISTER_CONFIG = 0x1A;
    const uint8_t MPU6050_REGISTER_GYRO_CONFIG = 0x1B;
    const uint8_t MPU6050_REGISTER_ACCEL_CONFIG = 0x1C;
    const uint8_t MPU6050_REGISTER_FIFO_EN = 0x23;
    const uint8_t MPU6050_REGISTER_INT_ENABLE = 0x38;
    const uint8_t MPU6050_REGISTER_ACCEL_XOUT_H = 0x3B;
    const uint8_t MPU6050_REGISTER_SIGNAL_PATH_RESET = 0x68;
    int16_t AccelX, AccelY, AccelZ, Hőmérséklet, GyroX, GyroY, GyroZ;
    #define DO_IT_SMALL
    // Adja meg az alábbi MAC-címet és IP-címet a vezérlőhöz.
    // Az IP-cím a helyi hálózattól függ:
    byte mac = {
    0x90, 0xA2, 0xDA, 0x0F, 0x08, 0xE11};
    IPAddress Local (192,168,0,70); // Helyi cím
    IPAddress PLC (192,168,0,71); // PLC cím
    A következő konstansok szükségesek, ha WIFI-n keresztül csatlakozik
    // Az ssid a WIFI-hálózat neve (a jelszó nyilvánvalóan rossz)
    char ssid = "FPT-Telecom"; // A hálózati SSID (név)
    char pass = "12345689"; // A hálózati jelszó (ha van)
    IPAddress átjáró (192, 168, 0, 1);
    IPAddress alhálózat (255, 255, 255, 0);
    int DBNum = 2; // A DB-nek jelen kell lennie a PLC-ben
    bájt puffer 512;
    #ifdef S7WIFI
    // S7Client egy WiFiClient-et hoz létre TCP kliensként
    S7Client ügyfél (_S7WIFI);
    #más
    // Az S7Client EthernetClient-et hoz létre TCP kliensként
    S7Client ügyfél (_S7WIRED);
    #endif
    nem jelölt hosszú Eltelt; // A végrehajtási idő kiszámításához
    //----------------------------------------------------------------------
    // Beállítás: Init Ethernet és soros port
    //----------------------------------------------------------------------
    érvénytelen beállítás () {
    // Soros kommunikáció megnyitása és várjon a port megnyitásához:
    Wire.begin (sda, scl);
    MPU6050_Init ();
    Serial.begin (9600);
    míg (! Soros) {
    ; // várjon, amíg a soros port csatlakozik. Csak Leonardo esetében szükséges
    }
    #ifdef S7WIFI
    // --------------------------------------------- ESP8266 inicializálás
    Serial.println ();
    Serial.print ("Csatlakozás");
    Serial.println (SSID);
    WiFi.begin (ssid, pass);
    WiFi.config (helyi, átjáró, alhálózat);
    míg (WiFi.status ()! = WL_CONNECTED)
    {
    késleltetés (500);
    Serial.print ("");
    }
    Serial.println ("");
    Serial.println ("WiFi csatlakozik");
    Serial.print ("Helyi IP-cím:");
    Serial.println (WiFi.localIP ());
    #más
    // -------------------------------- Vezetékes Ethernet védelem inicializálása
    // Indítsa el az Ethernet könyvtárat
    Ethernet.begin (mac, Local);
    // Beállítási idő, valaki azt mondta, hogy elhagyom a 2000-et, mert néhány
    // a szemét kompatibilis táblák egy kicsit süket.
    késleltetés (2000);
    Serial.println ("");
    Serial.println ("Kábel csatlakoztatva");
    Serial.print ("Helyi IP-cím:");
    Serial.println (Ethernet.localIP ());
    #endif
    }
    //----------------------------------------------------------------------
    // Csatlakozik a PLC-hez
    //----------------------------------------------------------------------
    Bool Connect ()
    {
    int Eredmény = Client.ConnectTo (PLC,
    0, // Rack (lásd a dokumentumot)
    2); // Slot (lásd a dokumentumot)
    Serial.print ("Csatlakozás"); Serial.println (PLC);
    ha (Eredmény == 0)
    {
    Serial.print ("Connected! PDU Length ="); Serial.println (Client.GetPDULength ());
    }
    más
    Serial.println ("Kapcsolati hiba");
    Vissza eredmény == 0;
    }
    //----------------------------------------------------------------------
    // Egy puffert (nagyon durva rutin) dob
    //----------------------------------------------------------------------
    érvénytelen Dump (void * Buffer, int Length)
    {
    int i, cnt = 0;
    pbyte buf;
    ha (puffer! = NULL)
    buf = pbyte (puffer);
    más
    buf = pbyte (& PDU.DATA 0);
    Serial.print ("Dumping"); Serial.print (Length);
    Serial.println ("bytes ==========================");
    a (i = 0; i
    {
    cnt ++;
    ha (buf i <0x10)
    Serial.print ("0");
    Serial.print (buf i, HEX);
    Serial.print ("");
    ha (cnt == 16)
    {
    cnt = 0;
    Serial.println ();
    }
    }
    Serial.println ("============================================= == ");
    }
    //----------------------------------------------------------------------
    // Kinyomtatja a hibaszámot
    //----------------------------------------------------------------------
    érvénytelen CheckError (int ErrNo)
    {
    Serial.print (0x hiba);
    Serial.println (ErrNo, HEX);
    // Ellenőrzi, hogy ez egy súlyos hiba => meg kell szakítanunk
    ha (ErrNo & 0x00FF)
    {
    Serial.println ("SEVERE ERROR, disconnecting.");
    Client.Disconnect ();
    }
    }
    //----------------------------------------------------------------------
    // Profilozási rutinok
    //----------------------------------------------------------------------
    érvénytelen MarkTime ()
    {
    Eltelt = Millis ();
    }
    //----------------------------------------------------------------------
    érvénytelen ShowTime ()
    {
    // Az időt kalkulálja
    Eltelt = Millis () - Eltelt;
    Serial.print ("Munkaidő (ms):");
    Serial.println (Eltelt);
    }
    //----------------------------------------------------------------------
    // Fő hurok
    //----------------------------------------------------------------------
    érvénytelen hurok ()
    {
    int Méret, eredmény;
    érvénytelen * Cél;
    dupla Ax, Ay, Az, T, Gx, Gy, Gz;
    kettős tekercs = 0,00, hangmagasság = 0,00; // A Roll & Pitch az X és y tengely által elforduló szögek
    Read_RawValue (MPU6050SlaveAddress, MPU6050_REGISTER_ACCEL_XOUT_H);
    // megoszthatja mindegyikét az érzékenység skála faktorával
    Ax = (kettős) AccelX / AccelScaleFactor;
    Ay = (kettős) AccelY / AccelScaleFactor;
    Az = (kettős) AccelZ / AccelScaleFactor;
    T = (kettős) Hőmérséklet / 340 + 36,53; // hőmérséklet-képlet
    Gx = (kettős) GyroX / GyroScaleFactor;
    Gy = (kettős) GyroY / GyroScaleFactor;
    Gz = (kettős) GyroZ / GyroScaleFactor;
    roll = atan2 (Ay, Az) * 57,3;
    pitch = atan2 ((- Ax), sqrt (Ay * Ay + Az * Az)) * 57,3;
    //Serial.print ("Roll:"); Serial.println (Roll);
    //Serial.print ("Pitch:"); Serial.println (pitch);
    //Serial.print ("Az:"); Serial.print (AZ);
    //Serial.print ("T:"); Serial.print (T);
    //Serial.print ("Gx:"); Serial.print (Gx);
    //Serial.print ("Gy:"); Serial.print (Gy);
    //Serial.print ("Gz:"); Serial.println (Gz);
    késleltetés (100);
    //----------------------------------------------------------------------
    // Programm_for változó Int
    //----------------------------------------------------------------------
    int write_data = (int) (térkép (roll, -180, 180, -1000, 1000)); //// Írja be a görgetést a PLC-be
    //Serial.print ("Adatok írása:"); Serial.println (write_data);
    // késleltetés (500);
    //----------------------------------------------------------------------
    // Csatlakozás DB
    //----------------------------------------------------------------------
    #ifdef DO_IT_SMALL
    Méret = 2;
    Cél = NULL; // A belső puffert használja (PDU.DATA)
    #más
    Méret = 1024;
    Cél = és puffer; // Nagyobb puffert használ
    #endif
    // Kapcsolat
    míg (! Client.Connected)
    {
    ha (! Connect ())
    késleltetés (500);
    }
    //----------------------------------------------------------------------
    // Little_Endian & Big_Endian konverzió
    //----------------------------------------------------------------------
    int write_data_var1 = write_data;
    byte * bytes = (byte *) & write_data_var1;
    //----------------------------------------------------------------------
    // Szó / Int korrekció
    //----------------------------------------------------------------------
    void Correction (void * bytes);
    {
    byte * pointerbyte;
    bájthőmérséklet;
    pointerbyte = (byte *) (bájt);
    // Bájtcsere
    temp = * (pointerbyte + 1);
    * (pointerbyte + 1) = * pointerbyte;
    * pointerbyte = temp;
    }
    //----------------------------------------------------------------------
    // Soros ellenőrzés
    //----------------------------------------------------------------------
    Serial.print ("Write"); Serial.print (Méret); Serial.println ("byte by DB1.DBB0");
    // Tegye az aktuális pipát
    MarkTime ();
    Result = Client.WriteArea (S7AreaDB, // DB hozzáférést kérünk
    1, // DB szám = 1
    0, // Kezdje az N.0 bájtból
    Méret, // "Méret" bájtra van szükség
    bájt); // Tedd be a célunkba (puffer vagy PDU)
    ha (Eredmény == 0)
    {
    ShowTime ();
    Dump (cél, méret);
    }
    más
    CheckError (Eredmény);
    késleltetés (500);
    }
    érvénytelen I2C_Write (uint8_t deviceAddress, uint8_t regAddress, uint8_t adatok) {
    Wire.beginTransmission (deviceAddress);
    Wire.write (regAddress);
    Wire.write (adatok);
    Wire.endTransmission ();
    }
    / / olvassa el az összes 14 regisztert
    void Read_RawValue (uint8_t deviceAddress, uint8_t regAddress) Wire.read ());
    Hőmérséklet = (((int16_t) Wire.read () << 8)
    // az MPU6050 konfigurálása
    érvénytelen MPU6050_Init () {
    késleltetés (150);
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_SMPLRT_DIV, 0x07);
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_PWR_MGMT_1, 0x01);
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_PWR_MGMT_2, 0x00);
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_CONFIG, 0x00);
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_GYRO_CONFIG, 0x00); +/- 250 fok / másodperc teljes skálán
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_ACCEL_CONFIG, 0x00); // beállítva +/- 2g teljes skálát
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_FIFO_HU, 0x00);
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_INT_ENABLE, 0x01);
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_SIGNAL_PATH_RESET, 0x00);
    I2C_Write (MPU6050SlaveAddress, MPU6050_REGISTER_USER_CTRL, 0x00);
    }
    Nézd meg a RawNodeMCU_CONTROL_SIEMENS_PLC-t, amelyet a GitHub. szolgáltatott

    7. lépés: PLC PROGRAM - NODEMCU ESP 12-E V1.0

    PLC programvezérlő egyenáramú motor:

    • A motor iránya (CW vagy CCW) az MPU6050 - ROLL VALUE (pozitív vagy negatív) szerint van. Q124.4. & Q124.5 az "átalakítótáblához" és az L298N-hez csatlakoztatva az IN1, IN2 csapokhoz a motorirány beállítása.
    • És a motor fordulatszáma - DB1.DBW2 - ABS (ROLL VALUE). A PLC PWM kimenet Q124.0 a "fedőlemezhez" és L298N csatlakozóhoz csatlakozik ENA az egyenáramú motor PWM vezérlésére.
    • Az SFB49-et az alábbi létraprogramban használtuk PWM generálására a 0 - Q124.0 kimeneti csatornán.

    8. lépés: 24V-tól 5V-ig terjedő konvertertábla

    A feszültségszint átalakításához ULN2803-at használtam. Mindegyik ULN2803 nyolc drágaköves tranzisztort tartalmaz, ami azt jelenti, hogy 8 ULN2803 használatával 8 jelet tudunk átalakítani. Áramkör-diagram az alábbiak szerint:

    Konvertáló tábla képe

    9. lépés: TOVÁBB KÉPEK ÉS VIDEÓK

    A projektről ellenőrizheti a csatornám címét:

    És további videók a PLC projekthez:

    10. lépés: ÖSSZEFOGLALÁS

    • Ebben a tesztben az S7-300 PLC-vel a Settimino szinte olvashat / írhat a PLC-re, függetlenül a CPU védelmi szintjétől. Ez a biztonsági probléma minden bizonnyal nagy nehézséget okoz az automatizálási mérnökök számára, akik a Siemens ™ CPU-kkal dolgoznak.
    • Az Arduino nem kompatibilis az olyan ipari környezetekkel, mint a por, páratartalom, hőmérséklet, és nem felel meg a megbízhatósági követelményeknek, mint PLC-nek. Többé-kevésbé ez nem rossz módja annak, hogy az IoT / Smart Home-ot új generációs Siemens CPU-kkal, beépített Ethernet-szel, az Arduino-val együtt megfizethetővé tegyük.
    • Külön köszönet Dave Nardellának a "settimino" könyvtárért.

    SZÜKSÉGES SZEMBEN VÁLASZLJA … úgy, hogy több motivációm legyen hasznosabb projektek elvégzéséhez !!!