Light Sensor

Expansion modules and attachments
Post Reply
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Light Sensor

Post by jsclownfish »

Hi all,


Awhile ago I was working on a light sensor for the aquarium. http://forum.reefangel.com/viewtopic.ph ... =cds#p4008 I finally got around to setting it up last weekend. I thought I'd share it with you all. I like that I can actually confirm the lights are on and maybe I'll be able to pick up a loss of lamp intenstiy over time. The pieces are really cheap. You just need to connect to the analog pins of an IO module or use a your own Arduino to connect to the RA.

Here is a picture of the meters I use. I just found these little containers at an art store and used a little silicone to seal the cable in and hold the photoresistor in place.
CDS.jpg
CDS.jpg (71.06 KiB) Viewed 7594 times
I used this code on my I/O module to smooth the signal and scale it to a single byte.

Code: Select all

/* IO program has these functions:
Flow meters (skimmer, overflow, and phosban reactor)
Light sensors (2 readers connected to analog pins 0&1)
Autofeeder signal (signal output to the autofeeder relay)
Float sensors (overflow clog, reservoir empty)
*/

#include <Wire.h>
#include <avr/wdt.h>

/* Photocell simple testing sketch.  Connect one end of the photocell to 5V, the other end to Analog 0.
Then connect one end of a 10K resistor from Analog 0 to ground For more information see http://learn.adafruit.com/photocells */ 
int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellPin2 = 1;
int photocellReading;     // the analog reading from the analog resistor divider 
int photocellReading2;     // the analog reading from the analog resistor divider 
int photocelllevel;
int photocelllevel2;

// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array
const int numReadings = 10;
int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

const int numReadings2 = 10;
int readings2[numReadings2];      // the readings from the analog input
int index2 = 0;                  // the index of the current reading
int total2 = 0;                  // the running total
int average2 = 0;                // the average

byte Overflow=0;   //float in overflow box to turn off pump if clogged
byte Reservoir=0;  //float in reservoir to keep from filling if empty
byte Feeder=0;   //autofeeder signal

byte IOOut[11];

//flow meters 
volatile int Flow0 = 0;  //skimmer
volatile int Flow1 = 0;   //overflow
volatile int Flow2 = 0;    //phosban reactor
unsigned long lastmillis=millis();

void FlowMeter1()
{
  Flow1++;
}

SIGNAL(PCINT0_vect) {
  Flow0++;
}

SIGNAL(PCINT2_vect) {
  Flow2++;
}

void setup()
{
  //  Serial.begin(57600);
  Wire.begin(7);
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);
  pinMode(3,INPUT);
  digitalWrite(3,HIGH); //pull up resistor
  pinMode(5,INPUT);
  digitalWrite(5,HIGH); //pull up resistor
  pinMode(6,INPUT);
  digitalWrite(6,HIGH); //pull up resistor
  pinMode(9,INPUT);
  digitalWrite(9,HIGH); //pull up resistor
  pinMode(10,OUTPUT);
  digitalWrite(10,LOW); //pull up resistor
  pinMode(11,INPUT);
  digitalWrite(11,HIGH); //pull up resistor

  PCMSK0 |= (1<<PCINT3); // Pin 11
  PCICR |= (1<<PCIE0); // Interrupt 0

    PCMSK2 |= (1<<PCINT21); // Pin 5
  PCICR |= (1<<PCIE2); // Interrupt 2

    MCUCR = (1<<ISC01) | (1<<ISC01);  //Rising edge

  attachInterrupt(1, FlowMeter1, RISING); // Interrupt 1  
  wdt_enable(WDTO_1S);
}

void loop()
{
  wdt_reset();
  
  //smoothing functions on cds
  photocellReading = analogRead(photocellPin);     
  photocellReading2 = analogRead(photocellPin2);  
  photocelllevel = map(photocellReading, 0, 1023, 0, 255);
  total = total - readings[index];   // subtract the last reading:         
  readings[index] = photocelllevel;   // read from the sensor: 
  total = total + readings[index];   // add the reading to the total:       
     index = index + 1;  // advance to the next position in the array:                   
  if (index >= numReadings)     // if we're at the end of the array...           
    index = 0;       // ...wrap around to the beginning:                         
  average = total / numReadings;    // calculate the average:
  photocelllevel2 = map(photocellReading2, 0, 1023, 0, 255);
  total2 = total2 - readings2[index2];   // subtract the last reading:         
  readings2[index2] = photocelllevel2;   // read from the sensor: 
  total2 = total2 + readings2[index2];   // add the reading to the total:       
     index2 = index2 + 1;  // advance to the next position in the array:                   
  if (index2 >= numReadings2)     // if we're at the end of the array...           
    index2 = 0;       // ...wrap around to the beginning:                         
  average2 = total2 / numReadings2;    // calculate the average:

  if (millis()-lastmillis>1000)
  {
    lastmillis=millis();
    IOOut[0]=0;
    IOOut[1]=Flow0>>8;
    IOOut[2]=Flow0;
    IOOut[3]=Flow1>>8;
    IOOut[4]=Flow1;
    IOOut[5]=Flow2>>8;
    IOOut[6]=Flow2;
    Flow0=0;
    Flow1=0;
    Flow2=0;
  }

  //overflow sensor
  Overflow = digitalRead(6);

  //reservoir sensor
  Reservoir = digitalRead(9);

  IOOut[7]=Overflow;
  IOOut[8]=Reservoir;
  IOOut[9]=average;
  IOOut[10]=average2;

  //overtemp alarm 
 if (Feeder == 0)
 {
   digitalWrite(10, LOW);
 }
 else if (Feeder == 1)
 {
   digitalWrite(10, HIGH);
 }
}
void requestEvent() {
  Wire.write(IOOut,sizeof(IOOut));
}

void receiveEvent(int howMany) 
{
  if (howMany==4)  // Our custom protocol is 4 bytes
  {
    byte cmd1,cmd2,cmd3,cmd4;
    cmd1=Wire.read();
    cmd2=Wire.read();
    cmd3=Wire.read();
    cmd4=Wire.read();  
    if (cmd1=='$' && cmd2=='$' && cmd3=='$') // the first 3 bytes of the custom protocol are $$$ to ensure it's coming from RA
    {
      Feeder=cmd4;
    }
  }
  else
    for (int a=0;a<howMany;a++)
      Wire.read(); // if the number of bytes is not 4, discard everything
} 

It seems to work well and I can see the fluorescents and the MH turn on and off as schedule. The graph of the light sensors on as custom variables looks like this....
light sensors.jpg
light sensors.jpg (78.16 KiB) Viewed 7594 times
Let me know if anyone wants more info or if some of you more expreienced programmers could clean up my amateur code. ;)

Thanks,
Jon
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Light Sensor

Post by lnevo »

Wow, very cool!

I can see this being awesome for someone who has a controllable light fixture and wants to sync their RA functions to their light schedule instead of vice-versa.
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Light Sensor

Post by DrewPalmer04 »

Or for LEDs. One could serial print a string of the data and match the output of the PWM pins to the values of the light output the sensor reads. Or read the string from the RA and do a percentage value of what it received to incrementally reduce the arduino output consistently. IE: MH photoresistor reading. Output string to arduino. Match value output with supplemental LEDs or do a % (value) to make it a lesser percent consistently of the photo value received.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Light Sensor

Post by DrewPalmer04 »

What does this measure exactly? Lumens? I would be insanely awesome to measure PAR on the fly.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Light Sensor

Post by jsclownfish »

It would be very cool to measure PAR, but these aren't quite in that spectrum. There is a long discussion on the topic here http://www.plantedtank.net/forums/showt ... p?t=120109. I just wanted a light meter to know for sure the bulbs are on and maybe pick up some loss of intensity over time to decide when to replace them. I just used these photoresistors https://www.adafruit.com/products/161.

-Jon
User avatar
DrewPalmer04
Posts: 818
Joined: Tue May 29, 2012 2:12 pm
Location: Christopher, IL

Re: Light Sensor

Post by DrewPalmer04 »

I saw the same link. http://www.plantedtank.net/forums/showt ... 109&page=5

This was why I was curious.
Out for now...but not over.

VISIT: Ethernet Module/Wifi Alternative
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Light Sensor

Post by lnevo »

Just saw this on reefs.com and thought of this :) Would be great for those that don't want to DIY the sensor, but it looks like it's using a mono jack, so should be able to splice it right into the IO module pretty easily.

http://www.reefs.com/blog/2013/03/12/aq ... more-18485
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Light Sensor

Post by jsclownfish »

Wouldn't you know it, right after I put these together. ;) Although this was really cheap to make and I know it gives me a variable readout. I wonder if these will do that as well (the description just says Day or Night reading).

-Jon
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Light Sensor

Post by lnevo »

Probably just being interpreted by their inferior controller that way ;)

I'm sure it's just like any other sensor that generates a current based on the light it receives. But who know's it could have some circuitry to just be on/off..
iiluisii
Posts: 80
Joined: Mon Jul 09, 2012 10:16 am

Re: Light Sensor

Post by iiluisii »

were can i get the same sensor you are using
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Light Sensor

Post by jsclownfish »

I ordered the photoresistors here....
http://www.adafruit.com/products/161

-Jon
markywmson
Posts: 51
Joined: Wed Feb 27, 2013 11:35 am

Re: Light Sensor

Post by markywmson »

So could your light sensor be hooked right up to the I/O module to take readings? Or does this have to run through something else. It would be great for me, as my LED light has a built in controller, and I'd love to be able to have my pumps ramp up through morning actinic, full on during full daylight, ramp down on evening actinic, and be running low at night.

How easy is it to make your sensor (if what I'd like to do is possible)?

Thanks
-mark
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Light Sensor

Post by lnevo »

Yep, that's pretty much what you'd do, as far as hooking it to io module. And exactly why I thought it would be great. You should be able to control pumps etc based on your light output.
markywmson
Posts: 51
Joined: Wed Feb 27, 2013 11:35 am

Re: Light Sensor

Post by markywmson »

So if I wired it as such:
Image

and enclosed it in a case like clownfish did, I should be able to get light readings into my RA and then it's just a matter of defining what those 'general' levels do?
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Light Sensor

Post by lnevo »

Sounds right
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Light Sensor

Post by jsclownfish »

A couple of things to consider...

1. I used a pull down resistor as in the desription here http://learn.adafruit.com/photocells/using-a-photocell.

2. I 'hacked' a wire to the analogue pins of the I/O chip. I think you could also get one modified like this if you want.

3. I wrote my own code to send the data over I2C communication and scale it to a single byte. I think you could use the default code as well, but I have lots of other stuff going on with my I/O so the code is pretty custom.

As always, I am not either a programmer or electrician so I'd defer to the experts here if they have a better way to do this. I'm happy to help if I can.

-Jon
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Light Sensor

Post by lnevo »

hehe, this is why I haven't commented definitively... :)
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Light Sensor

Post by rimai »

What Jon said :)
Don't believe when he says he is not expert :ugeek:
Roberto.
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Light Sensor

Post by jsclownfish »

Ha! :) I learned what I know from this forum. So maybe I'm a padawan to the jedi masters. :ugeek:

-Jon
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Light Sensor

Post by lnevo »

jsclownfish wrote:I just wanted a light meter to know for sure the bulbs are on and maybe pick up some loss of intensity over time to decide when to replace them.
Jon, Curious if you were ever able to detect any change of intensity over the lifetime of the bulbs?
User avatar
jsclownfish
Posts: 378
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Light Sensor

Post by jsclownfish »

Not really. I have caught a bulb go out, but not a gradual change in intensity. Maybe if I had a better photoresistor more in the proper spectrum. You can see them as at my reeftronics.net account as C0 and C1. I do see when I forget to turn off the lights in the room at night. :)

I still like them and would be interested to see how they would work on an LED system with more gradual dimming.

Jon
Post Reply