Commit dbdcfbd0 authored by Hermann Mayer's avatar Hermann Mayer

[Sensors][Config][Docs] Implemented the ambient light sensor interface. Added an…

[Sensors][Config][Docs] Implemented the ambient light sensor interface. Added an additional configuration parameter and documented it. (See #4)
parent f1406f9b
......@@ -48,6 +48,8 @@ turn_device_off_after = 600;
# The daemon assumes a state change from LOW to HIGH represents a recognized motion
motion_sensor_gpio = 17;
# The daemon assumes to read the light level from a MCP3008 which is connected
# to the SPI bus. With this setting you can configure which channel of the chip
# will be read out.
# to the SPI bus. With this setting you can choose the Linux kernel SPI device
# the daemon should use. Defaults to "/dev/spidev0.0".
# light_sensor_device = "/dev/spidev0.0";
# With this setting you can configure which channel of the chip will be read out.
# light_sensor_channel = 0;
......@@ -126,6 +126,18 @@ This value is a
This value is a
.IR "integer".
.B "light_sensor_device"
The daemon assumes to read the light level from a MCP3008 which is connected
to the SPI bus. With this setting you can choose the Linux kernel SPI device
the daemon should use. Defaults to
.IR "/dev/spidev0.0".
This parameter is
.I ignored by
.BR "avmctl".
This value is a
.IR "string".
.B "light_sensor_channel"
The daemon assumes to read the light level from a MCP3008 which is connected
......
......@@ -148,7 +148,8 @@ void init_sensors(struct config *conf)
exit(EXIT_FAILURE);
}
if (0 != amblght_init((uint8_t) conf->sensor.light_channel)) {
if (0 != amblght_init(conf->sensor.light_dev,
(uint8_t) conf->sensor.light_channel)) {
utlog(LOG_ERR, "Failed to initialize the Ambient Light sensor.\n");
exit(EXIT_FAILURE);
}
......
......@@ -19,27 +19,110 @@
* along with avm-motion-trigger. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include "ambient-light.h"
static uint8_t amblght_chnl;
static int amblght_fd = -1;
/* Initialize the Ambient Light sensor on a given SPI/ADC channel, 0 on success */
int amblght_init(uint8_t chnl)
/* Initialize the Ambient Light sensor on a given SPI/Dev + SPI/ADC channel,
* 0 on success */
int amblght_init(const char *devspi, uint8_t chnl)
{
int ret = -1;
amblght_fd = open(devspi, O_RDWR);
if (amblght_fd < 0) {
return ret;
}
ret = ioctl(amblght_fd, SPI_IOC_WR_MODE, SPI_MODE_0);
if (amblght_fd < 0) {
return ret;
}
ret = ioctl(amblght_fd, SPI_IOC_RD_MODE, SPI_MODE_0);
if (amblght_fd < 0) {
return ret;
}
ret = ioctl(amblght_fd, SPI_IOC_WR_BITS_PER_WORD, SPI_BITSPERWORD);
if (amblght_fd < 0) {
return ret;
}
ret = ioctl(amblght_fd, SPI_IOC_RD_BITS_PER_WORD, SPI_BITSPERWORD);
if (amblght_fd < 0) {
return ret;
}
ret = ioctl(amblght_fd, SPI_IOC_WR_MAX_SPEED_HZ, SPI_SPEED);
if (amblght_fd < 0) {
return ret;
}
ret = ioctl(amblght_fd, SPI_IOC_RD_MAX_SPEED_HZ, SPI_SPEED);
if (amblght_fd < 0) {
return ret;
}
// Set the given pin as our static default one
amblght_chnl = chnl;
return 0;
}
int amblght_spi_wr(unsigned char *data, int length)
{
struct spi_ioc_transfer spi[length];
for (int i = 0; i < length; i++) {
spi[i].tx_buf = (unsigned long)(data + i);
spi[i].rx_buf = (unsigned long)(data + i);
spi[i].len = sizeof(*(data + i));
spi[i].speed_hz = SPI_SPEED;
spi[i].delay_usecs = 0 ;
spi[i].bits_per_word = SPI_BITSPERWORD;
spi[i].cs_change = 0;
spi[i].tx_nbits = 0;
spi[i].rx_nbits = 0;
spi[i].pad = 0;
}
return ioctl(amblght_fd, SPI_IOC_MESSAGE(length), &spi);
}
/* Read out the current ambient light level, returns 0-1023 */
int amblght_level()
{
int lvl = 0;
unsigned char data[3];
// Setup the block
data[0] = 1;
data[1] = 0b10000000 | ((amblght_chnl & 7) << 4); // (SGL/DIF = 1, D2=D1=D0=0)
data[2] = 0;
// Fire the message on the SPI bus
amblght_spi_wr(data, sizeof(data));
// Shift a bit around to strip out the readed value
lvl = (data[1] << 8) & 0b1100000000;
lvl |= (data[2] & 0xff);
lvl = 1024 - lvl;
// The brighter the environment, the greater the level
return 905;
// 0 the darkest, 1024 the brightest
return lvl;
}
/* Close Ambient Light sensor connection */
void amblght_close()
{
close(amblght_fd);
}
......@@ -23,10 +23,13 @@
#define SENSORS_AMBIENT_LIGHT_H
#include <stdint.h>
#include <bcm2835.h>
/* Initialize the Ambient Light sensor on a given SPI/ADC channel, 0 on success */
int amblght_init(uint8_t);
#define SPI_SPEED 1000000
#define SPI_BITSPERWORD 8
/* Initialize the Ambient Light sensor on a given SPI/Dev + SPI/ADC channel,
* 0 on success */
int amblght_init(const char*, uint8_t);
/* Read out the current ambient light level, returns 0-1023 */
int amblght_level();
......
......@@ -8,7 +8,7 @@
int main(void)
{
if (0 != amblght_init((uint8_t) ADC_CHANNEL)) {
if (0 != amblght_init((const char*) "/dev/spidev0.0", (uint8_t) ADC_CHANNEL)) {
printf("Failed to initialize the Ambient Light sensor.\n");
exit(EXIT_FAILURE);
}
......
......@@ -48,6 +48,8 @@ turn_device_off_after = 600;
# The daemon assumes a state change from LOW to HIGH represents a recognized motion
motion_sensor_gpio = 24;
# The daemon assumes to read the light level from a MCP3008 which is connected
# to the SPI bus. With this setting you can configure which channel of the chip
# will be read out.
# to the SPI bus. With this setting you can choose the Linux kernel SPI device
# the daemon should use. Defaults to "/dev/spidev0.0".
# light_sensor_device = "/dev/spidev0.0";
# With this setting you can configure which channel of the chip will be read out.
# light_sensor_channel = 0;
......@@ -54,6 +54,7 @@ struct config* init_config(struct config *conf)
conf->tholds.motion_locktime = 30;
conf->sensor.motion_gpio = 0;
conf->sensor.light_dev = "/dev/spidev0.0";
conf->sensor.light_channel = 0;
return conf;
......@@ -114,6 +115,7 @@ struct config get_config(const char *path)
* Sensor ports section settings
*/
config_lookup_int(c, "motion_sensor_gpio", &conf.sensor.motion_gpio);
config_lookup_string(c, "light_sensor_device", &conf.sensor.light_dev);
config_lookup_int(c, "light_sensor_channel", &conf.sensor.light_channel);
free((char*) actor_command);
......
......@@ -41,6 +41,7 @@ struct config {
} tholds;
struct config_sensor {
int motion_gpio;
const char *light_dev;
int light_channel;
} sensor;
struct config_t *ptr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment