// motors.cpp
// (C) 1993,95 by Heiko Damerow MPG AG "Roentgenbeugung"
/*******************************************************************************
Version 1.9
Datum 951122
*******************************************************************************/
static long Drive628c(BYTE,WORD,long,WORD,WORD);
#include "m_motcom.h"
#include "m_mothw.h"
#include "m_layer.h"
#include "ieee.h"
#define DirectAccess
// #define WriteLog
// #define CheckCorrect
// #define TESTLAUF
char szMsgFailure[] = "Failure";
char szMessage[] = "Message";
char szMsgLine001[] = "Initializing of drive module %s";
char szMsgLine002[] = "Problems with drive module startup !\n\nAbbort
?";
char szMsgLine003[] = "Starting up the drive module";
char szMsgLine004[] = "Save settings of %s
";
char szMsgLine005[] = "This operation shouldn't be used for this
drive !";
char szMsgLine006[] = "No valid drive !";
char szMsgLine007[] = "Calibration isn't done !";
char szMsgLine008[] = "Absolute zero for drive %s";
char szMsgLine009[] = "Calibration ready !";
char szMsgLine010[] = "\n\nThe new calibration data was saved !";
char szMsgLine011[] = "Optimize DCM-Parameter for %s";
char szMsgLine012[] = "Can't initialize the drive %s!";
static const int MAXIT = 30;
// maximal number of iterations
int TMotor::nMaxId
= 0;
extern LPMList lpMList;
extern TModalDlg* TheDialog;
HINSTANCE hGPIBModule = NULL;
TInitialize gInitialize;
TSend gSend;
TEnter gEnter;
TTransmit gTransmit;
TReceive gReceive;
TSPoll gSPoll;
TPPoll gPPoll;
TSetPort gSetPort;
TSetTimeout gSetTimeout;
TSetOutputEOS gSetOutputEOS;
TSetInputEOS gSetInputEOS;
TEnable488Ex gEnable488Ex;
TEnable488SD gEnable488SD;
TListenerOk gListenerOk;
TBoardPresent gBoardPresent;
//**** variables belonging C-832 ***********************************************
static TCSet CmdSet[] =
{// LM628/629-commands exept RDSTAT
{RESET, 0,0,0}, {PORT8, 0,0,0}, {PORT12,0,0,0}, {DFH,
0,0,0},
{SIP, 0,0,0}, {LPEI, 0,1,0}, {LPES,
0,1,0}, {SBPA, 0,2,1},
{SBPR, 0,2,1}, {MSKI, 0,1,0}, {RSTI, 0,1,0},
{LFIL, 0,4,0},
{UDF, 0,0,0}, {LTRJ, 0,3,1}, {STT,
0,0,0}, {RDSTAT,1,1,0},
{RDSIGS,1,1,0}, {RDIP, 1,1,1}, {RDDP, 1,1,1},
{RDRP, 1,1,1},
{RDDV, 1,1,1}, {RDRV, 1,1,0}, {RDSUM, 1,1,0}
};
static BYTE config;
static WORD drive;
static WORD baddr;
static BYTE raddr;
static UINT nEvent;
static int GetWord(WORD,WORD);
static long GetDWord(WORD,WORD);
static void PutWord(int,WORD,WORD);
static void PutDWord(long,WORD,WORD);
static BOOL LM628Ready(WORD);
int nC812 = -1;
//******************************************************************************
TMList::TMList(int maxn,HINSTANCE inst)
{
char buf[] = "Start of Program\r";
AD_X = -1;
AD_Y = -1;
AD_Z = -1;
AD_Rotation = -1;
AD_Tilt = -1;
AD_DC
= -1;
AD_Collimator = -1;
AD_DF
= -1;
AD_Encoder = -1;
AD_Absorber = -1;
AD_Psi = -1;
AD_Phi = -1;
AD_Theta = -1;
AD_Omega = -1;
nActiveDrive = -1;
nLastDrive = -1;
nMaxNumber = maxn;
hMInstance = inst;
#ifdef WriteLog
FILE *LogFile;
LogFile = fopen("motor.log","w");
if(LogFile)
{
fseek(LogFile,0,2);
fwrite(buf,strlen(buf),1,LogFile);
fclose(LogFile);
}
#endif
aMotor = new TMotor* [nMaxNumber];
};
TMList::~TMList(void)
{
delete[] aMotor;
};
BOOL TMList::InitializeModule(void)
{
BOOL bNoFailure = TRUE;
int id;
char Ident[MaxString],ctype[MaxString];
char buf[MaxString];
//*** build of motor list
nLastDrive = -1; id = 0;
do
{
sprintf(Ident,"Motor%d",id);
GetPrivateProfileString(Ident,"Type","",ctype,MaxString,GetCFile());
if(strlen(ctype) < 2) break;
nLastDrive = id;
if(strstr(strupr(ctype),"C-812ISA"))
{
aMotor[id] = (TMotor*)(TC_812ISA*)new TC_812ISA();
continue;
}
if(strstr(strupr(ctype),"C-812GPIB"))
{
aMotor[id] = (TMotor*)(TC_812GPIB*)new TC_812GPIB();
continue;
}
if(strstr(strupr(ctype),"C-832"))
{
aMotor[id] = (TC_832 *)new TC_832();
continue;
}
aMotor[id] = (TMotor*)new TMotor();
}
while(id++ < nMaxNumber);
if(nLastDrive > -1)
nActiveDrive = 0;
//********** initializion of all motors **************************************
for(id = 0;id <= LastId();id++)
{
sprintf(buf,szMsgLine001,MP(id)->pCharacteristic());
SetInfo(buf);
if(R_OK != MP(id)->Initialize())
{
bNoFailure = FALSE;
if(IDYES == MessageBox(GetFocus(),szMsgLine001,szMsgFailure,MBASK))
return bNoFailure;
delete aMotor[id];
aMotor[id] = (TMotor*)new TMotor();
aMotor[id]->Initialize();
}
}
SetInfo(szMsgLine003);
// Keine relative Winkel setzen
for(id = 0;id <= LastId();id++)
MP(id)->dAngleBias = 0.0;
// Die Positions-Register der Motor-Steuerung werden auf
NULL gesetzt und
// die abgespeicherten Positionen werden rechnerisch einbezogen
// Die abgespeicherten Positionen werden nicht ber‚cksichtigt.
// Es wird unterstellt, dai die Register der Motor-Steuerung
noch
// aktuell sind
return bNoFailure;
};
TAxisType TMList::ParsingAxis(LPSTR axisname)
{
if( !strcmp(axisname,"AzimutalRotation") ||
!strcmp(axisname,"AZ") ||
!strcmp(axisname,"Rotation") ||
!strcmp(axisname,"Azimute"))
return Rotation;
if( !strcmp(axisname,"X") ||
!strcmp(axisname,"x") ||
!strcmp(axisname,"Horizontal") ||
!strcmp(axisname,"x-Achse") ||
!strcmp(axisname,"x-Axis") )
return X;
if( !strcmp(axisname,"Y") ||
!strcmp(axisname,"y") ||
!strcmp(axisname,"y-Achse") ||
!strcmp(axisname,"y-Axis") )
return Y;
if( !strcmp(axisname,"Z") ||
!strcmp(axisname,"z") ||
!strcmp(axisname,"Vertical") ||
!strcmp(axisname,"z-Achse") ||
!strcmp(axisname,"z-Axis") )
return Z;
if(!strcmp(axisname,"Theta"))
return Theta;
if(!strcmp(axisname,"Omega"))
return Omega;
if( !strcmp(axisname,"Tilt") ||
!strcmp(axisname,"TL"))
return Tilt;
if( !strcmp(axisname,"DC") ||
!strcmp(axisname,"Diffraction coarse") ||
!strcmp(axisname,"Beugung grob") )
return DC;
if( !strcmp(axisname,"DF") ||
!strcmp(axisname,"Diffraction fine") ||
!strcmp(axisname,"Beugung fein"))
return DF;
if( !strcmp(axisname,"Psi"))
return Psi;
if( !strcmp(axisname,"Phi"))
return Phi;
if( !strcmp(axisname,"CC") ||
!strcmp(axisname,"Collimator") ||
!strcmp(axisname,"Kollimator"))
return Collimator;
if( !strcmp(axisname,"Absorber"))
return Absorber;
if( !strcmp(axisname,"Monochromator"))
return Monochromator;
if( !strcmp(axisname,"Encoder"))
return Encoder;
return (TAxisType)0;
};
BOOL TMList::SaveModuleSettings(void)
{
int id;
char buf[MaxString];
for(id = 0;id <= LastId();id++)
{
sprintf(buf,szMsgLine004,(LPSTR)MP(id)->pCharacteristic());
SetInfo(buf);
MP(id)->SaveSettings(TRUE);
MP(id)->StopDrive(FALSE);
}
return TRUE;
};
void TMList::SetAngleDefault(void)
{
int id;
for(id = 0;id <= LastId();id++)
{
MP(id)->dAngleBias = 0.0;
MP(id)->SetAngleRange();
}
}
TMotor* TMList::MP(void)
{
return aMotor[nActiveDrive];
};
TMotor* TMList::MP(int n)
{
if((n >= 0) && (n <= nLastDrive))
return aMotor[n];
return aMotor[nActiveDrive];
};
void TMList::SetParametersDlg(void)
{
TMotorParam* dlg;
dlg = new TMotorParam();
TheDialog = (TMotorParam *)dlg;
dlg->ExecuteDialog(GetFrameHandle());
delete dlg;
};
void TMList::InquireReferencePointDlg(int task)
{
TModalDlg* dlg;
dlg = (TCalibrate *)new TCalibrate(task);
dlg->ExecuteDialog(GetFrameHandle());
delete dlg;
};
BOOL TMList::SetAxis(int n)
{
if((n >= 0) && (n <= nLastDrive))
{
nActiveDrive = n;
return TRUE;
}
else
{
nActiveDrive = 0;
return FALSE;
}
};
//******************************************************************************
//**************************************************************************
// Anfahren der Nullstellung : Referenzpunktlauf
TCalibrate::TCalibrate(int task) : TModalDlg("CalibrateMotors")
{
bZeroShouldSet = FALSE;
nTask = task;
lOldPos
= new long [lpMList->LastId()+1];
bZeroPosReached = new BOOL [lpMList->LastId()+1];
bIndexPosReached = new BOOL [lpMList->LastId()+1];
bTargetPosReached = new BOOL [lpMList->LastId()+1];
switch(nTask) {
case 99:
bAllMotors
= TRUE;
bHoldPosition = FALSE;
bValidCalibrationData = TRUE;
break;
default:
bValidCalibrationData = TRUE;
bAllMotors
= FALSE;
bHoldPosition = FALSE;
}
};
TCalibrate::~TCalibrate(void)
{
delete[] lOldPos;
delete[] bZeroPosReached;
delete[] bTargetPosReached;
delete[] bIndexPosReached;
};
BOOL TCalibrate::Dlg_OnInit(HWND hwnd,HWND hwndCtl,LPARAM)
{
int i;
// Initialisieren der Parameterfenster f‚r einen Motor
Motor = lpMList->MP();
SetDlgItemText(hwnd,id_Report,"");
CheckDlgButton(hwnd,id_ValidCalibrationData,bValidCalibrationData);
hMotorList = GetDlgItem(hwnd,id_ChooseMotor);
i = 0;
while(i <= lpMList->LastId())
ComboBox_AddString(hMotorList,lpMList->MP(i++)->pCharacteristic());
ComboBox_SelectString(hMotorList,0,Motor->pCharacteristic());
switch(nTask) {
case 99:
FORWARD_WM_COMMAND(hwnd,cm_CarryOnZero,hwndCtl,0,PostMessage);
break;
default:;
}
return TRUE;
};
void TCalibrate::Dlg_OnTimer(HWND hwnd,UINT id)
{
int idx;
BOOL AnyToDo = FALSE;
if(id != TimerIdInformation)
return;
KillTimer(hwnd,TimerIdInformation);
for(idx = 0;idx <= lpMList->LastId();idx++)
{
if(!bIndexPosReached[idx])
{
AnyToDo = TRUE;
if(lpMList->MP(idx)->IsIndexArrived())
{
// Indexposition
// bei C-812 meist die linke Endlage plus RemoveLimit
// bei C-832 meist genau die Index-Position
plus RemoveLimit
// Es wurde noch kein Home neu gesetzt
FORWARD_WM_COMMAND(hwnd,cm_IndexArrived,0,idx,SendMessage);
continue;
}
continue;
}
if(!bZeroPosReached[idx])
{
AnyToDo = TRUE;
if(lpMList->MP(idx)->IsMoveFinish())
{
FORWARD_WM_COMMAND(hwnd,cm_DistanceSet,0,idx,SendMessage);
continue;
}
}
}
if(AnyToDo)
SetTimer(hwnd,TimerIdInformation,130,NULL);
return;
};
void TCalibrate::Dlg_OnCommand(HWND hwnd,int id,HWND hwndCtl,UINT
codeNotify)
{
int idx;
char buf[2*MaxString];
int NextMotor;
switch(id)
{
case cm_CarryOnZero:
if(bZeroShouldSet)
{
MessageBeep(0);
break;
}
// Kalibrierungs-Bedarf festlegen
bHoldPosition = IsDlgButtonChecked(GetHandle(),id_HoldPosition);
bValidCalibrationData = IsDlgButtonChecked(GetHandle(),id_ValidCalibrationData);
if(!bValidCalibrationData)
{
strcpy(buf,"Es wird davon ausgegangen, dai sich der
Antrieb\r\n");
strcat(buf,"in der Position der physikalischen Null
befindet.\r\n");
strcat(buf,"Es werden Kalibrierungsdaten ge*ndert
!");
if(IDYES != MessageBox(GetFocus(),buf,"Meldung",MBASK))
return;
}
for(idx = 0;idx <= lpMList->LastId();idx++)
bIndexPosReached[idx] = bZeroPosReached[idx] = TRUE;
if(!bAllMotors)
{
if(lpMList->MP()->bInitialMoveReady)
bIndexPosReached[Motor->GetId()] = bZeroPosReached[Motor->GetId()]
= FALSE;
else
MessageBox(GetHandle(),szMsgLine005,szMessage,MBINFO);
}
else
{
for(idx = 0;idx <= lpMList->LastId();idx++)
if(lpMList->MP(idx)->bInitialMoveReady)
bIndexPosReached[idx] = bZeroPosReached[idx]
= FALSE;
}
for(idx = 0;idx <= lpMList->LastId();idx++)
{
Motor = lpMList->MP(idx);
if(Motor->GetId() != idx)
MessageBox(GetHandle(),"Motor Id",szMsgFailure,MBINFO);
if(!bIndexPosReached[idx])
{
Motor->PushSettings();
Motor->StartToIndex(lOldPos[idx]); //
old position will be returned
bZeroShouldSet = TRUE;
}
}
if(bZeroShouldSet)
{
SetDlgItemText(GetHandle(),id_Report,"");
EnableWindow(GetDlgItem(hwnd,id_ChooseMotor),FALSE);
EnableWindow(GetDlgItem(hwnd,cm_SetHome),FALSE);
EnableWindow(GetDlgItem(hwnd,cm_CarryOnZero),FALSE);
goto ExitWithTimer;
}
switch(nTask) {
case 99:
FORWARD_WM_COMMAND(hwnd,IDCANCEL,hwndCtl,0,PostMessage);
break;
default:
SetDlgItemText(hwnd,id_Report,szMsgLine007);
}
return;
case cm_IndexArrived:
if(!lpMList->SetAxis(codeNotify))
{
MessageBox(GetHandle(),szMsgLine006,szMessage,MBINFO);
return;
}
Motor = lpMList->MP();
// Alle fertigen Motoren nicht mehr behandeln
if(bZeroPosReached[Motor->GetId()])
goto ExitWithTimer;
if(bIndexPosReached[Motor->GetId()])
goto ExitWithTimer;
// measure the difference between startpoint and index point
if(!bValidCalibrationData || bHoldPosition)
{
Motor->GetPosition(TRUE);
lOldPos[Motor->GetId()] -= Motor->lPosition;
}
if(!bValidCalibrationData)
Motor->lDistanceToZero = lOldPos[Motor->GetId()];
// compute and set up the zero point
Motor->SetHome();
Motor->lDeltaPosition = -Motor->lDistanceToZero;
bIndexPosReached[Motor->GetId()] = TRUE;
Motor->bIsCalibrated = TRUE;
sprintf(buf,"Index %s",Motor->pCharacteristic());
SetDlgItemText(GetHandle(),id_Report,(LPSTR)buf);
// start next motor to target position
// if hold old position take the old position
// in all other cases take the TargetAngle
// notify old position
if(bHoldPosition)
Motor->MoveByPosition(lOldPos[Motor->GetId()]);
else
Motor->MoveToAngle(Motor->dInitialAngle);
goto ExitWithTimer;
case cm_DistanceSet:
if(!lpMList->SetAxis(codeNotify))
{
MessageBox(GetHandle(),szMsgLine006,szMsgFailure,MBINFO);
return;
}
Motor = lpMList->MP();
if(bHoldPosition)
sprintf(buf,"Alte Position %s",Motor->pCharacteristic());
else
sprintf(buf,"Target Pos %s",Motor->pCharacteristic());
SetDlgItemText(GetHandle(),id_Report,(LPSTR)buf);
bZeroPosReached[Motor->GetId()] = TRUE;
Motor->GetAngle(1);
Motor->PopSettings(ThisPosition);
if(!bValidCalibrationData)
Motor->SaveSettings(FALSE);
// Ist ein Motor noch nicht am Zielpunkt?
NextMotor = FALSE;
for(idx = 0;idx <= lpMList->LastId();idx++)
if(!bZeroPosReached[idx])
NextMotor = TRUE;
if(NextMotor)
goto ExitWithTimer;
//*** Calibration finished
if(!bValidCalibrationData)
{
bValidCalibrationData = TRUE;
CheckDlgButton(GetHandle(),id_ValidCalibrationData,TRUE);
}
MessageBeep(0);
switch(nTask) {
case 99:
FORWARD_WM_COMMAND(hwnd,IDCANCEL,hwndCtl,0,PostMessage);
break;
default:
if(!bValidCalibrationData)
{
strcpy(buf,szMsgLine009);
strcat(buf,szMsgLine010);
MessageBox(GetHandle(),buf,szMessage,MBINFO);
}
else
MessageBox(GetHandle(),szMsgLine009,szMessage,MBINFO);
bZeroShouldSet = FALSE;
EnableWindow(GetDlgItem(GetHandle(),id_ChooseMotor),TRUE);
EnableWindow(GetDlgItem(GetHandle(),cm_SetHome),TRUE);
EnableWindow(GetDlgItem(GetHandle(),cm_CarryOnZero),TRUE);
}
return;
case cm_SetHome:
Motor->SetHome();
Motor->GetAngle(1);
sprintf(buf,szMsgLine008,Motor->pCharacteristic());
SetDlgItemText(GetHandle(),id_Report,buf);
return;
case id_ChooseMotor:
switch(codeNotify)
{
case CBN_SELCHANGE:
idx = ComboBox_GetCurSel(hMotorList);
if((Motor != lpMList->MP(idx)) && (idx !=
CB_ERR))
{
lpMList->SetAxis(idx);
Motor = lpMList->MP();
}
return;
}
return;
case cm_RotateMotor:
lpMList->SetAxis(Motor->GetId()+1);
Motor = lpMList->MP();
ComboBox_SelectString(hMotorList,0,Motor->pCharacteristic());
return;
case id_ValidCalibrationData:
if(bZeroShouldSet)
break;
bValidCalibrationData = IsDlgButtonChecked(GetHandle(),id_ValidCalibrationData);
if(bValidCalibrationData)
{
EnableWindow(GetDlgItem(GetHandle(),id_HoldPosition),TRUE);
EnableWindow(GetDlgItem(GetHandle(),id_AllMotorsReset),TRUE);
}
else
{
bHoldPosition = FALSE;
EnableWindow(GetDlgItem(GetHandle(),id_HoldPosition),FALSE);
EnableWindow(GetDlgItem(GetHandle(),id_AllMotorsReset),FALSE);
}
return;
case id_AllMotorsReset:
if(bZeroShouldSet)
break;
bAllMotors = IsDlgButtonChecked(GetHandle(),id_AllMotorsReset);
if(bAllMotors)
{
// Motor-Button deaktivieren
EnableWindow(GetDlgItem(GetHandle(),id_ChooseMotor),FALSE);
EnableWindow(GetDlgItem(GetHandle(),cm_SetHome),FALSE);
}
else
{
// Motor-Button aktivieren
EnableWindow(GetDlgItem(GetHandle(),id_ChooseMotor),TRUE);
EnableWindow(GetDlgItem(GetHandle(),cm_SetHome),TRUE);
}
return;
default:
TModalDlg::Dlg_OnCommand(hwnd,id,hwndCtl,codeNotify);
}
return;
ExitWithTimer:
SetTimer(GetHandle(),TimerIdInformation,200,NULL);
return;
};
BOOL TCalibrate::CanClose(void)
{
if(bZeroShouldSet) return FALSE;
// LimitWatch disable
return TRUE;
};
BOOL TCalibrate::LeaveDialog(void)
{
int id;
KillTimer(GetHandle(),TimerIdInformation);
for(id = 0;id <= lpMList->LastId();id++)
{
Motor = lpMList->MP(id);
Motor->StopDrive(TRUE);
}
return TRUE;
};
//**************************************************************************
// Steuerung des Probentellers ‚ber die Position
void TMList::PositionControlDlg(void)
{
TModalDlg* dlg;
dlg = (TPosControl*)new TPosControl();
dlg->ExecuteDialog(GetFrameHandle());
delete dlg;
};
TPosControl::TPosControl() : TModalDlg("PositionControl")
{
bMoveActive = FALSE;
};
BOOL TPosControl::Dlg_OnInit(HWND hwnd,HWND hwndCtl,LPARAM)
{
int cnt;
Motor = lpMList->MP();
BarHandle = GetDlgItem(hwnd,id_Bar);
hMotorList = GetDlgItem(hwnd,id_ChooseMotor);
cnt = 0;
while(cnt <= lpMList->LastId())
ComboBox_AddString(hMotorList,lpMList->MP(cnt++)->pCharacteristic());
FORWARD_WM_COMMAND(hwnd,cm_ParamSet,hwndCtl,0,SendMessage);
SetFocus(BarHandle);
return TRUE;
};
void TPosControl::Dlg_OnTimer(HWND hwnd,UINT id)
{
char buf[MaxString];
switch(id) {
case TimerIdInformation:
while(!Motor->GetPosition(TRUE));
sprintf(buf,"%ld",Motor->lPosition);
SetDlgItemText(hwnd,id_Position,buf);
if(Motor->IsMoveFinish() && bMoveActive)
{
KillTimer(hwnd,TimerIdInformation);
bMoveActive = FALSE;
}
FORWARD_WM_COMMAND(hwnd,cm_SetupDlgItem,0,0,SendMessage);
}
return;
};
void TPosControl::Dlg_OnCommand(HWND hwnd,int id,HWND hwndCtl,UINT
codeNotify)
{
char buf[20];
int idx;
switch(id)
{
case cm_SetupDlgItem:
SetScrollPos(BarHandle,SB_CTL,GetBarPos(Motor),TRUE);
sprintf(buf,"%ld",Motor->lPosition);
SetDlgItemText(GetHandle(),id_NewPosition,buf);
return;
case cm_ParamSet:
// Initialisieren des Motor-Scroll-Bar“s
sprintf(buf,"%ld",Motor->lPosition);
SetDlgItemText(GetHandle(),id_Position,buf);
ComboBox_SelectString(hMotorList,0,Motor->pCharacteristic());
BarHandle = GetDlgItem(GetHandle(),id_Bar);
SetScrollRange(BarHandle,SB_CTL,-GetBarRange(Motor)/2,GetBarRange(Motor)/2,FALSE);
// Initialisieren aller Positionsfenster
FORWARD_WM_COMMAND(hwnd,cm_SetupDlgItem,hwndCtl,0,SendMessage);
return;
case id_ChooseMotor:
switch(codeNotify)
{
case CBN_SELCHANGE:
idx = ComboBox_GetCurSel(hMotorList);
if((Motor != lpMList->MP(idx)) && (idx !=
CB_ERR))
{
Motor = lpMList->MP(idx);
lpMList->SetAxis(Motor->GetId());
FORWARD_WM_COMMAND(hwnd,cm_ParamSet,hwndCtl,0,SendMessage);
FORWARD_WM_COMMAND(hwnd,cm_MotorInit,hwndCtl,0,PostMessage);
}
}
return;
case cm_RotateMotor:
if(bMoveActive) break;
lpMList->SetAxis(Motor->GetId()+1);
Motor = lpMList->MP();
FORWARD_WM_COMMAND(hwnd,cm_ParamSet,hwndCtl,0,SendMessage);
return;
case IDOK:
// Der Nutzer hat mit Return eine neue Position eingegeben
GetDlgItemText(GetHandle(),id_NewPosition,(LPSTR)buf,10);
NewPosition = atol(buf);
if(NewPosition < Motor->lPositionMin)
NewPosition = Motor->lPositionMin;
else
if(NewPosition > Motor->lPositionMax)
NewPosition = Motor->lPositionMax;
FORWARD_WM_COMMAND(hwnd,cm_MoveButton,hwndCtl,0,PostMessage);
SetFocus(GetDlgItem(GetHandle(),id_Bar));
return;
case cm_MoveButton:
Motor->MoveToPosition(NewPosition);
SetTimer(GetHandle(),TimerIdInformation,80,NULL);
bMoveActive = TRUE;
FORWARD_WM_COMMAND(hwnd,cm_SetupDlgItem,hwndCtl,0,PostMessage);
return;
default:
TModalDlg::Dlg_OnCommand(hwnd,id,hwndCtl,codeNotify);
}
};
BOOL TPosControl::HScrollBar(WPARAM wParam,LPARAM)
{
switch(wParam)
{
case SB_LINEUP:
NewPosition = Motor->lPosition - Motor->wPositionWidth;
NewPosition = max(Motor->lPositionMin,NewPosition);
break;
case SB_LINEDOWN:
NewPosition = Motor->lPosition + Motor->wPositionWidth;
NewPosition = min(Motor->lPositionMax,NewPosition);
break;
case SB_PAGEUP:
NewPosition = Motor->lPosition - 5 * Motor->wPositionWidth;
NewPosition = max(Motor->lPositionMin,NewPosition);
break;
case SB_PAGEDOWN:
NewPosition = Motor->lPosition + 5 * Motor->wPositionWidth;
NewPosition = min(Motor->lPositionMax,NewPosition);
break;
case SB_ENDSCROLL:
// Bewegung ausl÷sen
FORWARD_WM_COMMAND(GetHandle(),cm_MoveButton,0,0,PostMessage);
break;
}
return TRUE;
};
int TPosControl::GetBarRange(const TMotor *act)
{
return (int)((act->lPositionMax - act->lPositionMin)/act->wPositionWidth);
};
int TPosControl::GetBarPos(const TMotor *act)
{
return (int)(act->lPosition / act->wPositionWidth);
};
BOOL TPosControl::LeaveDialog(void)
{
Motor->StopDrive(1);
KillTimer(GetHandle(),TimerIdInformation);
return TRUE;
};
//******************************************************************************
//*** Allgemeine Einstellungen f‚r Motoren
TMotorParam::TMotorParam(void) : TModalDlg("DriveSettings")
{
};
#pragma argsused
BOOL TMotorParam::Dlg_OnInit(HWND hwnd,HWND hwndCtl,LPARAM lParam)
{
int i;
// Initialisieren der Parameterfenster f‚r einen Motor
Motor = lpMList->MP();
hMotorList = GetDlgItem(GetHandle(),id_ChooseMotor);
i = 0;
while(i <= lpMList->LastId())
ComboBox_AddString(hMotorList, lpMList->MP(i++)->pCharacteristic());
FORWARD_WM_COMMAND(hwnd,cm_ParamSet,hwndCtl,0,SendMessage);
SetFocus(GetDlgItem(GetHandle(),id_Velocity));
return TRUE;
};
void TMotorParam::Dlg_OnCommand(HWND hwnd,int id,HWND hwndCtl,UINT
codeNotify)
{
int idx;
char buf[MaxString];
switch(id)
{
case cm_ParamSet:
// Initialisieren der Parameterfenster f‚r einen Motor
ComboBox_SelectString(hMotorList, 0, Motor->pCharacteristic());
sprintf(buf,Motor->pSF(),Motor->GetSpeed());
SetDlgItemText(GetHandle(),id_Velocity,(LPSTR)buf);
SetDlgItemText(GetHandle(),id_Limit,(LPSTR)ltoa(Motor->GetLimit(),(LPSTR)buf,10));
SetDlgItemText(GetHandle(),id_PositionMax,(LPSTR)ltoa(Motor->lPositionMax,(LPSTR)buf,10));
SetDlgItemText(GetHandle(),id_PositionMin,(LPSTR)ltoa(Motor->lPositionMin,(LPSTR)buf,10));
SetDlgItemText(GetHandle(),id_PositionWidth,(LPSTR)ltoa(Motor->wPositionWidth,(LPSTR)buf,10));
SetDlgItemText(GetHandle(),id_Unit,(LPSTR)Motor->szUnit);
sprintf(buf,Motor->pSF(),Motor->GetAngleWidth());
SetDlgItemText(GetHandle(),id_AngleWidth,(LPSTR)buf);
sprintf(buf,Motor->pDF(),Motor->dAngleMin);
SetDlgItemText(GetHandle(),id_AngleMin,(LPSTR)buf);
sprintf(buf,Motor->pDF(),Motor->dAngleMax);
SetDlgItemText(GetHandle(),id_AngleMax,(LPSTR)buf);
return;
case cm_SwitchLimitWatch:
if(!Motor->StartLimitWatch())
Motor->StopLimitWatch();
return;
case id_ChooseMotor:
switch(codeNotify)
{
case CBN_EDITCHANGE:
SetWindowText(hMotorList,Motor->pCharacteristic());
return;
case CBN_SELCHANGE:
idx = ComboBox_GetCurSel(hMotorList);
if((Motor != lpMList->MP(idx)) && (idx !=
CB_ERR))
{
if(CanClose())
{
Motor = lpMList->MP(idx);
lpMList->SetAxis(Motor->GetId());
}
FORWARD_WM_COMMAND(hwnd,cm_ParamSet,0,0,SendMessage);
}
return;
}
return;
case cm_RotateMotor:
// Erst die Einstellungen f‚r den aktuellen Motor sichern
if(CanClose())
{
lpMList->SetAxis(Motor->GetId()+1);
Motor = lpMList->MP();
}
FORWARD_WM_COMMAND(hwnd,cm_ParamSet,0,0,SendMessage);
return;
default:
TModalDlg::Dlg_OnCommand(hwnd,id,hwndCtl,codeNotify);
}
};
BOOL TMotorParam::LeaveDialog(void)
{
return TRUE;
};
BOOL TMotorParam::CanClose(void)
{
char buf[MaxString];
BOOL FActivate = FALSE;
BOOL FFail = FALSE;
WORD valueW;
DWORD valueDW;
double valueF;
for(;;)
{
GetDlgItemText(GetHandle(),id_Velocity,(LPSTR)buf,10);
if(!buf) { FFail = TRUE;break;}
valueF = atof(buf);
if(valueF == 0.0) { FFail = TRUE;break;}
if(Motor->SetSpeed(valueF))
FActivate = TRUE;
GetDlgItemText(GetHandle(),id_Limit,(LPSTR)buf,10);
if(!buf)
{
FFail = TRUE;
break;
}
valueDW = (DWORD)atol(buf);
if(Motor->GetLimit() != valueDW)
Motor->SetLimit(valueDW);
break;
}
if(FActivate) Motor->ActivateDrive();
if(FFail) return FALSE;
GetDlgItemText(GetHandle(),id_PositionWidth,(LPSTR)buf,10);
valueW = (WORD)atoi(buf);
if(0 != valueW)
Motor->wPositionWidth = valueW;
else
return FALSE;
GetDlgItemText(GetHandle(),id_PositionMax,(LPSTR)buf,10);
Motor->lPositionMax = atol(buf);
GetDlgItemText(GetHandle(),id_PositionMin,(LPSTR)buf,10);
Motor->lPositionMin = atol(buf);
GetDlgItemText(GetHandle(),id_AngleMax,(LPSTR)buf,10);
valueF = atof(buf);
if((0.0 != valueF))
{
Motor->dAngleMax = valueF;
}
else return FALSE;
GetDlgItemText(GetHandle(),id_AngleMin,(LPSTR)buf,10);
valueF = atof(buf);
if((0.0 != valueF))
{
Motor->dAngleMin = valueF;
}
else return FALSE;
GetDlgItemText(GetHandle(),id_AngleWidth,(LPSTR)buf,10);
valueF = atof(buf);
if(0.0 != valueF)
{
Motor->SetAngleWidth(valueF);
}
else return FALSE;
return TRUE;
};
//******************************************************************************
TOptimizeDC_832::TOptimizeDC_832(void) : TModalDlg("OptimizeDC_832")
{
Drive = (TC_832*)lpMList->MP();
bCancel = TRUE;
};
BOOL TOptimizeDC_832::Dlg_OnInit(HWND hwnd,HWND hwndCtl,LPARAM)
{
old_vel = Drive->dwMaxVelocity;
old_accel = Drive->dwAcceleration;
old_kp = Drive->wKP;
old_kd = Drive->wKD;
old_ki = Drive->wKI;
old_kl = Drive->wKL;
old_poswidth= Drive->wPositionWidth;
FORWARD_WM_COMMAND(hwnd,cm_ParamSet,hwndCtl,0,SendMessage);
return TRUE;
};
void TOptimizeDC_832::Dlg_OnCommand(HWND hwnd,int id,HWND hwndCtl,UINT
codeNotify)
{
char buf[MaxString];
switch(id){
case cm_ParamSet:
sprintf(buf,"Optimize DCM-Parameter for %s",Drive->pCharacteristic());
SetWindowText(GetHandle(),buf);
sprintf(buf,"%ld",Drive->dwMaxVelocity);
SetDlgItemText(GetHandle(),id_Velocity,(LPSTR)buf);
sprintf(buf,"%ld",Drive->dwAcceleration);
SetDlgItemText(GetHandle(),id_Acceleration,(LPSTR)buf);
sprintf(buf,"%d",Drive->wKD);
SetDlgItemText(GetHandle(),id_kd,(LPSTR)buf);
sprintf(buf,"%d",Drive->wKP);
SetDlgItemText(GetHandle(),id_kp,(LPSTR)buf);
sprintf(buf,"%d",Drive->wKI);
SetDlgItemText(GetHandle(),id_ki,(LPSTR)buf);
sprintf(buf,"%d",Drive->wKL);
SetDlgItemText(GetHandle(),id_kl,(LPSTR)buf);
sprintf(buf,"%d",Drive->wPositionWidth);
SetDlgItemText(GetHandle(),id_PositionWidth,(LPSTR)buf);
break;
case cm_StartMoveScan:
GetDlgItemText(GetHandle(),id_Velocity,buf,MaxString);
Drive->dwMaxVelocity = atol(buf);
GetDlgItemText(GetHandle(),id_Acceleration,buf,MaxString);
Drive->dwAcceleration = atol(buf);
GetDlgItemText(GetHandle(),id_kd,buf,MaxString);
Drive->wKD = (WORD)atoi(buf);
GetDlgItemText(GetHandle(),id_kp,buf,MaxString);
Drive->wKP = (WORD)atoi(buf);
GetDlgItemText(GetHandle(),id_ki,buf,MaxString);
Drive->wKI = (WORD)atoi(buf);
GetDlgItemText(GetHandle(),id_kl,buf,MaxString);
Drive->wKL = (WORD)atoi(buf);
GetDlgItemText(GetHandle(),id_PositionWidth,buf,MaxString);
Drive->wPositionWidth = (WORD)atoi(buf);
Drive->ActivateFilterParameters();
mStartMoveScan(10,0);
return;
default:
TModalDlg::Dlg_OnCommand(hwnd,id,hwndCtl,codeNotify);
}
return;
};
BOOL TOptimizeDC_832::CanClose(void)
{
bCancel = FALSE;
Drive->SaveSettings(0);
return TRUE;
};
BOOL TOptimizeDC_832::LeaveDialog(void)
{
if(bCancel)
{
Drive->dwMaxVelocity = old_vel;
Drive->dwAcceleration = old_accel;
Drive->wKP
= old_kp;
Drive->wKD
= old_kd;
Drive->wKI
= old_ki;
Drive->wKL
= old_kl;
Drive->wPositionWidth = old_poswidth;
}
Drive->ActivateFilterParameters();
return TRUE;
};
//******************************************************************************
//******************************************************************************
void TC_812::OptimizingDlg(void)
{
TModalDlg* dlg;
dlg = (TOptimizeDC_812 *)new TOptimizeDC_812();
dlg->ExecuteDialog(GetFrameHandle());
delete dlg;
};
TOptimizeDC_812::TOptimizeDC_812(void) : TModalDlg("OptimizeDC_812")
{
Drive = (TC_812*)lpMList->MP();
bCancel = TRUE;
};
#pragma argsused
BOOL TOptimizeDC_812::Dlg_OnInit(HWND hwnd,HWND hwndCtl,LPARAM
lParam)
{
old_vel = Drive->dwMaxVelocity;
old_accel = Drive->dwAcceleration;
old_gain = Drive->wStaticGain;
old_dgain = Drive->wDynamicGain;
old_torque = Drive->wTorque;
old_poswidth= Drive->wPositionWidth;
FORWARD_WM_COMMAND(hwnd,cm_ParamSet,hwndCtl,0,SendMessage);
return TRUE;
};
void TOptimizeDC_812::Dlg_OnCommand(HWND hwnd,int id,HWND hwndCtl,UINT
codeNotify)
{
char buf[MaxString];
switch(id){
case cm_ParamSet:
sprintf(buf,szMsgLine011,Drive->pCharacteristic());
SetWindowText(hwnd,buf);
sprintf(buf,"%ld",Drive->dwMaxVelocity);
SetDlgItemText(hwnd,id_Velocity,(LPSTR)buf);
sprintf(buf,"%ld",Drive->dwAcceleration);
SetDlgItemText(hwnd,id_Acceleration,(LPSTR)buf);
sprintf(buf,"%d",Drive->wTorque);
SetDlgItemText(hwnd,id_Torque,(LPSTR)buf);
sprintf(buf,"%d",Drive->wStaticGain);
SetDlgItemText(hwnd,id_Gain,(LPSTR)buf);
sprintf(buf,"%d",Drive->wDynamicGain);
SetDlgItemText(hwnd,id_DynamicGain,(LPSTR)buf);
sprintf(buf,"%d",Drive->wPositionWidth);
SetDlgItemText(hwnd,id_PositionWidth,(LPSTR)buf);
break;
case cm_StartMoveScan:
GetDlgItemText(hwnd,id_Velocity,buf,MaxString);
Drive->dwMaxVelocity = atol(buf);
GetDlgItemText(hwnd,id_Acceleration,buf,MaxString);
Drive->dwAcceleration = atol(buf);
GetDlgItemText(hwnd,id_Gain,buf,MaxString);
Drive->wStaticGain = (WORD)atoi(buf);
GetDlgItemText(hwnd,id_DynamicGain,buf,MaxString);
Drive->wDynamicGain = (WORD)atoi(buf);
GetDlgItemText(hwnd,id_Torque,buf,MaxString);
Drive->wTorque = (WORD)atoi(buf);
GetDlgItemText(GetHandle(),id_PositionWidth,buf,MaxString);
Drive->wPositionWidth = (WORD)atoi(buf);
Drive->ActivateFilterParameters();
mStartMoveScan(15,0);
break;
default:
TModalDlg::Dlg_OnCommand(hwnd,id,hwndCtl,codeNotify);
}
};
BOOL TOptimizeDC_812::CanClose(void)
{
char buf[MaxString];
bCancel = FALSE;
GetDlgItemText(GetHandle(),id_Velocity,buf,MaxString);
Drive->dwMaxVelocity = atol(buf);
GetDlgItemText(GetHandle(),id_Acceleration,buf,MaxString);
Drive->dwAcceleration = atol(buf);
GetDlgItemText(GetHandle(),id_Gain,buf,MaxString);
Drive->wStaticGain = (WORD)atoi(buf);
GetDlgItemText(GetHandle(),id_DynamicGain,buf,MaxString);
Drive->wDynamicGain = (WORD)atoi(buf);
GetDlgItemText(GetHandle(),id_Torque,buf,MaxString);
Drive->wTorque = (WORD)atoi(buf);
Drive->ActivateFilterParameters();
Drive->SaveSettings(0);
return TRUE;
};
BOOL TOptimizeDC_812::LeaveDialog(void)
{
if(bCancel)
{
Drive->dwMaxVelocity = old_vel;
Drive->dwAcceleration = old_accel;
Drive->wTorque
= old_torque;
Drive->wStaticGain = old_gain;
Drive->wDynamicGain = old_dgain;
Drive->wPositionWidth = old_poswidth;
Drive->ActivateFilterParameters();
}
return TRUE;
};
//******************************************************************************
//******************************************************************************
TMotor::TMotor()
{
char Ident[MaxString];
char ifile[MaxString];
char buf[MaxString];
nId
= nMaxId++;
dAngleBias
= 0.0;
dAngle = 0.0;
lCorrPos = 0;
fCorrBias = 0.0;
bIndexLine = FALSE;
bIndexDetected = FALSE;
bControlBoardOk = FALSE;
bLimitWatchActive = FALSE;
eCorrStatus = CorrLinear;
bIsCalibrated = FALSE;
bInquireStatus = FALSE;
bRangeHit
= FALSE;
bUpwards
= TRUE;
lDeltaPosition = 0;
lPosition
= 0;
lPreviousPosition = 0;
strcpy(ifile,GetCFile());
sprintf(Ident,"motor%d",nId);
GetPrivateProfileString(Ident,"Name","Motor",szCharacteristic,MaxString,GetCFile());
WritePrivateProfileString(Ident,"Name",szCharacteristic,GetCFile());
dwHysteresis = (DWORD)GetPrivateProfileInt(Ident,"Hysteresis",0,GetCFile());
WritePrivateProfileString(Ident,"Hysteresis",ltoa(dwHysteresis,buf,10),GetCFile());
strcpy(buf,szCharacteristic);
switch(lpMList->ParsingAxis(buf)) {
case Rotation: case Phi:
lpMList->AD_Phi = nId;
lpMList->AD_Rotation = nId;
break;
case X:
lpMList->AD_X = nId;
break;
case Y:
lpMList->AD_Y = nId;
break;
case Z:
lpMList->AD_Z = nId;
break;
case Theta:
lpMList->AD_Theta = nId;
break;
case Omega: case DF:
lpMList->AD_Omega = nId;
lpMList->AD_DF = nId;
break;
case Tilt: case Psi:
lpMList->AD_Psi = nId;
lpMList->AD_Tilt = nId;
break;
case DC:
lpMList->AD_DC = nId;
break;
case Collimator:
lpMList->AD_Collimator = nId;
break;
case Absorber:
lpMList->AD_Absorber = nId;
break;
case Monochromator:
lpMList->AD_Monochromator = nId;
break;
case Encoder:
lpMList->AD_Encoder = nId;
break;
}
};
TMotor::Initialize(void)
{
HCURSOR hCursorOld;
float MaxFailure;
char Ident[MaxString+1];
char buf[MaxString+1];
hCursorOld = SetCursor(LoadCursor(NULL,IDC_WAIT));
// Motor identifizieren
sprintf(Ident,"motor%d",nId);
GetPrivateProfileString(Ident,"MaxVelocity","8000",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"MaxVelocity",buf,GetCFile());
dwMaxVelocity = atol(buf);
GetPrivateProfileString(Ident,"Velocity","8000",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"Velocity",buf,GetCFile());
dwVelocity = atol(buf);
if(dwVelocity == 0)
dwVelocity = dwMaxVelocity / 2;
GetPrivateProfileString(Ident,"Unit","Unit",szUnit,20,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"Unit",szUnit,GetCFile());
eUnit = UnitEnum(szUnit);
strcpy(DFmt,"%.2lf");
strcpy(SFmt,"%.2lf");
GetPrivateProfileString(Ident,"Digits","2",buf,MaxString,GetCFile());
DFmt[2] = (char)('0' + atoi(buf));
SFmt[2] = (char)('1' + atoi(buf));
if(CreateDefaults())
WritePrivateProfileString(Ident,"Digits",buf,GetCFile());
GetPrivateProfileString(Ident,"MinimalWidth","10",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"MinimalWidth",buf,GetCFile());
wPositionMinWidth = (WORD)atoi(buf);
GetPrivateProfileString(Ident,"MaximalWidth","510",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"MaximalWidth",buf,GetCFile());
wPositionMaxWidth = (WORD)atoi(buf);
GetPrivateProfileString(Ident,"PositionMin","-100",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"PositionMin",buf,GetCFile());
lPositionMin = atol(buf);
GetPrivateProfileString(Ident,"PositionMax","100",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"PositionMax",buf,GetCFile());
lPositionMax = atol(buf);
if(lPositionMax <= lPositionMin)
lPositionMax = lPositionMin + 100;
GetPrivateProfileString(Ident,"PositionWidth","10",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"PositionWidth",buf,GetCFile());
wPositionWidth = (WORD)atoi(buf);
if(wPositionWidth == 0)
wPositionWidth = 0.2;
GetPrivateProfileString(Ident,"InitialMove","0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"InitialMove",buf,GetCFile());
bInitialMoveReady = atoi(buf);
GetPrivateProfileString(Ident,"RestartPosible","0",buf,MaxString,GetCFile());
WritePrivateProfileString(Ident,"RestartPosible","0",GetCFile());
if(bInitialMoveReady)
SetCalibrationState(atoi(buf));
else
SetCalibrationState(TRUE);
GetPrivateProfileString(Ident,"DeltaPosition","0",buf,MaxString,GetCFile());
lDeltaPosition = atol(buf);
if(IsCalibrated())
{
if(!bUpwards)
lDeltaPosition += dwHysteresis;
}
dAngleBias = 0.0;
lCorrPos = 0;
GetPrivateProfileString(Ident,"DistanceToZero","0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"DistanceToZero",buf,GetCFile());
lDistanceToZero = atol(buf);
GetPrivateProfileString(Ident,"RemoveLimit","4000",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"RemoveLimit",buf,GetCFile());
dwRemoveLimit = (DWORD)atol(buf);
GetPrivateProfileString(Ident,"MoveFirstToLimit","0",buf,MaxString,GetCFile());
bMoveFirstToLimit = atoi(buf);
GetPrivateProfileString(Ident,"IndexLine","0",buf,MaxString,GetCFile());
bIndexLine = atoi(buf);
GetPrivateProfileString(Ident,"InitialAngle","0.0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"InitialAngle",buf,GetCFile());
dInitialAngle = atof(buf);
GetPrivateProfileString(Ident,"Acceleration","10",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"Acceleration",buf,GetCFile());
dwAcceleration = atol(buf);
GetPrivateProfileString(Ident,"AngleMin","-1.0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"AngleMin",buf,GetCFile());
dAngleMin = atof(buf);
GetPrivateProfileString(Ident,"AngleMax","1.0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"AngleMax",buf,GetCFile());
dAngleMax = atof(buf);
GetPrivateProfileString(Ident,"AngleWidth","0.1",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"AngleWidth",buf,GetCFile());
dAngleWidth = atof(buf);
GetPrivateProfileString(Ident,"Koeff_3","0.0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"Koeff_3",buf,GetCFile());
dKoeff_3 = atof(buf);
GetPrivateProfileString(Ident,"Koeff_2","0.0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"Koeff_2",buf,GetCFile());
dKoeff_2 = atof(buf);
GetPrivateProfileString(Ident,"Koeff_1","1.0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"Koeff_1",buf,GetCFile());
dKoeff_1 = atof(buf);
GetPrivateProfileString(Ident,"SpeedScale","10.0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"SpeedScale",buf,GetCFile());
fSpeedScale = atof(buf);
SetCursor(hCursorOld);
GetPrivateProfileString(Ident,"MaxFailure","30.0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"MaxFailure",buf,GetCFile());
MaxFailure = atof(buf);
dwInterval = (DWORD)(3.0 * MaxFailure / dKoeff_1);
switch(eUnit) {
case Grad: dwInterval *= 3600; break;
case Minuten: dwInterval *= 60; break;
}
GetPrivateProfileString(Ident,"Correction","0",buf,MaxString,GetCFile());
if(CreateDefaults())
WritePrivateProfileString(Ident,"Correction",buf,GetCFile());
bCorrection = atoi(buf);
SetCorrectionState(TRUE);
return R_OK;
};
//*************** Element-Funktionen ******************************************
BOOL TMotor::SetAngleRange(void)
{
double a1,a2;
Translate(a1,lPositionMin);
Translate(a2,lPositionMax);
dAngleMax = max(a1,a2);
dAngleMin = min(a1,a2);
return TRUE;
};
BOOL TMotor::PushSettings(void)
{
Settings.dAngle = dAngle;
Settings.dAngleMin = dAngleMin;
Settings.dAngleMax = dAngleMax;
Settings.dAngleWidth = dAngleWidth;
Settings.dSpeed = dSpeed;
return TRUE;
};
BOOL TMotor::PopSettings(TMParameter param)
{
if(dAngle != Settings.dAngle)
if(param == OldPosition)
MoveToAngle(Settings.dAngle);
dAngleMin = Settings.dAngleMin;
dAngleMax = Settings.dAngleMax;
SetAngleWidth(Settings.dAngleWidth);
SetSpeed(Settings.dSpeed);
return TRUE;
};
// Umrechnung von Position in Winkel mit einem Polynom
// Umkehrfunktion mit Newton-Verfahren
void TMotor::funcd(double arg,double offset,double *f,double *df)
{
*f = arg * (dKoeff_1 + arg * (dKoeff_2 + arg * dKoeff_3))
- offset;
*df = dKoeff_1 + arg * (2*dKoeff_2 + arg * 3*dKoeff_3);
};
int TMotor::rtsave(double offset,double x1,double x2,double
xacc,double *ret)
/* Using a combination of Newton-Raphson and bisection,
find the */
/* root of a function bracketed between x1 and x2.
The root, re- */
/* turned as the function value rtsafe, will be refined
until its */
/* accuracy is known within +-xacc. funcd is a user-supplied
rou- */
/* tine that provides both the function value and the
first deriv- */
/* ative of the function.
*/
{
int j;
double df,dx,dxold,f,fh,fl,xh,xl,rts;
funcd(x1,offset,&fl,&df);
funcd(x2,offset,&fh,&df);
if((fl)*(fh)>=0.0)
return -1; // "Root must be bracketed in RTSAFE"
if((fl)<0.0) // Orient the search so that f(xl)<0.
{
xl=x1; xh=x2;
}
else
{
xh=x1; xl=(fl); fl=fh; fh=xl; xl=x2;
}
rts = 0.5*(x1+x2);
// Initialize the guess for root,
dx=dxold=fabs(x2-x1);
// the "step-size before last" and the last step.
funcd(rts,offset,&f,&df);
for(j=1;j<=MAXIT;j++)
// Loop over allowed iterations.
{
if((((rts-xh)*df-f)*((rts-xl)*df-f)>=0.0)
// Bisect if Newton out of range,
||(fabs(2.0*f)>fabs(dxold*df)))
// or not decreasing fast enough.
{
dxold = dx;
dx = 0.5*(xh-xl);
rts = xl+dx;
if(xl==rts)
{
// Change in root is negligible.
*ret = rts;
return 0;
}
}
else
// Newton step acceptable. Take it.
{
dxold = dx;
dx = f/df;
df = rts;
rts -= dx;
if(df==rts)
{
*ret = rts;
return 0;
}
}
if(fabs(dx)<xacc)
// Convergence criterion.
{
*ret = rts;
return 0;
}
funcd(rts,offset,&f,&df);
// The one new function evaluation per iteration.
if(f<0.0)
// Maintain the bracket on the root.
{
xl = rts; fl = f;
}
else
{
xh = rts; fh = f;
}
}
return -2; // "Maximum number of iterations exceeded in RTSAFE"
};
BOOL TMotor::Translate(long &pos,double ang)
{
// translate angle to position
char buffer[MaxString];
double l_ang;
double l_pos;
double xleft,xright;
int ret;
// Liegt Winkel im Bereich ?
bRangeHit = FALSE;
l_ang = ang - dAngleBias + fCorrBias;
if(l_ang > dAngleMax)
{
bRangeHit = TRUE; l_ang = dAngleMax;
}
if(ang < dAngleMin)
{
bRangeHit = TRUE; l_ang = dAngleMin;
}
// *bersetzen des Winkels in eine Position
switch(eUnit) {
case Grad: l_ang = l_ang * 3600.0; break;
case Minuten: l_ang = l_ang * 60.0; break;
}
switch(eCorrStatus) {
case CorrPolynom:
xleft = xright = l_ang / dKoeff_1;
xright += dwInterval;
xleft -= dwInterval;
ret = rtsave(l_ang,xleft,xright,1,&l_pos);
if(ret)
{
sprintf(buffer,"Newton %d !\n",ret);
MessageBox(GetFocus(),buffer,szMsgFailure,MBINFO);
return FALSE;
}
break;
default:
l_pos = l_ang / dKoeff_1;
}
pos = max(min((long)ceil(l_pos),lPositionMax),lPositionMin);
return TRUE;
};
BOOL TMotor::Translate(double&ang,long pos)
{
// translate position to angle
double l_ang;
// Positions-Offset ber‚cksichtigen
switch(eCorrStatus) {
case CorrPolynom:
l_ang = pos * (dKoeff_1 + pos * (dKoeff_2 + pos * dKoeff_3));
break;
default:
l_ang = pos * dKoeff_1;
}
switch(eUnit) {
case Grad:
l_ang = l_ang / 3600.0;
break;
case Minuten:
l_ang = l_ang / 60.0;
}
ang = l_ang + dAngleBias - fCorrBias;
return TRUE;
};
void TMotor::SetCorrectionState(BOOL onoff)
{
long dcpos;
float ang1,ang2;
lCorrPos = 0;
fCorrBias = 0.0;
if(!bCorrection || !bIsCalibrated)
{
eCorrStatus = CorrLinear;
return;
}
if(onoff)
{
if(nId != lpMList->AD_DF)
{
eCorrStatus = CorrPolynom;
return;
}
lpMList->MP(lpMList->AD_DC)->GetPosition(1);
dcpos = lpMList->MP(lpMList->AD_DC)->lPosition;
if(dcpos == lCorrPos)
{
eCorrStatus = CorrPolynom;
return;
}
GetAngle(1);
ang1 = dAngle;
lCorrPos = dcpos;
fCorrBias = 0.0;
eCorrStatus = CorrPolynom;
GetAngle(1); // MS-Pos
ang2 = dAngle;
fCorrBias = ang2 - ang1;
}
else
{
eCorrStatus = CorrLinear;
lCorrPos = 0;
fCorrBias = 0.0;
}
};
BOOL TMotor::SetHome(void)
{
bIsCalibrated = FALSE;
SetCorrectionState(0);
lPreviousPosition = GetPosition(1);
lDeltaPosition = 0;
lPosition = 0;
dAngle = 0.0;
dAngleBias = 0.0;
return TRUE;
};
BOOL TMotor::MoveByPosition(long pos)
{
lPosition += pos;
return TRUE;
};
BOOL TMotor::MoveToPosition(long pos)
{
lPosition = pos;
return TRUE;
};
BOOL TMotor::MoveToAngle(double ang)
{
long lpos;
if(Translate(lpos,ang))
if(MoveToPosition(lpos))
return TRUE;
return FALSE;
};
BOOL TMotor::MoveByAngle(double ang)
{
long lpos;
if(!GetAngle(1))
return FALSE;
if(Translate(lpos,(ang+dAngle)))
if(MoveToPosition(lpos))
return TRUE;
return FALSE;
};
BOOL TMotor::SetAngleWidth(double dang)
{
double dposcmp,dpos;
switch(eUnit) {
case Grad: dposcmp = dpos = 3600.0 * fabs(dang
/ dKoeff_1); break;
case Minuten: dposcmp = dpos = 60.0 * fabs(dang / dKoeff_1);
break;
default: dposcmp = dpos = fabs(dang /
dKoeff_1); break;
}
dpos = max(min(dpos,(double)wPositionMaxWidth),(double)wPositionMinWidth);
switch(eUnit) {
case Grad:
dAngleWidth = fabs(dKoeff_1 * dpos / 3600.0);
break;
case Minuten:
dAngleWidth = fabs(dKoeff_1 * dpos / 60.0);
break;
default:
dAngleWidth = fabs(dKoeff_1 * dpos);
}
if(dpos != dposcmp)
return FALSE;
return TRUE;
};
BOOL TMotor::GetAngle(BOOL saveyesno)
{
double ang;
if(!GetPosition(saveyesno))
return FALSE;
if(!Translate(ang,lPosition))
return FALSE;
dAngle = ang;
#ifdef CheckCorrect
if(saveyesno)
{
char buf[MaxString];
sprintf(buf,"P:%ld dP:%ld dW:%.2f",lPosition,lCorrPos,fCorrBias);
SetInfo(buf);
}
#endif
return TRUE;
};
int TMotor::SaveSettings(BOOL LastSave)
{
//*** Abspeichern der Motoreinstellungen in den Parameter-File.
HCURSOR hCursorOld;
char buf[MaxString];
char Ident[MaxString];
if(!bControlBoardOk) return R_Failure;
sprintf(Ident,"motor%d",nId);
hCursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
sprintf(buf,"%ld",lDistanceToZero);
WritePrivateProfileString(Ident,"DistanceToZero",buf,GetCFile());
if(LastSave)
{
SetCorrectionState(OFF);
sprintf(buf,"%ld",dwVelocity);
WritePrivateProfileString(Ident,"Velocity",buf,GetCFile());
sprintf(buf,"%u",wPositionWidth);
WritePrivateProfileString(Ident,"PositionWidth",buf,GetCFile());
sprintf(buf,"%d",bUpwards);
WritePrivateProfileString(Ident,"Upwards",buf,GetCFile());
GetPosition(TRUE);
sprintf(buf,"%ld",lPosition);
WritePrivateProfileString(Ident,"DeltaPosition",buf,GetCFile());
sprintf(buf,pDF(),dAngleMin);
WritePrivateProfileString(Ident,"AngleMin",buf,GetCFile());
sprintf(buf,pSF(),dAngleWidth);
WritePrivateProfileString(Ident,"AngleWidth",buf,GetCFile());
sprintf(buf,pDF(),dAngleBias);
WritePrivateProfileString(Ident,"AngleBias",buf,GetCFile());
sprintf(buf,pDF(),dAngleMax);
WritePrivateProfileString(Ident,"AngleMax",buf,GetCFile());
if(bIsCalibrated)
WritePrivateProfileString(Ident,"RestartPosible","1",GetCFile());
}
SetCursor(hCursorOld);
return R_OK;
};
//******************************************************************************
TDC_Drive::TDC_Drive(void) : TMotor()
{
char Ident[MaxString];
nMaxError = 2;
sprintf(Ident,"motor%d",nId);
wDeathBand = (WORD)GetPrivateProfileInt(Ident,"DeathBand",1,GetCFile());
wDeccelerationPoint = (WORD)GetPrivateProfileInt(Ident,"DeccelerationPoint",20,GetCFile());
};
int TDC_Drive::SaveSettings(BOOL onlythis)
{
return TMotor::SaveSettings(onlythis);
}
int TDC_Drive::Initialize(void)
{
char buf[MaxString];
if(R_OK != TMotor::Initialize())
goto Exit;
if(CheckBoardOk())
{
if(!Reset())
goto Exit;
if(!ActivateFilterParameters())
goto Exit;
if(!ActivateDrive())
goto Exit;
}
else
{
sprintf(buf,szMsgLine012,pCharacteristic());
MessageBox(GetFocus(),buf,szMsgFailure,MBSTOP);
#ifdef TESTLAUF
return R_NoCommunication;
#endif
}
return R_OK;
Exit:
#ifdef TESTLAUF
return FALSE;
#else
return R_OK;
#endif
};
BOOL TDC_Drive::PushSettings(void)
{
return TRUE;
};
BOOL TDC_Drive::PopSettings(void)
{
return TRUE;
};
BOOL TDC_Drive::MoveToPosition(long position)
{
// Ber‚cksichtigen des Spiels
if(bUpwards && (position < lPosition))
{
lDeltaPosition += dwHysteresis;
bUpwards = FALSE;
}
else
if(!bUpwards && (position > lPosition))
{
lDeltaPosition -= dwHysteresis;
bUpwards = TRUE;
};
// Ber‚cksichtigen der relativen Position nach Programm-Start
und Richtungswechsel
position -= lDeltaPosition + lCorrPos;
return MoveAbsolute(position);
};
BOOL TDC_Drive::MoveByPosition(long distance)
{
return MoveRelative(distance);
};
BOOL TDC_Drive::SetSpeed(double speed)
{
DWORD velocity;
velocity = fSpeedScale * speed;
SetVelocity(velocity);
dSpeed = (double)GetVelocity() / fSpeedScale;
return TRUE;
};
double TDC_Drive::GetSpeed(void)
{
DWORD vel;
vel = GetVelocity();
if(vel == 0) return 0.0;
dSpeed = (double)vel / fSpeedScale;
return dSpeed;
};
BOOL TDC_Drive::GetPosition(BOOL bSave)
{
long pos1,pos2;
if(_GetPosition(&pos1))
{
if(bSave)
{
if(!_GetPosition(&pos2)) return FALSE;
if(pos1 != pos2) return FALSE;
}
// Ber‚cksichtigen der relativen Karten-Position
lPosition = pos1 + lDeltaPosition + lCorrPos;
return TRUE;
}
return FALSE;
};
long TDC_Drive::GetFailure(void)
{
long failure;
int check = 3;
while(!_GetFailure(&failure))
{
if(0 == check--)
return 100;
}
return failure;
};
//*************************************************************************
TC_812::TC_812(void) : TDC_Drive()
{
char Ident[MaxString];
sprintf(Ident,"motor%d",nId);
nOnBoardId = GetPrivateProfileInt(Ident,"BoardId",1,GetCFile());
wStaticGain = (WORD)GetPrivateProfileInt(Ident,"Gain",100,GetCFile());
wDynamicGain = (WORD)GetPrivateProfileInt(Ident,"DynamicGain",37,GetCFile());
wMaxTorque = 127;
nWaitTicks = 5;
wTorque = (WORD)GetPrivateProfileInt(Ident,"Torque",110,GetCFile());
};
int TC_812::SaveSettings(BOOL bLastSave)
{
char buf[MaxString];
char Ident[MaxString];
if(!bControlBoardOk) return R_Failure;
sprintf(Ident,"motor%d",nId);
sprintf(buf,"%u",wDynamicGain);
WritePrivateProfileString(Ident,"DynamicGain",buf,GetCFile());
sprintf(buf,"%u",wTorque);
WritePrivateProfileString(Ident,"Torque",buf,GetCFile());
sprintf(buf,"%u",wStaticGain);
WritePrivateProfileString(Ident,"Gain",buf,GetCFile());
sprintf(buf,"%lu",dwMaxVelocity);
WritePrivateProfileString(Ident,"MaxVelocity",buf,GetCFile());
sprintf(buf,"%lu",dwAcceleration);
WritePrivateProfileString(Ident,"Acceleration",buf,GetCFile());
sprintf(buf,"%lu",dwVelocity);
WritePrivateProfileString(Ident,"Velocity",buf,GetCFile());
return TDC_Drive::SaveSettings(bLastSave);
};
BOOL TC_812::ActivateFilterParameters(void)
{
char cmd[MaxString];
sprintf(cmd,"%uDB%u\r",nOnBoardId,wDeathBand);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
sprintf(cmd,"%uSQ%u,%uSG%u,%uSE%u\r", nOnBoardId,wTorque,\
nOnBoardId,wStaticGain,\
nOnBoardId,wDynamicGain);
if(R_OK!=ExecuteCmd(cmd))
return FALSE;
SetVelocity(dwMaxVelocity);
SetAcceleration(dwAcceleration);
SetLimit(dwRemoveLimit);
GetSpeed();
return TRUE;
};
BOOL TC_812::Reset(void)
{
long lDeltaP = lDeltaPosition;
BOOL bIsCal = IsCalibrated();
BOOL ret = SetHome();
lDeltaPosition = lDeltaP;
SetCalibrationState(bIsCal);
nC812 = GetId();
return ret;
};
BOOL TC_812::SetMoment(float moment)
{
// Dreh-Moment 0 .. 1.0
if(moment <= 1.0)
wTorque = 127 * moment;
else
wTorque = 60;
SetTorque(wTorque);
return TRUE;
};
float TC_812::GetMoment(void)
{
WORD torque;
// Dreh-Moment 0 .. 1.0
torque = GetTorque();
return (torque / wMaxTorque);
};
BOOL TC_812::SetLine(int number,BOOL status)
{
char cmd[MaxString+1];
if((1 > number) && (16 < number))
return FALSE;
if(status)
sprintf(cmd,"%uCT%u,%uCN%u\r",nOnBoardId,number,nOnBoardId,number);
else
sprintf(cmd,"%uCT%u,%uCF%u\r",nOnBoardId,number,nOnBoardId,number);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
return TRUE;
};
BOOL TC_812::IsLimitHit(void)
{
if(GetStatus() & StatMLimitHit)
return TRUE;
else
return FALSE;
};
BOOL TC_812::IsMoveFinish(void)
{
if(bInquireStatus)
{
if(GetStatus() & StatMStopped)
return TRUE;
}
else
{
if(labs(GetFailure()) <= (long)wDeathBand)
return TRUE;
}
return FALSE;
};
BOOL TC_812::IsIndexArrived(void)
{
if(bIndexDetected && IsMoveFinish())
return TRUE;
if(IsLimitHit())
{
if(!bIndexDetected)
{
DelayTime(20);
bIndexDetected = TRUE;
}
}
return FALSE;
};
BOOL TC_812::StartToIndex(long &oldPos)
{
SetSpeed(10000.0);
lDeltaPosition = 0;
SetCorrectionState(0);
GetPosition(TRUE);
oldPos = lPosition;
bIndexDetected = FALSE;
bIndexLine = FALSE;
MoveToPosition(lPosition - 400000000l);
// Die Motoren werden in Bewegung gesetzt
// Erreichen der Stillstands-Position
DelayTime(100);
return TRUE;
};
BOOL TC_812::ActivateDrive(void)
{
char cmd[MaxString+1];
sprintf(cmd,"%uSP%u\r",nOnBoardId,wDeccelerationPoint);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
sprintf(cmd,"%uMN\r",nOnBoardId);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
return TRUE;
};
BOOL TC_812::StopDrive(int bOffOn)
{
char cmd[MaxString+1];
if(bOffOn)
{
sprintf(cmd,"%uAB\r",nOnBoardId);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
// Einige Motoren k÷nnen nach diesem Stop ihre Position
// nicht mehr einregeln, deshalb ein zweites Kommando zum
// zum Gleichsetzen von Target und Position
Delay(100);
sprintf(cmd,"%uAB\r",nOnBoardId);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
sprintf(cmd,"%uMN\r",nOnBoardId);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
}
else
{
sprintf(cmd,"%uAB\r",nOnBoardId);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
}
return TRUE;
};
BOOL TC_812::SetDynamicGain(WORD dygain)
{
char cmd[MaxString+1];
dygain = min(dygain,(WORD)255);
dygain = max(dygain,(WORD)1);
wDynamicGain = dygain;
sprintf(cmd,"%uSE%u\r",nOnBoardId,wDynamicGain);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
return TRUE;
};
WORD TC_812::GetDynamicGain(void)
{
return wDynamicGain;
};
BOOL TC_812::SetTorque(WORD torque)
{
char cmd[MaxString+1];
wTorque = min(torque,(WORD)127);
sprintf(cmd,"%uSQ%u\r",nOnBoardId,wTorque);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
return TRUE;
};
WORD TC_812::GetTorque(void)
{
wTorque = min(wTorque,(WORD)127);
return wTorque;
};
BOOL TC_812::SetVelocity(DWORD velocity)
{
char cmd[MaxString+1];
dwVelocity = (velocity<dwMaxVelocity)?velocity:dwMaxVelocity;
sprintf(cmd,"%uSV%lu\r",nOnBoardId,dwVelocity);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
sprintf(cmd,"%uCP\r",nOnBoardId);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
return TRUE;
};
DWORD TC_812::GetVelocity(void)
{
dwVelocity = (dwVelocity<dwMaxVelocity)?dwVelocity:dwMaxVelocity;
return dwVelocity;
};
BOOL TC_812::SetAcceleration(DWORD acceleration)
{
char cmd[MaxString+1];
dwAcceleration = acceleration;
sprintf(cmd,"%uSA%lu\r",nOnBoardId,dwAcceleration);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
sprintf(cmd,"%uSD%lu\r",nOnBoardId,dwAcceleration);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
sprintf(cmd,"%uCP\r",nOnBoardId);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
return TRUE;
};
DWORD TC_812::GetAcceleration(void)
{
return dwAcceleration;
};
BOOL TC_812::SetLimit(DWORD limit)
{
char cmd[MaxString+1];
dwRemoveLimit = limit;
sprintf(cmd,"%uLS%lu\r",nOnBoardId,dwRemoveLimit);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
return TRUE;
};
BOOL TC_812::SetHome(void)
{
char cmd[MaxString+1];
// changing K-System
TMotor::SetHome();
sprintf(cmd,"%uDH\r",nOnBoardId);
if(R_OK != ExecuteCmd(cmd))
return FALSE;
return TRUE;
};
WORD TC_812::GetStatus(void)
{
char buf[MaxString+1];
char msg[MaxString];
char *token;
WORD _status;
sprintf(buf,"%uTS\r",nOnBoardId);
switch(ExecuteCmd(buf)) {
case R_OK:
token = strtok(buf,"\n\3\r");
if(!token) return FALSE;
if((token[1]-'0') != nOnBoardId) return FALSE;
if(token[2] != 'S') return FALSE;
if(strlen(token) < 6) return FALSE;
sscanf(&(token[3]),"%u",&_status);
return _status;
case R_TimeOut:
sprintf(msg,"GetStatus: %s",buf);
MessageBox(GetFocus(),msg,"TimeOut MS",MBFAILURE);
return -1;
case R_UnknownCmd:
sprintf(msg,"GetStatus: %s",buf);
MessageBox(GetFocus(),msg,"Fehler",MBFAILURE);
return -1;
default:
return -1;
}
};
BOOL TC_812::_GetPosition(long *position)
{
char buf[MaxString];
char msg[MaxString];
char *token;
sprintf(buf,"%uTP\r",nOnBoardId);
switch(ExecuteCmd(buf)) {
case R_OK:
token = strtok(buf,"\n\3\r");
if(!token) return FALSE;
if((token[1]-'0') != nOnBoardId) return FALSE;
if(token[2] != 'P') return FALSE;
sscanf(&(token[3]),"%ld",position);
return TRUE;
case R_TimeOut:
sprintf(msg,"GetPosition: %s",buf);
MessageBox(GetFocus(),msg,"TimeOut MS",MBFAILURE);
return FALSE;
case R_UnknownCmd:
sprintf(msg,"GetPosition: %s",buf);
MessageBox(GetFocus(),msg,"Fehler",MBFAILURE);
return FALSE;
default:
return FALSE;
}
};
BOOL TC_812::_GetFailure(long *failure)
{
char buf[MaxString+1];
char msg[MaxString];
char *token;
sprintf(buf,"%uTE\r",nOnBoardId);
switch(ExecuteCmd(buf)) {
case R_OK:
token = strtok(buf,"\n\3\r");
if(!token) return FALSE;
if((token[1]-'0') != nOnBoardId) return FALSE;
if(token[2] != 'E') return FALSE;
if(strlen(token) < 12)
{
nWaitTicks += 2;
return FALSE;
}
sscanf(&(token[3]),"%ld",failure);
return TRUE;
case R_TimeOut:
sprintf(msg,"GetFailure: %s",buf);
MessageBox(GetFocus(),msg,"TimeOut MS",MBFAILURE);
return FALSE;
case R_UnknownCmd:
sprintf(msg,"GetFailure: %s",buf);
MessageBox(GetFocus(),msg,"Fehler",MBFAILURE);
return FALSE;
default:
return FALSE;
}
};
BOOL TC_812::MoveRelative(long pos)
{
char cmd[MaxString+1];
sprintf(cmd,"%uMR%ld\r",nOnBoardId,pos);
if(R_OK == ExecuteCmd(cmd))
return TRUE;
return FALSE;
};
BOOL TC_812::MoveAbsolute(long pos)
{
char cmd[MaxString+1];
sprintf(cmd,"%uMA%ld\r",nOnBoardId,pos);
if(R_OK == ExecuteCmd(cmd))
return TRUE;
return FALSE;
};
//##############################################################################
//############## IEEE Interface ################################################
//##############################################################################
//##############################################################################
TC_812GPIB::TC_812GPIB(void) : TC_812()
{
char Ident[MaxString],buf[MaxString];
WORD hostio,hostaddr;
while(!hGPIBModule)
{
// IEEE - Controller initialisieren
sprintf(Ident,"GPIB0",nId);
hGPIBModule = LoadLibrary("win488.dll");
if(!hGPIBModule)
break;
hostio = (WORD)GetPrivateProfileInt(Ident,"IOAddr",0x200,GetCFile());
hostaddr = (WORD)GetPrivateProfileInt(Ident,"GPIBAddr",1,GetCFile());
(FARPROC)gInitialize = GetProcAddress(hGPIBModule,"IEEE488_INITIALIZE");
(FARPROC)gSend
= GetProcAddress(hGPIBModule,"IEEE488_SEND");
(FARPROC)gEnter = GetProcAddress(hGPIBModule,"IEEE488_ENTER");
(FARPROC)gTransmit = GetProcAddress(hGPIBModule,"IEEE488_TRANSMIT");
(FARPROC)gReceive = GetProcAddress(hGPIBModule,"IEEE488_RECEIVE");
(FARPROC)gSPoll = GetProcAddress(hGPIBModule,"IEEE488_SPOLL");
(FARPROC)gPPoll = GetProcAddress(hGPIBModule,"IEEE488_PPOLL");
(FARPROC)gSetPort = GetProcAddress(hGPIBModule,"IEEE488_SETPORT");
(FARPROC)gSetTimeout = GetProcAddress(hGPIBModule,"IEEE488_SETTIMEOUT");
(FARPROC)gSetOutputEOS= GetProcAddress(hGPIBModule,"IEEE488_SETOUTPUTEOS");
(FARPROC)gSetInputEOS = GetProcAddress(hGPIBModule,"IEEE488_SETINPUTEOS");
(FARPROC)gEnable488Ex = GetProcAddress(hGPIBModule,"IEEE488_ENABLE_488EX");
(FARPROC)gEnable488SD = GetProcAddress(hGPIBModule,"IEEE488_ENABLE_488SD");
(FARPROC)gListenerOk = GetProcAddress(hGPIBModule,"IEEE488_LISTENER_PRESENT");
(FARPROC)gBoardPresent= GetProcAddress(hGPIBModule,"IEEE488_BOARD_PRESENT");
gSetPort(0,hostio);
gInitialize(hostaddr,0);
break;
}
sprintf(Ident,"motor%d",nId);
wGPIBAddr = (WORD)GetPrivateProfileInt(Ident,"GPIBAddr",15,GetCFile());
bInquireStatus = (BOOL)GetPrivateProfileInt(Ident,"InquireStatus",0,GetCFile());
sprintf(buf,"%d",bInquireStatus);
WritePrivateProfileString(Ident,"InquireStatus",buf,GetCFile());
};
int TC_812GPIB::Initialize(void)
{
int retval;
if(!hGPIBModule)
{
MessageBox(GetFocus(),"Can't find win488.dll","Motor Library",MBSTOP);
return R_Failure;
}
if(!gBoardPresent())
{
MessageBox(GetFocus(),"No GPIB-Controller present !","Failure",MBSTOP);
return R_Failure;
}
gSetTimeout(100);
gSetInputEOS(3);
retval = TC_812::Initialize();
return retval;
};
BOOL TC_812GPIB::CheckBoardOk(void)
{
char buf[MaxString];
int status;
char poll;
if(!gListenerOk(wGPIBAddr))
{
sprintf(buf,"No GPIB-Device with Address %d present !",wGPIBAddr);
MessageBox(GetFocus(),buf,"Failure",MBSTOP);
return FALSE;
}
gSPoll(wGPIBAddr,&poll,&status);
bControlBoardOk = TRUE;
return TRUE;
};
int TC_812GPIB::ExecuteCmd(char *pString)
{
char buf[MaxString],poll;
// char info[20];
int status,retval = R_OK,cnt;
WORD length;
static BOOL bCmdActive
= FALSE;
if(!bControlBoardOk)
return 0;
if(bCmdActive)
return R_Failure;
bCmdActive = TRUE;
// Befehls-String senden
sprintf(buf,"UNL UNT MTA LISTEN %d DATA ' %s'",wGPIBAddr,pString);
gTransmit(buf,0xFFFF,&status);
if(status != 0)
{
retval = R_Failure;
goto Exit;
}
#ifdef WriteLog
FILE *LogFile;
LogFile = fopen("\\motor.log","a");
if(LogFile)
{
fseek(LogFile,0,2);
fwrite(pString,strlen(pString),1,LogFile);
fclose(LogFile);
}
#else
Delay(3);
#endif
// Antwort empfangen
cnt = 0;
do
{
gSPoll(wGPIBAddr,&poll,&status);
if(0x41 == poll)
{
Delay(3);
break;
}
if(0x12 == poll)
{
Delay(3);
break;
}
if(0x2 == poll)
{
Delay(7);
}
if(++cnt > 20) break;
}
while(1);
// Feststellen, ob im vorherigen Kommando ein Fehler aufgetreten
ist
if(poll & 0x4)
{
#ifdef WriteLog
FILE *LogFile;
LogFile = fopen("\\motor.log","a");
if(LogFile)
{
fseek(LogFile,0,2);
fwrite(pString,strlen(pString),1,LogFile);
fclose(LogFile);
}
MessageBox(GetFocus(),(LPSTR)pString,"Command Failure",MBSTOP);
#else
MessageBox(GetFocus(),(LPSTR)pString,"Command Failure",MBSTOP);
#endif
}
if(poll & 1)
{
sprintf(buf,"UNL UNT MLA TALK %d",wGPIBAddr);
gTransmit(buf,0xFFFF,&status);
gReceive(pString,80,&length,&status);
}
else
pString[0] = 0;
Exit:
bCmdActive = FALSE;
return R_OK;
};
//##############################################################################
//############### ISA Interface ################################################
//##############################################################################
//##############################################################################
TC_812ISA::TC_812ISA(void) : TC_812()
{
char buf[MaxString];
char Ident[MaxString];
sprintf(Ident,"motor%d",nId);
GetPrivateProfileString(Ident,"RamAddr","0xD000",buf,MaxString,(LPSTR)GetCFile());
sscanf(buf,"%x",&wBaseAddr);
if((0xC000 <= wBaseAddr) && (0xD000 > wBaseAddr))
{
#ifdef __WIN32__
lpOut1 = (LPSTR)(0x10 * 0xC000 + 0x03fc + 0x10 * (wBaseAddr-0xC000));
lpOut2 = (LPSTR)(0x10 * 0xC000 + 0x03ff + 0x10 * (wBaseAddr-0xC000));
lpFlag = (LPSTR)(0x10 * 0xC000 + 0x0800 + 0x10 * (wBaseAddr-0xC000));
lpIn = (LPSTR)(0x10 * 0xC000 + 0x03fe + 0x10
* (wBaseAddr-0xC000));
lpDPRam = (LPSTR)(0x10 * 0xC000 + 0x10 * (wBaseAddr-0xC000));
#else
lpOut1 = (LPSTR)MK_FP(FP_OFF(__C000h),0x03fc + 0x10
* (wBaseAddr-0xC000));
lpOut2 = (LPSTR)MK_FP(FP_OFF(__C000h),0x03ff + 0x10
* (wBaseAddr-0xC000));
lpFlag = (LPSTR)MK_FP(FP_OFF(__C000h),0x0800 + 0x10
* (wBaseAddr-0xC000));
lpIn = (LPSTR)MK_FP(FP_OFF(__C000h),0x03fe
+ 0x10 * (wBaseAddr-0xC000));
lpDPRam = (LPSTR)MK_FP(FP_OFF(__C000h),0x10 * (wBaseAddr-0xC000));
#endif
}
if((0xD000 <= wBaseAddr) && (0xE000 > wBaseAddr))
{
#ifdef __WIN32__
lpOut1 = (LPSTR)(0x10 * 0xD000 + 0x03fc + 0x10 * (wBaseAddr-0xD000));
lpOut2 = (LPSTR)(0x10 * 0xD000 + 0x03ff + 0x10 * (wBaseAddr-0xD000));
lpFlag = (LPSTR)(0x10 * 0xD000 + 0x0800 + 0x10 * (wBaseAddr-0xD000));
lpIn = (LPSTR)(0x10 * 0xD000 + 0x03fe + 0x10
* (wBaseAddr-0xD000));
lpDPRam = (LPSTR)(0x10 * 0xD000 + 0x10 * (wBaseAddr-0xD000));
#else
lpOut1 = (LPSTR)MK_FP(FP_OFF(__D000h),0x03fc + 0x10
* (wBaseAddr-0xD000));
lpOut2 = (LPSTR)MK_FP(FP_OFF(__D000h),0x03ff + 0x10
* (wBaseAddr-0xD000));
lpFlag = (LPSTR)MK_FP(FP_OFF(__D000h),0x0800 + 0x10
* (wBaseAddr-0xD000));
lpIn = (LPSTR)MK_FP(FP_OFF(__D000h),0x03fe
+ 0x10 * (wBaseAddr-0xD000));
lpDPRam = (LPSTR)MK_FP(FP_OFF(__D000h),0x10 * (wBaseAddr-0xD000));
#endif
}
nWaitTicks = 5;
};
BOOL TC_812ISA::CheckBoardOk(void)
{
char buf[MaxString];
int cnt = 60;
int retval;
*lpOut1 = '\r';
*lpOut1 = '\r';
do
{
DelayTime(4);
if(*lpIn == '\r')
break;
if(*lpIn == '\03')
break;
}
while(--cnt);
if(!cnt)
{
sprintf(buf,"No C-812 Board present at address %X !",wBaseAddr);
MessageBox(GetFocus(),buf,"Fehler MS",MBSTOP);
#ifndef TESTLAUF
return FALSE;
#endif
}
bControlBoardOk = TRUE;
/* {
char info[20*MaxString];
int hFile;
OFSTRUCT of;
strcpy(info,"HE6\r");
retval = ExecuteCmd(info);
hFile = OpenFile("info.txt",&of,OF_CREATE);
_lwrite(hFile,(LPSTR)info,strlen(info));
_lclose(hFile);
} */
strcpy(buf,"DM\r");
retval = ExecuteCmd(buf);
strcpy(buf,"EF\r");
retval = ExecuteCmd(buf);
if(retval != R_OK)
{
MessageBox(GetFocus(),buf,"Fehler MS",MBFAILURE);
#ifndef TESTLAUF
bControlBoardOk = FALSE;
return FALSE;
#endif
}
return TRUE;
};
BOOL TC_812ISA::SetHome(void)
{
if(!TC_812::SetHome()) return FALSE;
#ifdef DirectAccess
int addr = 0x010A + nOnBoardId - 1;
*(lpDPRam + addr)
= 0x00;
*(lpDPRam + addr + 0x0004) = 0x00;
*(lpDPRam + addr + 0x0008) = 0x00;
*(lpDPRam + addr + 0x000C) = 0x00;
#endif
return TRUE;
};
BOOL TC_812ISA::IsMoveFinish(void)
{
#ifdef DirectAccess
long fail1,fail2;
_GetFailure(&fail1);
if(labs(fail1) > (long)wDeathBand)
return FALSE;
DelayTime(100);
_GetFailure(&fail2);
if(fail1-fail2)
return FALSE;
return TRUE;
#else
return TC_812::IsMoveFinish();
#endif
};
BOOL TC_812ISA::_GetPosition(long *position)
{
#ifdef DirectAccess
tpos data;
int addr = 0x010A + nOnBoardId -
1;
data.byte[0] = (char)*(lpDPRam + addr);
data.byte[1] = (char)*(lpDPRam + addr + 0x0004);
data.byte[2] = (char)*(lpDPRam + addr + 0x0008);
data.byte[3] = (char)*(lpDPRam + addr + 0x000C);
*position = data.pos;
return TRUE;
#else
return TC_812::_GetPosition(position);
#endif
};
BOOL TC_812ISA::_GetFailure(long *failure)
{
#ifdef DirectAccess
tpos data;
int addr = 0x006C + nOnBoardId - 1;
data.byte[0] = (char)*(lpDPRam + addr);
data.byte[1] = (char)*(lpDPRam + addr + 0x0004);
data.byte[2] = (char)*(lpDPRam + addr + 0x0008);
data.byte[3] = (char)*(lpDPRam + addr + 0x000C);
*failure = data.pos;
return TRUE;
#else
return TC_812::_GetFailure(failure);
#endif
};
int TC_812ISA::ExecuteCmd(char *pString)
{
#ifndef TESTLAUF
int idx,cnt,retval =
R_OK;;
char chr;
#endif
static BOOL bCmdActive = FALSE;
if(!bControlBoardOk) return 0;
if(bCmdActive)
return R_Failure;
bCmdActive = TRUE;
#ifndef TESTLAUF
cnt = 50;
while ((chr = GetChar()) != '\x0')
{
if(!cnt--)
{
// timeout
strcpy(pString,"TimeOut read");
bControlBoardOk = FALSE;
bCmdActive = FALSE;
retval = R_TimeOut;
goto Exit;
}
}
#endif
// Befehls-String senden
#ifdef WriteLog
FILE *LogFile;
LogFile = fopen("\motor.log","a");
if(LogFile) fseek(LogFile,0,2);
#endif
#ifndef TESTLAUF
idx = 0;
while(pString[idx] != 0)
{
if(!PutChar(pString[idx]))
{
Delay(10);
if(!PutChar(pString[idx]))
{
chr = GetChar();
if(chr) continue;
// Timeout beim Schreiben
bCmdActive = FALSE;
bControlBoardOk = FALSE;
strcpy(pString,"TimeOut write");
retval = R_TimeOut;
goto Exit;
}
}
idx++;
}
#endif
#ifdef WriteLog
if(LogFile) fwrite(pString,strlen(pString),1,LogFile);
#endif
// recieve Request
Delay(50);
#ifndef TESTLAUF
idx = 0; cnt = 250;
while(idx < (20 * MaxString))
{
chr = GetChar();
if(!chr)
{
Delay(15);
if(!cnt)
{ // Timeout beim Lesen
MessageBox(GetFocus(),"TimeOut read","C-812",MBINFO);
// strcpy(pString,"TimeOut read");
bCmdActive = FALSE;
// bControlBoardOk = FALSE;
retval = R_TimeOut;
goto Exit;
}
if((cnt--) && (idx == 0)) continue;
// auf den Request warten
if(pString[idx-1] == '\x3') break; // Ende der *bertragung
abwarten
continue;
}
pString[idx++] = chr;
}
pString[idx] = '\x0';
bCmdActive = FALSE;
if(pString[0] == '?')
{
retval = R_Failure;
goto Exit;
}
if(!cnt)
{
retval = R_Failure;
goto Exit;
}
#endif
Exit:
#ifdef WriteLog
if(LogFile) fclose(LogFile);
#endif
#ifndef TESTLAUF
return retval;
#else
bCmdActive = FALSE;
pString[0] = '\x0';
return R_OK;
#endif
};
int TC_812ISA::PutChar(const char c)
{
int time1,time2;
Delay(3); // 3
for(time1 = 30000; (*lpFlag & 0x01) && time1;
time1--);
if(time1) //time
{
// check if timeout
*lpOut1 = c; // write data
Delay(3); // 3
*lpOut2 = c; // generate internal sidnal
}
for(time2 = 30000; (*lpFlag & 0x00) && time2;
time2--);
Delay(3); // 3
return time1; // return zero for timeout
};
char TC_812ISA::GetChar(void)
{
char chr = 0;
Delay(1); // 1
// Wenn Bit 1 gesetzt ist, so liegen Daten von der Steuerung
an.
if(!(*lpFlag & 0x02)) // text ready-flag
return 0;
// no data available
chr = *lpIn;
// read data
Delay(2); // 2
return chr;
};
//##############################################################################
//################### Interface ################################################
//##############################################################################
//##############################################################################
BOOL TC_832::bLimitHit = FALSE;
BOOL TC_832::bIdle = FALSE;
BOOL TC_832::bIOActive = FALSE;
TC_832::TC_832(void) : TDC_Drive()
{
char Ident[MaxString],buf[MaxString];
sprintf(Ident,"motor%d",nId);
GetPrivateProfileString(Ident,"IOAddr","0x210",(LPSTR)buf,MaxString,GetCFile());
sscanf(buf,"%x",&wBaseAddr);
nOnBoardId = GetPrivateProfileInt(Ident,"BoardId",0,GetCFile());
wKI = (WORD)GetPrivateProfileInt(Ident,"IntegralGain",10,GetCFile());
wKL = (WORD)GetPrivateProfileInt(Ident,"IntegralLimit",10,GetCFile());
wKP = (WORD)GetPrivateProfileInt(Ident,"Gain",100,GetCFile());
wKD = (WORD)GetPrivateProfileInt(Ident,"DynamicGain",37,GetCFile());
cConfig = 0x80;
if(GetPrivateProfileInt(Ident,"DifferentialEncoder",0,GetCFile()))
if(0 == nOnBoardId)
cConfig |= 0x10;
else
cConfig |= 0x20;
if(GetPrivateProfileInt(Ident,"EnableInterrupts",0,GetCFile()))
cConfig |= 0x40;
wSample = 0x0100; // 512 ´s
};
BOOL TC_832::Reset(void)
{
// Reset setzt Position auf Null, falls Initialisierung nicht
eindeutig genug
// sollte hier erst Position gelesen werden und dann der
Reset ausgef‚hrt
// werden.
// changing K-System
Drive628(RESET,0,0);
Drive628(RSTI,0,0);
Drive628(MSKI,0,0);
return TRUE;
};
void TC_832::OptimizingDlg(void)
{
TModalDlg* dlg;
dlg = (TOptimizeDC_832 *)new TOptimizeDC_832();
dlg->ExecuteDialog(GetFrameHandle());
delete dlg;
};
BOOL TC_832:: ActivateFilterParameters(void)
{
// Static Gain entspricht dem P-Term
Drive628(LFIL,wSample | LD_KP,wKP);
// Dynamic Gain entspricht dem D-Term
Drive628(LFIL,wSample | LD_KD,wKD);
// Integral Gain entspricht dem I-Term
Drive628(LFIL,wSample | LD_KI,wKI);
// Integral-Limit entspricht dem L-Term
Drive628(LFIL,wSample | LD_IL,wKL);
Drive628(UDF,0,0);
SetVelocity(dwMaxVelocity);
SetAcceleration(dwAcceleration);
GetSpeed();
//StartLimitWatch();
return TRUE;
};
int TC_832::SaveSettings(int LastSave)
{
char buf[MaxString];
char Ident[MaxString];
sprintf(Ident,"motor%d",nId);
sprintf(buf,"%u",wKD);
WritePrivateProfileString(Ident,"DynamicGain",buf,GetCFile());
sprintf(buf,"%u",wKP);
WritePrivateProfileString(Ident,"Gain",buf,GetCFile());
sprintf(buf,"%u",wKI);
WritePrivateProfileString(Ident,"IntegralGain",buf,GetCFile());
sprintf(buf,"%u",wKL);
WritePrivateProfileString(Ident,"IntegralLimit",buf,GetCFile());
sprintf(buf,"%lu",dwMaxVelocity);
WritePrivateProfileString(Ident,"MaxVelocity",buf,GetCFile());
sprintf(buf,"%lu",dwAcceleration);
WritePrivateProfileString(Ident,"Acceleration",buf,GetCFile());
sprintf(buf,"%lu",dwVelocity);
WritePrivateProfileString(Ident,"Velocity",buf,GetCFile());
return TDC_Drive::SaveSettings(LastSave);
};
BOOL TC_832::SetHome(void)
{
TMotor::SetHome();
// changing K-System
Drive628(DFH,0,0);
Drive628(LTRJ,LD_POS,0);
Drive628(STT,0,0);
return TRUE;
};
BOOL TC_832::ActivateDrive(void)
{
long pos;
Drive628(UDF,0,0);
_GetPosition(&pos);
Drive628(LTRJ,LD_POS,pos);
Drive628(STT,0,0);
return TRUE;
};
BOOL TC_832::StopDrive(int bOffOn)
{
WORD ctr = 0x0400; // Stop smoothly --> programming
manual (page 29)
Drive628(LTRJ,ctr,0);
Drive628(STT,0,0);
while(!IsMoveFinish()) DelayTime(4);
if(!bOffOn) return TRUE;
Drive628(UDF,0,0);
Drive628(STT,0,0);
return TRUE;
};
BOOL TC_832::StartLimitWatch(void)
{
if(bLimitWatchActive) return FALSE;
nEvent = timeSetEvent(150,1,(LPTIMECALLBACK)&TC_832::LimitWatch,0,TIME_PERIODIC);
bLimitWatchActive = TRUE;
return TRUE;
};
BOOL TC_832::StopLimitWatch(void)
{
if(!bLimitWatchActive) return FALSE;
timeKillEvent(nEvent);
bLimitWatchActive = FALSE;
return TRUE;
};
void CALLBACK TC_832::LimitWatch(UINT /*IDEvent*/,UINT,DWORD /*dwUser*/,DWORD,DWORD)
// UINT IDEvent; identifies timer event
// UINT uReserved; not used
// DWORD dwUser; application-defined instance
data */
// DWORD dwReserved1; not used
// DWORD dwReserved2; not used
{
BYTE status = 0;
static count = 0;
static MessageIsPosted = 0;
LM628Ready(::baddr);
#ifndef __WIN32__
outp(::baddr,::config | 0x07);
status = inp(::baddr+1);
#endif
bLimitHit = 0;
count++;
PostMessage(GetFrameHandle(),WM_COMMAND,cm_SetWatchIndicator,(LPARAM)count);
if(status & 0x01)
{
::raddr = (::config | 0x00);
Drive628c(LTRJ,0x400,0,::baddr,::raddr);
Drive628c(STT,0,0,::baddr,::raddr);
bLimitHit = 1;
}
if(status & 0x02)
{
::raddr = (::config | 0x02);
Drive628c(LTRJ,0x400,0,::baddr,::raddr);
Drive628c(STT,0,0,::baddr,::raddr);
bLimitHit = 2;
}
if(bLimitHit && !MessageIsPosted)
PostMessage(GetFrameHandle(),WM_COMMAND,cm_LimitHitOccure,(LPARAM)bLimitHit);
};
BOOL TC_832::IsLimitHit(void)
{
BYTE status;
// Interrupt-Register
LM628Ready(wBaseAddr);
#ifndef __WIN32__
outp(wBaseAddr,cConfig | 0x07);
status = inp(wBaseAddr+1);
#else
status = 1;
#endif
if(status & (nOnBoardId+1))
{
Drive628(LTRJ,0x400,0); // stop appruptly
Drive628(STT,0,0);
if(bUpwards)
Drive628(LTRJ,LD_RPOS,-labs(dwRemoveLimit));
else
Drive628(LTRJ,LD_RPOS,labs(dwRemoveLimit));
bUpwards = !bUpwards;
Drive628(STT,0,0);
while(!IsMoveFinish())
DelayTime(10);
DelayTime(100);
LM628Ready(wBaseAddr);
#ifndef __WIN32__
outp(wBaseAddr,cConfig | 0x07);
status = inp(wBaseAddr+1);
outp(wBaseAddr+1,status & ~(nOnBoardId+1));
#endif
DelayTime(10);
bLimitHit = bRangeHit = TRUE;
return TRUE;
}
bLimitHit = FALSE;
return FALSE;
};
BOOL TC_832::IsIndexArrived(void)
{
long ipos,pos;
if(IsLimitHit())
{
Drive628(RSTI,0,0);
Drive628(MSKI,0,0);
Drive628(STT,0,0);
if(bIndexLine)
{
Drive628(SIP,0,0);
Drive628(LTRJ,LD_RPOS,400000000l);
bUpwards = TRUE;
Drive628(STT,0,0);
return FALSE;
}
return TRUE;
}
if(bIndexLine && bIndexDetected && IsMoveFinish())
return TRUE;
if(!bIndexLine && bRangeHit && IsMoveFinish())
return TRUE;
if(!bRangeHit && bMoveFirstToLimit)
return FALSE;
if(0x08 & Drive628(RDSIGS,0,0))
{
// stop drive
Drive628(LTRJ,0x400,0);
Drive628(STT,0,0);
bIndexDetected = TRUE;
Drive628(RSTI,0,0);
Drive628(MSKI,0,0);
ipos = Drive628(RDIP,0,0);
while(!IsMoveFinish());
pos = Drive628(RDRP,0,0);
bUpwards = (ipos > pos);
Drive628(LTRJ,LD_POS,ipos);
Drive628(STT,0,0);
Delay(150);
return FALSE;
}
return FALSE;
};
BOOL TC_832::StartToIndex(long &oldPos)
{
SetSpeed(10000.0);
bIndexDetected = FALSE;
bRangeHit = FALSE;
bLimitHit = FALSE;
lDeltaPosition = 0;
SetCalibrationState(FALSE);
SetCorrectionState(FALSE);
lPosition = oldPos = Drive628(RDRP,0,0);
bUpwards = FALSE;
if(!bMoveFirstToLimit && bIndexLine)
{
Drive628(RSTI,0,0);
Drive628(SIP,0,0);
}
Drive628(LTRJ,LD_RPOS,-400000000l);
Drive628(STT,0,0);
// Die Motoren werden in Bewegung gesetzt
// Erreichen der Stillstands-Position
DelayTime(150);
return TRUE;
};
BOOL TC_832::SetVelocity(DWORD velocity)
{
dwVelocity = (velocity<dwMaxVelocity)?velocity:dwMaxVelocity;
if(R_OK != Drive628(LTRJ,0x0008,dwVelocity))
return FALSE;
return TRUE;
};
DWORD TC_832::GetVelocity(void)
{
dwVelocity = (dwVelocity<dwMaxVelocity)?dwVelocity:dwMaxVelocity;
return dwVelocity;
};
BOOL TC_832::SetAcceleration(DWORD acceleration)
{
dwAcceleration = acceleration;
if(R_OK != Drive628(LTRJ,0x0020,dwAcceleration))
return FALSE;
return TRUE;
};
DWORD TC_832::GetAcceleration(void)
{
return dwAcceleration;
};
BOOL TC_832::SetLimit(DWORD limit)
{
dwRemoveLimit = limit;
return TRUE;
};
WORD TC_832::GetStatus(void)
{
return (WORD)Drive628(RDSTAT,0,0);
};
BOOL TC_832::_GetPosition(long *position)
{
*position = Drive628(RDRP,0,0);
return TRUE;
};
BOOL TC_832::_GetFailure(long *failure)
{
*failure = (Drive628(RDRP,0,0) - Drive628(RDDP,0,0));
return TRUE;
};
BOOL TC_832::MoveRelative(long position)
{
long rpos;
rpos = Drive628(RDRP,0,0);
rpos += position;
Drive628(LTRJ,LD_POS,rpos);
Drive628(STT,0,0);
return TRUE;
};
BOOL TC_832::MoveAbsolute(long pos)
{
Drive628(LTRJ,LD_POS,pos);
Drive628(STT,0,0);
return TRUE;
};
BOOL TC_832::IsMoveFinish(void)
{
DelayTime(5);
if(Drive628(RDSIGS,0,0) & ON_TARGET)
return TRUE;
else
return FALSE;
};
BOOL TC_832::CheckBoardOk()
{
bControlBoardOk = FALSE;
#ifndef TESTLAUF
#ifndef __WIN32__
outp(wBaseAddr,cConfig | (nOnBoardId << 1));
if(inp(wBaseAddr+1) == 0xFF)
return FALSE;
#endif
#endif
bControlBoardOk = TRUE;
return TRUE;
};
BOOL TC_832::ExecuteCmd(LPSTR)
{
return R_OK;
};
long TC_832::Drive628(BYTE cmd,WORD ctrl_word,long param)
{
// load static variables
::config = cConfig;
::drive = nOnBoardId;
::baddr = wBaseAddr;
::raddr = (::config | (::drive<<1));
#ifdef WriteLog
FILE *LogFile;
char buf[30];
LogFile = fopen("\motor.log","a");
if(LogFile)
{
fseek(LogFile,0,2);
sprintf(buf,"%d\n",cmd);
fwrite(buf,strlen(buf),1,LogFile);
fclose(LogFile);
}
#endif
return Drive628c(cmd,ctrl_word,param,::baddr,::raddr);
};
//******************************************************************************
//******************************************************************************
long Drive628c(BYTE cmd,WORD ctrl_word,long param,WORD base,WORD
regaddr)
{
TCSet *pCmdDesc;
if(TC_832::bIdle)
{
TC_832::bIdle = FALSE;
};
TC_832::bIdle = TRUE;
#ifndef __WIN32__
// seeking command description
pCmdDesc = CmdSet;
if(cmd==RDSTAT)
{
// Status
outp(base,regaddr);
TC_832::bIdle = FALSE;
return((long)inp(base + 1));
}
else
while(cmd != pCmdDesc->cmd)
pCmdDesc++;
LM628Ready(base);
outp(base + 1,cmd);
if(pCmdDesc->data)
{
// read/write data
if((cmd==LTRJ) | (cmd==LFIL))
PutWord(ctrl_word,base,regaddr);
if(pCmdDesc->report)
{
// report command
if(pCmdDesc->length32)
{
TC_832::bIdle = FALSE;
return GetDWord(base,regaddr); // 32 Bit
data
}
else
{
TC_832::bIdle = FALSE;
return (long)GetWord(base,regaddr);
// 16 Bit data
}
}
else
{
// control command
if(pCmdDesc->length32)
PutDWord(param,base,regaddr); // 32 Bit
parameter
else
PutWord((int)param,base,regaddr); // 16 Bit
parameter
}
}
#endif
TC_832::bIdle = FALSE;
return 0;
};
int GetWord(WORD base,WORD regaddr)
{
union {
int integer;
BYTE byte[2];
} temp;
LM628Ready(base);
#ifndef __WIN32__
outp(base,regaddr + 1);
temp.byte[1] = inp(base + 1);
temp.byte[0] = inp(base + 1);
#endif
return temp.integer;
};
long GetDWord(WORD base,WORD regaddr)
{
union {
long lval;
BYTE byte[4];
} temp;
LM628Ready(base);
#ifndef __WIN32__
outp(base,regaddr + 1);
temp.byte[3] = inp(base + 1);
temp.byte[2] = inp(base + 1);
LM628Ready(base);
outp(base,regaddr+1);
temp.byte[1] = inp(base + 1);
temp.byte[0] = inp(base + 1);
#endif
return temp.lval;
};
void PutWord(int data,WORD base,WORD regaddr)
{
union {
int integer;
BYTE byte[2];
} temp;
LM628Ready(base);
#ifndef __WIN32__
outp(base,regaddr + 1);
Delay(2);
temp.integer = data;
outp(base + 1,temp.byte[1]);
outp(base + 1,temp.byte[0]);
#else
data = 1;
#endif
};
void PutDWord(long data,WORD base,WORD regaddr)
{
union {
long lval;
BYTE byte[4];
} temp;
temp.lval = data;
LM628Ready(base);
#ifndef __WIN32__
outp(base,regaddr+1);
outp(base + 1,temp.byte[3]);
outp(base + 1,temp.byte[2]);
LM628Ready(base);
outp(base,regaddr+1);
outp(base + 1,temp.byte[1]);
outp(base + 1,temp.byte[0]);
#else
data = 1;
#endif
};
BOOL LM628Ready(WORD base)
{
int tt;
int time_out=1000;
// command register
#ifndef __WIN32__
outp(base,::config | (::drive<<1));
do {
tt = inp(base+1);
if(!(time_out--)) return FALSE;
}
// test BUSY bit 0
while(tt & 0x01);
if(tt & 0x02)
{
time_out++;
}
#endif
return TRUE;
};
// __LastLine__