00001 /********************************************************************************* 00002 00003 Copyright 2006-2008 MakingThings 00004 00005 Licensed under the Apache License, 00006 Version 2.0 (the "License"); you may not use this file except in compliance 00007 with the License. You may obtain a copy of the License at 00008 00009 http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software distributed 00012 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00013 CONDITIONS OF ANY KIND, either express or implied. See the License for 00014 the specific language governing permissions and limitations under the License. 00015 00016 *********************************************************************************/ 00017 00018 // MakingThings - Make Controller Board - 2006 00019 00020 /** \file motor.c 00021 DC_Motor. 00022 Functions for controlling DC Motors with the MAKE Application Board. 00023 */ 00024 00025 #include "motor.h" 00026 #include "pwmout.h" 00027 #include "config.h" 00028 00029 #define MOTOR_COUNT 4 00030 00031 static int Motor_Start( int motor ); 00032 static int Motor_Stop( int motor ); 00033 00034 struct Motor_ 00035 { 00036 int users; 00037 int direction; 00038 int speed; 00039 } Motor[ MOTOR_COUNT ]; 00040 00041 static int Motor_SetFinal( int index, struct Motor_ * mp ); 00042 00043 /** \defgroup Motor Motor 00044 The Motor subsystem provides forward/reverse and speed control for up to 4 DC motors across the 8 high current outputs. 00045 Each motor controller is composed of 2 adjacent Digital Outs on the Make Application Board: 00046 - motor 0 - Digital Outs 0 and 1. 00047 - motor 1 - Digital Outs 2 and 3. 00048 - motor 2 - Digital Outs 4 and 5. 00049 - motor 3 - Digital Outs 6 and 7. 00050 00051 Other output devices cannot be used simultaneously - for example, the DigitalOuts cannot be called without 00052 first setting overlapping the DC motor I/O lines to inactive. 00053 00054 See the digital out section of the 00055 <a href="http://www.makingthings.com/documentation/tutorial/application-board-overview/digital-outputs"> 00056 Application Board overview</a> for more details. 00057 \ingroup Libraries 00058 @{ 00059 */ 00060 00061 /** 00062 Sets whether the specified motor is active. 00063 @param index An integer specifying which Motor (0-3). 00064 @param state An integer specifying the availability of the motor's I/O lines - 1 (active) or 0 (inactive). 00065 @return Zero on success. 00066 00067 \b Example 00068 \code 00069 // Enable motor 0 00070 Motor_SetActive(0, 1); 00071 \endcode 00072 */ 00073 int Motor_SetActive( int index, int state ) 00074 { 00075 if ( index < 0 || index >= MOTOR_COUNT ) 00076 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00077 00078 if ( state ) 00079 return Motor_Start( index ); 00080 else 00081 return Motor_Stop( index ); 00082 } 00083 00084 /** 00085 Returns the active state of the DC Motor I/O lines. 00086 @param index An integer specifying which DC Motor (0-3). 00087 @return The availability of the motor's I/O lines - 1 (active) or 0 (inactive). 00088 00089 \b Example 00090 \code 00091 if( Motor_GetActive(0) ) 00092 { 00093 // Motor 0 is active 00094 } 00095 else 00096 { 00097 // Motor 0 is inactive 00098 } 00099 \endcode 00100 */ 00101 int Motor_GetActive( int index ) 00102 { 00103 if ( index < 0 || index >= MOTOR_COUNT ) 00104 return false; 00105 return Motor[ index ].users > 0; 00106 } 00107 00108 /** 00109 Set the speed of a DC motor. 00110 @param index An integer specifying which DC Motor (0-3). 00111 @param duty An integer (0 - 1023) specifying the speed. 00112 @returns Zero on success. 00113 00114 \b Example 00115 \code 00116 // Set the speed of motor 3 to %75 00117 Motor_SetSpeed(3, 768); 00118 \endcode 00119 */ 00120 int Motor_SetSpeed( int index, int duty ) 00121 { 00122 if ( index < 0 || index >= MOTOR_COUNT ) 00123 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00124 00125 struct Motor_* mp = &Motor[ index ]; 00126 00127 if ( mp->users == 0 ) 00128 { 00129 int status = Motor_Start( index ); 00130 if ( status != CONTROLLER_OK ) 00131 return status; 00132 } 00133 00134 mp->speed = duty; 00135 00136 return Motor_SetFinal( index, mp ); 00137 } 00138 00139 /** 00140 Set the direction of a DC motor. 00141 @param index An integer specifying which DC Motor (0-3). 00142 @param forward A character specifying direction - 1/non-zero (forward) or 0 (reverse). 00143 @return Zero on success. 00144 00145 \b Example 00146 \code 00147 // Set the direction of motor 2 to reverse. 00148 Motor_SetDirection(2, 0); 00149 \endcode 00150 */ 00151 int Motor_SetDirection( int index, char forward ) 00152 { 00153 if ( index < 0 || index >= MOTOR_COUNT ) 00154 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00155 00156 struct Motor_* mp = &Motor[ index ]; 00157 00158 if ( mp->users == 0 ) 00159 { 00160 int status = Motor_Start( index ); 00161 if ( status != CONTROLLER_OK ) 00162 return status; 00163 } 00164 00165 mp->direction = forward; 00166 00167 return Motor_SetFinal( index, mp ); 00168 } 00169 00170 /** 00171 Read the speed of a DC motor. 00172 @param index An integer specifying which DC Motor (0-3). 00173 @return the speed (0 - 1023) 00174 00175 \b Example 00176 \code 00177 // check the current speed of motor 1 00178 int motor1_speed = Motor_GetSpeed(1); 00179 \endcode 00180 */ 00181 int Motor_GetSpeed( int index ) 00182 { 00183 if ( index < 0 || index >= MOTOR_COUNT ) 00184 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00185 00186 struct Motor_* mp = &Motor[ index ]; 00187 00188 if ( mp->users == 0 ) 00189 { 00190 int status = Motor_Start( index ); 00191 if ( status != CONTROLLER_OK ) 00192 return 0; 00193 } 00194 00195 return mp->speed; 00196 } 00197 00198 /** 00199 Read the direction of a DC motor. 00200 @param index An integer specifying which DC Motor (0-3). 00201 @return Direction - non-zero (forward) or 0 (reverse). 00202 00203 \b Example 00204 \code 00205 if( Motor_GetDirection(0) ) 00206 { 00207 // Motor 0 is going forward 00208 } 00209 else 00210 { 00211 // Motor 0 is going in reverse 00212 } 00213 \endcode 00214 */ 00215 int Motor_GetDirection( int index ) 00216 { 00217 if ( index < 0 || index >= MOTOR_COUNT ) 00218 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00219 00220 struct Motor_* mp = &Motor[ index ]; 00221 00222 if ( mp->users == 0 ) 00223 { 00224 int status = Motor_Start( index ); 00225 if ( status != CONTROLLER_OK ) 00226 return 0; 00227 } 00228 00229 return mp->direction; 00230 } 00231 00232 /** @} 00233 */ 00234 00235 int Motor_Start( int index ) 00236 { 00237 if ( index < 0 || index >= MOTOR_COUNT ) 00238 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00239 00240 struct Motor_* mp = &Motor[ index ]; 00241 if ( mp->users++ == 0 ) 00242 { 00243 mp->direction = 1; 00244 mp->speed = 0; 00245 00246 int status = PwmOut_SetActive( index, true ); 00247 if ( status != CONTROLLER_OK ) 00248 { 00249 mp->users--; 00250 return status; 00251 } 00252 } 00253 00254 return Motor_SetFinal( index, mp ); 00255 } 00256 00257 int Motor_Stop( int index ) 00258 { 00259 if ( index < 0 || index >= MOTOR_COUNT ) 00260 return CONTROLLER_ERROR_ILLEGAL_INDEX; 00261 00262 struct Motor_* mp = &Motor[ index ]; 00263 if ( --mp->users == 0 ) 00264 { 00265 return PwmOut_SetActive( index, false ); 00266 } 00267 00268 return CONTROLLER_OK; 00269 } 00270 00271 00272 static int Motor_SetFinal( int index, struct Motor_ * mp ) 00273 { 00274 int speed = mp->speed; 00275 // Work out the speed 00276 if ( !mp->direction ) 00277 speed *= -1; 00278 00279 // possibly add a dead zone inbetween? 00280 int status; 00281 if ( speed >= 0 ) 00282 status = PwmOut_SetAll( index, speed, 0, 1 ); 00283 else 00284 status = PwmOut_SetAll( index, -speed, 1, 0 ); 00285 return status; 00286 } 00287 00288 #ifdef OSC 00289 00290 /** \defgroup MotorOSC Motor - OSC 00291 Control DC motors with the Application Board via OSC. 00292 \ingroup OSC 00293 00294 \section devices Devices 00295 There are 4 DC Motor controllers available on the Application Board, numbered 0 - 3. 00296 00297 Each motor controller is composed of 2 adjacent Digital Outs on the Make Application Board: 00298 - motor 0 - Digital Outs 0 and 1. 00299 - motor 1 - Digital Outs 2 and 3. 00300 - motor 2 - Digital Outs 4 and 5. 00301 - motor 3 - Digital Outs 6 and 7. 00302 00303 \section properties Properties 00304 Each motor controller has three properties: 00305 - speed 00306 - direction 00307 - active 00308 00309 \par Speed 00310 The \b speed property corresponds to the speed at which a motor is being driven. 00311 This value can be both read and written. The range of values expected by the board 00312 is from 0 - 1023. A speed of 0 means the motor is stopped, and 1023 means it is 00313 being driven at full speed. 00314 \par 00315 To set the second motor (connected to Digital Outs 2 and 3) at half speed, send the message 00316 \verbatim /motor/1/speed 512 \endverbatim 00317 Leave the argument value off to read the speed of the motor: 00318 \verbatim /motor/1/speed \endverbatim 00319 00320 \par Direction 00321 The \b direction property corresponds to the forward/reverse direction of the motor. 00322 This value can be both read and written, and the range of values expected is simply 00323 0 or 1. 1 means forward and 0 means reverse. 00324 \par 00325 For example, to set the first motor to move in reverse, send the message 00326 \verbatim /motor/0/direction 0 \endverbatim 00327 Simply change the argument of 0 to a 1 in order to set the motor's direction to forward. 00328 00329 \par Active 00330 The \b active property corresponds to the active state of the motor. 00331 If the motor is set to be active, no other tasks will be able to 00332 use its 2 digital out lines. If you're not seeing appropriate 00333 responses to your messages to the motor, check the whether it's 00334 locked by sending a message like 00335 \verbatim /motor/0/active \endverbatim 00336 \par 00337 If you're no longer using the motor, you can free the 2 Digital Outs by 00338 sending the message 00339 \verbatim /motor/0/active 0 \endverbatim 00340 */ 00341 00342 #include "osc.h" 00343 #include "string.h" 00344 #include "stdio.h" 00345 00346 // Need a list of property names 00347 // MUST end in zero 00348 static char* MotorOsc_Name = "motor"; 00349 static char* MotorOsc_PropertyNames[] = { "active", "speed", "direction", 0 }; // must have a trailing 0 00350 00351 int MotorOsc_PropertySet( int index, int property, int value ); 00352 int MotorOsc_PropertyGet( int index, int property ); 00353 00354 // Returns the name of the subsystem 00355 const char* MotorOsc_GetName( ) 00356 { 00357 return MotorOsc_Name; 00358 } 00359 00360 // Now getting a message. This is actually a part message, with the first 00361 // part (the subsystem) already parsed off. 00362 int MotorOsc_ReceiveMessage( int channel, char* message, int length ) 00363 { 00364 int status = Osc_IndexIntReceiverHelper( channel, message, length, 00365 MOTOR_COUNT, MotorOsc_Name, 00366 MotorOsc_PropertySet, MotorOsc_PropertyGet, 00367 MotorOsc_PropertyNames ); 00368 00369 if ( status != CONTROLLER_OK ) 00370 return Osc_SendError( channel, MotorOsc_Name, status ); 00371 return CONTROLLER_OK; 00372 } 00373 00374 // Set the index LED, property with the value 00375 int MotorOsc_PropertySet( int index, int property, int value ) 00376 { 00377 switch ( property ) 00378 { 00379 case 0: 00380 Motor_SetActive( index, value ); 00381 break; 00382 case 1: 00383 Motor_SetSpeed( index, value ); 00384 break; 00385 case 2: 00386 Motor_SetDirection( index, value ); 00387 break; 00388 } 00389 return CONTROLLER_OK; 00390 } 00391 00392 // Get the index LED, property 00393 int MotorOsc_PropertyGet( int index, int property ) 00394 { 00395 int value = 0; 00396 switch ( property ) 00397 { 00398 case 0: 00399 value = Motor_GetActive( index ); 00400 break; 00401 case 1: 00402 value = Motor_GetSpeed( index ); 00403 break; 00404 case 2: 00405 value = Motor_GetDirection( index ); 00406 break; 00407 } 00408 00409 return value; 00410 } 00411 00412 #endif
The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.