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

- File List
- Globals

# analogin.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 analogin.c
    00021   Functions for reading the analog inputs on the MAKE Application Board.
    00022 */
    00023
    00024 /* Library includes. */
    00025 #include <string.h>
    00026 #include <stdio.h>
    00027
    00028 /* Scheduler includes. */
    00029 #include "FreeRTOS.h"
    00030 #include "task.h"
    00031 #include "semphr.h"
    00032
    00033 /* Hardware specific headers. */
    00034 #include "Board.h"
    00035 #include "AT91SAM7X256.h"
    00036
    00037 #include "config.h"
    00038
    00039 #include "io.h"
    00040
    00041 #include "analogin.h"
    00042 #include "analogin_internal.h"
    00043
    00044 #define ANALOGIN_0_IO IO_PB27
    00045 #define ANALOGIN_1_IO IO_PB28
    00046 #define ANALOGIN_2_IO IO_PB29
    00047 #define ANALOGIN_3_IO IO_PB30
    00048
    00049 #define AUTOSENDSAVE 0xDF
    00050
    00051 static int AnalogIn_Start( int index );
    00052 static int AnalogIn_Stop( int index );
    00053
    00054 static int AnalogIn_Init( void );
    00055 static int AnalogIn_Deinit( void );
    00056
    00057 static int AnalogIn_GetIo( int index );
    00058
    00059 extern void ( AnalogInIsr_Wrapper )( void );
    00060
    00061 struct AnalogIn_* AnalogIn;
    00062
    00063 /** \defgroup AnalogIn Analog Inputs
    00064   The AnalogIn subsystem converts 0-3.3V signals to 10-bit digital values.
    00065   The analog to digital converters read incoming signals from 0 - 3.3V.  They are rated as 5V tolerant,
    00066   and indeed can momentarily withstand higher voltages, but will not return meaningful values for anything
    00067   above 3.3V.\n
    00068
    00069   Converting the 0 - 1023 reading of the AnalogIn channel into a voltage is performed as follows:
    00070    \verbatim v = 3.3 * ( a / 1023.0 ) \endverbatim
    00071     where a is the AnalogIn value
    00072
    00073   This is of course a floating point operation (slowish) using a division (slowish).  Fixed point
    00074   versions may be more suitable for some applications.  Where reduced accuracy is acceptable, the following
    00075   can be used to get the input as a percentage of 3.3V:
    00076   \verbatim  p = ( 100 * a ) / 1023 \endverbatim
    00077
    00078   Initializing the controller's AnalogIn system is pretty involved (see AnalogIn_Init() in AnalogIn->c).  There are a lot of
    00079   different options - different converter speeds, DMA access, etc.  We've chosen something pretty simple here.
    00080   More ambitious users may wish to alter the implementation.
    00081
    00082   \todo Provide multi-channel conversion routines
    00083
    00084   \ingroup Core
    00085   @{
    00086 */
    00087
    00088 /**
    00089   Sets whether the specified channel is active.
    00090   This initializes the AnalogIn system and gets a lock on its IO lines.  It only needs to be called once.
    00091   @param index An integer specifying the channel (0 - 7).
    00092   @param state An integer specifying the active state - 1 (active) or 0 (inactive).
    00093   @return Zero on success.
    00094
    00095
    00096   \par Example
    00097   \code
    00098   if( AnalogIn_SetActive( 0, 1 )  == CONTROLLER_OK ) // set analogin 0 to active
    00099     // then continue processing
    00100   else
    00101     // some error occurred
    00102   \endcode
    00103 */
    00104 int AnalogIn_SetActive( int index, int state )
    00105 {
    00106   if ( index < 0 || index >= ANALOGIN_CHANNELS )
    00107     return CONTROLLER_ERROR_ILLEGAL_INDEX;
    00108
    00109   if ( state )
    00110   {
    00111     if( AnalogIn == NULL )
    00112     {
    00113       AnalogIn = MallocWait( sizeof( struct AnalogIn_ ), 100 );
    00114       AnalogIn->users = 0;
    00115       int i;
    00116       for( i = 0; i < ANALOGIN_CHANNELS; i++ )
    00117         AnalogIn->channelUsers[ i ] = 0;
    00118       #ifdef OSC
    00119       AnalogIn_AutoSendInit( );
    00120       #endif
    00121     }
    00122
    00123     return AnalogIn_Start( index );
    00124   }
    00125   else
    00126   {
    00127     // TODO: check if any channels are still active and if not, Free( ) the AnalogIn struct
    00128     return AnalogIn_Stop( index );
    00129   }
    00130 }
    00131
    00132 /**
    00133   Returns the active state of a channel.
    00134   @param index An integer specifying the ANALOGIN channel (0 - 7).
    00135   @return State - 1/non-zero (active) or 0 (inactive).
    00136
    00137   \par Example
    00138   \code
    00139   int active = AnalogIn_GetActive( 0 ) // check whether analogin 0 is active
    00140   \endcode
    00141 */
    00142 int AnalogIn_GetActive( int index )
    00143 {
    00144   if( AnalogIn == NULL )
    00145     return 0;
    00146
    00147   if ( index < 0 || index >= ANALOGIN_CHANNELS )
    00148     return false;
    00149   return AnalogIn->channelUsers[ index ] > 0;
    00150 }
    00151
    00152 /**
    00153   Read the value of an analog input.
    00154   @param index An integer specifying which input (0-7).
    00155   @return The value as an integer (0 - 1023).
    00156
    00157   \par Example
    00158   \code
    00159   int analogin1 = AnalogIn_GetValue( 1 );
    00160   \endcode
    00161 */
    00162 int AnalogIn_GetValue( int index )
    00163 {
    00164   AnalogIn_SetActive( index, 1 );
    00165   if ( index < 0 || index >= ANALOGIN_CHANNELS )
    00166     return CONTROLLER_ERROR_ILLEGAL_INDEX;
    00167
    00168   if ( AnalogIn->channelUsers[ index ] < 1 )
    00169   {
    00170     int status = AnalogIn_Start( index );
    00171     if ( status != CONTROLLER_OK )
    00172       return status;
    00173   }
    00174
    00175   int value;
    00176
    00177   if ( !xSemaphoreTake( AnalogIn->semaphore, 1000 ) )
    00178     return -1;
    00179
    00180   /* Third Step: Select the active channel */
    00181   int mask = 1 << index;
    00182   AT91C_BASE_ADC->ADC_CHDR = ~mask;
    00183   AT91C_BASE_ADC->ADC_CHER = mask;
    00184
    00185   /* Fourth Step: Start the conversion */
    00186   AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
    00187
    00188   /* Busy wait */
    00189   // while ( !( AT91C_BASE_ADC->ADC_CHSR  & ( 1 << index ) ) );
    00190
    00191   if ( !xSemaphoreTake( AnalogIn->doneSemaphore, 1000 ) )
    00192     return -1;
    00193
    00194   value = AT91C_BASE_ADC->ADC_LCDR & 0xFFFF;
    00195
    00196   xSemaphoreGive( AnalogIn->semaphore );
    00197
    00198   return value;
    00199 }
    00200
    00201 /**
    00202   Read the value of several of the analog inputs.
    00203   Due to the current ISR handling, this isn't too much quicker than making
    00204   calls to each of the channels individually.
    00205   @param mask A bit mask specifying which channels to read.
    00206   @param values A pointer to an int array to be filled with the values.
    00207   @return 0 on success, otherwise non-zero.
    00208
    00209   \par Example
    00210   \code
    00211   int mask = 0xFF;
    00212   int samples[8];
    00213   AnalogIn_GetValueMulti( mask, samples ); // now samples is filled with all the analogin values
    00214   \endcode
    00215 */
    00216 int AnalogIn_GetValueMulti( int mask, int values[] )
    00217 {
    00218   //AnalogIn_SetActive( 1 );
    00219   if ( mask < 0 || mask > 255 ) // check the value is a valid 8-bit mask
    00220     return CONTROLLER_ERROR_ILLEGAL_INDEX;
    00221
    00222   int i; // Is this the best way to make sure everything is started up properly?
    00223   for( i = 0; i < 8; i++ )
    00224   {
    00225     if( mask >> i & 1 )
    00226     {
    00227       if ( AnalogIn->channelUsers[ i ] < 1 )
    00228       {
    00229         int status = AnalogIn_Start( i );
    00230         if ( status != CONTROLLER_OK )
    00231         return status;
    00232       }
    00233     }
    00234   }
    00235
    00236   if ( !xSemaphoreTake( AnalogIn->semaphore, 1000 ) )
    00237     return -1;
    00238
    00239   /* Third Step: Select the active channels */
    00240   AT91C_BASE_ADC->ADC_CHDR = ~mask;
    00241   AT91C_BASE_ADC->ADC_CHER = mask;
    00242
    00243   /* Fourth Step: Start the conversion */
    00244   AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
    00245
    00246   if ( !xSemaphoreTake( AnalogIn->doneSemaphore, 1000 ) )
    00247     return -1;
    00248
    00249   //Figure out which of the channels we want to read
    00250   volatile uint* reg = &AT91C_BASE_ADC->ADC_CDR0; // the address of the first ADC result register
    00251   for( i = 0; i < 8; i++ )
    00252   {
    00253     if( mask >> i & 1 )
    00254       values[ i ] = *reg++ & 0xFFFF;
    00255   }
    00256
    00257   xSemaphoreGive( AnalogIn->semaphore );
    00258
    00259   return CONTROLLER_OK;
    00260 }
    00261
    00262 /**
    00263   Read the value of an analog input without the use of any OS services.
    00264   Note that this is not thread safe and shouldn't be used if another
    00265   part of the code might be using it or the thread safe versions.
    00266   @param index An integer specifying which input (0-7).
    00267   @return The value as an integer (0 - 1023).
    00268
    00269   \par Example
    00270   \code
    00271   int analogin1 = AnalogIn_GetValueWait( 1 );
    00272   \endcode
    00273 */
    00274 int AnalogIn_GetValueWait( int index )
    00275 {
    00276   AnalogIn_SetActive( index, 1 );
    00277   if ( index < 0 || index >= ANALOGIN_CHANNELS )
    00278     return CONTROLLER_ERROR_ILLEGAL_INDEX;
    00279
    00280   if ( AnalogIn->channelUsers[ index ] < 1 )
    00281   {
    00282     int status = AnalogIn_Start( index );
    00283     if ( status != CONTROLLER_OK )
    00284       return status;
    00285   }
    00286
    00287   int value = 0;
    00288
    00289   // Third Step: Select the active channel
    00290   int mask = 1 << index;
    00291   AT91C_BASE_ADC->ADC_CHDR = ~mask;
    00292   AT91C_BASE_ADC->ADC_CHER = mask;
    00293
    00294   AT91C_BASE_ADC->ADC_IDR = AT91C_ADC_DRDY;
    00295
    00296   // Fourth Step: Start the conversion
    00297   AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
    00298
    00299   value++;
    00300   value++;
    00301
    00302   // Busy wait
    00303   while ( !( AT91C_BASE_ADC->ADC_SR & AT91C_ADC_DRDY ) )
    00304     value++;
    00305
    00306   AT91C_BASE_ADC->ADC_IDR = AT91C_ADC_DRDY;
    00307
    00308   value = AT91C_BASE_ADC->ADC_LCDR & 0xFFFF;
    00309
    00310   return value;
    00311 }
    00312
    00313 /** @}
    00314 */
    00315
    00316 #ifdef OSC
    00317 void AnalogIn_AutoSendInit( )
    00318 {
    00319   int autosend;
    00320   Eeprom_Read( EEPROM_ANALOGIN_AUTOSEND, (uchar*)&autosend, 4 );
    00321   if( !((autosend >> 16) & 0xFF) == AUTOSENDSAVE )
    00322     AnalogIn->autosend = AUTOSENDSAVE << 16;
    00323   else
    00324     AnalogIn->autosend = autosend;
    00325 }
    00326 #endif
    00327
    00328 int AnalogIn_Start( int index )
    00329 {
    00330   if ( index < 0 || index >= ANALOGIN_CHANNELS )
    00331     return CONTROLLER_ERROR_ILLEGAL_INDEX;
    00332   if ( AnalogIn->channelUsers[ index ]++ == 0 )
    00333   {
    00334     int status;
    00335
    00336     // The lower four channel pins are shared with other subsystems, so no locking
    00337     if ( index < 4 )
    00338     {
    00339       int io = AnalogIn_GetIo( index );
    00340       status = Io_Start( io, false );
    00341       if ( status != CONTROLLER_OK )
    00342       {
    00343         AnalogIn->channelUsers[ index ]--;
    00344         return status;
    00345       }
    00346
    00347       Io_SetPullup( io, false );
    00348     }
    00349
    00350     if ( AnalogIn->users++ == 0 )
    00351     {
    00352       AnalogIn_Init();
    00353     }
    00354   }
    00355
    00356   return CONTROLLER_OK;
    00357 }
    00358
    00359 int AnalogIn_Stop( int index )
    00360 {
    00361   if ( index < 0 || index >= ANALOGIN_CHANNELS )
    00362     return CONTROLLER_ERROR_ILLEGAL_INDEX;
    00363   if ( AnalogIn->channelUsers[ index ] <= 0 )
    00364     return CONTROLLER_ERROR_TOO_MANY_STOPS;
    00365   if ( --AnalogIn->channelUsers[ index ] == 0 )
    00366   {
    00367     if ( index < 4 )
    00368     {
    00369       int io = AnalogIn_GetIo( index );
    00370       Io_Stop( io );
    00371     }
    00372     if ( --AnalogIn->users == 0 )
    00373     {
    00374       AnalogIn_Deinit();
    00375     }
    00376   }
    00377   return CONTROLLER_OK;
    00378 }
    00379
    00380 int AnalogIn_Init()
    00381 {
    00382   // Enable the peripheral clock
    00383   AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_ADC;
    00384
    00385   // Set up
    00386   AT91C_BASE_ADC->ADC_MR =
    00387        AT91C_ADC_TRGEN_DIS | // Hardware Trigger Disabled
    00388     // AT91C_ADC_TRGEN_EN  | // Hardware Trigger Disabled
    00389     //   AT91C_ADC_TRGSEL_ | // Hardware Trigger Disabled
    00390     // AT91C_ADC_TRGSEL_TIOA0  | // Trigger Selection Don't Care
    00391        AT91C_ADC_LOWRES_10_BIT | // 10 bit conversion
    00392     // AT91C_ADC_LOWRES_8_BIT | // 8 bit conversion
    00393        AT91C_ADC_SLEEP_NORMAL_MODE | // SLEEP
    00394     // AT91C_ADC_SLEEP_MODE | // SLEEP
    00395        ( ( 9 << 8 ) & AT91C_ADC_PRESCAL ) | // Prescale rate (8 bits)
    00396        ( ( 127 << 16 ) & AT91C_ADC_STARTUP ) | // Startup rate
    00397        ( ( 127 << 24 ) & AT91C_ADC_SHTIM ); // Sample and Hold Time
    00398
    00399   //TODO: Will need to fine-tune these timings.
    00400
    00401   // Do the OS stuff
    00402
    00403   vSemaphoreCreateBinary( AnalogIn->semaphore );
    00404
    00405   // Create the sempahore that will be used to wake the calling process up
    00406   vSemaphoreCreateBinary( AnalogIn->doneSemaphore );
    00407   xSemaphoreTake( AnalogIn->doneSemaphore, 0 );
    00408
    00409   // Initialize the interrupts
    00410   // WAS AT91F_AIC_ConfigureIt( AT91C_ID_ADC, 3, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) AnalogInIsr_Wrapper );
    00411   // Which is defined at the bottom of the AT91SAM7X256.h file
    00412   unsigned int mask ;
    00413
    00414   mask = 0x1 << AT91C_ID_ADC;
    00415
    00416   /* Disable the interrupt on the interrupt controller */
    00417   AT91C_BASE_AIC->AIC_IDCR = mask ;
    00418   /* Save the interrupt handler routine pointer and the interrupt priority */
    00419   AT91C_BASE_AIC->AIC_SVR[ AT91C_ID_ADC ] = (unsigned int)AnalogInIsr_Wrapper;
    00420   /* Store the Source Mode Register */
    00421   AT91C_BASE_AIC->AIC_SMR[ AT91C_ID_ADC ] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 4  ;
    00422   /* Clear the interrupt on the interrupt controller */
    00423   AT91C_BASE_AIC->AIC_ICCR = mask ;
    00424
    00425   AT91C_BASE_ADC->ADC_IER = AT91C_ADC_DRDY;
    00426
    00427   AT91C_BASE_AIC->AIC_IECR = mask;
    00428
    00429   return CONTROLLER_OK;
    00430 }
    00431
    00432 int AnalogIn_Deinit()
    00433 {
    00434   return CONTROLLER_OK;
    00435 }
    00436
    00437 int AnalogIn_GetIo( int index )
    00438 {
    00439   int io = -1;
    00440   switch ( index )
    00441   {
    00442     case 0:
    00443       io = ANALOGIN_0_IO;
    00444       break;
    00445     case 1:
    00446       io = ANALOGIN_1_IO;
    00447       break;
    00448     case 2:
    00449       io = ANALOGIN_2_IO;
    00450       break;
    00451     case 3:
    00452       io = ANALOGIN_3_IO;
    00453       break;
    00454   }
    00455   return io;
    00456 }
    00457
    00458 #ifdef OSC
    00459
    00460 /**
    00461   Read whether a particular channel is enabled to check for and send new values automatically.
    00462   @param index An integer specifying which input (0-7).
    00463   @return True if enabled, false if disabled.
    00464 */
    00465 bool AnalogIn_GetAutoSend( int index )
    00466 {
    00467   AnalogIn_SetActive( index, 1 );
    00468   return (AnalogIn->autosend >> index) & 0x01;
    00469 }
    00470
    00471 /**
    00472   Set whether a particular channel is enabled to check for and send new values automatically.
    00473   @param index An integer specifying which input (0-7).
    00474   @param onoff A boolean specifying whether to turn atuosending on or off.
    00475 */
    00476 void AnalogIn_SetAutoSend( int index, bool onoff )
    00477 {
    00478   AnalogIn_SetActive( index, 1 );
    00479   if( ((AnalogIn->autosend >> index) & 0x01) != onoff )
    00480   {
    00481     int mask = (1 << index);
    00482     if( onoff )
    00483       AnalogIn->autosend |= mask;
    00484     else
    00485       AnalogIn->autosend &= ~mask;
    00486
    00487     Eeprom_Write( EEPROM_ANALOGIN_AUTOSEND, (uchar*)&AnalogIn->autosend, 4 );
    00488   }
    00489 }
    00490
    00491 /** \defgroup AnalogInOSC Analog In - OSC
    00492   Read the Application Board's Analog Inputs via OSC.
    00493   \ingroup OSC
    00494
    00495   \section devices Devices
    00496   There are 8 Analog Inputs on the Make Application Board, numbered 0 - 7.
    00497
    00498   \section properties Properties
    00499   The Analog Ins have three properties:
    00500   - value
    00501   - active
    00502   - autosend
    00503
    00504   \par Value
    00505   The \b value property corresponds to the incoming signal of an Analog In.
    00506   The range of values you can expect to get back are from 0 - 1023.
    00507   Because you can only ever \em read the value of an input, you'll never
    00508   want to include an argument at the end of your OSC message to read the value.\n
    00509   To read the sixth Analog In, send the message
    00510   \verbatim /analogin/5/value \endverbatim
    00511   The board will then respond by sending back an OSC message with the Analog In value.
    00512
    00513   \par Autosend
    00514   The \b autosend property corresponds to whether an analogin will automatically send a message
    00515   when its incoming value changes.
    00516   To tell the Controller to automatically send messages from analogin 4, send the message
    00517   \verbatim /analogin/5/autosend 1 \endverbatim
    00518   To have the Controller stop sending messages from analogin 4, send the message
    00519   \verbatim /analogin/5/autosend 0 \endverbatim
    00520   All autosend messages send at the same interval.  You can set this interval, in
    00521   milliseconds, by sending the message
    00522   \verbatim /system/autosend-interval 10 \endverbatim
    00523   so that messages will be sent every 10 milliseconds.  This can be anywhere from 1 to 5000 milliseconds.
    00524   \par
    00525   You also need to select whether the board should send to you over USB or Ethernet.  Send
    00526   \verbatim /system/autosend-usb 1 \endverbatim
    00527   to send via USB, and
    00528   \verbatim /system/autosend-udp 1 \endverbatim
    00529   to send via Ethernet.  Via Ethernet, the board will send messages to the last address it received a message from.
    00530
    00531   \par Active
    00532   The \b active property corresponds to the active state of an Analog In.
    00533   If an Analog In is set to be active, no other tasks will be able to
    00534   read from it as an Analog In.  If you're not seeing appropriate
    00535   responses to your messages to the Analog In, check the whether it's
    00536   locked by sending a message like
    00537   \verbatim /analogin/0/active \endverbatim
    00538   \par
    00539   You can set the active flag by sending
    00540   \verbatim /analogin/0/active 1 \endverbatim
    00541 */
    00542
    00543 #include "osc.h"
    00544 #include "string.h"
    00545 #include "stdio.h"
    00546
    00547 // Need a list of property names
    00548 // MUST end in zero
    00549 static char* AnalogInOsc_Name = "analogin";
    00550 static char* AnalogInOsc_PropertyNames[] = { "active", "value", "autosend", 0 }; // must have a trailing 0
    00551
    00552 int AnalogInOsc_PropertySet( int index, int property, int value );
    00553 int AnalogInOsc_PropertyGet( int index, int property );
    00554
    00555 // Returns the name of the subsystem
    00556 const char* AnalogInOsc_GetName( )
    00557 {
    00558   return AnalogInOsc_Name;
    00559 }
    00560
    00561 // Now getting a message.  This is actually a part message, with the first
    00562 // part (the subsystem) already parsed off.
    00563 int AnalogInOsc_ReceiveMessage( int channel, char* message, int length )
    00564 {
    00565   int status = Osc_IndexIntReceiverHelper( channel, message, length,
    00566                                      ANALOGIN_CHANNELS, AnalogInOsc_Name,
    00567                                      AnalogInOsc_PropertySet, AnalogInOsc_PropertyGet,
    00568                                      AnalogInOsc_PropertyNames );
    00569   if ( status != CONTROLLER_OK )
    00570     return Osc_SendError( channel, AnalogInOsc_Name, status );
    00571   return CONTROLLER_OK;
    00572
    00573 }
    00574
    00575 // Set the index LED, property with the value
    00576 int AnalogInOsc_PropertySet( int index, int property, int value )
    00577 {
    00578   switch ( property )
    00579   {
    00580     case 0:
    00581       AnalogIn_SetActive( index, value );
    00582       break;
    00583     case 2: // autosend
    00584       AnalogIn_SetAutoSend( index, value );
    00585       break;
    00586   }
    00587   return CONTROLLER_OK;
    00588 }
    00589
    00590 // Get the index LED, property
    00591 int AnalogInOsc_PropertyGet( int index, int property )
    00592 {
    00593   int value = 0;
    00594   switch ( property )
    00595   {
    00596     case 0:
    00597       value = AnalogIn_GetActive( index );
    00598       break;
    00599     case 1:
    00600       value = AnalogIn_GetValue( index );
    00601       break;
    00602     case 2: // autosend
    00603       value = AnalogIn_GetAutoSend( index );
    00604       break;
    00605   }
    00606
    00607   return value;
    00608 }
    00609
    00610 int AnalogInOsc_Async( int channel )
    00611 {
    00612   int newMsgs = 0;
    00613   char address[ OSC_SCRATCH_SIZE ];
    00614   int i;
    00615   int value;
    00616   for( i = 0; i < ANALOGIN_CHANNELS; i ++ )
    00617   {
    00618     if( !AnalogIn_GetAutoSend( i ) )
    00619       continue;
    00620     value = AnalogIn_GetValue( i );
    00621     if( value != AnalogIn->lastValues[i] )
    00622     {
    00623       AnalogIn->lastValues[i] = value;
    00624       snprintf( address, OSC_SCRATCH_SIZE, "/%s/%d/value", AnalogInOsc_Name, i );
    00625       Osc_CreateMessage( channel, address, ",i", value );
    00626       newMsgs++;
    00627     }
    00628   }
    00629
    00630   return newMsgs;
    00631 }
    00632
    00633 #endif // OSC

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.