WIP light meter app

This commit is contained in:
Joey Castillo 2021-09-24 18:26:33 -04:00
parent 115c555c4c
commit bc3b71328d
6 changed files with 211 additions and 0 deletions

79
apps/Light Meter/app.c Normal file
View File

@ -0,0 +1,79 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "watch.h"
#include "tsl2591.h"
#include "app.h"
ApplicationState application_state;
char buf[16] = {0};
void app_init() {
memset(&application_state, 0, sizeof(application_state));
}
void app_wake_from_deep_sleep() {
// This app does not support deep sleep mode.
}
void app_setup() {
watch_enable_external_interrupts();
watch_register_interrupt_callback(BTN_MODE, cb_mode_pressed, INTERRUPT_TRIGGER_RISING);
watch_register_interrupt_callback(BTN_LIGHT, cb_light_pressed, INTERRUPT_TRIGGER_RISING);
watch_register_extwake_callback(BTN_ALARM, cb_alarm_pressed, true);
watch_enable_buzzer();
watch_enable_leds();
// pin A0 powers the sensor on this board.
watch_enable_digital_output(A0);
watch_set_pin_level(A0, true);
delay_ms(10);
watch_enable_i2c();
watch_enable_display();
watch_register_tick_callback(cb_tick);
delay_ms(5000);
if (!tsl2591_init()) {
printf("Sensor init failed?\n");
}
}
void app_prepare_for_sleep() {
}
void app_wake_from_sleep() {
}
bool app_loop() {
return true;
}
void cb_mode_pressed() {
application_state.mode = (application_state.mode + 1) % NUM_MODES;
application_state.mode_changed = true;
application_state.mode_ticks = 300;
application_state.page = 0;
}
void cb_light_pressed() {
application_state.light_ticks = 3;
}
void cb_alarm_pressed() {
}
void cb_tick() {
uint16_t result = tsl2591_get_visible_light_reading();
printf("Visible Light : %d\n\n", result);
if (application_state.light_ticks > 0) {
application_state.light_ticks--;
}
if (application_state.mode_ticks > 0) {
application_state.mode_ticks--;
}
}

37
apps/Light Meter/app.h Normal file
View File

@ -0,0 +1,37 @@
// Sensor Watch: Hiking Log Demo App
// This app displays a clock and temperature data from a BME280 temperature and humidiity sensor.
// It also logs up to 36 hours of temperature data for playback.
// You can use this app on backcountry treks: take the watch off at night and place it outside your tent.
// It will log overnight low temperatures for review in the morning and optional transfer to your notepad.
#define MAX_DATA_POINTS 36
typedef enum ApplicationMode {
MODE_CLOCK = 0, // Displays month, day and current time.
MODE_TEMP, // (TE) Displays temperature and an optional humidity reading (0-10 representing 0-100%)
MODE_LOG, // (LO) Plays back temperature data (temperature in seconds slot)
MODE_PREFS, // (PR) Allows setting options for the application
MODE_SET, // (ST) Set time and date
NUM_MODES // Last item in the enum, it's the number of cases.
} ApplicationMode;
typedef struct SensorReading {
bool is_valid;
uint8_t hour;
int8_t temperature;
} SensorReading;
typedef struct ApplicationState {
// Internal application state
ApplicationMode mode; // Current mode
bool mode_changed; // Lets us perform one-time setup for a given mode
uint16_t mode_ticks; // Timeout for the mode (returns to clock after timeout expires)
uint8_t light_ticks; // Timeout for the light
bool led_on; // Indicates that the LED is on
uint8_t page; // Tracks the current page in log, prefs or settings.
} ApplicationState;
void cb_light_pressed();
void cb_mode_pressed();
void cb_alarm_pressed();
void cb_tick();

1
apps/Light Meter/make/.gitignore vendored Executable file
View File

@ -0,0 +1 @@
build/

11
apps/Light Meter/make/Makefile Executable file
View File

@ -0,0 +1,11 @@
TOP = ../../..
include $(TOP)/make.mk
INCLUDES += \
-I../
SRCS += \
../app.c \
../tsl2591.c
include $(TOP)/rules.mk

View File

@ -0,0 +1,37 @@
#include "tsl2591.h"
#include "watch_i2c.h"
bool tsl2591_init() {
uint8_t device_id = watch_i2c_read8(TSL2591_ADDRESS, TSL2591_REGISTER_DEVICE_ID | TSL2591_COMMAND_BIT);
if (device_id != 0x50) return false;
tsl2591_set_gain(TSL2591_CONTROL_GAIN_LOW);
tsl2591_set_integration_time(TSL2591_CONTROL_INTEGRATIONTIME_100MS);
watch_i2c_write8(TSL2591_ADDRESS, TSL2591_REGISTER_ENABLE | TSL2591_COMMAND_BIT, TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN);
return true;
}
void tsl2591_set_gain(TSL2591Control gain) {
uint8_t control = watch_i2c_read8(TSL2591_ADDRESS, TSL2591_REGISTER_CONTROL | TSL2591_COMMAND_BIT);
control &= 0b11001111;
control |= gain;
watch_i2c_write8(TSL2591_ADDRESS, TSL2591_REGISTER_CONTROL | TSL2591_COMMAND_BIT, control);
}
void tsl2591_set_integration_time(TSL2591Control integration_time) {
uint8_t control = watch_i2c_read8(TSL2591_ADDRESS, TSL2591_REGISTER_CONTROL | TSL2591_COMMAND_BIT);
control &= 0b11111000;
control |= integration_time;
watch_i2c_write8(TSL2591_ADDRESS, TSL2591_REGISTER_CONTROL | TSL2591_COMMAND_BIT, control);
}
uint16_t tsl2591_get_visible_light_reading() {
uint16_t full = make_le_16(watch_i2c_read16(TSL2591_ADDRESS, TSL2591_REGISTER_CHAN0_LOW | TSL2591_COMMAND_BIT));
uint16_t infrared = make_le_16(watch_i2c_read16(TSL2591_ADDRESS, TSL2591_REGISTER_CHAN1_LOW | TSL2591_COMMAND_BIT));
printf("Full Spectrum : %d\n", full);
printf("Infrared : %d\n", infrared);
int32_t result = full - infrared;
return (result > 0) ? (uint16_t)result : 0;
}

View File

@ -0,0 +1,46 @@
#ifndef TSL2591_H_INCLUDED
#define TSL2591_H_INCLUDED
#include <stdint.h>
#include <stdbool.h>
#define TSL2591_ADDRESS (0x29)
#define TSL2591_COMMAND_BIT (0xA0)
typedef enum TSL2591Register {
TSL2591_REGISTER_ENABLE = 0x00,
TSL2591_REGISTER_CONTROL = 0x01,
TSL2591_REGISTER_DEVICE_ID = 0x12,
TSL2591_REGISTER_CHAN0_LOW = 0x14,
TSL2591_REGISTER_CHAN1_LOW = 0x16,
} TSL2591Register;
typedef enum TSL2591Control {
TSL2591_CONTROL_INTEGRATIONTIME_100MS = 0x00,
TSL2591_CONTROL_INTEGRATIONTIME_200MS = 0x01,
TSL2591_CONTROL_INTEGRATIONTIME_300MS = 0x02,
TSL2591_CONTROL_INTEGRATIONTIME_400MS = 0x03,
TSL2591_CONTROL_INTEGRATIONTIME_500MS = 0x04,
TSL2591_CONTROL_INTEGRATIONTIME_600MS = 0x05,
TSL2591_CONTROL_GAIN_LOW = 0x00,
TSL2591_CONTROL_GAIN_MEDIUM = 0x10,
TSL2591_CONTROL_GAIN_HIGH = 0x20,
TSL2591_CONTROL_GAIN_MAX = 0x30
} TSL2591Control;
typedef enum TSL2591Enable {
TSL2591_ENABLE_POWEROFF = 0x00,
TSL2591_ENABLE_POWERON = 0x01,
TSL2591_ENABLE_AEN = 0x02,
TSL2591_ENABLE_AIEN = 0x10,
TSL2591_ENABLE_NPIEN = 0x80,
} TSL2591Enable;
inline uint16_t make_le_16(uint16_t val) { return (val >> 8) | (val << 8); }
bool tsl2591_init();
void tsl2591_set_gain(TSL2591Control gain);
void tsl2591_set_integration_time(TSL2591Control integration_time);
uint16_t tsl2591_get_visible_light_reading();
#endif // TSL2591_H_INCLUDED