File: MOTRSTRG\MOTORS.CPP
1 //#############################################################################
2 // //
3 // MOTORS.CPP //
4 // Subsystem: Motorsteuerung //
5 // Benutung durch andere Subsysteme erforderlich: JA //
6 // //
7 //---------------------------------------------------------------------------//
8 // Autoren: Heiko Damerow MPG AG "Roentgenbeugung" (C) 1993,95 //
9 // Stand: 05.08.2002 //
10 // //
11 //#############################################################################
12
13 #include "internls\evrythng.h" // GermanVersion
14 #include "winresrc\rc_def.h" // Ressourcen-IDs
15 #include "help\help_def.h" // Help-IDs
16 #pragma hdrstop
17
18 #include "motrstrg\motrstrg.h"
19 #include "motrstrg\m_layer.h"
20 #include "motrstrg\m_motcom.h"
21 #include "motrstrg\m_mothw.h"
22 #include "motrstrg\C_8x2.h"
23 #include "hardware\hwio.h"
24
25 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
26
27 extern DeviceList MotorDrivers;
28 extern ControllerList MotorControllers;
29
30 #define DirectAccess
31 // #define WriteLog
32 // #define CheckCorrect
33 // #define TESTLAUF
34
35 //vormals in evrythng.h
36 #define R_TimeOut 214
37 #define R_UnknownCmd 215
38
39 #ifdef GermanVersion
40 char szMsgFailure[]= "Fehler";
41 char szMessage[]= "Meldung";
42 char szMsgLine001[]= "Initialisieren von %s";
43 char szMsgLine002[]= "Probleme beim Initialisieren der Motor-Steuerung !\n\nAbbrechen ?";
44 char szMsgLine003[]= "Startup der Motor-Steuerung";
45 char szMsgLine004[]= "Sichern von Motor-Einstellungen %s ";
46 char szMsgLine005[]= "Diese Aktion ist für diesen Antrieb nicht vorbereitet !";
47 char szMsgLine006[]= "Kein gültiger Motor !";
48 char szMsgLine007[]= "Keine Kalibrierung erfolgt !";
49 char szMsgLine008[]= "Absolute Null für Motor %s";
50 char szMsgLine009[]= "Kalibrierung beendet !";
51 char szMsgLine010[]= "\n\nDie neuen Kalibrierungsdaten wurden gesichert !";
52 // Testgruppe
53 char szMsgLine011[]= "%s DCM-Parameter für %s optimieren";
54 //
55 char szMsgLine012[]= "Fehler beim Initialisieren des Antrieb %s!";
73 #endif
74 //------------------------------------------------------------------------------
75
76 static const int MAXIT= 30; // maximal number of iterations
77
78 int TMotor::nMaxId= 0;
79
80 extern LPMList lpMList;
81 extern HINSTANCE hModuleInstance;
82
83 //Datum: 27.07.2002 extern TModalDlg* TheDialog;
84 //**** variables belonging C-832 ***********************************************
85 // LM628/629-commands exept RDSTAT
86 // Definition der Kommandos und des Typs TCSet in "C_8x2.inc"
87 static TCSet CmdSet[] =
88 {
89 {RESET, 0, 0, 0}, {PORT8, 0, 0, 0}, {PORT12, 0, 0, 0}, {DFH, 0, 0, 0},
90 {SIP, 0, 0, 0}, {LPEI, 0, 1, 0}, {LPES, 0, 1, 0}, {SBPA, 0, 2, 1},
91 {SBPR, 0, 2, 1}, {MSKI, 0, 1, 0}, {RSTI, 0, 1, 0}, {LFIL, 0, 4, 0},
92 {UDF, 0, 0, 0}, {LTRJ, 0, 3, 1}, {STT, 0, 0, 0}, {RDSTAT, 1, 1, 0},
93 {RDSIGS, 1, 1, 0}, {RDIP, 1, 1, 1}, {RDDP, 1, 1, 1}, {RDRP, 1, 1, 1},
94 {RDDV, 1, 1, 1}, {RDRV, 1, 1, 0}, {RDSUM, 1, 1, 0}
95 };
96
97 int nC812= -1;
98
99 //******************************************************************************
100 //***** definitions for motor simulation / hardware access *********************
101
102 static TSimulationType simulation_type= no_simulation;
103 static T812ISA_GET_CALLBACK c812isa_get_callback;
104 static T812ISA_PUT_CALLBACK c812isa_put_callback;
105 static T832_GET_CALLBACK c832_get_callback;
106 static T832_PUT_CALLBACK c832_put_callback;
107
108 void _MOTORCLASS WINAPI msSetSimulationType( TSimulationType t )
109 {
110 simulation_type= t;
111 }
112 void _MOTORCLASS WINAPI msRegister_C812ISA_Get( T812ISA_GET_CALLBACK cb )
113 {
114 c812isa_get_callback= cb;
115 }
116 void _MOTORCLASS WINAPI msRegister_C812ISA_Put( T812ISA_PUT_CALLBACK cb )
117 {
118 c812isa_put_callback= cb;
119 }
120 void _MOTORCLASS WINAPI msRegister_C832_Get( T832_GET_CALLBACK cb )
121 {
122 c832_get_callback= cb;
123 }
124 void _MOTORCLASS WINAPI msRegister_C832_Put( T832_PUT_CALLBACK cb )
125 {
126 c832_put_callback= cb;
127 }
128 //******************************************************************************
129
130 TMList::TMList( int maxn ) // Kullmann, Reinecker (08.08.02) 2.Parameter, hier: HINSTANCE inst, entfernt
131 {
132 #ifdef WriteLog
133 char buf[]= "Start of Program\r"; 134 #endif
135
136 AD_X= -1;
137 AD_Y= -1;
138 AD_Z= -1;
139 AD_Rotation= -1;
140 AD_Tilt= -1;
141 AD_DC= -1;
142 AD_Collimator= -1;
143 AD_DF= -1;
144 AD_Encoder= -1;
145 AD_Absorber= -1;
146 AD_Psi= -1;
147 AD_Phi= -1;
148 AD_Theta= -1;
149 AD_Omega= -1;
150 AD_Monochromator= -1;
151 nActiveDrive= -1;
152 nLastDrive= -1;
153 nMaxNumber= maxn;
154 //hMInstance = inst; ( Toter Code, am 08.08.02 auskommentiert)
155
156 #ifdef WriteLog
166 #endif
167
168 aMotor= new TMotor * [ nMaxNumber ];
169 };
170
171
172 TMList::~TMList( void )
173 {
174 _FREELIST(aMotor);
175 };
176
177
178 BOOL TMList::InitializeModule( void )
179 {
180 BOOL bNoFailure= TRUE;
181 int id;
182 char Ident[ MaxString ], ctype[ MaxString ];
183 char buf[ MaxString ];
184
185 //temp. Motorliste
186 TMotor** initializedMotors= new TMotor* [nMaxNumber];
187
188
189 //
190 // erzeugung der motor objekte in der motoren liste entsprechen type-parameter
191 // aus ini-file
192 // beginnend bei [Motor0] werden solange die [MotorX]-sektionen gelesen bis
193 // die erste gefunden wird die keinen oder einen leeren type-parameter hat
194 //
195 nLastDrive= -1;
196 id= 0;
197 do
198 {
199 sprintf( Ident, "Motor%d", id );
200 GetPrivateProfileString( Ident, "Type", "", ctype, MaxString, GetHWFile( ) );
201 if ( strlen( ctype ) == 0 )
202 break;
203 nLastDrive= id;
204
205 if ( strcmpi( ctype, "C-812ISA" ) == 0 )
206 {
207 aMotor[ id ]= ( TMotor* )( TC_812ISA* ) new TC_812ISA();
208 continue;
209 }
210 if ( strcmpi( ctype, "C-832" ) == 0)
211 {
212 aMotor[ id ]= ( TC_832 * ) new TC_832();
213 continue;
214 }
215 // TMotor oder ungueltige type bezeichnung
216 aMotor[ id ]= ( TMotor* ) new TMotor();
217 } while ( id++ < nMaxNumber );
218
219 // test ob wenigstens ein motor in motoren-liste
220 // falls nicht wird ein dummy motor in die liste eingetragen
221 if ( nLastDrive == -1 )
222 {
223 aMotor[0]= ( TMotor* ) new TMotor();
224 nLastDrive= 0;
225 }
226
227 // achse 0 ist stets per default aktiviert
228 nActiveDrive= 0;
229
230 //********** initializion of all motors ************************************
231
232 int initID= 0;
233 for ( id= 0; id <= LastId(); id++ )
234 {
235 sprintf( buf, szMsgLine001, MP( id ) -> pCharacteristic());
236 SetInfo( buf );
237 // Initialisierung der Motor-Hardware
238 if ( R_OK != MP( id ) -> Initialize() )
239 {
240 _FREEOBJ(aMotor[id]);
241 }
242 else
243 {
244 initializedMotors[initID++]= aMotor[id];
245 }
246 }
247 SetInfo( szMsgLine003 );
248 nLastDrive= initID -1;
249
250 //hp test ob wenigstens ein motor erfolgreich initialisiert wurde
251 // falls nicht wird ein dummy-motor initialisiert
252 if ( nLastDrive == -1 )
253 {
254 initializedMotors[initID++]= ( TMotor* ) new TMotor();
255 initializedMotors[initID-1]->Initialize();
256 nLastDrive= 0;
257 }
258
259 //hp aufnehmen der initialisierten Motoren in Motorenliste
260 for(id=0;id<initID;id++)
261 {
262 aMotor[id]= initializedMotors[id];
263 }
264 _FREELIST(initializedMotors);
265
266 // Keine relativen Winkel setzen
267 for ( id= 0;id <= LastId();id++ )
268 MP( id ) -> SetAngleBias( 0.0 ); // Kullmann, Reinecker (04.08.02) dAngleBias ersetzt
269 // HINWEIS zu SetAngleBias: SetAngleBias setzt dAngleBias nur, wenn der Antrieb steht,
270 // während vorher in jedem Fall dAngleBias geschrieben wurde -> mögliche Nebeneffekte
271 // Obwohl laut Spezifikation das Schreiben von dAngleBias NUR im Stillstand erlaubt ist
272
273 // Die Positions-Register der Motor-Steuerung werden auf NULL gesetzt und
274 // die abgespeicherten Positionen werden rechnerisch einbezogen
275 // Die abgespeicherten Positionen werden nicht beruecksichtigt.
276 // Es wird unterstellt, dass die Register der Motor-Steuerung noch
277 // aktuell sind
278 return bNoFailure;
279 };
280
281
282 EAxisType TMList::ParsingAxis( LPCSTR axisname)
283 {
284 if ( !strcmp( axisname, "AzimutalRotation" ) ||
285 !strcmp( axisname, "AZ" ) ||
286 !strcmp( axisname, "Rotation" ) ||
287 !strcmp( axisname, "Azimute" ) )
288 return Rotation;
289
290 if ( !strcmp( axisname, "X" ) ||
291 !strcmp( axisname, "x" ) ||
292 !strcmp( axisname, "Horizontal" ) ||
293 !strcmp( axisname, "x-Achse" ) ||
294 !strcmp( axisname, "x-Axis" ) )
295 return X;
296
297 if ( !strcmp( axisname, "Y" ) ||
298 !strcmp( axisname, "y" ) ||
299 !strcmp( axisname, "y-Achse" ) ||
300 !strcmp( axisname, "y-Axis" ) )
301 return Y;
302
303 if ( !strcmp( axisname, "Z" ) ||
304 !strcmp( axisname, "z" ) ||
305 !strcmp( axisname, "Vertical" ) ||
306 !strcmp( axisname, "z-Achse" ) ||
307 !strcmp( axisname, "z-Axis" ) )
308 return Z;
309
310 if ( !strcmp( axisname, "Theta" ) )
311 return Theta;
312
313 if ( !strcmp( axisname, "Omega" ) )
314 return Omega;
315
316 if ( !strcmp( axisname, "Tilt" ) ||
317 !strcmp( axisname, "TL" ) )
318 return Tilt;
319
320 if ( !strcmp( axisname, "DC" ) ||
321 !strcmp( axisname, "Diffraction coarse" ) ||
322 !strcmp( axisname, "Beugung Grob" ) || // neu 10.01.2002 Kullmann+Reinecker
323 !strcmp( axisname, "Beugung grob" ) )
324 return DC;
325
326 if ( !strcmp( axisname, "DF" ) ||
327 !strcmp( axisname, "Diffraction fine" ) ||
328 !strcmp( axisname, "Beugung Fein" ) || // neu 10.01.2002 Kullmann+Reinecker
329 !strcmp( axisname, "Beugung fein" ) )
330 return DF;
331
332 if ( !strcmp( axisname, "Psi" ) )
333 return Psi;
334
335 if ( !strcmp( axisname, "Phi" ) )
336 return Phi;
337
338 if ( !strcmp( axisname, "CC" ) ||
339 !strcmp( axisname, "Collimator" ) ||
340 !strcmp( axisname, "Kollimator" ) )
341 return Collimator;
342
343 if ( !strcmp( axisname, "Absorber" ) )
344 return Absorber;
345
346 if ( !strcmp( axisname, "Monochromator" ) )
347 return Monochromator;
348
349 if ( !strcmp( axisname, "Encoder" ) )
350 return Encoder;
351
352 return ( EAxisType ) 0;
353 };
354
355
356 BOOL TMList::SaveModuleSettings( void )
357 {
358 int id;
359 char buf[ MaxString ];
360
361 for ( id= 0;id <= LastId( );id++ )
362 {
363 sprintf( buf, szMsgLine004, (LPSTR)MP( id ) -> pCharacteristic( ) );
364 SetInfo( buf );
365 MP( id ) -> SaveSettings( TRUE );
366 MP( id ) -> StopDrive( FALSE );
367 }
368 return TRUE;
369 };
370
371
372 void TMList::SetAngleDefault( void )
373 {
374 int id;
375
376 for ( id= 0;id <= LastId( );id++ )
377 {
378 MP( id ) ->SetAngleBias( 0.0 ); // Kullmann, Reinecker (04.08.02) dAngleBias ersetzt
379 // siehe oben: HINWEIS zu SetAngleBias
380 MP( id ) ->SetAngleRange( );
381 }
382 }
383
384 TMotor* TMList::MP( void )
385 {
386 return aMotor[ nActiveDrive ];
387 };
388
389
390 TMotor* TMList::MP( int n )
391 {
392 if ( ( n >= 0 ) && ( n <= nLastDrive ) )
393 return aMotor[ n ];
394 return aMotor[ nActiveDrive ];
395 };
396
397
398 void TMList::SetParametersDlg( void )
399 {
400 TMotorParamDlg* dlg;
401
402 dlg= new TMotorParamDlg( );
403 //Datum: 27.07.2002 TheDialog= ( TMotorParamDlg * ) dlg;
404 if ( dlg ) dlg->ExecuteDialog( GetFrameHandle( ) );
405 _FREEOBJ(dlg);
406 };
407
408
409 void TMList::InquireReferencePointDlg( BOOL task ) // Kullmann, Reinecker (08.08.02) Parameter geändert int -> BOOL
410 {
411 TModalDlg* dlg;
412
413 dlg= ( TCalibrateDlg * ) new TCalibrateDlg( task );
414 if ( dlg ) dlg->ExecuteDialog( GetFrameHandle( ) );
415 _FREEOBJ(dlg);
416 };
417
418
419 BOOL TMList::SetAxis( int n )
420 {
421 if ( ( n >= 0 ) && ( n <= nLastDrive ) )
422 {
423 // Motor, der zur Achse n gehoert, wird als aktiver Motor gekennzeichnet
424 nActiveDrive= n;
425 return TRUE;
426 }
427 else
428 {
429 nActiveDrive= 0;
430 return FALSE;
431 }
432 };
433
434
435 //**************************************************************************
436 //**************************************************************************
437 // Anfahren der Nullstellung : Referenzpunktlauf
438 TCalibrateDlg::TCalibrateDlg( BOOL task ) : TModalDlg( "CALIBRATEMOTORS", hModuleInstance ) // Kullmann, Reinecker (08.08.02) Parameter geändert int -> BOOL
439 {
440 bZeroShouldSet= FALSE;
441 nTask= task;
442 lOldPos= new long [ lpMList->LastId( ) + 1 ];
443 bZeroPosReached= new BOOL [ lpMList->LastId( ) + 1 ];
444 bIndexPosReached= new BOOL [ lpMList->LastId( ) + 1 ];
445 bTargetPosReached= new BOOL [ lpMList->LastId( ) + 1 ];
446 // ANFANG: Kullmann, Reinecker (08.08.02)
447 /*switch( nTask )
448 {
449 case 99:
450 bAllMotors= TRUE;
451 bHoldPosition= FALSE;
452 bValidCalibrationData= TRUE;
453 break;
454
455 default:
456 bValidCalibrationData= TRUE;
457 bAllMotors= FALSE;
458 bHoldPosition= FALSE;
459 }*/
460 if ( nTask )
461 { // war 99
462 bAllMotors= TRUE;
463 bHoldPosition= FALSE;
464 bValidCalibrationData= TRUE;
465 }
466 else
467 {
468 bValidCalibrationData= TRUE;
469 bAllMotors= FALSE;
470 bHoldPosition= FALSE;
471 };
472 // ENDE: Kullmann, Reinecker (08.08.02)
473 };
474
475
476 TCalibrateDlg::~TCalibrateDlg( void )
477 {
478 _FREELIST(lOldPos);
479 _FREELIST(bZeroPosReached);
480 _FREELIST(bTargetPosReached);
481 _FREELIST(bIndexPosReached);
482 };
483
484
485 BOOL TCalibrateDlg::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM )
486 {
487 int i;
488
489 // Initialisieren der Parameterfenster fuer einen Motor
490 Motor= lpMList->MP( );
491 SetDlgItemText( hwnd, id_Report, "" );
492 CheckDlgButton( hwnd, id_ValidCalibrationData, bValidCalibrationData );
493 hMotorList= GetDlgItem( hwnd, id_ChooseMotor );
494
495 i= 0;
496 while ( i <= lpMList->LastId( ) )
497 {
498 ComboBox_AddString( hMotorList, lpMList->MP( i++ ) ->pCharacteristic( ) );
499 }
500 ComboBox_SelectString( hMotorList, 0, Motor->pCharacteristic( ) );
501
502 if ( nTask ) // Kullmann, Reinecker (08.08.02) nTask==99 ersetzt
503 FORWARD_WM_COMMAND( hwnd, cm_CarryOnZero, hwndCtl, 0, PostMessage );
504
505 // HotKey's Hilfe laden (nur Win32)
506 LoadHotKeys( LoadAccelerators(GetInstance(), MAKEINTRESOURCE(ACC_CalibrateMotor)) ); // Accelerator aus Ressourcen laden
507
508 return TRUE;
509 };
510
511
512 void TCalibrateDlg::Dlg_OnTimer( HWND hwnd, UINT id )
513 {
514 int idx;
515 BOOL AnyToDo= FALSE;
516
517 if ( id != TimerIdInformation )
518 return;
519 KillTimer( hwnd, TimerIdInformation );
520
521 for ( idx= 0;idx <= lpMList->LastId( );idx++ )
522 {
523 if ( !bIndexPosReached[ idx ] )
524 {
525 AnyToDo= TRUE;
526 if ( lpMList->MP( idx ) -> IsIndexArrived( ) )
527 {
528 // Indexposition
529 // bei C-812 meist die linke Endlage plus RemoveLimit
530 // bei C-832 meist genau die Index-Position plus RemoveLimit
531 // Es wurde noch kein Home neu gesetzt
532 FORWARD_WM_COMMAND( hwnd, cm_IndexArrived, 0, idx, SendMessage );
533 continue;
534 }
535 continue;
536 }
537 if ( !bZeroPosReached[ idx ] )
538 {
539 AnyToDo= TRUE;
540 if ( lpMList->MP( idx ) ->IsMoveFinish( ) )
541 {
542 FORWARD_WM_COMMAND( hwnd, cm_DistanceSet, 0, idx, SendMessage );
543 continue;
544 }
545 }
546 }
547 if ( AnyToDo )
548 SetTimer( hwnd, TimerIdInformation, 130, NULL );
549 return;
550 };
551
552
553 void TCalibrateDlg::Dlg_OnCommand( HWND hwnd, int id, HWND hwndCtl, UINT codeNotify )
554 {
555 int idx;
556 char buf[ 2*MaxString ];
557 int NextMotor;
558
559 switch ( id )
560 {
561 case cm_Help:
562 WinHelp(GetHandle(), GetHelpFile(), HELP_CONTEXT, Help_CalibrateMotorsDlg);
563 break;
564
565 case cm_CarryOnZero:
566 if ( bZeroShouldSet )
567 {
568 MessageBeep( 0 );
569 break;
570 }
571 //
572 // Kalibrierungs-Bedarf festlegen
573 //
574 bHoldPosition= IsDlgButtonChecked( GetHandle( ), id_HoldPosition );
575 bValidCalibrationData= IsDlgButtonChecked( GetHandle( ),
576 id_ValidCalibrationData );
577
578 if ( !bValidCalibrationData )
579 {
580 strcpy( buf, "Es wird davon ausgegangen, dass sich der Antrieb\r\n" );
581 strcat( buf, "in der Position der physikalischen Null befindet.\r\n" );
582 strcat( buf, "Es werden Kalibrierungsdaten geaendert !" );
583 if ( IDYES != MessageBox( buf, "Meldung", MBASK ) )
584 return;
585 }
586 for ( idx= 0;idx <= lpMList->LastId( );idx++ )
587 bIndexPosReached[ idx ]= bZeroPosReached[ idx ]= TRUE;
588
589 if ( !bAllMotors )
590 {
591 if ( lpMList->MP( ) -> IsInitialMoveReady() ) // Kullmann, Reinecker (04.08.02) bInitialMoveReady ersetzt
592 bIndexPosReached[ Motor->GetId( ) ]= bZeroPosReached[ Motor->GetId( ) ]
593 = FALSE;
594 else
595 MessageBox( szMsgLine005, szMessage, MBINFO );
596 }
597 else
598 {
599 for ( idx= 0;idx <= lpMList->LastId( );idx++ )
600 if ( lpMList->MP( idx ) -> IsInitialMoveReady() ) // Kullmann, Reinecker (04.08.02) bInitialMoveReady ersetzt
601 bIndexPosReached[ idx ]= bZeroPosReached[ idx ]= FALSE;
602 }
603
604 //
605 // RPL starten
606 //
607 for ( idx= 0;idx <= lpMList->LastId( );idx++ )
608 {
609 Motor= lpMList->MP( idx );
610 if ( Motor->GetId( ) != idx )
611 MessageBox( "Motor Id", szMsgFailure, MBINFO );
612 if ( !bIndexPosReached[ idx ] )
613 {
614 Motor->PushSettings( );
615 Motor->StartToIndex( lOldPos[ idx ] ); // old position will be returned
616 bZeroShouldSet= TRUE;
617 }
618 }
619
620 if ( bZeroShouldSet )
621 {
622 SetDlgItemText( GetHandle( ), id_Report, "" );
623 EnableWindow( GetDlgItem( hwnd, id_ChooseMotor ), FALSE );
624 EnableWindow( GetDlgItem( hwnd, cm_SetHome ), FALSE );
625 EnableWindow( GetDlgItem( hwnd, cm_CarryOnZero ), FALSE );
626 goto ExitWithTimer;
627 }
628 if ( nTask ) // Kullmann, Reinecker (08.08.02) nTask==99 ersetzt
629 FORWARD_WM_COMMAND( hwnd, IDCANCEL, hwndCtl, 0, PostMessage );
630 else
631 SetDlgItemText( hwnd, id_Report, szMsgLine007 );
632 return;
633
634 case cm_IndexArrived:
635 if ( !lpMList->SetAxis( codeNotify ) )
636 {
637 MessageBox( szMsgLine006, szMessage, MBINFO );
638 return;
639 }
640 Motor= lpMList->MP( );
641
642 // Alle fertigen Motoren nicht mehr behandeln
643 if ( bZeroPosReached[ Motor->GetId( ) ] )
644 goto ExitWithTimer;
645 if ( bIndexPosReached[ Motor->GetId( ) ] )
646 goto ExitWithTimer;
647
648 // measure the difference between startpoint and index point
649 if ( !bValidCalibrationData || bHoldPosition )
650 {
651 Motor->GetPosition( TRUE );
652 lOldPos[ Motor->GetId( ) ] -= Motor->GetPosition(); // Kullmann, Reinecker (04.08.02) lPosition ersetzt
653 }
654 if ( !bValidCalibrationData )
655 Motor->SetDistanceToZero( lOldPos[Motor->GetId()] ); // Kullmann, Reinecker (04.08.02) lDistanceToZero ersetzt
656
657 // compute and set up the zero point
658 Motor->SetHome( );
659 // Motor->SetDeltaPosition()= -Motor->GetDistanceToZero();
660 Motor->SetDeltaPosition( -Motor->GetDistanceToZero() ); // Kullmann, Reinecker (04.08.02) lDeltaPosition, lDistanceToZero ersetzt
661 bIndexPosReached[ Motor->GetId( ) ]= TRUE;
662 Motor->SetCalibrationState( TRUE ); // Kullmann, Reinecker (04.08.02) bIsCalibrated ersetzt
663 sprintf( buf, "Index %s", Motor->pCharacteristic( ) );
664 SetDlgItemText( GetHandle( ), id_Report, (LPSTR)buf );
665
666 // start next motor to target position
667 // if hold old position take the old position
668 // in all other cases take the TargetAngle
669 // notify old position
670 if ( bHoldPosition )
671 Motor->MoveByPosition( lOldPos[ Motor->GetId( ) ] );
672 else
673 Motor->MoveToAngle( Motor->GetInitialAngle() ); // Kullmann, Reinecker (04.08.02) dInitialAngle ersetzt
674 goto ExitWithTimer;
675
676 case cm_DistanceSet:
677 if ( !lpMList->SetAxis( codeNotify ) )
678 {
679 MessageBox( szMsgLine006, szMsgFailure, MBINFO );
680 return;
681 }
682 Motor= lpMList->MP( );
683 if ( bHoldPosition )
684 sprintf( buf, "Alte Position %s", Motor->pCharacteristic( ) );
685 else
686 sprintf( buf, "Target Pos %s", Motor->pCharacteristic( ) );
687 SetDlgItemText( GetHandle( ), id_Report, (LPSTR)buf );
688 bZeroPosReached[ Motor->GetId( ) ]= TRUE;
689 Motor->GetAngle( 1 );
690 Motor->PopSettings( ThisPosition );
691 if ( !bValidCalibrationData )
692 Motor->SaveSettings( FALSE );
693
694 // Ist ein Motor noch nicht am Zielpunkt?
695 NextMotor= FALSE;
696 for ( idx= 0;idx <= lpMList->LastId( );idx++ )
697 if ( !bZeroPosReached[ idx ] )
698 NextMotor= TRUE;
699 if ( NextMotor )
700 goto ExitWithTimer;
701
702 //*** Calibration finished
703 if ( !bValidCalibrationData )
704 {
705 bValidCalibrationData= TRUE;
706 CheckDlgButton( GetHandle( ), id_ValidCalibrationData, TRUE );
707 }
708 MessageBeep( 0 );
709 if ( !nTask ) // Kullmann, Reinecker (08.08.02) nTask!=99 ersetzt
710 {
711 if ( !bValidCalibrationData )
712 {
713 strcpy( buf, szMsgLine009 );
714 strcat( buf, szMsgLine010 );
715 MessageBox( buf, szMessage, MBINFO );
716 }
717 else
718 MessageBox( szMsgLine009, szMessage, MBINFO );
719
720 bZeroShouldSet= FALSE;
721 EnableWindow( GetDlgItem( GetHandle( ), id_ChooseMotor ), TRUE );
722 EnableWindow( GetDlgItem( GetHandle( ), cm_SetHome ), TRUE );
723 EnableWindow( GetDlgItem( GetHandle( ), cm_CarryOnZero ), TRUE );
724 }
725 else
726 FORWARD_WM_COMMAND( hwnd, IDCANCEL, hwndCtl, 0, PostMessage );
727 return;
728
729 case cm_SetHome:
730 Motor->SetHome( );
731 Motor->GetAngle( 1 );
732 sprintf( buf, szMsgLine008, Motor->pCharacteristic( ) );
733 SetDlgItemText( GetHandle( ), id_Report, buf );
734 return;
735
736 case id_ChooseMotor:
737 if ( codeNotify==CBN_SELCHANGE )
738 {
739 idx= ComboBox_GetCurSel( hMotorList );
740 if ( ( Motor != lpMList->MP( idx ) ) && ( idx != CB_ERR ) )
741 {
742 lpMList->SetAxis( idx );
743 Motor= lpMList->MP( );
744 }
745 }
746 return;
747
748 //Datum: 02.08.2002
749 /*case cm_RotateMotor:
750 lpMList->SetAxis( Motor->GetId( ) +1 );
751 Motor= lpMList->MP( );
752 ComboBox_SelectString( hMotorList,0,Motor->pCharacteristic( ) );
753 return;*/
754
755 case id_ValidCalibrationData:
756 if ( bZeroShouldSet )
757 break;
758 bValidCalibrationData= IsDlgButtonChecked( GetHandle( ),
759 id_ValidCalibrationData );
760 if ( bValidCalibrationData )
761 {
762 EnableWindow( GetDlgItem( GetHandle( ), id_HoldPosition ), TRUE );
763 EnableWindow( GetDlgItem( GetHandle( ), id_AllMotorsReset ), TRUE );
764 }
765 else
766 {
767 bHoldPosition= FALSE;
768 EnableWindow( GetDlgItem( GetHandle( ), id_HoldPosition ), FALSE );
769 EnableWindow( GetDlgItem( GetHandle( ), id_AllMotorsReset ), FALSE );
770 }
771 return;
772
773 case id_AllMotorsReset:
774 if ( bZeroShouldSet )
775 break;
776 bAllMotors= IsDlgButtonChecked( GetHandle( ), id_AllMotorsReset );
777 if ( bAllMotors )
778 {
779 // Motor-Button deaktivieren
780 EnableWindow( GetDlgItem( GetHandle( ), id_ChooseMotor ), FALSE );
781 EnableWindow( GetDlgItem( GetHandle( ), cm_SetHome ), FALSE );
782 }
783 else
784 {
785 // Motor-Button aktivieren
786 EnableWindow( GetDlgItem( GetHandle( ), id_ChooseMotor ), TRUE );
787 EnableWindow( GetDlgItem( GetHandle( ), cm_SetHome ), TRUE );
788 }
789 return;
790
791 default:
792 TModalDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
793 }
794 return;
795
796 ExitWithTimer:
797 SetTimer( GetHandle( ), TimerIdInformation, 200, NULL );
798 return;
799 };
800
801
802 BOOL TCalibrateDlg::CanClose( void )
803 {
804 if ( bZeroShouldSet )
805 return FALSE;
806 // LimitWatch disable
807 return TRUE;
808 };
809
810
811 void TCalibrateDlg::LeaveDialog( void )
812 {
813 int id;
814 KillTimer( GetHandle( ), TimerIdInformation );
815 for ( id= 0;id <= lpMList->LastId( );id++ )
816 {
817 Motor= lpMList->MP( id );
818 Motor->StopDrive( TRUE );
819 }
820 };
821
822
823 //**************************************************************************
824 // Steuerung des Probentellers ueber die Position
825 void TMList::PositionControlDlg( void )
826 {
827 TModalDlg* dlg;
828 dlg= ( TPosControlDlg* ) new TPosControlDlg( );
829 if ( dlg ) dlg->ExecuteDialog( GetFrameHandle( ) );
830 _FREEOBJ(dlg);
831 };
832
833
834 TPosControlDlg::TPosControlDlg( ) : TModalDlg( "PositionControl", hModuleInstance )
835 {
836 bMoveActive= FALSE;
837 };
838
839
840 BOOL TPosControlDlg::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM )
841 {
842 int cnt;
843
844 Motor= lpMList->MP( );
845 BarHandle= GetDlgItem( GetHandle(), id_Bar );
846 hMotorList= GetDlgItem( GetHandle(), id_ChooseMotor );
847 cnt= 0;
848 while ( cnt <= lpMList->LastId( ) )
849 ComboBox_AddString( hMotorList, lpMList->MP( cnt++ ) ->pCharacteristic( ) );
850 FORWARD_WM_COMMAND( GetHandle(), cm_ParamSet, hwndCtl, 0, SendMessage );
851 SetFocus( BarHandle );
852 return TRUE;
853 };
854
855
856 void TPosControlDlg::Dlg_OnTimer( HWND hwnd, UINT id )
857 {
858 if ( id!=TimerIdInformation ) return;
859
860 while ( !Motor->GetPosition( TRUE ) )
861 /* wait for actual position */;
862 CtrlSetDouble(id_Position, Motor->GetPosition(), 0, '.' );
863 if ( Motor->IsMoveFinish( ) && bMoveActive )
864 {
865 KillTimer( hwnd, TimerIdInformation );
866 bMoveActive= FALSE;
867 }
868 FORWARD_WM_COMMAND( hwnd, cm_SetupDlgItem, 0, 0, SendMessage );
869 };
870
871
872 void TPosControlDlg::Dlg_OnCommand( HWND hwnd, int id, HWND hwndCtl, UINT codeNotify )
873 {
874 int idx;
875 BOOL bValid;
876
877 SCROLLINFO scrInfo;
878 scrInfo.cbSize= sizeof(SCROLLINFO);
879
880 switch ( id )
881 {
882 case cm_SetupDlgItem:
883 scrInfo.fMask= SIF_POS;
884 scrInfo.nPos= ScrollbarCalculate(Motor, ePos);
885 SetScrollInfo(BarHandle,SB_CTL,&scrInfo,TRUE);
886 CtrlSetLong(id_NewPosition, Motor->GetPosition());
887 return;
888
889 case cm_ParamSet:
890 // Initialisieren des Motor-Scroll-Bar's
891 CtrlSetLong(id_Position, Motor->GetPosition());
892 ComboBox_SelectString( hMotorList, 0, Motor->pCharacteristic( ) );
893 BarHandle= GetDlgItem( GetHandle( ), id_Bar );
894 scrInfo.fMask= SIF_RANGE;
895 // ANFANG Kullmann+Reinecker (12.03.2004)
896 /*scrInfo.nMin= -GetBarRange(Motor)/2;
897 scrInfo.nMax= GetBarRange(Motor)/2;*/
898 scrInfo.nMin= ScrollbarCalculate(Motor, eMin);
899 scrInfo.nMax= ScrollbarCalculate(Motor, eMax);
900 // ENDE Kullmann+Reinecker (12.03.2004)
901 SetScrollInfo(BarHandle,SB_CTL,&scrInfo,TRUE);
902 // Initialisieren aller Positionsfenster
903 FORWARD_WM_COMMAND( GetHandle(), cm_SetupDlgItem, hwndCtl, 0, SendMessage );
904 return;
905
906 case id_ChooseMotor:
907 if ( codeNotify!=CBN_SELCHANGE ) return;
908
909 idx= ComboBox_GetCurSel( hMotorList );
910 if ( ( Motor != lpMList->MP( idx ) ) && ( idx != CB_ERR ) )
911 {
912 Motor= lpMList->MP( idx );
913 lpMList->SetAxis( Motor->GetId( ) );
914 FORWARD_WM_COMMAND( hwnd, cm_ParamSet, hwndCtl, 0, SendMessage );
915 FORWARD_WM_COMMAND( hwnd, cm_MotorInit, hwndCtl, 0, PostMessage );
916 }
917 return;
918
919 //Datum: 02.08.2002
920 /*case cm_RotateMotor:
921 if( bMoveActive )
922 break;
923 lpMList->SetAxis( Motor->GetId( ) +1 );
924 Motor= lpMList->MP( );
925 FORWARD_WM_COMMAND( hwnd,cm_ParamSet,hwndCtl,0,SendMessage );
926 return;*/
927
928 case IDOK:
929 // Der Nutzer hat mit Return eine neue Position eingegeben
930 NewPosition= CtrlGetDouble(id_NewPosition, 0, '.', bValid);
931 if ( NewPosition < Motor->GetPositionMin() ) //Neu : Kullmann, Reinecker (27.07.02) lPositionMin ersetzt
932 NewPosition= Motor->GetPositionMin(); //Neu : Kullmann, Reinecker (27.07.02) lPositionMin ersetzt
933 else
934 if ( NewPosition > Motor->GetPositionMax() ) //Neu : Kullmann, Reinecker (27.07.02) lPositionMax ersetzt
935 NewPosition= Motor->GetPositionMax(); //Neu : Kullmann, Reinecker (27.07.02) lPositionMax ersetzt
936 FORWARD_WM_COMMAND( hwnd, cm_MoveButton, hwndCtl, 0, PostMessage );
937 SetFocus( GetDlgItem( GetHandle( ), id_Bar ) );
938 return;
939
940 case cm_MoveButton:
941 Motor->MoveToPosition( NewPosition );
942 SetTimer( GetHandle( ), TimerIdInformation, 80, NULL );
943 bMoveActive= TRUE;
944 FORWARD_WM_COMMAND( hwnd, cm_SetupDlgItem, hwndCtl, 0, PostMessage );
945 return;
946
947 default:
948 TModalDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
949 }
950 };
951
952
953 BOOL TPosControlDlg::HScrollBar( WPARAM wParam, LPARAM )
954 {
955 switch ( wParam )
956 {
957 case SB_LINEUP:
958 NewPosition= Motor->GetPosition() - Motor->GetPositionWidth(); //Neu : Kullmann, Reinecker (27.07.02) lPosition u. wPositionWidth ersetzt
959 NewPosition= max( Motor->GetPositionMin(), NewPosition ); //Neu : Kullmann, Reinecker (27.07.02) lPositionMin ersetzt
960 break;
961
962 case SB_LINEDOWN:
963 NewPosition= Motor->GetPosition() + Motor->GetPositionWidth(); //Neu : Kullmann, Reinecker (27.07.02) lPosition u. wPositionWidth ersetzt
964 NewPosition= min( Motor->GetPositionMax() , NewPosition ); //Neu : Kullmann, Reinecker (27.07.02) lPositionMax ersetzt
965 break;
966
967 case SB_PAGEUP:
968 NewPosition= Motor->GetPosition() - 5 * Motor->GetPositionWidth(); //Neu : Kullmann, Reinecker (27.07.02) lPosition u. wPositionWidth ersetzt
969 NewPosition= max( Motor->GetPositionMin(), NewPosition ); //Neu : Kullmann, Reinecker (27.07.02) lPositionMin ersetzt
970 break;
971
972 case SB_PAGEDOWN:
973 NewPosition= Motor->GetPosition() + 5 * Motor->GetPositionWidth(); //Neu : Kullmann, Reinecker (27.07.02) lPosition u. wPositionWidth ersetzt
974 NewPosition= min( Motor->GetPositionMax(), NewPosition ); //Neu : Kullmann, Reinecker (27.07.02) lPositionMax ersetzt
975 break;
976
977 case SB_ENDSCROLL: // Bewegung ausloesen
978 FORWARD_WM_COMMAND( GetHandle( ), cm_MoveButton, 0, 0, PostMessage );
979 break;
980 }
981 return TRUE;
982 };
983
984 // ANFANG Kullmann+Reinecker (12.03.2004)
985 int TPosControlDlg::ScrollbarCalculate( TMotor *act, EPosType aType ) {
986 long ma= act->GetPositionMax();
987 long mi= act->GetPositionMin();
988 float skale;
989 try
990 {
991 skale= (float) ( 32000 / (float)(ma-mi));
992 }
993 catch (...)
994 {
995 skale= 0;
996 }
997 if ( aType==eMax ) return (int) ( (ma-mi)*skale );
998 else if ( aType==ePos ) return (int) ( (act->GetPosition()-mi)*skale );
999 else return 0; // eMin
1000 }
1001
1002 /*int TPosControlDlg::GetBarRange( TMotor *act ) //Neu : Kullmann, Reinecker (14.11.02) const beim Parameter entfernt, sonst const-member-functions im Motor nötig
1003 {
1004 try {
1005 //return ( int ) ( ( act->GetPositionMax() - act->GetPositionMin() ) / act->GetPositionWidth() ); //Neu : Kullmann, Reinecker (27.07.02) lPositionMax, lPositionMin, wPositionWidth ersetzt
1006 } catch (...) {
1007 return 0; //Neu : Kullmann+Reinecker: Div 0
1008 }
1009 };
1010
1011
1012 int TPosControlDlg::GetBarPos( TMotor *act ) //Neu : Kullmann, Reinecker (14.11.02) const beim Parameter entfernt, sonst const-member-functions im Motor nötig
1013 {
1014 try {
1015 //return ( int ) ( ( act->GetPosition() - act->GetPositionMin() ) / act->GetPositionWidth() ); //Neu : Kullmann, Reinecker (27.07.02) lPositionMax, lPositionMin, wPositionWidth ersetzt
1016 } catch (...) { //Neu Kullmann+Reinecker: div 0
1017 return 0;
1018 }
1019 };*/
1020 // ENDE Kullmann+Reinecker (12.03.2004)
1021
1022 void TPosControlDlg::LeaveDialog( void )
1023 {
1024 Motor->StopDrive( 1 );
1025 KillTimer( GetHandle( ), TimerIdInformation );
1026 };
1027
1028
1029 //*************************************************************************
1030 //*** Allgemeine Einstellungen fuer Motoren
1031 TMotorParamDlg::TMotorParamDlg( void ) : TModalDlg( "DRIVESETTINGS", hModuleInstance )
1032 {
1033 };
1034
1035
1036
1037 BOOL TMotorParamDlg::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM lParam )
1038 {
1039 int i;
1040
1041 // Initialisieren der Parameterfenster fuer einen Motor
1042 Motor= lpMList->MP( );
1043 hMotorList= GetDlgItem( GetHandle( ), id_ChooseMotor );
1044 i= 0;
1045 while ( i <= lpMList->LastId( ) )
1046 ComboBox_AddString( hMotorList, lpMList->MP( i++ ) ->pCharacteristic( ) );
1047 FORWARD_WM_COMMAND( hwnd, cm_ParamSet, hwndCtl, 0, SendMessage );
1048 SetFocus( GetDlgItem( GetHandle( ), id_Velocity ) );
1049 return TRUE;
1050 };
1051
1052
1053 void TMotorParamDlg::Dlg_OnCommand( HWND hwnd, int id, HWND hwndCtl, UINT codeNotify )
1054 {
1055 int idx;
1056 char buf[ MaxString ];
1057
1058 switch ( id )
1059 {
1060 case cm_ParamSet: // Initialisieren der Parameterfenster fuer einen Motor
1061 ComboBox_SelectString( hMotorList, 0, Motor->pCharacteristic( ) );
1062 sprintf( buf, Motor->pSF( ), Motor->GetSpeed( ) );
1063 SetDlgItemText( GetHandle( ), id_Velocity, ( LPSTR ) buf );
1064 SetDlgItemText( GetHandle( ), id_Limit, ( LPSTR ) ltoa( Motor->GetLimit( ),
1065 ( LPSTR ) buf, 10 ) );
1066 SetDlgItemText( GetHandle( ), id_PositionMax,
1067 ( LPSTR ) ltoa( Motor->GetPositionMax(), ( LPSTR ) buf, 10 ) ); // Kullmann, Reinecker (04.08.02) lPositionMax ersetzt
1068 SetDlgItemText( GetHandle( ), id_PositionMin,
1069 ( LPSTR ) ltoa( Motor->GetPositionMin(), ( LPSTR ) buf, 10 ) ); // Kullmann, Reinecker (04.08.02) lPositionMin ersetzt
1070 SetDlgItemText( GetHandle( ), id_PositionWidth,
1071 ( LPSTR ) ltoa( Motor->GetPositionWidth(), ( LPSTR ) buf, 10 ) ); // Kullmann, Reinecker (04.08.02) wPositionWidth ersetzt
1072 SetDlgItemText( GetHandle( ), id_Unit, ( LPSTR ) Motor->GetUnitName() ); // Kullmann, Reinecker (04.08.02) szUnit ersetzt
1073 sprintf( buf, Motor->pSF( ), Motor->GetAngleWidth( ) );
1074 SetDlgItemText( GetHandle( ), id_AngleWidth, ( LPSTR ) buf );
1075 sprintf( buf, Motor->pDF( ), Motor->GetAngleMin() ); // Kullmann, Reinecker (04.08.02) dAngleMin ersetzt
1076 SetDlgItemText( GetHandle( ), id_AngleMin, ( LPSTR ) buf );
1077 sprintf( buf, Motor->pDF( ), Motor->GetAngleMax() ); // Kullmann, Reinecker (04.08.02) dAngleMax ersetzt
1078 SetDlgItemText( GetHandle( ), id_AngleMax, ( LPSTR ) buf );
1079 return;
1080
1081 case cm_SwitchLimitWatch:
1082 if ( !Motor->StartLimitWatch( ) )
1083 Motor->StopLimitWatch( );
1084 return;
1085
1086 case id_ChooseMotor:
1087 switch ( codeNotify )
1088 {
1089 case CBN_EDITCHANGE:
1090 SetWindowText( hMotorList, Motor->pCharacteristic( ) );
1091 return;
1092
1093 case CBN_SELCHANGE:
1094 idx= ComboBox_GetCurSel( hMotorList );
1095 if ( ( Motor != lpMList->MP( idx ) ) && ( idx != CB_ERR ) )
1096 {
1097 if ( CanClose( ) )
1098 {
1099 Motor= lpMList->MP( idx );
1100 lpMList->SetAxis( Motor->GetId( ) );
1101 }
1102 FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, SendMessage );
1103 }
1104 return;
1105 }
1106 return;
1107
1108 //Datum: 02.08.2002
1109 /*case cm_RotateMotor:
1110 // Erst die Einstellungen fuer den aktuellen Motor sichern
1111 if( CanClose( ) ) {
1112 lpMList->SetAxis( Motor->GetId( ) +1 );
1113 Motor= lpMList->MP( );
1114 }
1115 FORWARD_WM_COMMAND( hwnd,cm_ParamSet,0,0,SendMessage );
1116 return;*/
1117
1118 default:
1119 TModalDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
1120 }
1121 };
1122
1123
1124 BOOL TMotorParamDlg::CanClose( void )
1125 {
1126 char buf[ MaxString ];
1127 BOOL FActivate= FALSE;
1128 BOOL FFail= FALSE;
1129 WORD valueW;
1130 DWORD valueDW;
1131 double valueF;
1132
1133 for (;; )
1134 {
1135 GetDlgItemText( GetHandle( ), id_Velocity, ( LPSTR ) buf, 10 );
1136 if ( !buf )
1137 {
1138 FFail= TRUE;
1139 break;
1140 }
1141 valueF= atof( buf );
1142 if ( valueF == 0.0 )
1143 {
1144 FFail= TRUE;
1145 break;
1146 }
1147 if ( Motor->SetSpeed( valueF ) )
1148 FActivate= TRUE;
1149 GetDlgItemText( GetHandle( ), id_Limit, ( LPSTR ) buf, 10 );
1150 if ( !buf )
1151 {
1152 FFail= TRUE;
1153 break;
1154 }
1155 valueDW= ( DWORD ) atol( buf );
1156 if ( Motor->GetLimit( ) != valueDW )
1157 Motor->SetLimit( valueDW );
1158 break;
1159 }
1160 if ( FActivate )
1161 Motor->ActivateDrive( );
1162 if ( FFail )
1163 return FALSE;
1164 GetDlgItemText( GetHandle( ), id_PositionWidth, ( LPSTR ) buf, 10 );
1165 valueW= ( WORD ) atoi( buf );
1166 if ( 0 != valueW )
1167 Motor->SetPositionWidth( valueW ); // Kullmann, Reinecker (04.08.02) wPositionWidth ersetzt
1168 else
1169 return FALSE;
1170
1171 GetDlgItemText( GetHandle( ), id_PositionMax, ( LPSTR ) buf, 10 );
1172 Motor->SetPositionMax( atol( buf ) ); // Kullmann, Reinecker (04.08.02) lPositionMax ersetzt
1173 GetDlgItemText( GetHandle( ), id_PositionMin, ( LPSTR ) buf, 10 );
1174 Motor->SetPositionMin( atol( buf ) ); // Kullmann, Reinecker (04.08.02) lPositionMin ersetzt
1175 GetDlgItemText( GetHandle( ), id_AngleMax, ( LPSTR ) buf, 10 );
1176 valueF= atof( buf );
1177
1178 if ( ( 0.0 != valueF ) )
1179 {
1180 Motor->SetAngleMax( valueF ); // Kullmann, Reinecker (04.08.02) dAngleMax ersetzt
1181 }
1182 else
1183 return FALSE;
1184
1185 GetDlgItemText( GetHandle( ), id_AngleMin, ( LPSTR ) buf, 10 );
1186 valueF= atof( buf );
1187 if ( ( 0.0 != valueF ) )
1188 {
1189 Motor->SetAngleMin( valueF ); // Kullmann, Reinecker (04.08.02) dAngleMin ersetzt
1190 }
1191 else
1192 return FALSE;
1193 GetDlgItemText( GetHandle( ), id_AngleWidth, ( LPSTR ) buf, 10 );
1194 valueF= atof( buf );
1195 if ( 0.0 != valueF )
1196 {
1197 Motor->SetAngleWidth( valueF );
1198 }
1199 else
1200 return FALSE;
1201 return TRUE;
1202 };
1203
1204
1205 //*************************************************************************
1206
1207 TOptimizeDC_832Dlg::TOptimizeDC_832Dlg( void ) : TModalDlg( "OptimizeDC_832", hModuleInstance )
1208 {
1209 Drive= (TC_832*)lpMList->MP( );
1210 bCancel= TRUE;
1211 };
1212
1213
1214 BOOL TOptimizeDC_832Dlg::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM )
1215 {
1216 old_vel= Drive->dwMaxVelocity;
1217 old_accel= Drive->dwAcceleration;
1218 old_kp= Drive->wKP;
1219 old_kd= Drive->wKD;
1220 old_ki= Drive->wKI;
1221 old_kl= Drive->wKL;
1222 old_poswidth= Drive->wPositionWidth;
1223 FORWARD_WM_COMMAND( hwnd, cm_ParamSet, hwndCtl, 0, SendMessage );
1224 return TRUE;
1225 };
1226
1227 void TOptimizeDC_832Dlg::Dlg_OnCommand( HWND hwnd, int id, HWND hwndCtl,
1228 UINT codeNotify )
1229 {
1230 char buf[ MaxString ];
1231
1232 switch ( id )
1233 {
1234 case cm_ParamSet:
1235 // Testgruppe
1236 sprintf( buf, szMsgLine011, "C832", Drive->pCharacteristic( ) );
1237 SetWindowText( hwnd, buf );
1238 //
1239 SetWindowText( GetHandle( ), buf );
1240 sprintf( buf, "%ld", Drive->dwMaxVelocity );
1241 SetDlgItemText( GetHandle( ), id_Velocity, ( LPSTR ) buf );
1242 sprintf( buf, "%ld", Drive->dwAcceleration );
1243 SetDlgItemText( GetHandle( ), id_Acceleration, ( LPSTR ) buf );
1244 sprintf( buf, "%d", Drive->wKD );
1245 SetDlgItemText( GetHandle( ), id_kd, ( LPSTR ) buf );
1246 sprintf( buf, "%d", Drive->wKP );
1247 SetDlgItemText( GetHandle( ), id_kp, ( LPSTR ) buf );
1248 sprintf( buf, "%d", Drive->wKI );
1249 SetDlgItemText( GetHandle( ), id_ki, ( LPSTR ) buf );
1250 sprintf( buf, "%d", Drive->wKL );
1251 SetDlgItemText( GetHandle( ), id_kl, ( LPSTR ) buf );
1252 sprintf( buf, "%d", Drive->wPositionWidth );
1253 SetDlgItemText( GetHandle( ), id_PositionWidth, ( LPSTR ) buf );
1254 break;
1255
1256 case cm_StartMoveScan:
1257 GetDlgItemText( GetHandle( ), id_Velocity, buf, MaxString );
1258 Drive->dwMaxVelocity= atol( buf );
1259 GetDlgItemText( GetHandle( ), id_Acceleration, buf, MaxString );
1260 Drive->dwAcceleration= atol( buf );
1261 GetDlgItemText( GetHandle( ), id_kd, buf, MaxString );
1262 Drive->wKD= ( WORD ) atoi( buf );
1263 GetDlgItemText( GetHandle( ), id_kp, buf, MaxString );
1264 Drive->wKP= ( WORD ) atoi( buf );
1265 GetDlgItemText( GetHandle( ), id_ki, buf, MaxString );
1266 Drive->wKI= ( WORD ) atoi( buf );
1267 GetDlgItemText( GetHandle( ), id_kl, buf, MaxString );
1268 Drive->wKL= ( WORD ) atoi( buf );
1269 GetDlgItemText( GetHandle( ), id_PositionWidth, buf, MaxString );
1270 Drive->wPositionWidth= ( WORD ) atoi( buf );
1271 Drive->ActivateFilterParameters( );
1272 mStartMoveScan( 10, 0 );
1273 return;
1274
1275 default:
1276 TModalDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
1277 }
1278 return;
1279 };
1280
1281
1282 BOOL TOptimizeDC_832Dlg::CanClose( void )
1283 {
1284 bCancel= FALSE;
1285 Drive->SaveSettings( 0 );
1286 return TRUE;
1287 };
1288
1289
1290 void TOptimizeDC_832Dlg::LeaveDialog( void )
1291 {
1292 if ( bCancel )
1293 {
1294 Drive->dwMaxVelocity= old_vel;
1295 Drive->dwAcceleration= old_accel;
1296 Drive->wKP= old_kp;
1297 Drive->wKD= old_kd;
1298 Drive->wKI= old_ki;
1299 Drive->wKL= old_kl;
1300 Drive->wPositionWidth= old_poswidth;
1301 }
1302 Drive->ActivateFilterParameters( );
1303 };
1304
1305
1306 //******************************************************************************
1307 //******************************************************************************
1308 void TC_812::OptimizingDlg( void )
1309 {
1310 TModalDlg* dlg;
1311
1312 dlg= ( TOptimizeDC_812Dlg * ) new TOptimizeDC_812Dlg( );
1313 if ( dlg ) dlg->ExecuteDialog( GetFrameHandle( ) );
1314 _FREEOBJ(dlg);
1315 };
1316
1317
1318 TOptimizeDC_812Dlg::TOptimizeDC_812Dlg( void ) : TModalDlg( "OptimizeDC_812", hModuleInstance )
1319 {
1320 Drive= ( TC_812* ) lpMList->MP( );
1321 bCancel= TRUE;
1322 };
1323
1324
1325
1326 BOOL TOptimizeDC_812Dlg::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM lParam )
1327 {
1328 old_vel= Drive->dwMaxVelocity;
1329 old_accel= Drive->dwAcceleration;
1330 old_gain= Drive->wStaticGain;
1331 old_dgain= Drive->wDynamicGain;
1332 old_torque= Drive->wTorque;
1333 old_poswidth= Drive->wPositionWidth;
1334 FORWARD_WM_COMMAND( hwnd, cm_ParamSet, hwndCtl, 0, SendMessage );
1335 return TRUE;
1336 };
1337
1338 void TOptimizeDC_812Dlg::Dlg_OnCommand( HWND hwnd, int id, HWND hwndCtl,
1339 UINT codeNotify )
1340 {
1341 char buf[ MaxString ];
1342
1343 switch ( id )
1344 {
1345 case cm_ParamSet:
1346 // Testgruppe
1347 sprintf( buf, szMsgLine011, "C812", Drive->pCharacteristic( ) );
1348 SetWindowText( hwnd, buf );
1349 //
1350 sprintf( buf, "%ld", Drive->dwMaxVelocity );
1351 SetDlgItemText( hwnd, id_Velocity, ( LPSTR ) buf );
1352 sprintf( buf, "%ld", Drive->dwAcceleration );
1353 SetDlgItemText( hwnd, id_Acceleration, ( LPSTR ) buf );
1354 sprintf( buf, "%d", Drive->wTorque );
1355 SetDlgItemText( hwnd, id_Torque, ( LPSTR ) buf );
1356 sprintf( buf, "%d", Drive->wStaticGain );
1357 SetDlgItemText( hwnd, id_Gain, ( LPSTR ) buf );
1358 sprintf( buf, "%d", Drive->wDynamicGain );
1359 SetDlgItemText( hwnd, id_DynamicGain, ( LPSTR ) buf );
1360 sprintf( buf, "%d", Drive->wPositionWidth );
1361 SetDlgItemText( hwnd, id_PositionWidth, ( LPSTR ) buf );
1362 break;
1363
1364 case cm_StartMoveScan:
1365 GetDlgItemText( hwnd, id_Velocity, buf, MaxString );
1366 Drive->dwMaxVelocity= atol( buf );
1367 GetDlgItemText( hwnd, id_Acceleration, buf, MaxString );
1368 Drive->dwAcceleration= atol( buf );
1369 GetDlgItemText( hwnd, id_Gain, buf, MaxString );
1370 Drive->wStaticGain= ( WORD ) atoi( buf );
1371 GetDlgItemText( hwnd, id_DynamicGain, buf, MaxString );
1372 Drive->wDynamicGain= ( WORD ) atoi( buf );
1373 GetDlgItemText( hwnd, id_Torque, buf, MaxString );
1374 Drive->wTorque= ( WORD ) atoi( buf );
1375 GetDlgItemText( GetHandle( ), id_PositionWidth, buf, MaxString );
1376 Drive->wPositionWidth= ( WORD ) atoi( buf );
1377 Drive->ActivateFilterParameters( );
1378 mStartMoveScan( 15, 0 );
1379 break;
1380
1381 default:
1382 TModalDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
1383 }
1384 };
1385
1386
1387 BOOL TOptimizeDC_812Dlg::CanClose( void )
1388 {
1389 char buf[ MaxString ];
1390
1391 bCancel= FALSE;
1392 GetDlgItemText( GetHandle( ), id_Velocity, buf, MaxString );
1393 Drive->dwMaxVelocity= atol( buf );
1394 GetDlgItemText( GetHandle( ), id_Acceleration, buf, MaxString );
1395 Drive->dwAcceleration= atol( buf );
1396 GetDlgItemText( GetHandle( ), id_Gain, buf, MaxString );
1397 Drive->wStaticGain= ( WORD ) atoi( buf );
1398 GetDlgItemText( GetHandle( ), id_DynamicGain, buf, MaxString );
1399 Drive->wDynamicGain= ( WORD ) atoi( buf );
1400 GetDlgItemText( GetHandle( ), id_Torque, buf, MaxString );
1401 Drive->wTorque= ( WORD ) atoi( buf );
1402 Drive->ActivateFilterParameters( );
1403 Drive->SaveSettings( 0 );
1404 return TRUE;
1405 };
1406
1407
1408 void TOptimizeDC_812Dlg::LeaveDialog( void )
1409 {
1410 if ( bCancel )
1411 {
1412 Drive->dwMaxVelocity= old_vel;
1413 Drive->dwAcceleration= old_accel;
1414 Drive->wTorque= old_torque;
1415 Drive->wStaticGain= old_gain;
1416 Drive->wDynamicGain= old_dgain;
1417 Drive->wPositionWidth= old_poswidth;
1418 Drive->ActivateFilterParameters( );
1419 }
1420 };
1421
1422
1423
1424 //****************************************************************************
1425 //****************************************************************************
1426 TMotor::TMotor( )
1427 {
1428 char Ident[ MaxString ];
1429 char ifile[ MaxString ];
1430 char buf[ MaxString ];
1431
1432 nId= nMaxId++;
1433 dAngleBias= 0.0;
1434 dAngle= 0.0;
1435 lCorrPos= 0;
1436 fCorrBias= 0.0;
1437 bIndexLine= FALSE;
1438 bIndexDetected= FALSE;
1439 bControlBoardOk= FALSE;
1440 bLimitWatchActive= FALSE;
1441 eCorrStatus= CorrLinear;
1442 bIsCalibrated= FALSE;
1443 bInquireStatus= FALSE;
1444 bRangeHit= FALSE;
1445 bUpwards= TRUE;
1446 lDeltaPosition= 0;
1447 lPosition= 0;
1448 // lPreviousPosition= 0; Kullmann, Reinecker ( Toter Code, am 04.08.02 auskommentiert )
1449
1450
1451 strcpy( ifile, GetHWFile( ) );
1452 sprintf( Ident, "motor%d", nId );
1453 GetPrivateProfileString( Ident, "Name", "Motor", szCharacteristic, _MAXLENCHARACTERISTIC, GetHWFile( ) );
1454 WritePrivateProfileString( Ident, "Name", szCharacteristic, GetHWFile( ) );
1455
1456 dwHysteresis= ( DWORD ) GetPrivateProfileInt( Ident, "Hysteresis", 0, GetHWFile( ) );
1457 WritePrivateProfileString( Ident, "Hysteresis", ltoa( dwHysteresis, buf, 10 ),
1458 GetHWFile( ) );
1459
1460 bUpwards= GetPrivateProfileInt( Ident, "Upwards", 1, GetHWFile( ) );
1461 WritePrivateProfileString( Ident, "Upwards", ltoa( bUpwards, buf, 10 ),
1462 GetHWFile( ) );
1463
1464 switch ( lpMList->ParsingAxis( szCharacteristic ) )
1465 {
1466 case Rotation:
1467 case Phi:
1468 lpMList->AD_Phi= nId;
1469 lpMList->AD_Rotation= nId;
1470 break;
1471
1472 case X:
1473 lpMList->AD_X= nId;
1474 break;
1475
1476 case Y:
1477 lpMList->AD_Y= nId;
1478 break;
1479
1480 case Z:
1481 lpMList->AD_Z= nId;
1482 break;
1483
1484 case Theta:
1485 lpMList->AD_Theta= nId;
1486 break;
1487
1488 case Omega:
1489 case DF:
1490 lpMList->AD_Omega= nId;
1491 lpMList->AD_DF= nId;
1492 break;
1493
1494 case Tilt:
1495 case Psi:
1496 lpMList->AD_Psi= nId;
1497 lpMList->AD_Tilt= nId;
1498 break;
1499
1500 case DC:
1501 lpMList->AD_DC= nId;
1502 break;
1503
1504 case Collimator:
1505 lpMList->AD_Collimator= nId;
1506 break;
1507
1508 case Absorber:
1509 lpMList->AD_Absorber= nId;
1510 break;
1511
1512 case Monochromator:
1513 lpMList->AD_Monochromator= nId;
1514 break;
1515
1516 case Encoder:
1517 lpMList->AD_Encoder= nId;
1518 break;
1519 }
1520 };
1521
1522
1523 TMotor::Initialize( void )
1524 {
1525 HCURSOR hCursorOld;
1526 float MaxFailure;
1527 char Ident[ MaxString + 1 ];
1528 char buf[ MaxString + 1 ];
1529
1530 hCursorOld= SetCursor( LoadCursor(NULL,IDC_WAIT) );
1531 // Motor identifizieren
1532 sprintf( Ident, "motor%d", nId );
1533
1534 GetPrivateProfileString( Ident, "MaxVelocity", "8000", buf, MaxString, GetHWFile( ) );
1535 if ( CreateIniDefaults( ) )
1536 WritePrivateProfileString( Ident, "MaxVelocity", buf, GetHWFile( ) );
1537 dwMaxVelocity= atol( buf );
1538
1539 GetPrivateProfileString( Ident, "Velocity", "8000", buf, MaxString, GetHWFile( ) );
1540 if ( CreateIniDefaults( ) )
1541 WritePrivateProfileString( Ident, "Velocity", buf, GetHWFile( ) );
1542 dwVelocity= atol( buf );
1543 if ( dwVelocity == 0 )
1544 dwVelocity= dwMaxVelocity / 2;
1545
1546 GetPrivateProfileString( Ident, "Unit", "Unit", szUnit, _MAXLENUNIT, GetHWFile( ) );
1547 if ( CreateIniDefaults( ) )
1548 WritePrivateProfileString( Ident, "Unit", szUnit, GetHWFile( ) );
1549 eUnit= UnitEnum( szUnit );
1550 strcpy( DFmt, "%.2lf" );
1551 strcpy( SFmt, "%.2lf" );
1552
1553 GetPrivateProfileString( Ident, "Digits", "2", buf, MaxString, GetHWFile( ) );
1554 nDigits= atoi( buf ); // NEU: Kullmann, Reinecker (23.07.2002)
1555 DFmt[ 2 ]= ( char ) ( '0' + nDigits ); // NEU: Kullmann, Reinecker: atoi durch nDigits ersetzt (12.08.2002)
1556 SFmt[ 2 ]= ( char ) ( '1' + nDigits ); // NEU: Kullmann, Reinecker: atoi durch nDigits ersetzt (12.08.2002)
1557 if ( CreateIniDefaults( ) )
1558 WritePrivateProfileString( Ident, "Digits", buf, GetHWFile( ) );
1559
1560 GetPrivateProfileString( Ident, "MinimalWidth", "10", buf, MaxString, GetHWFile( ) );
1561 if ( CreateIniDefaults() )
1562 WritePrivateProfileString( Ident, "MinimalWidth", buf, GetHWFile( ) );
1563 wPositionMinWidth= ( WORD ) atoi( buf );
1564
1565 GetPrivateProfileString( Ident, "MaximalWidth", "510", buf, MaxString, GetHWFile( ) );
1566 if ( CreateIniDefaults() )
1567 WritePrivateProfileString( Ident, "MaximalWidth", buf, GetHWFile( ) );
1568 wPositionMaxWidth= ( WORD ) atoi( buf );
1569
1570 GetPrivateProfileString( Ident, "PositionMin", "-100", buf, MaxString, GetHWFile( ) );
1571 if ( CreateIniDefaults() )
1572 WritePrivateProfileString( Ident, "PositionMin", buf, GetHWFile( ) );
1573 lPositionMin= atol( buf );
1574
1575 GetPrivateProfileString( Ident, "PositionMax", "100", buf, MaxString, GetHWFile( ) );
1576 if ( CreateIniDefaults() )
1577 WritePrivateProfileString( Ident, "PositionMax", buf, GetHWFile( ) );
1578 lPositionMax= atol( buf );
1579 if ( lPositionMax <= lPositionMin )
1580 lPositionMax= lPositionMin + 100;
1581
1582 GetPrivateProfileString( Ident, "PositionWidth", "10", buf, MaxString, GetHWFile( ) );
1583 if ( CreateIniDefaults() )
1584 WritePrivateProfileString( Ident, "PositionWidth", buf, GetHWFile( ) );
1585 wPositionWidth= ( WORD ) atoi( buf );
1586 if ( wPositionWidth == 0 )
1587 wPositionWidth= 0.2;
1588
1589 GetPrivateProfileString( Ident, "InitialMove", "0", buf, MaxString, GetHWFile( ) );
1590 if ( CreateIniDefaults() )
1591 WritePrivateProfileString( Ident, "InitialMove", buf, GetHWFile( ) );
1592 bInitialMoveReady= atoi( buf );
1593
1594 GetPrivateProfileString( Ident, "RestartPossible", "0", buf, MaxString, GetHWFile( ) );
1595 WritePrivateProfileString( Ident, "RestartPossible", "0", GetHWFile( ) ); // Programm als "nicht ordnungsgemäß beendet" kennzeichnen
1596 if ( bInitialMoveReady )
1597 SetCalibrationState( atoi( buf ) );
1598 else
1599 SetCalibrationState( TRUE );
1600
1601 GetPrivateProfileString( Ident, "DeltaPosition", "0", buf, MaxString, GetHWFile( ) );
1602 lDeltaPosition= atol( buf );
1603 if ( IsCalibrated( ) )
1604 {
1605 if ( !bUpwards )
1606 lDeltaPosition += dwHysteresis;
1607 }
1608 dAngleBias= 0.0;
1609 lCorrPos= 0;
1610
1611 GetPrivateProfileString( Ident, "DistanceToZero", "0", buf, MaxString, GetHWFile( ) );
1612 if ( CreateIniDefaults() )
1613 WritePrivateProfileString( Ident, "DistanceToZero", buf, GetHWFile( ) );
1614 lDistanceToZero= atol( buf );
1615
1616 GetPrivateProfileString( Ident, "RemoveLimit", "4000", buf, MaxString, GetHWFile( ) );
1617 if ( CreateIniDefaults() )
1618 WritePrivateProfileString( Ident, "RemoveLimit", buf, GetHWFile( ) );
1619 dwRemoveLimit= ( DWORD ) atol( buf );
1620
1621 GetPrivateProfileString( Ident, "MoveFirstToLimit", "0", buf, MaxString,
1622 GetHWFile( ) );
1623 bMoveFirstToLimit= atoi( buf );
1624
1625 GetPrivateProfileString( Ident, "IndexLine", "0", buf, MaxString, GetHWFile( ) );
1626 bIndexLine= atoi( buf );
1627
1628 GetPrivateProfileString( Ident, "InitialAngle", "0.0", buf, MaxString, GetHWFile( ) );
1629 if ( CreateIniDefaults() )
1630 WritePrivateProfileString( Ident, "InitialAngle", buf, GetHWFile( ) );
1631 dInitialAngle= atof( buf );
1632
1633 GetPrivateProfileString( Ident, "Acceleration", "10", buf, MaxString, GetHWFile( ) );
1634 if ( CreateIniDefaults() )
1635 WritePrivateProfileString( Ident, "Acceleration", buf, GetHWFile( ) );
1636 dwAcceleration= atol( buf );
1637
1638 GetPrivateProfileString( Ident, "AngleMin", "-1.0", buf, MaxString, GetHWFile( ) );
1639 if ( CreateIniDefaults() )
1640 WritePrivateProfileString( Ident, "AngleMin", buf, GetHWFile( ) );
1641 dAngleMin= atof( buf );
1642
1643 GetPrivateProfileString( Ident, "AngleMax", "1.0", buf, MaxString, GetHWFile( ) );
1644 if ( CreateIniDefaults() )
1645 WritePrivateProfileString( Ident, "AngleMax", buf, GetHWFile( ) );
1646 dAngleMax= atof( buf );
1647
1648 GetPrivateProfileString( Ident, "AngleWidth", "0.1", buf, MaxString, GetHWFile( ) );
1649 if ( CreateIniDefaults() )
1650 WritePrivateProfileString( Ident, "AngleWidth", buf, GetHWFile( ) );
1651 dAngleWidth= atof( buf );
1652
1653 GetPrivateProfileString( Ident, "Koeff_3", "0.0", buf, MaxString, GetHWFile( ) );
1654 if ( CreateIniDefaults() )
1655 WritePrivateProfileString( Ident, "Koeff_3", buf, GetHWFile( ) );
1656 dKoeff_3= atof( buf );
1657
1658 GetPrivateProfileString( Ident, "Koeff_2", "0.0", buf, MaxString, GetHWFile( ) );
1659 if ( CreateIniDefaults() )
1660 WritePrivateProfileString( Ident, "Koeff_2", buf, GetHWFile( ) );
1661 dKoeff_2= atof( buf );
1662
1663 GetPrivateProfileString( Ident, "Koeff_1", "1.0", buf, MaxString, GetHWFile( ) );
1664 if ( CreateIniDefaults() )
1665 WritePrivateProfileString( Ident, "Koeff_1", buf, GetHWFile( ) );
1666 dKoeff_1= atof( buf );
1667
1668 GetPrivateProfileString( Ident, "SpeedScale", "10.0", buf, MaxString, GetHWFile( ) );
1669 if ( CreateIniDefaults() )
1670 WritePrivateProfileString( Ident, "SpeedScale", buf, GetHWFile( ) );
1671 fSpeedScale= atof( buf );
1672 SetCursor( hCursorOld );
1673
1674 GetPrivateProfileString( Ident, "MaxFailure", "30.0", buf, MaxString, GetHWFile( ) );
1675 if ( CreateIniDefaults() )
1676 WritePrivateProfileString( Ident, "MaxFailure", buf, GetHWFile( ) );
1677 MaxFailure= atof( buf );
1678
1679 /*dwInterval= ( DWORD ) ( 3.0 * MaxFailure / dKoeff_1 );
1680 switch ( eUnit )
1681 {
1682 case utGrad:
1683 dwInterval *= 3600;
1684 break;
1685
1686 case utMinuten:
1687 dwInterval *= 60;
1688 break;
1689 }*/
1690 dwInterval= (DWORD)CalcValueFromUnit(eUnit, DWORD(3.0 * MaxFailure / dKoeff_1));
1691
1692 GetPrivateProfileString( Ident, "Correction", "0", buf, MaxString, GetHWFile( ) );
1693 if ( CreateIniDefaults() )
1694 WritePrivateProfileString( Ident, "Correction", buf, GetHWFile( ) );
1695 bCorrection= atoi( buf );
1696 SetCorrectionState( TRUE );
1697 return R_OK;
1698 };
1699
1700
1701 //*************** Element-Funktionen ******************************************
1702 BOOL TMotor::SetAngleRange( void )
1703 {
1704 double a1, a2;
1705
1706 Translate( a1, lPositionMin );
1707 Translate( a2, lPositionMax );
1708 // 19.12.02 Kullmann, Reinecker : es soll auch a1 > a2 möglich sein, um die Bewegungsrichtung umzukehren
1709 dAngleMin= a1; // alt: min( a1,a2 );
1710 dAngleMax= a2; // alt: max( a1,a2 );
1711 return TRUE;
1712 };
1713
1714 BOOL TMotor::PushSettings( void )
1715 {
1716 Settings.dAngle= dAngle;
1717 Settings.dAngleMin= dAngleMin;
1718 Settings.dAngleMax= dAngleMax;
1719 Settings.dAngleWidth= dAngleWidth;
1720 Settings.dSpeed= dSpeed;
1721 return TRUE;
1722 };
1723
1724 BOOL TMotor::PopSettings ( EMParameter param )
1725 {
1726 if ( (dAngle != Settings.dAngle) && (param == OldPosition) )
1727 MoveToAngle( Settings.dAngle );
1728 dAngleMin= Settings.dAngleMin;
1729 dAngleMax= Settings.dAngleMax;
1730 SetAngleWidth( Settings.dAngleWidth );
1731 SetSpeed( Settings.dSpeed );
1732 return TRUE;
1733 };
1734
1735 //ANFANG: neu Kullmann, Reinecker (04.05.2002) neue Methoden
1736
1737 //------------------------------------------------------------------------------
1738 //Offset für Relative Null vorhanden
1739
1740 BOOL TMotor::IsDistanceRelative( void )
1741 {
1742 return ((int)( dAngleBias * pow( (float)10, (float)GetDigits() ) ) != 0);
1743 };
1744 //------------------------------------------------------------------------------
1745 //Relative Null setzen (nur wenn Antrieb steht)
1746
1747 BOOL TMotor::SetRelativeZero( void )
1748 {
1749 BOOL bValid= FALSE;
1750 if ( IsMoveFinish() )
1751 dAngleBias= -1 * GetAngleAbs(FALSE, bValid); //nur wenn der Antrieb steht: auf aktuellen Winkel setzen
1752
1753 return IsDistanceRelative(); //relative Null gesetzt?
1754 };
1755 //------------------------------------------------------------------------------
1756 //Relative Null aufheben (nur wenn Antrieb steht)
1757
1758 BOOL TMotor::ResetRelativeZero( void )
1759 {
1760 if ( IsMoveFinish() )
1761 dAngleBias= 0.0; //nur wenn der Antrieb steht: Relative Null aufheben
1762
1763 return !IsDistanceRelative(); //relative Null aufgehoben?
1764 };
1765
1766 //ENDE: neu Kullmann, Reinecker (03.05.2002)
1767
1768 //------------------------------------------------------------------------------
1769 // Umrechnung von Position in Winkel mit einem Polynom
1770 // Umkehrfunktion mit Newton-Verfahren
1771
1772 void TMotor::funcd( double arg, double offset, double *f, double *df )
1773 {
1774 *f= arg * ( dKoeff_1 + arg * ( dKoeff_2 + arg * dKoeff_3 ) ) - offset;
1775 *df= dKoeff_1 + arg * ( 2 * dKoeff_2 + arg * 3 * dKoeff_3 );
1776 };
1777
1778
1779 int TMotor::rtsave( double offset, double x1, double x2, double xacc, double *ret )
1780 /* Using a combination of Newton-Raphson and bisection, find the */
1781 /* root of a function bracketed between x1 and x2. The root, re- */
1782 /* turned as the function value rtsafe, will be refined until its */
1783 /* accuracy is known within +-xacc. funcd is a user-supplied rou- */
1784 /* tine that provides both the function value and the first deriv- */
1785 /* ative of the function. */
1786 {
1787 int j;
1788 double df, dx, dxold, f, fh, fl, xh, xl, rts;
1789
1790 funcd( x1, offset, &fl, &df );
1791 funcd( x2, offset, &fh, &df );
1792 if ( ( fl ) *( fh ) >= 0.0 )
1793 return -1; // "Root must be bracketed in RTSAFE"
1794 if ( ( fl ) < 0.0 ) // Orient the search so that f(xl)<0.
1795 {
1796 xl= x1;
1797 xh= x2;
1798 }
1799 else
1800 {
1801 xh= x1;
1802 xl= ( fl );
1803 fl= fh;
1804 fh= xl;
1805 xl= x2;
1806 }
1807 rts= 0.5 * ( x1 + x2 );
1808 // Initialize the guess for root,
1809 dx= dxold= fabs( x2 - x1 );
1810 // the "step-size before last" and the last step.
1811 funcd( rts, offset, &f, &df );
1812
1813 // Loop over allowed iterations.
1814 for ( j= 1;j <= MAXIT;j++ )
1815 {
1816 // Bisect if Newton out of range,
1817 if ( ( ( ( rts - xh ) *df - f ) *( ( rts - xl ) *df - f ) >= 0.0 ) || ( fabs( 2.0*f ) > fabs( dxold*df ) ) )
1818 // or not decreasing fast enough.
1819 {
1820 dxold= dx;
1821 dx= 0.5 * ( xh - xl );
1822 rts= xl + dx;
1823 if ( xl == rts )
1824 {
1825 // Change in root is negligible.
1826 *ret= rts;
1827 return 0;
1828 }
1829 }
1830 else
1831 // Newton step acceptable. Take it.
1832 {
1833 dxold= dx;
1834 dx= f / df;
1835 df= rts;
1836 rts -= dx;
1837 if ( df == rts )
1838 {
1839 *ret= rts;
1840 return 0;
1841 }
1842 }
1843 if ( fabs( dx ) < xacc )
1844 // Convergence criterion.
1845 {
1846 *ret= rts;
1847 return 0;
1848 }
1849 funcd( rts, offset, &f, &df );
1850 // The one new function evaluation per iteration.
1851 if ( f < 0.0 )
1852 // Maintain the bracket on the root.
1853 {
1854 xl= rts;
1855 fl= f;
1856 }
1857 else
1858 {
1859 xh= rts;
1860 fh= f;
1861 }
1862 }
1863 return -2; // "Maximum number of iterations exceeded in RTSAFE"
1864 };
1865
1866
1867 BOOL TMotor::Translate( long &pos, double ang )
1868 {
1869 // translate angle to position
1870 char buffer[ MaxString ];
1871 double l_ang;
1872 double l_pos;
1873 double xleft, xright;
1874 double temp;
1875 int ret;
1876
1877 // Liegt Winkel im Bereich ?
1878 bRangeHit= FALSE;
1879 l_ang= ang - dAngleBias + fCorrBias;
1880
1881 // 19.12.02 Kullmann, Reinecker
1882 // es ist bei einem negativen Koeff1 auch möglich das dAngleMin > dAngleMax ist
1883 // dies würde hier immer zu einem RageHit führen -> keine Antriebsbewegung möglich
1884 /*if( l_ang > dAngleMax )
1885 {
1886 bRangeHit= TRUE;
1887 l_ang= dAngleMax;
1888 }
1889 if( ang < dAngleMin )
1890 {
1891 bRangeHit= TRUE;
1892 l_ang= dAngleMin;
1893 }*/
1894 temp= l_ang;
1895 bRangeHit= !SetInRange( temp, dAngleMin, dAngleMax ); // bei Intervallüberschreitung wird bRangeHit= TRUE
1896
1897 // Uebersetzen des Winkels in eine Position
1898 /*switch ( eUnit )
1899 {
1900 case utGrad:
1901 l_ang= l_ang * 3600.0;
1902 break;
1903
1904 case utMinuten:
1905 l_ang= l_ang * 60.0;
1906 break;
1907 }*/
1908 l_ang= CalcValueFromUnit(eUnit, l_ang);
1909
1910 switch ( eCorrStatus )
1911 {
1912 case CorrPolynom:
1913 xleft= xright= l_ang / dKoeff_1;
1914 xright += dwInterval;
1915 xleft -= dwInterval;
1916 ret= rtsave( l_ang, xleft, xright, 1, &l_pos );
1917 if ( ret )
1918 {
1919 sprintf( buffer, "Newton %d !\n", ret );
1920 MessageBox( GetFocus( ), buffer, szMsgFailure, MBINFO );
1921 return FALSE;
1922 }
1923 break;
1924
1925 default:
1926 l_pos= l_ang / dKoeff_1;
1927 }
1928 pos= (long)ceil(l_pos);
1929 bRangeHit= !SetInRange( pos , lPositionMax , lPositionMin ); // bei Intervallüberschreitung wird bRangeHit= TRUE
1930
1931 // 19.12.02 Kullmann, Reinecker
1932 // der selbe Grund wie oben in der Methode bei temp
1933 // pos= max( min( (long)ceil( l_pos ), lPositionMax ), lPositionMin );
1934 return TRUE;
1935 };
1936
1937
1938 BOOL TMotor::Translate( double &ang, long pos )
1939 {
1940 // translate position to angle
1941 double l_ang;
1942
1943 // Positions-Offset beruecksichtigen
1944 switch ( eCorrStatus )
1945 {
1946 case CorrPolynom:
1947 l_ang= pos * ( dKoeff_1 + pos * ( dKoeff_2 + pos * dKoeff_3 ) );
1948 break;
1949
1950 default:
1951 l_ang= pos * dKoeff_1;
1952 }
1953
1954 /*switch ( eUnit )
1955 {
1956 case utGrad:
1957 l_ang= l_ang / 3600.0;
1958 break;
1959
1960 case utMinuten:
1961 l_ang= l_ang / 60.0;
1962 break;
1963 }*/
1964 l_ang= CalcValueInUnit(eUnit, l_ang);
1965 ang= l_ang + dAngleBias - fCorrBias;
1966 return TRUE;
1967 };
1968
1969 // ANFANG: Kullmann, Reinecker (14.11.02) neu Hilfs-Methode zur Berechnung der absoluten Winkelposition
1970 // ----------------------------------------------------------------------------
1971 // translates position to angle
1972
1973 BOOL TMotor::TranslateAbs( double &ang, long pos )
1974 {
1975 double l_ang;
1976 // Positions-Offset beruecksichtigen
1977 switch ( eCorrStatus )
1978 {
1979 case CorrPolynom:
1980 l_ang= pos * ( dKoeff_1 + pos * ( dKoeff_2 + pos * dKoeff_3 ) );
1981 break;
1982
1983 default:
1984 l_ang= pos * dKoeff_1;
1985 }
1986 /*switch ( eUnit )
1987 {
1988 case utGrad:
1989 l_ang= l_ang / 3600.0;
1990 break;
1991
1992 case utMinuten:
1993 l_ang= l_ang / 60.0;
1994 break;
1995 }*/
1996 l_ang= CalcValueInUnit(eUnit, l_ang);
1997 ang= l_ang - fCorrBias; // ang ist wahre absolute Winkelposition
1998 return TRUE;
1999 };
2000 // ENDE: Kullmann, Reinecker (14.11.02)
2001
2002 void TMotor::SetCorrectionState( BOOL onoff )
2003 {
2004 long dcpos;
2005 float ang1, ang2;
2006
2007 lCorrPos= 0;
2008 fCorrBias= 0.0;
2009
2010 if ( !bCorrection || !bIsCalibrated )
2011 {
2012 eCorrStatus= CorrLinear;
2013 return;
2014 }
2015 if ( onoff )
2016 {
2017 if ( nId != lpMList->AD_DF )
2018 {
2019 eCorrStatus= CorrPolynom;
2020 return;
2021 }
2022 lpMList->MP( lpMList->AD_DC ) ->GetPosition( 1 );
2023 dcpos= lpMList->MP( lpMList->AD_DC ) ->lPosition;
2024 if ( dcpos == lCorrPos )
2025 {
2026 eCorrStatus= CorrPolynom;
2027 return;
2028 }
2029 GetAngle( 1 );
2030 ang1= dAngle;
2031 lCorrPos= dcpos;
2032 fCorrBias= 0.0;
2033 eCorrStatus= CorrPolynom;
2034 GetAngle( 1 ); // MS-Pos
2035 ang2= dAngle;
2036 fCorrBias= ang2 - ang1;
2037 }
2038 else
2039 {
2040 eCorrStatus= CorrLinear;
2041 lCorrPos= 0;
2042 fCorrBias= 0.0;
2043 }
2044 };
2045
2046
2047 BOOL TMotor::SetHome( void )
2048 {
2049 bIsCalibrated= FALSE;
2050 SetCorrectionState( 0 );
2051 // lPreviousPosition= GetPosition( 1 ); Kullmann, Reinecker ( Toter Code, am 04.08.02 auskommentiert )
2052 lDeltaPosition= 0;
2053 lPosition= 0;
2054 dAngle= 0.0;
2055 dAngleBias= 0.0;
2056 return TRUE;
2057 };
2058
2059
2060 BOOL TMotor::MoveByPosition( long pos )
2061 {
2062 lPosition += pos;
2063 return TRUE;
2064 };
2065
2066
2067 BOOL TMotor::MoveToPosition( long pos )
2068 {
2069 lPosition= pos;
2070 return TRUE;
2071 };
2072
2073
2074 BOOL TMotor::MoveToAngle( double ang )
2075 {
2076 long lpos;
2077
2078 // Umwandlung von Winkel- in Positionsangaben
2079 if ( Translate( lpos, ang ) )
2080 // Aufruf der TDC_Drive-Funktion MoveToPosition() mit Pos.angabe
2081 if ( MoveToPosition( lpos ) )
2082 return TRUE;
2083 // bei Fehlschlag: FALSE
2084 return FALSE;
2085 };
2086
2087
2088 BOOL TMotor::MoveByAngle( double ang )
2089 {
2090 long lpos;
2091
2092 if ( !GetAngle( 1 ) )
2093 return FALSE;
2094 if ( Translate(lpos, (dAngle + ang)) )
2095 if ( MoveToPosition(lpos) )
2096 return TRUE;
2097 return FALSE;
2098 };
2099
2100
2101 BOOL TMotor::SetAngleWidth( double dang )
2102 {
2103 double dposcmp, dpos;
2104
2105 /*switch ( eUnit )
2106 {
2107 case utGrad:
2108 dposcmp= dpos= 3600.0 * fabs( dang / dKoeff_1 );
2109 break;
2110
2111 case utMinuten:
2112 dposcmp= dpos= 60.0 * fabs( dang / dKoeff_1 );
2113 break;
2114
2115 default:
2116 dposcmp= dpos= fabs( dang / dKoeff_1 );
2117 break;
2118 }*/
2119 dposcmp= dpos= CalcValueFromUnit(eUnit, fabs(dang / dKoeff_1));
2120
2121 dpos= max( min( dpos, ( double ) wPositionMaxWidth ), ( double ) wPositionMinWidth );
2122 /*switch ( eUnit )
2123 {
2124 case utGrad:
2125 dAngleWidth= fabs( dKoeff_1 * dpos / 3600.0 );
2126 break;
2127
2128 case utMinuten:
2129 dAngleWidth= fabs( dKoeff_1 * dpos / 60.0 );
2130 break;
2131
2132 default:
2133 dAngleWidth= fabs( dKoeff_1 * dpos );
2134 }*/
2135 dAngleWidth= CalcValueInUnit(eUnit, dKoeff_1 * dpos);
2136 if ( dpos != dposcmp )
2137 return FALSE;
2138 return TRUE;
2139 };
2140
2141
2142 BOOL TMotor::GetAngle( BOOL saveyesno )
2143 {
2144 double ang;
2145
2146 // Holt Motorposition und speichert in IPosition,
2147 // Rueckgabewert bei C832 immer TRUE
2148 // nur bei C812 ohne DirectAccess FALSE moeglich
2149 if ( !GetPosition( saveyesno ) )
2150 return FALSE;
2151 // Falls keine Uebersetzung der IPosition in Winkel ang moeglich,
2152 // dann FALSE
2153 if ( !Translate( ang, lPosition ) ) // rechnet lPosition in ang um; bAngleBias wird beachtet
2154 return FALSE;
2155 // sonst Abspeichern des Winkels in Membervar dAngel und TRUE
2156 dAngle= ang;
2157
2158 // Debug Code
2159 #ifdef CheckCorrect
2167 #endif
2168
2169 return TRUE;
2170 };
2171
2172 //ANFANG: neu Kullmann, Reinecker (04.08.2002) neue Methoden
2173 //------------------------------------------------------------------------------
2174 // aktuelle absolute Antriebsposition in Nutzereinheiten
2175
2176 double TMotor::GetAngleAbs( BOOL saveyesno, BOOL &aValid )
2177 {
2178 double ang= 0.0;
2179 aValid= FALSE;
2180 // Holt Motorposition und speichert in IPosition,
2181 // Rueckgabewert bei C832 immer TRUE
2182 // nur bei C812 ohne DirectAccess FALSE moeglich
2183 if ( !GetPosition( saveyesno ) )
2184 return 0.0;
2185 // Falls keine Uebersetzung der IPosition in Winkel ang moeglich,
2186 // dann FALSE
2187 if ( !TranslateAbs( ang, lPosition ) )
2188 return 0.0;
2189
2190 // Debug Code
2191 #ifdef CheckCorrect
2199 #endif
2200 aValid= TRUE;
2201 return ang;
2202 };
2203 //------------------------------------------------------------------------------
2204 // aktuelle Antriebsposition in Nutzereinheiten
2205
2206 double TMotor::GetAngle( BOOL aStatus, BOOL &aValid )
2207 {
2208 if ( !GetAngle( aStatus ) )
2209 aValid= FALSE; // Auslesen und Umrechen
2210
2211 aValid= TRUE;
2212 return dAngle;
2213 };
2214 //------------------------------------------------------------------------------
2215 // minimale RELATIVE Antriebsposition in Nutzereinheiten
2216
2217 double TMotor::GetAngleRelativeMin( void )
2218 {
2219 return dAngleMin + GetAngleBias();
2220 };
2221 //------------------------------------------------------------------------------
2222 // maximale RELATIVE Antriebsposition in Nutzereinheiten
2223
2224 double TMotor::GetAngleRelativeMax( void )
2225 {
2226 return dAngleMax + GetAngleBias();
2227 };
2228 //------------------------------------------------------------------------------
2229 // minimale Schrittweite
2230
2231 double TMotor::GetMinAngleWidth()
2232 {
2233 double a;
2234 /*if ( eUnit == utGrad )
2235 a= fabs( dKoeff_1 * wPositionMinWidth / 3600.0 );
2236
2237 else if ( eUnit == utMinuten )
2238 a= fabs( dKoeff_1 * wPositionMinWidth / 60.0 );
2239
2240 else
2241 a= fabs( dKoeff_1 * wPositionMinWidth );
2242 */
2243 a= CalcValueInUnit(eUnit, dKoeff_1 * wPositionMinWidth);
2244
2245 return a;
2246 };
2247 //------------------------------------------------------------------------------
2248 // maximale Schrittweite
2249
2250 double TMotor::GetMaxAngleWidth()
2251 {
2252 double a;
2253 /* if ( eUnit == utGrad )
2254 a= fabs( dKoeff_1 * wPositionMinWidth / 3600.0 );
2255
2256 else if ( eUnit == utMinuten )
2257 a= fabs( dKoeff_1 * wPositionMinWidth / 60.0 );
2258
2259 else
2260 a= fabs( dKoeff_1 * wPositionMinWidth );*/
2261 a= CalcValueInUnit(eUnit, dKoeff_1 * wPositionMinWidth);
2262
2263 return a;
2264 };
2265 //------------------------------------------------------------------------------
2266
2267 double TMotor::GetAcceleration()
2268 {
2269 double a;
2270 Translate(a, dwAcceleration);
2271 return fabsl(a);
2272 };
2273 //------------------------------------------------------------------------------
2274 // minimale Antriebsgeschwindigkeit in Nutzereinheiten
2275
2276 double TMotor::GetMinSpeed()
2277 {
2278 return (double)(1 / fSpeedScale);
2279 };
2280
2281 //------------------------------------------------------------------------------
2282 // maximale Antriebsgeschwindigkeit in Nutzereinheiten
2283
2284 double TMotor::GetMaxSpeed()
2285 {
2286 return (double)(dwMaxVelocity / fSpeedScale);
2287 };
2288 //------------------------------------------------------------------------------
2289 // setzt den Offset in Nutzereinheiten
2290
2291 BOOL TMotor::SetAngleBias( double aAngleBias )
2292 {
2293 if ( !IsMoveFinish() )
2294 return FALSE; //nur bei Stillstand des Antriebs kann gesetzt werden
2295 dAngleBias= aAngleBias;
2296 return TRUE;
2297 };
2298 //------------------------------------------------------------------------------
2299
2300 UINT TMotor::GetDigits( void )
2301 {
2302 return nDigits;
2303 };
2304
2305 //ENDE : neu Kullmann, Reinecker (04.08.2002)
2306
2307 //------------------------------------------------------------------------------
2308
2309 int TMotor::SaveSettings( BOOL LastSave )
2310 {
2311 //*** Abspeichern der Motoreinstellungen in den Parameter-File.
2312 HCURSOR hCursorOld;
2313 char buf[ MaxString ];
2314 char Ident[ MaxString ];
2315
2316 if ( !bControlBoardOk )
2317 return R_Failure;
2318 sprintf( Ident, "motor%d", nId );
2319 hCursorOld= SetCursor( LoadCursor(NULL,IDC_WAIT) );
2320 sprintf( buf, "%ld", lDistanceToZero );
2321 WritePrivateProfileString( Ident, "DistanceToZero", buf, GetHWFile( ) );
2322 if ( LastSave )
2323 {
2324 SetCorrectionState( FALSE );
2325 sprintf( buf, "%ld", dwVelocity );
2326 WritePrivateProfileString( Ident, "Velocity", buf, GetHWFile( ) );
2327 sprintf( buf, "%u", wPositionWidth );
2328 WritePrivateProfileString( Ident, "PositionWidth", buf, GetHWFile( ) );
2329 sprintf( buf, "%d", bUpwards );
2330 WritePrivateProfileString( Ident, "Upwards", buf, GetHWFile( ) );
2331 GetPosition( TRUE );
2332 sprintf( buf, "%ld", lPosition );
2333 WritePrivateProfileString( Ident, "DeltaPosition", buf, GetHWFile( ) );
2334 sprintf( buf, pDF( ), dAngleMin );
2335 WritePrivateProfileString( Ident, "AngleMin", buf, GetHWFile( ) );
2336 sprintf( buf, pSF( ), dAngleWidth );
2337 WritePrivateProfileString( Ident, "AngleWidth", buf, GetHWFile( ) );
2338 sprintf( buf, pDF( ), dAngleBias );
2339 WritePrivateProfileString( Ident, "AngleBias", buf, GetHWFile( ) );
2340 sprintf( buf, pDF( ), dAngleMax );
2341 WritePrivateProfileString( Ident, "AngleMax", buf, GetHWFile( ) );
2342 WritePrivateProfileString( Ident, "MJ_Offset", "0", GetHWFile( ) ); // 10.12.2002 Kullmann+Reinecker: Manuelle Justage Offset =0 setzen
2343 if ( bIsCalibrated )
2344 WritePrivateProfileString( Ident, "RestartPossible", "1", GetHWFile( ) );
2345 }
2346 SetCursor( hCursorOld );
2347 return R_OK;
2348 };
2349
2350
2351 //******************************************************************************
2352 TDC_Drive::TDC_Drive( void ) : TMotor( )
2353 {
2354 char Ident[ MaxString ];
2355 nMaxError= 2;
2356
2357 sprintf( Ident, "motor%d", nId );
2358 wDeathBand= ( WORD ) GetPrivateProfileInt( Ident, "DeathBand", 1, GetHWFile( ) );
2359 wDeccelerationPoint= ( WORD ) GetPrivateProfileInt( Ident, "DeccelerationPoint",
2360 20, GetHWFile( ) );
2361 };
2362
2363
2364 int TDC_Drive::SaveSettings( BOOL onlythis )
2365 {
2366 return TMotor::SaveSettings( onlythis );
2367 }
2368
2369
2370 int TDC_Drive::Initialize( void )
2371 {
2372 char buf[ MaxString ];
2373
2374 if ( R_OK != TMotor::Initialize( ) )
2375 goto Exit;
2376 if ( CheckBoardOk( ) )
2377 {
2378 if ( !Reset( ) )
2379 goto Exit;
2380 if ( !ActivateFilterParameters( ) )
2381 goto Exit;
2382 if ( !ActivateDrive( ) )
2383 goto Exit;
2384 }
2385 else
2386 {
2387 sprintf( buf, szMsgLine012, pCharacteristic( ) );
2388 MessageBox( GetFocus( ), buf, szMsgFailure, MBSTOP );
2389 #ifdef TESTLAUF
2392 #endif
2393 return(FALSE);
2394 }
2395 return R_OK;
2396
2397 Exit:
2398 #ifdef TESTLAUF
2401 #else
2402
2403 return R_OK;
2404 #endif
2405 };
2406
2407
2408 BOOL TDC_Drive::PushSettings( void )
2409 {
2410 return TRUE;
2411 };
2412
2413
2414 BOOL TDC_Drive::PopSettings( void )
2415 {
2416 return TRUE;
2417 };
2418
2419
2420 BOOL TDC_Drive::MoveToPosition( long position )
2421 {
2422 // Test auf Richtungswechsel zur Beruecksichtigen des Motorspiels
2423 if ( bUpwards && ( position < lPosition ) )
2424 {
2425 // ===> wechselt in <===
2426 lDeltaPosition += dwHysteresis;
2427 bUpwards= FALSE;
2428 }
2429 else
2430 {
2431 if ( !bUpwards && ( position > lPosition ) )
2432 {
2433 // <=== wechselt in ===>
2434 lDeltaPosition -= dwHysteresis;
2435 bUpwards= TRUE;
2436 }
2437 }
2438
2439 // Beruecksichtigen der relativen Position nach Programm-Start
2440 // und Richtungswechsel
2441 position -= lDeltaPosition + lCorrPos;
2442
2443 // Aufruf der motorabhaengigen Hardware-Funktion
2444 // TC_812::MoveAbsolute() bzw. TC_832::MoveAbsolute()
2445 // mit umgerechneter bzw. korrigierter Positionsangabe
2446 // (unter Berücksichtigung von Richtung, Spiel und relativer Position)
2447 return MoveAbsolute( position );
2448 };
2449
2450
2451 BOOL TDC_Drive::MoveByPosition( long distance )
2452 {
2453 return MoveRelative( distance );
2454 };
2455
2456
2457 BOOL TDC_Drive::SetSpeed( double speed )
2458 {
2459 DWORD velocity;
2460
2461 velocity= fSpeedScale * speed;
2462 SetVelocity( velocity );
2463 dSpeed= (double) GetVelocity() / fSpeedScale;
2464 return TRUE;
2465 };
2466
2467
2468 double TDC_Drive::GetSpeed( void )
2469 {
2470 DWORD vel;
2471
2472 vel= GetVelocity( );
2473 if ( vel == 0 )
2474 return 0.0;
2475 dSpeed= (double) vel / fSpeedScale;
2476 return dSpeed;
2477 };
2478
2479
2480 BOOL TDC_Drive::GetPosition( BOOL bSave )
2481 {
2482 long pos1, pos2;
2483
2484 // Aufruf der Member-Fkt. _GetPosition
2485 // fuer die speziellen Karten (C812(ISA), C832)
2486 // Rueckgabewert bei C832 immer TRUE;
2487 // FALSE nur bei C812 ohne DirectAccess moeglich
2488
2489 // Auslesen der 'real position'
2490 if ( _GetPosition( &pos1 ) )
2491 {
2492 if ( bSave ) // Wert speichern ?
2493 {
2494 // erneutes Auslesen der akt. Position
2495 if ( !_GetPosition( &pos2 ) )
2496 return FALSE;
2497 // bei Positionswertaenderung -> kein Speichern (Fahrbetrieb ?)
2498 if ( pos1 != pos2 )
2499 return FALSE;
2500 }
2501 // Beruecksichtigen der relativen Karten-Position
2502 lPosition= pos1 + lDeltaPosition + lCorrPos;
2503 return TRUE;
2504 }
2505 return FALSE;
2506 };
2507
2508
2509 long TDC_Drive::GetFailure( void )
2510 {
2511 long failure;
2512 int check= 3;
2513
2514 while ( !_GetFailure( &failure ) )
2515 {
2516 if ( 0 == check-- )
2517 return 100;
2518 }
2519 return failure;
2520 };
2521
2522
2523 //*************************************************************************
2524 TC_812::TC_812( void ) : TDC_Drive( )
2525 {
2526 char Ident[ MaxString ];
2527
2528 sprintf( Ident, "motor%d", nId );
2529 nOnBoardId= GetPrivateProfileInt( Ident, "BoardId", 1, GetHWFile( ) );
2530 wStaticGain= ( WORD ) GetPrivateProfileInt( Ident, "Gain", 100, GetHWFile( ) );
2531 wDynamicGain= ( WORD ) GetPrivateProfileInt( Ident, "DynamicGain", 37, GetHWFile( ) );
2532 wMaxTorque= 127;
2533 nWaitTicks= 5;
2534 wTorque= ( WORD ) GetPrivateProfileInt( Ident, "Torque", 110, GetHWFile( ) );
2535 };
2536
2537
2538 int TC_812::SaveSettings( BOOL bLastSave )
2539 {
2540 char buf[ MaxString ];
2541 char Ident[ MaxString ];
2542
2543 if ( !bControlBoardOk )
2544 return R_Failure;
2545 sprintf( Ident, "motor%d", nId );
2546 sprintf( buf, "%u", wDynamicGain );
2547 WritePrivateProfileString( Ident, "DynamicGain", buf, GetHWFile( ) );
2548 sprintf( buf, "%u", wTorque );
2549 WritePrivateProfileString( Ident, "Torque", buf, GetHWFile( ) );
2550 sprintf( buf, "%u", wStaticGain );
2551 WritePrivateProfileString( Ident, "Gain", buf, GetHWFile( ) );
2552 sprintf( buf, "%lu", dwMaxVelocity );
2553 WritePrivateProfileString( Ident, "MaxVelocity", buf, GetHWFile( ) );
2554 sprintf( buf, "%lu", dwAcceleration );
2555 WritePrivateProfileString( Ident, "Acceleration", buf, GetHWFile( ) );
2556 sprintf( buf, "%lu", dwVelocity );
2557 WritePrivateProfileString( Ident, "Velocity", buf, GetHWFile( ) );
2558 return TDC_Drive::SaveSettings( bLastSave );
2559 };
2560
2561
2562 BOOL TC_812::ActivateFilterParameters( void )
2563 {
2564 char cmd[ MaxString ];
2565
2566 sprintf( cmd, "%uDB%u\r", nOnBoardId, wDeathBand );
2567 if ( R_OK != ExecuteCmd( cmd ) )
2568 return FALSE;
2569 sprintf( cmd, "%uSQ%u,%uSG%u,%uSE%u\r", nOnBoardId, wTorque, nOnBoardId,
2570 wStaticGain, nOnBoardId, wDynamicGain );
2571
2572 if ( R_OK != ExecuteCmd( cmd ) )
2573 return FALSE;
2574 SetVelocity( dwMaxVelocity );
2575 SetAcceleration( dwAcceleration );
2576 SetLimit( dwRemoveLimit );
2577 GetSpeed( );
2578 return TRUE;
2579 };
2580
2581
2582 BOOL TC_812::Reset( void )
2583 {
2584 long lDeltaP= lDeltaPosition;
2585 BOOL bIsCal= IsCalibrated( );
2586 BOOL ret= SetHome( );
2587 lDeltaPosition= lDeltaP;
2588 SetCalibrationState( bIsCal );
2589 nC812= GetId( );
2590 return ret;
2591 };
2592
2593
2594 BOOL TC_812::SetMoment( float moment )
2595 {
2596 // Dreh-Moment 0 .. 1.0
2597 if ( moment <= 1.0 )
2598 wTorque= 127 * moment;
2599 else
2600 wTorque= 60;
2601 SetTorque( wTorque );
2602 return TRUE;
2603 };
2604
2605
2606 float TC_812::GetMoment( void )
2607 {
2608 WORD torque;
2609 // Dreh-Moment 0 .. 1.0
2610 torque= GetTorque( );
2611 return ( torque / wMaxTorque );
2612 };
2613
2614
2615 BOOL TC_812::SetLine( int number, BOOL status )
2616 {
2617 char cmd[ MaxString + 1 ];
2618
2619 if ( ( 1 > number ) && ( 16 < number ) )
2620 return FALSE;
2621 if ( status )
2622 sprintf( cmd, "%uCT%u,%uCN%u\r", nOnBoardId, number, nOnBoardId, number );
2623 else
2624 sprintf( cmd, "%uCT%u,%uCF%u\r", nOnBoardId, number, nOnBoardId, number );
2625 if ( R_OK != ExecuteCmd( cmd ) )
2626 return FALSE;
2627 return TRUE;
2628 };
2629
2630
2631 BOOL TC_812::IsLimitHit( void )
2632 {
2633 if ( GetStatus() & StatMLimitHit )
2634 return TRUE;
2635 else
2636 return FALSE;
2637 };
2638
2639
2640 BOOL TC_812::IsMoveFinish( void )
2641 {
2642 if ( bInquireStatus )
2643 {
2644 if ( GetStatus() & StatMStopped )
2645 return TRUE;
2646 }
2647 else
2648 {
2649 if ( labs( GetFailure() ) <= (long) wDeathBand )
2650 return TRUE;
2651 }
2652 return FALSE;
2653 };
2654
2655
2656 BOOL TC_812::IsIndexArrived( void )
2657 {
2658 if ( bIndexDetected && IsMoveFinish() )
2659 return TRUE;
2660 if ( IsLimitHit() )
2661 {
2662 if ( !bIndexDetected )
2663 {
2664 DelayTime( 20 );
2665 bIndexDetected= TRUE;
2666 }
2667 }
2668 return FALSE;
2669 };
2670
2671
2672 BOOL TC_812::StartToIndex( long &oldPos )
2673 {
2674 SetSpeed( 10000.0 );
2675 lDeltaPosition= 0;
2676 SetCorrectionState( 0 );
2677 GetPosition( TRUE );
2678 oldPos= lPosition;
2679 bIndexDetected= FALSE;
2680 bIndexLine= FALSE;
2681 MoveToPosition( lPosition - 400000000l );
2682 // Die Motoren werden in Bewegung gesetzt
2683 // Erreichen der Stillstands-Position
2684 DelayTime( 100 );
2685 return TRUE;
2686 };
2687
2688
2689 BOOL TC_812::ActivateDrive( void )
2690 {
2691 char cmd[ MaxString + 1 ];
2692
2693 sprintf( cmd, "%uSP%u\r", nOnBoardId, wDeccelerationPoint );
2694 if ( R_OK != ExecuteCmd( cmd ) )
2695 return FALSE;
2696 sprintf( cmd, "%uMN\r", nOnBoardId );
2697 if ( R_OK != ExecuteCmd( cmd ) )
2698 return FALSE;
2699 return TRUE;
2700 };
2701
2702
2703 BOOL TC_812::StopDrive( BOOL bOffOn ) // Kullmann, Reinecker (08.08.02) Parameter geändert int -> BOOL
2704 {
2705 char cmd[ MaxString + 1 ];
2706
2707 if ( bOffOn )
2708 {
2709 sprintf( cmd, "%uAB\r", nOnBoardId );
2710 if ( R_OK != ExecuteCmd( cmd ) )
2711 return FALSE;
2712 // Einige Motoren koennen nach diesem Stop ihre Position
2713 // nicht mehr einregeln, deshalb ein zweites Kommando zum
2714 // Gleichsetzen von Target und Position
2715 Delay( 100 );
2716
2717 sprintf( cmd, "%uAB\r", nOnBoardId );
2718 if ( R_OK != ExecuteCmd( cmd ) )
2719 return FALSE;
2720 sprintf( cmd, "%uMN\r", nOnBoardId );
2721 if ( R_OK != ExecuteCmd( cmd ) )
2722 return FALSE;
2723 }
2724 else
2725 {
2726 sprintf( cmd, "%uAB\r", nOnBoardId );
2727 if ( R_OK != ExecuteCmd( cmd ) )
2728 return FALSE;
2729 }
2730 return TRUE;
2731 };
2732
2733
2734 BOOL TC_812::SetDynamicGain( WORD dygain )
2735 {
2736 char cmd[ MaxString + 1 ];
2737
2738 dygain= min( dygain, ( WORD ) 255 );
2739 dygain= max( dygain, ( WORD ) 1 );
2740 wDynamicGain= dygain;
2741
2742 sprintf( cmd, "%uSE%u\r", nOnBoardId, wDynamicGain );
2743 if ( R_OK != ExecuteCmd( cmd ) )
2744 return FALSE;
2745 return TRUE;
2746 };
2747
2748
2749 WORD TC_812::GetDynamicGain( void )
2750 {
2751 return wDynamicGain;
2752 };
2753
2754
2755 BOOL TC_812::SetTorque( WORD torque )
2756 {
2757 char cmd[ MaxString + 1 ];
2758
2759 wTorque= min( torque, ( WORD ) 127 );
2760 sprintf( cmd, "%uSQ%u\r", nOnBoardId, wTorque );
2761 if ( R_OK != ExecuteCmd( cmd ) )
2762 return FALSE;
2763 return TRUE;
2764 };
2765
2766
2767 WORD TC_812::GetTorque( void )
2768 {
2769 wTorque= min( wTorque, ( WORD ) 127 );
2770 return wTorque;
2771 };
2772
2773
2774 BOOL TC_812::SetVelocity( DWORD velocity )
2775 {
2776 char cmd[ MaxString + 1 ];
2777
2778 dwVelocity= ( velocity < dwMaxVelocity ) ? velocity : dwMaxVelocity;
2779 sprintf( cmd, "%uSV%lu\r", nOnBoardId, dwVelocity );
2780 if ( R_OK != ExecuteCmd( cmd ) )
2781 return FALSE;
2782 sprintf( cmd, "%uCP\r", nOnBoardId );
2783 if ( R_OK != ExecuteCmd( cmd ) )
2784 return FALSE;
2785 return TRUE;
2786 };
2787
2788
2789 DWORD TC_812::GetVelocity( void )
2790 {
2791 dwVelocity= ( dwVelocity < dwMaxVelocity ) ? dwVelocity : dwMaxVelocity;
2792 return dwVelocity;
2793 };
2794
2795
2796 BOOL TC_812::SetAcceleration( DWORD acceleration )
2797 {
2798 char cmd[ MaxString + 1 ];
2799
2800 dwAcceleration= acceleration;
2801 sprintf( cmd, "%uSA%lu\r", nOnBoardId, dwAcceleration );
2802 if ( R_OK != ExecuteCmd( cmd ) )
2803 return FALSE;
2804 sprintf( cmd, "%uSD%lu\r", nOnBoardId, dwAcceleration );
2805 if ( R_OK != ExecuteCmd( cmd ) )
2806 return FALSE;
2807 sprintf( cmd, "%uCP\r", nOnBoardId );
2808 if ( R_OK != ExecuteCmd( cmd ) )
2809 return FALSE;
2810 return TRUE;
2811 };
2812
2813
2814 DWORD TC_812::GetAcceleration( void )
2815 {
2816 return dwAcceleration;
2817 };
2818
2819
2820 BOOL TC_812::SetLimit( DWORD limit )
2821 {
2822 char cmd[ MaxString + 1 ];
2823
2824 dwRemoveLimit= limit;
2825 sprintf( cmd, "%uLS%lu\r", nOnBoardId, dwRemoveLimit );
2826 if ( R_OK != ExecuteCmd( cmd ) )
2827 return FALSE;
2828 return TRUE;
2829 };
2830
2831
2832 BOOL TC_812::SetHome( void )
2833 {
2834 char cmd[ MaxString + 1 ];
2835
2836 // changing K-System
2837 TMotor::SetHome( );
2838 sprintf( cmd, "%uDH\r", nOnBoardId );
2839 if ( R_OK != ExecuteCmd( cmd ) )
2840 return FALSE;
2841 return TRUE;
2842 };
2843
2844
2845 WORD TC_812::GetStatus( void )
2846 {
2847 char buf[ MaxString + 1 ];
2848 char msg[ MaxString ];
2849 char *token;
2850 WORD _status;
2851
2852 sprintf( buf, "%uTS\r", nOnBoardId );
2853 switch ( ExecuteCmd( buf ) )
2854 {
2855 case R_OK:
2856 token= strtok( buf, "\n\3\r" );
2857 if ( !token )
2858 return FALSE;
2859 if ( ( token[ 1 ] - '0' ) != nOnBoardId )
2860 return FALSE;
2861 if ( token[ 2 ] != 'S' )
2862 return FALSE;
2863 if ( strlen( token ) < 6 )
2864 return FALSE;
2865 sscanf( &( token[ 3 ] ), "%u", &_status );
2866 return _status;
2867
2868 case R_TimeOut:
2869 sprintf( msg, "GetStatus: %s", buf );
2870 MessageBox( GetFocus( ), msg, "TimeOut MS", MBFAILURE );
2871 return -1;
2872
2873 case R_UnknownCmd:
2874 sprintf( msg, "GetStatus: %s", buf );
2875 MessageBox( GetFocus( ), msg, "Fehler", MBFAILURE );
2876 return -1;
2877
2878 default:
2879 return -1;
2880 }
2881 };
2882
2883
2884 BOOL TC_812::_GetPosition( long *position )
2885 {
2886 char buf[ MaxString ];
2887 char msg[ MaxString ];
2888 char *token;
2889
2890 sprintf( buf, "%uTP\r", nOnBoardId );
2891 switch ( ExecuteCmd( buf ) )
2892 {
2893 case R_OK:
2894 token= strtok( buf, "\n\3\r" );
2895 if ( !token )
2896 return FALSE;
2897 if ( ( token[ 1 ] - '0' ) != nOnBoardId )
2898 return FALSE;
2899 if ( token[ 2 ] != 'P' )
2900 return FALSE;
2901 sscanf( &( token[ 3 ] ), "%ld", position );
2902 return TRUE;
2903
2904 case R_TimeOut:
2905 sprintf( msg, "GetPosition: %s", buf );
2906 MessageBox( GetFocus( ), msg, "TimeOut MS", MBFAILURE );
2907 return FALSE;
2908
2909 case R_UnknownCmd:
2910 sprintf( msg, "GetPosition: %s", buf );
2911 MessageBox( GetFocus( ), msg, "Fehler", MBFAILURE );
2912 return FALSE;
2913
2914 default:
2915 return FALSE;
2916 }
2917 };
2918
2919
2920 BOOL TC_812::_GetFailure( long *failure )
2921 {
2922 char buf[ MaxString + 1 ];
2923 char msg[ MaxString ];
2924 char *token;
2925
2926 sprintf( buf, "%uTE\r", nOnBoardId );
2927 switch ( ExecuteCmd( buf ) )
2928 {
2929 case R_OK:
2930 token= strtok( buf, "\n\3\r" );
2931 if ( !token )
2932 return FALSE;
2933 if ( ( token[ 1 ] - '0' ) != nOnBoardId )
2934 return FALSE;
2935 if ( token[ 2 ] != 'E' )
2936 return FALSE;
2937 if ( strlen( token ) < 12 )
2938 {
2939 nWaitTicks += 2;
2940 return FALSE;
2941 }
2942 sscanf( &( token[ 3 ] ), "%ld", failure );
2943 return TRUE;
2944
2945 case R_TimeOut:
2946 sprintf( msg, "GetFailure: %s", buf );
2947 MessageBox( GetFocus( ), msg, "TimeOut MS", MBFAILURE );
2948 return FALSE;
2949
2950 case R_UnknownCmd:
2951 sprintf( msg, "GetFailure: %s", buf );
2952 MessageBox( GetFocus( ), msg, "Fehler", MBFAILURE );
2953 return FALSE;
2954
2955 default:
2956 return FALSE;
2957 }
2958 };
2959
2960
2961 BOOL TC_812::MoveRelative( long pos )
2962 {
2963 char cmd[ MaxString + 1 ];
2964
2965 sprintf( cmd, "%uMR%ld\r", nOnBoardId, pos );
2966 if ( R_OK == ExecuteCmd( cmd ) )
2967 return TRUE;
2968 return FALSE;
2969 };
2970
2971
2972 BOOL TC_812::MoveAbsolute( long pos )
2973 {
2974 char cmd[ MaxString + 1 ];
2975
2976 // Zusammensetzung des Motorkommandos "Move Absolute"
2977 // [boardID] MA [Position] [RETURN]
2978 sprintf( cmd, "%uMA%ld\r", nOnBoardId, pos );
2979 // Aufruf der Hardwarezugriffsfkt.
2980 // TC_812ISA::ExecuteCmd()
2981 if ( R_OK == ExecuteCmd( cmd ) )
2982 // bei korrekter Ausfuehrung des Kommandos: TRUE
2983 return TRUE;
2984 // wenn Fehler bei Kommandoausfuehrg.: FALSE
2985 return FALSE;
2986 };
2987
2988 //############################################################################
2989 //############### ISA Interface ##############################################
2990 //############################################################################
2991 //############################################################################
2992
2993 TC_812Controller::TC_812Controller(EDeviceType DeviceID, LPTSTR HardwareID, DeviceList* Devices)
2994 : Controller(C812,HardwareID,4),oDPRam(0),oFlag(0),oIn(0),oOut1(0),oOut2(0)
2995 {
2996 char* szDeviceName= Devices->GetFileName(DeviceID, HardwareID);
2997 if(!szDeviceName)
2998 {
2999 if(simulation_type == simulation_only)
3000 { //MsgBox bzgl. des fehlenden Treibers in der Simulation unterdrücken
3001 Hardware= new DummyIo(DeviceID, HardwareID, false);
3002 }
3003 else
3004 {
3005 Hardware= new DummyIo(DeviceID, HardwareID);
3006 }
3007 }
3008 else
3009 {
3010 Hardware= new HardwareIo(szDeviceName);
3011 }
3012 }
3013
3014 BOOL TC_812Controller::Check()
3015 {
3016 char buf[ MaxString ];
3017 int cnt= 60;
3018 int retval;
3019
3020 Put(oOut1,(BYTE)0x0D);
3021 Put(oOut1,(BYTE)0x0D);
3022
3023 do
3024 {
3025 BYTE inByte= 0;
3026
3027 DelayTime(4);
3028 inByte= Get(oIn);
3029 if(inByte == 0x0D)
3030 break;
3031 inByte= Get(oIn);
3032 if(inByte == 0x03)
3033 break;
3034 } while(--cnt);
3035
3036 if( !cnt )
3037 {
3038 sprintf(buf,"No Board present at address 0x%s !",HardwareID);
3039 MessageBox(GetFocus( ),buf,"C-812",MBSTOP);
3040 return(FALSE);
3041 }
3042
3043 strcpy(buf,"DM\r");
3044 retval= ExecuteCmd(buf);
3045 strcpy(buf,"EF\r");
3046 retval= ExecuteCmd(buf);
3047 if(retval != R_OK)
3048 {
3049 MessageBox(GetFocus(),buf,"C-812",MBFAILURE);
3050 return(FALSE);
3051 }
3052
3053 return(TRUE);
3054 }
3055
3056 char TC_812Controller::Get(DWORD addr)
3057 {
3058 char return_val= 0;
3059
3060 if ( simulation_type & 1 )
3061 {
3062 // case no_simulation: case test_simulation:
3063 // get the hardware generated return value
3064 Read(addr,(BYTE*)&return_val);
3065
3066 if ( simulation_type & 2 )
3067 {
3068 // case test_simulation:
3069 // inform driver if possible, simulated value is ignored
3070 if ( c812isa_get_callback )
3071 {
3072 char* p= (char*)addr;
3073 c812isa_get_callback(p, return_val);
3074
3075 }
3076 }
3077 }
3078 else
3079 {
3080 // case simulation_only:
3081 // let driver generate a simulated value
3082 if ( c812isa_get_callback )
3083 {
3084 char* p= (char*)addr;
3085 return_val= c812isa_get_callback(p,0);
3086 }
3087 }
3088
3089 return return_val;
3090 }
3091
3092 void TC_812Controller::Put(DWORD addr, BYTE data)
3093 {
3094 if ( simulation_type & 1 )
3095 {
3096 // case no_simulation: case test_simulation:
3097 // write the value to hardware
3098 Write(addr,data);
3099 }
3100 if ( simulation_type & 2 )
3101 {
3102 // case simulation_only: case test_simulation:
3103 // write the value to the simulation driver
3104 if ( c812isa_put_callback )
3105 {
3106 char* p= (char*)addr;
3107 c812isa_put_callback(p, data);
3108 }
3109 }
3110 }
3111
3112 int TC_812Controller::ExecuteCmd(LPTSTR pString)
3113 {
3114 int idx,cnt,retval= R_OK;
3115 char chr;
3116
3117 static BOOL bCmdActive= FALSE;
3118
3119 // bereits im Kommandomodus ? ja -> Fehler
3120 if(bCmdActive)
3121 return R_Failure;
3122
3123 // nun Umschalten in Kommandomodus
3124 bCmdActive= TRUE;
3125
3126 cnt= 50; // Anzahl der zulaessigen Wiederholungen
3127 // Wiederholen bis keine Daten mehr zu lesen
3128 while ((chr= GetChar()) != '\x0')
3129 {// maximale Anzahl der Wiederholungsversuche erreicht => timeout
3130 if(!cnt--)
3131 {
3132 // timeout aufgetreten
3133 strcpy(pString,"TimeOut read");
3134 bCmdActive= FALSE;
3135 retval= R_TimeOut; // Rueckgabewert R_TimeOut
3136 return retval;
3137 }
3138 }
3139
3140 // Befehls-String senden
3141 idx= 0;
3142 // solange Kommandostring noch nicht abgearbeitet
3143 while(pString[idx]!= 0)
3144 {
3145 // Zeichen des Kommando-Strings senden
3146 // Rueckgabe==0 ? d.h. Senden schlug fehl
3147 if(!PutChar(pString[idx]))
3148 {
3149 Delay(10); // 10 "delays" warten ??
3150 //Zeichensenden fehlgeschlagen ?
3151 if(!PutChar(pString[idx]))
3152 {
3153 // mgl.weise ex. noch auszulesendes Zeichen ?
3154 chr= GetChar();
3155 if(chr)
3156 continue; // falls ja: Sprung zum Anfang der While-Schleife
3157 // chr=0 -> Timeout beim Schreiben
3158 bCmdActive= FALSE;
3159 strcpy(pString,"TimeOut write");
3160 retval= R_TimeOut; // Rueckgabewert R_TimeOut
3161 return(retval);
3162 }
3163 }
3164 //naechstes Zeichen im Kommandostring
3165 idx++;
3166 }
3167
3168 // recieve Request (Warten auf Uebertragungsende -> 0x03 an lpIn)
3169 Delay(50);
3170 idx= 0;
3171 cnt= 250; // max. Wiederholungen bis TimeOut
3172
3173 while(idx < (20 * MaxString))
3174 {
3175 // Zeichen an lpIn auslesen
3176 chr= GetChar();
3177 if(!chr)
3178 {
3179 Delay(15);
3180 if(!cnt)
3181 { // Timeout beim Lesen
3182 MessageBox(GetFocus(),"TimeOut read","C-812",MBINFO);
3183 // strcpy(pString,"TimeOut read");
3184 bCmdActive= FALSE;
3185 // bControlBoardOk= FALSE;
3186 retval= R_TimeOut; // Rueckgabewert R_TimeOut
3187 return retval;
3188 }
3189 if((cnt--) && (idx == 0))
3190 continue; // zum Anfang der While-Schleife: auf den Request warten
3191 if(pString[idx-1] == '\x3')
3192 break; // Ende der Uebertragung erreicht
3193 continue; // zum Anfang der While-Schleife: auf den Request warten
3194 }
3195 // ausgelesene Zeichen an lpIn zu String zusammenfuegen
3196 pString[idx++]= chr;
3197 }
3198
3199 // Nulltermierung des Strings
3200 pString[idx]= '\x0';
3201 // Kommandomodus verlassen
3202 bCmdActive= FALSE;
3203
3204 // Fehlernachricht von Karten empfangen ?
3205 if(pString[0] == '?')
3206 {
3207 retval= R_Failure; // Rueckgabewert R_Failure
3208 return retval;
3209 }
3210
3211 if(!cnt)
3212 {
3213 retval= R_Failure; // Rueckgabewert R_Failure
3214 return retval;
3215 }
3216
3217 return R_OK;
3218 }
3219
3220 int TC_812Controller::PutChar(const char c)
3221 {
3222 int time1,time2;
3223
3224 Delay(3); // wozu ????
3225 // solange Bit 0 (Busy-Flag) an Adresse lpFlag gesetzt (=1)
3226 // oder time1 > 0 wird die Schleife abgearbeitet (gewartet)
3227 // Timeout ist aufgetreten falls time1=0
3228 BYTE inByte= Get(oFlag);
3229 for(time1= 30000;(inByte & 0x01) && time1; time1--)
3230 {
3231 inByte= Get(oFlag);
3232 }
3233
3234 // Test ob Timeout ( time1=0) aufgetreten
3235 // falls nicht (time1>0) und damit Bit 0 (Busy-Flag) an lpFlag=0
3236 if( time1 ) //time
3237 {
3238 Put(oOut1,(BYTE)c); // write data
3239 Delay( 3 ); // Verzoegerung
3240 Put(oOut2,(BYTE)c); // generate internal signal
3241 }
3242
3243 // Warten bis Controller wieder schreibbereit
3244 // (Bit 0 (Busy-Flag) von lpFlag= 0)
3245 inByte= Get(oFlag);
3246 for(time2= 30000; (inByte & 0x00) && time2; time2--)
3247 {
3248 inByte= Get(oFlag);
3249 }
3250 Delay(3); // Verzoegerung, wozu ???
3251
3252 // Returnwert 0=timeout, sonst OK
3253 return time1;
3254 }
3255
3256 char TC_812Controller::GetChar(void)
3257 {
3258 char chr= 0;
3259
3260 Delay( 1 ); // 1
3261 // Wenn Bit 1 gesetzt ist, so liegen Daten von der Steuerung an.
3262 BYTE inByte= Get(oFlag);
3263 if(!(inByte & 0x02))
3264 return(0);
3265
3266 inByte= Get(oIn);
3267 chr= (char)inByte;
3268
3269 Delay( 2 ); // wozu ???
3270 return chr;
3271 }
3272 // ph
3273 /////////////////////////////////////////////////////////////////
3274
3275
3276 TC_812ISA::TC_812ISA( void ) : TC_812( )
3277 {
3278 char buf[ MaxString ];
3279 char Ident[ MaxString ];
3280
3281 sprintf( Ident, "motor%d", nId );
3282 GetPrivateProfileString( Ident, "RamAddr", "0xD0000", buf, MaxString,
3283 (LPSTR)GetHWFile( ) );
3284 sscanf( buf, "%x", &dwBaseAddr );
3285
3286 //initialisieren des zugehörigen Controller-Objekts
3287 Hardware= dynamic_cast<TC_812Controller*>(GetController(C812,buf,&MotorControllers,&MotorDrivers));
3288 // Member des Controller-Objects initialisieren (ggf. schon initialisiert)
3289
3290 Hardware->oOut1= 0x03FC;
3291 Hardware->oOut2= 0x03FF;
3292 Hardware->oFlag= 0x0800;
3293 Hardware->oIn= 0x03FE;
3294 Hardware->oDPRam= 0;
3295 //ph
3296
3297 nWaitTicks= 5;
3298 };
3299
3300
3301 BOOL TC_812ISA::CheckBoardOk( void )
3302 {
3303 char buf[ MaxString ];
3304 int cnt= 60;
3305 int retval;
3306
3307 Hardware->Put(Hardware->oOut1,(BYTE)0x0D);
3308 Hardware->Put(Hardware->oOut1,(BYTE)0x0D);
3309 do
3310 {
3311 BYTE inByte= 0;
3312
3313 DelayTime(4);
3314 inByte= Hardware->Get(Hardware->oIn);
3315 if(inByte == 0x0D)
3316 break;
3317 inByte= Hardware->Get(Hardware->oIn);
3318 if(inByte == 0x03)
3319 break;
3320 } while(--cnt);
3321
3322 if ( !cnt )
3323 {
3324 //hp sprintf( buf, "No C-812 Board present at address %X !", dwBaseAddr );
3325 //hp MessageBox( GetFocus( ), buf, "C-812", MBSTOP );
3326 #ifndef TESTLAUF
3327
3328 return FALSE;
3329 #endif
3330
3331 }
3332 bControlBoardOk= TRUE;
3333
3334 strcpy( buf, "DM\r" );
3335 retval= ExecuteCmd( buf );
3336 if ( retval != R_OK )
3337 {
3338 MessageBox( GetFocus( ), buf, "C-812", MBFAILURE );
3339 #ifndef TESTLAUF
3340
3341 bControlBoardOk= FALSE;
3342 return FALSE;
3343 #endif
3344 }
3345
3346 strcpy( buf, "EF\r" );
3347 retval= ExecuteCmd( buf );
3348 if ( retval != R_OK )
3349 {
3350 MessageBox( GetFocus( ), buf, "C-812", MBFAILURE );
3351 #ifndef TESTLAUF
3352
3353 bControlBoardOk= FALSE;
3354 return FALSE;
3355 #endif
3356 }
3357 return TRUE;
3358 };
3359
3360
3361 BOOL TC_812ISA::SetHome( void )
3362 {
3363
3364 char cmd[ MaxString+1 ];
3365
3366 // changing K-System
3367 TMotor::SetHome( );
3368 sprintf( cmd,"%uDH\r",nOnBoardId );
3369 if(R_OK != ExecuteCmd(cmd))
3370 return FALSE;
3371
3372 int addr= 0x010A + nOnBoardId - 1;
3373 Hardware->Put(Hardware->oDPRam + addr,(BYTE)0x00);
3374 Hardware->Put(Hardware->oDPRam + addr + 0x0004,(BYTE)0x00);
3375 Hardware->Put(Hardware->oDPRam + addr + 0x0008,(BYTE)0x00);
3376 Hardware->Put(Hardware->oDPRam + addr + 0x000C,(BYTE)0x00);
3377 //ph
3378
3379 return TRUE;
3380 };
3381
3382
3383 BOOL TC_812ISA::IsMoveFinish( void )
3384 {
3385
3386 long fail1, fail2;
3387
3388 _GetFailure( &fail1 );
3389 if ( labs( fail1 ) > (long)wDeathBand )
3390 {
3391 return FALSE;
3392 }
3393 else
3394 {
3395 // der Positionsfehler ist kleiner als Deathband, d.h. es kann sein,
3396 // das der Controller mit der aktuellen Position zufrieden ist (dicht genug
3397 // an der Sollposition)
3398 // um sicher zu gehen warten wie einen Moment; wenn der Positionsfehler dann
3399 // unverändert ist, steht der Motor
3400 DelayTime( 100 );
3401 _GetFailure( &fail2 );
3402 if ( fail1 - fail2 )
3403 {
3404 return FALSE;
3405 }
3406 else
3407 {
3408 return TRUE;
3409 }
3410 }
3411
3412 };
3413
3414
3415 BOOL TC_812ISA::_GetPosition( long *position )
3416 {
3417 tpos data;
3418 int addr= 0x010A + nOnBoardId - 1;
3419
3420 data.byte[ 0 ]= Hardware->Get(Hardware->oDPRam + addr);
3421 data.byte[ 1 ]= Hardware->Get(Hardware->oDPRam + addr + 0x0004);
3422 data.byte[ 2 ]= Hardware->Get(Hardware->oDPRam + addr + 0x0008);
3423 data.byte[ 3 ]= Hardware->Get(Hardware->oDPRam + addr + 0x000C);
3424 *position= data.pos;
3425 return TRUE;
3426 };
3427
3428
3429 BOOL TC_812ISA::_GetFailure( long *failure )
3430 {
3431 tpos data;
3432 int addr= 0x006C + nOnBoardId - 1;
3433
3434 data.byte[ 0 ]= Hardware->Get(Hardware->oDPRam + addr);
3435 data.byte[ 1 ]= Hardware->Get(Hardware->oDPRam + addr + 0x0004);
3436 data.byte[ 2 ]= Hardware->Get(Hardware->oDPRam + addr + 0x0008);
3437 data.byte[ 3 ]= Hardware->Get(Hardware->oDPRam + addr + 0x000C);
3438 *failure= data.pos;
3439 return TRUE;
3440
3441 };
3442
3443
3444 int TC_812ISA::ExecuteCmd( char *pString )
3445 {
3446 #ifndef TESTLAUF
3447 int idx, cnt, retval= R_OK;
3448 char chr;
3449 #endif
3450
3451 static BOOL bCmdActive= FALSE;
3452
3453 // DC-Controller-Karte OK ?
3454 if ( !bControlBoardOk )
3455 return 0;
3456 // bereits im Kommandomodus ? ja -> Fehler
3457 if ( bCmdActive )
3458 return R_Failure;
3459 // nun Umschalten in Kommandomodus
3460 bCmdActive= TRUE;
3461
3462 #ifndef TESTLAUF
3463
3464 cnt= 250; // Anzahl der zulaessigen Wiederholungen
3465 // Wiederholen bis keine Daten mehr zu lesen
3466
3467 while ( ( chr= GetChar( ) ) != '\x0' )
3468 {
3469 // maximale Anzahl der Wiederholungsversuche erreicht => timeout
3470 if ( !cnt-- )
3471 {
3472 // timeout aufgetreten
3473 strcpy( pString, "TimeOut read" );
3474 bControlBoardOk= FALSE;
3475 bCmdActive= FALSE;
3476 retval= R_TimeOut; // Rueckgabewert R_TimeOut
3477 goto Exit;
3478 }
3479 }
3480
3481 #endif
3482
3483 // Befehls-String senden
3484 #ifdef WriteLog
3489 #endif
3490
3491 #ifndef TESTLAUF
3492
3493 idx= 0;
3494 // solange Kommandostring noch nicht abgearbeitet
3495
3496 while ( pString[ idx ] != 0 )
3497 {
3498 // Zeichen des Kommando-Strings senden
3499 // Rueckgabe==0 ? d.h. Senden schlug fehl
3500 if ( !PutChar( pString[ idx ] ) )
3501 {
3502 Delay( 10 ); // 10 "delays" warten ??
3503 //Zeichensenden fehlgeschlagen ?
3504 if ( !PutChar( pString[ idx ] ) )
3505 {
3506 // mgl.weise ex. noch auszulesendes Zeichen ?
3507 chr= GetChar( );
3508 if ( chr )
3509 continue; // falls ja: Sprung zum Anfang der While-Schleife
3510 // chr=0 -> Timeout beim Schreiben
3511 bCmdActive= FALSE;
3512 bControlBoardOk= FALSE;
3513 strcpy( pString, "TimeOut write" );
3514 retval= R_TimeOut; // Rueckgabewert R_TimeOut
3515 goto Exit;
3516 }
3517 }
3518 //naechstes Zeichen im Kommandostring
3519 idx++;
3520 }
3521
3522 #endif
3523
3524 #ifdef WriteLog
3527 #endif
3528
3529 // recieve Request (Warten auf Uebertragungsende -> 0x03 an lpIn)
3530 Delay( 50 );
3531 #ifndef TESTLAUF
3532
3533 idx= 0;
3534 cnt= 500; // max. Wiederholungen bis TimeOut
3535
3536 while ( idx < ( 20 * MaxString ) )
3537 {
3538 // Zeichen an lpIn auslesen
3539 chr= GetChar( );
3540 if ( !chr )
3541 {
3542 Delay( 15 );
3543 if ( !cnt )
3544 { // Timeout beim Lesen
3545 MessageBox( GetFocus( ), "TimeOut read", "C-812", MBINFO );
3546 // strcpy(pString,"TimeOut read");
3547 bCmdActive= FALSE;
3548 // bControlBoardOk= FALSE;
3549 retval= R_TimeOut; // Rueckgabewert R_TimeOut
3550 goto Exit;
3551 }
3552 if ( ( cnt-- ) && ( idx == 0 ) )
3553 continue; // zum Anfang der While-Schleife: auf den Request warten
3554 if ( pString[ idx - 1 ] == '\x3' )
3555 break; // Ende der Uebertragung erreicht
3556 continue; // zum Anfang der While-Schleife: auf den Request warten
3557 }
3558 // ausgelesene Zeichen an lpIn zu String zusammenfuegen
3559
3560
3561 pString[ idx++ ]= chr;
3562 }
3563
3564 // Nulltermierung des Strings
3565 pString[ idx ]= '\x0';
3566 // Kommandomodus verlassen
3567 bCmdActive= FALSE;
3568 // Fehlernachricht von Karten empfangen ?
3569 if ( pString[ 0 ] == '?' )
3570 {
3571 retval= R_Failure; // Rueckgabewert R_Failure
3572 goto Exit;
3573 }
3574 if ( !cnt )
3575 {
3576 retval= R_Failure; // Rueckgabewert R_Failure
3577 goto Exit;
3578 }
3579 #endif
3580
3581 Exit:
3582
3583 #ifdef WriteLog
3587 #endif
3588
3589 #ifndef TESTLAUF
3590
3591 return retval; // Rueckgabe des jeweiligen Rueckgabewerts
3597 #endif
3598
3599 };
3600
3601
3602 int TC_812ISA::PutChar( const char c )
3603 {
3604 int time1, time2;
3605
3606 Delay( 3 ); // wozu ????
3607 // solange Bit 0 (Busy-Flag) an Adresse lpFlag gesetzt (=1)
3608 // oder time1 > 0 wird die Schleife abgearbeitet (gewartet)
3609 // Timeout ist aufgetreten falls time1=0
3610 BYTE inByte= Hardware->Get(Hardware->oFlag);
3611 for( time1= 300; (inByte & 0x01) && time1; time1--)
3612 {
3613 Delay(1); //hp absolute Zeiteinheit warten
3614 inByte= Hardware->Get(Hardware->oFlag);
3615 }
3616
3617 // Test ob Timeout ( time1=0) aufgetreten
3618 // falls nicht (time1>0) und damit Bit 0 (Busy-Flag) an lpFlag=0
3619 if( time1 ) //time
3620 {
3621 Hardware->Put(Hardware->oOut1,(BYTE)c); // write data
3622 Delay( 3 ); // Verzoegerung
3623 Hardware->Put(Hardware->oOut2,(BYTE)c); // generate internal signal
3624 }
3625 else
3626 return(0); //hp abbrechen, da weitere Versuche sinnlos
3627 // Warten bis Controller wieder schreibbereit
3628 // (Bit 0 (Busy-Flag) von lpFlag= 0)
3629 inByte= Hardware->Get(Hardware->oFlag);
3630 for( time2= 300; (inByte & 0x00) && time2; time2--)
3631 {
3632 Delay(1); //hp absolute Zeiteinheit warten
3633 inByte= Hardware->Get(Hardware->oFlag);
3634 }
3635 Delay( 3 ); // Verzoegerung, wozu ???
3636 // Returnwert 0=timeout, sonst OK
3637 return time1;
3638 //ph
3639 };
3640
3641
3642 char TC_812ISA::GetChar( void )
3643 {
3644 char chr= 0;
3645
3646 Delay( 1 ); // 1
3647 // Wenn Bit 1 gesetzt ist, so liegen Daten von der Steuerung an.
3648 BYTE inByte= Hardware->Get(Hardware->oFlag);
3649 if(!(inByte & 0x02))
3650 return(0);
3651
3652 inByte= Hardware->Get(Hardware->oIn);
3653 chr= (char)inByte;
3654
3655 /*if ( !( C812ISA_Get( lpFlag ) & 0x02 ) ) // text ready-flag
3656 return 0; // no data available
3657 chr= C812ISA_Get( lpIn ); // read data
3658 */
3659 //ph
3660 Delay( 2 ); // wozu ???
3661 return chr;
3662 };
3663
3664
3665
3666
3667 //############################################################################
3668 //################### Interface ##############################################
3669 //############################################################################
3670 //############################################################################
3671
3672 TC_832::TC_832( void ) : TDC_Drive() ,CmdRegister(0) ,DataRegister(1)
3673 {
3674 char Ident[ MaxString ], buf[ MaxString ];
3675
3676 sprintf( Ident, "motor%d", nId );
3677
3678 GetPrivateProfileString( Ident, "IOAddr", "0x210", (LPSTR)buf, MaxString,
3679 GetHWFile( ) );
3680 sscanf( buf, "%x", &wBaseAddr );
3681
3682 nOnBoardId= GetPrivateProfileInt( Ident, "BoardId", 0, GetHWFile( ) );
3683
3684 wKI= (WORD)GetPrivateProfileInt( Ident, "IntegralGain", 10, GetHWFile( ) );
3685 wKL= (WORD)GetPrivateProfileInt( Ident, "IntegralLimit", 10, GetHWFile( ) );
3686 wKP= (WORD)GetPrivateProfileInt( Ident, "Gain", 100, GetHWFile( ) );
3687 wKD= (WORD)GetPrivateProfileInt( Ident, "DynamicGain", 37, GetHWFile( ) );
3688
3689 cConfig= 0x80;
3690 if ( GetPrivateProfileInt( Ident, "DifferentialEncoder", 0, GetHWFile( ) ) )
3691 {
3692 if ( 0 == nOnBoardId )
3693 cConfig |= 0x10;
3694 else
3695 cConfig |= 0x20;
3696 }
3697 if ( GetPrivateProfileInt( Ident, "EnableInterrupts", 0, GetHWFile( ) ) )
3698 {
3699 cConfig |= 0x40;
3700 }
3701 wSample= 0x0100; // 512 ´s
3702
3703 // initialisieren des zugehörigen Controller-Objekts (in buf steht wBaseAddr)
3704 Hardware= dynamic_cast<TC_832Controller*>(GetController(C832,buf,&MotorControllers,&MotorDrivers,
3705 &ControllerIndex));
3706 //Member des Controller-Objects initialisieren (ggf. schon initialisiert)
3707 Hardware->activeConfig= cConfig; // Konfigurations Register
3708 Hardware->activeDrive= nOnBoardId;
3709 Hardware->baddr= 0; //BaseAddr ist im Treiber eingestellt -> hier nur Offsets
3710 baddr= 0; //BaseAddr ist im Treiber eingestellt -> hier nur Offsets
3711 raddr= (cConfig | (nOnBoardId << 1));
3712 //ph
3713
3714 }
3715 ;
3716
3717
3718 BOOL TC_832::Reset( void )
3719 {
3720 // Reset setzt Position auf Null, falls Initialisierung nicht eindeutig genug
3721 // sollte hier erst Position gelesen werden und dann der Reset ausgefuehrt
3722 // werden.
3723 // changing K-System
3724
3725 Hardware->UpdateController(cConfig,nOnBoardId);
3726 Drive628( RESET, 0, 0 );
3727 Drive628( RSTI, 0, 0 );
3728 Drive628( MSKI, 0, 0 );
3729 return TRUE;
3730 };
3731
3732
3733 void TC_832::OptimizingDlg( void )
3734 {
3735 TModalDlg* dlg;
3736
3737 dlg= (TOptimizeDC_832Dlg *) new TOptimizeDC_832Dlg( );
3738 if ( dlg ) dlg->ExecuteDialog( GetFrameHandle( ) );
3739 _FREEOBJ(dlg);
3740 };
3741
3742
3743 BOOL TC_832:: ActivateFilterParameters( void )
3744 {
3745
3746 Hardware->UpdateController(cConfig,nOnBoardId);
3747 // Static Gain entspricht dem P-Term
3748 Drive628( LFIL, wSample | LD_KP, wKP );
3749 // Dynamic Gain entspricht dem D-Term
3750 Drive628( LFIL, wSample | LD_KD, wKD );
3751 // Integral Gain entspricht dem I-Term
3752 Drive628( LFIL, wSample | LD_KI, wKI );
3753 // Integral-Limit entspricht dem L-Term
3754 Drive628( LFIL, wSample | LD_IL, wKL );
3755 Drive628( UDF, 0, 0 );
3756 SetVelocity( dwMaxVelocity );
3757 SetAcceleration( dwAcceleration );
3758 GetSpeed( );
3759 //StartLimitWatch();
3760 return TRUE;
3761 };
3762
3763
3764 int TC_832::SaveSettings( int LastSave )
3765 {
3766 char buf[ MaxString ];
3767 char Ident[ MaxString ];
3768
3769 Hardware->UpdateController(cConfig,nOnBoardId);
3770 sprintf( Ident, "motor%d", nId );
3771 sprintf( buf, "%u", wKD );
3772 WritePrivateProfileString( Ident, "DynamicGain", buf, GetHWFile( ) );
3773 sprintf( buf, "%u", wKP );
3774 WritePrivateProfileString( Ident, "Gain", buf, GetHWFile( ) );
3775 sprintf( buf, "%u", wKI );
3776 WritePrivateProfileString( Ident, "IntegralGain", buf, GetHWFile( ) );
3777 sprintf( buf, "%u", wKL );
3778 WritePrivateProfileString( Ident, "IntegralLimit", buf, GetHWFile( ) );
3779 sprintf( buf, "%lu", dwMaxVelocity );
3780 WritePrivateProfileString( Ident, "MaxVelocity", buf, GetHWFile( ) );
3781 sprintf( buf, "%lu", dwAcceleration );
3782 WritePrivateProfileString( Ident, "Acceleration", buf, GetHWFile( ) );
3783 sprintf( buf, "%lu", dwVelocity );
3784 WritePrivateProfileString( Ident, "Velocity", buf, GetHWFile( ) );
3785 return TDC_Drive::SaveSettings( LastSave );
3786 };
3787
3788
3789 BOOL TC_832::SetHome( void )
3790 {
3791
3792
3793 Hardware->UpdateController(cConfig,nOnBoardId);
3794
3795 TMotor::SetHome( );
3796 // changing K-System
3797 Drive628( DFH, 0, 0 );
3798 Drive628( LTRJ, LD_POS, 0 );
3799 Drive628( STT, 0, 0 );
3800 return TRUE;
3801 };
3802
3803
3804 BOOL TC_832::ActivateDrive( void )
3805 {
3806 long pos;
3807
3808 Hardware->UpdateController(cConfig,nOnBoardId);
3809 Drive628( UDF, 0, 0 );
3810 _GetPosition( &pos );
3811 Drive628( LTRJ, LD_POS, pos );
3812 Drive628( STT, 0, 0 );
3813 return TRUE;
3814 };
3815
3816
3817 BOOL TC_832::StopDrive( BOOL bOffOn ) // Kullmann, Reinecker (08.08.02) Parameter geändert int -> BOOL
3818 {
3819
3820 Hardware->UpdateController(cConfig,nOnBoardId);
3821
3822 WORD ctr= 0x0400; // Stop smoothly --> programming manual (page 29)
3823
3824 Drive628( LTRJ, ctr, 0 );
3825 Drive628( STT, 0, 0 );
3826 while ( !IsMoveFinish( ) )
3827 DelayTime( 4 );
3828 if ( !bOffOn )
3829 return TRUE;
3830 Drive628( UDF, 0, 0 );
3831 Drive628( STT, 0, 0 );
3832 return TRUE;
3833 };
3834
3835
3836 BOOL TC_832::StartLimitWatch( void )
3837 {
3838 Hardware->UpdateController(cConfig,nOnBoardId);
3839
3840 if ( bLimitWatchActive )
3841 return FALSE;
3842 nEvent= timeSetEvent( 150,1,( LPTIMECALLBACK ) &TC_832Controller::LimitWatch,ControllerIndex,
3843 TIME_PERIODIC );
3844 bLimitWatchActive= TRUE;
3845 return TRUE;
3846 };
3847
3848
3849 BOOL TC_832::StopLimitWatch( void )
3850 {
3851
3852 Hardware->UpdateController(cConfig,nOnBoardId);
3853
3854 if ( !bLimitWatchActive )
3855 return FALSE;
3856 timeKillEvent( nEvent );
3857 bLimitWatchActive= FALSE;
3858 return TRUE;
3859 };
3860
3861 BOOL TC_832::IsLimitHit( void )
3862 {
3863
3864 Hardware->UpdateController(cConfig,nOnBoardId);
3865
3866 BYTE status;
3867 // Interrupt-Register
3868 Hardware->LM628Ready(CmdRegister,nOnBoardId);
3869
3870 Hardware->Put(CmdRegister,cConfig | 0x07 );
3871 status= Hardware->Get(DataRegister);
3872
3873 if( status & ( nOnBoardId+1 ) )
3874 {
3875 Drive628( LTRJ,0x400,0 ); // stop appruptly
3876 Drive628( STT,0,0 );
3877 if( bUpwards )
3878 Drive628( LTRJ,LD_RPOS,-labs( dwRemoveLimit ) );
3879 else
3880 Drive628( LTRJ,LD_RPOS,labs( dwRemoveLimit ) );
3881 bUpwards= !bUpwards;
3882 Drive628( STT,0,0 );
3883 while( !IsMoveFinish( ) )
3884 DelayTime( 10 );
3885 DelayTime( 100 );
3886 Hardware->LM628Ready(CmdRegister,nOnBoardId);
3887
3888 Hardware->Put(CmdRegister,cConfig | 0x07 );
3889 status= Hardware->Get(DataRegister);
3890 Hardware->Put(DataRegister,status & ~( nOnBoardId+1 ) );
3891 DelayTime( 10 );
3892 Hardware->bLimitHit= bRangeHit= TRUE;
3893 return TRUE;
3894 }
3895 Hardware->bLimitHit= FALSE;
3896 return FALSE;
3897
3898
3899 };
3900
3901
3902 BOOL TC_832::IsIndexArrived( void )
3903 {
3904
3905 Hardware->UpdateController(cConfig,nOnBoardId);
3906
3907 long ipos, pos;
3908
3909 if ( IsLimitHit( ) )
3910 {
3911 Drive628( RSTI, 0, 0 );
3912 Drive628( MSKI, 0, 0 );
3913 Drive628( STT, 0, 0 );
3914 if ( bIndexLine )
3915 {
3916 Drive628( SIP, 0, 0 );
3917 Drive628( LTRJ, LD_RPOS, 400000000l );
3918 bUpwards= TRUE;
3919 Drive628( STT, 0, 0 );
3920 return FALSE;
3921 }
3922 return TRUE;
3923 }
3924 if ( bIndexLine && bIndexDetected && IsMoveFinish( ) )
3925 return TRUE;
3926 if ( !bIndexLine && bRangeHit && IsMoveFinish( ) )
3927 return TRUE;
3928 if ( !bRangeHit && bMoveFirstToLimit )
3929 return FALSE;
3930 if ( 0x08 & Drive628( RDSIGS, 0, 0 ) )
3931 {
3932 // stop drive
3933 Drive628( LTRJ, 0x400, 0 );
3934 Drive628( STT, 0, 0 );
3935 bIndexDetected= TRUE;
3936 Drive628( RSTI, 0, 0 );
3937 Drive628( MSKI, 0, 0 );
3938 ipos= Drive628( RDIP, 0, 0 );
3939 while ( !IsMoveFinish( ) )
3940 /* wait until finish */;
3941 pos= Drive628( RDRP, 0, 0 );
3942 bUpwards= ( ipos > pos );
3943 Drive628( LTRJ, LD_POS, ipos );
3944 Drive628( STT, 0, 0 );
3945 Delay( 150 );
3946 return FALSE;
3947 }
3948 return FALSE;
3949 };
3950
3951
3952 BOOL TC_832::StartToIndex( long &oldPos )
3953 {
3954
3955 Hardware->UpdateController(cConfig,nOnBoardId);
3956
3957 SetSpeed( 10000.0 );
3958 bIndexDetected= FALSE;
3959 bRangeHit= FALSE;
3960 Hardware->bLimitHit= FALSE;
3961 lDeltaPosition= 0;
3962 SetCalibrationState( FALSE );
3963 SetCorrectionState( FALSE );
3964 lPosition= oldPos= Drive628( RDRP, 0, 0 );
3965 bUpwards= FALSE;
3966 if ( !bMoveFirstToLimit && bIndexLine )
3967 {
3968 Drive628( RSTI, 0, 0 );
3969 Drive628( SIP, 0, 0 );
3970 }
3971 Drive628( LTRJ, LD_RPOS, -400000000l );
3972 Drive628( STT, 0, 0 );
3973 // Die Motoren werden in Bewegung gesetzt
3974 // Erreichen der Stillstands-Position
3975 DelayTime( 150 );
3976 return TRUE;
3977 };
3978
3979
3980 BOOL TC_832::SetVelocity( DWORD velocity )
3981 {
3982 Hardware->UpdateController(cConfig,nOnBoardId);
3983
3984 dwVelocity= ( velocity < dwMaxVelocity ) ? velocity : dwMaxVelocity;
3985 if ( R_OK != Drive628( LTRJ, 0x0008, dwVelocity ) )
3986 return FALSE;
3987 return TRUE;
3988 };
3989
3990
3991 DWORD TC_832::GetVelocity( void )
3992 {
3993
3994 Hardware->UpdateController(cConfig,nOnBoardId);
3995
3996 dwVelocity= ( dwVelocity < dwMaxVelocity ) ? dwVelocity : dwMaxVelocity;
3997 return dwVelocity;
3998 };
3999
4000
4001 BOOL TC_832::SetAcceleration( DWORD acceleration )
4002 {
4003
4004 Hardware->UpdateController(cConfig,nOnBoardId);
4005
4006 dwAcceleration= acceleration;
4007 if ( R_OK != Drive628( LTRJ, 0x0020, dwAcceleration ) )
4008 return FALSE;
4009 return TRUE;
4010 };
4011
4012
4013 DWORD TC_832::GetAcceleration( void )
4014 {
4015 Hardware->UpdateController(cConfig,nOnBoardId);
4016
4017 return dwAcceleration;
4018 };
4019
4020
4021 BOOL TC_832::SetLimit( DWORD limit )
4022 {
4023
4024 Hardware->UpdateController(cConfig,nOnBoardId);
4025
4026 dwRemoveLimit= limit;
4027 return TRUE;
4028 };
4029
4030
4031 WORD TC_832::GetStatus( void )
4032 {
4033
4034 Hardware->UpdateController(cConfig,nOnBoardId);
4035
4036 return ( WORD ) Drive628( RDSTAT, 0, 0 );
4037 };
4038
4039
4040 BOOL TC_832::_GetPosition( long *position )
4041 {
4042
4043 Hardware->UpdateController(cConfig,nOnBoardId);
4044
4045 *position= Drive628( RDRP, 0, 0 );
4046 return TRUE;
4047 };
4048
4049
4050 BOOL TC_832::_GetFailure( long *failure )
4051 {
4052
4053 Hardware->UpdateController(cConfig,nOnBoardId);
4054
4055 *failure= ( Drive628( RDRP, 0, 0 ) - Drive628( RDDP, 0, 0 ) );
4056 return TRUE;
4057 };
4058
4059
4060 BOOL TC_832::MoveRelative( long position )
4061 {
4062
4063 Hardware->UpdateController(cConfig,nOnBoardId);
4064
4065 long rpos;
4066 rpos= Drive628( RDRP, 0, 0 );
4067 rpos += position;
4068 Drive628( LTRJ, LD_POS, rpos );
4069 Drive628( STT, 0, 0 );
4070 return TRUE;
4071 };
4072
4073
4074 BOOL TC_832::MoveAbsolute( long pos )
4075 {
4076
4077 Hardware->UpdateController(cConfig,nOnBoardId);
4078
4079 // Aufruf der Hardwarezugriffsfkt. TC_832::Drive628 und Drive628c
4080 // mit den Motorkommandos LTRJ und STT
4081 // LTRJ -> Load Trajectory Parameters mit Pos.Parameter
4082 // (weitere Parameter z.B. pos, velo, accel, operation mode)
4083 // STT -> Start Motion Control: (execute selected Trajectory) )
4084 Drive628( LTRJ, LD_POS, pos );
4085 Drive628( STT, 0, 0 );
4086 // Rueckgabewert immer TRUE (Wieso ?)
4087 return TRUE;
4088 };
4089
4090
4091 BOOL TC_832::IsMoveFinish( void )
4092 {
4093 Hardware->UpdateController(cConfig,nOnBoardId);
4094
4095 DelayTime( 5 );
4096 if ( Drive628( RDSIGS, 0, 0 ) & ON_TARGET )
4097 return TRUE;
4098 else
4099 return FALSE;
4100 };
4101
4102
4103 BOOL TC_832::CheckBoardOk( )
4104 {
4105 Hardware->UpdateController(cConfig,nOnBoardId);
4106
4107 bControlBoardOk= FALSE;
4108
4109 #ifndef TESTLAUF
4110 Hardware->Put(CmdRegister,cConfig | ( nOnBoardId << 1 ) );
4111 if(Hardware->Get(DataRegister) == 0xFF )
4112 return FALSE;
4113 #endif
4114
4115
4116 bControlBoardOk= TRUE;
4117 return TRUE;
4118 };
4119
4120
4121 BOOL TC_832::ExecuteCmd( LPSTR )
4122 {
4123
4124 Hardware->UpdateController(cConfig,nOnBoardId);
4125 return R_OK;
4126 };
4127
4128
4129 long TC_832::Drive628( BYTE cmd, WORD ctrl_word, long param )
4130 {
4131
4132 Hardware->UpdateController(cConfig,nOnBoardId);
4133
4134 #ifdef WriteLog
4147 #endif
4148
4149 return(Hardware->Drive628c(cmd, ctrl_word, param,baddr,raddr,nOnBoardId));
4150
4151 };
4152
4153 /////////////////////////////////////////////////////////////////
4154 TC_832Controller::TC_832Controller(EDeviceType DeviceID, LPTSTR HardwareID, DeviceList* Devices)
4155 : Controller(C832,HardwareID,2), bIdle(FALSE), bIOActive(FALSE),
4156 bLimitHit(FALSE), activeConfig(0), activeDrive(0), baddr(0),
4157 CmdRegister(0),DataRegister(1)
4158 {
4159 char* szDeviceName= Devices->GetFileName(DeviceID, HardwareID);
4160 if(!szDeviceName)
4161 {
4162 if(simulation_type == simulation_only)
4163 { //MsgBox bzgl. des fehlenden Treibers in der Simulation unterdrücken
4164 Hardware= new DummyIo(DeviceID, HardwareID, false);
4165 }
4166 else
4167 {
4168 Hardware= new DummyIo(DeviceID, HardwareID);
4169 }
4170 }
4171 else
4172 {
4173 Hardware= new HardwareIo(szDeviceName);
4174 }
4175
4176 sscanf(HardwareID,"%x",&dwSimBasePort);
4177 }
4178
4179 BOOL TC_832Controller::Check()
4180 {
4181 Put(CmdRegister,activeConfig | (activeDrive << 1));
4182 if(Get(DataRegister) == 0xFF )
4183 return(FALSE);
4184
4185 return(TRUE);
4186 }
4187
4188 void TC_832Controller::UpdateController(BYTE _activeConfig, WORD _activeDrive)
4189 {
4190 activeConfig= _activeConfig;
4191 activeDrive= _activeDrive;
4192 }
4193
4194 //ap
4195 void CALLBACK TC_832Controller::LimitWatch(UINT IDEvent,UINT,DWORD dwUser,DWORD,DWORD)
4196 // UINT IDEvent; identifies timer event
4197 // UINT uReserved; not used
4198 // DWORD dwUser; application-defined instance data */
4199 // DWORD dwReserved1; not used
4200 // DWORD dwReserved2; not used
4201 {
4202 BYTE status= 0;
4203 BYTE raddr= 0;
4204 static count= 0;
4205 static MessageIsPosted= 0;
4206 TC_832Controller* Hardware= dynamic_cast<TC_832Controller*>(MotorControllers.GetController(dwUser));
4207
4208 Hardware->LM628Ready(Hardware->baddr,Hardware->activeDrive);
4209 Hardware->Put(Hardware->baddr,Hardware->activeConfig | 0x07 );
4210 status= Hardware->Get(Hardware->baddr + 1);
4211
4212 Hardware->bLimitHit= 0;
4213 count++;
4214 PostMessage( GetFrameHandle( ),WM_COMMAND,cm_SetWatchIndicator,( LPARAM ) count );
4215 if( status & 0x01 )
4216 {
4217 raddr= (Hardware->activeConfig | 0x00);
4218 Hardware->Drive628c(LTRJ,0x400,0,Hardware->baddr,raddr,Hardware->activeDrive);
4219 Hardware->Drive628c(STT,0,0,Hardware->baddr,raddr,Hardware->activeDrive);
4220 Hardware->bLimitHit= 1;
4221 }
4222 if( status & 0x02 )
4223 {
4224 raddr= (Hardware->activeConfig | 0x02);
4225 Hardware->Drive628c(LTRJ,0x400,0,Hardware->baddr,raddr,Hardware->activeDrive);
4226 Hardware->Drive628c(STT,0,0,Hardware->baddr,raddr,Hardware->activeDrive);
4227 Hardware->bLimitHit= 2;
4228 }
4229 if(Hardware->bLimitHit && !MessageIsPosted)
4230 PostMessage(GetFrameHandle( ),WM_COMMAND,cm_LimitHitOccure,( LPARAM )Hardware->bLimitHit);
4231 };
4232
4233 //******************************************************************************
4234 //******************************************************************************
4235 long TC_832Controller::Drive628c(BYTE cmd,WORD ctrl_word,long param,WORD base,WORD regaddr,unsigned short drive)
4236 {
4237 TCSet *pCmdDesc;
4238
4239 if((base != 0))
4240 {
4241 MessageBox(0,"Ungültiger Offset für C832.","Drive628c", MBFAILURE);
4242 return(0);
4243 }
4244
4245
4246 if(bIdle) // Ist Drive nicht in Benutzung ?
4247 {
4248 bIdle= FALSE; // Ja! Dann Status in "benutzt"
4249 }
4250
4251 bIdle= TRUE; // sonst, Status wird in "nicht benutzt" gesetzt
4252 // Wozu macht er das eigentlich ??
4253 // an dieser Stelle ist TC_832::bIdle immer True!
4254
4255 // Kommandosatz durchgehen
4256 pCmdDesc= CmdSet;
4257 if( cmd==RDSTAT ) // Liegt Kommando "RDSTAT"(Read Status) vor ?
4258 {
4259 // Status
4260 Put(base,regaddr); // Ja! Fordere Auslesen des Configuration
4261 // Data Registers
4262 bIdle= FALSE; // Setze Status in "benutzt"
4263 return((long)Get(base + 1)); // Lese die entsprechenden Daten aus dem
4264 // Datenregister und gebe sie zurueck
4265 }
4266 else
4267 while(cmd != pCmdDesc->cmd) // Wenn nicht RDSTAT, dann gehe Kommandosatz durch
4268 pCmdDesc++;
4269
4270 LM628Ready(base,drive); // Test ob Busy-Bit gesetzt,(Test ist aber
4271 // sinnlos,wenn er nicht ausgewertet wird !!)
4272 Put(base + 1,cmd); // Sende Kommando an Controller
4273
4274 if( pCmdDesc->data ) // nur alle Data Kommandos
4275 {
4276 // read/write data
4277 if( ( cmd==LTRJ ) | ( cmd==LFIL ) ) // wenn "LTRJ"- oder "LFIL"-Kommando
4278 PutWord(ctrl_word,base,regaddr,drive); // dann schreibe
4279 if( pCmdDesc->report ) // Liegt ein Report-Kommando vor?
4280 {
4281 // Ja! Report Kommando liegt vor
4282 if(pCmdDesc->length32) // Hat es einen 32Bit Parameter ?
4283 {
4284 bIdle= FALSE; // Setze Status in "benutzt"
4285 return GetDWord(base,regaddr,drive); // hole 32 Bit data
4286 }
4287 else // ansonsten
4288 {
4289 bIdle= FALSE; // Setze Status in "benutzt"
4290 return (long)GetWord(base,regaddr,drive); // hole 16 Bit data
4291 }
4292 }
4293 else // wenn kein Report Kommando
4294 {
4295 // dann nur noch Control Kommando moeglich
4296 if( pCmdDesc->length32 ) // 32Bit ?
4297 PutDWord(param,base,regaddr,drive); // hole 32 Bit parameter
4298 else // ansonsten
4299 PutWord((int)param,base,regaddr,drive); // hole 16 Bit parameter
4300 }
4301 }
4302
4303 bIdle= FALSE; // Setze Status in "benutzt"
4304 return 0;
4305 };
4306
4307 int TC_832Controller::GetWord(WORD base,WORD regaddr,unsigned short drive)
4308 {
4309 union
4310 {
4311 int integer;
4312 BYTE byte[ 2 ];
4313 } temp;
4314
4315 if((base != 0))
4316 {
4317 MessageBox(0,"Ungültiger Offset für C832.","GetWord", MBFAILURE);
4318 return(0);
4319 }
4320
4321 LM628Ready(base,drive);
4322
4323 Put(base,regaddr + 1);
4324 temp.byte[ 1 ]= Get(base + 1);
4325 temp.byte[ 0 ]= Get(base + 1);
4326
4327 return temp.integer;
4328 };
4329
4330 long TC_832Controller::GetDWord(WORD base,WORD regaddr,unsigned short drive)
4331 {
4332 union
4333 {
4334 long lval;
4335 BYTE byte[ 4 ];
4336 } temp;
4337
4338 if((base != 0))
4339 {
4340 MessageBox(0,"Ungültiger Offset für C832.","GetDWord", MBFAILURE);
4341 return(0);
4342 }
4343
4344 LM628Ready(base,drive);
4345
4346 Put(base,regaddr + 1);
4347 temp.byte[ 3 ]= Get(base + 1);
4348 temp.byte[ 2 ]= Get(base + 1);
4349 LM628Ready(base,drive);
4350 Put(base,regaddr+1 );
4351 temp.byte[ 1 ]= Get(base + 1);
4352 temp.byte[ 0 ]= Get(base + 1);
4353
4354 return temp.lval;
4355 };
4356
4357 void TC_832Controller::PutWord(int data,WORD base, WORD regaddr, unsigned short drive)
4358 {
4359 union
4360 {
4361 int integer;
4362 BYTE byte[ 2 ];
4363 } temp;
4364
4365 if((base != 0))
4366 {
4367 MessageBox(0,"Ungültiger Offset für C832.","PutWord", MBFAILURE);
4368 return;
4369 }
4370
4371 LM628Ready(base,drive);
4372
4373 Put(base,regaddr + 1);
4374 Delay( 2 );
4375 temp.integer= data;
4376 Put(base + 1,temp.byte[ 1 ]);
4377 Put(base + 1,temp.byte[ 0 ]);
4378
4379 };
4380
4381 void TC_832Controller::PutDWord(long data,WORD base,WORD regaddr, unsigned short drive)
4382 {
4383 union
4384 {
4385 long lval;
4386 BYTE byte[ 4 ];
4387 } temp;
4388
4389 if((base != 0))
4390 {
4391 MessageBox(0,"Ungültiger Offset für C832.","PutDWord", MBFAILURE);
4392 return;
4393 }
4394
4395 temp.lval= data;
4396 LM628Ready(base,drive);
4397
4398 Put(base,regaddr+1 );
4399 Put(base + 1,temp.byte[ 3 ]);
4400 Put(base + 1,temp.byte[ 2 ]);
4401 LM628Ready(base,drive);
4402 Put(base,regaddr+1 );
4403 Put(base + 1,temp.byte[ 1 ]);
4404 Put(base + 1,temp.byte[ 0 ]);
4405
4406
4407 };
4408
4409 int TC_832Controller::Get(unsigned port)
4410 {
4411 int return_val= 0;
4412
4413 if ( simulation_type & 1 )
4414 {
4415 // case no_simulation: case test_simulation:
4416 // get the hardware generated return valu
4417 Read(port,(BYTE*)&return_val);
4418
4419 if ( simulation_type & 2 )
4420 {
4421 // case test_simulation:
4422 // inform driver if possible, simulated value is ignored
4423 if ( c832_get_callback )
4424 {
4425 port += dwSimBasePort; //erforderlich, da die Simulation mit absoluten Adressen arbeitet
4426 c832_get_callback( port, return_val );
4427 }
4428 }
4429 }
4430 else
4431 {
4432 // case simulation_only:
4433 // let driver generate a simulated value
4434 if ( c832_get_callback )
4435 {
4436 port += dwSimBasePort; //erforderlich, da die Simulation mit absoluten Adressen arbeitet
4437 return_val= c832_get_callback( port, 0 );
4438 }
4439 }
4440
4441 return return_val;
4442 }
4443
4444 void TC_832Controller::Put(unsigned port, int value)
4445 {
4446 if ( simulation_type & 1 )
4447 {
4448 // case no_simulation: case test_simulation:
4449 // write the value to hardware
4450 Write(port,(BYTE)value);
4451 }
4452 if ( simulation_type & 2 )
4453 {
4454 // case simulation_only: case test_simulation:
4455 // write the value to the simulation driver
4456 if ( c832_put_callback )
4457 {
4458 port += dwSimBasePort; //erforderlich, da die Simulation mit absoluten Adressen arbeitet
4459 c832_put_callback( port, value );
4460 }
4461 }
4462 }
4463
4464
4465
4466 BOOL TC_832Controller::LM628Ready(WORD base, unsigned short drive)
4467 {
4468 int tt;
4469 int time_out=1000;
4470
4471 //ap -> Test,ob nur Offsets !!!
4472 if((base != 0))
4473 {
4474 MessageBox(0,"Ungültiger Offset für C832.","LM628Ready",MBFAILURE);
4475 return(0);
4476 }
4477
4478 // command register vom aktiven drive
4479 Put(base,activeConfig | (drive<<1));
4480 do
4481 {
4482 tt= Get(base+1);
4483 if( !( time_out-- ) )
4484 return FALSE;// wenn timeout, dann FALSE ->"nicht bereit"
4485 } while( tt & 0x01 ); // teste ob bit 0 von "tt" gesetzt (BUSY-Bit)
4486 if( tt & 0x02 ) // teste ob bit 1 von "tt" gesetzt, welche Bedeutung ?
4487 {
4488 time_out++; // warum nochmal time_out um eins erhoehen ??
4489 }
4490
4491 return TRUE; // BUSY-Bit geloescht
4492 }
4493 ;
4494 // __LastLine__
4495