- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# motor.c

Go to the documentation of this file.

    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.