Files

869 lines
32 KiB
C#

using MTC;
using SCMA.AdapterCom;
using EsaCncLib;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
namespace SCMA.AdapterPLC.CMS
{
public class EsaKosmos : Generic
{
/// <summary>
/// Configurazione valori da leggere IOT_Byte
/// </summary>
public otherData[] mapIOT_Byte;
/// <summary>
/// Configurazione valori da leggere IOT_Word
/// </summary>
public otherData[] mapIOT_Word;
/// <summary>
/// Configurazione valori da leggere IOT_DWord
/// </summary>
public otherData[] mapIOT_DWord;
/// <summary>
/// Configurazione valori da leggere IOT_String
/// </summary>
public otherData[] mapIOT_String;
/// <summary>
/// Oggetto elenco allarmi SOLO CNC (OCCHIO codice numerico = INDICE!!!)
/// </summary>
public allarme[] elencoAllarmiCNC;
/// <summary>
/// variabile contatore cicli prima di rileggere codici G di un path inattivo...
/// </summary>
public int contChkGCod;
/// <summary>
/// Vettore codici G attivi...
/// </summary>
int[] vettGCodesAct;
/// <summary>
/// Override asse Z (hard coded x ESA)
/// </summary>
int ZRateOver = 0;
/// <summary>
/// Carico file conf dati IOT
/// </summary>
protected override void loadOtherFile()
{
base.loadOtherFile();
loadMaintData("CNT", 0, 1);
loadStatusData("MNT", 0, 1);
loadAnalogData("ANALOG", 0, 1);
loadStringData("STR", 0, 1);
loadAllarmiCNC();
}
/// <summary>
/// caricamento allarmi da file (CON RIEMPIMENTO MANCANTI!!!!)
/// </summary>
protected void loadAllarmiCNC()
{
if (utils.CRB("verbose"))
{
lg.Info("Inizio caricamento vettore allarmi");
}
int totRighe = 0;
string fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("AlarmListCNC"));
string linea;
try
{
string lastLine = File.ReadLines(fileName).Last();
totRighe = startNumb(lastLine, utils.CRC("testCharSep"));
}
catch
{
totRighe = File.ReadLines(fileName).Count();
}
// creo un vettore della dimensione corretta... PRENDO IL MASSIMO dei valori...
elencoAllarmiCNC = new allarme[totRighe];
// ora creo un vettore di allarmi VUOTI...
for (int i = 1; i <= totRighe; i++)
{
elencoAllarmiCNC[i - 1] = new allarme(i.ToString(), "CNC", "WARNING", string.Format("[{0}] MISSING", i), string.Format("[{0}] MISSING", i), string.Format("[{0}] MISSING", i));
}
// carica da file...
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
// leggo 1 linea alla volta...
int numRiga = 0;
while ((linea = file.ReadLine()) != null)
{
// SE non è un commento...
if (linea.Substring(0, 1) != "#")
{
// recupero numRiga da prima parte linea...
numRiga = startNumb(linea, utils.CRC("testCharSep"));
elencoAllarmiCNC[numRiga - 1] = decodeAlarmLine(linea, utils.CRC("testCharSep"));
}
}
// chiudo file
file.Close();
if (utils.CRB("verbose"))
{
lg.Info(string.Format("Fine caricamento vettore allarmi CNC: {0} allarmi caricati!", numRiga));
}
}
/// <summary>
/// Restituisce path completo file da chaive configurazione
/// </summary>
/// <param name="keyFile">chaive conf x file richiesto</param>
/// <returns></returns>
protected string filePath(string keyFile)
{
return string.Format(@"{0}\{1}", utils.confDir, utils.CRS(keyFile));
}
/// <summary>
/// oggetto onnessione ESA
/// </summary>
protected thdNcEsaKvara ncDevice;
/// <summary>
/// thread del processo comunicazione esa
/// </summary>
protected Thread thdDevice;
/// <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 EsaKosmos(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];
// GCodes!
vettGCodesAct = new int[10];
contChkGCod = utils.CRI("contChkGCod");
string iniPath = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("defaultEsaFile"));
lg.Info("Start init Adapter ESA dal file {0}", iniPath);
EsaCncLib.IniFile EsaIni = new EsaCncLib.IniFile(iniPath);
if (utils.CRB("verbose"))
{
lg.Info("step 01: impostato INI File {0}", iniPath);
}
loadOtherFile();
parentForm.commPlcActive = true;
// init classe comunicazione NC
ncDevice = new thdNcEsaKvara(EsaIni);
parentForm.commPlcActive = false;
if (utils.CRB("verbose"))
{
lg.Info("step 02: avviato thdNcEsaGvKvara da INI File {0}", iniPath);
}
// inizializzo posizioni assi...
prevPosAxis = new double[adpConf.nAxis];
prevDirAxis = new int[adpConf.nAxis];
// verifica avvio...
lg.Info("ESA: tryConnect");
tryConnect();
lg.Info("End init Adapter ESA");
// leggo dati "statici" dal PLC...
}
/// <summary>
/// Override disconnessione
/// </summary>
public override void tryDisconnect()
{
base.tryDisconnect();
// disconnetto
ncDevice.Disconnect();
connectionOk = false;
}
/// <summary>
/// Override connessione
/// </summary>
public override void tryConnect()
{
base.tryConnect();
// se non già connesso provo a connettermi...
if (!ncDevice.Connected)
{
// provo a collegarmi
if (!ncDevice.Connect())
{
//altrimenti disconnette...
ncDevice.Disconnect();
connectionOk = false;
}
else
{
connectionOk = true;
}
}
}
/// <summary>
/// Verifico connessione ESA...
/// </summary>
/// <returns></returns>
public override bool connectionOk
{
get
{
return ncDevice.Connected;
}
set
{
ncDevice.Connected = value;
}
}
/// <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)
{
ncDevice.ReadlAlarms();
MemBlock = ncDevice.SCMA_MMan_ALM.data;
return true;
}
/// <summary>
/// Effettuo lettura dei 16 byte di strobe/status
/// </summary>
public override void getStrobeAndAckStatus()
{
base.getStrobeAndAckStatus();
if (connectionOk)
{
// leggo TUTTO il blocco di memoria
parentForm.commPlcActive = true;
inizio = DateTime.Now;
ncDevice.ReadStatus();
ncDevice.ReadAckStrobe();
if (utils.CRB("recTime"))
{
TimingData.addResult("R-PLC_SCMA-ACK-Strobe", DateTime.Now.Subtract(inizio).Ticks);
}
parentForm.commPlcActive = false;
// copio ACK
Buffer.BlockCopy(ncDevice.SCMA_MMan_ACK.data, 0, Acknowl, 0, 16);
// copio strobes (all)
Buffer.BlockCopy(ncDevice.SCMA_MMan_STROBE.data, 0, Strobes, 0, 16);
// status...
ouStatus = ncDevice.SCMA_MMan_status.data[0];
// copio su ack...
Acknowl[12] = (byte)ouStatus;
}
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, 1, 0, ref UserAction); // 0 --> primo byte della ACK MST
//...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, 1, 2, ref UserAction); // 2 --> terzo byte della ACK MST
}
//2019.07.22 NON RIPORTO USER_ACTION x SOUR
if (currGateway.protocollo != gwProtocol.SOURS)
{
// 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, 1, 30);
// 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;
// converto DWord a byte, è la DW1 = ACK[1]...
byte[] actualAck = BitConverter.GetBytes(ncDevice.SCMA_MMan_ACK.data[1]);
// sistemo nella memoria dell'NC i valori di ack richiesti...
Buffer.BlockCopy(currACK_DW, 0, actualAck, memIndexAck, 1);
// riconverto a DWord
ncDevice.SCMA_MMan_ACK.data[1] = BitConverter.ToUInt32(actualAck, 0);
try
{
inizio = DateTime.Now;
// scrivo TUTTA la Hack
fatto = ncDevice.WriteAck();
if (utils.CRB("recTime"))
{
TimingData.addResult(string.Format("W{0}-ACK_DW1", currACK_DW.Length), DateTime.Now.Subtract(inizio).Ticks);
}
}
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
{
inizio = DateTime.Now;
// leggo memoria (TUTTA) e POI ricopio a byte x il resto delal gestione...
ncDevice.ReadMSTData();
// copio M
Buffer.BlockCopy(ncDevice.SCMA_MMan_MNUM.data, idxPath, MemBlock_MST, 0, 2);
Buffer.BlockCopy(ncDevice.SCMA_MMan_MF.data, idxPath * 10, MemBlock_MST, 2, 20);
// copio S
Buffer.BlockCopy(ncDevice.SCMA_MMan_SNUM.data, idxPath, MemBlock_MST, 22, 2);
Buffer.BlockCopy(ncDevice.SCMA_MMan_SF.data, idxPath * 5, MemBlock_MST, 24, 10);
// copio T
Buffer.BlockCopy(ncDevice.SCMA_MMan_TNUM.data, idxPath, MemBlock_MST, 34, 2);
Buffer.BlockCopy(ncDevice.SCMA_MMan_TF.data, idxPath * 5, MemBlock_MST, 36, 10);
if (utils.CRB("recTime"))
{
TimingData.addResult(string.Format("R{0}-STRB_DW1-P{1:00}", MemBlock_MST.Length, idxPath), DateTime.Now.Subtract(inizio).Ticks);
}
}
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)
{
bool fatto = false;
// converto DWord a byte, è la DW2 = ACK[2]...
byte[] actualAck = BitConverter.GetBytes(ncDevice.SCMA_MMan_ACK.data[2]);
// sistemo nella memoria dell'NC i valori di ack richiesti...
Buffer.BlockCopy(retACK_DW, 0, actualAck, 0, 4);
// riconverto a DWord
ncDevice.SCMA_MMan_ACK.data[2] = BitConverter.ToUInt32(actualAck, 0);
// chiamo scrittura...
fatto = ncDevice.WriteAck();
return fatto;
}
/// <summary>
/// Scrive vettore ACK degli allarmi
/// </summary>
/// <param name="retACK_DW0"></param>
/// <returns></returns>
public override bool writeAlarmAck(ref byte[] retACK_DW0)
{
bool fatto = false;
// converto DWord a byte, è la DW2 = ACK[2]...
byte[] actualAck = BitConverter.GetBytes(ncDevice.SCMA_MMan_ACK.data[0]);
// sistemo nella memoria dell'NC i valori di ack richiesti...
Buffer.BlockCopy(retACK_DW0, 0, actualAck, 0, 4);
// riconverto a DWord
ncDevice.SCMA_MMan_ACK.data[0] = BitConverter.ToUInt32(actualAck, 0);
// chiamo scrittura...
fatto = ncDevice.WriteAck();
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)
{
// rileggo comunque tutto che faccio prima...
bool fatto = false;
try
{
ncDevice.ReadlAlarms();
var currMemBlock = ncDevice.SCMA_MMan_ALM.data;
MemBlock[0] = currMemBlock[blockIndex];
}
catch
{ }
return fatto;
}
#region implementazione processing GlobalData
/// <summary>
/// Legge dati globali...
/// </summary>
public override void readGlobalData()
{
// leggo dati globali...
parentForm.commPlcActive = true;
inizio = DateTime.Now;
ncDevice.ReadMSTData();
if (utils.CRB("recTime"))
{
TimingData.addResult("PLC-MST-Data", DateTime.Now.Subtract(inizio).Ticks);
}
parentForm.commPlcActive = false;
}
/// <summary>
/// legge dati override...
/// </summary>
/// <param name="sb1"></param>
/// <returns></returns>
public override bool readOverrides(ref StringBuilder sb1)
{
bool fatto = false;
try
{
// lettura override
inizio = DateTime.Now;
var allSpeedFeedData = ncDevice.getFeedSpeed();
if (utils.CRB("recTime"))
{
TimingData.addResult("PLC-R-overrides", DateTime.Now.Subtract(inizio).Ticks);
}
// inizio indicando feed...
sb1.AppendLine(string.Format("FeedRate: {0} mm/min", allSpeedFeedData.realFeed));
sb1.AppendLine(string.Format("SpeedRate: {0} mm/min", allSpeedFeedData.realSpeed));
fatto = true;
}
catch (Exception exc)
{
lg.Error(exc, "Eccezione in readOverrides");
}
// HARD CODE: forzo path 1 (indice 0...)
int idxPath = 0;
// accodo dati path in DataMonitor......
StringBuilder sb = new StringBuilder();
// Processing area BYTE x OVERRIDE e status
ZRateOver = ncDevice.SCMA_MMan_OVR.data[0];
FeedRateOver = ncDevice.SCMA_MMan_OVR.data[1];
RapidOver = ncDevice.SCMA_MMan_OVR.data[2];
SpeedRateOver = ncDevice.SCMA_MMan_OVR.data[3];
// commentato x test sul campo da Gianandrea Grisetti + Marco Annese: si sovrascrivono status da PATH (processo) e generale, eliminato qui
#if false
string pathExeMode = $"{(macState)ouStatus}";
// copio exeMode sul path corrente
currGateway.updateItemNodeValue(vettPath[idxPath].exeModeKey, pathExeMode);
// sistemo le stringhe x display
sb.AppendLine(string.Format("ExeMode: {0}", pathExeMode));
#endif
sb.AppendLine(string.Format("ZRateOver: {0} %", ZRateOver));
sb.AppendLine(string.Format("FeedRateOver: {0} %", FeedRateOver));
sb.AppendLine(string.Format("RapidOver: {0} %", RapidOver));
sb.AppendLine(string.Format("SpeedRateOver: {0} %", SpeedRateOver));
// update form!
parentForm.dataMonitor_1 += sb.ToString();
return fatto;
}
/// <summary>
/// Gestione lettura dati manutenzione
/// </summary>
public override bool getMtzDataFromPlc()
{
bool fatto = false;
try
{
if (maintData != null)
{
if (maintData.Length > 0)
{
// recupero dati
uint[] tabDatiMtz = new uint[maintDataMaxNum];
inizio = DateTime.Now;
ncDevice.ReadCounterData();
if (utils.CRB("recTime"))
{
TimingData.addResult(string.Format("R{0}-DatiMtz", tabDatiMtz.Length * 4), DateTime.Now.Subtract(inizio).Ticks);
}
// copio maint data
tabDatiMtz = ncDevice.SCMA_MMan_CNT.data.Take(maintDataMaxNum).ToArray();
// decodifico aree memoria secondo tab configurazione
processMaintData(tabDatiMtz, maintData);
// se log verboso 10+ --> scrivo tutti!
if (utils.CRI("loglevel") > 9)
{
lg.Info($" Lettura di {maintDataMaxNum} variabili maintData");
}
}
fatto = true;
}
}
catch (Exception exc)
{
lg.Error(string.Format("{0}", exc));
}
return fatto;
}
/// <summary>
/// Gestione lettura dati analogici
/// </summary>
public override bool getAnalogDataFromPlc()
{
bool fatto = false;
try
{
// leggo e salvo var analogiche ANALOG
if (analogDataMaxNum > 0)
{
// recupero dati
inizio = DateTime.Now;
ncDevice.ReadAnalogData();
if (utils.CRB("recTime"))
{
TimingData.addResult("R-AnalogData", DateTime.Now.Subtract(inizio).Ticks);
}
uint[] tabDatiAnalog = new uint[analogDataMaxNum];
tabDatiAnalog = ncDevice.SCMA_MMan_ANALOG.data.Take(analogDataMaxNum).ToArray();
// decodifico aree memoria secondo tab configurazione
processAnalogData(tabDatiAnalog, analogData);
}
fatto = true;
}
catch (Exception exc)
{
lg.Error(string.Format("{0}", exc));
}
return fatto;
}
/// <summary>
/// Gestione lettura dati stringa
/// </summary>
public override bool getStringDataFromPlc()
{
bool fatto = false;
try
{
// leggo e salvo var analogiche ANALOG
if (stringDataMaxNum > 0)
{
// recupero dati
inizio = DateTime.Now;
ncDevice.ReadStringData();
if (utils.CRB("recTime"))
{
TimingData.addResult("R-StringData", DateTime.Now.Subtract(inizio).Ticks);
}
string[] tabDatiString = new string[stringDataMaxNum];
for (int i = 0; i < stringDataMaxNum; i++)
{
tabDatiString[i] = ncDevice.SCMA_MManCMS_Strings[i].data.Trim();
}
// decodifico aree memoria secondo tab configurazione
processStringData(tabDatiString, stringData);
}
fatto = true;
}
catch (Exception exc)
{
lg.Error(string.Format("{0}", exc));
}
return fatto;
}
/// <summary>
/// Gestione lettura dati status da PLC
/// </summary>
public override bool getStatusDataFromPlc()
{
bool fatto = false;
try
{
// leggo e salvo status BIT STATUS MNT
if (statusDataMaxNum > 0)
{
// recupero dati
inizio = DateTime.Now;
ncDevice.ReadStatus();
if (utils.CRB("recTime"))
{
TimingData.addResult("R-Status", DateTime.Now.Subtract(inizio).Ticks);
}
int numByte = 1 + (statusDataMaxNum / 8);
// arrotondo ai 4 byte...
numByte = 4 * (int)Math.Ceiling((double)numByte / 4);
byte[] tabDatiStatus = new byte[numByte];
for (int i = 0; i < numByte / 4; i++)
{
Buffer.BlockCopy(BitConverter.GetBytes(ncDevice.SCMA_MMan_MNT.data[i]), 0, tabDatiStatus, i * 4, 4);
}
// decodifico aree memoria secondo tab configurazione
processStatusData(tabDatiStatus, statusData);
}
fatto = true;
}
catch (Exception exc)
{
lg.Error(string.Format("{0}", exc));
}
return fatto;
}
#endregion
public override void getPath()
{
var allSpeedFeedData = ncDevice.getFeedSpeed();
// cicl su path
for (int i = 0; i < currAdpConf.nPath; i++)
{
currGateway.updateItemNodeValue(vettPath[i].feedKey, allSpeedFeedData.realFeed);
currGateway.updateItemNodeValue(vettPath[i].feedOverKey, FeedRateOver);
currGateway.updateItemNodeValue(vettPath[i].rapidOverKey, RapidOver);
}
}
/// <summary>
/// Recupera la speed override x i mandrini (UnOp)
/// </summary>
public override void getUnOp()
{
var allSpeedFeedData = ncDevice.getFeedSpeed();
// cicl su UnOp
for (int i = 0; i < currAdpConf.nUnOp; i++)
{
currGateway.updateItemNodeValue(vettUnOp[i].speedOverKey, SpeedRateOver);
currGateway.updateItemNodeValue(vettUnOp[i].speedKey, allSpeedFeedData.realSpeed);
}
// ora recupero G Codes
StringBuilder sb_2;
StringBuilder sb_3;
// faccio VERA lettura SOLO ogni TOT cicli...
if (contChkGCod <= 0)
{
// reimposto contatore
contChkGCod = utils.CRI("contChkGCod");
// recupero vettore generale G MODE
parentForm.commPlcActive = true;
inizio = DateTime.Now;
vettGCodesAct = ncDevice.getGCodes();
if (utils.CRB("recTime"))
{
TimingData.addResult("R-GCodModal", DateTime.Now.Subtract(inizio).Ticks);
}
parentForm.commPlcActive = false;
}
else
{
contChkGCod--;
}
for (int i = 0; i < currAdpConf.nPath; i++)
{
// accodo dati path in DataMonitor...
sb_2 = new StringBuilder();
sb_3 = new StringBuilder();
// attenzione: il vettore contiene come campi "vuoti" il valore MAX di USHort (16bit) ovvero 2^16 -1 (base 0) --> 65535
string GCodAttivi = "";
for (int j = 0; j < vettGCodesAct.Length; j++)
{
// se il valore è < di UShort.max (65535)...
if (vettGCodesAct[j] < ushort.MaxValue && vettGCodesAct[j] >= 0)
{
GCodAttivi += string.Format("[G{0}]", vettGCodesAct[j]);
}
}
if (currGateway.getItemNode(vettPath[i].gCodeAct_Key).ToString() != $"{vettPath[i].gCodeAct_Key}||{GCodAttivi}")
{
currGateway.updateItemNodeValue(vettPath[i].gCodeAct_Key, GCodAttivi);
}
if (currGateway.protocollo != gwProtocol.SOURS)
{
// 2017.01.16 da rivedere
currGateway.updateItemNodeValue(vettPath[i].currProgRowNumKey, "");
currGateway.updateItemNodeValue(vettPath[i].activeAxesKey, "");
sb_2.AppendLine(string.Format("Path {0}, PROG: {1}", i + 1, currGateway.getItemNode(vettPath[i].currProgKey)));
}
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>
/// Carica info accessorie assi (direzione, feed, ...)
/// </summary>
public override void getAxis()
{
// mostro assi in DataMonitor......
StringBuilder sb = new StringBuilder();
// leggo in blocco dati dall'NC
var allAxisData = ncDevice.getAxisData();
var allSpeedFeedData = ncDevice.getFeedSpeed();
// nuova posizione (per calcoli)
double newPos = 0;
double distPerc = 0;
int newDir = 0;
string direzione = "";
int numInvAx = 0;
int currFeedOver = 0;
// leggo in modo "cablato" i dati dei vari assi...
for (int i = 0; i < currAdpConf.nAxis; i++)
{
// speed singolo asse
currGateway.updateItemNodeValue(vettAxis[i].feedrateKey, allAxisData[i].speed);
/*--------------------------------------------------------
* Override calcolata come segue:
* - asse Z: sempre "specifica"
* - altri assi:
* - se HO G0 (RAPID) --> OVR[2]
* - se HO G1 (FEED) --> OVR[1]
--------------------------------------------------------*/
if (!string.IsNullOrEmpty(allAxisData[i].name))
{
if (allAxisData[i].name == "Z")
{
currFeedOver = ZRateOver;
}
else
{
currFeedOver = FeedRateOver;
}
// imposto!
currGateway.updateItemNodeValue(vettAxis[i].feedOverKey, currFeedOver);
}
// load... divido per 10 x avere Ampere
currGateway.updateItemNodeValue(vettAxis[i].loadKey, allAxisData[i].load / 10);
// name
if (!string.IsNullOrEmpty(allAxisData[i].name))
{
currGateway.updateItemNodeValue(vettAxis[i].descriptionKey, allAxisData[i].name);
}
// calcolo distanza e salvo valore...
newPos = allAxisData[i].posMac;
currGateway.updateItemNodeValue(vettAxis[i].posActKey, newPos);
distPerc = newPos - prevPosAxis[i];
// posizione target = posizione atutale + sistance
currGateway.updateItemNodeValue(vettAxis[i].posTgtKey, newPos + allAxisData[i].distanceToGo);
// sistemo direzione +/- (POS/NEG se lineari, CCW/CW se rotativi)
if (distPerc != 0)
{
newDir = Convert.ToInt32(distPerc / Math.Abs(distPerc));
}
else
{
newDir = prevDirAxis[i];
}
// calcolo direzione
direzione = calculateDirection(newDir, i);
// imposto direzione
currGateway.updateItemNodeValue(vettAxis[i].directionKey, direzione);
// se la direzione è variata salvo il cambio direzione...
if (newDir != prevDirAxis[i])
{
// recupero num prec...
numInvAx = Convert.ToInt32(istNumInvAssi[i].vcMedian);
numInvAx++;
// salvo "+1" come cambi direzione.... ATTENZIONE servirà che la finestra sia "corta" (tipo 1 sec...) mentre io ne inserisco 3 distanziati di 1/5 sec
istNumInvAssi[i].addValue(DateTime.Now.AddMilliseconds(-400), numInvAx);
istNumInvAssi[i].addValue(DateTime.Now.AddMilliseconds(-200), numInvAx);
istNumInvAssi[i].addValue(DateTime.Now, numInvAx);
}
if (utils.CRB("verbose"))
{
sb.AppendLine($"Asse {i}: PosAct:{newPos:N3} | {direzione}");
sb.AppendLine($"Asse {i}: ESA speed {allAxisData[i].speed}");
}
// salvo valori vettore prec...
prevPosAxis[i] = newPos;
prevDirAxis[i] = newDir;
}
parentForm.dataMonitor_3 += sb.ToString();
}
}
}