Tuesday, October 25, 2016

Chameleon Softie

I stumbled upon this light colour sensor while trawling around the Internets, and got the idea of using it to build a softie that would change its colour based on what it sensed around it (like a chameleon). This colour sensor uses four different photosensitive sensing elements with different band pass filters for sensing the proportions of red, green, blue and clear (visible?) light. It also has a white LED on board that can be used to illuminate a target surface that sits close to the sensor, in order to provide consistent colour readings under different ambient light conditions. I got the 'Flora' version of the sensor (3.3V only and with sewable pads), but there is also a standard breadboard breakout version of the sensor too which allows for 3.3-5V with the addition of logic level conversion, so it can be used with pretty much any Arduino or other microcontroller. The sensor uses I2C for communication with the micro.

I had a few spare Gemmas sitting around, so I wanted to use this board instead of the larger Flora (of which I had none). A bit of reading here on the Gemma pins and it looks like it's got what I need: I2C comms through pins 0 and 2, which leaves pin 1 for driving some neopixels to light up the chameleon different colours.

I downloaded the library for the colour sensor from here and a library for I2C communication on the ATTiny (micro used on the Gemma and Trinket) from here. I modified the Adafruit_TCS34725 library to use TinyWireM, instead of "Wire" (the built-in Arduino library for I2C communications on larger boards). This pretty much was just replacing every instance in the code of "Wire" with "TinyWireM", a class that provides essentially all the same functionality. I then wrote a sketch that connected to the colour sensor and to four neopixels, and in a loop would read the colour values and basically cut and paste them into the RGB values for the neopixel. The code switches on the illuminating LED on the colour sensor and leaves it on.

Initial result was that I could discern the colours of objects I put in front of the sensor, but the output was very "white", i.e. very low colour saturation values. I wrote a function that would take the RGB values and maximise the colour saturation. I started off by writing a function to first compute the hue from the RGB values, and then produce another set of RGB values of that same hue but at full saturation and value. Unfortunately, I ran out of program space ... the Gemma is super restrictive! I re-wrote the function to do things in one step: set the maximum channel to 255, minimum channel to zero, and intermediate channel scaled between 0 and 255, based on it's relative difference to the max/min values. I just managed to scrape in under the maximum program space (after shaving off a few options in the modified Adafruit_TCS34725 library), but the results were not great: the colour would sort of flick randomly: I think I was saturating the sensor and getting a lot of white signals, which would saturate to random colours.

I ended up going for a simpler solution in which I would subtract a set of calibrated values from each of the RGB channels, to try and get a more saturated output signal. I experimented with several differently coloured objects, including white paper, and tweaked the gains, until I got the desired range of colour replication.

Once I got the electronics working, I turned my attention to building and sewing the chameleon. I wanted to make it entirely out of white felt with the neopixels mounted inside and surrounded by stuffing to diffuse the light out a bit. I experimented a bit to see how close I would need to mount the neopixels from each other and how much stuffing to use to try and get the illumination from the neopixels spread out as evenly as possible. Once I had this sorted I cutout and section of felt and sewed up the Gemma and neopixels circuit using conductive thread. I designed the Gemma to sit on one eye of the chameleon, and the colour sensor on the other, such that the Gemma was accessible for turning on/off. I then designed the chameleon's outside body, cut it out of felt, and sewed it together with the nexopixel circuit. Once completed, I sewed on the colour sensor to the other eye and sewed all the conductive lines to the Gemma. I stuffed the insides with soft fill in order to puff out the chameleon and diffuse some of the light from the neopixels, such that it would look like the chameleon was sort of glowing.

The end result was OK. I had to fiddle around a lot with the calibration gains on the colour channels to get good matching for various colours. I was a bit disappointed I couldn't add more functionality to the programming ... I would have liked to have a bit more intelligence in inferring when the chameleon was moving or still, so I could decide to actively flash the white LED and get another reading, otherwise if still, just leave it off. One of the limitations of the ATTiny85 on the Gemma ... still, it's cool that its so small.

The code for the sketch is available here.

No comments:

Post a Comment