Skip to content →

p-comp / midterm – rgb light to cmyk pigment

for the p-comp midterm me and Nilomee decided to make a RGB to CMYK converter, in which you pick the light color and get the correspondent color pigment. In simple steps, we wanted the whole mechanism to work in this order:

  1. set the amount of red, green and blue you want;
  2. save this color;
  3. convert this color from RGB color mode to CMYK;
  4. put the percentage of each of the colors of the CMYK mode inside a recipient;
  5. mix the colors;
  6. print them on a paper.

Also developing the process in this order, we chose to work with three potentiometers and a RGB LED light so that the user can pick separately the amount of each color(red, green and blu). Once the user had set the color, he/she would click on a button to save the value of each channel.


After we had the RGB value, it was time to convert it do CMYK. We searched over the internet for formulas that would easily convert them and we didn’t find any that was clear to the program or that gave precise values (they would only point if any of the channels were present or not). So we decided to figure out by ourselves the formula, which started very confusing because the RGB works with a range of amounts (0-255) and the CMYK works with percentage (0-100) that are independent of each other. Also, it was confusing to know when the shade of a color got lighter/darker due to the opposite behaviours each of them have on the two color modes and what was the exact correspondency between those systems (which colors on RGB generate colocr channels of the CMYK and vice-versa).

After some brain melting, we decided to use 255 as the value that represent 100% on the CMYK and to create the exceptions. If all the channels of the RGB are 0, we have 100% in all CMYK channels(black) and if we have 255 in all RGB channels, all colors are 0% (white). And we found the proportion between the color correspondency between RGB to CMYK. The colors are not exactly the same, but they are as close as possible


C = G + B

G and B have the same proportion and we know they have to be on their maximum value to get 100% cyan.

100C = 255G + 255B



B = C + M

And to have Blue, you have cyan and magenta at 100% and 0% of yellow or black.

255B = 100C + 100M + 0Y + 0K

So not only we mapped the potentiometer values (0-1023) to the RGB colors (0-255), but we also mapped the RGB colors(0-255) into CMYK correspondents(0-100).

//RGB LED declare
int pin1 = 11; //red
int pin2 = 10; // green
int pin3 = 9; // blue

// switch button
int switchPin1 = 7;

// RGB color combinationl
int colorRed;
int colorGreen;
int colorBlue;

// CMYK color combination
int colorC;
int colorM;
int colorY;
int colorK;
void setup() {
//RGB LED individual pins as output
pinMode(pin1, OUTPUT); //RED
pinMode(pin2, OUTPUT); //GREEN
pinMode(pin3, OUTPUT); //BLUE

//switch button as input
pinMode(switchPin1, INPUT);

void loop() {
//map potentiometer1 to output Red's value
int pot1 = analogRead(A0);
int pot1converted = map(pot1, 0, 1023, 0, 255);
analogWrite(pin1, pot1converted);

//map potentiometer2 to output Green's value
int pot2 = analogRead(A1);
int pot2converted = map(pot2, 0, 1023, 0, 255);
analogWrite(pin2, pot2converted);

//map potentiometer3 to output Blue's value
int pot3 = analogRead(A2);
int pot3converted = map(pot3, 0, 1023, 0, 255);
analogWrite(pin3, pot3converted);

//if button is pushed, save the RGB combination
if (digitalRead(switchPin1) == 1) {
int colorRed = pot1converted;
int colorGreen = pot2converted;
int colorBlue = pot3converted;

Serial.print("RGB color = ");

colorC = (map(colorBlue, 0, 255, 0, 100) + map(colorGreen, 0, 255, 0, 100)) / 2;
colorM = (map(colorBlue, 0, 255, 0, 100) + map(colorRed, 0, 255, 0, 100)) / 2;
colorY = (map(colorRed, 0, 255, 0, 100) + map(colorGreen, 0, 255, 0, 100)) / 2;
if (colorRed == 0 && colorGreen == 0 && colorBlue == 0) {
colorC = 100;
colorM = 100;
colorY = 100;
colorK = 100;
if (colorRed == 255 && colorGreen == 255 && colorBlue == 255) {
colorC = 0;
colorM = 0;
colorY = 0;
colorK = 0;
Serial.print("CMYK color = ");


Once we had the CMYK values, we started to test the ink dripping – this was definitely the trickiest part of the process and that we ended up spending more time than we could. We wanted to make a treadmill in which you would have each color hanging in recipients above it. A small recipient would be over the treadmil’s belt; it would stop below each color recipient and wait for the color to drip the right amount before moving on to the next color.

pcomp-midterm-02At first, we wanted this part of the machine to be fully automated: once you pick your color on the LED, it would start to move the recipient to the first color, count how many drops of ink felt and then move on to the other color. But then we saw that it would demand a bigger time to: analyze the rhythm in which the ink dripped and also what kind of mechanism would we use to stop/star tthe dripping.


After talking with Jeff and Pedro (one of the residents), we saw that we had some possibilities to do so: use a syringe + mechanism to press it, use a dropper + solenoid, use a peristaltic pump or leave the recipients dripping and control the time they stay under each color.

Because of time and budget limitations, we experimented the dropper and the control time options. We tried using the dropper of the ink itself and it was made of a plastic that was too rigid, so it wouldn’t vary that much when pressed with a solenoid or a servo motor. So we moved on and tried to work with time duration and the dripping. Calculating how many drops per second was not that precise to translate it in time duration because the pace would vary according to the volume of the flask.

In the end, we decided that the more manageable alternative to do so was to leave all recipients continually dripping (with a recipient below the treadmill) and the user controls how much time the pot stays below each color ( ideally counting the drops) by pressing a button to make the recipient over the threadmill move.



int switchPin = 3;

Servo myServo;
int angle = 0;
int buttonState = 0;

void setup() {
  pinMode(switchPin, INPUT);


void loop() {

  buttonState = digitalRead(switchPin);
  if (buttonState == HIGH) {
    angle = angle + 30;
    Serial.print("angle =");
    if (angle > 180) {
      angle = 0;

To make the treadmill, we used two servo motors and tested several sizes of gears attached to the servos, that had a belt over them. We opted to get bigger gears to have a bigger distance between the recipients, so we started prototyping for the final version – and that’s when things got tangled. I think that the part that demanded knowlegde that neither me or Nilomee have was the fabrication part. We perceived to build it, but there were some measurements and pieces placement that we didn’t think it through that much and once we had the final pieces, it wouldn’t fit.


However, for the purpose of illustration and delightment, here’s a picture of our little frankenstein:


It was great working with Nilomee, I think we were able to colaborate and build up this project a lot due to our different interests/background. We definitely need to get better on our fabrication skills – which means we did the right thing of taking intro to fabrication on the 2nd session. Right on time for the final =)

Published in fall 2015 p-comp

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *