Difference between revisions of "Sparkfun: Mini Photocell"

From eLinux.org
Jump to: navigation, search
(Bone Usage)
(Bone Usage)
Line 26: Line 26:
 
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.1kΩ) 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.
 
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.1kΩ) 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.
  
[[File:MiniPhotocellWiring|thumb|Wiring Example of MiniPhotocell]]
+
[[File:MiniPhotocellWiring.jpg|thumb|Wiring Example of MiniPhotocell]]
  
 
== Reading and Interpreting Analog Input Data ==
 
== Reading and Interpreting Analog Input Data ==

Revision as of 17:47, 3 October 2012


Overview: 
Wiring:   
Code:     
git/Compiles with make: 
Demo:     
Total:    
Comments: Generally the same comments as your other sensor.

Overview

The product. The datasheet.

This is a small sensor that changes resistance depending on the amount of light it is exposed to. The Photocell is also referred to as a photo-resistor, photo-detector, and photo-conductor.

Input and Outputs of Mini Photocell

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Ω 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.1kΩ) 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.

Wiring Example of MiniPhotocell

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 10MΩ, but normal ranges occur anywhere from 8 to 20kΩ. 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.