The RCX Input Mux & Color Sensor


A multiplexer works by connecting multiple sensors to a single input one at a time.  Most computers employ a multiplexer in their analog to digital conversion hardware to save space and money.  In fact, the RCX has a multiplexer, but only three inputs are available for the user.  The RCX uses one of the other channels internally to read its own battery voltage.


The design of a multiplexer for the RCX is tricky.  Some obvious schemes use motor outputs with relays to select multiple sensors.  However, because the RCX only has three outputs, these methods do not seem very acceptable.  Something is needed that can sense that the RCX program wants to change to a different sensor without wasting one of the precious outputs.


In order to design an acceptable multiplexer you need to understand how the RCX reads its sensor inputs.  The RCX has two sensor modes, passive and powered.  Examples of passive types are touch and temperature sensors.   While powered types include the light and rotation sensors.


In the passive mode, the RCX measures a voltage on the input.  To make reading resistive sensors or switches easier, there is a 10K Ohm resistor trying to pull the input up to 5V.   In powered mode, the RCX applies about 8V to the input for 3ms and then reads the input just like a passive type during a short 0.1ms period.


By quickly toggling an input from powered mode to passive and back a multiplexer circuit could detect that the RCX program wanted to change to another sensor.  The selection of whether an input is in passive or powered mode can be changed on-the-fly from within programming languages like Not Quite C or Visual Basic.  Unfortunately, RCX Code and Lego's P-brick Script language does not allow this flexibility.


Limiting the type of multiplexed sensors to passive achieves a great simplification in the multiplexer design.  It means that only the sensor signals are switched and not the power to operate them.  Passive light sensing with Cadmium Sulfide (CdS) photocells works about as well as the Lego light sensor anyway. 




Figure 1 is the schematic of the sensor multiplexer.  It allows the three resistive sensors S1, S2 and S3 to share a single RCX input.  Good examples of resistive sensors are photocells, thermistors, and potentiometers.  Switches can also be used since they are just extreme examples of resistive sensors.



Diodes D1 through D4 and capacitor C2 form the power supply.  The full wave bridge arrangement allows the power connector attachment to the RCX to be in any orientation.  Make sure you observe the polarity of C2.  CMOS integrated circuits U1 and U2 have their power supply connections shown in tables next to VCC and GND.  VCC should measure at least 6V during normal operation with good batteries.


Integrated circuit U2 is a digital counter that sequences from zero to three and then resets.  Diodes D7 and D8 along with resistor R3 and capacitor C1 create the clock for U2.  The voltage on the clock input stays high during the normal powered mode reading of the sensor by the RCX, but drops low during the much longer time when the sensor input changes to passive.  When the sensor input toggles back to powered mode the circuit creates the rising edge needed to clock U2.


Integrated circuit U1 contains the analog switches used to connect one sensor to the RCX at a time.  U1A provides feedback to the RCX for synchronization.  Otherwise, you could not tell which sensor was connected.  Analog switch U1A closes when U2 counts zero and this connects the RCX through diode D5 or D6 and R1 to ground.  The reading created on the RCX under this condition is always 100.  The three sensors connect through R2, which is sized so that their maximum reading will never quite reach 100.


Figure 2 shows a range of inputs and the resulting reading on the RCX.  Either resistive sensors or voltages can be applied to the inputs.  The readings are backwards from what you might expect.  Zero volt results in a reading near 95 while about 4.3V is 0.  Zero resistance results in a reading near 95 while very high resistance reads 0. 





The parts needed to build the circuit are very common and available from most electronic suppliers.  Readers familiar with my Extreme Mindstorms book should recognize the construction method illustrated in Figures 3 and 4.  First you build and test the circuit on an electronic breadboard and then transfer the parts to the related prototype PC board.  Although the method works well, the results in are not very compact and there is a chance of wiring mistakes.  For this reason, I have prepared a small through-hole type PC board to make building and housing the circuit easier.




Figure 5 shows the populated PC board with three CdS photocells for sensors.  The particular photocells used (Mouser #338-54C348) are small enough to fit into the little recessed area around the holes in Lego Technic beams.   Short pieces of insulated tubing slid over the ungrounded lead of the photocells prevent shorting during operation.  All three photocells must be fed through the beam before soldering to the PC board.  A Tictac® candy box provides a simple enclosure for the completed project as shown in Figure 6.  Connection to the RCX is made by cutting a Lego #5111 9V Motor Wire in half.




Alternatively, the PC board is small enough for the project to be housed in a #5391 Lego 9V Battery Box.  This is a handy enclosure with a connector built right into the top.  It is easier to connect the sensors to a short piece of four-conductor wire when using this box.  Short wires soldered to the posts where the 9V battery would have attached couples the circuit to the Lego connector on the top of the box.




Color sensing depends on measuring the intensity of light at different wavelengths.  A spectrometer does this by splitting the light with a prism or diffraction grating into its component wavelengths.  However, spectrometers are complex and too difficult to build.  Another approach measures the light intensity in three primary color bands: red, green, and blue.   Then calculates the color or hue of the light in software.


Hue is a single number that describes the overall color of a light.  It ranges from 0 to 360, much like the degrees of angle around a circle.  In the case of hue: 0 is red, 120 is green, 240 is blue and 360 is back around to red again.  Intermediate colors have hues like 60 for yellow, 180 for cyan and 300 for magenta.  The calculation of hue from red, green and blue values is a simple algorithm described later.


My first approach was to use colored LED lenses for filters.  You can see them in Figure 3.  They turned out to be too pale and off color for accurate measurements.  Then I investigated using transparent Lego plates.  They are available red, green and blue in the Lego #5316 Transparent Accessories kit.  They plug perfectly into holes of Technic beams to form filters for the CdS sensors shown in Figure 6.


After substantial experimentation, I found that the blue and green plates were too pale for use individually.  Stacking two green and three blue plates created enough filter density for good color measurement.  The actual color spectrum of the resulting filters can be seen by photographing sunlight shining through them with a diffraction grating as shown in Figure 8.


The spectral sensitivity of the photocell is another important factor in determining the color measurement accuracy.  Not all CdS photocells are alike in this regard.  The best type for color discrimination is called Type 5.  It has peak sensitivity at about 560nm in the green part of the spectrum.  Most other photocell types tend to be too red or even infrared sensitive.  I have experimented with photocells from several sources and found the Mouser #338-54C348 has the best spectral response as well as the desirable geometry for mounting previously mentioned.




Listing 1 is a Not Quite C program that controls the multiplexer and converts the red, green and blue intensities into a hue value.  It turns the RCX into a simple colorimeter by continuously displaying the hue on its LCD.  Using the sensor to build a robotic Lego brick sorter would be a more useful application of the sensor.


// Color Sensor Demonstration Program

// by Michael Gasperi

#define COLOR SENSOR_1               //color sensor on sensor port 1

#define SHORT_WAIT 2                 //short wait for value to stabilize

int hue;                             //hue as a global 

task main()


  int r,g,b,max,min,d,rd,gd,bd,h;    //declare all other variables

  SetUserDisplay (hue,0);            //set display to show hue value

  SetSensor(COLOR, SENSOR_LIGHT);    //power on sensor by making it light type

  while (true)                       //loop forever


    while (COLOR != 100)             //only mux channel 0 will read 100


      SetSensor(COLOR, SENSOR_TOUCH);//power off sensor by making touch

      SetSensor(COLOR, SENSOR_LIGHT);//reapply power to toggle channel

      Wait(SHORT_WAIT);              //wait for reading to stabilize

      PlaySound(SOUND_LOW_BEEP);     //alarm sound


    SetSensor(COLOR, SENSOR_TOUCH);  //toggle power to change to channel 1



    r = COLOR*100;                   //read the red and scale by 100

    SetSensor(COLOR, SENSOR_TOUCH);  //toggle power to change to channel 2



    g = COLOR*100;                   //read the green and scale by 100

    SetSensor(COLOR, SENSOR_TOUCH);  //toggle power to change to channel 3



    b = COLOR*100;                   //read the blue color scale by 100  

    SetSensor(COLOR, SENSOR_TOUCH);  //toggle power to change to channel 0


    if(r>g){max = r;}else{max = g;}  //find the color with max intensity


    if(r<g){min = r;}else{min = g;}  //find the color with min intensity


    d = ((max-min)/60);              //diff of max and min also scale

    rd = (max - r)/d;                //normalize color intensity

    gd = (max - g)/d;

    bd = (max - b)/d;

    if(b==max){h = 240 + gd - rd;}   //compute hue based on max color

    if(g==max){h = 120 + rd - bd;}

    if(r==max){h = bd - gd;}

    if(h<0){h = h + 360;}            //if hue is negative add 360

    hue = h;




After variable declaration and initialization there is a "while color not equal to 100" loop.  This loop handles synchronization to make sure that the multiplexer is on the right count.  Only when the counter in the multiplexer is zero will the reading be 100.  The program keeps toggling the power and clocking the multiplexer until it reads 100. 


There is a PlaySound call at the bottom of the loop that makes a buzz sound.   This signals that synchronization is taking place.  After the first time through, the program should not need to go into this loop again.  If the RCX keeps making the buzz sound for more than a few seconds, there is something wrong with the multiplexer.


The next program steps toggle the power and read the red, green and blue values.  Because the RCX only has integer math, the values need to be scaled up by 100 for later arithmetic.  In integer math 1 divided by 4 results in 0 not 0.25 since there is no fractional part.  By scaling the denominator by one hundred before the division, the result becomes 25.  An additional toggle of the power after reading blue sets the multiplexer to start the process over again.


Hue calculation requires first determining which color had the maximum and which had minimum value.  After that, the difference between the maximum and minimum is calculated.  Then dividing by the difference normalizes the color intensities.  Ordinarily you would need to be concerned about the unlikely event that the difference equaled zero, but the RCX makes the result of division by zero simply zero.  The hue is computed using the color with the maximum value.  If the hue is negative, adding 360 fixes the result.




Figure 9 shows how well the color sensor works.  The chart compares the hue of nearly 100 different light sources to the RCX reading. Transmission values were obtained by shining broad-spectrum fluorescent light through transparent filters manufactured by Rosco Laboratories Ltd. and available from Edmund Scientific as catalog number CR30394-17.  A Rosco engineer sent me the equivalent red, green and blue values of the filters, which were used to calculate the expected hue.  Emission values were taken by holding the sensor against a solid color window on the screen of a computer monitor.  A simple Visual Basic program allowed control of the red, green and blue color components for the color of the window.  The reflected values where measured by reflecting light off the color samples of a test pattern in a Kodak Professional Photoguide.



It looks like the hue measurement is accurate within plus or minus 60.  That means for example, you might not be able to discriminate between green and cyan, but you certainly can tell green from blue.  The color and type of light source has a significant effect on the accuracy too.  If you use the color sensor to sort bricks, you need to calibrate the hue reading for the bricks you want to sort with a controlled light source.


Click Here to Return to the Main Page