{code}
// miniCANopen.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "can.h"
#include "kvaserdriver.h"
#include "inputevent.h"
#include "util/vt100.h"
#include "util/misc.h"
// Paletti luokan esittely
// Jokaista linjan palettia vastaan yksi tämän luokan instanssi
// Luokan metodeilla voidaan määrätä palettikohtaisesti palettien reitti ja kierrosten lukumäärä
class paletti
{
public:
//int sijainti;
void otettu();
// Kun paletti otettu jollekkin asemalle, funktio muuttaa paletin vaihetta
int kohde();
// Lukijat tarkistavat minne paletin kuuluisi mennä
// Funktio palauttaa seuraavana vuorossa olevan työpisteen numeron
void aseta_reitti(int k0, int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, int k9);
// Parametreiksi annetaan työkierto asemien numeroina
// 1=manuaaliasema
// 2=sr6
// 3=sr60
// Viimeisen vaiheen on oltava 0, jolloin työkierto palaa alkuun
void aseta_tyovaihe(int k0, int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, int k9);
//asetetaan työvaihe paleteille mahd. arvot 1-3
void aseta_kierrosten_maara(int k);
// Parametriksi annetaan kuinka monta kertaa työkierto halutaan suorittaa
// Arvolla 0 työkiertoa ajetaan ikuisesti
int kierros();
// Palauttaa arvon joka kertoo kuinka monta kertaa työkierto on käyty läpi
void aktivoi();
void deaktivoi();
// Paletti aktivoidaan tai deaktivoidaan. Deaktivoitu paletti kiertää linjaston keskellä
void reset();
// Kierrosten määrä ja työkierron vaihe nollataan
bool aktiivisuus();
// Palauttaa boolean arvon, joka kertoo onko paletti aktiivinen
paletti();
virtual ~paletti();
int sijainti; //1 = manuaali-asema, 2 = sr6, 3 = sr60
//pidetään lukua onko paletti otettu jollekkin roboteista, jotta sitten robotilla
//voidaan tarkistaa, että mikä paletti on tulossa robolle (voidaan lukea robon arvot). Arvo asetetaan rfid:n lukuhetkellä tila[0],[6],[10]:ssa
//Vai onko paletilla tieto siitä missä kohtaa linjalle paletti on menossa? --JH
private:
int reitti[10];
int tyovaihe[10]; //työvaiheen numerot eli mitä tehdään kyseisellä robolla.
int vaihe;
int kierrosten_maara;
int kierroslaskuri;
bool aktiivinen;
int robotinOhjelma;
int kuittausRobotilta; //0 = susi, 1 = ok, 2 = aika ylitetty
//asetetaan kuittaus-tyyppi. paletti odottaa tietyn ajan ja jos kuittausta ei siinä
//ajassa ole tullut niin asetetaan tila '3' jolloin paletti siirtyy yleiseen kiertoon
};
// ************************
// Palettiluokan toteutus
// ************************
// Konstruktori
paletti::paletti()
{
}
// Destruktori
paletti::~paletti()
{
}
void paletti::otettu() {
vaihe++;
if(reitti[vaihe]==0) {
vaihe=0;
kierroslaskuri++;
}
if(kierroslaskuri>=kierrosten_maara && kierrosten_maara!=0) {
deaktivoi();
}
}
int paletti::kohde() {
if(aktiivinen)
return reitti[vaihe];
else return 0;
}
void paletti::aseta_reitti(int k0, int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, int k9) {
reitti[0]=k0;
reitti[1]=k1;
reitti[2]=k2;
reitti[3]=k3;
reitti[4]=k4;
reitti[5]=k5;
reitti[6]=k6;
reitti[7]=k7;
reitti[8]=k8;
reitti[9]=k9;
}
void paletti::aseta_tyovaihe(int k0, int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8, int k9) {
tyovaihe[0] = k0;
tyovaihe[1] = k0;
tyovaihe[2] = k0;
tyovaihe[3] = k0;
tyovaihe[4] = k0;
tyovaihe[5] = k0;
tyovaihe[6] = k0;
tyovaihe[7] = k0;
tyovaihe[8] = k0;
tyovaihe[9] = k0;
}
void paletti::aseta_kierrosten_maara(int k) {
kierrosten_maara=k;
kierroslaskuri=0;
vaihe=0;
}
int paletti::kierros() {
return kierroslaskuri;
}
void paletti::aktivoi() {
aktiivinen=true;
}
void paletti::deaktivoi() {
aktiivinen=false;
}
void paletti::reset() {
kierroslaskuri=0;
vaihe=0;
}
bool paletti::aktiivisuus() {
return aktiivinen;
}
// ***********************************
// Globaalien apufunktioiden esittely
// ***********************************
void reittien_alustus();
void nodeon(int CANnode, int slave, int bitti);
void nodeoff(int CANnode, int slave, int bitti);
bool nodestate(int CANnode, int slave, int bitti);
//testiä: olivat ennen ..nodeon(int CAN_NodeID..)
// ***************************************
// Ohjelman Globaalit muuttujat ja luokat
// ***************************************
// Taulukko tilakoneille
int tila[24];
char tilan_viesti[20][50];
//Muuttujat rfid-lukijoille
unsigned char lukija[3];
//Luodaan 13 palettia
paletti p[13];
//Laskuri ohjelman nopeuden selvittämistä varten
int laskuri;
// Luodaan globaalit PDOt jotka sisältävät linjan inputtien tilat
PDO tpdo181(0x181); //Digitaali-inputit 1-15
PDO tpdo281(0x281); //Digitaali-inputit 16-31
PDO tpdo1c1(0x1c1); //RFID-lukija 1
PDO tpdo2c1(0x2c1); //RFID-lukija 2
PDO tpdo3c1(0x3c1); //RFID-lukija 3
//ASi node 2 transmit pdot
PDO tpdo381(0x381); //Digitaali-inputit 1-15 ??? -JH
// Linjan outputit ovat näissä kahdessa RDPOssa
PDO rpdo201(0x201); //Digitaalioutputit 1-15
PDO rpdo301(0x301); //Digitaalioutputit 16-31
PDO rpdo401(0x401); //Digitaalioutputit 1-15 ASi Master 2
//testiä:
//uuden konfiguraation vaatimat muuttujat@14.4 -JH
//node 2:
PDO tpdo182(0x182); //node 2, input 1-15
PDO tpdo282(0x282); //input 1-15 //onko tätä? -JH
PDO rpdo202(0x202); //node 2, output 1-15
PDO rpdo302(0x301); //output 16-31 //onko tätä? -JH
int Run=1;
int LinjaAsiNode=1;
int RoboAsiNode=2;
// ***********
// Pääohjelma
// ***********
int main()
{
//Asetetaan paleteille reitit
reittien_alustus();
// Alustetaan näppäimistön käyttö
eventinit();
KvaserDriver driver;
// Avataan megabitin nopaudella
driver.open(1000000);
driver.set_debug(6);
decoder_openlog("\\temp\\canlog.txt");
// Luodaan CAN olio
CAN can;
can.set_debug(0); // Tulostetaan errorit ja ohjelma pysähtyy CAN-pinon virhetilanteisiin
// Ladataan CAN driver
can.load_driver(driver);
// Pysäytetään kaikien noodien toiminta
can.stop_node(0);
u_sleep(100000);
// Määritellään PDO:den pituudet
tpdo181.set_len(8);
tpdo281.set_len(8);
tpdo1c1.set_len(8);
tpdo2c1.set_len(8);
tpdo3c1.set_len(8);
//node 2
tpdo381.set_len(1);
rpdo201.set_len(8);
rpdo201.set_value(0); // Nollataan RDPOn kaikkien kahdeksan tavun sisältö
rpdo301.set_len(8);
rpdo301.set_value(0); // Nollataan RDPOn kaikkien kahdeksan tavun sisältö
//node 2
rpdo401.set_len(1);
rpdo401.set_value(0);
//testiä:
//asetetaan pituudet.
tpdo182.set_len(1);
rpdo202.set_len(8); // pitäisikö olla ..(1)..? --JH
rpdo201.set_value(0);
// Mapataan rfid-lukijoiden muuttujat oikeisii tpdo:hin.
tpdo1c1.mapcopy(0,lukija[1]);
tpdo2c1.mapcopy(0,lukija[2]);
tpdo3c1.mapcopy(0,lukija[3]);
// Lisätään TPDOt listaan
can.add_tpdo(tpdo181);
can.add_tpdo(tpdo281);
can.add_tpdo(tpdo1c1);
can.add_tpdo(tpdo2c1);
can.add_tpdo(tpdo3c1);
can.add_tpdo(tpdo381);
//testiä:
//lisätään luotujen tpdo182 + rpdo202 listaan. -- JH
can.add_tpdo(tpdo182);
can.add_rpdo(rpdo202);
// Lisätään RPDOt listaan
can.add_rpdo(rpdo201);
can.add_rpdo(rpdo301);
can.add_rpdo(rpdo401);
//SDO alustukset
// Asetetaan CAN-noodi preoperational-tilaan
can.set_preoperational(0);
u_sleep(100000);
// IFM:n boksin alustukset
// Tarvitaan 5 TPDO:ta ja 2 RPDO:ta
// Määrätään PDO-viesteille COBID:t
// TDPO cobid konfigurointi
can.sdo_write(1, 0x1800, 1, 4, 384+1);
can.sdo_write(1, 0x1801, 1, 4, 640+1);
can.sdo_write(1, 0x1802, 1, 4, 448+1);
can.sdo_write(1, 0x1803, 1, 4, 704+1);
can.sdo_write(1, 0x1804, 1, 4, 960+1);
can.sdo_write(1, 0x1805, 1, 4, 896+1);
// RDPO cobid konfigurointi
can.sdo_write(1, 0x1400, 1, 4, 512+1);
can.sdo_write(1, 0x1401, 1, 4, 768+1);
can.sdo_write(1, 0x1402, 1, 4, 1024+1);
u_sleep(100000);
can.start_node(0);
u_sleep(100000);
VT100::clearscreen();
//luodaan globaali-tekstitiedosto, johon voi kirjoittaa halutussa kohtaa ohjelmaa tekstiä ---@7.4 JH
int iApu;
//apumuuttuja (voidaan tallentaa tiloja esim. iApu = nodeon(x,x,x)
FILE *pFile;
pFile = fopen("debug_tekstia.txt", "w");
//"w" = kirjoita tiedostoon, ylikirjoita kaikki, luo tarvittavissa
//"a" = jatka jo olemassa olevan perään
if (pFile == NULL)
perror("error opening file");
fprintf(pFile, "debug tekstiä\n*******************************\n");
//käytetään kirjoittamalla: "fprintf(pFile, "_teksti_tähän_, %d, %s", int_muuttuja, char_muuttuja);"
// Pääohjelma alkaa tästä ja suorittaa ikuista looppia
//tuleva valikko-ohjelma:
int valinta = 0;
//do{
printf("This is the program for the production line!!\n\n");
printf("\nWhen the line program is running you should stretch your terminal window downwards so that all information can be shown at the screen\n\n");
printf("The following keys are valid:\n\n");
printf("When the production line program is _running_ pressing '1' will activate the line. Pressing '0' will shutdown the line. Pressing 'ESC' will shutdown the line and exit\n\n");
printf("What do you want me to do MASTER?\n");
printf("Pressing number '1' will start the production-line program\n");
printf("Any other button will end quit the program\n\n\n\n");
printf("your selection: ");
scanf("%d", &valinta);
VT100::clearscreen();
if (valinta == 1) {
do{
// Linjan moottorit päälle kun painetaan näppäintä '1'
if (keydown('1'))
{
//moottorit käynnistetään yksi kerrallaan virtapiikin estämiseksi
for(int i=1; i<=23; i++) {
if(i==1) nodeon(1,17,1); //manuaalilinjan moottorit
if(i==2) nodeon(1,27,1);
if(i==3) nodeon(1,27,2);
if(i==4) nodeon(1,6,1);
if(i==5) nodeon(1,6,2);
if(i==6) nodeon(1,6,3);
if(i==7) nodeon(1,16,1);
if(i==8) nodeon(1,16,2);
// tehdään alustus, jossa '1' napin painalluksella jäämäpalettien poiston caset lähtevät käyntiin
if(i==9) tila[0]=1;
if(i==10) tila[1]=1;
if(i==11) tila[2]=1;
if(i==12) tila[3]=1;
if(i==13) tila[6]=1;
if(i==14) tila[7]=1;
if(i==15) tila[8]=1;
if(i==16) tila[11]=1;
if(i==17) tila[12]=1;
if(i==18) tila[13]=1;
if(i==19) tila[14]=1;
if(i==20) tila[16]=1;
if(i==21) tila[17]=1;
if(i==22) tila[18]=1;
if(i==23) tila[19]=1;
printf("Moottori :%d\n",i);
u_sleep(500000); //500ms
can.send_only_changed_rpdos();
}
}
// Linjan moottorit pois päältä kun painetaan näppäintä '0'
if (keydown('0'))
{
//moottorit pysäytetään yksi kerrallaan virtapiikin estämiseksi
for(int i=1; i<=8; i++) {
if(i==1) nodeoff(1,17,1); //manuaalilinjan moottorit
if(i==2) nodeoff(1,27,1);
if(i==3) nodeoff(1,27,2);
if(i==4) nodeoff(1,6,1);
if(i==5) nodeoff(1,6,2);
if(i==6) nodeoff(1,6,3);
if(i==7) nodeoff(1,16,1);
if(i==8) nodeoff(1,16,2);
printf("Moottori :%d\n",i);
u_sleep(500000); //500ms
can.send_only_changed_rpdos();
}
}
//
if (keydown('A'))
{
nodeoff(1,6,3);
nodeoff(1,20,4);
}
//
if (keydown('B'))
{
nodeon(1,6,3);
nodeon(1,20,4);
}
if (keydown('C'))
{
int Tila;
Tila=nodestate(2,1,1);
printf("\ntila on %d",Tila);
}
if(keydown('D'))
{
//nodeon(2,3,1);
//nodeon(2,3,2);
/*nodeon(2,2,1);
nodeon(2,2,2);*/
// nodeon(1,26,3);
/*nodeon(2,4,3);
nodeon(2,4,4);
nodeon(2,3,3);
nodeon(2,3,4);
nodeon(2,3,3);
nodeon(2,3,4);*/
//nodeon(2,4,1);
//nodeon(2,4,2);
//nodeon(2,4,3);
//nodeon(2,4,4);
//nodeon(2,5,1);
//nodeon(2,5,2);
//fprintf(pFile, "näppäintä D painettu:\n");
//fprintf(pFile, "nodestate(2,5,1): %d\nnodestate(2,5,2): %d\n", iApu = nodestate(2,5,1), iApu = nodestate(2,5,2));
//rpdo401.set_value(15);
if(nodestate(2, 2, 1))
fprintf(pFile, "IFFIN SISässä***** D-nappi: noodi 2.2.1 päällä\n");
}
if(keydown('E'))
{
if (nodestate(2, 2, 2))
fprintf(pFile, "E-nappi: noodi 2.2.2 päällä\n");
//nodeoff(2,4,3);
//nodeoff(2,4,4);
//nodeoff(2, 2, 1);
//nodeoff(2,4,1);
//nodeoff(2,4,2);
//nodeoff(2,5,1);
//nodeoff(2,5,2);
//fprintf(pFile, "näppäintä E painettu:\n");
//fprintf(pFile, "nodestate(2,5,1): %d\nnodestate(2,5,2): %d\n", iApu = nodestate(2,5,1), iApu = nodestate(2,5,2));
//nodeon(2,5,3);
//nodeon(2,5,4);
// nodeoff(1,26,3);
}
if(Run==1)
{
// Varsinainen ohjelman logikka alkaa
// 20 tilakonetta seuraavat linjaston tapahtumia, ja ohjaavaat toimilaitteita
// lisäksi neljä tilakonetta ohjaavat jäämäpalettien poistoa
switch(tila[0]) {
// case 0-1 ovat jäämäpalettien poistamiseksi ajon alussa
case 0:
//tyhjä case anturien toiminnan parantamiseksiajon alussa
break;
case 1:
if(nodestate(1,21,1)) //Jos mekaaninen anturi 21,1 vaikuttuu, asetetaan hissi 20,3 yläasentoon.
nodeon(1,20,3);
if(timedelay(0,25000000)) //Ajastin laskee 25000ms, jonka jälkeen tila[0] siirtyy seuraavaan caseen.
tila[0]++;
break;
case 2:
strcpy(tilan_viesti[0],"20.1");
nodeoff(1,20,4); //Hissi asetetaan keskiasentoon.
nodeoff(1,20,3);
if(nodestate(1,20,1)) //Jos anturi 20,1 vaikuttuu, siirtyy tila[0] seuraavaan caseen.
tila[0]++;
break;
case 3:
strcpy(tilan_viesti[0],"20.2");
nodeon(1,21,3); //Stoppari 21,3 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,20,2)) //Jos induktiivinen anturi 20,2 vaikuttuu, siirtyy tila[0] seuraavaan caseen.
tila[0]++;
break;
case 4:
strcpy(tilan_viesti[0],"21.1");
nodeoff(1,21,3); //Stoppari 21,3 menee poispäältä, estäen seuraavan paletin kulun.
if(nodestate(1,21,1)) { //Jos mekaaninen anturi 21,1 vaikuttuu, ja jos tila[1]=1, niin RFID-lukija[1] lukee paletin tagin.
strcpy(tilan_viesti[0],"tila[4], tila[12], tila[1]");
if(tila[1]==1 && p[ lukija[1] ].kohde()==1 ) { //Jos reitti paletille on 1 eli manuaaliasema, niin silta 20,3 vaikuttuu, tila[0] siirtyy seuraavaan caseen ja tila[1]=1.
resettimedelay(0);
nodeon(1,20,3);
tila[0]++;
tila[1]=1;
p[lukija[1]].otettu(); //kuitataan että paletti otettiin
p[lukija[1]].sijainti = 1; //astetaan paletin sijainniksi 1, eli manuaaliasema
}
//Jos kohde ei ole manuaaliasema tai tunnistuksessa kestää yli sekunti
//(paletti ilman tagia?), ajetaan suoraan
else if((lukija[1]!=0 && p[ lukija[1] ].kohde()!=1) || timedelay(0,1000000)) {
if(tila[4]==0 && tila[12]==1) { //Jos tila[4]=0 ja tila[12]=1, vaikuttuu silta 20,4, tila[12]=2 ja tila[0] siirtyy seuraavaan caseen.
resettimedelay(0);
nodeon(1,20,4);
tila[12]=2;
tila[0]++;
}
}
}
break;
case 5: //viive että paletti ehtii pois hissistä, sitten nollaus
strcpy(tilan_viesti[0],"Ajastin 2s");
if(timedelay(0,2000000)) //Kun ajastin on laskenut 2000ms, on tila[0]=2.
tila[0]=2;
break;
}
switch(tila[1]) {
case 0:
//tyhjä case anturien toiminnan parantamiseksi ajon alussa
break;
case 1:
strcpy(tilan_viesti[1],"22.1");
if(nodestate(1,22,1) && tila[2]==2) //Jos induktiivinen anturi 22,1 vaikuttuu ja tila[2]=2, siirtyy tila[1] seuraavaan caseen.
tila[1]++;
break;
case 2:
strcpy(tilan_viesti[1],"22.2");
nodeon(1,22,3); //Stoppari 22,3 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,22,2)) //Jos induktiivinen anturi 22,2 vaikuttuu, siirtyy tila[1] seuraavaan caseen.
tila[1]++;
break;
case 3:
strcpy(tilan_viesti[1],"23.1");
nodeoff(1,22,3); //Stoppari 22,3 menee poispäältä, estäen seuraavan paletin kulun.
if(nodestate(1,23,1)) { //Jos induktiivinen anturi 23,1 vaikuttuu, on tila[1]=1.
tila[1]=1;
}
break;
}
switch(tila[2]) {
//Case 0
1 poistaa jäämäpaletit ennen kuin tila[2] aloittaa normaalin työkierron.
case 0:
//tyhjä case anturien toiminnan parantamiseksiajon alussa
break;
case 1:
//if-lause yhden stopparin toiminnan parantamiseksi jäämäpaletteja poistettaessa ajon alussa
if(tila[3]==1) { //Jos tila[3]=1, niin stoppari 26,3 menee päälle, päästäen paletin ylitseen.
nodeon(1,26,3);
if(timedelay(2,500000)){ //Lisäksi ajastin laskee 500ms, jonka jälkeen stoppari 26,3 menee pois päältä, estäen seuraavan paletin kulun ja tila[2] siirtyy seuraavaan caseen.
nodeoff(1,26,3);
tila[2]++;
}
}
break;
case 2:
strcpy(tilan_viesti[2],"23.1");
if(nodestate(1,23,1)) //Jos induktiivinen anturi 23,1 vaikuttuu, siirtyy tila[2] seuraavaan caseen.
tila[2]++;
break;
case 3:
strcpy(tilan_viesti[2],"gut tai auto");
nodeon(1,23,3); //Pöytä asetetaan yläasentoon.
nodeoff(1,23,4); //Toimilaite 23,4 menee pois päältä.
//kappale päästetään eteenpäin gut-napilla tai auto-valinnalla
if(!nodestate(1,25,3) || nodestate(1,25,2)) //Jos painonappi auto/man ei ole painettuna tai gut nappi on painettuna, siirtyy tila[2] seuraavaan caseen.
tila[2]++;
break;
case 4:
strcpy(tilan_viesti[2],"23.2");
nodeon(1,22,4); //Pöytä 22,4 asetetaan ala-asentoon.
nodeoff(1,23,3); //Toimilaite 23,3 menee pois päältä.
nodeon(1,23,4); //Toimilaite 23,4 menee päälle.
if(nodestate(1,23,2)) //Jos induktiivinen anturi 23,2 vaikuttuu, siirtyy tila[2] seuraavaan caseen.
tila[2]++;
break;
case 5:
strcpy(tilan_viesti[2],"tila[3]");
nodeoff(1,22,4); //Stoppari 22,4 menee pois päältä, estäen seuraavan paletin kulun.
if(tila[3]==1) //Jos tila[3]=1, siirtyy tila[2] seuraavaan caseen.
tila[2]++;
break;
case 6:
strcpy(tilan_viesti[2],"26.1");
nodeon(1,26,3); //Stoppari 26,3 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,26,1)) //Jos induktiivinen anturi 26,1 vaikuttuu, siirtyy tila[2] seuraavaan caseen.
tila[2]++;
break;
case 7:
nodeoff(1,22,4); //Stopparit 22,4 ja 26,3 menevät pois päältä, estäen seuraavien palettien kulun.
nodeoff(1,26,3);
tila[2]=2; //Tila[2]=2.
break;
}
switch(tila[3]) {
case 0:
//tyhjä case anturien toiminnan parantamiseksi ajon alussa
break;
case 1:
strcpy(tilan_viesti[3],"26.2");
if(nodestate(1,26,2)) //Jos mekaaninen anturi 26,2 vaikuttuu, siirtyy tila[3] seuraavaan caseen.
tila[3]++;
break;
case 2:
strcpy(tilan_viesti[3],"ajastin 800ms");
if(timedelay(3,800000)) //Ajastin laskee 800ms, jonka jälkeen tila[3] siirtyy seuraavaan caseen.
tila[3]++;
break;
case 3:
strcpy(tilan_viesti[3],"24.2, tila[4]");
nodeon(1,26,4); //Hissi 26,4 asetetaan yläasentoon.
if(nodestate(1,24,2) && tila[4]==0) //Jos mekaaninen anturi 24,2 vaikuttuu ja tila[4]=0, siirtyy tila[3] seuraavaan caseen.
tila[3]++;
break;
case 4:
strcpy(tilan_viesti[3],"24.3");
nodeoff(1,26,4); //Hissi 26,4 asetetaan ala-asentoon.
if(nodestate(1,24,3)) //Jos induktiivinen anturi 24,3 vaikuttuu, on tila[3]=1.
tila[3]=1;
break;
}
switch(tila[4]) {
case 0:
strcpy(tilan_viesti[4],"28.1, tila[12]");
if(nodestate(1,28,1) && tila[12]==1) //Jos induktiivinen anturi 28,1 vaikuttuu ja tila[12]=1, siirtyy tila[4] seuraavaan caseen.
tila[4]++;
break;
case 1:
strcpy(tilan_viesti[4],"28.2");
nodeon(1,28,3); //Stoppari 28,3 menee päälle, päästäen paletin ylitseen.
nodeon(1,21,4); //Hissi 21,4 asetetaan yläasentoon.
if(timedelay(4,500000)){ //Ajastin laskee 500ms, jonka jälkeen stoppari 28,3 menee pois päältä, estäen seuraavan paletin kulun. Lisäksi tila[4]=0.
nodeoff(1,28,3);
tila[4]=0;
}
break;
}
switch(tila[5]){
case 0:
strcpy(tilan_viesti[5],"7.1");
nodeon(1,7,3); //Stoppari 7,3 menee päälle päästäen paletin ylitseen.
if(nodestate(1,7,1)) //Jos induktiivinen anturi 7,1 vaikuttuu , siirtyy tila[5] seuraavaan caseen.
tila[5]++;
break;
case 1:
strcpy(tilan_viesti[5],"7.2");
nodeoff(1,7,3); //Stoppari 7,3 menee poispäältä, estäen seuraavan paletin kulun.
if(nodestate(1,7,2)) { //Jos induktiivinen anturi 7,2 vaikuttuu, on tila[5]=0.
tila[5]=0;
}
break;
}
switch(tila[6]) {
//Case 0
1 poistaa jäämäpaletit ennen kuin tila[6] aloittaa normaalin työkierron.
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
if(nodestate(1,8,2)) //Jos mekaaninen anturi 8,2 vaikuttuu, asetetaan hissi 9,3 ala-asentoon.
nodeon(1,9,3);
if(timedelay(6,3000000)) //Ajastin laskee 3000ms, jonka jälkeen tila[6] siirtyy seuraavaan caseen.
tila[6]++;
break;
case 2:
strcpy(tilan_viesti[6],"7.2");
nodeoff(1,9,2); //Hissi 9,2 ja 9,3 asetetaan keskiasentoon.
nodeoff(1,9,3);
if(nodestate(1,7,2)) //Jos induktiivinen anturi 7,2 vaikuttuu, siirtyy tila[6] seuraavaan caseen.
tila[6]++;
break;
case 3:
strcpy(tilan_viesti[6],"8.1");
nodeon(1,9,1); //Stoppari 9,1 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,8,1)) //Jos induktiivinen anturi 8,1 vaikuttuu, siirtyy tila[6] seuraavaan caseen.
tila[6]++;
break;
case 4:
strcpy(tilan_viesti[6],"8.2, tila[7]");
nodeoff(1,9,1); //Stoppari 9,1 menee poispäältä, estäen seuraavan paletin kulun
if(nodestate(1,8,2)) { //Jos mekaaninen anturi 8,2 vaikuttuu ja tila[7]=2, lukee RFID-lukija[2] paletin tagin.
if(tila[7]==2 && p[lukija[2]].kohde()==2) { //Jos reitti paletille on 2 eli SR6-asema, niin tila[6]=5 ja paletti kuitataan otetuksi.
resettimedelay(6);
tila[6]=5;
p[lukija[2]].otettu();
//testiä:
p[lukija[2]].sijainti = 2;
//asetetaan paletin-sijainniksi rfid:n numero
//jotta tiedetään mikä paletti on tulossa kyseiselle robolle.
}
else if((lukija[2]!=0 && p[ lukija[1] ].kohde()!=2) || timedelay(6,1000000)) { //Jos taas paletin retti on eri kuin 2 tai lukuaika on enemmän kuin 1000ms, on tila[6]=6.
resettimedelay(6);
tila[6]=6;
}
tila[5]=0; //Asetetaan tila[5]=0.
}
break;
//Case 5 robotille, case 6 kiertoon
case 5:
//Tämä case ohjaa paletin SR6-robotille.
strcpy(tilan_viesti[6],"ajastin 2s");
nodeon(1,9,2); //Hissi 9,2 asetetaan yläasentoon.
if(timedelay(6,2000000)) //Kun ajastin on laskenut 2000ms kuluneeksi, on tila[6]=2.
tila[6]=2;
break;
case 6:
//Tämä case ohjaa paletin kiertoon.
strcpy(tilan_viesti[6],"ajastin 2s");
nodeon(1,9,3); //Hissi 9,3 asetetaan ala-asentoon.
if(timedelay(6,2000000)) //Kun ajastin on laskenut 2000ms kuluneeksi, on tila[6]=2.
tila[6]=2;
break;
}
switch(tila[7]) {
//case 0-1 poistaa jäämäpaletit aluksi ennen kuin tila[7] aloittaa normaalin työkierron
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
//Tilakone tila[22] ohjaa jäämäpalettien poistoa ajon alussa tässä casessa.
switch(tila[22]) { //Tämä tilakone ohjaa tila[7]:n jäämäpalettien poistoa.
case 0:
nodeon(1,10,3); //Stoppari 10,3 menee päälle, päästäen paletin ylitseen.
nodeon(1,10,4); //Hissi 10,4 asetetaan yläasentoon.
tila[22]++; //Tila[22] siirtyy seuraavaan caseen.
break;
case 1:
if(nodestate(1,10,1)) //Jos induktiivinen anturi 10,1 vaikuttuu, menee stoppari 10,3 pois päältä, estäen seuraavan paletin kulun.
nodeoff(1,10,3);
if(nodestate(1,10,2)){ //Jos mekaaninen anturi 10,2 vaikuttuu, asetetaan hissi 10,4 ala-asentoon ja tila[22] siirtyy seuraavaan caseen.
nodeoff(1,10,4);
tila[22]++;
}
if(timedelay(22,2000000)) //Ajastin laskee 2000ms, jonka jälkeen tila[22] siirtyy seuraavaan caseen.
tila[22]++;
break;
case 2:
if(timedelay(22,4000000)){ //Ajastin laskee 4000ms, jonka jälkeen hissi 10,4 asetetaan yläasentoon ja stoppari 10,3 menee päälle, päästäen paletin ylitseen. Lisäksi tila[22] siirtyy seuraavaan caseen.
nodeon(1,10,4);
nodeon(1,10,3);
tila[22]++;
}
break;
case 3:
if(nodestate(1,10,1)) //Jos induktiivinen anturi 10,1 vaikuttuu, menee stoppari 10,3 pois päältä, estäen seuraavan paletin kulun.
nodeoff(1,10,3);
if(nodestate(1,10,2)) //Jos mekaaninen anturi 10,2 vaikuttuu, asetetaan hissi 10,4 ala-asentoon.
nodeoff(1,10,4);
if(timedelay(22,4000000)) //Ajastin laskee 4000ms, jonka jälkeen tila[22]=0.
tila[22]=0;
break;
}
if(timedelay(7,40000000)){ //Ajastin laskee 40000ms, jonka jälkeen jälkeen hissi 10,4 asetetaan ala-asentoon ja stoppari 10,3 menee päälle, estäen seuraavan paletin kulun. Lisäksi tila[7] siirtyy seuraavaan caseen.
nodeoff(1,10,4);
nodeoff(1,10,3);
tila[7]++;
}
break;
case 2:
strcpy(tilan_viesti[7],"8.3");
if(nodestate(1,8,3)) //Jos induktiivinen anturi 8,3 vaikuttuu, siirtyy tila[7] seuraavaan caseen.
tila[7]++;
break;
case 3:
strcpy(tilan_viesti[7],"tila[16]");
if(tila[16]==3) //Jos tila[16]=3, siirtyy tila[7] seuraavaan caseen.
tila[7]++;
break;
case 4:
strcpy(tilan_viesti[7],"10.1");
nodeon(1,10,3); //Stoppari 10,3 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,10,1)) //Jos induktiivinen anturi 10,1 vaikuttuu, tila[7] siirtyy seuraavaan caseen.
tila[7]++;
break;
case 5:
strcpy(tilan_viesti[7],"10.2");
nodeon(1,10,4); //Hissi 10,4 asetetaan yläasentoon.
nodeoff(1,10,3); //Stoppari 10,3 menee pois päältä, estäen seuraavan paletin kulun.
if(nodestate(1,10,2)) //Jos mekaaninen anturi 10,2 vaikuttuu, siirtyy tila[7] seuraavaan caseen.
tila[7]++;
break;
case 6:
strcpy(tilan_viesti[7],"ajastin 1s");
nodeoff(1,10,4); //Hissi 10,4 asetetaan ala-asentoon.
if(timedelay(7,1000000)) //Ajastin laskee 1000ms, jonka jälkeen tila[7]=2.
tila[7]=2;
break;
}
switch(tila[8]){
//case 0-1 poistaa jäämäpaletit aluksi ennen kuin tila[7] aloittaa normaalin työkierron
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
//Tilakone tila[23] ohjaa jäämäpalettien poistoa ajon alussa tässä casessa.
switch(tila[23]) { //Tämä tilakone ohjaa tila[8]:n jäämäpalettien poistoa.
case 0:
nodeon(1,5,3); //Stoppari 5,3 menee päälle, päästäen paletin ylitseen.
nodeon(1,5,4); //Hissi 5,4 asetetaan yläasentoon.
tila[23]++; //Tila[23] siirtyy seuraavaan caseen.
break;
case 1:
if(nodestate(1,4,3)) //Jos induktiivinen anturi 4,3 vaikuttuu, menee stoppari 5,3 pois päältä, estäen seuraavan paletin kulun.
nodeoff(1,5,3);
if(nodestate(1,4,4)){ //Jos mekaaninen anturi 4,4 vaikuttuu, asetetaan hissi 5,4 ala-asentoon ja tila[23] siirtyy seuraavaan caseen.
nodeoff(1,5,4);
tila[23]++;
}
if(timedelay(23,4000000)) //Ajastin laskee 4000ms, jonka jälkeen tila[23] siirtyy seuraavaan caseen.
tila[23]++;
break;
case 2:
if(timedelay(23,4000000)){ //Ajastin laskee 4000ms, jonka jälkeen hissi 5,4 asetetaan yläasentoon ja stoppari 5,3 menee päälle, päästäen paletin ylitseen. Lisäksi tila[23] siirtyy seuraavaan caseen.
nodeon(1,5,4);
nodeon(1,5,3);
tila[23]++;
}
break;
case 3:
if(nodestate(1,4,3)) //Jos induktiivinen anturi 4,3 vaikuttuu, menee stoppari 5,3 pois päältä, estäen seuraavan paletin kulun.
nodeoff(1,5,3);
if(nodestate(1,4,4)) //Jos mekaaninen anturi 4,4 vaikuttuu, asetetaan hissi 5,4 ala-asentoon.
nodeoff(1,5,4);
if(timedelay(23,4000000)) //Ajastin laskee 4000ms, jonka jälkeen tila[23]=0.
tila[23]=0;
break;
}
if(timedelay(8,40000000)){ //Ajastin laskee 40000ms, jonka jälkeen hissi 5,4 asetetaan ala-asentoon ja stoppari 5,3 menee päälle, estäen seuraavan paletin kulun. Lisäksi tila[8] siirtyy seuraavaan caseen.
nodeoff(1,5,4);
nodeoff(1,5,3);
tila[8]++;
}
break;
case 2:
strcpy(tilan_viesti[8],"29.1");
if(nodestate(1,29,1)) tila[8]++; //Jos induktiivinen anturi 29,1 vaikuttuu, tila[8] siirtyy seuraavaan caseen.
break;
case 3:
strcpy(tilan_viesti[8],"4.3");
nodeon(1,5,3); //Stoppari 5,3 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,4,3)) //Jos induktiivinen anturi 4,3 vaikuttuu, siirtyy tila[8] seuraavaan caseen.
tila[8]++;
break;
case 4:
strcpy(tilan_viesti[8],"4.4");
nodeoff(1,5,3); //Stoppari 5,3 menee poispäältä, estäen seuraavan paletin kulun.
nodeon(1,5,4); //Hissi 5,4 asetetaan yläasentoon.
if(nodestate(1,4,4) && tila[18]==3) //Jos mekaaninen anturi 4,4 vaikuttuu ja tila[18]=3, tila[8] siirtyy seuraavaan caseen.
tila[8]++;
break;
case 5:
strcpy(tilan_viesti[8],"ajastin 1400ms");
nodeoff(1,5,4); //Hissi 5,4 asetetaan ala-asentoon.
if(timedelay(8,1400000)) tila[8]=2; //Ajastin laskee 1400ms, jonka jälkeen tila[8]=2.
break;
}
switch(tila[9]) {
case 0:
nodeoff(1,14,2); //Hissi 14,2 asetetaan ala-asentoon.
break;
case 1:
strcpy(tilan_viesti[9],"13.2, tila[15]");
if(nodestate(1,13,2) && tila[15]==0) //Jos mekaaninen anturi 13,2 vaikuttuu ja tila[15]=0, siirtyy tila[9] seuraavaan caseen.
tila[9]++;
break;
case 2:
strcpy(tilan_viesti[9],"ajastin 1500ms");
nodeoff(1,14,2); //Hissi 14,2 asetetaan ala-asentoon.
if(timedelay(9,2000000)){ //Ajastin laskee 2000ms, jonka jälkeen tila[9]=0.
tila[9]=0;
}
break;
}
switch(tila[10]) {
case 0:
strcpy(tilan_viesti[10],"31.4");
nodeoff(1,30,3); //Hissi asetetaan keskiasentoon.
nodeoff(1,30,4);
if(nodestate(1,31,4)) //Jos mekaaninen anturi 31,4 vaikuttuu, siirtyy tila[10] seuraavaan caseen.
tila[10]++;
break;
case 1:
strcpy(tilan_viesti[7],"ajastin 400ms");
if(timedelay(10,800000)) tila[10]++; //Ajastin laskee 800ms paletin asettumiseksi hissille, minkä jälkeen tila[10] siirtyy seuraavaan caseen.
break;
case 2:
strcpy(tilan_viesti[10],"31.4, tila[8]");
if(nodestate(1,31,4)) { //Jos mekaaninen anturi 31,4 vaikuttuu ja tila[8]=2, lukee RFID-lukija[3] paletin tagin.
if(tila[8]==2 && p[lukija[3]].kohde()==3) {
resettimedelay(10);
tila[10]=3;
//testiä:
p[lukija[3]].sijainti = 3; //paletti otetaan robolle, joten sijainti asetetaan 3.
}
else if((lukija[3]!=0 && p[ lukija[3] ].kohde()!=3) || timedelay(10,2000000)) { //Jos reitti paletille on 3 eli SR60-asema, niin tila[10]=3.
resettimedelay(10);
tila[10]=4;
}
}
break;
case 3:
//Tämä case ohjaa paletin SR60-robotille.
nodeon(1,30,3); //Hissi asetetaan yläasentoon.
nodeoff(1,30,4);
nodeon(1,5,3); //Stoppari 5,3 menee päälle, päästäen paletin ylitseen.
p[lukija[3]].otettu(); //Paletti kuitataan otetuksi.
tila[10]=5; //Tila[10]=5.
break;
case 4:
//Tämä case ohjaa paletin kiertoon.
nodeon(1,30,4); //Hissi asetetaan ala-asentoon.
nodeoff(1,30,3);
tila[10]++; //Tila[10] siirtyy seuraavaan caseen.
break;
case 5:
strcpy(tilan_viesti[10],"ajastin 2s");
// odotetaan ajastimella että hissi tyhjenee
if(timedelay(10,4000000)) tila[10]=0; //Ajastin laskee 4000ms hissin tyhjentymistä varten, minkä jälkeen tila[10]=0.
break;
}
switch(tila[11]) {
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
strcpy(tilan_viesti[11],"13.1, tila[9]");
//odotetaan että tila[9] ja tila[19] ovat tyhjiä ennekuin päästetään paletti
if(nodestate(1,13,1) && tila[9]==0 && tila[19]==1) { //Jos induktiivinen anturi 13,1 vaikuttuu, tila[9]=0 ja tila[19]=1, niin tila[9]=1 ja tila[11] siirtyy seuraavaan caseen.
tila[9]=1;
tila[11]++;
}
break;
case 2:
strcpy(tilan_viesti[11],"ajastin 500ms");
nodeon(1,14,1); //Stoppari 14,1 menee päälle, päästäen paletin ylitseen.
nodeoff(1,14,2); //Hissi 14,2 asetetaan ala-asentoon.
if(timedelay(11,500000)){ //Ajastin laskee 500ms, jonka jälkeen stoppari 14,1 menee pois päältä, estäen seuraavan paletin kulun ja tila[11]=1.
nodeoff(1,14,1);
tila[11]=1;
}
break;
}
switch(tila[12]) {
//Hissin 21,4 lasku case 1:ssa on jäämäpaletteja varten
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
strcpy(tilan_viesti[12],"28.2");
if(nodestate(1,21,2)) //Jos mekaaninen anturi 21,2 vaikuttuu, asetetaan hissi 21,4 ala-asentoon.
nodeoff(1,21,4);
if(nodestate(1,28,2)) //Jos induktiivinen anturi 28,2 vaikuttuu, siirtyy tila[12] seuraavaan caseen.
tila[12]++;
break;
case 2:
strcpy(tilan_viesti[12],"21.2");
if(nodestate(1,21,2)) { //Jos mekaaninen anturi 21,2 vaikuttuu, asetetaan hissi 21,4 ala-asentoon ja tila[12] siirtyy seuraavaan caseen.
nodeoff(1,21,4);
tila[12]++;
}
break;
case 3:
strcpy(tilan_viesti[12],"ajastin 2s");
if(timedelay(12,2000000)) tila[12]=1; //Ajastin laskee 2000ms, jonka jälkeen tila[12]=1.
break;
}
switch(tila[13]) {
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
//odotetaan että tila[14] sekä tila[17] ovat tyhjiä ennen kuin päästetään paletti
strcpy(tilan_viesti[13],"31.1, tila[14]");
if(nodestate(1,31,1) && tila[14]==2 && tila[17]==1) { //Jos induktiivinen anturi 31,1 vaikuttuu, tila[14]=2 ja tila[17]=1, niin tila[14]=3 ja tila[13] siirtyy seuraavaan caseen.
tila[14]=3;
tila[13]++;
}
break;
case 2:
strcpy(tilan_viesti[13],"ajastin 500ms");
nodeon(1,29,3); //Stoppari 29,3 menee päälle, päästäen paletin ylitseen.
nodeoff(1,30,1); //Hissi asetetaan keskiasentoon.
nodeoff(1,30,2);
if(timedelay(13,500000)) tila[13]++; //Ajastin laskee 500ms, jonka jälkeen tila[13] siirtyy seuraavaan caseen.
break;
case 3:
nodeoff(1,29,3); //Stoppari 29,3 menee pois päältä, estäen seuraavan paletin kulun.
tila[13]=1; //Tila[13]=1.
break;
}
switch(tila[14]) {
//caset 0-1 ovat jäämäpalettien poistoa varten ajon alussa
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
if(nodestate(1,31,2) && tila[10]==0){ //Jos mekaaninen anturi 31,2 vaikuttuu ja tila[10]=0, niin hissi asetetaan ala-asentoon.
nodeoff(1,30,1);
nodeon(1,30,2);
}
if(timedelay(14,3000000))//Ajastin laskee 3000ms, jonka jälkeen tila[14] siirtyy seuraavaan caseen.
tila[14]++;
break;
case 2:
nodeoff(1,30,1); //Hissi asetetaan keskiasentoon.
nodeoff(1,30,2);
break;
case 3:
strcpy(tilan_viesti[14],"31.2, tila[10]");
if(nodestate(1,31,2) && tila[10]==0) //Jos mekaaninen anturi 31,2 vaikuttuu ja tila[10]=0, niin tila[14] siirtyy seuraavaan caseen.
tila[14]++;
break;
case 4:
strcpy(tilan_viesti[14],"ajastin 2s");
nodeoff(1,30,1); //Hissi asetetaan ala-asentoon.
nodeon(1,30,2);
if(timedelay(14,2000000)) //Ajastin laskee 2000ms, jonka jälkeen tila[14]=2.
tila[14]=2;
break;
}
switch(tila[15]) {
case 0:
strcpy(tilan_viesti[15],"12.1");
nodeon(1,12,3); //Stoppari 12,3 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,12,1)) //Jos induktiivinen anturi 12,1 vaikuttuu, siirtyy tila[15] seuraavaan caseen.
tila[15]++;
break;
case 1:
strcpy(tilan_viesti[15],"12.2");
nodeoff(1,12,3); //Stoppari 12,3 menee pois päältä, estäen seuraavan paletin kulun.
if(nodestate(1,12,2)) //Jos induktiivinen anturi 12,2 vaikuttuu, on tila[15]=0.
tila[15]=0;
break;
}
switch(tila[16]) {
//Case 0
2 poistaa jäämäpaletit ennenkuin tila[16] aloittaa normaalin työkierron.
case 0:
nodeon(1,11,3); //Stopparit 11,3 ja 11,4 menevät päälle, päästäen paletin ylitseen.
nodeon(1,11,4);
nodeon(1,5,2); //Hissi 5,2 asetetaan yläasentoon.
break;
case 1:
//Tila[20] ohjaa hissiä 5.2 jäämäpaletteja poistettaessa ajon alussa.
switch(tila[20]) { //Tämä tilakone ohjaa tila[16]:ta jäämäpalettien poistoa.
case 0:
if(timedelay(20,4500000)){ //Ajastin laskee 4500ms, jonka jälkeen hissi 5,2 asetetaan ala-asentoon ja stoppari 5,1 menee päälle, päästäen paletin ylitseen. Lisäksi tila[20] siirtyy seuraavaan caseen.
resettimedelay(20);
nodeoff(1,5,2);
nodeon(1,5,1);
tila[20]++;
}
if(nodestate(1,4,2)) //Jos mekaaninen anturi 4,2 vaikuttuu, asetetaan hissi 5,2 yläasentoon.
nodeon(1,5,2);
break;
case 1:
//suljetaan tie seuraavalta paletilta, jotta hissillä oleva paletti ei puristuisi
if(timedelay(25,500000)){ //Ajastin laskee 500ms, jonka jälkeen stoppari 5,1 menee pois päältä estäen seuraavan paletin kulun. Lisäksi tila[20]=0.
resettimedelay(25);
nodeoff(1,5,1);
tila[20]=0;
}
break;
}
if(timedelay(16,40000000)) //Ajastin laskee 40000ms, jonka aikana jäämäpalettien poisto tapahtuu, minkä jälkeen tila[16] siirtyy seuraavaan caseen.
tila[16]++;
break;
case 2:
nodeoff(1,11,3); //Stopparit 11,3, 11,4 ja 5,1 menevät pois päältä, estäen seuraavan paletin kulun.
nodeoff(1,11,4);
nodeoff(1,5,1);
nodeoff(1,5,2); //Hissi 5,2 asetetaan ala-asentoon.
tila[16]=3; //Tila[16]=3.
break;
case 3:
strcpy(tilan_viesti[16],"11.1");
nodeon(1,11,3); //Stoppari 11,3 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,11,1)) //Jos induktiivinen anturi 11,1 vaikuttuu, tila[16] siirtyy seuraavaan caseen.
tila[16]++;
break;
case 4:
strcpy(tilan_viesti[16],"11.2");
nodeoff(1,11,3); //Stoppari 11,3 menee pois päältä, estäen seuraavan paletin kulun.
if(nodestate(1,11,2)) //Jos induktiivinen anturi 11,2 vaikuttuu, siirtyy tila[16] seuraavaan caseen.
tila[16]++;
break;
//robotin toiminta:
case 5:
//Viive että robotti ehtii toimia
strcpy(tilan_viesti[16],"ajastin 2s");
//testiä:
//onko tila 11.2 aktiivinen, ts. onko paletti tullut noodille
if(nodestate(1,11,2)) {
//koska robotti ei tiedä mikä paletti tulee pisteelle, niin katsotaan
//millä paletilla sijainti = 2, sijainti asetetaan tila[6]:ssa
for (int i = 0; i <= 9; i++) {
if (p[i].sijainti == 2) { //paletti on nyt robolla.
//kommentoi if-lause pois jos et halua että paletti pysähtyy robolle:
if (nodestate(2, 2, 1)) {
//kun sr6:n työvaihe on valmis niin se kuittaa
//noodin 2,2,1 päälle. Jolloin stopperi pois päältä ja kasvatetaan tilaa eteenpäin.
nodeoff (1, 11, 2);
tila[16]++;
}
}
}
/* vanha timerillä toimiva setti:
for (int i = 0; i <= 9; i++) {
if (p[i].sijainti == 2) {
if (timedelay(16, 33000000)) {
//nodeoff(1, 11, 2);
tila[16]++;
}
}
}*/
}
/* if(timedelay(16,2000000)) //2000ms
tila[16]++; */
break;
case 6:
strcpy(tilan_viesti[16],"4.1");
nodeon(1,11,4); //Stoppari 11,4 menee päälle, päästäen paletin ylitseen.
nodeoff(1,5,2); //Hissi asetetaan ala-asentoon.
nodeon(1,5,1); //Stoppari 5,1 menee päälle, päästäen paletin ylitseen.
if(nodestate(1,4,1)) //Jos 4,1 on vaikuttunut, tila[16] siirtyy seuraavaan caseen.
tila[16]++;
break;
case 7:
strcpy(tilan_viesti[16],"4.2, tila[17]");
nodeoff(1,11,4); //Stopparit 11,4 ja 5,1 menevät pois päältä, estäen seuraavan paletin kulun.
nodeoff(1,5,1);
if(nodestate(1,4,2) && tila[17]==1) //Jos mekaaninen anturi 4,2 vaikuttuu ja tila[17]=1, siirtyy tila[16] seuraavaan caseen.
tila[16]++;
break;
case 8:
strcpy(tilan_viesti[16],"ajastin 1400ms");
nodeon(1,5,2); //Hissi 5,2 asetetaan yläasentoon.
if(timedelay(16,1400000)) tila[16]=3; //Ajastin laskee 1400ms, jonka jälkeen tila[16]=3.
break;
}
switch(tila[17]) {
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
strcpy(tilan_viesti[17],"31.1, tila[14]");
if(nodestate(1,31,3) && tila[14]==2) //Jos induktiivinen anturi 31,3 aktivoituu ja tila[14]=2, siirtyy tila[17] seuraavaan caseen.
tila[17]++;
break;
case 2:
strcpy(tilan_viesti[17],"31.2");
nodeon(1,29,4); //Stoppari 29,4 menee päälle, päästäen paletin ylitseen.
nodeon(1,30,1); //Hissi asetetaan yläasentoon.
nodeoff(1,30,2);
tila[14]=3; //Tila[14]=3.
if(timedelay(17,500000)){ //Ajastin laskee 500ms, jonka jälkeen stoppari 29,4 menee pois päältä, estäen seuraavan paletin kulun ja tila[17] siirtyy seuraavaan caseen.
nodeoff(1,29,4);
tila[17]++;
}
break;
case 3:
if(nodestate(1,31,2)) //Jos mekaaninen anturi 31,2 vaikuttuu, on tila[17]=1.
tila[17]=1;
break;
}
switch(tila[18]) {
//Case 0
2 poistaa jäämäpaletit ennen kuin tila[18] aloittaa normaalin työkierron.
case 0:
nodeon(1,18,3); //Stopparit 18,3 ja 18,4 menevät päälle, päästäen paletin ylitseen.
nodeon(1,18,4);
nodeon(1,15,4); //Hissi 15,4 asetetaan yläasentoon.
break;
case 1:
//Tila[21] ohjaa hissiä 15.4, jäämäpaletteja poistettaessa ajon alussa tässä casessa.
switch(tila[21]) { //Tämä tilakone ohjaa tila[18]:ta jäämäpalettien poistoa.
case 0:
if(timedelay(21,4500000)){ //Ajastin laskee 4500ms, jonka jälkeen hissi 15,4 asetetaan ala-asentoon ja stoppari 15,3 menee päälle, päästäen paletin ylitseen. Lisäksi tila[21] siirtyy seuraavaan caseen.
resettimedelay(21);
nodeoff(1,15,4);
nodeon(1,15,3);
tila[21]++;
}
if(nodestate(1,15,2)) //Jos mekaaninen anturi 15,2 vaikuttuu, asetetaan hissi 15,4 yläasentoon.
nodeon(1,15,4);
break;
case 1:
//suljetaan tie seuraavalta paletilta, jotta hissillä oleva paletti ei puristu.
if(timedelay(21,500000)){ //Ajastin laskee 500ms, jonka jälkeen stoppari 15,3 menee pois päältä estäen seuraavan paletin kulun. Lisäksi tila[21]=0.
resettimedelay(21);
nodeoff(1,15,3);
tila[21]=0;
}
break;
}
if(timedelay(18,45000000)) //Ajastin laskee 45000ms, jonka aikana jäämäpalettien poisto tapahtuu. Lisäksi tila[18] siirtyy seuraavaan caseen.
tila[18]++;
break;
case 2:
nodeoff(1,18,3); //Stopparit 18,3, 18,4 ja 15,3 menevät pois päältä, estäen seuraavan paletin kulun.
nodeoff(1,18,4);
nodeoff(1,15,3);
nodeoff(1,15,4); //Hissi 15,4 asetetaan ala-asentoon.
tila[18]=3; //Tila[18]=3.
break;
case 3:
strcpy(tilan_viesti[18],"18.1");
nodeon(1,18,3); //Stoppari 18,3 menee päälle, päästäen paletin ylitseen.
nodeoff(1,15,4); //Hissi 15,4 asetetaan ala-asentoon.
if(nodestate(1,18,1)) //Jos induktiivinen anturi 18,1 aktivoituu, siirtyy tila[18] seuraavaan caseen.
tila[18]++;
break;
case 4:
//Viive robotin toimintaa varten
strcpy(tilan_viesti[18],"ajastin 2s");
nodeoff(1,18,3); //Stoppari 18,3 menee pois päältä, estäen seuraavan paletin kulun.
//testiä:
//paletti robolla n+1 s.
if(nodestate(1, 18, 2)) {
for (int i = 0; i <= 9; i++) { //tsekataan millä paletilla sijainti ==3
if (p[i].sijainti == 3) { //sijainti asetetaan rfid:llä 3, tila[10].
if (timedelay(16, 33000000))
tila[18]++;
}
}
}
/*if(timedelay(18,2000000)) //Ajastin laskee 2000ms, jonka jälkeen tila[18] siirtyy seuraavaan caseen.
tila[18]++;
*/
break;
case 5:
strcpy(tilan_viesti[18],"15.2");
nodeon(1,18,4); //Stoppari 18,4 ja 15,3 menevät päälle, päästäen seuraavan paletin ylitseen.
nodeon(1,15,3);
if(nodestate(1,15,2) && tila[19]==1) //Jos mekaaninen anturi 15,2 aktivoituu ja tila[19]=1, siirtyy tila[18] seuraavaan caseen.
tila[18]++;
break;
case 6:
strcpy(tilan_viesti[18],"ajastin 2s");
nodeon(1,15,4); //Hissi 15,4 asetetaan yläasentoon.
nodeoff(1,18,3); //Stopparit 18,3, 18,4 ja 15,3 menevät pois päältä, estäen seuraavan paletin kulun.
nodeoff(1,18,4);
nodeoff(1,15,3);
if(timedelay(18,2000000)) //Ajastin laskee 2000ms, jonka jälkeen tila[18]=3.
tila[18]=3;
break;
}
switch(tila[19]) {
case 0:
//Tämä tyhjä case on anturin toiminnan parantamiseksi, jos anturilla on paletti ajon alussa.
break;
case 1:
strcpy(tilan_viesti[19],"13.3, tila[9]");
if(nodestate(1,13,3) && tila[9]==0) { //Jos induktiivinen anturi 13,3 aktivoituu ja tila[9]=0, niin tila[19] siirtyy seuraavaan caseen.
tila[19]++;
}
break;
case 2:
strcpy(tilan_viesti[19],"ajastin 500ms");
nodeon(1,14,3); //Stoppari 14,3 aktiovoituu, päästäen paletin ylitseen.
nodeon(1,14,2); //Hissi 14,2 asetetaan yläasentoon.
tila[9]=1; //Tila[9]=1
if(timedelay(19,500000)){ //Ajastin laskee 500ms, jonka jälkeen stoppari 14,3 menee pois päältä, estäen seuraavan paletin kulun ja tila[19]=1.
nodeoff(1,14,3);
tila[19]=1;
}
break;
case 3:
strcpy(tilan_viesti[19],"ajastin 1500ms");
if (nodestate(1,13,2)) //Jos mekaaninen anturi 13,2 vaikuttuu, niin tila[19]=1.
tila[19]=1;
break;
}
// Printataan tilakoneiden ja palettien tilat
VT100::goxy(0,0);
for(int i=0;i<=19;i++)
printf("Tila[%d]: %d ,Viesti :%s\n", i, tila[i],tilan_viesti[i]);
for(int i=1;i<=12;i++)
printf("Paletti[%d]: Kohde: %d Kierrokset: %d Aktiivinen :%i\n",i,p[i].kohde(),p[i].kierros(),p[i].aktiivisuus());
// Printataan RFID-lukijoiden tilat
for(int i=1;i<=3; i++) printf("Lukija[%d]: %d \n",i, lukija[i]);
// Printataan ohjelman nopeus
if(!timedelay(31,1000000)) laskuri++;
else { printf("%d kierrosta/s\n",laskuri); laskuri=0;}
}
// Hoidetaan CAN-kommunikaatio
// Lähetetään kaikki RPDOt joiden tilat ovat muuttuneet
can.send_only_changed_rpdos();
can.sync();
// Käydään lukemassa kaikki meille lähtetyt CAN viestit.
// Nukumme hetken kierrosten välissä jos ei useita samoja TDPO paketteja.
// Jos on samoja käsittelemme ne heti uudestaan jotta eivät jää puskuriin ja käsittelemättä.
can.read_all_messages();
u_sleep(4000);
}
while(!key(VK_ESCAPE)); // ESC näppäimen painallus lopettaa ohjelman suorituksen
VT100::clearscreen();
printf("\nSystem Shutdown !\n");
printf("Wait a few seconds for all devices to go down !\n");
// Ohjelma lopetaan.
// Asetetaan kaikki outputit nollatilaan.
// Nollataan kaikki outputit yksi kerrallaan pienin väliajoin jotta ei tule sähköpiikkiä
for (int i=1 ; i<32 ; i++ )
for (int j=1 ; j<5 ; j++ ) {
if (nodestate(1,i,j)) { // Jos nodeon päällä niin
nodeoff(1,i,j); // Node pois päältä
can.send_only_changed_rpdos();
u_sleep(100000);//ennen 100000
}
}
u_sleep(10000);
can.stop_node(0); // Lähetetään CAN-väylälle stop-paketti kaikille nodeille jolloin noodit menevät stopped tilaan
} //if
else
VT100::clearscreen();
printf("\n\n\n\n\n\n\n\n\n\n\t\t\tYou ended the program..");
u_sleep(1000000);
//} while (valinta != 9);
/*//ehkis maailman hienoin "efekti"
printf("\n\n You ended the production line program. The application will now close");
for (int i = 0; i < 2; i++) {
printf(".");
u_sleep(1000000);
}*/
#ifdef LINUX
VT100::terminalreset();
#endif // !LINUX
fclose(pFile);
//suljetaan avattu tiedosto
decoder_closelog();
}
// *********************
// Globaalit apufunkiot
// *********************
//testiä:
// Asetetaan palettien reitit
void reittien_alustus() {
p[1].aktivoi();
p[2].aktivoi();
p[3].aktivoi();
p[4].aktivoi();
p[5].aktivoi();
p[6].aktivoi();
p[7].aktivoi();
p[8].aktivoi();
p[9].aktivoi();
p[10].aktivoi();
p[11].aktivoi();
p[12].aktivoi();
p[1].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
p[2].aseta_reitti(0,0,0,0,0,1,0,0,0,0);
p[3].aseta_reitti(0,0,0,0,1,0,1,0,0,0);
p[4].aseta_reitti(2,1,0,0,0,0,0,0,0,0);
p[5].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
p[6].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
p[7].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
p[8].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
p[9].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
p[10].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
p[11].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
p[12].aseta_reitti(0,0,0,0,0,0,0,0,0,0);
//asetetaan robojen tyovaiheet:
p[1].aseta_tyovaihe(0,0,0,0,0,0,0,0,0,0);
p[2].aseta_tyovaihe(0,0,0,0,1,0,0,1,0,0);
p[3].aseta_tyovaihe(0,0,0,0,0,0,1,0,1,0);
p[4].aseta_tyovaihe(1,2,3,2,0,0,0,0,0,0);
p[5].aseta_tyovaihe(0,0,0,0,0,0,0,0,0,0);
p[6].aseta_tyovaihe(0,0,0,0,0,0,0,0,0,0);
p[7].aseta_tyovaihe(0,0,0,0,1,0,0,1,0,0);
p[8].aseta_tyovaihe(0,0,0,0,0,0,0,0,0,0);
p[9].aseta_tyovaihe(0,0,0,0,0,0,0,0,0,0);
p[10].aseta_tyovaihe(0,0,0,0,0,0,0,0,0,0);
p[11].aseta_tyovaihe(0,0,0,0,0,0,0,0,0,0);
p[12].aseta_tyovaihe(0,0,0,0,0,0,0,0,0,0);
p[1].aseta_kierrosten_maara(2);
p[2].aseta_kierrosten_maara(2);
p[3].aseta_kierrosten_maara(2);
p[4].aseta_kierrosten_maara(1);
p[5].aseta_kierrosten_maara(2);
p[6].aseta_kierrosten_maara(2);
p[7].aseta_kierrosten_maara(2);
p[8].aseta_kierrosten_maara(1);
p[9].aseta_kierrosten_maara(2);
p[10].aseta_kierrosten_maara(2);
p[11].aseta_kierrosten_maara(2);
p[12].aseta_kierrosten_maara(2);
//laiskan miehen kierros lkm asetus, kommentoi jos et käytä
/* for (int i = 1; i <= 12; i++) {
p[i].aseta_kierrosten_maara(1);
//i++;
}*/
}
// ***************************************************
// Funktiot Noodien tilan asettamiseen ja tutkimiseen
// ***************************************************
//ottavat vastaan cannoodin (1 tai 2), slave, bitti
//asetetaan haluttu noodi päälle:
void nodeon(int CANnode, int slave, int bitti) {
if (CANnode == 1) {
if ((slave >= 1 && slave <= 31) && (bitti >= 1 && bitti <= 4)) {
if (slave < 16) {
if (slave &1)
rpdo201.set_bit((slave - 1) * 4 + bitti - 1);
else
rpdo201.set_bit((slave + 1) * 4 + bitti - 1);
}
else {
if (slave &1)
rpdo301.set_bit((slave - 17) * 4 + bitti - 1);
else
rpdo301.set_bit((slave - 15) * 4 + bitti - 1);
}
}
}
else if (CANnode == 2) {
if ((slave >= 1 && slave <= 31) && (bitti >= 1 && bitti <= 4)) {
if (slave <16) {
if (slave &1)
rpdo202.set_bit((slave -1) * 4 + bitti - 1);
else
rpdo202.set_bit((slave + 1) * 4 + bitti - 1);
}
else {
//outputteja 16-31 ei ole.
}
}
}
}
//sammutetaan haluttu noodi:
void nodeoff(int CANnode, int slave, int bitti) {
if (CANnode == 1) {
if((slave >= 1 && slave <= 31) && (bitti >= 1 && bitti <= 4)) {
if (slave < 16) {
if (slave &1)
rpdo201.clear_bit((slave - 1) * 4 + bitti - 1);
else
rpdo201.clear_bit((slave + 1) * 4 + bitti - 1);
}
else {
if (slave &1)
rpdo301.clear_bit((slave - 17) * 4 + bitti - 1);
else
rpdo301.clear_bit((slave - 15) * 4 + bitti - 1);
}
}
}
else if (CANnode == 2) {
if ((slave >= 1 && slave <= 31) && (bitti >= 1 && bitti <= 4)) { //joku mättää jossain koska virhe tulee '>=' kohdasta..
if (slave < 16) {
if (slave &1)
rpdo202.clear_bit((slave - 1) * 4 + bitti - 1);
else
rpdo202.clear_bit((slave + 1) * 4 + bitti - 1);
}
else {
//outputteja 16-31 ei ole
}
}
}
}
//tarkistetaan halutun noodin inputin tila:
bool nodestate(int CANnode, int slave, int bitti) {
bool retval;
if (CANnode == 1) {
if (slave < 16) {
if (slave &1)
retval = tpdo181.get_bit((slave - 1) * 4 + bitti - 1);
else
retval = tpdo181.get_bit((slave + 1) * 4 + bitti - 1);
}
else {
if (slave &1)
retval = tpdo281.get_bit((slave - 17) * 4 + bitti - 1);
else
retval = tpdo281.get_bit((slave - 15) * 4 + bitti - 1);
}
return(retval);
}
else if (CANnode == 2) {
if (slave < 16) {
if (slave &1)
retval = tpdo182.get_bit((slave - 1) * 4 + bitti - 1);
else
retval = tpdo182.get_bit((slave + 1) * 4 + bitti - 1);
}
else {
//inputteja 16-31 ei ole
}
return(retval);
}
}
//!vanhat node-funktiot!!!! (ennen 15.4)
/*
// Asete3tetaan jokin noodi päälle
// Parametreina ASI slaven numero ja slaven outputin numero 1-4
void nodeon(int ASiMasterID,int slave, int bitti) {
if(ASiMasterID==1)
{
if((slave>=1 && slave<=31) && (bitti>=1 && bitti<=4)) {
if(slave<16) {
if(slave &1)
rpdo201.set_bit((slave-1) * 4 + bitti -1);
else
rpdo201.set_bit((slave+1) * 4 + bitti - 1);
}
else {
if(slave &1)
rpdo301.set_bit((slave-17) * 4 + bitti - 1);
else
rpdo301.set_bit((slave-15) * 4 + bitti - 1);
}
}
}
else if(ASiMasterID==2)
{
if((slave>=1 && slave<=31) && (bitti>=1 && bitti<=4)) {
if(slave<16) {
if(slave &1)
rpdo401.set_bit((slave-1) * 4 + bitti -1);
else
rpdo401.set_bit((slave+1) * 4 + bitti - 1);
}
else { //kommentoi-->
if(slave &1)
rpdo302.set_bit((slave-17) * 4 + bitti - 1);
else
rpdo302.set_bit((slave-15) * 4 + bitti - 1);
//<---kommentoi
}
}
}
}
*/
/*
// Asetetetaan jokin noodi pois päältä
// Parametreina ASI slaven numero ja slaven outputin numero 1-4
void nodeoff(int ASiMasterID,int slave, int bitti) {
if(ASiMasterID==1)
{
if((slave>=1 && slave<=31) && (bitti>=1 && bitti<=4)) {
if(slave<16) {
if(slave &1)
rpdo201.clear_bit((slave-1) * 4 + bitti -1);
else
rpdo201.clear_bit((slave+1) * 4 + bitti - 1);
}
else {
if(slave &1)
rpdo301.clear_bit((slave-17) * 4 + bitti - 1);
else
rpdo301.clear_bit((slave-15) * 4 + bitti - 1);
}
}
}
else if(ASiMasterID==2)
{
if((slave>=1 && slave<=31) && (bitti>=1 && bitti<=4)) {
if(slave<16) {
if(slave &1)
rpdo401.clear_bit((slave-1) * 4 + bitti -1);
else
rpdo401.clear_bit((slave+1) * 4 + bitti - 1);
}
else { //kommentoi-->
if(slave &1)
rpdo302.clear_bit((slave-17) * 4 + bitti - 1);
else
rpdo302.clear_bit((slave-15) * 4 + bitti - 1);
//<---kommentoi
}
}
}
}
*/
/*
// tarkistetaan halutun noodin inputin tila
// Parametreina ASI slaven numero ja slaven outputin numero 1-4
bool nodestate(int ASiMasterID,int slave, int bitti) {
bool retval;
if(ASiMasterID==1)
{
if(slave<16) {
if(slave &1)
retval=tpdo181.get_bit((slave-1) * 4 + bitti -1);
else
retval=tpdo181.get_bit((slave+1) * 4 + bitti - 1);
}
else {
if(slave &1)
retval=tpdo281.get_bit((slave-17) * 4 + bitti - 1);
else
retval=tpdo281.get_bit((slave-15) * 4 + bitti - 1);
}
return(retval);
}
//vanha-->
else if (ASiMasterID==2)
{
if(slave<16)
{
if(slave &1)
retval=tpdo381.get_bit((slave-1) * 4 + bitti -1);
else
retval=tpdo381.get_bit((slave+1) * 4 + bitti - 1);
}
else { //kommentoi -->
if(slave &1)
retval=tpdo281.get_bit((slave-17) * 4 + bitti - 1);
else
retval=tpdo281.get_bit((slave-15) * 4 + bitti - 1); // <--- kommentoi
}
return(retval);
}//else if
}
*/
{code} |