Jump to content
OMRON Forums

steveneads

Members
  • Posts

    107
  • Joined

  • Last visited

Everything posted by steveneads

  1. Hi Curt/Charles I think that I've a better understanding now - I need to be careful that high priority tasks don't interrupt a read-modify-write sequence being performed by a background task. However, if I'm writing data from a background PLC, can you confirm what size of variable is safe? In C code I believe that I can write a byte, 2 bytes, 4 bytes, or 8 bytes directly, but I'd need to do a read-modify-write to write a bit. Is this the same for background PLCs? How does your code handle variables of different sizes? Is it only variables that are less than a byte long which are a risk, or are longer variables also handled with a read-modify-write by PMAC? Thanks Steve
  2. Hi Curt Thanks - I presume that this locking is just to protect background PLCs from foreground PLCs and motion programs? As I understand it the background PLCs run sequentially as they did in UMAC - so they can't interrupt each other - is that right? Does this also give protection from higher priority tasks such at C code in a user servo or rtiplc or even cfromscript called from a motion program? I still haven't had an answer that I understand about protection in the C environment! Can you help with this please? If I'm using pointers to write to ushm, what read/write size is safe and what isn't? Thanks Steve
  3. Hi Charles, Can you clarify this a little more for me? Are you talking about blocks of 4 bytes, ie 32 bit words, or 8 bytes, ie 64 bit words? Does this mean that I need to be careful how I use Sys.Idata, Sys.Cdata etc. in multiple threads? Steve
  4. Hi Can you tell me whether it's thread safe to read/write to bits located in user shared memory from C code? It seems that to set a bit, I need to read at least one byte, change the required bit and then write the byte back - which needs multiple lines of code. Can another process access this address and change other parts of the byte whilst the read/write is mid way through? If I have a variable defined such as: ptr myvar->u:user:4.1.1 is reading and writing to this from PMAC script always thread safe too? Thanks Steve
  5. As I understand it Sys.pushm can be used as a convenient method of disabling inputs and outputs, ie: Motor[2].pDac=Sys.pushm; Motor[3].pPhaseEnc=Sys.pushm; Am I correct that this is OK? My worry is that an output such as Motor[2].pDac will put data into this address which will then be read by "unused" inputs also pointing to Sys.pushm.
  6. In my existing UMAC code I use the commanded motor positions located in addresses such as: M161->D:$000088 ; #1 Commanded position (1/[ixx08*32] cts) What is the direct equivalent of this in PowerPMAC? It seems from the manual that Motor[x].DesPos is not really the same (as it includes the master position). How does Motor[x].Desired.Pos relate to this? Is this the desired position at the start of each move? (I don't really understand the description in the manual!) Thanks Steve
  7. Thanks for your assistance. FYI, the A/D card is 16 bits starting from bit 8 - hence the casting to "short int" in my code. This does seem to work correctly for both positive and negative numbers. Does the shifting up do something that the cast doesn't? I don't really see why you need it in this case!
  8. I can understand why a timer is a good idea to prevent code hanging indefinitely in a WHILE loop - however, this is the opposite problem to what I believe I'm seeing. In my case the WHILE loop seems to exit too soon unless a timer is used to hold it there for a short period. This seems to be because the desired velocity bit is not behaving as I expect. Maybe I'm going to have to put it down to being another of life's mysteries!
  9. Hi Charles With regard to defining constants, I was really wondering if there was a simple way to define them for both the C code and the Script so that it could be done in one place only? Before getting your response on the bit shifting point, I had already changed my code to read: debug1 = (short int) (ADCval[0] >> 8) ; This seems to work correctly, does this seem a sensible way (the best way?) to extract the 16 bit signed value from the middle of the 32 bit word?
  10. Hi Richard I've read the other thread, but I don't think that you explain why a timer is needed! In my code I issue the jog command, wait for the desired velocity zero to go false to indicate that the move has begun, and then wait for it to go true again to determine when it's finished. As far as I can see, this logic should be robust without a timer delay if the desired velocity zero bit really works correctly. If there really is a need for a timer delay, how short can it be? In my example, when I used the 500 servo-cycle delay, this was too long in some circumstances, so I really need to keep the delay to the absolute minimum necessary.
  11. Hi I have a PLC that commands jog moves and waits for them to execute before moving on. It uses the desired velocity zero bit to determine when the move has started and completed. However, with slow jog moves the code doesn't work as I expect (it's OK with faster moves) and it seems as if the desired velocity zero bit glitches at the start of the move. Here's a simplified excerpt of the code: ;addresses used (motor 4) brDesiredVelocityZero->X:$000230,13,1 brPosJogCommand->L:$000257 ;code.... IF(brDesiredVelocityZero=1) COMMAND"#4HOMEZ" ;set motor axis position to zero brTimer=0 ;this is automatically decremented each servo cycle WHILE(brTimer>-20) ;wait for 20 servo cycles for command to execute ENDW brPosJogCommand=brStroke ;set jog distance (expected time for jog about 10 seconds) COMMAND"#4J=*" I5211=0 ;zero timer WHILE(brDesiredVelocityZero=1) ;hold until move begins debug1=I5211 ;record time in loop ENDW brMoveDone=0 I5211=0 ;zero timer WHILE(brMoveDone=0) ;wait for move to complete IF(brDesiredVelocityZero=1) brMoveDone=1 debug2=I5211 ;record time in loop ENDIF ENDW ENDIF The move is expected to take about 10 seconds, but the second while loop actually exits far too soon. I added debug variables in the loops to time how long they stayed there. debug1 registered 20 servo cycles - suggesting that this was the time taken for the jog command to execute and for desired velocity zero to go false. However, the second while loop also exited very quickly - after about another 20 servo cycles instead of the expected 10 seconds. If I modify the first loop to wait for 500 servo cycles instead of using desired velocity zero - the second loop exits correctly at the right time. This suggests to me a glitch of some sort in the desired velocity zero bit. Have I missed something here?
  12. Hi Charles Thanks for your comments - I was aware of avoiding divides as I've always done this in UMAC, but the more PowerPMAC related items are useful additional information for me. Since you mention constants, can I use #define to set a value for a constant to be used throughout my C code and script code (#define g 9.81 for instance)? If so, where should this be done? Regarding using pointers, I think that I understand this to some extent - but not fully! Here's an example that I've tried for reading values from our 16 bit analogue card (Acc36 UK) - which is made for us by DeltaTau UK (John White). I've set up a pointer variable array to look at these values: ptr ADC(32)->*; ADC(0)->i.io:$B18694.8.16; ADC(1)->i.io:$B18698.8.16; etc... In my C code I set up... int *ADCval; ADCval = (int*) piom + 2908581; //assign address location (1st address of Acc36UK card /4) debug1 = ADCval[0]; //debug1 is a global debug2 = ADCval[1]; I'm looking at debug1 and debug2 in the watch window, but the value is wrong because I'm seeing all 32 bits instead of the 16 true bits. What's the best way to deal with this? Thanks Steve
  13. Do you have any notes on writing applications to be as efficient as possible? I am in the process of deciding how to convert my existing UMAC code to PowerPMAC. I took a great deal of care in the UMAC code to make it run as fast as possible, because we have a lot of time critical background calculations. Although PowerPMAC is clearly faster, I want to make sure that I make the right design choices early on. I've tried a few read/write experiments for getting data into and out of C code and this has already revealed some big timing differences based on the type of data. I've made a block of successive reads and writes of different types of variable and timed each block of 50 reads and 50 writes to get the following results (in microseconds): 1/ using GetPtrVar/SetPtrVar for shared memory doubles = 11.9 2/ using GetPtrVar/SetPtrVar for shared memory floats = 13.4 3/ using GetPtrVar/SetPtrVar for user shared memory floats = 16 to 20 (the time seems to vary) 4/ using pshm->P[xx] = 1.5 to 6 (the time seems to vary) 5/ using the name of the global variable directly = 1.4 to 5 (the time seems to vary) 6/ using pointer array declarations for user shared memory = 1.7 to 6 (the time seems to vary) These results suggest that the GetPtrVar and SetPtrVar functions should be avoided if at all possible - particularly for user shared memory, and that using P variables is best, with pointer arrays also being quite good. Do these findings match what you'd expect? Any words of wisdom would be appreciated!
  14. Hi Curt I've been on other projects for the last couple of weeks - so I haven't had a chance to try your suggestion until today. I'm pretty sure that I got something like your suggestion working by using a flag set by user servo code to indicate when it has run, so that the next phase cycle pre-processing calculations can be run at the right time before the next servo cycle processing. I recorded the system time in the phase calculations and checked it again in the servo calculations and the result was around 1e-5 secs, so I believe that all calculations were therefore being done within the same servo-cycle. Thanks for your help. Steve
  15. Two issues: Firstly I sometimes see an error message appear in the terminal window on issuing a save command: "Save to pp_diff.cfg failed: Error in section: [bRICK]" What does this mean? Secondly, when I first start the IDE after power up, it always complains that my project does not match the project saved in PMAC - even if nothing has changed since my last save. This does not inspire any confidence on what is actually stored on the card! What's going on? How can I know that the right code is loaded?
  16. I'd like to confirm daves findings. My system (v 1.6.030) always reports UserAlgo.CFunc=0. I've tried setting it =1 from the terminal window and in "pp_startup.txt". Neither works. However, despite this setting always being =0, if I try using a "CfromScript" call it works in some cases: Call from PLC 0 - yes OK Call from motion program - yes OK Call from PLC 1 (background) - not OK If I understand the manual correctly, none of these should work when UserAglo.CFunc=0! Can someone at DeltaTau explain what we are doing wrong - or whether it's in fact a system bug, and if so, whether it's being worked on? Thanks.
  17. Thanks for this suggestion. It seems like a good idea to do the feedback pre-processing in the phase so that it's done before the encoder conversion table runs to avoid the 1 cycle delay. I've had a go at implementing your suggested code to see how it works, but have failed to compile it successfully. The main issue has been the following error: "C:\PowerPMAC Projects\PowerPmacExamples\PowerPmac1\C Language\Realtime Routines\\usrcode.c(45,0): Error : 'ioremap_nocache' was not declared in this scope" I've spent some time trying to work out what to include to solve this - but have failed. Some more help is needed!
  18. Hi Steve Thanks for pointing this out to me - unfortunately I'd been looking at the previous version of the manual which didn't contain this information! I seem to have both saved on my PC - I'll get rid of the old one. Thanks Steve
  19. Hi Steve Are you referring to this statement in the Reference Manual?... "When reporting axis positions, the positions are given in the scaled user axis units, relative to the axis’ programming origin (which is not necessarily the same as the zero position of the underlying motor)." ...or have I missed something somewhere else? Thanks Steve
  20. - sorry, that one's in the reference manual.
  21. Here's another on page 144... enable plc 0 // Enable execution of CPLC 0 enable plc 2,4,6 // Enable execution of CPLCs 2, 4, and 6 enable plc 7..10 // Enable execution of CPLCs 7, 8, 9, and 10 enable plc 11,13..16,20 // Enable execution of CPLCs 11, 13, 14, 15, 16, and 20
  22. Hi Curt I'm trying to understand the timing when adopting the strategy in one of your previous suggestions to me, namely, that it's possible to write a user servo to "poke" values into unused encoder conversion table entries to be used by subsequent higher numbered servos, or into the compensation registers of higher numbered servos themselves. I have read in another thread a comment from you stating "Each servo cycle, Power PMAC computes these terms [PosError, ActVel etc] for all motors before it executes the servo loop for any motor." If this is the case, then presumably these terms will have been calculated before the user servo has written to its target registers and therefore there will be a 1 cycle delay before the new value is used. Is this right, or am I missing something? If there is a 1 cycle delay - then it seems to me that the numbering of the servos becomes irrelevant. This is rather at odds with your description of step 5 above - which suggests to me that the values are calculated for each loop in turn just before the loop calculations for that loop. Hence my confusion! Can you please clarify this? Regarding suitable code for poking numbers into the encoder conversions table, this is what I've been doing... //method to write directly to "unused" encoder conversion table entry[50] lastAccel = pshm->EncTable[50].PrevEnc; //read current position accelDiff = accel - lastAccel; //calculate new change in position ("accel" is my new value) pshm->EncTable[50].DeltaPos = accelDiff; //write back to table pshm->EncTable[50].PrevEnc = accel; Is this what you would expect to do? (it seems to work). Thanks Steve
×
×
  • Create New...