WIP light meter app
This commit is contained in:
parent
115c555c4c
commit
bc3b71328d
79
apps/Light Meter/app.c
Normal file
79
apps/Light Meter/app.c
Normal 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
37
apps/Light Meter/app.h
Normal 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
1
apps/Light Meter/make/.gitignore
vendored
Executable file
@ -0,0 +1 @@
|
|||||||
|
build/
|
11
apps/Light Meter/make/Makefile
Executable file
11
apps/Light Meter/make/Makefile
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
TOP = ../../..
|
||||||
|
include $(TOP)/make.mk
|
||||||
|
|
||||||
|
INCLUDES += \
|
||||||
|
-I../
|
||||||
|
|
||||||
|
SRCS += \
|
||||||
|
../app.c \
|
||||||
|
../tsl2591.c
|
||||||
|
|
||||||
|
include $(TOP)/rules.mk
|
37
apps/Light Meter/tsl2591.c
Normal file
37
apps/Light Meter/tsl2591.c
Normal 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;
|
||||||
|
}
|
46
apps/Light Meter/tsl2591.h
Normal file
46
apps/Light Meter/tsl2591.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user