Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80e42f1952 | ||
|
|
28f49e8463 | ||
|
|
b77e1d5a51 |
No files matched your search
@@ -14,7 +14,16 @@ FireFly Solar is a small outdoor LED blinker inspired by the idea of an LED thro
|
|||||||
During the day, the solar cell charges the energy storage.
|
During the day, the solar cell charges the energy storage.
|
||||||
At night, the circuit wakes up and sends a simple Morse-style light signal.
|
At night, the circuit wakes up and sends a simple Morse-style light signal.
|
||||||
|
|
||||||
The project is partly a small garden object, partly a low-power electronics experiment, and partly a design exercise for future DIY kits.
|
## About this Project
|
||||||
|
|
||||||
|
FireFly Solar is my **technology playground**. It is a small garden object, but its real purpose is to learn by building something complete. With it I learn about:
|
||||||
|
|
||||||
|
- **Circuit design at the edge**: in this case, as low power as possible
|
||||||
|
- **PCB design**
|
||||||
|
- **Weatherproof casing**
|
||||||
|
- **ATtiny programming**
|
||||||
|
|
||||||
|
Possible next technology step: everything about DIY SMD design and soldering.
|
||||||
|
|
||||||
## Project Goals
|
## Project Goals
|
||||||
|
|
||||||
@@ -24,6 +33,40 @@ The project is partly a small garden object, partly a low-power electronics expe
|
|||||||
- Test mechanical concepts for outdoor 3D-printed parts
|
- Test mechanical concepts for outdoor 3D-printed parts
|
||||||
- Learn what is needed to turn a small electronics project into a possible DIY kit
|
- Learn what is needed to turn a small electronics project into a possible DIY kit
|
||||||
|
|
||||||
|
## Software
|
||||||
|
|
||||||
|
The firmware runs on an **ATtiny85** at 1 MHz (internal clock, ATTinyCore: `clock=1internal`, `millis=disabled`). The LED itself is used as the light sensor. When it is dark, the firefly sends a short Morse text ("TGO 26") about once a minute.
|
||||||
|
|
||||||
|
### Current Firmware version: v0.4 (2026-11-08)
|
||||||
|
|
||||||
|
Goal: lowest possible average current.
|
||||||
|
|
||||||
|
Changes vs v0.3:
|
||||||
|
|
||||||
|
- No `delay()` / `millis()`; Timer0 and Timer1 are gated off in PRR.
|
||||||
|
- The watchdog (interrupt mode) is the only timebase: Morse units (~96 ms), the sensing window and the 8 s sleeps. The CPU sleeps in power-down in between.
|
||||||
|
- Darkness sensing: the CPU sleeps in 16 ms steps while the LED junction discharges, instead of a busy `digitalRead()` loop. Bright light exits after the first step. `darknessThreshold` is replaced by `darkSteps`.
|
||||||
|
- The ADC is disabled before it is gated off in PRR; pins are set up before PRR.
|
||||||
|
- After a power-on or external reset, no blinking for `RECOVER_CYCLES` (about 16 min), so the supercap can recharge.
|
||||||
|
- `DEBUG_TEST` switch for bench testing: 8 s cycle, no recovery wait, short flash when the sketch decides "bright". Set it to 0 for the field.
|
||||||
|
- Optional `BOD_FUSE_ENABLED` (BOD off during sleep); unused with the BOD fuse off.
|
||||||
|
|
||||||
|
Tested: compiles with ATTinyCore and runs on hardware. Current draw is not yet measured.
|
||||||
|
|
||||||
|
## PCB
|
||||||
|
|
||||||
|
- Finished: a batch of 10 is assembled, tested and working.
|
||||||
|
- Latest adjustment: fine-tuned the resistors for the LED, and the 3.9 V Zener diode is confirmed safe avoid overcharging 4V supercap.
|
||||||
|
- Next version: the PCB should be a little shorter. The wiring space is a bit too tight now.
|
||||||
|
|
||||||
|
## Casing
|
||||||
|
|
||||||
|
Works basically as intended. Lessons for the next version:
|
||||||
|
|
||||||
|
- Better locking of the solar modules.
|
||||||
|
- The rope structure works, but building it is too complicated and takes a lot of nerves.
|
||||||
|
- Using material tension to secure the modules via rope was basically a good idea.
|
||||||
|
|
||||||
## Naming
|
## Naming
|
||||||
|
|
||||||
The English project name remains:
|
The English project name remains:
|
||||||
@@ -39,9 +82,12 @@ The name roughly means **sun-disc firefly**. It keeps the solar theme, adds a sl
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
PRs and issues welcome. Keep it simple.
|
|
||||||
|
PRs and issues welcome. Keep it simple.
|
||||||
Photos of your build you send me go in `Documentation/gallery/` with a short caption and license notice.
|
Photos of your build you send me go in `Documentation/gallery/` with a short caption and license notice.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Default license**: [CC-BY-NC-4.0](https://creativecommons.org/licenses/by-nc/4.0/)
|
## License
|
||||||
|
|
||||||
|
Default license: [CC-BY-NC-4.0](https://creativecommons.org/licenses/by-nc/4.0/)
|
||||||
@@ -1,24 +1,46 @@
|
|||||||
/*
|
/*
|
||||||
=============================================================================
|
=============================================================================
|
||||||
FireFly Morse Throwie
|
FireFly Solar / 日輪蛍 – Nichirin Hotaru / a Solar Morse Throwie
|
||||||
- a light controlled (LED as Sensor) morse blinker throwie with ATTiny85
|
|
||||||
|
太陽を宿し、夜にモールスを灯す蛍。
|
||||||
|
Taiyō o yadoshi, yoru ni Mōrusu o tomosu hotaru.
|
||||||
|
A firefly carrying the sun, lighting Morse in the night.
|
||||||
=============================================================================
|
=============================================================================
|
||||||
|
|
||||||
Project definitions, sources
|
Project definitions, sources
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
Version: 0.3 - ATTiny85, 1 MHz, BOD fuse disabled
|
Version : 0.5 - ATTiny85, 1 MHz, BOD fuse disabled
|
||||||
gitea : https://gitea.togo-lab.io/tgohle/0001-FireFly
|
used Flash: 1284 bytes
|
||||||
Date : 2026-06-14
|
|
||||||
|
gitea : https://gitea.togo-lab.io/tgohle/0001-FireFly
|
||||||
|
Date : 2026-11-10
|
||||||
|
|
||||||
|
|
||||||
|
Key changes Version 0.5 (goal: lowest possible average current):
|
||||||
|
|
||||||
Key changes Version 0.3:
|
- No delay(), no millis(): Timer0 and Timer1 are not needed any more and
|
||||||
|
are switched off in PRR.
|
||||||
|
- ALL timing (Morse units, sensing window, 8 s sleep) is done by the watchdog
|
||||||
|
in interrupt mode while the CPU is in POWER-DOWN. The CPU runs only for a
|
||||||
|
few microseconds per wake-up. LED pins keep their state in power-down.
|
||||||
|
- Darkness sensing by LED no longer polls digitalRead() in a busy loop (that was
|
||||||
|
~0.3-1 s awake per cycle). The LED junction is charged, then the CPU sleeps
|
||||||
|
in 16 ms steps and checks the pin: bright light exits after the first step.
|
||||||
|
- ADC is disabled BEFORE it is gated off in PRR (order matters).
|
||||||
|
- After a power-on, external, brown-out or watchdog reset the sketch waits
|
||||||
|
RECOVER_CYCLES cycles before blinking, allowing the supercap to recharge.
|
||||||
|
Default ~13 min 20 s (nominal); the debug option bypasses recovery.
|
||||||
|
- Startup code saves MCUSR and disables the watchdog early (.init3), avoiding
|
||||||
|
a watchdog-reset loop before setup() can execute.
|
||||||
|
- Optional: BOD disable during sleep (only useful if BOD fuse is enabled).
|
||||||
|
But found out that also BOD Fuse for 1.8V shorten unnecessary blinking time,
|
||||||
|
will still work ~1V, meaning ~20 min longer blinking time.
|
||||||
|
- Field Test: After a sunny day in Winter, outdoor -1 ... 8°C, with a payload
|
||||||
|
of 10 signs) it blinks for >> 12h.
|
||||||
|
|
||||||
- Removed unnecessary ADC enable/disable from loop()
|
Timing note: the watchdog oscillator is not precise (changes with Vcc and
|
||||||
- Disabled ADC and analog comparator in setup()
|
temperature). All Morse timing comes from the same clock, so dit/dah/gap
|
||||||
- Added INPUT_PULLUP for unused Arduino pins 0, 1, 2 will save power
|
ratios stay correct; only the absolute speed drifts a little.
|
||||||
- Added safer watchdog setup with interrupt protection to save run near brownout
|
The HW actual allowes 5V and 3.3V, standard is 3.3V. So don't expec exact timing.
|
||||||
- Added wdt_reset() before sleep for cleaner 8 s timing
|
|
||||||
- Added lowercase-to-uppercase handling
|
|
||||||
- Unsupported characters are now ignored without adding fake timing gaps
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -44,7 +66,9 @@ Inspired by Karl Lunt's FireFly project:
|
|||||||
'.', ".-.-.-" ',', "--..--" '?', "..--.."
|
'.', ".-.-.-" ',', "--..--" '?', "..--.."
|
||||||
'!', "-.-.--" ':', "---..." ';', "-.-.-."
|
'!', "-.-.--" ':', "---..." ';', "-.-.-."
|
||||||
'(', "-.--." ')', "-.--.-" '"', ".-..-."
|
'(', "-.--." ')', "-.--.-" '"', ".-..-."
|
||||||
'@', ".--.-." '&', ".-..."
|
'@', ".--.-." '&', ".-..." '-', "-....-"
|
||||||
|
'/', "-..-." ''', ".----." '+', ".-.-."
|
||||||
|
'=', "-...-" '_', "..--.-"
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -60,6 +84,12 @@ Inspired by Karl Lunt's FireFly project:
|
|||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// DEBUG_TEST 1 = bench testing: no reset-recovery wait, a blink attempt every
|
||||||
|
// 8 s, and a short flash when the sketch thinks it is BRIGHT.
|
||||||
|
// SET TO 0 FOR THE FIELD (40 s idle sleep, ~13m20s reset recovery).
|
||||||
|
#define DEBUG_TEST 0
|
||||||
|
|
||||||
#ifndef cbi
|
#ifndef cbi
|
||||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||||
#endif
|
#endif
|
||||||
@@ -68,16 +98,55 @@ Inspired by Karl Lunt's FireFly project:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Timing: unit length in ms.
|
// Watchdog timeout codes (nominal, at ~5 V; real values vary with Vcc/temp):
|
||||||
// At 1 MHz, delay() is accurate when F_CPU=1000000L is set in boards.txt.
|
// actual HW uses 3.3 (standard) or 5V (for blue LED experimental setup)
|
||||||
// 100 ms gives readable optical Morse; raise to 150 ms if readability is poor.
|
// so don't expect exact timing)
|
||||||
#define unitLength 100
|
// 0=16ms 1=32ms 2=64ms 3=128ms 4=250ms 5=500ms
|
||||||
|
// 6=1s 7=2s 8=4s 9=8s
|
||||||
|
//
|
||||||
|
// One Morse unit = UNIT_WDT_A + UNIT_WDT_B -> 64 ms + 32 ms = ~96 ms
|
||||||
|
// A=3, B=0 -> ~144 ms (easier to read, more LED time)
|
||||||
|
// A=3, B=0xFF -> ~128 ms
|
||||||
|
// A=2, B=0xFF -> ~64 ms (fast, less LED time, harder to read by eye)
|
||||||
|
// Use 0xFF for B to skip the second sleep.
|
||||||
|
#define UNIT_WDT_A 2
|
||||||
|
#define UNIT_WDT_B 1
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Sleep interval.
|
// Sleep interval between two sensing/blink attempts: sleepCycles x 8 s.
|
||||||
// Watchdog setup uses 8 s. For final use, change sleepCycles from 4 to 6
|
// 5 x 8 s = 40 s. Goal ~ 1 blink/min.
|
||||||
// for about 32s - 48s between sensing/blinking activations. Goal ~ 1 blink/min
|
#if DEBUG_TEST
|
||||||
const uint8_t sleepCycles = 6;
|
const uint8_t sleepCycles = 1;
|
||||||
|
#else
|
||||||
|
const uint8_t sleepCycles = 5;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Darkness window in 16 ms steps (nominal).
|
||||||
|
// After charging the LED junction the CPU sleeps step by step. If the pin
|
||||||
|
// reads LOW within the window the LED discharged quickly = bright = no blink.
|
||||||
|
// Still HIGH after the full window = dark = blink.
|
||||||
|
// Longer window = triggers in darker conditions
|
||||||
|
// The window costs almost no energy (CPU sleeps), so it is only a threshold.
|
||||||
|
// Calibrate at real dusk. Old threshold 17000 loops: measure the old
|
||||||
|
// sensDarkness() time with micros() at your dusk level and divide it by 16 ms.
|
||||||
|
const uint8_t darkSteps = 40; // ~640 ms
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// After a power-on / brown-out / external / watchdog reset, do not blink for
|
||||||
|
// this many cycles (each has 40 s of sleep) so the supercap can recharge.
|
||||||
|
// 20 -> ~13 min 20 s nominal. Set to 0 for bench testing/uploading.
|
||||||
|
#if DEBUG_TEST
|
||||||
|
#define RECOVER_CYCLES 0
|
||||||
|
#else
|
||||||
|
#define RECOVER_CYCLES 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Set to 1 only if the BOD fuse is enabled (e.g. hfuse 0xDE = 1.8 V).
|
||||||
|
// Then BOD is switched off during power-down to save its ~20 uA.
|
||||||
|
// With BOD fuse disabled this has no effect, leave it 0.
|
||||||
|
#define BOD_FUSE_ENABLED 0
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// LED pin definitions (N-side = cathode, P-side = anode for sensing/driving).
|
// LED pin definitions (N-side = cathode, P-side = anode for sensing/driving).
|
||||||
@@ -95,28 +164,38 @@ const uint8_t sleepCycles = 6;
|
|||||||
// ATTiny85 has 512 bytes SRAM; this keeps the Morse text in flash.
|
// ATTiny85 has 512 bytes SRAM; this keeps the Morse text in flash.
|
||||||
// Only uppercase letters, digits, spaces, and the special chars in the switch
|
// Only uppercase letters, digits, spaces, and the special chars in the switch
|
||||||
// below are emitted. Lowercase letters are converted to uppercase.
|
// below are emitted. Lowercase letters are converted to uppercase.
|
||||||
// Test setup: 20 x "0" because 0 = "-----" gives maximum LED ON time for test.
|
// Shorter text = less LED time = less energy.
|
||||||
// shorter text will better, more text will cost more power.
|
const char morseText[] PROGMEM = "TOGO-LAB.IO FIREFLY";
|
||||||
const char morseText[] PROGMEM = "TGO 26";
|
// Ruler: 0....0....1....1....2
|
||||||
// Ruler: 0....0....1...1....2
|
// Ruler: 01...5....0....5....0
|
||||||
// Ruler: 0....5....0...5....0
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Darkness threshold.
|
|
||||||
// Higher value = triggers in brighter conditions.
|
|
||||||
// Best calibrated at actual dusk/dawn with the chosen LED type.
|
|
||||||
const unsigned int darknessThreshold = 17000;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Watchdog interrupt flag — volatile because it is written in an ISR.
|
// Watchdog interrupt flag - volatile because it is written in an ISR.
|
||||||
volatile bool f_wdt = true;
|
volatile bool f_wdt = false;
|
||||||
|
|
||||||
|
// Remaining cycles without blinking after a reset.
|
||||||
|
static uint8_t recoverCycles = 0;
|
||||||
|
|
||||||
|
// Preserve the reset flags before Arduino startup and stop a watchdog left
|
||||||
|
// running by a previous reset. AVR-libc's recommended .init3 pattern.
|
||||||
|
// .noinit is not cleared by C runtime initialization.
|
||||||
|
static uint8_t resetCauseEarly __attribute__((section(".noinit")));
|
||||||
|
|
||||||
|
void earlyWatchdogInit(void) __attribute__((used, naked, section(".init3")));
|
||||||
|
void earlyWatchdogInit(void)
|
||||||
|
{
|
||||||
|
resetCauseEarly = MCUSR;
|
||||||
|
MCUSR = 0; // Clear WDRF before disabling WDT.
|
||||||
|
wdt_disable(); // Prevent repeated ~15 ms watchdog resets.
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
void setup_watchdog(uint8_t ii);
|
static void sleepWdt(uint8_t ii);
|
||||||
void system_sleep();
|
static void waitUnits(uint8_t n);
|
||||||
void configureUnusedPins();
|
void configureUnusedPins();
|
||||||
void releaseLedPins(int LED_N, int LED_P);
|
void releaseLedPins(int LED_N, int LED_P);
|
||||||
unsigned int sensDarkness(int LED_N, int LED_P);
|
bool isDark(int LED_N, int LED_P);
|
||||||
void morse(int LED_N, int LED_P);
|
void morse(int LED_N, int LED_P);
|
||||||
void dit(int LED_P);
|
void dit(int LED_P);
|
||||||
void dah(int LED_P);
|
void dah(int LED_P);
|
||||||
@@ -126,22 +205,28 @@ void dah(int LED_P);
|
|||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// Disable unused peripherals immediately to save power.
|
// Reset cause was captured before C/Arduino initialization in .init3.
|
||||||
// PRTIM1, PRUSI: unused, safe to gate off.
|
// Include WDRF: a watchdog reset also needs supercap recovery time.
|
||||||
// PRADC: ADC is not used; LED sensing is done with digitalRead().
|
if (resetCauseEarly & ((1 << PORF) | (1 << BORF) |
|
||||||
// PRTIM0: must stay ON while awake because delay() depends on Timer0.
|
(1 << EXTRF) | (1 << WDRF))) {
|
||||||
PRR = (1 << PRTIM1) | (1 << PRUSI) | (1 << PRADC);
|
recoverCycles = RECOVER_CYCLES;
|
||||||
|
}
|
||||||
// ADC off. It is not needed for digitalRead()-based LED sensing.
|
|
||||||
cbi(ADCSRA, ADEN);
|
|
||||||
|
|
||||||
// Analog comparator off. Saves a little sleep current.
|
|
||||||
ACSR |= (1 << ACD);
|
|
||||||
|
|
||||||
|
// Pins first (while the Arduino core can still reach all timer registers
|
||||||
|
// for its turnOffPWM() handling in digitalWrite()).
|
||||||
configureUnusedPins();
|
configureUnusedPins();
|
||||||
releaseLedPins(LED1_N_SIDE, LED1_P_SIDE);
|
releaseLedPins(LED1_N_SIDE, LED1_P_SIDE);
|
||||||
|
|
||||||
setup_watchdog(9); // 8-second watchdog interval.
|
// ADC off FIRST, then gate its clock. With PRADC set, ADC register
|
||||||
|
// writes are ignored, so the order matters.
|
||||||
|
cbi(ADCSRA, ADEN);
|
||||||
|
|
||||||
|
// Analog comparator off.
|
||||||
|
ACSR |= (1 << ACD);
|
||||||
|
|
||||||
|
// Power reduction: ADC, USI, Timer0, Timer1 all off.
|
||||||
|
// Nothing in this sketch uses them: no delay(), no millis(), no analogWrite().
|
||||||
|
PRR = (1 << PRADC) | (1 << PRUSI) | (1 << PRTIM0) | (1 << PRTIM1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -149,22 +234,29 @@ void setup()
|
|||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
if (f_wdt) {
|
if (recoverCycles > 0) {
|
||||||
f_wdt = false;
|
recoverCycles--;
|
||||||
|
} else if (isDark(LED1_N_SIDE, LED1_P_SIDE)) {
|
||||||
if (sensDarkness(LED1_N_SIDE, LED1_P_SIDE) > darknessThreshold) {
|
morse(LED1_N_SIDE, LED1_P_SIDE);
|
||||||
morse(LED1_N_SIDE, LED1_P_SIDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return LED pins to high-Z before sleeping.
|
|
||||||
// Internal pullups stay disabled for the LED pins.
|
|
||||||
releaseLedPins(LED1_N_SIDE, LED1_P_SIDE);
|
|
||||||
}
|
}
|
||||||
|
#if DEBUG_TEST
|
||||||
|
else {
|
||||||
|
// Sketch decided "bright": one short ~128 ms flash so you can see it.
|
||||||
|
pinMode(LED1_N_SIDE, OUTPUT);
|
||||||
|
pinMode(LED1_P_SIDE, OUTPUT);
|
||||||
|
digitalWrite(LED1_N_SIDE, LOW);
|
||||||
|
digitalWrite(LED1_P_SIDE, HIGH);
|
||||||
|
sleepWdt(3);
|
||||||
|
digitalWrite(LED1_P_SIDE, LOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Return LED pins to high-Z before sleeping.
|
||||||
|
// Internal pullups stay disabled for the LED pins.
|
||||||
|
releaseLedPins(LED1_N_SIDE, LED1_P_SIDE);
|
||||||
|
|
||||||
// Test setup: 1 x 8 s sleep.
|
|
||||||
// Final setup: set sleepCycles = 4 for about 32 s.
|
|
||||||
for (uint8_t i = 0; i < sleepCycles; i++) {
|
for (uint8_t i = 0; i < sleepCycles; i++) {
|
||||||
system_sleep();
|
sleepWdt(9); // 8 s each
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,87 +280,110 @@ void releaseLedPins(int LED_N, int LED_P)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
// Sleep helpers
|
// Sleep helpers (watchdog = only timebase)
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
void system_sleep()
|
ISR(WDT_vect)
|
||||||
{
|
{
|
||||||
// Reset watchdog counter so each sleep cycle starts with a fresh interval.
|
f_wdt = true;
|
||||||
wdt_reset();
|
|
||||||
|
|
||||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
|
||||||
|
|
||||||
// Atomic sleep entry pattern.
|
|
||||||
// After sei(), AVR executes the next instruction before servicing interrupts,
|
|
||||||
// so sleep_cpu() is not skipped by a just-pending interrupt.
|
|
||||||
cli();
|
|
||||||
sleep_enable();
|
|
||||||
sei();
|
|
||||||
sleep_cpu();
|
|
||||||
|
|
||||||
// WDT interrupt wakes the CPU here.
|
|
||||||
sleep_disable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watchdog setup - ii selects timeout:
|
// Sleep in POWER-DOWN until the watchdog interrupt fires after timeout code ii
|
||||||
// 0=16ms 1=32ms 2=64ms 3=128ms 4=250ms 5=500ms
|
// (0=16 ms ... 9=8 s). Reconfigures the watchdog on every call, so the full
|
||||||
// 6=1s 7=2s 8=4s 9=8s
|
// interval always starts fresh.
|
||||||
void setup_watchdog(uint8_t ii)
|
static void sleepWdt(uint8_t ii)
|
||||||
{
|
{
|
||||||
if (ii > 9) ii = 9;
|
if (ii > 9) ii = 9;
|
||||||
|
|
||||||
uint8_t bb = ii & 7;
|
uint8_t bb = ii & 7;
|
||||||
if (ii > 7) bb |= (1 << WDP3);
|
if (ii > 7) bb |= (1 << WDP3);
|
||||||
|
|
||||||
uint8_t oldSREG = SREG;
|
// Interrupt-only mode (WDE = 0). WDIF written as 1 clears a stale flag.
|
||||||
|
const uint8_t cfg = bb | (1 << WDIE) | (1 << WDIF);
|
||||||
|
|
||||||
|
f_wdt = false;
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
MCUSR &= ~(1 << WDRF);
|
|
||||||
|
|
||||||
// Timed sequence: enable configuration change, then set interrupt-only WDT.
|
// WDCE/WDE unlock and configuration: two consecutive OUT instructions.
|
||||||
WDTCR |= (1 << WDCE) | (1 << WDE);
|
// The second write is guaranteed to occur within the required four cycles.
|
||||||
WDTCR = bb | (1 << WDIE);
|
const uint8_t unlock = _BV(WDCE) | _BV(WDE);
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"out %[wdt], %[unlock] \n\t"
|
||||||
|
"out %[wdt], %[config] \n\t"
|
||||||
|
:
|
||||||
|
: [wdt] "I" (_SFR_IO_ADDR(WDTCR)),
|
||||||
|
[unlock] "r" (unlock),
|
||||||
|
[config] "r" (cfg)
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
|
||||||
SREG = oldSREG;
|
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||||
|
|
||||||
|
// Atomic sleep entry: after sei() the next instruction (sleep_cpu) still
|
||||||
|
// executes before any interrupt is serviced, so the wake-up cannot be missed.
|
||||||
|
// Loop again if something else woke the CPU.
|
||||||
|
while (!f_wdt) {
|
||||||
|
sleep_enable();
|
||||||
|
#if BOD_FUSE_ENABLED
|
||||||
|
sleep_bod_disable();
|
||||||
|
#endif
|
||||||
|
sei();
|
||||||
|
sleep_cpu();
|
||||||
|
sleep_disable();
|
||||||
|
cli();
|
||||||
|
}
|
||||||
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(WDT_vect)
|
// Wait n Morse units in power-down.
|
||||||
|
static void waitUnits(uint8_t n)
|
||||||
{
|
{
|
||||||
f_wdt = true;
|
while (n--) {
|
||||||
|
sleepWdt(UNIT_WDT_A);
|
||||||
|
#if UNIT_WDT_B != 0xFF
|
||||||
|
sleepWdt(UNIT_WDT_B);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
// Light sensor
|
// Light sensor
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
// Returns a "darkness level": higher = darker.
|
// Returns true if it is dark.
|
||||||
// Charges the LED junction capacitance, then times how long it takes to bleed
|
// Charges the LED junction capacitance, then lets it bleed through the
|
||||||
// back through the reverse-biased LED until the input reads LOW.
|
// reverse-biased LED while the CPU sleeps. Checks the pin every ~16 ms.
|
||||||
// ~30000 = pitch black, ~0 = bright light
|
// LOW within the window -> bright (discharged fast)
|
||||||
unsigned int sensDarkness(int LED_N, int LED_P)
|
// still HIGH at the end -> dark
|
||||||
|
// In power-down the input buffer of the floating pin is disabled by hardware,
|
||||||
|
// so the slowly falling voltage causes no shoot-through current.
|
||||||
|
bool isDark(int LED_N, int LED_P)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
// Charge the LED junction capacitance.
|
// Charge the LED junction capacitance.
|
||||||
pinMode(LED_N, OUTPUT);
|
pinMode(LED_N, OUTPUT);
|
||||||
pinMode(LED_P, OUTPUT);
|
pinMode(LED_P, OUTPUT);
|
||||||
digitalWrite(LED_N, HIGH);
|
digitalWrite(LED_N, HIGH);
|
||||||
digitalWrite(LED_P, LOW);
|
digitalWrite(LED_P, LOW);
|
||||||
|
|
||||||
// Let the N-side float and measure bleed-down time.
|
// Let the N-side float (no pullup) and measure bleed-down time.
|
||||||
pinMode(LED_N, INPUT);
|
pinMode(LED_N, INPUT);
|
||||||
digitalWrite(LED_N, LOW); // disable internal pullup
|
digitalWrite(LED_N, LOW);
|
||||||
|
|
||||||
for (i = 0; i < 30000; i++) {
|
bool dark = true;
|
||||||
if (digitalRead(LED_N) == LOW) break;
|
for (uint8_t k = 0; k < darkSteps; k++) {
|
||||||
|
sleepWdt(0); // ~16 ms
|
||||||
|
if (digitalRead(LED_N) == LOW) {
|
||||||
|
dark = false; // bright: stop early
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up after sensing: both LED pins low, then caller releases them.
|
// Clean up after sensing: both LED pins low, caller releases them.
|
||||||
pinMode(LED_N, OUTPUT);
|
pinMode(LED_N, OUTPUT);
|
||||||
digitalWrite(LED_N, LOW);
|
digitalWrite(LED_N, LOW);
|
||||||
pinMode(LED_P, OUTPUT);
|
pinMode(LED_P, OUTPUT);
|
||||||
digitalWrite(LED_P, LOW);
|
digitalWrite(LED_P, LOW);
|
||||||
|
|
||||||
return i;
|
return dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -277,17 +392,17 @@ unsigned int sensDarkness(int LED_N, int LED_P)
|
|||||||
void dit(int LED_P)
|
void dit(int LED_P)
|
||||||
{
|
{
|
||||||
digitalWrite(LED_P, HIGH);
|
digitalWrite(LED_P, HIGH);
|
||||||
delay(unitLength);
|
waitUnits(1);
|
||||||
digitalWrite(LED_P, LOW);
|
digitalWrite(LED_P, LOW);
|
||||||
delay(unitLength);
|
waitUnits(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dah(int LED_P)
|
void dah(int LED_P)
|
||||||
{
|
{
|
||||||
digitalWrite(LED_P, HIGH);
|
digitalWrite(LED_P, HIGH);
|
||||||
delay(unitLength * 3);
|
waitUnits(3);
|
||||||
digitalWrite(LED_P, LOW);
|
digitalWrite(LED_P, LOW);
|
||||||
delay(unitLength);
|
waitUnits(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -354,24 +469,30 @@ void morse(int LED_N, int LED_P)
|
|||||||
case '9': dah(LED_P); dah(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // ----.
|
case '9': dah(LED_P); dah(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // ----.
|
||||||
case '0': dah(LED_P); dah(LED_P); dah(LED_P); dah(LED_P); dah(LED_P); symbolSent = true; break; // -----
|
case '0': dah(LED_P); dah(LED_P); dah(LED_P); dah(LED_P); dah(LED_P); symbolSent = true; break; // -----
|
||||||
|
|
||||||
// ----- Punctuation -----
|
// ----- Punctuation & Specials -----
|
||||||
case '.': dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); symbolSent = true; break; // .-.-.-
|
case '.': dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); symbolSent = true; break; // .-.-.-
|
||||||
case ',': dah(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); symbolSent = true; break; // --..--
|
case ',': dah(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); symbolSent = true; break; // --..--
|
||||||
case '?': dit(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); symbolSent = true; break; // ..--..
|
case '?': dit(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); symbolSent = true; break; // ..--..
|
||||||
case '!': dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); symbolSent = true; break; // -.-.--
|
case '!': dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); symbolSent = true; break; // -.-.--
|
||||||
case ':': dah(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); dit(LED_P); symbolSent = true; break; // ---...
|
case ':': dah(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); dit(LED_P); symbolSent = true; break; // ---...
|
||||||
case ';': dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // -.-.-.
|
case ';': dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // -.-.-.
|
||||||
case '(': dah(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // -.--.
|
case '(': dah(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // -.--.
|
||||||
case ')': dah(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); symbolSent = true; break; // -.--.-
|
case ')': dah(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); symbolSent = true; break; // -.--.-
|
||||||
case '"': dit(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // .-..-.
|
case '"': dit(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // .-..-.
|
||||||
case '@': dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // .--.-.
|
case '@': dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // .--.-.
|
||||||
case '&': dit(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); dit(LED_P); symbolSent = true; break; // .-...
|
case '&': dit(LED_P); dah(LED_P); dit(LED_P); dit(LED_P); dit(LED_P); symbolSent = true; break; // .-...
|
||||||
|
case '-': dah(LED_P); dit(LED_P); dit(LED_P); dit(LED_P); dit(LED_P); dah(LED_P); symbolSent = true; break; // -....-
|
||||||
|
case '/': dah(LED_P); dit(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // -..-.
|
||||||
|
case '\'': dit(LED_P); dah(LED_P); dah(LED_P);dah(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // .----.
|
||||||
|
case '+': dit(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); dit(LED_P); symbolSent = true; break; // .-.-.
|
||||||
|
case '=': dah(LED_P); dit(LED_P); dit(LED_P); dit(LED_P); dah(LED_P); symbolSent = true; break; // -...-
|
||||||
|
case '_': dit(LED_P); dit(LED_P); dah(LED_P); dah(LED_P); dit(LED_P); dah(LED_P); symbolSent = true; break; // ..--.-
|
||||||
|
|
||||||
// Space handling:
|
// Space handling:
|
||||||
// Previous symbol already ended with 1 unit OFF and then received the
|
// Previous symbol already ended with 1 unit OFF and then received the
|
||||||
// normal 2 unit character gap. Add 4 units here -> total word gap 7 units.
|
// normal 2 unit character gap. Add 4 units here -> total word gap 7 units.
|
||||||
case ' ':
|
case ' ':
|
||||||
delay(unitLength * 4);
|
waitUnits(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Unsupported chars are ignored without adding an artificial gap.
|
// Unsupported chars are ignored without adding an artificial gap.
|
||||||
@@ -382,7 +503,7 @@ void morse(int LED_N, int LED_P)
|
|||||||
// Inter-character gap: 3 units total.
|
// Inter-character gap: 3 units total.
|
||||||
// dit()/dah() already trail 1 unit OFF, so add the remaining 2 units.
|
// dit()/dah() already trail 1 unit OFF, so add the remaining 2 units.
|
||||||
if (symbolSent) {
|
if (symbolSent) {
|
||||||
delay(unitLength * 2);
|
waitUnits(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -9,7 +9,7 @@
|
|||||||
(paper "A4")
|
(paper "A4")
|
||||||
(title_block
|
(title_block
|
||||||
(title "日輪蛍 / Nichirin Hotaru / FireFly Solar")
|
(title "日輪蛍 / Nichirin Hotaru / FireFly Solar")
|
||||||
(date "2026-07-02")
|
(date "2026-09-27")
|
||||||
(rev "FireFly Sol 2")
|
(rev "FireFly Sol 2")
|
||||||
(company "WWW: https://togo-lab.io")
|
(company "WWW: https://togo-lab.io")
|
||||||
(comment 1 "Email: tgohle@togo-lab.io")
|
(comment 1 "Email: tgohle@togo-lab.io")
|
||||||
@@ -2094,8 +2094,8 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "Value" "3V6 1.3W"
|
(property "Value" "3V9 1.3W"
|
||||||
(at 5.588 0.508 0)
|
(at 5.5372 0.0508 0)
|
||||||
(layer "F.SilkS")
|
(layer "F.SilkS")
|
||||||
(uuid "0961063d-f8b2-473d-ac71-4e9497f2e68d")
|
(uuid "0961063d-f8b2-473d-ac71-4e9497f2e68d")
|
||||||
(effects
|
(effects
|
||||||
@@ -9803,7 +9803,7 @@
|
|||||||
(justify left bottom)
|
(justify left bottom)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(gr_text "#0001 日輪蛍\nNichirin Hotaru\n\nFireFly Solar\n\ntogo-lab.io\n2026 V 1.0"
|
(gr_text "#0001 日輪蛍\nNichirin Hotaru\n\nFireFly Solar\n\ntogo-lab.io\n2026 V 3.0"
|
||||||
(at 135.382 84.709 0)
|
(at 135.382 84.709 0)
|
||||||
(layer "B.SilkS")
|
(layer "B.SilkS")
|
||||||
(uuid "88b0a397-e4a2-4145-86f6-0fa60b4a4bd9")
|
(uuid "88b0a397-e4a2-4145-86f6-0fa60b4a4bd9")
|
||||||
@@ -9816,7 +9816,7 @@
|
|||||||
)
|
)
|
||||||
(justify bottom mirror)
|
(justify bottom mirror)
|
||||||
)
|
)
|
||||||
(render_cache "#0001 日輪蛍\nNichirin Hotaru\n\nFireFly Solar\n\ntogo-lab.io\n2026 V 1.0"
|
(render_cache "#0001 日輪蛍\nNichirin Hotaru\n\nFireFly Solar\n\ntogo-lab.io\n2026 V 3.0"
|
||||||
0
|
0
|
||||||
(polygon
|
(polygon
|
||||||
(pts
|
(pts
|
||||||
@@ -11359,25 +11359,37 @@
|
|||||||
)
|
)
|
||||||
(polygon
|
(polygon
|
||||||
(pts
|
(pts
|
||||||
(xy 132.305492 83.4953) (xy 132.314285 83.529005) (xy 132.327181 83.570771) (xy 132.3407 83.588268)
|
(xy 132.102893 83.703028) (xy 132.149778 83.746548) (xy 132.206794 83.779305) (xy 132.328427 83.832941)
|
||||||
(xy 132.364843 83.601472) (xy 132.374882 83.627484) (xy 132.393493 83.659577) (xy 132.414229 83.697752)
|
(xy 132.388647 83.886206) (xy 132.456068 83.932739) (xy 132.59045 84.022937) (xy 132.581218 84.057229)
|
||||||
(xy 132.420316 83.715223) (xy 132.419871 83.727721) (xy 132.539672 83.915739) (xy 132.597455 84.01795)
|
(xy 132.578067 84.085806) (xy 132.560533 84.091707) (xy 132.535056 84.110498) (xy 132.490653 84.159298)
|
||||||
(xy 132.648775 84.119511) (xy 132.702436 84.223652) (xy 132.765719 84.333834) (xy 132.835364 84.438492)
|
(xy 132.475747 84.183918) (xy 132.47336 84.196008) (xy 132.449373 84.212983) (xy 132.422069 84.248251)
|
||||||
(xy 132.905304 84.523757) (xy 132.921099 84.519152) (xy 132.927945 84.505879) (xy 132.930583 84.472759)
|
(xy 132.3773 84.33127) (xy 132.349383 84.393991) (xy 132.351509 84.41993) (xy 132.368946 84.441325)
|
||||||
(xy 132.930583 84.463234) (xy 132.921649 84.459409) (xy 132.904718 84.434877) (xy 132.86559 84.354351)
|
(xy 132.392561 84.452427) (xy 132.407708 84.4477) (xy 132.563852 84.475324) (xy 132.649371 84.483492)
|
||||||
(xy 132.819281 84.247006) (xy 132.775464 84.138782) (xy 132.742931 84.054225) (xy 132.736337 84.049975)
|
(xy 132.737216 84.486242) (xy 132.824442 84.483972) (xy 132.905524 84.477376) (xy 132.983273 84.465188)
|
||||||
(xy 132.722195 84.045286) (xy 132.720713 84.024039) (xy 132.707394 83.987034) (xy 132.669219 83.909438)
|
(xy 133.050457 84.447773) (xy 133.029476 84.436084) (xy 132.990813 84.423227) (xy 132.894752 84.402418)
|
||||||
(xy 132.642474 83.857707) (xy 132.630824 83.820924) (xy 132.621518 83.816277) (xy 132.610161 83.796524)
|
(xy 132.793782 84.386884) (xy 132.726298 84.379043) (xy 132.70776 84.379043) (xy 132.644965 84.379043)
|
||||||
(xy 132.591989 83.742083) (xy 132.581804 83.699658) (xy 132.575796 83.695408) (xy 132.556012 83.679801)
|
(xy 132.608563 84.376692) (xy 132.577994 84.370104) (xy 132.554249 84.357412) (xy 132.545387 84.340722)
|
||||||
(xy 132.539892 83.660163) (xy 132.539879 83.650038) (xy 132.55037 83.637742) (xy 132.542195 83.624458)
|
(xy 132.546275 84.326793) (xy 132.55799 84.300861) (xy 132.596312 84.241803) (xy 132.639836 84.184944)
|
||||||
(xy 132.531099 83.618251) (xy 132.521226 83.61234) (xy 132.51791 83.601106) (xy 132.536359 83.590858)
|
(xy 132.669145 84.151458) (xy 132.690748 84.131855) (xy 132.71626 84.115554) (xy 132.738221 84.095772)
|
||||||
(xy 132.567589 83.58352) (xy 132.640203 83.578831) (xy 132.706588 83.584546) (xy 132.730403 83.592341)
|
(xy 132.752383 84.061552) (xy 132.741386 84.049543) (xy 132.736117 84.034221) (xy 132.733625 84.003813)
|
||||||
(xy 132.737655 83.599787) (xy 132.75728 83.608464) (xy 132.778354 83.608725) (xy 132.802575 83.599787)
|
(xy 132.733625 83.997732) (xy 132.693353 83.964706) (xy 132.644452 83.931493) (xy 132.543556 83.868551)
|
||||||
(xy 132.860681 83.559926) (xy 132.849836 83.536552) (xy 132.849201 83.52133) (xy 132.857603 83.503286)
|
(xy 132.459145 83.81008) (xy 132.429495 83.781769) (xy 132.417307 83.760327) (xy 132.367921 83.741716)
|
||||||
(xy 132.815325 83.490317) (xy 132.795016 83.480533) (xy 132.787481 83.462107) (xy 132.703344 83.436625)
|
(xy 132.345324 83.728468) (xy 132.330258 83.714166) (xy 132.322976 83.697839) (xy 132.326815 83.681046)
|
||||||
(xy 132.621738 83.419389) (xy 132.537841 83.412686) (xy 132.441267 83.419535) (xy 132.431971 83.428417)
|
(xy 132.342529 83.664113) (xy 132.370339 83.656207) (xy 132.402194 83.650219) (xy 132.435112 83.636643)
|
||||||
(xy 132.421996 83.431113) (xy 132.397523 83.427742) (xy 132.384041 83.42613) (xy 132.370046 83.424445)
|
(xy 132.446933 83.626784) (xy 132.451891 83.617226) (xy 132.457379 83.609352) (xy 132.471748 83.605062)
|
||||||
(xy 132.34691 83.435561) (xy 132.330771 83.45456)
|
(xy 132.517925 83.578938) (xy 132.579166 83.558094) (xy 132.645633 83.544235) (xy 132.718092 83.535526)
|
||||||
|
(xy 132.861487 83.529591) (xy 132.929014 83.531692) (xy 132.983779 83.537431) (xy 133.032407 83.546654)
|
||||||
|
(xy 133.058444 83.55509) (xy 133.065185 83.567766) (xy 133.077348 83.569818) (xy 133.089658 83.569818)
|
||||||
|
(xy 133.106584 83.57568) (xy 133.122645 83.541587) (xy 133.120872 83.51926) (xy 133.097572 83.482477)
|
||||||
|
(xy 133.082184 83.462913) (xy 133.079347 83.453219) (xy 133.081818 83.442836) (xy 133.057696 83.422252)
|
||||||
|
(xy 133.038514 83.414993) (xy 132.998214 83.41404) (xy 132.968538 83.415725) (xy 132.954304 83.412354)
|
||||||
|
(xy 132.937031 83.400484) (xy 132.89336 83.402243) (xy 132.840531 83.402243) (xy 132.737143 83.402243)
|
||||||
|
(xy 132.624009 83.409131) (xy 132.612808 83.425319) (xy 132.608768 83.427376) (xy 132.600342 83.421587)
|
||||||
|
(xy 132.587006 83.412355) (xy 132.579428 83.414676) (xy 132.566197 83.431113) (xy 132.554405 83.425924)
|
||||||
|
(xy 132.527362 83.426643) (xy 132.461856 83.441884) (xy 132.394519 83.463719) (xy 132.343594 83.481451)
|
||||||
|
(xy 132.341689 83.483429) (xy 132.27567 83.52351) (xy 132.205621 83.563956) (xy 132.176091 83.592213)
|
||||||
|
(xy 132.153671 83.63188) (xy 132.140744 83.632576) (xy 132.132348 83.641186) (xy 132.12253 83.667564)
|
||||||
|
(xy 132.115203 83.687934)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(polygon
|
(polygon
|
||||||
|
|||||||
@@ -379,7 +379,7 @@
|
|||||||
"internal_id": "",
|
"internal_id": "",
|
||||||
"mfg": "",
|
"mfg": "",
|
||||||
"mpn": "",
|
"mpn": "",
|
||||||
"sch_revision": "2"
|
"sch_revision": "3"
|
||||||
},
|
},
|
||||||
"layer_pairs": [],
|
"layer_pairs": [],
|
||||||
"layer_presets": [],
|
"layer_presets": [],
|
||||||
@@ -665,6 +665,7 @@
|
|||||||
"netlist": "",
|
"netlist": "",
|
||||||
"plot": "",
|
"plot": "",
|
||||||
"specctra_dsn": "",
|
"specctra_dsn": "",
|
||||||
|
"step": "",
|
||||||
"vrml": ""
|
"vrml": ""
|
||||||
},
|
},
|
||||||
"page_layout_descr_file": ""
|
"page_layout_descr_file": ""
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
(paper "A4")
|
(paper "A4")
|
||||||
(title_block
|
(title_block
|
||||||
(title "日輪蛍 / Nichirin Hotaru / FireFly Solar")
|
(title "日輪蛍 / Nichirin Hotaru / FireFly Solar")
|
||||||
(date "2026-07-02")
|
(date "2026-09-27")
|
||||||
(rev "2")
|
(rev "3")
|
||||||
(company "Tōgō Lab / 塔郷研究所")
|
(company "Tōgō Lab / 塔郷研究所")
|
||||||
(comment 1 "WWW: https://togo-lab.io")
|
(comment 1 "WWW: https://togo-lab.io")
|
||||||
(comment 2 "Email: tgohle@togo-lab.io")
|
(comment 2 "Email: tgohle@togo-lab.io")
|
||||||
@@ -2123,9 +2123,9 @@
|
|||||||
(embedded_fonts no)
|
(embedded_fonts no)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(text "R2 value depends on volage Setting and D6 LED Type:\n\n3.3 V: - RED 470 Ω (tested)\n - GREEN, LOW-VF 470 Ω (not tested)\n - YELLOW, LOW-VF 470 Ω (not tested)\n\n5.0 V: - RED 560 Ω tested, but 5V not recommended"
|
(text "R2 value depends on volage Setting and D6 LED Type.\nOnly tested this settings:\n\n3.3 V:\n- RED 640 Ω (~ 2,2 mA tested,)\n- GREEN 330 Ω (~ 2,2 mA tested, very bright!)\n\n"
|
||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(at 196.342 59.69 0)
|
(at 219.964 58.42 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@@ -2144,9 +2144,9 @@
|
|||||||
)
|
)
|
||||||
(uuid "0bf54ea3-f975-4977-80ee-b53880b5df6d")
|
(uuid "0bf54ea3-f975-4977-80ee-b53880b5df6d")
|
||||||
)
|
)
|
||||||
(text "I use 4V SuperCap 50F.\nThis needs protection for overvoltage \nfrom Solar panels therefore Z-Diode\nwith 3.6V.\nDuring a bright Day most energy is\nused by R1, therefore 2W typ.\nC1 = SuperCap should load < 1h."
|
(text "I use 4V SuperCap 50F.\nThis needs protection for overvoltage \nfrom solar panels therefore Z-Diode\nwith 3.6 - 3.9V. (depending on solar panel)\nDuring a bright Day most energy is\nused by R1, therefore 2W typ.\nC1 = SuperCap should load 2..3 h."
|
||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(at 76.2 69.342 0)
|
(at 76.708 63.246 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@@ -2155,13 +2155,14 @@
|
|||||||
)
|
)
|
||||||
(uuid "151e3e93-9403-408a-bca5-e165542b5719")
|
(uuid "151e3e93-9403-408a-bca5-e165542b5719")
|
||||||
)
|
)
|
||||||
(text "C6 RESET, optional"
|
(text "C6 RESET, optional\n\nin V1 not used, works without"
|
||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(at 263.398 105.156 0)
|
(at 254.762 108.966 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
)
|
)
|
||||||
|
(justify left)
|
||||||
)
|
)
|
||||||
(uuid "1bf5fdfb-548f-4ff1-9dbf-73a875269c83")
|
(uuid "1bf5fdfb-548f-4ff1-9dbf-73a875269c83")
|
||||||
)
|
)
|
||||||
@@ -2176,9 +2177,9 @@
|
|||||||
)
|
)
|
||||||
(uuid "71b72fad-9748-4a7a-92a5-a4bc4876fb33")
|
(uuid "71b72fad-9748-4a7a-92a5-a4bc4876fb33")
|
||||||
)
|
)
|
||||||
(text "max 3x Solar Modules,\n5V Type with 60x60mm\n ~ 4.5 V and 10mA under real conditions\n will charge C1 in ~ 1.5h upt to 3.5V\n\nPin 1 = +\nPin 2 = -/GND\n"
|
(text "max 3x Solar Modules,\n~ 5V Type with 60x60mm\n -> ~ 4.5 V and 10mA under real conditions\n will charge C1 in ~ 3h upt to > 3.5V\n\nPin 1 = +\nPin 2 = -/GND\n"
|
||||||
(exclude_from_sim no)
|
(exclude_from_sim no)
|
||||||
(at 25.4 69.596 0)
|
(at 25.908 63.5 0)
|
||||||
(effects
|
(effects
|
||||||
(font
|
(font
|
||||||
(size 1.27 1.27)
|
(size 1.27 1.27)
|
||||||
@@ -4930,7 +4931,7 @@
|
|||||||
(justify left)
|
(justify left)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(property "Value" "BZV85-C3V6 1.3W"
|
(property "Value" "BZV85-C3V9 1.3W"
|
||||||
(at 80.772 84.582 0)
|
(at 80.772 84.582 0)
|
||||||
(show_name no)
|
(show_name no)
|
||||||
(do_not_autoplace no)
|
(do_not_autoplace no)
|
||||||
|
|||||||
Binary file not shown.
Reference in new issue
Block a user