1068 lines
34 KiB
C#
1068 lines
34 KiB
C#
using CMSCncLib.CNC;
|
||
using MTC;
|
||
using SCMA.AdapterCom;
|
||
using Siemens.Sinumerik.Operate.Services;
|
||
using System;
|
||
using System.Text;
|
||
|
||
namespace SCMA
|
||
{
|
||
public class AdapterSiemens : AdapterGeneric
|
||
{
|
||
/// <summary>
|
||
/// Oggetto MAIN x connessione SIEMENS
|
||
/// </summary>
|
||
protected SIEMENS SIEMENS_ref;
|
||
/// <summary>
|
||
/// Area di memoria "Top" che contiene le informazioni principali x adpter (da scompattare), dato overhead lettura la leggiamo sempre tutta poi alla bisogna processamento...
|
||
/// </summary>
|
||
public byte[] MemBlockTop = new byte[284];
|
||
/// <summary>
|
||
/// Vettore posizione assi (MAX 16...)
|
||
/// </summary>
|
||
public uint[] axisPosData = new uint[16];
|
||
|
||
/// <summary>
|
||
/// Area di memoria base x MTConnect con SIEMENS (DB1499)
|
||
/// </summary>
|
||
protected int baseMemDb = 1499;
|
||
/// <summary>
|
||
/// Area di memoria base x dati ASSI (241)
|
||
/// </summary>
|
||
protected int baseMemAx = 241;
|
||
/// <summary>
|
||
/// Area di memoria base x dati UTENSILE (DB253)
|
||
/// </summary>
|
||
protected int baseMemUT = 253;
|
||
/// <summary>
|
||
/// Area di memoria base x dati TESTE (DB254)
|
||
/// </summary>
|
||
protected int baseMemUO = 254;
|
||
/// <summary>
|
||
/// Oggetto appoggio memorie dati UT
|
||
/// </summary>
|
||
protected SIEMENS.UtData ValUT;
|
||
|
||
/// <summary>
|
||
/// wrapper chiamata lettura/scrittura SINGOLO BYTE...
|
||
/// </summary>
|
||
/// <param name="bWrite"></param>
|
||
/// <param name="MemType">main address (1499/1500)</param>
|
||
/// <param name="memIndex"></param>
|
||
/// <param name="Value"></param>
|
||
/// <returns></returns>
|
||
public bool SIEMENSMemRW_Byte(bool bWrite, int MemType, Int32 memIndex, ref byte Value)
|
||
{
|
||
bool answ = false;
|
||
if (SIEMENS_ref.Connected)
|
||
{
|
||
try
|
||
{
|
||
parentForm.commPlcActive = true;
|
||
// chiamo la versione multibyte...
|
||
byte[] ValArray = new byte[1];
|
||
SIEMENSMemRW_Byte(bWrite, MemType, memIndex, ref ValArray);
|
||
Value = ValArray[0];
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("Eccezione in SIEMENSMemRW_Byte: {0}{1}", Environment.NewLine, exc));
|
||
}
|
||
}
|
||
parentForm.commPlcActive = false;
|
||
return answ;
|
||
}
|
||
/// <summary>
|
||
/// wrapper chiamata lettura/scrittura MULTI BYTE...
|
||
/// </summary>
|
||
/// <param name="bWrite"></param>
|
||
/// <param name="MemType">main address (1499/1500)</param>
|
||
/// <param name="memIndex"></param>
|
||
/// <param name="MATRICE Value"></param>
|
||
/// <returns></returns>
|
||
public bool SIEMENSMemRW_Byte(bool bWrite, int MemType, Int32 memIndex, ref byte[] Value)
|
||
{
|
||
bool answ = false;
|
||
if (SIEMENS_ref.Connected)
|
||
{
|
||
try
|
||
{
|
||
parentForm.commPlcActive = true;
|
||
answ = SIEMENS_ref.S_RW_Byte(bWrite, MemType, memIndex, ref Value);
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("Eccezione in SIEMENSMemRW_ByteArray: {0}{1}", Environment.NewLine, exc));
|
||
}
|
||
}
|
||
parentForm.commPlcActive = false;
|
||
return answ;
|
||
}
|
||
/// <summary>
|
||
/// wrapper chiamata lettura/scrittura MULTI Word...
|
||
/// </summary>
|
||
/// <param name="bWrite"></param>
|
||
/// <param name="MemType">main address (1499/1500)</param>
|
||
/// <param name="memIndex"></param>
|
||
/// <param name="MATRICE Value"></param>
|
||
/// <returns></returns>
|
||
public bool SIEMENSMemRW_Word(bool bWrite, int MemType, Int32 memIndex, ref ushort[] Value)
|
||
{
|
||
bool answ = false;
|
||
if (SIEMENS_ref.Connected)
|
||
{
|
||
try
|
||
{
|
||
parentForm.commPlcActive = true;
|
||
answ = SIEMENS_ref.S_RW_Word(bWrite, MemType, memIndex, ref Value);
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("Eccezione in SIEMENSMemRW_Word: {0}{1}", Environment.NewLine, exc));
|
||
}
|
||
}
|
||
parentForm.commPlcActive = false;
|
||
return answ;
|
||
}
|
||
/// <summary>
|
||
/// wrapper chiamata lettura/scrittura MULTI DWord...
|
||
/// </summary>
|
||
/// <param name="bWrite"></param>
|
||
/// <param name="MemType">main address (1499/1500)</param>
|
||
/// <param name="memIndex"></param>
|
||
/// <param name="MATRICE Value"></param>
|
||
/// <returns></returns>
|
||
public bool SIEMENSMemRW_DWord(bool bWrite, int MemType, Int32 memIndex, ref uint[] Value)
|
||
{
|
||
bool answ = false;
|
||
if (SIEMENS_ref.Connected)
|
||
{
|
||
try
|
||
{
|
||
parentForm.commPlcActive = true;
|
||
answ = SIEMENS_ref.S_RW_DWord(bWrite, MemType, memIndex, ref Value);
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("Eccezione in SIEMENSMemRW_DWord: {0}{1}", Environment.NewLine, exc));
|
||
}
|
||
}
|
||
parentForm.commPlcActive = false;
|
||
return answ;
|
||
}
|
||
/// <summary>
|
||
/// wrapper chiamata lettura/scrittura MULTI Float...
|
||
/// </summary>
|
||
/// <param name="bWrite"></param>
|
||
/// <param name="MemType">main address (1499/1500)</param>
|
||
/// <param name="memIndex"></param>
|
||
/// <param name="MATRICE Value"></param>
|
||
/// <returns></returns>
|
||
public bool SIEMENSMemRW_Float(bool bWrite, int MemType, Int32 memIndex, ref float[] Value)
|
||
{
|
||
bool answ = false;
|
||
if (SIEMENS_ref.Connected)
|
||
{
|
||
try
|
||
{
|
||
parentForm.commPlcActive = true;
|
||
answ = SIEMENS_ref.S_RW_Real(bWrite, MemType, memIndex, ref Value);
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("Eccezione in SIEMENSMemRW_Float: {0}{1}", Environment.NewLine, exc));
|
||
}
|
||
}
|
||
parentForm.commPlcActive = false;
|
||
return answ;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Vettore degli allarmi CNC attivi
|
||
/// </summary>
|
||
public Alarm[] allarmiCNC;
|
||
|
||
/// <summary>
|
||
/// estende l'init della classe base...
|
||
/// </summary>
|
||
/// <param name="caller">FORM chaimante</param>
|
||
/// <param name="adpConf">CONFIGURAZIONE adapter</param>
|
||
/// <param name="gatewayObj">OGGETTO gestione comunicazione OUT (tipologia e metodi)</param>
|
||
public AdapterSiemens(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj)
|
||
{
|
||
// !!!HARD CODED!!! aggiunto banco STATUS del 2 processo IN CODA... (4+1)DW=20byte x strobes...!!!
|
||
Strobes = new byte[20];
|
||
|
||
//fix dimensione memorie MST: 26 short(16bit) x (11+6+6) aree (attenzione: secondo set di 2 bit è VUOTO...)
|
||
MemBlock_MST = new byte[46];
|
||
// salto NON necessario!
|
||
saltoMST = 0;
|
||
// è little endian (SERVE conversione)
|
||
hasBigEndian = true;
|
||
|
||
lg.Info("Start init Adapter SIEMENS");
|
||
|
||
parentForm.commPlcActive = true;
|
||
Runtime.CreateNC(CNC.NcType.SIEMENS, utils.CRS("ipPLC"));
|
||
parentForm.commPlcActive = false;
|
||
|
||
// inizializzo posizioni assi...
|
||
prevPosAxis = new double[adpConf.nAxis];
|
||
prevDirAxis = new int[adpConf.nAxis];
|
||
|
||
SIEMENS_ref = (CMSCncLib.CNC.SIEMENS)Runtime.NC;
|
||
if (utils.CRB("verbose"))
|
||
{
|
||
lg.Info("SIEMENS_ref da CMSCncLib");
|
||
}
|
||
|
||
// disconnetto e connetto...
|
||
if (utils.CRB("verbose"))
|
||
{
|
||
lg.Info("SIEMENS: tryDisconnect");
|
||
}
|
||
|
||
tryDisconnect();
|
||
lg.Info("SIEMENS: tryConnect");
|
||
tryConnect();
|
||
lg.Info("End init Adapter SIEMENS");
|
||
}
|
||
/// <summary>
|
||
/// Override disconnessione
|
||
/// </summary>
|
||
public override void tryDisconnect()
|
||
{
|
||
if (connectionOk)
|
||
{
|
||
string szStatusConnection = "";
|
||
try
|
||
{
|
||
SIEMENS_ref.Disconnect(ref szStatusConnection);
|
||
connectionOk = false;
|
||
lg.Info(szStatusConnection);
|
||
lg.Info("Effettuata disconnessione adapter SIEMENS!");
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Fatal(exc, "Errore nella disconnessione dall'adapter SIEMENS");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
lg.Error("IMPOSSIBILE effettuare disconnessione: Connessione non disponibile...");
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// Override connessione
|
||
/// </summary>
|
||
public override void tryConnect()
|
||
{
|
||
if (!connectionOk)
|
||
{
|
||
string szStatusConnection = "";
|
||
try
|
||
{
|
||
parentForm.commPlcActive = true;
|
||
SIEMENS_ref.Connect(ref szStatusConnection);
|
||
lg.Info("szStatusConnection: " + szStatusConnection);
|
||
connectionOk = true;
|
||
// refresh stato allarmi!!!
|
||
if (connectionOk)
|
||
{
|
||
if (adpRunning)
|
||
{
|
||
// carico status allarmi (completo)
|
||
lg.Info("Inizio refresh completo stato allarmi...");
|
||
forceAlarmCheck();
|
||
lg.Info("Completato refresh completo stato allarmi!");
|
||
}
|
||
else
|
||
{
|
||
lg.Info("Connessione OK");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
lg.Error("Impossibile procedere, connessione mancante...");
|
||
}
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Fatal(string.Format("Errore nella connessione all'adapter SIEMENS: {0}{1}{2}", szStatusConnection, Environment.NewLine, exc));
|
||
connectionOk = false;
|
||
lg.Info(string.Format("Segnalo Adapter NON running, pausa di {0} msec prima di ulteriori tentativi di riconnessione", utils.CRI("waitRecMSec")));
|
||
}
|
||
parentForm.commPlcActive = false;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// Verifico connessione SIEMENS...
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public override bool connectionOk
|
||
{
|
||
get
|
||
{
|
||
return SIEMENS_ref.Connected;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Effettuo lettura dei 16+4 byte di strobe/status
|
||
/// </summary>
|
||
public override void getStrobeAndAckStatus()
|
||
{
|
||
base.getStrobeAndAckStatus();
|
||
if (connectionOk)
|
||
{
|
||
int memIndex = 0;
|
||
if (utils.CRB("readAllTop"))
|
||
{
|
||
// leggo TUTTI i primi 284 byte...
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_Byte(R, baseMemDb, memIndex, ref MemBlockTop);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-STROBES", MemBlockTop.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
// suddivido! (...la prima parte ack/strobe...)
|
||
Buffer.BlockCopy(MemBlockTop, 0, Acknowl, 0, Acknowl.Length);
|
||
Buffer.BlockCopy(MemBlockTop, Acknowl.Length, Strobes, 0, Strobes.Length);
|
||
}
|
||
else
|
||
{
|
||
// leggo TUTTO ack e strobe,
|
||
byte[] MemBlock = new byte[Strobes.Length + Acknowl.Length];
|
||
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_Byte(R, baseMemDb, memIndex, ref MemBlock);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-STROBES", MemBlock.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
// suddivido! (...la prima parte ack/strobe...)
|
||
Buffer.BlockCopy(MemBlock, 0, Acknowl, 0, Acknowl.Length);
|
||
Buffer.BlockCopy(MemBlock, Acknowl.Length, Strobes, 0, Strobes.Length);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
lg.Error("Errore connessione mancante in getStrobeAndAckStatus");
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// processing strobe!
|
||
/// </summary>
|
||
public override void processStrobe()
|
||
{
|
||
// inizializzo userAction
|
||
string UserAction = "";
|
||
// oggetti "accessori" x processing (1 byte di strobe x ogni path)
|
||
StFlag8 currStrobe;
|
||
StFlag8 currAck;
|
||
|
||
// processo ora i dati dei path... di sicuro il primo
|
||
currStrobe = (StFlag8)(Strobes[4]); // 5° byte
|
||
currAck = (StFlag8)(Acknowl[4]); // 5° byte
|
||
procPathStrobes(0, currStrobe, currAck, 164, 4, ref UserAction);
|
||
|
||
//...e se c'è pure il secondo...
|
||
if (currAdpConf.nPath > 1)
|
||
{
|
||
currStrobe = (StFlag8)(Strobes[6]); // 7° byte
|
||
currAck = (StFlag8)(Acknowl[6]); // 7° byte
|
||
procPathStrobes(1, currStrobe, currAck, 210, 6, ref UserAction);
|
||
}
|
||
|
||
// 2017.01.16 INVIO vettore azioni (1 o +)... SE CE NE SONO!
|
||
if (UserAction.Trim() != "")
|
||
{
|
||
currGateway.updateItemNodeValue("USER_ACTION", UserAction.Trim());
|
||
}
|
||
|
||
// verifico strobe dell'auto-test
|
||
currStrobe = (StFlag8)(Strobes[7]); // 8° byte
|
||
currAck = (StFlag8)(Acknowl[7]); // 8° byte
|
||
processTestStrobe(currStrobe, currAck, 7, 1);
|
||
|
||
// gestione bit di watchdog... sulal DWord successiva
|
||
sendWatchDog();
|
||
}
|
||
/// <summary>
|
||
/// Scrive ACK x dati MST
|
||
/// </summary>
|
||
/// <param name="idxPath"></param>
|
||
/// <param name="memIndexMST"></param>
|
||
/// <param name="MemBlock_W"></param>
|
||
/// <returns></returns>
|
||
public override bool writeMST_ACK(int memIndexAck, ref byte[] currACK_DW)
|
||
{
|
||
bool fatto = false;
|
||
try
|
||
{
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_Byte(W, baseMemDb, memIndexAck, ref currACK_DW);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("W{0}-ACK_DW0", currACK_DW.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
fatto = true;
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("Errore in scrittura dati ACK MST:{0}{1}", Environment.NewLine, exc));
|
||
}
|
||
return fatto;
|
||
}
|
||
/// <summary>
|
||
/// Legge area memoria dati MST
|
||
/// </summary>
|
||
/// <param name="idxPath"></param>
|
||
/// <param name="memIndexMST"></param>
|
||
/// <param name="MemBlock_MST"></param>
|
||
/// <returns></returns>
|
||
public override bool readMST_data(int idxPath, int memIndexMST, ref byte[] MemBlock_MST)
|
||
{
|
||
bool fatto = false;
|
||
try
|
||
{
|
||
if (utils.CRB("readAllTop"))
|
||
{
|
||
// copio la memoria allarmi dalla memoria top...
|
||
Buffer.BlockCopy(MemBlockTop, memIndexMST, MemBlock_MST, 0, MemBlock_MST.Length);
|
||
}
|
||
else
|
||
{
|
||
// leggo tutto!!!
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_Byte(R, baseMemDb, memIndexMST, ref MemBlock_MST);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-STRB_DW1-P{1:00}", MemBlock_MST.Length, idxPath), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
}
|
||
fatto = true;
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("Errore in lettura dati MST:{0}{1}", Environment.NewLine, exc));
|
||
}
|
||
return fatto;
|
||
}
|
||
/// <summary>
|
||
/// Scrive watchdog
|
||
/// </summary>
|
||
/// <param name="retACK_DW"></param>
|
||
/// <returns></returns>
|
||
public override bool writeWatchDog(ref byte[] retACK_DW)
|
||
{
|
||
int memIndex = 8;
|
||
return SIEMENSMemRW_Byte(W, baseMemDb, memIndex, ref retACK_DW);
|
||
}
|
||
/// <summary>
|
||
/// Effettua lettura dati TESTING
|
||
/// </summary>
|
||
/// <param name="MemBlockTestData"></param>
|
||
/// <returns></returns>
|
||
public override bool readTestData(ref uint[] MemBlockTestData)
|
||
{
|
||
bool fatto = false;
|
||
try
|
||
{
|
||
// leggo tutto!!!
|
||
int memIndex = 284;
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_DWord(R, baseMemDb, memIndex, ref MemBlockTestData);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-TEST_DATA", MemBlockTestData.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
fatto = true;
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("Errore in lettura dati Test:{0}{1}", Environment.NewLine, exc));
|
||
}
|
||
return fatto;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Scrive vettore ACK degli allarmi
|
||
/// </summary>
|
||
/// <param name="retACK_DW0"></param>
|
||
/// <returns></returns>
|
||
public override bool writeAlarmAck(ref byte[] retACK_DW0)
|
||
{
|
||
// DB1499.DBX0.0
|
||
int memIndexAck = 0;
|
||
return SIEMENSMemRW_Byte(W, baseMemDb, memIndexAck, ref retACK_DW0);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Legge vettore di TUTTE memorie tipo DWord dato vettore memorie (completo)
|
||
/// </summary>
|
||
/// <param name="MemBlock"></param>
|
||
/// <returns></returns>
|
||
public override bool readAllAlarms(ref uint[] MemBlock)
|
||
{
|
||
// DB1499.DBW36
|
||
int memIndex = 36;
|
||
bool fatto = false;
|
||
if (utils.CRB("readAllTop"))
|
||
{
|
||
// copio la memoria allarmi dalla memoria top...
|
||
Buffer.BlockCopy(MemBlockTop, memIndex, MemBlock, 0, MemBlock.Length);
|
||
}
|
||
else
|
||
{
|
||
fatto = SIEMENSMemRW_DWord(R, baseMemDb, memIndex, ref MemBlock);
|
||
}
|
||
return fatto;
|
||
}
|
||
/// <summary>
|
||
/// Legge vettore di TUTTE memorie tipo DWord dato indice di partenza e vettore memorie
|
||
/// </summary>
|
||
/// <param name="MemBlock"></param>
|
||
/// <param name="blockIndex"></param>
|
||
/// <returns></returns>
|
||
public override bool readAlarmBlock(ref uint[] MemBlock, int blockIndex)
|
||
{
|
||
//DB1499.DBW36
|
||
int memIndex = 36;
|
||
bool fatto = false;
|
||
if (utils.CRB("readAllTop"))
|
||
{
|
||
// copio la memoria allarmi dalla memoria top...
|
||
Buffer.BlockCopy(MemBlockTop, memIndex + blockIndex * 4, MemBlock, 0, MemBlock.Length * 4);
|
||
}
|
||
else
|
||
{
|
||
fatto = SIEMENSMemRW_DWord(R, baseMemDb, memIndex + blockIndex * 4, ref MemBlock);
|
||
}
|
||
return fatto;
|
||
|
||
|
||
}
|
||
|
||
#region implementazione processing GlobalData
|
||
|
||
/// <summary>
|
||
/// Legge dati globali...
|
||
/// </summary>
|
||
public override void readGlobalData()
|
||
{
|
||
// 2017.11.20 tentato di recuperare il dato ma pare ci siano solo info x singolo asse, la DB21 SEMBRA promettente ma lato S7 abbiamo verificato con Adimar che nON E? usata nella DBW158 e seg.. x popolare dati di FEEDRATE/SPEEDRATE...
|
||
|
||
// Parameter manual NC... pag 790:
|
||
/*
|
||
* Leggendo questo:
|
||
* "The extended address of the F function contains an identifier with the following meaning:
|
||
– 0: Path feedrate
|
||
– 1 - 31: Machine axis number for feedrate for positioning axes
|
||
*
|
||
* SEMBREREBBE che leggere u1,0 significhi leggere per INTERO path non x un singolo asse...
|
||
* --> pag 21--> leggo /Channel/MachineAxis/actFeedRate[u1, 0]
|
||
* */
|
||
// leggo dati globali...
|
||
parentForm.commPlcActive = true;
|
||
inizio = DateTime.Now;
|
||
var fsData = SIEMENS_ref.getAllNcInfo(currAdpConf.nPath);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult("R-NcInfo", DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
parentForm.commPlcActive = false;
|
||
|
||
// recupero speed e feed...
|
||
FeedRate = Convert.ToInt32(fsData.Feed);
|
||
//SpeedRate = Convert.ToInt32(allNcData.realspeed);
|
||
}
|
||
/// <summary>
|
||
/// legge dati override...
|
||
/// </summary>
|
||
/// <param name="sb1"></param>
|
||
/// <returns></returns>
|
||
public override bool readOverrides(ref StringBuilder sb1)
|
||
{
|
||
bool fatto = false;
|
||
try
|
||
{
|
||
ushort[] PathData_mem = new ushort[14];
|
||
byte[] PathData_memByte = new byte[PathData_mem.Length * 2];
|
||
if (utils.CRB("readAllTop"))
|
||
{
|
||
// copio la memoria allarmi dalla memoria top...
|
||
Buffer.BlockCopy(MemBlockTop, 256, PathData_memByte, 0, PathData_memByte.Length);
|
||
// devo effettuare copia/conversione endianness da dati RAW (byte invertiti) a dat corretti
|
||
for (int i = 0; i < PathData_mem.Length; i++)
|
||
{
|
||
PathData_mem[i] = Endian.SwapUInt16(BitConverter.ToUInt16(PathData_memByte, i * 2));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// area path1/2: 7 WORD x ogni path...
|
||
int memIndex = 256;
|
||
parentForm.commPlcActive = true;
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_Word(R, baseMemDb, memIndex, ref PathData_mem);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-PathData", PathData_mem.Length * 2), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
parentForm.commPlcActive = false;
|
||
}
|
||
|
||
// inizio indicando feed...
|
||
sb1.AppendLine(string.Format("FeedRate: {0} mm/min", FeedRate));
|
||
sb1.AppendLine(string.Format("SpeedRate: {0} mm/min", SpeedRate));
|
||
|
||
// 2017.04.20: recupero OVER per Jog/Feed/Rapid/Spindle x i path multipli (qui cablati 1-2)
|
||
ushort[] currPathData = new ushort[7];
|
||
// processo ora i dai dei path... di sicuro il primo
|
||
Array.Copy(PathData_mem, 0, currPathData, 0, 7);
|
||
procPathOverride(0, currPathData, ref sb1);
|
||
//...e se c'è pure il secondo...
|
||
if (currAdpConf.nPath > 1)
|
||
{
|
||
Array.Copy(PathData_mem, 7, currPathData, 0, 7);
|
||
// anche il secondo!
|
||
procPathOverride(1, currPathData, ref sb1);
|
||
}
|
||
fatto = true;
|
||
}
|
||
catch
|
||
{ }
|
||
return fatto;
|
||
}
|
||
/// <summary>
|
||
/// processa allarmi CNC...
|
||
/// </summary>
|
||
public override bool procCncAlarm()
|
||
{
|
||
bool fatto = false;
|
||
try
|
||
{
|
||
parentForm.commPlcActive = true;
|
||
inizio = DateTime.Now;
|
||
allarmiCNC = SIEMENS_ref.getCncAlarm();
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult("R-CNC-ERROR-MSG", DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
parentForm.commPlcActive = false;
|
||
fatto = true;
|
||
}
|
||
catch
|
||
{ }
|
||
return fatto;
|
||
}
|
||
/// <summary>
|
||
/// Gestione lettura dati manutenzione
|
||
/// </summary>
|
||
public override bool getMtzDataFromPlc()
|
||
{
|
||
bool fatto = false;
|
||
try
|
||
{
|
||
if (maintData.Length > 0)
|
||
{
|
||
// recupero i dati di manutenzione dall'area di memoria IN BLOCCO
|
||
int memIndex = 536;
|
||
uint[] tabDatiMtz = new uint[maintData.Length];
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_DWord(R, baseMemDb, memIndex, ref tabDatiMtz);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-DatiMtz", tabDatiMtz.Length * 4), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
// decodifico aree memoria secondo tab configurazione
|
||
processMaintData(tabDatiMtz, maintData);
|
||
}
|
||
fatto = true;
|
||
}
|
||
catch
|
||
{ }
|
||
return fatto;
|
||
}
|
||
/// <summary>
|
||
/// Gestione lettura dati status da PLC
|
||
/// </summary>
|
||
public override bool getStatusDataFromPlc()
|
||
{
|
||
bool fatto = false;
|
||
try
|
||
{
|
||
if (statusData.Length > 0)
|
||
{
|
||
// recupero i dati di manutenzione dall'area di memoria IN BLOCCO
|
||
int memIndex = 1048;
|
||
int numByte = 1 + (statusData.Length / 8);
|
||
byte[] tabDatiStatus = new byte[numByte];
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_Byte(R, baseMemDb, memIndex, ref tabDatiStatus);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-DatiStatus", tabDatiStatus.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
// decodifico aree memoria secondo tab configurazione
|
||
processStatusData(tabDatiStatus, statusData);
|
||
}
|
||
fatto = true;
|
||
}
|
||
catch
|
||
{ }
|
||
return fatto;
|
||
}
|
||
/// <summary>
|
||
/// Gestione lettura dati analogici
|
||
/// </summary>
|
||
public override bool getAnalogDataFromPlc()
|
||
{
|
||
bool fatto = false;
|
||
try
|
||
{
|
||
if (analogData.Length > 0)
|
||
{
|
||
// recupero i dati di manutenzione dall'area di memoria IN BLOCCO
|
||
int memIndex = 1064;
|
||
uint[] tabDatiAnalog = new uint[analogData.Length];
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_DWord(R, baseMemDb, memIndex, ref tabDatiAnalog);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-DatiAnalog", tabDatiAnalog.Length * 4), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
// decodifico aree memoria secondo tab configurazione
|
||
processAnalogData(tabDatiAnalog, analogData);
|
||
}
|
||
fatto = true;
|
||
}
|
||
catch
|
||
{ }
|
||
return fatto;
|
||
}
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// Carico file conf dati CMS
|
||
/// </summary>
|
||
protected override void loadOtherFile()
|
||
{
|
||
base.loadOtherFile();
|
||
loadMaintData("DB1499", 536, 4);
|
||
loadStatusData("DB1499", 1048, 1);
|
||
loadAnalogData("DB1499", 1064, 1);
|
||
}
|
||
/// <summary>
|
||
/// Processing allarmi CNC
|
||
/// </summary>
|
||
public override void processAlarm()
|
||
{
|
||
base.processAlarm();
|
||
|
||
// aggiungo gestione allarmi CNC
|
||
checkCNCAlarms();
|
||
}
|
||
/// <summary>
|
||
/// Verifica i 10 allarmi CNC SE presenti
|
||
/// </summary>
|
||
private void checkCNCAlarms()
|
||
{
|
||
// faccio parse allarmi: se ci sono invio e presento
|
||
if (allarmiCNC != null)
|
||
{
|
||
if (allarmiCNC.Length > 0)
|
||
{
|
||
foreach (Alarm allarme in allarmiCNC)
|
||
{
|
||
sendAlarmIfPresent(allarme);
|
||
}
|
||
}
|
||
}
|
||
alarmMsgDispl = true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Invia singolo allarme CNC se presente
|
||
/// </summary>
|
||
/// <param name="allarmeSiemens"></param>
|
||
protected void sendAlarmIfPresent(Alarm allarmeSiemens)
|
||
{
|
||
// controllo valore...
|
||
if (allarmeSiemens.Id > 0)
|
||
{
|
||
try
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
if (utils.CRI("loglevel") > 5)
|
||
{
|
||
lg.Info(string.Format("Allarmi CNC: Id {0} | MESS: {1} | CAT: {2} | SRC: {3}", allarmeSiemens.Id, allarmeSiemens.Message, allarmeSiemens.Category, allarmeSiemens.Source));
|
||
}
|
||
|
||
// da gestire instance = PATH!!! 1/2, x cui raddoppia i messaggi...
|
||
|
||
string codAllarme = string.Format("P{0}:S{1}:{2}:{3}", allarmeSiemens.Instance + utils.CRI("SiemensBaseCountPath"), allarmeSiemens.Source.Name, allarmeSiemens.Id, allarmeSiemens.Message);
|
||
// se NON ancora mostrati allarmi...
|
||
if (!alarmMsgDispl)
|
||
{
|
||
// mostro in form!
|
||
sb.AppendLine(codAllarme);
|
||
parentForm.dataMonitor_1 += sb.ToString();
|
||
}
|
||
// predispongo allarme
|
||
allarme currAllarm = new allarme(codAllarme, "CNC", "FAULT", allarmeSiemens.Message);
|
||
currGateway.addAlarm(currAllarm);
|
||
}
|
||
catch (Exception exc)
|
||
{
|
||
lg.Error(string.Format("{0}", exc));
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// Recupero dati x UnOp
|
||
/// </summary>
|
||
public override void getUnOp()
|
||
{
|
||
// DB254.DBI140
|
||
// leggo in blocco tutte le speed da memoria...
|
||
int memIndex = 140;
|
||
// buffer memoria 60 byte... speed (16bit 2 * 20) + load (8bit 1 * 20) visto che sono 20 teste max
|
||
byte[] unOpSpeedMem = new byte[60];
|
||
|
||
inizio = DateTime.Now;
|
||
SIEMENSMemRW_Byte(R, baseMemUO, memIndex, ref unOpSpeedMem);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-SPEED_UNOP", unOpSpeedMem.Length), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
procUnOp(unOpSpeedMem);
|
||
}
|
||
/// <summary>
|
||
/// Procedura di processing lettura memoria x DatiUt - Step 4
|
||
/// </summary>
|
||
/// <param name="int32Mem"></param>
|
||
/// <param name="j"></param>
|
||
/// <returns></returns>
|
||
public override int getDatiUt_step4(ref byte[] int32Mem, int j)
|
||
{
|
||
// restituisco dati richiesti...
|
||
int memIndex = 4300 + 4 * j;
|
||
Buffer.BlockCopy(ValUT.tabVitaRes, j, int32Mem, 0, int32Mem.Length);
|
||
return memIndex;
|
||
}
|
||
/// <summary>
|
||
/// Procedura di processing lettura memoria x DatiUt - Step 3b
|
||
/// </summary>
|
||
/// <param name="int8Mem"></param>
|
||
/// <param name="j"></param>
|
||
/// <returns></returns>
|
||
public override int getDatiUt_step3b(ref byte int8Mem, int j)
|
||
{
|
||
// restituisco dati richiesti...
|
||
int memIndex = 1900 + 1 * j;
|
||
int8Mem = BitConverter.GetBytes(ValUT.tabTipoVitaRes[j])[0];
|
||
return memIndex;
|
||
}
|
||
/// <summary>
|
||
/// Procedura di processing lettura memoria x DatiUt - Step 3a
|
||
/// </summary>
|
||
/// <param name="tabFam_FamUt"></param>
|
||
/// <returns></returns>
|
||
public override int getDatiUt_step3a(ref byte[] tabFam_FamUt)
|
||
{
|
||
// restituisco dati richiesti...
|
||
int memIndex = 100;
|
||
Buffer.BlockCopy(ValUT.tabFamUt, 0, tabFam_FamUt, 0, tabFam_FamUt.Length);
|
||
return memIndex;
|
||
}
|
||
/// <summary>
|
||
/// Procedura di processing lettura memoria x DatiUt - Step 2b
|
||
/// </summary>
|
||
/// <param name="int16Mem"></param>
|
||
/// <param name="j"></param>
|
||
/// <returns></returns>
|
||
public override int getDatiUt_step2b(ref byte[] int16Mem, int j)
|
||
{
|
||
// restituisco dati richiesti...
|
||
int memIndex = 2900 + 2 * j;
|
||
Buffer.BlockCopy(ValUT.tabIdFamUt, j, int16Mem, 0, int16Mem.Length);
|
||
return memIndex;
|
||
}
|
||
/// <summary>
|
||
/// Procedura di processing lettura memoria x DatiUt - Step 2a
|
||
/// </summary>
|
||
/// <param name="tabUt_UT"></param>
|
||
/// <returns></returns>
|
||
public override int getDatiUt_step2a(ref byte[] tabUt_UT)
|
||
{
|
||
// restituisco dati richiesti...
|
||
int memIndex = 2500;
|
||
Buffer.BlockCopy(ValUT.tabUt_UT, 0, tabUt_UT, 0, tabUt_UT.Length);
|
||
return memIndex;
|
||
}
|
||
/// <summary>
|
||
/// Procedura di processing lettura memoria x DatiUt - Step 1
|
||
/// </summary>
|
||
/// <param name="elencoUtMem"></param>
|
||
/// <returns></returns>
|
||
public override int getDatiUt_step1(ref byte[] elencoUtMem)
|
||
{
|
||
// faccio un unica chiamata in blocco di TUTTE le aree che riguardano gli UT e le salvo in variabili locali siemens...
|
||
inizio = DateTime.Now;
|
||
ValUT = SIEMENS_ref.getAllUtData(numMemUt, 20);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-UT_ALL", numMemUt * 4 * 2 + numMemUt * 4 + 20 * 2), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
// restituisco dati richiesti...
|
||
int memIndex = 280;
|
||
Buffer.BlockCopy(ValUT.elencoUtMem, 0, elencoUtMem, 0, elencoUtMem.Length);
|
||
return memIndex;
|
||
}
|
||
/// <summary>
|
||
/// Processo dati di path
|
||
/// </summary>
|
||
public override void getPath()
|
||
{
|
||
base.getPath();
|
||
|
||
string[,] vettGCod = new string[2, 64];
|
||
// recupero vettore generale G MODE
|
||
inizio = DateTime.Now;
|
||
SIEMENS_ref.getPathGCodeMod(currAdpConf.nPath, ref vettGCod);
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult("R-GCodModal", DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
// ciclo su path
|
||
StringBuilder sb_2;
|
||
StringBuilder sb_3;
|
||
for (int i = 0; i < currAdpConf.nPath; i++)
|
||
{
|
||
// accodo dati path in DataMonitor...
|
||
sb_2 = new StringBuilder();
|
||
sb_3 = new StringBuilder();
|
||
|
||
// copio gcodes!
|
||
string GCodAttivi = "";
|
||
for (int j = 0; j < 64; j++)
|
||
{
|
||
// SOLO se è diverso da vuoto...
|
||
if (vettGCod[i, j] != "")
|
||
{
|
||
GCodAttivi += string.Format("[{0}]", vettGCod[i, j]);
|
||
}
|
||
}
|
||
|
||
currGateway.updateItemNodeValue(vettPath[i].gCodeAct_Key, GCodAttivi);
|
||
sb_3.AppendLine(string.Format("Path {0}, GCodes: {1}", i + 1, GCodAttivi));
|
||
|
||
parentForm.dataMonitor_2 += sb_2.ToString();
|
||
parentForm.dataMonitor_3 += sb_3.ToString();
|
||
}
|
||
|
||
}
|
||
/// <summary>
|
||
/// Override gestione caricamento dati assi
|
||
/// </summary>
|
||
public override void getAxis()
|
||
{
|
||
// mostro assi in DataMonitor......
|
||
StringBuilder sb = new StringBuilder();
|
||
// nuova posizione (per calcoli)
|
||
double newPos = 0;
|
||
double distPerc = 0;
|
||
int newDir = 0;
|
||
string tipoAsse = "";
|
||
string direzione = "";
|
||
|
||
// recupero in blocco dati assi...
|
||
inizio = DateTime.Now;
|
||
SIEMENS.AxData[] ValAssi = SIEMENS_ref.getAllAxisData();
|
||
if (utils.CRB("recTime"))
|
||
{
|
||
TimingData.addResult(string.Format("R{0}-AXIS_ALL", ValAssi.Length * 4 * 2), DateTime.Now.Subtract(inizio).Ticks);
|
||
}
|
||
|
||
for (int i = 0; i < currAdpConf.nAxis; i++)
|
||
{
|
||
// per sicurezza try-catch
|
||
try
|
||
{
|
||
// popolo valori... ipotesi MILLESIMI di mm... CONVERSIONE BigEndianness
|
||
newPos = ValAssi[i].PosAct;
|
||
currGateway.updateItemNodeValue(vettAxis[i].posActKey, newPos);
|
||
currGateway.updateItemNodeValue(vettAxis[i].loadKey, ValAssi[i].Load);
|
||
// imposto feed "generale" per asse... si potrebbe usare velocità del singolo asse... !!!FARE!!! verificare
|
||
currGateway.updateItemNodeValue(vettAxis[i].feedrateKey, ValAssi[i].Feed);
|
||
currGateway.updateItemNodeValue(vettAxis[i].feedOverKey, ValAssi[i].FeedOver);
|
||
// verifica pos TGT... NON E' correttamente letta lato area memoria...
|
||
currGateway.updateItemNodeValue(vettAxis[i].posTgtKey, ValAssi[i].PosTgt);
|
||
// calcolo distanza e salvo valore...
|
||
distPerc = newPos - prevPosAxis[i];
|
||
|
||
// sistemo direzione +/- (POS/NEG se lineari, CCW/CW se rotativi)
|
||
if (distPerc != 0)
|
||
{
|
||
newDir = Convert.ToInt32(distPerc / Math.Abs(distPerc));
|
||
}
|
||
else
|
||
{
|
||
newDir = prevDirAxis[i];
|
||
}
|
||
|
||
// verifico tipo direzione da tipo asse...
|
||
tipoAsse = currGateway.getItemNode(vettAxis[i].typeKey).ToString();
|
||
if (tipoAsse == "LINEAR")
|
||
{
|
||
// ?: conditional operator.
|
||
direzione = (newDir > 0) ? "POSITIVE" : "NEGATIVE";
|
||
}
|
||
else if (tipoAsse == "ROTARY")
|
||
{
|
||
direzione = (newDir > 0) ? "CLOCKWISE" : "COUNTER_CLOCKWISE";
|
||
}
|
||
// imposto direzione
|
||
currGateway.updateItemNodeValue(vettAxis[i].directionKey, direzione);
|
||
|
||
if (utils.CRB("verbose"))
|
||
{
|
||
sb.AppendLine(string.Format("Asse {0}: PosAct:{1:N3}, ToGo:{2:N3}{3} | {4}", i, newPos, ValAssi[i].PosTgt, "", direzione));
|
||
}
|
||
|
||
// salvo valori vettore prec...
|
||
prevPosAxis[i] = newPos;
|
||
prevDirAxis[i] = newDir;
|
||
|
||
// altri valori NON gestiti
|
||
//vettAxis[i].mAxMainProc.Value = AxData.AxisMainProc;
|
||
//vettAxis[i].mAxIsMaster.Value = AxData.AxisIsMaster;
|
||
//vettAxis[i].mAxMastId.Value = AxData.AxisMastId;
|
||
//vettAxis[i].mAxAccelAct.Value = AxData.AxisAccel;
|
||
//vettAxis[i].mAxBattery.Value = AxData.AxisBattery;
|
||
}
|
||
catch
|
||
{
|
||
lg.Error(string.Format("Errore in lettura asse {0}", i));
|
||
}
|
||
}
|
||
|
||
parentForm.dataMonitor_3 += sb.ToString();
|
||
}
|
||
}
|
||
}
|
||
|