![](http://content.invisioncic.com/q299037/set_resources_2/84c1e40ea0e759e3f1505eb1788ddf3c_pattern.png)
HJTrost
Members-
Posts
51 -
Joined
-
Last visited
-
Days Won
1
HJTrost last won the day on October 11 2023
HJTrost had the most liked content!
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
HJTrost's Achievements
-
I made a fresh installation of Power PMAC IDE 4.6.0.14 on a new Windows 10 computer. Everything works apparently fine including my programs for/on a CK3C AX1100. The only problem is that the Tune tool does not come up but show an error message Exception thrown by target of an invocation I have tried reinstalling a few times, but the message did not budge. There are two older programs on the system (which I control) that bring in Microsoft Visual C++ Distributables. Are there any scenarios known in which this message would pop up in this way? Cheers, Jochen
-
syntax error, unexpected '*' - Are any possible solutions known?
HJTrost replied to HJTrost's topic in Power PMAC
Quick addendum: The error message is issued by Intellisense, not Build. -
I failed yet again. I have from my homing procedure (drive into the hard end, turn around, look for index): Gate3[0].Chan[0].CaptFlagSel=0 Gate3[0].Chan[0].CaptFlagChan=0 Gate3[0].Chan[0].CaptCtrl=1 I move the setting of UserAlgo.CaptCompIntr=1 from my InitPlc to right before the test move in my script program: cmd"UserAlgo.CaptCompIntr=1"; X(MovEndX) Y(MovEndY) F(FeedRate/1000); While (InPosX==False || InPosY==False) {} The move nominally covers 20 mm and takes some 4 seconds. The encoder is a rotary one on the back of a stepper motor, which produces a motion of 6 mm per revolution, so I should see 3 or 4 calls. I see CaptCompIntr switch from 0 to 1 at the start position of my move but still/again no sign of activity in CaptCompISR - Sys.Idata[65524] remains at 0. Things get messier, actually. My X/Y/F move is not executed properly if I try to get CaptCompISR involved. In the present test with the capture, this means that instead of moving in x from 133333 counts to 159900 counts (1333 counts/mm), the stage takes a detour: 133333 -> 0 -> 159900. In the position compare test, the detour is 133333 -> 200000 -> 159900. I have no idea where that intermediate position comes from. If I keep the position compare a pure script affair, the moves are flawless. Is it time to move this to ODT-Support?
-
I am pulling this out of my thread "Using CaptCompISR" (https://forums.automation.omron.com/topic/10121-using-captcompisr/) A minimal test version of that function is this: #include "usrcode.h" #define _PPScriptMode_ #include "../Include/pp_proj.h" void CaptCompISR(void) { volatile GateArray3 *MyGate3; int *CompDebug; MyGate3 = GetGate3MemPtr(0); MyGate3->IntCtrl = 0x20; CompDebug = (int *)pushm + 65524; (*CompDebug)++; } It should increase the counter Sys.Idata[65524] by 1 when called and thus prove that it has been called. It does not do this. I do provide a legitimate trigger with script code, which is made visible by a LED. However, the question here is why the Power PMAC IDE flags the declaration of *MyGate3 with a twiddle line under the asterisk and issues the message " syntax error, unexpected '*' ". I have two look-alike motion systems (same hardware, one 15 years old, the other brand new), with the same CK3C controller on each (both brand new out of a delivery of 5 units), with an older Windows 10 laptop assigned to the old system and a new Windows 10 industrial panel PC to the new one. On both, the same version 4.6.0.14 of the IDE is installed, and the firmware reported for the CK3Cs is 2.7.1.0, the cpu is [arm,LS1021A]. Both systems suffer from the same disease. I have found one previous post asking the same question, with no solution reported in the forum. Does anybody have an answer? Jochen
-
I tried this, and I still don't see any call to CaptCompISR. I edited the function, issued a $$$***, did a Clean in Solution Explorer before Build and Download, issued a "save" after download (because my motion program issues a $$$ at the beginning) and ran my program. The watch window of the IDE says UserAlgo.CaptCompIntr=1 all along and the call counter Sys.Idata[65524] remains at 0. The attached text file shows my usrcode.h, usrcode.c and the relevant script snippet. CaptCompIntr is set much earlier than the occurrence of the move shown in the snippet. The move lasts 4 seconds. usrcode.txt
-
Yes, I am following pages 792ff. I have put my code for the CaptCompISR function into usrcode.c in the directory "C Language/Realtime Routines". The code follows the Compare Interrupt Routine Example on page 800, with these differences: - I use Chan[1] rather than Chan[0], which allows me to easily switch between triggering off of the positions of my x and y axes. Accordingly, I manipulate the channel-1 bits in Gate3[0].IntCtrl, not the channel-0 bits. - I pick up, from shared memory, the home offset and a direction parameter (+/-1) for setting the proper trigger positions. - I count calls to the interrupt routine with a counter in shared memory. I show this in the watch window, and it never counts a call. - I have removed additional code that I have listed in my original post. In my script programming, - I am setting UserAlgo.CaptCompIntr=1 and can see this in the watch window of the IDE while my program is running; - I am preloading the first trigger position, and this one trigger does fire but is not followed by a call to CaptCompISR. Things that are not addressed in pages 792ff: - In Solution Explorer, the Advanced property "Build Action" of usrcode.c is set to "Compile". I have turned the downloading of the C sources on. On the PMAC, I do find these as well as usralgo.so and usralgo.ko under /var/ftp/usrflash/Project here: Bin/Debug/usralgo.ko Bin/Debug/usralgo.so C Language/Realtime Routines/usralgo.so C Language/Realtime Routines/usrcode.c C Language/Realtime Routines/usrcode.h
-
More observations: UserAlgo.CaptCompIntr=1 is actually happening. usralgo.so appears in the same directory as usrcode.c and usrcode.h on the PMAC (a CK3C, by the way). I suspect that there are more trivial or stupid omissions in the IDE or project setups to be fixed rather than, or on top of, actual programming issues. I just can't find them ...
-
I found one omission: In the Solution Explorer, in the Properties of the file usrcode.c, the "Build Action" was still set to "Content". I changed this to "Compile", and now the build-and-download procedure actually compiles my C code. However, when I run my motion system, nothing has changed - "User written 'C' Real Time Interrupt Task is NOT active". And my counter at Sys.Idata[65524] remains at 0, so my CaptCompISR function still does not receive any position-compare trigger.
-
I am trying to use the C routine CaptCompISR to process position-compare triggers but the C code refuses to run. My general program structure works as follows: Run a oneshot script PLC InitPLC, including an instruction cmd"UserAlgo.CaptCompISR=1"; Start script PLCs for reporting current values (position, velocity, ...) to the host program watch for emergency stop situations handle action requests from the host program I prepare the trigger points for the position compare in Sys.Idata starting at 65536, with the factor 4096 multiplied in but no home offset applied. One action request is handled in a motion script program including the following instructions: Gate3[0].IntCtrl = 0x200000 ; PReadPtr=PVarOffset+TrigPtr ; L1 = PReadPtr ; TrigEnaY = $1 ; // Set EquWrite = $1. TrigAY=(Sys.Idata[L1]/4096-TrigDir*TrigPhs+HmOffset)*4096 ; // This is Gate3[0].Chan[1].CompA TrigBY=TrigAY+TrigDir*PStepAB*ScaleFct*4096; // This is Gate3[0].Chan[1].CompB TriggerPlcR=True ; // Enable plc TriggerPlc ; X(MovEndX) Y(MovEndY) F(CmdFeedRt/1000) ; //Index Through Print. While (InPosX == False || InPosY == False) {} TriggerPlcR=False ; // Disable plc TriggerPlc ; The C code looks as follows: #include "usrcode.h" #define _PPScriptMode_ #include "../Include/pp_proj.h" void CaptCompISR(void) { volatile GateArray3 *MyGate3; int *CompDebug; int *Comp8Million; int *CompType; int *CompCounter; int *CompPosStore; int *CompHmOffset, *CompHmOffsetX, *CompHmOffsetY; int *CompStepAB; int *CompTrigDir; int *CompDataLap; int *CompPVarSize; int Temp, TempPosStore, TempPosTest, Temp8Million, TempM8M, CStepAB, CTrigDir, CpVarSize, CTrigSel; MyGate3 = GetGate3MemPtr(0); MyGate3->WpKey = 0xAAAAAAAA; // Make IntCtrl writeable. MyGate3->IntCtrl = 0x20; // Clear interrupt. CompDebug = (int *)pushm + 65524; // Debug counter, serves to prove that this code is executed. CompPVarSize = (int *)pushm + 65525; CompTrigDir = (int *)pushm + 65526; CompStepAB = (int *)pushm + 65528; CompHmOffset = (int *)pushm + 65531; CpVarSize = *CompPVarSize; CTrigDir = *CompTrigDir; // Direction of motion - +1 or -1 CStepAB = *CompStepAB; CompDataLap = (int *)pushm + 65532; // Wrap-around flag, 0 or 1. Comp8Million = (int *)pushm + 65533; // end of run flag value. Temp8Million = *Comp8Million; TempM8M = - Temp8Million; CompType = (int *)pushm + 65534; // 0 for rectangular flying, 1 for curved flying. CompCounter = (int *)pushm + 65535; // The value for this index was preloaded, (*CompCounter)++; // so we point to the second value first time we get here. if (*CompCounter >= CpVarSize) { *CompCounter = 0; *CompDataLap = 0; } CompPosStore = (int *)pushm + *CompCounter + 65536; TempPosStore = *CompPosStore; TempPosTest = TempPosStore / 4096 ; (*CompDebug)++; // Counts calls here. if ((*CompType) == 0) { if ((TempPosTest < Temp8Million) && (TempPosTest > TempM8M)) { // Set new trigger point. MyGate3->Chan[1].CompA = TempPosStore + *CompHmOffset ; MyGate3->Chan[1].CompB = TempPosStore + *CompHmOffset + CStepAB * CTrigDir; // Set EquWrite = 1. Temp = MyGate3->Chan[1].OutCtrl; Temp &= 0xFFFFFF7F; // Clear bit 7 (0x80). MyGate3->WpKey=0xAAAAAAAA; // Make OutCtrl writeable. MyGate3->Chan[1].OutCtrl = Temp | 0x40; // Set bit 6. } } else if ((*CompType) == 1) { // ... case not used yet ... } } My usrcode.c file does also contain the dummies for other functions like GetLocal and CFromScript. The source gets actually downloaded, I have found it with Putty on the PMAC. If I disable the instruction to set CaptCompISR=1 in InitPlc and activate my script PLC "TriggerPlc" in the motion program, I get to see all expected triggers. Here is how TriggerPlc works: Open plc TriggerPlc //Trigger Target Generator. If (TrigStateY == True) // Test Gate3[0].Chan[1].Equ { p793=p793+1; // Debug counter TrigPtr=TrigPtr+1 ; If (TrigPtr == pVarSize) { TrigPtr=0 ; DataLap=False ; } PReadPtr=(PVarOffset+TrigPtr) ; L1 = PReadPtr ; TrigEnaY = $1 ; // Set EquWrite = $1. TrigAY=(Sys.Idata[L1]/4096-TrigDir*TrigPhs+HmOffset)*4096 ; // This is Gate3[0].Chan[1].CompA TrigBY=TrigAY+TrigDir*PStepAB*4096; // This is Gate3[0].Chan[1].CompB } Close The IDE does not like the statement volatile GateArray3 *MyGate3; It puts a red twiggle under the "*" of *MyGate3 and reports "syntax error, unexpected '*'". Of my script PLCs, only TriggerPlc is a RTIPLC. Sys.WpKey is globally set to $AAAAAAAA. I have set the build and download to include the C source code. The build and download does not report any error. When trying to run this code, the task list reports under "Real time interrupt" "User written 'C' Real Time Interrupt task not active". What am I missing? Cheers, Jochen
-
In position-compare triggering, I need to handle a range of 300 mm worth of quadrature encoder counts of 0.1 micron, i.e., 3 million. The trigger positions need to be stuffed into Gate3[0].Chan[1].CompA and .CompB for the leading and trailing edges of the TTL pulses. The units of CompA and CompB are 1/4096th of an encoder count, leaving a range of 20 bits for the full encoder counts, or about 1 million. With the Turbo PMAC family, I had 24 bits for a full range of 16 million plus. My encoder settings are Gate3[0].Chan[j].EncCtrl=3 or 7 (j=0, 1). Now the Power PMAC Software Reference Manual says this, under Gate3[i].Chan[j].CompA (last paragraph): In the Script environment, it is possible to write values from -2^31 to +2^31-1 to this element. (An attempt to write a value outside this range will cause the element value to saturate at the end of this legal range.) That is, for writing purposes, it can be treated as either a signed 32-bit value with a range of -2^31 to 2^31-1 or an unsigned 32-bit value with a range of 0 to 2^32-1. However, for reading purposes, it is always reported as an unsigned value, so if it is set to a negative value, the value reported will be 2^32 greater than that value. Note the second sentence, in parentheses: "An attempt to write a value outside this range will cause the element value to saturate at the end of this legal range." I understand this to mean that there is no rollover mechanism but rather a Procrustean bed, i.e., excess values are truncated down to the limit value. What are my options? Can CompA and CompB be made to operate on different units, e.g., with one unit in CompA and CompB being worth 1000 of my encoder counts? My trigger position set points need to be accurate to the 1 micron level, not 1/4000th of 0.1 micron.
- 1 reply
-
- 1
-
-
Triggering on passing positions in a CK3C AX1100 (Power PMAC Clipper)
HJTrost replied to HJTrost's topic in Power PMAC
Progress! Reordering the code by writing to EquWrite first and CompA and CompB thereafter makes the electric trigger pulses appear. Gate3[0].Chan[1].EquWrite=$1; // clear output signal Gate3[0].Chan[1].CompA=(P(P606)+Motor[1].HomePos)*P2999; Gate3[0].Chan[1].CompB=(P(P606)+P611+Motor[1].HomePos)*P2999; So the enabling of the autoincrement operation does actually more than that as my CompAdd is at default, i.e., 0. That leaves the 300 mm in 0.1 micro steps encoder issue. I'll open a new thread for that one. -
Triggering on passing positions in a CK3C AX1100 (Power PMAC Clipper)
HJTrost replied to HJTrost's topic in Power PMAC
Yes, that is intentional. By flipping Equ1Ena, using Chan[1] allows me to change the axis selection for the triggering on the fly. A working pair of programs is attached, updated slightly from my previous inline quotes. Setting Gate3[0].Chan[1].Equ1Ana=0 and using Motor[2] instead of Motor[1] converts this from the x axis to the y axis. This is what we did with the Turbos. "Working program" means I get the state changes of Equ and EquOut in software and count the correct number of trigger pulses (counter p793). The CK3C still does not give me the TTL pulses. TestTrig.pmc TriggerTestPlc.plc -
Triggering on passing positions in a CK3C AX1100 (Power PMAC Clipper)
HJTrost replied to HJTrost's topic in Power PMAC
It took me a while but I think I am finally getting a grip on this. The cutting off of the trigger in software that I am used to from the Turbo PMAC does not work here, and I need CompA and CompB to define the pulse length. The scaling with 4096 is correct. My motor units are quadrature encoder counts. So my trigger update looks like this: Gate3[0].Chan[1].CompA=(P(PReadPtr)+Motor[1].HomePos)*4096 ; Gate3[0].Chan[1].CompB=(P(PReadPtr)+50+Motor[1].HomePos)*4096 ; Gate3[0].Chan[1].EquWrite=$1 ; //Clear old Trigger. Here I have previously set Gate3[0].Chan[1].Equ1Ena=1 to get the x axis triggers on the EQU2 output line. I can flip Equ1Ena on the fly and thereby accommodate curved motions, in which triggering in the x-y plane uses the larger of the x and y projections. My problem now is that the hardware pulses do not show up on the EQU2 line, pin 18 of the JMACH2 port of the CK3C. I have yet to take an oscilloscope to it for a close look. But as there is no user manual for the CK3C yet, I'd like to know if that output pulse still is supposed to be a TTL pulse of 5 V amplitude. I also need to know what happens when the motor counts in .CompA and .CompB roll over as they will on my 300 mm long motion stages with 0.1 micron quadrature counts. -
Triggering on passing positions in a CK3C AX1100 (Power PMAC Clipper)
HJTrost replied to HJTrost's topic in Power PMAC
I have looked through those passages before, and I've looked again. I just don't recognize the answer there. My trigger strategy goes like this: Load first trigger point into CompA. Start the move of the stage. When Equ has turned on, load the next trigger point into CompA. Clear the old trigger by writing to EquWrite. When Equ has turned on, load the next trigger point into CompA. Clear the old trigger by writing to EquWrite. Here is the core of my program code: Open plc TriggerPlc If (Gate3[0].Chan[1].Equ == 1) { TrigPtr=TrigPtr+1 ; //Increment Pointer. If (TrigPtr == 60000) { TrigPtr=0 ; DataLap=False ; } PReadPtr=(3000+TrigPtr) ; Gate3[0].Chan[1].CompA=(P(PReadPtr)+Motor2.HomePos)*4096 ; Gate3[0].Chan[1].EquWrite=$1 ; //Clear old Trigger. } Close I have no use for the increment, it is left at its default, which should be zero. I have no use for CompB either, which I set to an out-of-range-of-interest position (8,000,000 for the Turbo PMAC, currently 80,000,000 for the CK3C). I don't see what keeps me from getting trigger output signals. -
I am trying to get triggering on hardware position converted from Turbo PMAC to Power PMAC. On Turbo PMAC I use the 24-bit full encoder counts registers M108 or M208. This gives me a range of 16,000,000+ encoder counts, sufficient for 300 mm of counts at 0.1 micron/count. I do not bother with the fractional counts in M188 and M288. Now, if I understand the Power PMAC User Manual correctly, I have to put my trigger position into Gate3[0].Chan[j].CompA in units of 1/4096 encoder counts and am thus limited to just over 1,000,000 full encoder counts range (20 bits rather than Turbo's 24). So I essentially write CompA = (myTrigPosition + HomeOffset) * 4096 ; and take a run of the respective motion stage to see the trigger light up. On the Turbo PMAC the equivalent (no 4096, of course) works. On the Power PMAC, I do not see any triggers - I have put CompA into my watch window in Power PMAC IDE, and I know that the value of myTrigPosition is valid and within my motion range for the trigger run. HomeOffset stands for M173 or M273 on Turbo PMAC and Motor[x].HomePos on Power PMAC. There is one oddity in my programs: When I am moving about without triggering, CompA and CompB are set to 8,000,000 on the Turbo PMAC and (because I thought initially that the Power PMAC gives me *more* range) 80,000,000 on the Power PMAC; the autoincrement is always 0. I don't touch CompB any further. When triggering, I preload the first sensible value into CompA and then start the move. Once a trigger shows up in Gate3[0].Chan[j].Equ, I clear the trigger in software with EquWrite = $1 and set the next value in CompA. Where am I losing it on the Power PMAC? How do I accommodate my 3,000,000 encoder counts on the Power PMAC? I'd absolutely hate to have to throw virtual motors in there with scaled virtual encoders (e.g., virtual = real / 4096, which would give me 32 bits of full encoder counts). Hans-Jochen Trost