Re: Output module: counters, rotations, overshooting...
Posted: 11 Mar 2012, 21:43
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.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.
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
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.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.
I will run some tests myself and report back my findings.
John Hansen