Pustih u pogon drugu mašinu od 100KVA.
Hvuuuš (brisanje znoja). Baš sam se umorio.
Sutra ću je snimiti u radu pa postaviti ovde snimak od ove nove, revidirane i poboljšane (normalno, samo mehanika je revidirana :-)
----------------------------------------------
Predlažem da se napravi neka zona industrijske elektronike na forumu. Može zatrebati.
Sasvim solidno sam iskoristio PIC18F4620.
Pokrećem jedan servo motor, četiri cilindra, dve power grupe od po 50KVA (2 x broj sinhronizovanih mrežnih perioda + 2 pwm kao nivo snage), motor za ubacivanje poprečne žice, trobojni semafor, displej, tastaturu i RS232 komunikaciju naravno...
Očitavam limite ose , senzor za nulovanje i senzor za poprečnu žicu, temperaturu bloka, nivo vode, pedalu, sve stop pečurku, pritisak vazduha.
Čitavu mašinu sam napravio pomoću velikog broja potpuno novih i mojih rešenja-dosetki, a najviše sam ponosan na veoma zanimljivu detekciju pneumatskih cilindara.
Naime, jednim jedinim preso-prekidačem sa histerezisom od +-0.4bara detektujem sledeće stvari:
-gornji položaj sva 4 cilindra (i sve ostalo za sva 4, odnosno za 2 kada je upotrebljena ta opcija),
-tok hoda na dole,
-ostvarenje nominalne sile na elektrodama za zavarivanje,
-tok hoda na gore,
-prisustvo tačnog pritiska kao preduslova za ispravan rad (alarm pre pokretanja rada).
Naravno sve pojedinačne stavke su praćene sa WDT ili detekcijom stanja, kao i odlaskom u stanje stop sa alarmom i nazivom greške na displeju.
Ostalo mi je slobodno još 4 pina na PIC18F4620 i 84% slobodnog fleša. A EEprom je zauzet sa 920 bajta parametara. Praktično 40 grupa sa po 23 parametra po jednoj.
Dovoljno od jednog piconje prosečne "snage"...
Evo i par komada koda, ako nekog interesuje:
I na primer ono oko cilindara...
Hvuuuš (brisanje znoja). Baš sam se umorio.
Sutra ću je snimiti u radu pa postaviti ovde snimak od ove nove, revidirane i poboljšane (normalno, samo mehanika je revidirana :-)
----------------------------------------------
Predlažem da se napravi neka zona industrijske elektronike na forumu. Može zatrebati.
Sasvim solidno sam iskoristio PIC18F4620.
Pokrećem jedan servo motor, četiri cilindra, dve power grupe od po 50KVA (2 x broj sinhronizovanih mrežnih perioda + 2 pwm kao nivo snage), motor za ubacivanje poprečne žice, trobojni semafor, displej, tastaturu i RS232 komunikaciju naravno...
Očitavam limite ose , senzor za nulovanje i senzor za poprečnu žicu, temperaturu bloka, nivo vode, pedalu, sve stop pečurku, pritisak vazduha.
Čitavu mašinu sam napravio pomoću velikog broja potpuno novih i mojih rešenja-dosetki, a najviše sam ponosan na veoma zanimljivu detekciju pneumatskih cilindara.
Naime, jednim jedinim preso-prekidačem sa histerezisom od +-0.4bara detektujem sledeće stvari:
-gornji položaj sva 4 cilindra (i sve ostalo za sva 4, odnosno za 2 kada je upotrebljena ta opcija),
-tok hoda na dole,
-ostvarenje nominalne sile na elektrodama za zavarivanje,
-tok hoda na gore,
-prisustvo tačnog pritiska kao preduslova za ispravan rad (alarm pre pokretanja rada).
Naravno sve pojedinačne stavke su praćene sa WDT ili detekcijom stanja, kao i odlaskom u stanje stop sa alarmom i nazivom greške na displeju.
Ostalo mi je slobodno još 4 pina na PIC18F4620 i 84% slobodnog fleša. A EEprom je zauzet sa 920 bajta parametara. Praktično 40 grupa sa po 23 parametra po jednoj.
Dovoljno od jednog piconje prosečne "snage"...
Evo i par komada koda, ako nekog interesuje:
Code:
/*--------------------------------grupa-parametara jednog proizvoda---------------------------------*/
const char * const message_param[] =
{
"Brz.Vuce Pr:", /* 0 */ //brzina vuce napred, mm/sek, max 500mm.
"Pred-mera Pr:", /* 1 */ //polozaj centra prve zice u odnosu na pocetak uzduznih zica
"Izbaciv. Pr:", /* 2 */ //rastojanje koje ce preci okvir u svrhu izbacivanja ili ostavljanja na poziciji
"Izbor para Pr:", /* 3 */ //izbor parova pow grupa i elektroda, levi ili oba
"Br.kor. F1 Pr:", /* 4 */ //broj koraka u prvoj fazi, uvek jedan manje od ukupnog, prva zica nije korak !!!
"Duz.kor.F1 Pr:", /* 5 */ //duzina koraka u prvoj fazi u mm.
"Peri.1 F1 Pr:", /* 6 */ //vreme zavarivanja leve (1.) power grupe, u mreznim periodama
"Snaga1 F1 Pr:", /* 7 */ //snaga leve power grupe (50KVA), u %, solidno linearizovana (TCA785, 2K2 pin 11)
"Peri.2 F1 Pr:", /* 8 */ //vreme zavarivanja desne (2.) power grupe, u mreznim periodama
"Snaga2 F1 Pr:", /* 9 */ //snaga desne power grupe, u %
"Br.kor. F2 Pr:", /*10 */ //kao i kod prve faze procesa, samo je ovde druga faza
"Duz.kor.F2 Pr:", /*11 */
"Peri.1 F2 Pr:", /*12 */
"Snaga1 F2 Pr:", /*13 */
"Peri.2 F2 Pr:", /*14 */
"Snaga2 F2 Pr:", /*15 */
"Br.kor. F3 Pr:", /*16 */ //kao i kod druge faze procesa, samo je ovde treca faza
"Duz.kor.F3 Pr:", /*17 */
"Peri.1 F3 Pr:", /*18 */
"Snaga1 F3 Pr:", /*19 */
"Peri.2 F3 Pr:", /*20 */
"Snaga2 F3 Pr:", /*21 */
"Opcija Pr:" /*22 +1 = velic_grupe = ukupni broj parametara u jednoj grupi. */
/*
* param. 22 je izbor opcije rada, tj. 0=automatski povratak rama, 1=cekaj pedalu
* za povratak, 2=simulacija procesa bez zavarivanja i ubacivanja zice,
* SVE TRI OPCIJE(0,1,2) VAZE ZA OKRUGLU MERU KORAKA U mm !!!
* Kada je u pitanju jedan jedini izuzetak sa korakom 52,5mm onda:
* 3=automatski povratak rama, 4=cekaj pedalu za povratak, 2=simulacija procesa bez
* zavarivanja i ubacivanja zice,
* SVE TRI OPCIJE (3,4,5) SU SA UVECANJEM KORAKA ZA +0,5mm na unesenu meru koraka !!!
* Saznao sam za postojanje neokrugle mere tek po zavrsenom projektu! Nije vredno truda
* pisati iznova ceo program zbog jednog izuzetka.
* Novi izuzeci su sve resetke!!! Kod njih je fiksna pred mera 88,5mm.
* Za tu svrhu u param[opcija] su dodate stavke 6,7 i 8. 6=resetke sa autom. povratkom,
* 7=resetke, cekaj pedalu za povratak, 8=resetke, simulacija, cekaj pedalu za povratak.
*/
};
//--------------------------jedinice u kojima su parametri, drugi red parametara-----------------
const char * const message_jedinice[] =
{
" x10 mm/sek", /* 0 */
" mm. ", /* 1 */
"x10mm.", /* 2 */
" 1=levi 2=oba",/* 3 */
" koraka", /* 4 */
" mm. ", /* 5 */
" perioda", /* 6 */
" % ", /* 7 */
" perioda", /* 8 */
" % ", /* 9 */
" koraka", /*10 */
" mm. ", /*11 */
" perioda", /*12 */
" % ", /*13 */
" perioda", /*14 */
" % ", /*15 */
" koraka", /*16 */
" mm. ", /*17 */
" perioda", /*18 */
" % ", /*19 */
" perioda", /*20 */
" % ", /*21 */
" po uputstvu" /*22 +1= velic_grupe = ukupni broj parametara u jednoj grupi. */
};
#define velic_grupe 23
/*------------------------------------------------------------------------------*/
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
const dwn_limit[]={ 1, 62, 10, 1, 0, 15, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0};
const up_limit[]= { 50,250,100, 2, 25, 70, 50,100, 50,100, 25, 70, 50,100, 50,100, 25, 70, 50,100, 50,100, 8};
/*gornji i donji limiti zadavanja param., broj elemenata = velic_grupe */
/* postoji i kontrola mesta zapete, broja decimala i predznaka, videti u "beliscanka.c" ili ranije */
#define broj_grupa 40 /* max 1009 byte eeproma, velic_grupe x broj_grupa */
//trenutno 920 parametara velicine BYTE
/*--------------------------------------------------------------*/
UBYTE param[velic_grupe];/* velic_grupe */ //array sadrzaja trenutno koriscene grupe, ucitana iz EE, u main();
/*------------------------------------------------------------------------------------------*/
/*-----------ofset vezan za msg_param, olaksano uzimanje konkr. parametra----*/
const
//---------------zajednicki----------------------------------------------------
brz_vuce=0,
predmera=1,
izbaci=2,
parovi=3,
//---------------prva faza procesa--------------------------------------------
br_korF1=4,
duz_korF1=5,
per1F1=6,
pow1F1=7,
per2F1=8,
pow2F1=9,
//---------------druga faza procesa--------------------------------------------
br_korF2=10,
duz_korF2=11,
per1F2=12,
pow1F2=13,
per2F2=14,
pow2F2=15,
//---------------treca faza procesa--------------------------------------------
br_korF3=16,
duz_korF3=17,
per1F3=18,
pow1F3=19,
per2F3=20,
pow2F3=21,
//--------------pedala za povratak okvira kod rucnog vadjenja komada i simulaciju proc------------
opcija=22;
/*ima ih koliko i elemenata grupe */
/* npr: param[parovi]; */
/*------------------------------------------------------------------------------------------*/
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
union //brojac koji se brise
{
struct {
UWORD brojac;
}cuvar_br;
UBYTE var_br[2];
}brojac_vars;
//-----------------------------------------
union //brojac koji se ne brise
{
struct {
UWORD abrojac_l;
UWORD abrojac_h;
}acuvar_br;
UBYTE avar_br[4];
}abrojac_vars;
/*-------------------------------------------------------------------------------------------*/
/*===========================================================================================*/
/*-------------------------------------------------------------------------------------------*/
void processor_init(void) //konfiguracija pinova i SFR
{
/*--------------------------------------------------------------------------*/
TRISA = 0b11111111;
TRISB = 0b11111111;
TRISC = 0b10010000;/* u slucaju koriscenja hardverskog i2c, obavezno postaviti RC3,RC4 kao ulaze */
TRISD = 0b00000000;
TRISE = 0b00000111;
/*------------------------ovo je slucaj 24in/out, 4-8-12-20 in, 20-12-8-4 out---------------------*/
/*---------------------------------------------------------------------------*/
//TRISA = 0b11111111; //radi sa i2c ekspanderima za sve izlaze
//TRISB = 0b11111111;
//TRISC = 0b11111000;/* u slucaju koriscenja hardverskog i2c, obavezno postaviti RC3,RC4 kao ulaze */
//TRISD = 0b11111111;/* kada se koriste pwm1 i pwm2, RC1 i RC2 postaviti kao izlaze. */
//TRISE = 0b00000111;
/*-----------------------ovo je slucaj sa i2c expanderima, 54 in/out, 22-30 in, 32-24 out----------*/
/*-----------------------------------------------------------------------------*/
ADCON1 = 0b00001111; /* adc off */ //4620
CMCON = 0b00000111; /* comparators off */ //4620
/*----------------------------------------------------------------------------- */
/* pwm 1 i/ili 2 , za 10 bita, res 0-1000 */
//PR2 = 0xFF;
//T2CON = 0b00000101;
//CCP1CON = 0b00001100; //pwm1
//CCP2CON = 0b00001100; //pwm2
/*-----------------------------------------------------------------------------*/
/* pwm 1 i/ili 2 , za 8 bita(res 0-100),T2CON,b0,b1; ako je preskaler 11=6,25KHz, 01=25KHz, 00=99KHz */
PR2 = 99;
T2CON = 0b00000101;// trenutno 25KHz
CCP1CON = 0b00001100; //pwm1
CCP2CON = 0b00001100; //pwm2
/*------------------------------------------------------------------------------*/
RCON = 0; /* Compatibility mode. Priority disabled. interapti */
T0CON = 0b00000010; /* prescaler 1:8, int clk, disabled */
INTCON = 0b10100000; /* GIE,TMR0IE = 1 */
//timer1
// PIR1 = 0b00000000; /* (0)TMR1IF */
// PIE1 = 0b00000001; /* (0)TMR1IE */
// IPR1 = 0b00000001; /* (0)TMR1IP */
// T1CON = 0b00000000; /* */
/*------------------------------------------------------------------------------*/
//setovanje svih in/out u nisko stanje
PORTA=0x00; PORTB=0x00; PORTC=0x00; PORTD=0x00; PORTE=0x00;
CCPR1L=0; CCPR2L=0;
}
/*----------------------------------------------------------------------------------------------*/
/*-------------------------- INTERRUPT HANDLER -----------------------------------------------*/
bit timeout; //globalne var., vezane za isr
bit timer0_blink;
UWORD timer1ms,timer10ms,timer100ms,Timer0H,Timer0L;
void interrupt int_hand (void)
{
/*----------------- merenje vremena, wdt, ili pulse gen..---------*/
/* za 1ms H=0xFE,L=0xCA tj.65226 */ //ako se unosi kao fiksan
/* za 10mS H=0xF3,L=0xF2 tj.62450 */
/* za 100mS H=0x86,L=0xC4 tj.34500 */....
I na primer ono oko cilindara...
Code:
//////////////////end switch master state masine///////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
if(n_vode)err_no=err_voda; //nedovoljan nivo vode za hladjenje
if(esc_test())err_no=err_ciklus; //stop esc tasterom
if(not_aus)err_no=err_n_aus; //stop pecurkom
///////////////////////////////////////////////////////////////////////////////
//////////////////////////operativni task//////////////////////////////////////
switch(operate_seq_no){
case 0: //stop,pasivno stanje
cilindar1par=0; cilindar2par=0;
enable1=0; enable2=0;
break;
//-------------------------------------------------------------
case 1: //cilindri,polazak na dole, kontrola pada pritiska, dokaz kretanja.
if(operate_jump){
calculate_tmr0(5); //10mS za TMR0
timer10ms=50; //500mS WDT
switch(param[parovi]){ //izbor parova cilindara prema parametrima proizvoda
case 1:
cilindar1par=1; cilindar2par=0;
break;
case 2:
cilindar1par=1; cilindar2par=1;
break;
}
timeout=0; //start WDT
operate_jump=0;
}
else{
if(timeout)err_no=err_p_vazd;
if(p_vazduha){
operate_jump=1;operate_seq_no=2;
}
}
break;
//---------------------------------------------------------------
case 2: //cilindri, predstezanje, kontrola postignutog pritiska radi preciznog zavara (presoprekidac)
if(operate_jump){
calculate_tmr0(5); //10mS za TMR0
timer10ms=50; //500mS WDT
timeout=0; //start WDT
operate_jump=0;
}
else{
if(timeout)err_no=err_p_vazd;
if(!p_vazduha){ //zavrseno predstezanje, pritisak ok.
//najbrzi metod, realno vreme ostvarenja nominalnog pritiska sa krajnje minimalnim cekanjem
if((param[opcija]==2)||(param[opcija]==5)||(param[opcija]==8)){
operate_jump=1;operate_seq_no=4; //preskoci zavar ako je simulacija
}
else{ //inace zavari
operate_jump=1;operate_seq_no=3;
}
}
}
break;
//-----------------------------------------------------------------
case 3: //zavari
if(operate_jump){
switch(seq_no){ //ucitavanje vremena zavara konkretne faze procesa
case 3:
temp_per1=param[per1F1]; temp_per2=param[per2F1]; //broj perioda obe power grupe, faza 1.
break;
case 4:
temp_per1=param[per1F2]; temp_per2=param[per2F2]; //broj perioda obe power grupe, faza 2.
break;
case 5:
temp_per1=param[per1F3]; temp_per2=param[per2F3]; //broj perioda obe power grupe, faza 3.
break;
case 6: //slucaj zavara poslednje zice
temp_per1=param[per1F3]; temp_per2=param[per2F3]; //broj perioda obe power grupe, faza 3.
break;
}
RS_jump=1; RSseq_no=1; //start sync+brojanje_per taska, 1.power grupe, 50KVA
ST_jump=1; STseq_no=1; //start sync+brojanje_per taska, 2.power grupe, 50KVA
operate_jump=0;
}
else{
if((RSseq_no==3)&&(STseq_no==3)){ // oba sync taska zavrsili?
RSseq_no=0;STseq_no=0; //vracanje RS i ST taskova u pasivno stanje
operate_jump=1;operate_seq_no=4;
}
}
break;
//---------------------------------------------------------------
case 4: //digni cilindre, kontrola pada pritiska, dokaz kretanja.
if(operate_jump){ //i eventualno ubaci sledecu zicu, optimizacija vremena masine
calculate_tmr0(5); //10mS za TMR0
timer10ms=200; //1000mS WDT, 6 pokusaja za zicu.
cilindar1par=0; cilindar2par=0;
vazduh_flag=0;zica_flag=0;
delay_ms(50);
if((param[opcija]==2)||(param[opcija]==5)||(param[opcija]==8)||(end_flag))zica_flag=1;
//ako je simulacija ili jedan zavar, omoguci nastavak kod simulacije ili samo jednog zavara
else{
if((!pedala)&&(!pedala_flag))motorce=0;
else motorce=1; //inace ubaci zicu
}
timeout=0; //start WDT
operate_jump=0;
}
else{
if(timeout){
if((param[opcija]==2)||(param[opcija]==5)||(param[opcija]==8)||(end_flag));
//ako je simulacija ili samo jedan zavar
else{
if(senz_zice)l_err_no=l_err_zica; //inace wdt prolaza zice
}
}
if(!senz_zice){motorce=0;zica_flag=1;} //prosla zica?
//if(p_vazduha)
vazduh_flag=1; //krenuli cilindri
if(l_err_no==l_err_zica){
operate_jump=1;operate_seq_no=5; //idi na pauzu
}
if((!pedala_flag)&&(!pedala)){
operate_jump=1;operate_seq_no=5; //idi na pauzu
}
if((vazduh_flag)&&(zica_flag)){ //ispunjena oba uslova
if((!temp_br_kor)||(!temp_duz)){
vazduh_flag=0;zica_flag=0;
operate_jump=1;operate_seq_no=8; //kod poslednjeg zavara, bez povlacenja
}
else{
vazduh_flag=0;zica_flag=0;
operate_jump=1;operate_seq_no=7; //inace povuci
}
}
}
break;
//--------------------------------------------------------------------
case 5: //pauza ili l_err
if(operate_jump){
motorce=0;
clr_line2();
lcd_goto(line2);
if(!pedala) lcd_puts("Pauza ");
if(l_err_no==l_err_zica)lcd_puts("Pauza, ZICA!!! ");
red=1;
operate_jump=0;
}
else{
if(!pedala)operate_seq_no=5; //cekaj pustenu
else operate_seq_no=6; //idi na cekanje stisnute
}
break;
//-----------------------------------------------------------------
case 6:
if(pedala)operate_seq_no=6;
else{
clr_line2(); red=0;l_err_no=0; //pocisti upozorenja
pedala_flag=1; //bila stisnuta za izlazak
operate_jump=1;operate_seq_no=4; //pokusaj opet zicu
}
break;
//---------------------------------------------------------------------
case 7: //povuci sledeci korak , servo motor.
if(operate_jump){
delay_ms(350);
dir=napred; //smer vuce, obavezno zbog postojanja povratka
servo_jump=1;servo_seq_no=1; //start servo taska
operate_jump=0;
}
else{
if(servo_seq_no==2){ //servo zavrsio?
servo_jump=0;servo_seq_no=0; //stavljanje servo taska u pasivno stanje
operate_jump=1;operate_seq_no=8; //zavrsio servo, sledece.
}
}
break;
//------------------------------------------------------------------
case 8: //verifikacija da su cilindri gore, pritiskom.
if(operate_jump){
calculate_tmr0(5); //10mS za TMR0
timer10ms=50; //500mS WDT
timeout=0; //start WDT
operate_jump=0;
}
else{
if(timeout)err_no=err_p_vazd;
if(!p_vazduha){ //gore su, pritisak ok.
operate_jump=1;operate_seq_no=9;
}
}
break;
//----------------------------------------------------------------------
case 9: //brojanje koraka doticne faze, eventualno ponavljanje.
if(operate_jump){
pedala_flag=0;
if(temp_br_kor>0)temp_br_kor--;
operate_jump=0;
}
else{
if(temp_br_kor<1){
operate_jump=0;operate_seq_no=10; //ako nema vise
}
else{
operate_jump=1;operate_seq_no=1; //izvrsi preostale korake
}
}
break;
//-----------------------------------------------------------------------
case 10: //indikator zavrsetka doticne faze procesa, pasivno stanje.
cilindar1par=0; cilindar2par=0;
enable1=0; enable2=0;
break;
}///////////////////////end operativni task///////////////////////////////////