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.
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
}
Let me know if anyone wants more info or if some of you more expreienced programmers could clean up my amateur code.
Thanks,
Jon