Page 2 of 2

Re: Output module: counters, rotations, overshooting...

Posted: 11 Mar 2012, 21:43
by afanofosc
mrblp wrote:Well, I can concentrate to one special case that does not work: The OUT_OPTIONS_RAMPDOWNTOLIMIT thing does not work. And I found out that this one is not a feature of the standard firmware. So it is added in the enhanced firmware... It is not declared as enhancement in the doxygen help.
I'm very confused by what you say above. OUT_OPTIONS_RAMPDOWNTOLIMIT is only for the OutputOptions field which does not even exist in the standard firmware. Or, it exists, but in the standard firmware it happens to be called SpareOne and you cannot set it using any API function, including SetOutput because in the standard firmware the 3 spare fields in the Output module IOMap structure are not exposed for use in the SETOUT opcode. The only way you could correctly set SpareOne to a value in the standard firmware is if you used IOMapWrite with the correct offset into the IOMap structure.

So if you were trying to use this option with the standard firmware it would be nice to know what functions you were calling to set its value (SetOutput ?). It looks like the way that the firmware is written it will wrap around to the next output if you specify a field number that is greater than the number of fields supported by the firmware for use with the SETOUT opcode, which means it would have been changing a value in OUT_B if you tried to change OUT_A's OutputOptions field with the standard firmware using SetOutput. If you were trying to call SetOutput with OUT_C and the OutputOptions field then it would abort with an ERR_INSTR error.

The other odd thing I don't understand is that the constants OUT_OPTIONS_RAMPDOWNTOLIMIT aren't even defined if you compile your code for the standard firmware or for a 1.0 firmware version:

Code: Select all

#if defined(__ENHANCED_FIRMWARE) && (__FIRMWARE_VERSION > 107)
/** @defgroup OutOptionConstants Output port option constants
 * Use these constants to configure the desired options for the
 * specified motor(s): hold at limit and ramp down to limit. Option constants
 * can be combined with bitwise OR.
 * \sa SetOutput()
 * @{
 */
#define OUT_OPTION_HOLDATLIMIT     0x10 /*!< Option to have the firmware hold the motor when it reaches the tachometer limit */
#define OUT_OPTION_RAMPDOWNTOLIMIT 0x20 /*!< Option to have the firmware rampdown the motor power as it approaches the tachometer limit */
/** @} */  // end of OutOptionConstants group
So if you used these options you had to have used the -EF switch on NBC so that __ENHANCED_FIRMWARE was defined which means you knew full well that your code required the enhanced NBC/NXC firmware. The doxygen-based help is generated with __ENHANCED_FIRMWARE defined. MotorOutputOptions is already documented as requiring the enhanced firmware.
Shame on me I still did not try the v1.31 enhanced firmware. So it may work as intended with that one. Previous versions do not work. The OUT_OPTIONS_RAMPDOWNTOLIMIT option manipulates the internal rotation counters in a way you cannot reset anymore. The behaviour of the output module will be a bit unpredictable after using this option. The only way I found is to switch of the NXT. Just stopping the program and restarting does not help.
Setting this option in the enhanced firmware does not change the internal counters in any way. If you have set the Options field in the Output module IOMap structure to a non-zero value for any of the outputs then it will get passed into the low level motor control routines in the call to dOutputSetTachoLimit but only if the UF_UPDATE_TACHO_LIMIT bit is set in the UpdateFlags field. So to turn it on requires the UF_UPDATE_TACHO_LIMIT bit and likewise to turn it off (i.e., to set Options from a non-zero value back to zero) it also requires the UF_UPDATE_TACHO_LIMIT to be set in the UpdateFlags field. The call to dOutputSetTachoLimit sets an internal Output module field (per output port) called RampDownToLimit. Regardless of the Options field value, if you set the TachoLimit to 0 it sets RampDownToLimit to 0. Only if TachoLimit is non-zero and Options is non-zero will RampDownToLimit be set to a non-zero value.

I will run some tests myself and report back my findings.

John Hansen

Re: Output module: counters, rotations, overshooting...

Posted: 11 Mar 2012, 23:03
by mrblp
Hello John,

thank you for your detailed answer. I am using enhanced firmware for those tests. OK, it is manipulated by me and self compiled. But only by removing the OBP feature and some other things. Perhaps you remember - we had a pm about that some years ago ;-)

When using the RAMPDOWNTOLIMIT feature the counters behave strange. I think this is because the counters will be reset at the wrong stage of moving. And I made an explicit "Coast" after the "Rotate"-commands. That means the counters are _not_ zero at the beginning of the next rotation commands. This was my fault of course. It is not simple to understand that system...

And I have got some news: I give leJOS a try. With linux and eclipse and JDK 1.6 it works nearly out of the box. I hope you do not get me wrong - you are really really really doing great work on the enhanced firmware and nbc/nxc. But today I started firmware understanding again and the first thing I thought was "To refactor this code I have to start at the "main" function!". I needed some time to find that one and this is typically... :-( The good news: I have two bricks - the other one has still the enhanced fw. And the one of my girl-friend has the 1.31 original... ;-)

Bye marvin