martes, 18 de noviembre de 2014

LED as sensor

Led as sensor



Controlled by Arduino, we are using a single yellow led as both light and sensor of light.
Five times per second we reverse the polarity of the led, charging it.
If there is light, photons are going to interact with the electrons discharging it faster.

We then measure the time it takes for the digit pin to read a logical 0.
If this zero is reached before some threshold time, we know there is light.
If it takes a lot of time, there are no photons helping our electrons cross the band gap of the diode.


 Arduino Code

//
// This example shows one way of using an LED as a light sensor.
// You will need to wire up your components as such:
//
//           + digital11
//           |
//           <
//           > 180 ohm resistor
//           <
//           |
//           |
//         -----
//          / \  LED, maybe a 5mm, clear plastic is good
//         -----
//           |
//           |
//           + digital12
//
// What we are going to do is apply a positive voltage at LED N Side and
// a low voltage at LED P Side. This is backwards for the LED, current will
// not flow and light will not come out, but we will charge up the 
// capacitance of the LED junction and the Arduino pin.
//
// Then we are going to disconnect the output drivers from LED P Side and
// count how long it takes the stored charge to bleed off through the 
// the LED. The brighter the light, the faster it will bleed away to 
// LED N Side.
//

#define LED_N_SIDE 11
#define LED_P_SIDE 12
#define MAX_COUNT 180

void setup()
{
}

void lightMode()
{
  // Turn the light on
  pinMode(LED_N_SIDE,OUTPUT);
  pinMode(LED_P_SIDE,OUTPUT);
  digitalWrite(LED_P_SIDE,HIGH);
  digitalWrite(LED_N_SIDE,LOW);
}

void sensorMode()
{
  // Apply reverse voltage, charge up the pin and led capacitance
  pinMode(LED_N_SIDE,OUTPUT);
  pinMode(LED_P_SIDE,OUTPUT);
  digitalWrite(LED_N_SIDE,HIGH);
  digitalWrite(LED_P_SIDE,LOW);

  // Isolate the LED N Side of the diode
  // Turn off internal pull-up resistor
  pinMode(LED_N_SIDE,INPUT);
  digitalWrite(LED_N_SIDE,LOW);
}

boolean isDark = true;

void loop()
{
  if (isDark)
  {
    lightMode();
    delay(200);
    sensorMode();
  }

  isDark = true;
  for( byte j = 0; j < MAX_COUNT; j++ )
  {
    if ( digitalRead(LED_N_SIDE) == 0 ) 
    {
      isDark = false;
      break;
    }
  }
}


I became first aware of this technique browsing through the Arduino Playground
http://playground.arduino.cc/Learning/LEDSensor. I tried implemented it with different leds and resistences but I could not make it work.

Then I found LED as a Light AND a Light Sensor - Arduino controlled which made this possible.
Special thanks to Ido Gendel for his code and patience.

sábado, 12 de abril de 2014

Arduino Web RGB



I created this simple python-Flask app to inteface with my Arduino.

I worked with an Arduino Nano mounted on a breadboard.
You can get an idea on how to wire yours reading this fritzing project.
http://fritzing.org/projects/simple-rgb-led-on-an-arduino-uno

The barebones of this project goes like this.

First we create route on our flask app to handle requests to the root of our webserver.

from flask import Flask
from flask import send_file
app = Flask(__name__)

@app.route('/')
def index():
    return send_file('templates/index.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0')

The file we have as index.html has the following script to get where the user has clicked, get the pixel information, and send it thru ajax back to our python app via the /color route.

$(document).ready(function(){
    $( "#colorpicker" ).on( "click", function(e) {
        var pixelData = this.canvas
                            .getContext('2d')
                            .getImageData(e.offsetX, e.offsetY, 1, 1)
                            .data;
        var hex = rgbToHex( pixelData[0], pixelData[1], pixelData[2]);
        $.post('/color', { color: hex });
    });
});
function componentToHex(c) {
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b) {
    return componentToHex(r) + componentToHex(g) + componentToHex(b);
}

Now, the route listening on /color receives the color, compacts the color information using only the two most significant bits of each color component, and sends it to the Arduino connected via serial.

import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)

def send_value( value ):
    char = str( chr( value ) )
    ser.write( char )

def rgb_to_6bit( rgb ):
    return int('00' + bin(int(rgb[0:1], 16))[2:].zfill(4)[0:2]
                + bin(int(rgb[2:3], 16))[2:].zfill(4)[0:2]
                + bin(int(rgb[4:5], 16))[2:].zfill(4)[0:2], 2)

@app.route('/color', methods=['GET', 'POST'])
def color():
    if request.method == 'POST':
        color = request.form['color']
        send_value( rgb_to_6bit( color ) )

Finally, the Arduino is listening all the time for any incoming information.
When it receives something, it converts the compacted RGB color into analog values, and controls the analog pins of the board with the proper value.

const int GREEN = 9;
const int BLUE = 10;
const int RED = 11;

const int rgb_val[] = { 0x00, 0x40, 0x80, 0xff };
const char mask = 3;
int rgb[3];

void six_bit_to_rgb( char color, int * rgb )
{
    char tmp;
    int i;
    tmp = color;
    for (i = 2; i >= 0; i--) {
        rgb[ i ] = 0xff - rgb_val[ tmp & mask ];
        tmp = tmp >> 2;
    }
}

void setup()
{
  // initialize the serial communication
  Serial.begin(9600);
  // initialize the pins as an output
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
}

void loop() {
  byte rgb6bit;

  // check if data has been sent from the computer
  if (Serial.available()) {
    // read the most recent byte (which will be from 0 to 255):
    rgb6bit = Serial.read();
    six_bit_to_rgb( rgb6bit, rgb );
    // set the brightness of the LED:
    analogWrite(RED, rgb[0]);
    analogWrite(GREEN, rgb[1]);
    analogWrite(BLUE, rgb[2]);
  }
}

Full python and Arduino code at https://github.com/facutk/arduino_web_rgb