Archive for the ‘Ambilamp’ Category

  • Ambilamp code

    Date: 2010.04.22 | Category: Ambilamp | Response: 0

    There it goes. v0.1 of the Ambilamp code.

    Basically, the lamp changes it’s color randomly, choosing a random target value for red, other for green and other for blue (yes, I’m using RGB leds :-) It then roams between the current value of each color to the target value. The colors are represented as hexadecimal numbers in RGB, so FF0000 is red, 00FF00 is green and 0000FF is blue, and so on…

    I mainly adapted the code from Devon D. Jones from evilsoft. His code provides a way of sending external commands to command the color you want to display, roam randomly, blink, etc… I’m only using the random roam (at least in v0.1, there are important additions in v0.2, not released yet). The code is easy to understand, so I won’t explain it here, I added a few modifications, though:

    - I forced using “stepmax” instead of a random number between stepmax and stepmin. This makes the transition between colors always as slow as possible.
    - When receiving a command for displaying a specific color, I prefer a transition to it instead of just displaying it inmediately.
    - I added a delay (5 seconds) after reaching the target color, to wait there for a while before roaming again.
    - To get better random numbers, I used as seed the value of an unconnected analog input pin, as using millis() as seed makes random numbers that repeat among restarts.

    
    /*
     * Adapted 15 June 2009
     * modification copyleft 2009 Enrique Jorreto
     * quercus [at] nosomos.org
     * http://projects.nosomos.org
     * Adapted 14 April 2007
     * modifications copyleft 2007 Devon D. Jones soulcatcher [at] evilsoft.org
     * http://www.evilsoft.org
     * Adapted from Serial RGB LED TOO
     * Created 18 October 2006
     * copyleft 2006 Tod E. Kurt tod [at] todbot.com
     * http://todbot.com/
     */
    
    /*
     * This program can take a number of inputs on the serial port:
     * 1) #[HHHHHH] where H = Hex.  Example: #FF6666.  This will set the orb to the color that is declared.
     * 2) roam.  This will cause the orb to float between colors
     * 3) %[HHHHHH] where H = Hex.  Examples: %, %00FF00.  This will put the orb into alert mode, where
     *    it will flash between the color (or FF0000 if no color is passed in) and a very dim version of the color
     */
    #define slen 7        // 7 characters, e.g. '#ff6666'
    #define maxCommandLength 16
    // For random colors, this is the lower & upper bound.
    // The result is multiplied by 16, and then normalized to 0-255
    // we start at -3 and go to 20 to bias the randomness towards 0 and 255
    // because it results in generally better colors
    #define randmin -3
    #define randmax 20
    // For color transition we use varied transition speed,
    // this is the lower & upper bound.
    #define stepmin 16
    #define stepmax 1
    
    char serInStr[slen];  // array to hold the incoming serial string bytes
    
    struct led {
      int curr; // Current brightness
      int dest; // Next intended brightness
      int step; // If transitioning from one brightness to another, this is the amount to step by
    }; // Struct representing a single led
    struct ledcolors { led red; led green; led blue; }; // Struct representing the 3 leds
    ledcolors colors;
    
    int roam = 0; // 0 roam off, 1 roam on
    int roamTo=0;
    
    int alert = 0; // 0 alert off, 1 alert off
    unsigned long alertMillis = 0; // used to determine when to swap colors
    int alertInterval = 300; // interval used between swap requests
    
    int gndPin   = 12;  // Ground pin.  We use this instead of gnd so that we can get 4 pins in a row.
                        //   Pin 13 has a resistor, so it is not a good pin for us to use.
                        //   as either gnd or vcc for an LED
    int redPin   = 11;  // Red LED,   connected to digital pin 11
    int greenPin = 10;  // Green LED, connected to digital pin 10
    int bluePin  = 9;   // Blue LED,  connected to digital pin 9
    
    void roamToColor(int red, int green, int blue);
    
    void setup() {
      // sets the pins as output
      pinMode(gndPin,   OUTPUT);
      digitalWrite(gndPin, LOW);
      pinMode(redPin,   OUTPUT);
      pinMode(greenPin, OUTPUT);
      pinMode(bluePin,  OUTPUT);
    
      Serial.begin(9600);
      roam = 1; // start off roaming
    }
    
    void loop () {
      //read the serial port and create a string out of what you read
      int spos = readSerialString();
    
      if(spos == slen && serInStr[0] == '#') {
        roam = 0;
        alert = 0;
        long colorVal = strtol(serInStr + 1, NULL, 16);
        decodeColor(colorVal);
        //displayColor(colors.red.curr, colors.green.curr, colors.blue.curr);
        roamToColor(colors.red.dest, colors.green.dest, colors.blue.dest);
        roam=1;
        roamTo=1;
        memset(serInStr,0,slen);      // indicates we've used this string
      }
      else if(spos != -1 && strncmp(serInStr, "roam", 4) == 0) {
        alert = 0;
        roam = 1;
        roamTo=0;
        initStruct();
        prepRoam();
      }
      else if(spos != -1 && serInStr[0] == '%') {
        roam = 0;
        alert = 1;
        initStruct();
        if(spos == slen) {
          long colorVal = strtol(serInStr + 1, NULL, 16);
          decodeColor(colorVal);
        }
        else {
          colors.red.curr = 255;
        }
        prepAlert();
      }
    
      if(roam == 1) {
        int ret = doRoam();
        displayColor(colors.red.curr, colors.green.curr, colors.blue.curr);
        if(ret > 0 && roamTo==0) {
          delay(5000);
          prepRoam();
        }
    
      }
    
      if(alert == 1) {
        doAlert();
        displayColor(colors.red.curr, colors.green.curr, colors.blue.curr);
      }
    
      delay(100);  // wait a bit, for serial data
    }
    
    // Takes in a string in ?000000 - ?FFFFFF format (Ex: #FFAA33)
    // and sets the curr color to the value
    void decodeColor(long colorVal) {
      colors.red.dest = (colorVal&0xff0000) >> 16;
      colors.green.dest = (colorVal&0x00ff00) >> 8;
      colors.blue.dest = (colorVal&0x0000ff) >> 0;
    }
    
    void displayColor(int red, int green, int blue) {
      analogWrite(redPin, red);
      analogWrite(greenPin, green);
      analogWrite(bluePin, blue);
    }
    
    //read a string from the serial and store it in an array
    int readSerialString () {
      int i = 0;
      if(!Serial.available()) {
        return -1;
      }
      while (Serial.available() && i < maxCommandLength) {
        int c = Serial.read();
          serInStr[i++] = c;
      }
      //Serial.println(serInStr);
      return i;
    }
    
    void initStruct() {
      colors.red.curr = 0;
      colors.red.dest = 0;
      colors.red.step = 0;
      colors.green.curr = 0;
      colors.green.dest = 0;
      colors.green.step = 0;
      colors.blue.curr = 0;
      colors.blue.dest = 0;
      colors.blue.step = 0;
    }
    
    //------------------------------
    //ALERT
    //------------------------------
    void doAlert() {
      if (millis() - alertMillis > alertInterval) {
        alertMillis = millis();
        int tmp = 0;
        tmp = colors.red.curr;
        colors.red.curr = colors.red.dest;
        colors.red.dest = tmp;
        tmp = colors.green.curr;
        colors.green.curr = colors.green.dest;
        colors.green.dest = tmp;
        tmp = colors.blue.curr;
        colors.blue.curr = colors.blue.dest;
        colors.blue.dest = tmp;
      }
    }
    
    void prepAlert() {
      colors.red.dest = colors.red.curr / 8;
      colors.green.dest = colors.green.curr / 8;
      colors.blue.dest = colors.blue.curr / 8;
    }
    
    //------------------------------
    //ROAMING
    //------------------------------
    int doRoam() {
      colors.red.curr = roamColor(colors.red.curr, colors.red.dest, colors.red.step);
      colors.green.curr = roamColor(colors.green.curr, colors.green.dest, colors.green.step);
      colors.blue.curr = roamColor(colors.blue.curr, colors.blue.dest, colors.blue.step);
      if((colors.red.curr == colors.red.dest)
          && (colors.green.curr == colors.green.dest)
          && (colors.blue.curr == colors.blue.dest)) {
        return 1;
      }
      else
      {
        // For some debugging
        /*
        Serial.print("#");
        Serial.print(colors.red.curr);
        Serial.print(" ");
        Serial.print(colors.green.curr);
        Serial.print(" ");
        Serial.print(colors.blue.curr);
        Serial.print(" -> #");
        Serial.print(colors.red.dest);
        Serial.print(" ");
        Serial.print(colors.green.dest);
        Serial.print(" ");
        Serial.println(colors.blue.dest);
        */
      }
      return 0;
    }
    
    int roamColor(int curr, int dest, int step) {
      int diff = curr - dest;
      if(diff < 0) {
        diff = diff * -1;
      }
    
      if(curr == dest) {
        return dest;
      }
      else if(curr < dest) {
        if(diff <= step) {
          return dest;
        }
        return curr + step;
      }
      else {
        if(diff <= step) {
          return dest;
        }
        return curr - step;
      }
    }
    
    void prepRoam() {
      randomSeed(analogRead(1));
      colors.red.dest = getRandomColor();
      // I prefer using stepmax for lower gradient
      //colors.red.step = random(stepmin, stepmax);
      colors.red.step = stepmax;
      colors.green.dest = getRandomColor();
      //colors.green.step = random(stepmin, stepmax);
      colors.green.step = stepmax;
      colors.blue.dest = getRandomColor();
      //colors.blue.step = random(stepmin, stepmax);
      colors.blue.step = stepmax;
    }
    
    void roamToColor(int red, int green, int blue) {
      colors.red.dest = red;
      // I prefer using always stepmax for lower gradient
      //colors.red.step = random(stepmin, stepmax);
      colors.red.step = stepmax;
      colors.green.dest = green;
      //colors.green.step = random(stepmin, stepmax);
      colors.green.step = stepmax;
      colors.blue.dest = blue;
      //colors.blue.step = random(stepmin, stepmax);
      colors.blue.step = stepmax;
    }
    
    int getRandomColor() {
      int color = (random(randmin, randmax) * 16) -1;
      if (color < 0) color = 0;
      if (color > 255) color = 255;
      return color;
    }
    

  • Ambilamp video!

    Date: 2009.09.16 | Category: Ambilamp | Response: 1

    Yeah, baby, here we go…

    More info in ambilamp page.

    Ambilamp from Quercus on Vimeo.

  • Some more ambilamp pictures

    Date: 2009.06.25 | Category: Ambilamp | Response: 0

    Here we go with a couple of new pictures of the ambilamp project. First one is the box where the arduino resides. It’s just a simple box that you can buy in any electronics shop.

    I added a switch for being able to turn off the lamp without unplugging it from the mains. Note that every project must use at least a piece of duct tape to be considered a real hardware hacking project :-)

    And the second is the same box, opened :-)

    You can see the mini-shield that I made to set the transistor bridge and solder the wires that go to the lamp. And the conector I used to connect the switch to the arduino board (you won’t be able to do it this way if you are using the newer arduino duemilanuove, as it doesn’t have anymore the jumper to switch the power supply):

  • Ambilamp code v0.1

    Date: 2009.06.17 | Category: Ambilamp | Response: 0

    Here we go, it is not probably very useful without the schematics if you plan to build your own ambilamp, but in the meantime you can have a look and start thinking how to improve this :-)

    This is the v0.1, it is a simple ambilamp very similar to the hundreds that are all around the internet. It is in fact an adaptated code, with some improvements that I like.

    Whatever… Show me the code!

  • Ambilamp first pictures

    Date: 2009.06.15 | Category: Ambilamp | Response: 0

    I might be somehow offline, but I’m not off at all :-)

    I’ve been working, among other things, in an arduino controlled ambient lamp. That is, a lamp that changes its color. Cool, isn’t it?

    What’s different between my lamp and the hundreds of ambilamps that are round the internet? Well, not much, at least not right now, but stay tuned… ;-)

    Here you have a couple of pictures of the lamp, soon I’ll upload some code, schematics, more pictures and hopefully a video :-)

    A nice blue:

    And the four RGB leds that do the magic stuff :-)