aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
Diffstat (limited to 'spaghetti-monster')
-rw-r--r--spaghetti-monster/anduril/anduril.c26
-rwxr-xr-xspaghetti-monster/anduril/build-all.sh3
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d1.h7
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d1s.h7
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4-219c.h8
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4.h7
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4s-219c.h5
-rw-r--r--spaghetti-monster/anduril/cfg-emisar-d4s.h17
-rw-r--r--spaghetti-monster/anduril/cfg-fw3a.h2
-rw-r--r--spaghetti-monster/fsm-events.c12
-rwxr-xr-xspaghetti-monster/rampingios/build-all.sh7
-rw-r--r--spaghetti-monster/rampingios/rampingios-v3.html501
-rw-r--r--spaghetti-monster/rampingios/rampingios-v3.md262
-rw-r--r--spaghetti-monster/rampingios/rampingios-v3.txt324
-rw-r--r--spaghetti-monster/rampingios/rampingiosv3.c61
15 files changed, 1201 insertions, 48 deletions
diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c
index c8517af..c98026f 100644
--- a/spaghetti-monster/anduril/anduril.c
+++ b/spaghetti-monster/anduril/anduril.c
@@ -26,8 +26,9 @@
//#define FSM_EMISAR_D1_DRIVER
//#define FSM_EMISAR_D1S_DRIVER
//#define FSM_EMISAR_D4_DRIVER
+//#define FSM_EMISAR_D4_219C_DRIVER
//#define FSM_EMISAR_D4S_DRIVER
-//#define FSM_EMISAR_D4S_219c_DRIVER
+//#define FSM_EMISAR_D4S_219C_DRIVER
//#define FSM_FF_ROT66_DRIVER
//#define FSM_FW3A_DRIVER
@@ -37,6 +38,10 @@
#define USE_THERMAL_REGULATION
#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this
+// short blip when crossing from "click" to "hold" from off
+// (helps the user hit moon mode exactly, instead of holding too long
+// or too short)
+#define MOON_TIMING_HINT
// short blips while ramping
#define BLINK_AT_CHANNEL_BOUNDARIES
//#define BLINK_AT_RAMP_FLOOR
@@ -84,10 +89,13 @@
#elif defined(FSM_EMISAR_D1S_DRIVER)
#include "cfg-emisar-d1s.h"
+#elif defined(FSM_EMISAR_D4_219C_DRIVER)
+#include "cfg-emisar-d4-219c.h"
+
#elif defined(FSM_EMISAR_D4_DRIVER)
#include "cfg-emisar-d4.h"
-#elif defined(FSM_EMISAR_D4S_219c_DRIVER)
+#elif defined(FSM_EMISAR_D4S_219C_DRIVER)
#include "cfg-emisar-d4s-219c.h"
#elif defined(FSM_EMISAR_D4S_DRIVER)
@@ -392,9 +400,19 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
}
// hold: go to lowest level
else if (event == EV_click1_hold) {
+ #ifdef MOON_TIMING_HINT
+ if (arg == 0) {
+ // let the user know they can let go now to stay at moon
+ uint8_t temp = actual_level;
+ set_level(0);
+ delay_4ms(2);
+ set_level(temp);
+ } else
+ #endif
// don't start ramping immediately;
// give the user time to release at moon level
- if (arg >= HOLD_TIMEOUT) {
+ //if (arg >= HOLD_TIMEOUT) { // smaller
+ if (arg >= (!ramp_style) * HOLD_TIMEOUT) { // more consistent
set_state(steady_state, 1);
}
return MISCHIEF_MANAGED;
@@ -524,7 +542,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
// 3 clicks: toggle smooth vs discrete ramping
else if (event == EV_3clicks) {
ramp_style = !ramp_style;
- memorized_level = nearest_level(memorized_level);
+ memorized_level = nearest_level(actual_level);
#ifdef USE_THERMAL_REGULATION
target_level = memorized_level;
#ifdef USE_SET_LEVEL_GRADUALLY
diff --git a/spaghetti-monster/anduril/build-all.sh b/spaghetti-monster/anduril/build-all.sh
index 794b285..a8bb397 100755
--- a/spaghetti-monster/anduril/build-all.sh
+++ b/spaghetti-monster/anduril/build-all.sh
@@ -9,8 +9,9 @@ for TARGET in \
EMISAR_D1 \
EMISAR_D1S \
EMISAR_D4 \
+ EMISAR_D4_219C \
EMISAR_D4S \
- EMISAR_D4S_219c \
+ EMISAR_D4S_219C \
FF_ROT66 \
FW3A \
; do
diff --git a/spaghetti-monster/anduril/cfg-emisar-d1.h b/spaghetti-monster/anduril/cfg-emisar-d1.h
index e9064ac..d35480c 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d1.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d1.h
@@ -2,5 +2,12 @@
#include "cfg-emisar-d4.h"
// stop panicking at ~75% power or ~1000 lm (D1 has a decent power-to-thermal-mass ratio)
+#ifdef THERM_FASTER_LEVEL
#undef THERM_FASTER_LEVEL
+#endif
#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high
+
+// no need to be extra-careful on this light
+#ifdef THERM_HARD_TURBO_DROP
+#undef THERM_HARD_TURBO_DROP
+#endif
diff --git a/spaghetti-monster/anduril/cfg-emisar-d1s.h b/spaghetti-monster/anduril/cfg-emisar-d1s.h
index 7e73fa7..eb98c2e 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d1s.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d1s.h
@@ -2,5 +2,12 @@
#include "cfg-emisar-d4.h"
// stop panicking at ~90% power or ~1200 lm (D1S has a good power-to-thermal-mass ratio)
+#ifdef THERM_FASTER_LEVEL
#undef THERM_FASTER_LEVEL
+#endif
#define THERM_FASTER_LEVEL 144 // throttle back faster when high
+
+// no need to be extra-careful on this light
+#ifdef THERM_HARD_TURBO_DROP
+#undef THERM_HARD_TURBO_DROP
+#endif
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4-219c.h b/spaghetti-monster/anduril/cfg-emisar-d4-219c.h
new file mode 100644
index 0000000..55ae1eb
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-emisar-d4-219c.h
@@ -0,0 +1,8 @@
+// Emisar D4-219C config options for Anduril
+// same as D4S but with FET modes limited to 80% power
+// to avoid destroying the LEDs
+#define FSM_EMISAR_D4_DRIVER
+#include "cfg-emisar-d4.h"
+
+#undef PWM2_LEVELS
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,7,8,9,11,12,13,15,16,17,19,20,21,23,24,26,28,29,31,32,34,36,38,40,41,44,45,47,49,51,53,56,57,60,62,64,67,69,72,74,76,79,81,84,87,89,92,95,97,100,103,106,109,112,115,118,121,124,128,132,135,138,141,145,148,152,156,160,164,167,171,175,179,183,187,191,195,200,204
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4.h b/spaghetti-monster/anduril/cfg-emisar-d4.h
index 4ac1f5e..251f81d 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4.h
@@ -14,7 +14,8 @@
#define QUARTERSPEED_LEVEL 5
// optional, makes initial turbo step-down faster so first peak isn't as hot
-//#define THERM_HARD_TURBO_DROP
+// the D4 runs very very hot, so be extra careful
+#define THERM_HARD_TURBO_DROP
-// stop panicking at ~25% power or ~1000 lm, this light is a hotrod
-#define THERM_FASTER_LEVEL (RAMP_SIZE*2/3) // throttle back faster when high
+// stop panicking at ~30% power or ~1200 lm
+#define THERM_FASTER_LEVEL 105
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4s-219c.h b/spaghetti-monster/anduril/cfg-emisar-d4s-219c.h
index a98f123..c02274d 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4s-219c.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4s-219c.h
@@ -1,9 +1,8 @@
-// Emisar D4S-219c config options for Anduril
+// Emisar D4S-219C config options for Anduril
// same as D4S but with FET modes limited to 80% power
// to avoid destroying the LEDs
#define FSM_EMISAR_D4S_DRIVER
#include "cfg-emisar-d4s.h"
#undef PWM2_LEVELS
-#define PWM2_LEVELS PWM2_LEVELS_219c
-
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,8,8,10,11,12,14,15,16,18,20,21,23,24,27,28,30,32,34,36,38,40,43,45,48,50,52,55,57,60,63,66,69,72,76,79,82,85,89,92,96,100,104,108,112,116,121,126,130,135,140,145,150,156,161,167,172,178,184,191,197,204
diff --git a/spaghetti-monster/anduril/cfg-emisar-d4s.h b/spaghetti-monster/anduril/cfg-emisar-d4s.h
index ddb56ee..ef55668 100644
--- a/spaghetti-monster/anduril/cfg-emisar-d4s.h
+++ b/spaghetti-monster/anduril/cfg-emisar-d4s.h
@@ -16,31 +16,26 @@
#define RAMP_LENGTH 150
// 3x7135 + FET
-#if 0 // first attempt
-// ../../bin/level_calc.py 2 150 7135 1 6 450 FET 1 10 1810
-// (because it made the ramp look better than accurate values)
-#define PWM1_LEVELS 1,1,2,2,3,3,4,5,5,6,7,7,8,9,10,11,12,13,14,15,16,18,19,20,22,23,25,26,28,30,32,33,35,37,39,42,44,46,48,51,53,56,58,61,64,67,70,73,76,79,83,86,89,93,97,100,104,108,112,116,121,125,129,134,139,143,148,153,158,163,169,174,180,185,191,197,203,209,215,222,228,235,241,248,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
-#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,6,9,11,14,16,19,22,24,27,30,33,36,39,42,45,48,51,54,57,61,64,67,71,74,78,82,85,89,93,96,100,104,108,112,116,121,125,129,133,138,142,147,151,156,160,165,170,175,180,185,190,195,200,205,210,216,221,227,232,238,243,249,255
-#define MAX_1x7135 85
-#define HALFSPEED_LEVEL 11
-#define QUARTERSPEED_LEVEL 5
-#else // updated, better shape
// ../../bin/level_calc.py 2 150 7135 1 11.2 450 FET 1 10 4000
// (with a x**9 curve instead of x**3)
// (because it made the ramp look better than accurate values)
#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,16,17,18,19,21,22,23,25,26,27,29,31,32,34,36,38,40,42,44,46,49,51,54,56,59,62,65,68,71,74,78,81,85,89,93,97,101,106,110,115,120,125,130,136,141,147,153,160,166,173,180,187,195,202,210,219,227,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,10,11,13,14,16,18,19,21,23,25,27,29,31,34,36,38,41,43,46,48,51,54,57,60,63,66,69,72,76,79,83,87,91,95,99,103,107,112,116,121,126,131,136,141,146,152,158,163,169,175,182,188,195,202,209,216,223,231,239,247,255
-#define PWM2_LEVELS_219c 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,8,8,10,11,12,14,15,16,18,20,21,23,24,27,28,30,32,34,36,38,40,43,45,48,50,52,55,57,60,63,66,69,72,76,79,82,85,89,92,96,100,104,108,112,116,121,126,130,135,140,145,150,156,161,167,172,178,184,191,197,204
#define MAX_1x7135 83
#define HALFSPEED_LEVEL 13
#define QUARTERSPEED_LEVEL 6
-#endif
// ceiling is level 120/150
#define RAMP_SMOOTH_CEIL (MAX_LEVEL*4/5)
// thermal regulation parameters
+#ifdef MIN_THERM_STEPDOWN
#undef MIN_THERM_STEPDOWN // this should be lower, because 3x7135 instead of 1x7135
+#endif
#define MIN_THERM_STEPDOWN 60 // lowest value it'll step down to
#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high
+// no need to be extra-careful on this light
+#ifdef THERM_HARD_TURBO_DROP
+#undef THERM_HARD_TURBO_DROP
+#endif
diff --git a/spaghetti-monster/anduril/cfg-fw3a.h b/spaghetti-monster/anduril/cfg-fw3a.h
index 262ef13..65f1e48 100644
--- a/spaghetti-monster/anduril/cfg-fw3a.h
+++ b/spaghetti-monster/anduril/cfg-fw3a.h
@@ -19,4 +19,4 @@
// stop panicking at about 3A or ~1100 lm, this light is a hotrod
#define THERM_FASTER_LEVEL MAX_Nx7135
// optional, makes initial turbo step-down faster so first peak isn't as hot
-//#define THERM_HARD_TURBO_DROP
+#define THERM_HARD_TURBO_DROP
diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c
index c71e822..ee7bc97 100644
--- a/spaghetti-monster/fsm-events.c
+++ b/spaghetti-monster/fsm-events.c
@@ -50,10 +50,14 @@ void empty_event_sequence() {
uint8_t push_event(uint8_t ev_type) {
ticks_since_last_event = 0; // something happened
uint8_t i;
- uint8_t prev_event = 0; // never push the same event twice in a row
- for(i=0; current_event[i] && (i<EV_MAX_LEN); i++)
- prev_event = current_event[i];
- if ((i < EV_MAX_LEN-1) && (prev_event != ev_type)) {
+ //uint8_t prev_event = 0; // never push the same event twice in a row
+ for(i=0; current_event[i] && (i<EV_MAX_LEN); i++) {
+ // this doesn't actually seem to be necessary any more...
+ //prev_event = current_event[i];
+ }
+ //if ((i < EV_MAX_LEN) && (prev_event != ev_type)) {
+ //if (prev_event != ev_type) {
+ if (i < EV_MAX_LEN) {
current_event[i] = ev_type;
return 1; // event pushed
} else {
diff --git a/spaghetti-monster/rampingios/build-all.sh b/spaghetti-monster/rampingios/build-all.sh
index 7546bd9..22597b7 100755
--- a/spaghetti-monster/rampingios/build-all.sh
+++ b/spaghetti-monster/rampingios/build-all.sh
@@ -5,15 +5,12 @@ cp -av ../anduril/cfg*.h .
UI=rampingiosv3
for TARGET in \
- BLF_GT \
- BLF_GT_MINI \
- BLF_Q8 \
EMISAR_D1 \
EMISAR_D1S \
EMISAR_D4 \
+ EMISAR_D4_219C \
EMISAR_D4S \
- EMISAR_D4S_219c \
- FW3A \
+ EMISAR_D4S_219C \
; do
echo "===== $TARGET ====="
../../../bin/build-85.sh "$UI" "-DFSM_${TARGET}_DRIVER"
diff --git a/spaghetti-monster/rampingios/rampingios-v3.html b/spaghetti-monster/rampingios/rampingios-v3.html
new file mode 100644
index 0000000..f72d1ec
--- /dev/null
+++ b/spaghetti-monster/rampingios/rampingios-v3.html
@@ -0,0 +1,501 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+<head>
+ <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scape=1.0; user-scalable=false;">
+ <link rel="apple-touch-icon" href="/phil/avatar-iphone.png">
+ <title>RampingIOS V3 Manual :: Phil! Gold</title>
+
+ <meta name="DC.title" content="Phil! Gold">
+
+ <link rel="openid2.provider" href="https://www.google.com/accounts/o8/ud" />
+ <link rel="openid2.local_id" href="https://plus.google.com/116471799767513262335" />
+ <!-- Old one preserved, because some sites use the provider as an account key (bad them). -->
+ <!--link rel="openid.server" href="http://www.livejournal.com/openid/server.bml"-->
+ <!--link rel="openid.delegate" href="http://phil-g.livejournal.com/"-->
+
+ <link rel="alternate" type="application/rss+xml" title="RSS" href="http://aperiodic.net/phil/archives/index.rss">
+ <link rel="stylesheet" type="text/css" href="/phil/default.css">
+ <link rel="stylesheet" type="text/css" href="/phil/blog.css">
+
+</head>
+
+<body>
+
+<div id="header">
+ <h1>RampingIOS V3 Manual</h1>
+</div>
+
+<div id="content">
+<h2>Tue, 28 Aug 2018</h2>
+
+<div class="story-title" id="rampingios-v3">
+ <h3>RampingIOS V3 Manual</h3>
+ <div class="title-links">
+ 9:47AM |
+ <a href="http://aperiodic.net/phil/archives/Geekery" >Geekery</a> |
+
+ <a href="http://aperiodic.net/phil/archives/Geekery/rampingios-v3.html" title="permalink for RampingIOS V3 Manual" rel="bookmark">#</a>
+ </div>
+</div>
+
+<p><figure style="float: right">
+ <a href="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3ui.png-20180807025443-zdamv4ixtu49o7hm-1/rampingiosv3-ui.png">
+ <!-- img width="256em" src="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3.svg-20180807025420-q28902kbav01123w-1/rampingiosv3.svg" -->
+ <img width="256em" src="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3ui.png-20180807025443-zdamv4ixtu49o7hm-1/rampingiosv3-ui.png">
+ </a>
+ <figcaption>RampingIOS V3 UI diagram</figcaption>
+</figure></p>
+
+<p>The Emisar <a href="https://intl-outdoor.com/emisar-d4s-26650-high-power-led-flashlight-p-932.html">D4S</a> flashlights use a firmware named RampingIOS
+V3. (The Emisar <a href="https://intl-outdoor.com/emisar-d4-high-power-led-flashlight-p-921.html">D4</a>, <a href="https://intl-outdoor.com/emisar-d1-mini-thrower-p-922.html">D1</a>, and <a href="https://intl-outdoor.com/emisar-d1s-thrower-p-926.html">D1S</a>
+all use <a href="http://aperiodic.net/phil/archives/Geekery/rampingios-v2.html">RampingIOS V2</a>.) There's not really a manual; the
+only thing we get is the diagram on the right. It's reasonably
+comprehensive, but there's a fair amount of detail it merely summarizes,
+so I thought a textual manual would be nice.</p>
+
+<p>The Emisar D4S only works when the head and tailcap are tightened fully.
+You can physically lock it out--prevent it from turning on
+accidentally--by simply loosening the tailcap a small amount. A quarter
+turn will do it.</p>
+
+<p>Emisar lights are known for their ramping interfaces. Rather than have a
+small number of distinct brightness levels, they can vary their brightness
+anywhere between their lowest and highest levels, like a light on a
+dimmer. The D4S is in ramping mode by default, but it also has a stepped
+mode that can be configured to be closer to how non-ramping lights work.</p>
+
+<p>Each mode--ramping and stepped--can have differently-configured brightness
+floors and ceilings.</p>
+
+<p>The driver for the D4S has two different chipsets. At low brightness
+levels, a fairly-efficient but low-power chipset (called a <em>7135</em>) is
+used. These lowest brightness levels are called the "<em>regulated levels</em>".
+Each regulated level will always be the same brightness regardless of how
+much charge the battery has. Above a particular brightness level, the
+light switches over to a less-efficient but high-power chipset (called a
+<em>FET</em>). These levels are called "<em>direct-drive</em>". The brightness of the
+direct-drive levels is directly related to the battery's charge level; the
+more charged the battery, the brighter the levels. The light is at its
+most efficient, in terms of power used for every lumen generated, at the
+brightest regulated level. When the light is first powered by tightening
+the tailcap, it will default to this level.</p>
+
+<p>At higher brightness levels, the light's LEDs generate a lot of heat. If
+the light exceeds its configured maximum temperature, it will begin
+dimming itself automatically until the temperature drops below the allowed
+maximum.</p>
+
+<p>The D4S has a set of cyan-colored auxiliary LEDs that can be on when the
+main LEDs are off. You can configure the behavior of the aux LEDs.</p>
+
+<h4>Basic Usage</h4>
+
+<p>The default mode for the light is ramping mode. Triple-pressing the
+button (<strong>3 clicks</strong>) while the light is on will toggle between ramping
+and stepped mode.</p>
+
+<p>While the light is off, press and release the button (<strong>1 click</strong>) to turn
+it on. It will turn on at the last-used brightness level. (This is
+called "<em>mode memory</em>".) Immediately after loosening and tightening the
+tailcap (or after changing the battery), the memorized level will be the
+light's max regulated level.</p>
+
+<p>When the light is on, 1 click will turn it off. The current brightness
+level will be memorized for future use. There's a fraction of a second
+delay between pressing the button and the light actually turning off.
+That's because of the way the light processes input; it's waiting to make
+sure you're only going to press the button once (since multiple presses
+will trigger other actions).</p>
+
+<p>When the light is on, holding the button down will brighten the light. In
+ramping mode, the brightness will increase gradually ("<em>ramping up</em>"). In
+stepped mode, the light will jump through increasing brightness levels.
+If you press, release, and then hold the button, it will begin dimming.
+In ramping mode, the brightness will decrease gradually ("<em>ramping
+down</em>"). In stepped mode, the light will jump through decreasing
+brightness levels. While the light is changing, if you release the button
+and immediately hold it again, the direction (dimming or brightening) will
+switch.</p>
+
+<p>In ramping mode, while the light is ramping, it'll briefly blink off and
+on again at two different brightness levels: the maximum regulated level
+and the brightness ceiling.</p>
+
+<p>While the light is off, double-pressing the button (<strong>2 clicks</strong>) will
+immediately jump to the brightness ceiling.</p>
+
+<p>While the light is on, <strong>2 clicks</strong> will jump to the maximum brightness
+level, regardless of the configured brightness ceiling. Another two
+clicks will go back to the previous brightness level.</p>
+
+<p>While the light is off, if you hold the button the light will turn on at
+its lowest level. If you continue holding the button, the light will
+begin brightening from there.</p>
+
+<h5>Configuration Menus</h5>
+
+<p>The light has several different configuration modes. Each of those modes
+works more or less the same way. The mode will have a series of menu
+items that it will go through. For each menu item, the light will first
+blink a number of times corresponding to the item number (first, second,
+etc.) After that, the light will begin fluttering on and off fairly
+quickly. While the light is fluttering, you can click the button a number
+of times; the light will count the number of button presses and use that
+number as its new configuration for that menu item. After a short period
+of time, the fluttering will stop and the light will move on to the next
+menu item. After the light has gone through all of the menu items, it
+will return to whatever mode it was in before entering the configuration
+mode.</p>
+
+<p>If you don't press the button during a particular menu item's fluttering,
+that item will remain unchanged.</p>
+
+<h5>Configuring the Basic Modes</h5>
+
+<p>While the light is on, <strong>4 clicks</strong> will enter ramping or stepped
+configuration mode, depending on which mode the light was in before the 4
+clicks.</p>
+
+<p>For ramping mode, there are two menu options:</p>
+
+<ol>
+<li>Brightness floor (default 1/150)</li>
+<li>Brightness ceiling (default 150/150)</li>
+</ol>
+
+<p>During the floor configuration, press the button equal to the number of
+ramping levels (out of 150) at which the floor should be. To set the
+lowest possible floor, click the button once.</p>
+
+<p>The ceiling is configured similarly, but you press the button equal to the
+number of steps away from maximum brightness. To set the highest possible
+ceiling (at max brightness), click the button once.</p>
+
+<p>For stepped mode, there are three menu options:</p>
+
+<ol>
+<li>Brightness floor (default 20/150)</li>
+<li>Brightness ceiling (default 120/150)</li>
+<li>Number of steps (default 7)</li>
+</ol>
+
+<h4>Other Modes</h4>
+
+<p>The other modes largely involve multiple clicks from off. Most of them
+are not generally needed for everyday use, but they supplement the light's
+basic operations.</p>
+
+<h5>BattCheck/TempCheck Modes</h5>
+
+<p>From off, <strong>3 clicks</strong> will enter "BattCheck" mode, which blinks out the
+current battery voltage. First it blinks the number of volts, then it
+pauses, then it blinks out the tenths of volts. Thus, if the battery were
+at 3.5 volts, the light would blink three times, pause, then five times.
+For zeroes, it gives a very short blink.</p>
+
+<p>A fully-charged lithium-ion battery is 4.2 volts. The light considers 2.8
+volts to be an empty battery and won't turn on if the battery is at or
+below 2.8 volts.</p>
+
+<p>The voltage sequence will continue blinking until you turn off the light
+with a single click.</p>
+
+<p>While the light is in BattCheck mode, <strong>2 clicks</strong> will enter TempCheck
+mode. Instead of blinking out the battery voltage, the light will start
+blinking out its current temperature in degrees Celsius, first the tens
+digit then the units digit. Like BattCheck mode, the light will continue
+blinking out the temperature until you turn it off with a single click.</p>
+
+<p>While the light is in TempCheck mode, <strong>4 clicks</strong> will enter thermal
+configuration mode. See the thermal configuration mode documentation
+below for how that works.</p>
+
+<h5>Tactical Mode</h5>
+
+<p>From off, <strong>4 clicks</strong> will enter "tactical" or "momentary" mode. The
+light will flash once to show that it's entered the mode. The auxiliary
+LEDs will turn off (if they were on). In tactical mode, the light will
+turn on at its memorized brightness for as long as the button is being
+held down. It will turn off as soon as the button is released.</p>
+
+<p>There's no button press combination that will exit tactical mode. To exit
+it, you will have to partially unscrew and retighten the tailcap.</p>
+
+<h5>Lockout Mode</h5>
+
+<p>From off, <strong>6 clicks</strong> will enter lockout mode. The light will flash
+twice to show that it's entered the mode. There's a separate aux LED mode
+for lockout mode, so you can tell whether the light is in lockout or not.</p>
+
+<p>In lockout mode, pressing the button will turn on the light at its lowest
+brightness ("<em>moonlight mode</em>") for as long as the button is held down.</p>
+
+<p>Another 6 clicks will exit lockout mode. The light will flash twice to
+show that it's left the mode.</p>
+
+<p>While in lockout mode, <strong>3 clicks</strong> will cycle through the various
+settings for the aux LEDs in lockout mode. The four modes are, in order:
+low, high, blink (on high), and off. The default mode is blink.</p>
+
+<p>Remember that loosening the tailcap a quarter turn will also lock out the
+light. Using the 6 clicks is called "<em>electronic lockout</em>", while turning
+the tailcap is "<em>physical lockout</em>".</p>
+
+<h5>Aux LED Configuration</h5>
+
+<p>From off, <strong>7 clicks</strong> will cycle to the next aux LED mode. The four
+modes are, in order: low, high, blink (on high), and off. The default
+mode is low.</p>
+
+<h5>Beacon Mode</h5>
+
+<p>From off, <strong>8 clicks</strong> will enter beacon mode. In beacon mode, the light
+will blink on and off every few seconds.</p>
+
+<p>By default, the light will blink every two seconds. To change the timing,
+use <strong>4 clicks</strong> while in beacon mode. The light will enter a one-item
+menu. During the flickering for input, press the button a number of times
+equal to the number of seconds between blinks.</p>
+
+<p>1 click will exit beacon mode.</p>
+
+<h5>Thermal Configuration Mode</h5>
+
+<p>From off, <strong>10 clicks</strong> will enter thermal configuration mode.</p>
+
+<p>The menu items here are:</p>
+
+<ol>
+<li>Current temperature (every click is one degree Celsius)</li>
+<li>Temperature ceiling (every click is one degree <em>above 30°C</em>)</li>
+</ol>
+
+<p>The "current temperature" item can be used to adjust the calibration of
+the light's temperature sensor. To use it, make sure the light has been
+off long enough that all of its components have cooled (or warmed) to the
+ambient temperature. Check the ambient temperature using a thermometer
+you trust. Go to thermal configuration mode, and enter the current
+temperature by clicking the button a number of times equal to the
+temperature in degrees Celsius. (If it's 22°C, click the button 22
+times.)</p>
+
+<p>You can check the default calibration by entering TempCheck mode from a
+room-temperature light. The D4Ss are supposed to go through a temperature
+calibration at the factory, so hopefully most of them won't need manual
+thermal calibration.</p>
+
+<p>The temperature ceiling is simply the highest temperature the light should
+be allowed to reach. Once it hits its temperature ceiling, it will
+progressively dim itself until the temperature stabilizes below the
+ceiling. Note that the number of clicks in that menu option is added to
+<em>30</em> to reach the actual ceiling. (Thus, you can't set a ceiling below
+31°C.) The maximum allowed ceiling is 70°C.</p>
+
+<p>The default temperature ceiling is 45°C.</p>
+
+
+</div>
+
+<div id="sidebar">
+ <h2>Static</h2>
+ <ul>
+ <li><a href="/phil/prompt/">zsh prompt</a></li>
+ <li><a href="/phil/pgp/">PGP</a></li>
+ <li><a href="/phil/ssh/">SSH</a></li>
+ <li><a href="/phil/MTA/">MTA</a></li>
+ <li><a href="/phil/tutorials/">tutorials</a></li>
+ <li><a href="/phil/configs/">config files</a></li>
+ <li><a href="http://www.flickr.com/photos/phil_g/sets/1671829/">desktop</a></li>
+ <li><a href="http://www.librarything.com/catalog/asciiphil">books I own</a></li>
+ <li><a href="/phil/stuff/">stuff I'm giving away</a></li>
+ <li><a href="/phil/drwho/">Dr. Who eps I have</a></li>
+ <li><a href="http://del.icio.us/phil_g">bookmarks</a></li>
+ <li><a href="http://www.flickr.com/photos/phil_g/">photos</a></li>
+ <li><a href="/phil/about.html">about</a></li>
+ </ul>
+
+ <h2>Directory</h2>
+ <ul class="categories">
+<li><a href="http://aperiodic.net/phil/archives/index.html">Root</a> (143)
+<ul>
+<li><a href="http://aperiodic.net/phil/archives/Books/index.html">Books</a> (32)
+</li>
+<li><a href="http://aperiodic.net/phil/archives/Events/index.html">Events</a> (7)
+<ul>
+<li><a href="http://aperiodic.net/phil/archives/Events/Burning_Man/index.html">Burning Man</a> (3)
+</li>
+<li><a href="http://aperiodic.net/phil/archives/Events/Camping/index.html">Camping</a> (2)
+</li>
+<li><a href="http://aperiodic.net/phil/archives/Events/PDF/index.html">PDF</a> (2)
+</li>
+</ul>
+</li>
+<li class="this-category">Geekery (36)
+<ul>
+<li><a href="http://aperiodic.net/phil/archives/Geekery/Test/index.html">Test</a> (3)
+</li>
+</ul>
+</li>
+<li><a href="http://aperiodic.net/phil/archives/General/index.html">General</a> (24)
+</li>
+<li><a href="http://aperiodic.net/phil/archives/Links/index.html">Links</a> (12)
+<ul>
+<li><a href="http://aperiodic.net/phil/archives/Links/Slashdot/index.html">Slashdot</a> (1)
+</li>
+</ul>
+</li>
+<li><a href="http://aperiodic.net/phil/archives/MTA/index.html">MTA</a> (22)
+</li>
+<li><a href="http://aperiodic.net/phil/archives/Recipes/index.html">Recipes</a> (4)
+</li>
+<li><a href="http://aperiodic.net/phil/archives/Video_Games/index.html">Video Games</a> (6)
+<ul>
+<li><a href="http://aperiodic.net/phil/archives/Video_Games/FFXI/index.html">FFXI</a> (1)
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+
+ <h2>Archive</h2>
+ <table class="month-calendar"><caption class="month-calendar-head"><a title="December 2017 (1)" href="http://aperiodic.net/phil/archives/2017/12/">&larr;</a><a title="August 2018 (2)" href="http://aperiodic.net/phil/archives/2018/08/">August</a>&rarr;</caption>
+ <tr>
+ <th class="month-calendar-day-head Sunday">Sun</th>
+ <th class="month-calendar-day-head Monday">Mon</th>
+ <th class="month-calendar-day-head Tuesday">Tue</th>
+ <th class="month-calendar-day-head Wednesday">Wed</th>
+ <th class="month-calendar-day-head Thursday">Thu</th>
+ <th class="month-calendar-day-head Friday">Fri</th>
+ <th class="month-calendar-day-head Saturday">Sat</th>
+ </tr>
+ <tr>
+ <td class="month-calendar-day-noday Sunday">&nbsp;</td>
+ <td class="month-calendar-day-noday Monday">&nbsp;</td>
+ <td class="month-calendar-day-noday Tuesday">&nbsp;</td>
+<td class="month-calendar-day-nolink Wednesday">1</td>
+<td class="month-calendar-day-nolink Thursday">2</td>
+<td class="month-calendar-day-nolink Friday">3</td>
+<td class="month-calendar-day-nolink Saturday">4</td>
+</tr>
+ <tr>
+<td class="month-calendar-day-nolink Sunday">5</td>
+<td class="month-calendar-day-nolink Monday">6</td>
+<td class="month-calendar-day-nolink Tuesday">7</td>
+<td class="month-calendar-day-nolink Wednesday">8</td>
+<td class="month-calendar-day-nolink Thursday">9</td>
+<td class="month-calendar-day-nolink Friday">10</td>
+<td class="month-calendar-day-nolink Saturday">11</td>
+</tr>
+ <tr>
+<td class="month-calendar-day-nolink Sunday">12</td>
+<td class="month-calendar-day-nolink Monday">13</td>
+<td class="month-calendar-day-nolink Tuesday">14</td>
+<td class="month-calendar-day-nolink Wednesday">15</td>
+<td class="month-calendar-day-nolink Thursday">16</td>
+<td class="month-calendar-day-nolink Friday">17</td>
+<td class="month-calendar-day-nolink Saturday">18</td>
+</tr>
+ <tr>
+<td class="month-calendar-day-nolink Sunday">19</td>
+<td class="month-calendar-day-nolink Monday">20</td>
+<td class="month-calendar-day-nolink Tuesday">21</td>
+<td class="month-calendar-day-nolink Wednesday">22</td>
+<td class="month-calendar-day-nolink Thursday">23</td>
+<td class="month-calendar-day-nolink Friday">24</td>
+<td class="month-calendar-day-nolink Saturday">25</td>
+</tr>
+ <tr>
+<td class="month-calendar-day-link Sunday"><a title="Sunday, 26 August 2018 (1)" href="http://aperiodic.net/phil/archives/2018/08/26/">26</a></td>
+<td class="month-calendar-day-nolink Monday">27</td>
+<td class="month-calendar-day-this-day Tuesday"><a title="Tuesday, 28 August 2018 (current) (1)" href="http://aperiodic.net/phil/archives/2018/08/28/">28</a></td>
+<td class="month-calendar-day-nolink Wednesday">29</td>
+<td class="month-calendar-day-nolink Thursday">30</td>
+<td class="month-calendar-day-nolink Friday">31</td>
+ <td class="month-calendar-day-noday Saturday">&nbsp;</td>
+</tr>
+</table>
+
+ <table class="year-calendar"><caption class="year-calendar-head"><a title="2017 (3)" href="http://aperiodic.net/phil/archives/2017/">&larr;</a><a title="2018 (2)" href="http://aperiodic.net/phil/archives/2018/">2018</a>&rarr;</caption><tr><th class="year-calendar-subhead" colspan="6">Months</th></tr>
+<tr>
+<td class="year-calendar-month-nolink">Jan</td>
+<td class="year-calendar-month-nolink">Feb</td>
+<td class="year-calendar-month-nolink">Mar</td>
+<td class="year-calendar-month-nolink">Apr</td>
+<td class="year-calendar-month-nolink">May</td>
+<td class="year-calendar-month-nolink">Jun</td>
+</tr>
+<tr>
+<td class="year-calendar-month-nolink">Jul</td>
+<td class="year-calendar-this-month"><a title="August 2018 (2)" href="http://aperiodic.net/phil/archives/2018/08/">Aug</a></td><td class="year-calendar-month-future">Sep</td>
+<td class="year-calendar-month-future">Oct</td>
+<td class="year-calendar-month-future">Nov</td>
+<td class="year-calendar-month-future">Dec</td>
+</tr>
+</table>
+
+
+ <h2>Search</h2>
+ <form method="GET" action="http://www.google.com/custom">
+ <p style="text-align: center">
+ <input type="hidden" name="domains" value="aperiodic.net">
+ <input type="hidden" name="cof" VALUE="GALT:#66CC6;S:http://aperiodic.net/phil/;GL:2;VLC:#CC66CC;AH:center;BGC:#000000;LC:#6666CC;GFNT:#666666;ALC:#CC6666;T:#CCCCCC;GIMP:#FFFFFF;AWFID:d3f1afbc39619250;">
+ <input type="hidden" name="sitesearch" value="aperiodic.net">
+ <input name="q" type="text" size="25" maxlength="255" style="width: 10em"><br>
+ Powered by <a href="http://www.google.com/"><span class="google-G1">G</span><span class="google-o1">o</span><span class="google-o2">o</span><span class="google-g2">g</span><span class="google-l">l</span><span class="google-e">e</span></a>
+ </p>
+ </form>
+
+
+ <h2>Currently Reading</h2>
+
+ <div id="wb55a1f3ca64835526140c06560a0205e"></div>
+ <script type="text/javascript" charset="UTF-8"
+ src="http://www.librarything.com/widget_get.php?userid=asciiphil&theID=wb55a1f3ca64835526140c06560a0205e">
+ </script>
+
+ <h2>Recent Books</h2>
+
+ <div id="wa13cfbb5a4be4d629ebe322b83f1e2f6"></div>
+ <script type="text/javascript" charset="UTF-8"
+ src="http://www.librarything.com/widget_get.php?userid=asciiphil&theID=wa13cfbb5a4be4d629ebe322b83f1e2f6">
+ </script>
+
+</div>
+
+<div class="hr"><hr></div>
+<address><a href="mailto:phil_g@pobox.com">Phil! Gold</a></address>
+<p class="footer">
+<a href="/phil/">Back to main page.</a><br>
+</p>
+<ul class="validation">
+ <li>
+ <a href="http://validator.w3.org/check/referer">
+ <img src="/phil/pics/html401.png" alt="Valid HTML 4.01">
+ </a>
+ </li>
+
+ <li>
+ <a href="http://jigsaw.w3.org/css-validator/check/referer">
+ <img src="/phil/pics/validcss.png" alt="Valid CSS 2">
+ </a>
+ </li>
+
+ <li>
+ <a href="http://aperiodic.net/phil/archives/index.rss">
+ <img src="/phil/pics/rss10.png" alt="RSS syndication">
+ </a>
+ </li>
+
+ <li>
+ <a href="http://feedvalidator.org/check?url=http://aperiodic.net/phil/archives/index.rss">
+ <img src="/phil/pics/validrss.png" alt="Valid RSS 1.0">
+ </a>
+ </li>
+
+</ul>
+
+</html>
diff --git a/spaghetti-monster/rampingios/rampingios-v3.md b/spaghetti-monster/rampingios/rampingios-v3.md
new file mode 100644
index 0000000..bc0e2b7
--- /dev/null
+++ b/spaghetti-monster/rampingios/rampingios-v3.md
@@ -0,0 +1,262 @@
+RampingIOS V3 Manual
+
+This Markdown-formatted manual was contributed by phil_g under a
+Creative Commons CC0 waiver:
+ http://aperiodic.net/phil/archives/Geekery/rampingios-v3.html
+ https://creativecommons.org/publicdomain/zero/1.0/
+
+
+<figure style="float: right">
+ <a href="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3ui.png-20180807025443-zdamv4ixtu49o7hm-1/rampingiosv3-ui.png">
+ <!-- img width="256em" src="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3.svg-20180807025420-q28902kbav01123w-1/rampingiosv3.svg" -->
+ <img width="256em" src="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3ui.png-20180807025443-zdamv4ixtu49o7hm-1/rampingiosv3-ui.png">
+ </a>
+ <figcaption>RampingIOS V3 UI diagram</figcaption>
+</figure>
+
+The Emisar [D4S][emisar-d4s] flashlights use a firmware named RampingIOS
+V3. (The Emisar [D4][emisar-d4], [D1][emisar-d1], and [D1S][emisar-d1s]
+all use [RampingIOS V2][rampingios-v2].) There's not really a manual; the
+only thing we get is the diagram on the right. It's reasonably
+comprehensive, but there's a fair amount of detail it merely summarizes,
+so I thought a textual manual would be nice.
+
+ [emisar-d4]: https://intl-outdoor.com/emisar-d4-high-power-led-flashlight-p-921.html
+ [emisar-d1]: https://intl-outdoor.com/emisar-d1-mini-thrower-p-922.html
+ [emisar-d1s]: https://intl-outdoor.com/emisar-d1s-thrower-p-926.html
+ [emisar-d4s]: https://intl-outdoor.com/emisar-d4s-26650-high-power-led-flashlight-p-932.html
+ [rampingios-v2]: http://aperiodic.net/phil/archives/Geekery/rampingios-v2.html
+
+The Emisar D4S only works when the head and tailcap are tightened fully.
+You can physically lock it out--prevent it from turning on
+accidentally--by simply loosening the tailcap a small amount. A quarter
+turn will do it.
+
+Emisar lights are known for their ramping interfaces. Rather than have a
+small number of distinct brightness levels, they can vary their brightness
+anywhere between their lowest and highest levels, like a light on a
+dimmer. The D4S is in ramping mode by default, but it also has a stepped
+mode that can be configured to be closer to how non-ramping lights work.
+
+Each mode--ramping and stepped--can have differently-configured brightness
+floors and ceilings.
+
+The driver for the D4S has two different chipsets. At low brightness
+levels, a fairly-efficient but low-power chipset (called a *7135*) is
+used. These lowest brightness levels are called the "*regulated levels*".
+Each regulated level will always be the same brightness regardless of how
+much charge the battery has. Above a particular brightness level, the
+light switches over to a less-efficient but high-power chipset (called a
+*FET*). These levels are called "*direct-drive*". The brightness of the
+direct-drive levels is directly related to the battery's charge level; the
+more charged the battery, the brighter the levels. The light is at its
+most efficient, in terms of power used for every lumen generated, at the
+brightest regulated level. When the light is first powered by tightening
+the tailcap, it will default to this level.
+
+At higher brightness levels, the light's LEDs generate a lot of heat. If
+the light exceeds its configured maximum temperature, it will begin
+dimming itself automatically until the temperature drops below the allowed
+maximum.
+
+The D4S has a set of cyan-colored auxiliary LEDs that can be on when the
+main LEDs are off. You can configure the behavior of the aux LEDs.
+
+#### Basic Usage
+
+The default mode for the light is ramping mode. Triple-pressing the
+button (**3 clicks**) while the light is on will toggle between ramping
+and stepped mode.
+
+While the light is off, press and release the button (**1 click**) to turn
+it on. It will turn on at the last-used brightness level. (This is
+called "*mode memory*".) Immediately after loosening and tightening the
+tailcap (or after changing the battery), the memorized level will be the
+light's max regulated level.
+
+When the light is on, 1 click will turn it off. The current brightness
+level will be memorized for future use. There's a fraction of a second
+delay between pressing the button and the light actually turning off.
+That's because of the way the light processes input; it's waiting to make
+sure you're only going to press the button once (since multiple presses
+will trigger other actions).
+
+When the light is on, holding the button down will brighten the light. In
+ramping mode, the brightness will increase gradually ("*ramping up*"). In
+stepped mode, the light will jump through increasing brightness levels.
+If you press, release, and then hold the button, it will begin dimming.
+In ramping mode, the brightness will decrease gradually ("*ramping
+down*"). In stepped mode, the light will jump through decreasing
+brightness levels. While the light is changing, if you release the button
+and immediately hold it again, the direction (dimming or brightening) will
+switch.
+
+In ramping mode, while the light is ramping, it'll briefly blink off and
+on again at two different brightness levels: the maximum regulated level
+and the brightness ceiling.
+
+While the light is off, double-pressing the button (**2 clicks**) will
+immediately jump to the brightness ceiling.
+
+While the light is on, **2 clicks** will jump to the maximum brightness
+level, regardless of the configured brightness ceiling. Another two
+clicks will go back to the previous brightness level.
+
+While the light is off, if you hold the button the light will turn on at
+its lowest level. If you continue holding the button, the light will
+begin brightening from there.
+
+##### Configuration Menus
+
+The light has several different configuration modes. Each of those modes
+works more or less the same way. The mode will have a series of menu
+items that it will go through. For each menu item, the light will first
+blink a number of times corresponding to the item number (first, second,
+etc.) After that, the light will begin fluttering on and off fairly
+quickly. While the light is fluttering, you can click the button a number
+of times; the light will count the number of button presses and use that
+number as its new configuration for that menu item. After a short period
+of time, the fluttering will stop and the light will move on to the next
+menu item. After the light has gone through all of the menu items, it
+will return to whatever mode it was in before entering the configuration
+mode.
+
+If you don't press the button during a particular menu item's fluttering,
+that item will remain unchanged.
+
+##### Configuring the Basic Modes
+
+While the light is on, **4 clicks** will enter ramping or stepped
+configuration mode, depending on which mode the light was in before the 4
+clicks.
+
+For ramping mode, there are two menu options:
+
+ 1. Brightness floor (default 1/150)
+ 2. Brightness ceiling (default 150/150)
+
+During the floor configuration, press the button equal to the number of
+ramping levels (out of 150) at which the floor should be. To set the
+lowest possible floor, click the button once.
+
+The ceiling is configured similarly, but you press the button equal to the
+number of steps away from maximum brightness. To set the highest possible
+ceiling (at max brightness), click the button once.
+
+For stepped mode, there are three menu options:
+
+ 1. Brightness floor (default 20/150)
+ 2. Brightness ceiling (default 120/150)
+ 3. Number of steps (default 7)
+
+#### Other Modes
+
+The other modes largely involve multiple clicks from off. Most of them
+are not generally needed for everyday use, but they supplement the light's
+basic operations.
+
+##### BattCheck/TempCheck Modes
+
+From off, **3 clicks** will enter "BattCheck" mode, which blinks out the
+current battery voltage. First it blinks the number of volts, then it
+pauses, then it blinks out the tenths of volts. Thus, if the battery were
+at 3.5 volts, the light would blink three times, pause, then five times.
+For zeroes, it gives a very short blink.
+
+A fully-charged lithium-ion battery is 4.2 volts. The light considers 2.8
+volts to be an empty battery and won't turn on if the battery is at or
+below 2.8 volts.
+
+The voltage sequence will continue blinking until you turn off the light
+with a single click.
+
+While the light is in BattCheck mode, **2 clicks** will enter TempCheck
+mode. Instead of blinking out the battery voltage, the light will start
+blinking out its current temperature in degrees Celsius, first the tens
+digit then the units digit. Like BattCheck mode, the light will continue
+blinking out the temperature until you turn it off with a single click.
+
+While the light is in TempCheck mode, **4 clicks** will enter thermal
+configuration mode. See the thermal configuration mode documentation
+below for how that works.
+
+##### Tactical Mode
+
+From off, **4 clicks** will enter "tactical" or "momentary" mode. The
+light will flash once to show that it's entered the mode. The auxiliary
+LEDs will turn off (if they were on). In tactical mode, the light will
+turn on at its memorized brightness for as long as the button is being
+held down. It will turn off as soon as the button is released.
+
+There's no button press combination that will exit tactical mode. To exit
+it, you will have to partially unscrew and retighten the tailcap.
+
+##### Lockout Mode
+
+From off, **6 clicks** will enter lockout mode. The light will flash
+twice to show that it's entered the mode. There's a separate aux LED mode
+for lockout mode, so you can tell whether the light is in lockout or not.
+
+In lockout mode, pressing the button will turn on the light at its lowest
+brightness ("*moonlight mode*") for as long as the button is held down.
+
+Another 6 clicks will exit lockout mode. The light will flash twice to
+show that it's left the mode.
+
+While in lockout mode, **3 clicks** will cycle through the various
+settings for the aux LEDs in lockout mode. The four modes are, in order:
+low, high, blink (on high), and off. The default mode is blink.
+
+Remember that loosening the tailcap a quarter turn will also lock out the
+light. Using the 6 clicks is called "*electronic lockout*", while turning
+the tailcap is "*physical lockout*".
+
+##### Aux LED Configuration
+
+From off, **7 clicks** will cycle to the next aux LED mode. The four
+modes are, in order: low, high, blink (on high), and off. The default
+mode is low.
+
+##### Beacon Mode
+
+From off, **8 clicks** will enter beacon mode. In beacon mode, the light
+will blink on and off every few seconds.
+
+By default, the light will blink every two seconds. To change the timing,
+use **4 clicks** while in beacon mode. The light will enter a one-item
+menu. During the flickering for input, press the button a number of times
+equal to the number of seconds between blinks.
+
+1 click will exit beacon mode.
+
+##### Thermal Configuration Mode
+
+From off, **10 clicks** will enter thermal configuration mode.
+
+The menu items here are:
+
+ 1. Current temperature (every click is one degree Celsius)
+ 2. Temperature ceiling (every click is one degree *above 30°C*)
+
+The "current temperature" item can be used to adjust the calibration of
+the light's temperature sensor. To use it, make sure the light has been
+off long enough that all of its components have cooled (or warmed) to the
+ambient temperature. Check the ambient temperature using a thermometer
+you trust. Go to thermal configuration mode, and enter the current
+temperature by clicking the button a number of times equal to the
+temperature in degrees Celsius. (If it's 22°C, click the button 22
+times.)
+
+You can check the default calibration by entering TempCheck mode from a
+room-temperature light. The D4Ss are supposed to go through a temperature
+calibration at the factory, so hopefully most of them won't need manual
+thermal calibration.
+
+The temperature ceiling is simply the highest temperature the light should
+be allowed to reach. Once it hits its temperature ceiling, it will
+progressively dim itself until the temperature stabilizes below the
+ceiling. Note that the number of clicks in that menu option is added to
+*30* to reach the actual ceiling. (Thus, you can't set a ceiling below
+31°C.) The maximum allowed ceiling is 70°C.
+
+The default temperature ceiling is 45°C.
diff --git a/spaghetti-monster/rampingios/rampingios-v3.txt b/spaghetti-monster/rampingios/rampingios-v3.txt
new file mode 100644
index 0000000..4598a76
--- /dev/null
+++ b/spaghetti-monster/rampingios/rampingios-v3.txt
@@ -0,0 +1,324 @@
+RampingIOS V3 Manual
+http://aperiodic.net/phil/archives/Geekery/rampingios-v3.html
+
+Tue, 28 Aug 2018
+9:47AM | Geekery | #
+
+
+RampingIOS V3 Manual
+--------------------
+
+[rampingiosv3-ui.png] RampingIOS V3 UI diagram
+
+The Emisar D4S flashlights use a firmware named RampingIOS V3. (The Emisar D4,
+D1, and D1S all use RampingIOS V2.) There's not really a manual; the only thing
+we get is the diagram on the right. It's reasonably comprehensive, but there's
+a fair amount of detail it merely summarizes, so I thought a textual manual
+would be nice.
+
+The Emisar D4S only works when the head and tailcap are tightened fully. You
+can physically lock it out--prevent it from turning on accidentally--by simply
+loosening the tailcap a small amount. A quarter turn will do it.
+
+Emisar lights are known for their ramping interfaces. Rather than have a small
+number of distinct brightness levels, they can vary their brightness anywhere
+between their lowest and highest levels, like a light on a dimmer. The D4S is
+in ramping mode by default, but it also has a stepped mode that can be
+configured to be closer to how non-ramping lights work.
+
+Each mode--ramping and stepped--can have differently-configured brightness
+floors and ceilings.
+
+The driver for the D4S has two different chipsets. At low brightness levels, a
+fairly-efficient but low-power chipset (called a 7135) is used. These lowest
+brightness levels are called the "regulated levels". Each regulated level will
+always be the same brightness regardless of how much charge the battery has.
+Above a particular brightness level, the light switches over to a
+less-efficient but high-power chipset (called a FET). These levels are called "
+direct-drive". The brightness of the direct-drive levels is directly related to
+the battery's charge level; the more charged the battery, the brighter the
+levels. The light is at its most efficient, in terms of power used for every
+lumen generated, at the brightest regulated level. When the light is first
+powered by tightening the tailcap, it will default to this level.
+
+At higher brightness levels, the light's LEDs generate a lot of heat. If the
+light exceeds its configured maximum temperature, it will begin dimming itself
+automatically until the temperature drops below the allowed maximum.
+
+The D4S has a set of cyan-colored auxiliary LEDs that can be on when the main
+LEDs are off. You can configure the behavior of the aux LEDs.
+
+
+Basic Usage
+-----------
+
+The default mode for the light is ramping mode. Triple-pressing the button (3
+clicks) while the light is on will toggle between ramping and stepped mode.
+
+While the light is off, press and release the button (1 click) to turn it on.
+It will turn on at the last-used brightness level. (This is called "mode memory
+".) Immediately after loosening and tightening the tailcap (or after changing
+the battery), the memorized level will be the light's max regulated level.
+
+When the light is on, 1 click will turn it off. The current brightness level
+will be memorized for future use. There's a fraction of a second delay between
+pressing the button and the light actually turning off. That's because of the
+way the light processes input; it's waiting to make sure you're only going to
+press the button once (since multiple presses will trigger other actions).
+
+When the light is on, holding the button down will brighten the light. In
+ramping mode, the brightness will increase gradually ("ramping up"). In stepped
+mode, the light will jump through increasing brightness levels. If you press,
+release, and then hold the button, it will begin dimming. In ramping mode, the
+brightness will decrease gradually ("ramping down"). In stepped mode, the light
+will jump through decreasing brightness levels. While the light is changing, if
+you release the button and immediately hold it again, the direction (dimming or
+brightening) will switch.
+
+In ramping mode, while the light is ramping, it'll briefly blink off and on
+again at two different brightness levels: the maximum regulated level and the
+brightness ceiling.
+
+While the light is off, double-pressing the button (2 clicks) will immediately
+jump to the brightness ceiling.
+
+While the light is on, 2 clicks will jump to the maximum brightness level,
+regardless of the configured brightness ceiling. Another two clicks will go
+back to the previous brightness level.
+
+While the light is off, if you hold the button the light will turn on at its
+lowest level. If you continue holding the button, the light will begin
+brightening from there.
+
+
+Configuration Menus
+-------------------
+
+The light has several different configuration modes. Each of those modes works
+more or less the same way. The mode will have a series of menu items that it
+will go through. For each menu item, the light will first blink a number of
+times corresponding to the item number (first, second, etc.) After that, the
+light will begin fluttering on and off fairly quickly. While the light is
+fluttering, you can click the button a number of times; the light will count
+the number of button presses and use that number as its new configuration for
+that menu item. After a short period of time, the fluttering will stop and the
+light will move on to the next menu item. After the light has gone through all
+of the menu items, it will return to whatever mode it was in before entering
+the configuration mode.
+
+If you don't press the button during a particular menu item's fluttering, that
+item will remain unchanged.
+
+
+Configuring the Basic Modes
+
+While the light is on, 4 clicks will enter ramping or stepped configuration
+mode, depending on which mode the light was in before the 4 clicks.
+
+For ramping mode, there are two menu options:
+
+ 1. Brightness floor (default 1/150)
+ 2. Brightness ceiling (default 150/150)
+
+During the floor configuration, press the button equal to the number of ramping
+levels (out of 150) at which the floor should be. To set the lowest possible
+floor, click the button once.
+
+The ceiling is configured similarly, but you press the button equal to the
+number of steps away from maximum brightness. To set the highest possible
+ceiling (at max brightness), click the button once.
+
+For stepped mode, there are three menu options:
+
+ 1. Brightness floor (default 20/150)
+ 2. Brightness ceiling (default 120/150)
+ 3. Number of steps (default 7)
+
+
+Other Modes
+-----------
+
+The other modes largely involve multiple clicks from off. Most of them are not
+generally needed for everyday use, but they supplement the light's basic
+operations.
+
+
+BattCheck/TempCheck Modes
+
+From off, 3 clicks will enter "BattCheck" mode, which blinks out the current
+battery voltage. First it blinks the number of volts, then it pauses, then it
+blinks out the tenths of volts. Thus, if the battery were at 3.5 volts, the
+light would blink three times, pause, then five times. For zeroes, it gives a
+very short blink.
+
+A fully-charged lithium-ion battery is 4.2 volts. The light considers 2.8 volts
+to be an empty battery and won't turn on if the battery is at or below 2.8
+volts.
+
+The voltage sequence will continue blinking until you turn off the light with a
+single click.
+
+While the light is in BattCheck mode, 2 clicks will enter TempCheck mode.
+Instead of blinking out the battery voltage, the light will start blinking out
+its current temperature in degrees Celsius, first the tens digit then the units
+digit. Like BattCheck mode, the light will continue blinking out the
+temperature until you turn it off with a single click.
+
+While the light is in TempCheck mode, 4 clicks will enter thermal configuration
+mode. See the thermal configuration mode documentation below for how that
+works.
+
+
+Tactical Mode
+
+From off, 4 clicks will enter "tactical" or "momentary" mode. The light will
+flash once to show that it's entered the mode. The auxiliary LEDs will turn off
+(if they were on). In tactical mode, the light will turn on at its memorized
+brightness for as long as the button is being held down. It will turn off as
+soon as the button is released.
+
+There's no button press combination that will exit tactical mode. To exit it,
+you will have to partially unscrew and retighten the tailcap.
+
+
+Lockout Mode
+
+From off, 6 clicks will enter lockout mode. The light will flash twice to show
+that it's entered the mode. There's a separate aux LED mode for lockout mode,
+so you can tell whether the light is in lockout or not.
+
+In lockout mode, pressing the button will turn on the light at its lowest
+brightness ("moonlight mode") for as long as the button is held down.
+
+Another 6 clicks will exit lockout mode. The light will flash twice to show
+that it's left the mode.
+
+While in lockout mode, 3 clicks will cycle through the various settings for the
+aux LEDs in lockout mode. The four modes are, in order: low, high, blink (on
+high), and off. The default mode is blink.
+
+Remember that loosening the tailcap a quarter turn will also lock out the
+light. Using the 6 clicks is called "electronic lockout", while turning the
+tailcap is "physical lockout".
+
+
+Aux LED Configuration
+
+From off, 7 clicks will cycle to the next aux LED mode. The four modes are, in
+order: low, high, blink (on high), and off. The default mode is low.
+
+
+Beacon Mode
+
+From off, 8 clicks will enter beacon mode. In beacon mode, the light will blink
+on and off every few seconds.
+
+By default, the light will blink every two seconds. To change the timing, use 4
+clicks while in beacon mode. The light will enter a one-item menu. During the
+flickering for input, press the button a number of times equal to the number of
+seconds between blinks.
+
+1 click will exit beacon mode.
+
+
+Thermal Configuration Mode
+
+From off, 10 clicks will enter thermal configuration mode.
+
+The menu items here are:
+
+ 1. Current temperature (every click is one degree Celsius)
+ 2. Temperature ceiling (every click is one degree above 30?C)
+
+The "current temperature" item can be used to adjust the calibration of the
+light's temperature sensor. To use it, make sure the light has been off long
+enough that all of its components have cooled (or warmed) to the ambient
+temperature. Check the ambient temperature using a thermometer you trust. Go to
+thermal configuration mode, and enter the current temperature by clicking the
+button a number of times equal to the temperature in degrees Celsius. (If it's
+22?C, click the button 22 times.)
+
+You can check the default calibration by entering TempCheck mode from a
+room-temperature light. The D4Ss are supposed to go through a temperature
+calibration at the factory, so hopefully most of them won't need manual thermal
+calibration.
+
+The temperature ceiling is simply the highest temperature the light should be
+allowed to reach. Once it hits its temperature ceiling, it will progressively
+dim itself until the temperature stabilizes below the ceiling. Note that the
+number of clicks in that menu option is added to 30 to reach the actual
+ceiling. (Thus, you can't set a ceiling below 31?C.) The maximum allowed
+ceiling is 70?C.
+
+The default temperature ceiling is 45?C.
+
+
+Static
+
+ * zsh prompt
+ * PGP
+ * SSH
+ * MTA
+ * tutorials
+ * config files
+ * desktop
+ * books I own
+ * stuff I'm giving away
+ * Dr. Who eps I have
+ * bookmarks
+ * photos
+ * about
+
+Directory
+
+ * Root (143)
+ + Books (32)
+ + Events (7)
+ o Burning Man (3)
+ o Camping (2)
+ o PDF (2)
+ + Geekery (36)
+ o Test (3)
+ + General (24)
+ + Links (12)
+ o Slashdot (1)
+ + MTA (22)
+ + Recipes (4)
+ + Video Games (6)
+ o FFXI (1)
+
+Archive
+
+ ?August?
+Sun Mon Tue Wed Thu Fri Sat
+ 1 2 3 4
+5 6 7 8 9 10 11
+12 13 14 15 16 17 18
+19 20 21 22 23 24 25
+26 27 28 29 30 31
+
+ ?2018?
+ Months
+Jan Feb Mar Apr May Jun
+Jul Aug Sep Oct Nov Dec
+
+Search
+
+[ ]
+Powered by Google
+
+Currently Reading
+
+Recent Books
+
+-------------------------------------------------------------------------------
+
+Copyright (C) 2018 Phil Gold
+
+Back to main page.
+
+ * Valid HTML 4.01
+ * Valid CSS 2
+ * RSS syndication
+ * Valid RSS 1.0
+
diff --git a/spaghetti-monster/rampingios/rampingiosv3.c b/spaghetti-monster/rampingios/rampingiosv3.c
index 8dbd08f..5c8f7ea 100644
--- a/spaghetti-monster/rampingios/rampingiosv3.c
+++ b/spaghetti-monster/rampingios/rampingiosv3.c
@@ -19,13 +19,17 @@
/********* User-configurable options *********/
// Physical driver type (uncomment one of the following or define it at the gcc command line)
+//#define FSM_BLF_GT_DRIVER
+//#define FSM_BLF_GT_MINI_DRIVER
+//#define FSM_BLF_Q8_DRIVER
+//#define FSM_EMISAR_D1_DRIVER
+//#define FSM_EMISAR_D1S_DRIVER
//#define FSM_EMISAR_D4_DRIVER
+//#define FSM_EMISAR_D4_219C_DRIVER
//#define FSM_EMISAR_D4S_DRIVER
-//#define FSM_EMISAR_D4S_219c_DRIVER
-//#define FSM_BLF_Q8_DRIVER
+//#define FSM_EMISAR_D4S_219C_DRIVER
+//#define FSM_FF_ROT66_DRIVER
//#define FSM_FW3A_DRIVER
-//#define FSM_BLF_GT_DRIVER
-//#define FSM_BLF_GT_MINI_DRIVER
#define USE_LVP // FIXME: won't build when this option is turned off
@@ -33,6 +37,10 @@
#define USE_THERMAL_REGULATION
#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this
+// short blip when crossing from "click" to "hold" from off
+// (helps the user hit moon mode exactly, instead of holding too long
+// or too short)
+#define MOON_TIMING_HINT
// short blips while ramping
#define BLINK_AT_CHANNEL_BOUNDARIES
//#define BLINK_AT_RAMP_FLOOR
@@ -64,15 +72,21 @@
#elif defined(FSM_EMISAR_D1S_DRIVER)
#include "cfg-emisar-d1s.h"
+#elif defined(FSM_EMISAR_D4_219C_DRIVER)
+#include "cfg-emisar-d4-219c.h"
+
#elif defined(FSM_EMISAR_D4_DRIVER)
#include "cfg-emisar-d4.h"
-#elif defined(FSM_EMISAR_D4S_219c_DRIVER)
+#elif defined(FSM_EMISAR_D4S_219C_DRIVER)
#include "cfg-emisar-d4s-219c.h"
#elif defined(FSM_EMISAR_D4S_DRIVER)
#include "cfg-emisar-d4s.h"
+#elif defined(FSM_FF_ROT66_DRIVER)
+#include "cfg-ff-rot66.h"
+
#elif defined(FSM_FW3A_DRIVER)
#include "cfg-fw3a.h"
@@ -203,15 +217,19 @@ volatile uint8_t ramp_discrete_steps = RAMP_DISCRETE_STEPS;
uint8_t ramp_discrete_step_size; // don't set this
#ifdef USE_INDICATOR_LED
-// bits 2-3 control lockout mode
-// bits 0-1 control "off" mode
-// modes are: 0=off, 1=low, 2=high, 3=blinking (if TICK_DURING_STANDBY enabled)
-#ifdef USE_INDICATOR_LED_WHILE_RAMPING
-//uint8_t indicator_led_mode = (1<<2) + 2;
-uint8_t indicator_led_mode = (2<<2) + 1;
-#else
-uint8_t indicator_led_mode = (3<<2) + 1;
-#endif
+ // bits 2-3 control lockout mode
+ // bits 0-1 control "off" mode
+ // modes are: 0=off, 1=low, 2=high, 3=blinking (if TICK_DURING_STANDBY enabled)
+ #ifdef INDICATOR_LED_DEFAULT_MODE
+ uint8_t indicator_led_mode = INDICATOR_LED_DEFAULT_MODE;
+ #else
+ #ifdef USE_INDICATOR_LED_WHILE_RAMPING
+ //uint8_t indicator_led_mode = (1<<2) + 2;
+ uint8_t indicator_led_mode = (2<<2) + 1;
+ #else
+ uint8_t indicator_led_mode = (3<<2) + 1;
+ #endif
+ #endif
#endif
// calculate the nearest ramp level which would be valid at the moment
@@ -265,9 +283,19 @@ uint8_t off_state(EventPtr event, uint16_t arg) {
}
// hold: go to lowest level
else if (event == EV_click1_hold) {
+ #ifdef MOON_TIMING_HINT
+ if (arg == 0) {
+ // let the user know they can let go now to stay at moon
+ uint8_t temp = actual_level;
+ set_level(0);
+ delay_4ms(2);
+ set_level(temp);
+ } else
+ #endif
// don't start ramping immediately;
// give the user time to release at moon level
- if (arg >= HOLD_TIMEOUT) {
+ //if (arg >= HOLD_TIMEOUT) { // smaller
+ if (arg >= (!ramp_style) * HOLD_TIMEOUT) { // more consistent
set_state(steady_state, 1);
}
return MISCHIEF_MANAGED;
@@ -400,7 +428,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
// 3 clicks: toggle smooth vs discrete ramping
else if (event == EV_3clicks) {
ramp_style = !ramp_style;
- memorized_level = nearest_level(memorized_level);
+ memorized_level = nearest_level(actual_level);
#ifdef USE_THERMAL_REGULATION
target_level = memorized_level;
#ifdef USE_SET_LEVEL_GRADUALLY
@@ -605,6 +633,7 @@ uint8_t steady_state(EventPtr event, uint16_t arg) {
#else
set_level(THERM_FASTER_LEVEL);
#endif
+ target_level = THERM_FASTER_LEVEL;
} else
#endif
if (actual_level > MIN_THERM_STEPDOWN) {