Sparkfun: Mini Photocell

From eLinux.org
Revision as of 14:23, 24 September 2012 by Popenhjc (Talk | contribs)

Jump to: navigation, search


Overview

The product. The datasheet.

Inputs and Outputs

As for inputs and outputs, the sensor is basically a resistor and thus should be read from the analog input pins. To work with the analog input, you must put 1k ohm resistor from analog ground to the analog input you choose then connect the sensor from the analog VDD to the analog input you choose. The input voltage can then be read by the processor to interpret the amount of light in the room.

Bone Usage

To interface this with the BeagleBone you just need to connect the photo-resistor from the analog VCC to an analog input and another resistor (I used 1.1kohms) from analog input to analog ground. From there you can read the voltage input and manipulate it using code however desired. In my case I basically took the number that the analog input gave me and manipulated it to work as the duty cycle for a pwm which dimmed the light if it was too bright and brightened the light if it was too dim. You can see this in the sample code provided.

Reading and Interpreting Analog Input Data

The resistance of the Mini Photocell is interpreted as such. When there is a very dim room the resistance shoots up to 10Mohms, but normal ranges occur anywhere from 8 to 20kohms. So, the lower the number the analog input pin says it is, the darker it is in the room, with the set up explained in the previous section.

Sample C Code


/****************************************************************
* James Popenhagen
* MiniProject02_LightSensor.c
* 9/23/12
****************************************************************/
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <unistd.h>


/****************************************************************
* Constants
****************************************************************/
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define POLL_TIMEOUT 1 /* 3 seconds */
#define MAX_BUF 64

/****************************************************************
* Global Variables
****************************************************************/
int keepgoing = 1;

void signal_handler(int sig)
{
	printf( "Ctrl-C pressed, cleaning up and exiting..\n" );
	keepgoing = 0;
}

/****************************************************************
 * set_mux_value
 ****************************************************************/
int set_mux_value(char* muxPin, int value){
	FILE *fp;
	char muxPath[MAX_BUF];

	snprintf(muxPath, sizeof muxPath, "/sys/kernel/debug/omap_mux/%s", muxPin);
	
	if((fp = fopen(muxPath, "w")) == NULL){
		printf("Cannot open specified mux, %s\n", muxPath);
		return 1;
	}
	
	rewind(fp);
	fprintf(fp, "%d\n", value);
	fflush(fp);
	fclose(fp);

}
	
/****************************************************************
 * read_ain
 ****************************************************************/
int read_ain(char* ain){
	FILE *fp;
	char ainPath[MAX_BUF];
	char ainRead[MAX_BUF];

	snprintf(ainPath, sizeof ainPath, "/sys/devices/platform/omap/tsc/%s", ain);

	if((fp = fopen(ainPath, "r")) == NULL){
		printf("Cannot open specified ain pin, %s\n", ain);
		return 1;
	}

	if(fgets(ainRead, MAX_BUF, fp) == NULL){
		printf("Cannot read specified ain pin, %s\n", ain);
	}
	
	fclose(fp);
	return atoi(ainRead);	
}

/****************************************************************
 * set_pwm
 ****************************************************************/	
int set_pwm(char* pwmNum, int periodFreq, int dutyPercent){
	FILE *fp;
	char pwmPath[MAX_BUF];
	
	snprintf(pwmPath, sizeof pwmPath, "/sys/class/pwm/%s/run", pwmNum);
	
	if((fp = fopen(pwmPath, "w")) == NULL){
		printf("Cannot open pwm run file, %s\n", pwmPath);
		return 1;
	}

	rewind(fp);
	fprintf(fp, "1\n");
	fflush(fp);
	fclose(fp);

	snprintf(pwmPath, sizeof pwmPath, "/sys/class/pwm/%s/duty_ns", pwmNum);

	if((fp = fopen(pwmPath, "w")) == NULL){
		printf("Cannot open pwm duty_ns file, %s\n", pwmPath);
	}

	rewind(fp);
	fprintf(fp, "0\n");
	fflush(fp);
	fclose(fp);

	snprintf(pwmPath, sizeof pwmPath, "/sys/class/pwm/%s/period_freq", pwmNum);

	if((fp = fopen(pwmPath, "w")) == NULL){
		printf("Cannot open pwm period_freq file, %s\n", pwmPath);
	}

	rewind(fp);
	fprintf(fp, "%d\n", periodFreq);
	fflush(fp);
	fclose(fp);

	snprintf(pwmPath, sizeof pwmPath, "/sys/class/pwm/%s/duty_percent", pwmNum);

	if((fp = fopen(pwmPath, "w")) == NULL){
		printf("Cannot open duty_percent file, %s\n", pwmPath);
	}

	rewind(fp);
	fprintf(fp, "%d\n", dutyPercent);
	fflush(fp);
	fclose(fp);
}

/****************************************************************
 * unset_pwm
 ****************************************************************/
int unset_pwm(char* pwmPin){
	FILE *fp;
	char pwmPath[MAX_BUF];

	snprintf(pwmPath, sizeof pwmPath, "/sys/class/pwm/%s/run", pwmPin);

	if((fp = fopen(pwmPath, "w")) == NULL) {
		printf("Cannot open pwm run file, %s\n", pwmPath);
		return 1;
	}

	rewind(fp);
	fprintf(fp, "0\n");
	fflush(fp);
	fclose(fp);

	return 0;

}
/****************************************************************
 * Main
 ****************************************************************/
int main(int argc, char **argv){

	int ainPin;
	char ain[MAX_BUF];
	float duty_cycle = 0;
	
	if (argc < 2){
		printf("Usage: ./MiniProject02 <ainpin>");
		exit(-1);
	}

	signal(SIGINT, signal_handler);
	ainPin = atoi(argv[1]);
	snprintf(ain, sizeof ain, "ain%d", ainPin);
	set_mux_value("gpmc_a2", 6);

	while (keepgoing) {
		usleep(250);
		duty_cycle = read_ain(ain);
		duty_cycle = duty_cycle/8190 * 100;
		duty_cycle = 35 - duty_cycle;
		duty_cycle = duty_cycle * 3;
		if ((int)duty_cycle >= 100) duty_cycle = 99;
		set_pwm("ehrpwm.1:0", 40000, (int)duty_cycle);
		printf("%d\r",(int)duty_cycle);
		fflush(stdout);
	}
	
	unset_pwm("ehrpwm.1:0");
	set_mux_value("gpmc_a2", 7);
	fflush(stdout);
	return 0;
}

This code uses the pwm on the gpmc_a2 mux, along with whichever ain you select when running the code.

You must first compile the code and use the ain pin number as the fist argument when running.