From 251f7ed37603f8080bbbd562b4784c2bd9e07058 Mon Sep 17 00:00:00 2001 From: Thomas Gohle Date: Mon, 25 May 2026 19:45:09 +0200 Subject: [PATCH] additional mechanical parts for housing --- .../ATTINY85_2026_MorseThrowie.ino | 544 + .../ATTINY45_2014_MorseThrowie.ino | 4 +- .../FireFly3DMechanical.FCStd | Bin 6854 -> 0 bytes .../FireFly3DMechanical_v0.1.scad | 288 - .../FireFly3DMechanical_v0.1.stl | Bin 5684 -> 0 bytes .../3D_Print-Designs/tetrahedron40mmC.stl | Bin 5684 -> 0 bytes ...Go-Lab_FireFly_MorseThrowie - LaserCut.dxf | 7960 ++++++ ...FireFly_MorseThrowie - LaserCut_Upload.dxf | 7410 +++++ .../CAD/ToGo-Lab_FireFly_MorseThrowie.dxf | 23006 ---------------- 9 files changed, 15916 insertions(+), 23296 deletions(-) create mode 100644 firmware/ATTINY85_2026_MorseThrowie/ATTINY85_2026_MorseThrowie.ino delete mode 100644 hardware/3D_Print-Designs/FireFly3DMechanical.FCStd delete mode 100644 hardware/3D_Print-Designs/FireFly3DMechanical_v0.1.scad delete mode 100644 hardware/3D_Print-Designs/FireFly3DMechanical_v0.1.stl delete mode 100644 hardware/3D_Print-Designs/tetrahedron40mmC.stl create mode 100644 hardware/CAD/ToGo-Lab_FireFly_MorseThrowie - LaserCut.dxf create mode 100644 hardware/CAD/ToGo-Lab_FireFly_MorseThrowie - LaserCut_Upload.dxf delete mode 100644 hardware/CAD/ToGo-Lab_FireFly_MorseThrowie.dxf diff --git a/firmware/ATTINY85_2026_MorseThrowie/ATTINY85_2026_MorseThrowie.ino b/firmware/ATTINY85_2026_MorseThrowie/ATTINY85_2026_MorseThrowie.ino new file mode 100644 index 0000000..6aba0ad --- /dev/null +++ b/firmware/ATTINY85_2026_MorseThrowie/ATTINY85_2026_MorseThrowie.ino @@ -0,0 +1,544 @@ +/* + ============================================================================= + FireFly Morse Throwie + - a light controled (LED as Sensor) morseblinker throwie with ATTiny45/85 + ============================================================================= + + Project definitions, sources + ----------------------------------------------------------------------------- + Version: 0.1 - Attiny85 Version + Date : 25.05.2026 + + ----------------------------------------------------------------------------- + + Inspired by Karl Lunt's FireFly project I wrote some code to make this + Throwie lasting longer, blinking only at low light levels and morse also + some text. + http://www.seanet.com/~karllunt/fireflyLED.html + + How it works (only the Morsethrowy part): + LED detects light level, using bleeding out time of LED pn-capacitor. + If dark enough blink a text in morsecode (ATTiny45 = 22 Chars, text will + be defined in line 191/192 of this file) + To save energy go to powersave mode after blinking or light level is + over threshold. Tests this every 8s (maximum time for watchdog timer + possible for ATTiny). Repeat this endless + + + The wiring, it's very simple, see also HW part of the Project. + + +---+ +------\/------+ + | | ATTINY45 /85 | + > | -+1=PB5 VCC=8+-> to SuperCap / DC-DC 3V/5V + xxx Ohm < | | | + > +------+2=PB3 PB2=7+- + | | | + ----- +------+3=PB4 PB1=6+- + LED / \ | | | + ----- | +--+4=GND PB0=5+- + | | | | | + +---+ | +--------------+ + | + +---------------------> to battery GND + + You can use other pins if necessary, theoretical up to 3 LEDs, as example I + tried out to connect another one at PB2&PB1. working fine. Basic wiring: + + + LED_N_Side), wired to a digital pin, NOT Vcc + | + < + > 100 - 460 ohm resistor depending Voltage + < + | + | + ----- + / \ LED, maybe a 5mm, clear plastic is good + ----- + | + | + + LED_P_Side), wired to a digital pin, NOT Gnd + + ----------------------------------------------------------------------------- + Im just a newbe in ATTiny / Arduino programming, so many thanks to: + + Programming ATTiny with Arduino IDE: + http://highlowtech.org/?p=1695 + + LED Lightsensor, Arduino Playground: + http://playground.arduino.cc/Learning/LEDSensor + + Powersaving Mode for Attiny45/85: + A good description by Martin Nawrath nawrath@khm.de and the folks at + http://www.insidegadgets.com/2011/02/05/reduce-attiny-power-consumption-by-sleeping-with-the-watchdog-timer/ + + With this description I got ~5uA during sleep mode. + in Morse-Mode with LED OFF: 1.7mA + LED ON: 6.9mA + --> I hope to run this throwies ~40days with one CR2032. + + Morsecode + To translate a text into morsecode, there are several ways. You can use + this fine online translator: + http://morsecode.scphillips.com/jtranslator.html + + There is also a great morse coder / encoder from Matthias Esterl aka madc. + Works fine for Arduino, but not for ATTiny because of RAM limitations. But + maybe this is helpful if your project works with an Arduino. + https://gist.github.com/madc/4474559 + + For this project I use a simple case structur. Looks arkward, but the + ATTiny45 has only 256byte RAM but 4kFlash. A data structure is better programming + but needs a lot of RAM we not have. Therefore this ugly case structure. + This will waste the flash memory but we have enough and saving RAM for + our payload - the ASCII-string with the morsetext. + + BTW - Morsecode itself: + + 'A', ".-" 'B', "-..." 'C', "-.-." + 'D', "-.." 'E', "." 'F', "..-." + 'G', "--." 'H', "...." 'I', ".." + 'J', ".---" 'K', ".-.-" 'L', ".-.." + 'M', "--" 'N', "-." 'O', "---" + 'P', ".--." 'Q', "--.-" 'R', ".-." + 'S', "..." 'T', "-" 'U', "..-" + 'V', "...-" 'W', ".--" 'X', "-..-" + 'Y', "-.--" 'Z', "--.." + + '1', ".----" '2', "..---" '3', "...--" + '4', "....-" '5', "....." '6', "-...." + '7', "--..." '8', "---.." '9', "----." + '0', "-----" + + '.', ".-.-.-" ',', "--..--" '?', "..--.." + '!', "-.-.--" ':', "---..." ';', "-.-.-." + '(', "-.--." ')', "-.--.-" '"', ".-..-." + '@', ".--.-." '&', ".-..." + + ----------------------------------------------------------------------------- + Legal stuff / Copyright: + Creative Commons Attribution ShareAlike 3.0.: + http://creativecommons.org/licenses/by-sa/3.0/legalcode + ----------------------------------------------------------------------------- +*/ + + +// =========================================================================== +// Ok folks, let's start +// =========================================================================== +// for sleep Mode / Powersave we need some additional stuff. Its alredy there, +// if you installed the Attiny extension for Arduino IDE, no additional +// installing needed. +#include +#include + +// =========================================================================== +// Some definitions for powersave depending of ATTiny type. +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +// =========================================================================== +// for ATTiny85 +// Unit length < 150 will hard to be read for optical morse code +// > 300 are too slow in my feeling for longer text +// +// for ATTiny85 at 8MHz (for 1MHz see ATTiny45) +// Unit length < 5 will hard to be read for optical morse code +// > 10 are too slow in my feeling for longer text +// +// + +#define unitLength 100 + +// --------------------------------------------------------------------------- +// LED Pin definitions, +// theoretical you can use up to 3 LED. For example you can use it for a +// landmark beacon. So if you point this LEDs to different directions you can +// detect the position in dependence of your location to the bacon. +#define LED1_N_SIDE 3 +#define LED1_P_SIDE 4 + +// =========================================================================== +// Variables +// =========================================================================== +// ########################################################################### +// # and now the text, but be aware, only 256Byte RAM for Attiny45 # +// # so there are only 22 Chars left for your message. # +// # BTW with an Attiny85 you will have additional 256byte # +// # => more than for twitter :-) # +// # => for FireFly with SuperCap: less ist better, charge last longer # + +String morseText = + "TOGO LAB"; +// # "....5....1....5....2.."; just a ruler, remember 22 Chars for ATTiny # +// IT IS USELESS +// HAIL GLOW CLOUD +// ########################################################################### + +// Define light trigger threshold. best way to set it on dusk / dawn level +// diffuse red ones are less sensitive than clear green ones... +int darknessThreshold = 17000; + +// Interrupt Flag, should be volatile, means: read from RAM, not register +// because registers are used for interrupt handling, it have to be volatile. +volatile boolean f_wdt = 1; + +// =========================================================================== +// Setup watchdog +// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms +// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec +// =========================================================================== +void setup() +{ + setup_watchdog(9); +} + +// =========================================================================== +// Main +// =========================================================================== + +void loop(){ + + if (f_wdt==1) { // wait for timed out watchdog + // flag is set when a watchdog timeout occurs + f_wdt=0; // reset flag + + // if it's dark enough [>darknesThreshold] morse + if (sensDarkness(LED1_N_SIDE, LED1_P_SIDE) > darknessThreshold){ + // looks like it's dark, so do your job + morse(LED1_N_SIDE, LED1_P_SIDE); + } + } + // set all used port to intput to save power + pinMode(LED1_N_SIDE,INPUT); + pinMode(LED1_P_SIDE,INPUT); + system_sleep(); + f_wdt=0; // 2nd time sleep + system_sleep(); +} + +// =========================================================================== +// Subroutines for Sleeping +// =========================================================================== +// set system into the sleep state +// system wakes up when wtchdog is timed out +void system_sleep() { + cbi(ADCSRA,ADEN); // switch Analog to + // Digitalconverter OFF + + set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here + sleep_enable(); + + sleep_mode(); // System sleeps here + + sleep_disable(); // System continues execution here when + // watchdog timed out + sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON +} + +// ---------------------------------------------------------------------------- +// Setup for watchdog. Parameter ii for sleeping time: +// 0 = 16ms, 1 = 32ms, 2 = 64ms, +// 3 = 128ms, 4 = 250ms, 5 = 500ms +// 6 = 1 sec, 7 = 2 sec, 8 = 4 sec, +// 9 = 8 sec +void setup_watchdog(int ii) { + + byte bb; + int ww; + if (ii > 9 ) ii=9; + bb=ii & 7; + if (ii > 7) bb|= (1<<5); + bb|= (1<onR=e@SF3{hULY*`uV=NQ}apko$*mTe{|4& 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 TRlx_yx`DyclJ8&tx0n74(39{@ diff --git a/hardware/3D_Print-Designs/FireFly3DMechanical_v0.1.scad b/hardware/3D_Print-Designs/FireFly3DMechanical_v0.1.scad deleted file mode 100644 index d1e10af..0000000 --- a/hardware/3D_Print-Designs/FireFly3DMechanical_v0.1.scad +++ /dev/null @@ -1,288 +0,0 @@ -/* - FireFly tetrahedron adapter - Base STL: tetrahedron40mmC.stl - - Purpose: - - Import original 40 mm foldable tetrahedron STL - - Scale it to 60 mm base geometry - - Add cable holes, vent/drain holes, and optional PCB mounting holes - - Workflow: - 1. Set PART = "upper" - 2. Render with F6 - 3. Export STL - 4. Set PART = "lower" - 5. Render with F6 - 6. Export STL - - Notes: - - Hole coordinates are defined on the original 40 mm STL coordinate system. - - The script scales them automatically to 60 mm. - - First export should be treated as v0.1 prototype. -*/ - - -/* ========================= - Main selection - ========================= */ - -PART = "upper"; // "upper", "lower", or "both_preview" - - -/* ========================= - Input file - ========================= */ - -input_stl = "tetrahedron40mmC.stl"; - - -/* ========================= - Scaling - ========================= */ - -// Original tetrahedron edge length -original_edge_mm = 40; - -// Target mechanical base size -target_edge_mm = 60; - -// XY scale from 40 mm to 60 mm -scale_xy = target_edge_mm / original_edge_mm; // 1.5 - -// Keep original thickness. -// Set to 1.2 or 1.3 if you want a slightly thicker part. -scale_z = 1.0; - - -/* ========================= - General hole settings - ========================= */ - -hole_fn = 40; -cut_height = 20; - - -/* ========================= - Feature switches - ========================= */ - -add_upper_cable_holes = true; -add_upper_hanger_hole = true; - -add_lower_vent_holes = true; -add_lower_cable_holes = true; -add_lower_pcb_mount_holes = true; - -// Keep this false for the first prototype. -// Standoffs may interfere with folding depending on print orientation. -add_lower_pcb_standoffs = false; - - -/* ========================= - Hole sizes - ========================= */ - -cable_hole_d = 3.2; // for small solar-panel wires -hanger_hole_d = 3.5; // for small ring / wire / eyelet -vent_hole_d = 2.0; // condensation vent / drain holes -pcb_screw_hole_d = 2.2; // M2 clearance-ish -pcb_standoff_d = 6.0; -pcb_standoff_h = 3.0; - - -/* ========================= - Coordinate reference - ========================= - - The uploaded STL is approximately: - - X: -34.64 to +34.64 - Y: -20.00 to +60.00 - Z: -0.10 to +2.00 - - The original model is a flat foldable tetrahedron net. - Coordinates below are before scaling. -*/ - - -/* ========================= - Upper part hole positions - ========================= */ - -// Cable holes for three solar panels. -// Adjust after checking where your real panel wires exit. -upper_cable_points = [ - [-18, 20], - [ 24, 7], - [ 24, 33] -]; - -// Optional hanger hole close to one upper fold/vertex area. -// If this weakens the corner too much, disable it and use an external loop instead. -upper_hanger_points = [ - [0, 38] -]; - - -/* ========================= - Lower part hole positions - ========================= */ - -// Cable transfer holes between upper solar section and lower electronics bay. -lower_cable_points = [ - [-10, 20], - [ 12, 13], - [ 12, 27] -]; - -// Small vent/drain hole clusters near likely lower/edge areas. -// These are deliberately small. -lower_vent_centres = [ - [ 0, 3], - [ 0, 37], - [-30, 20], - [ 31, 20] -]; - -// Approximate triangular PCB mounting pattern. -// Tune this after measuring your actual red triangle PCB. -lower_pcb_mount_points = [ - [ 0, 8], - [ 25, 20], - [ 0, 32] -]; - - -/* ========================= - Basic modules - ========================= */ - -module base_import_scaled() -{ - scale([scale_xy, scale_xy, scale_z]) - import(input_stl, convexity = 10); -} - - -module vertical_hole(p, d) -{ - translate([p[0] * scale_xy, p[1] * scale_xy, 1]) - cylinder(h = cut_height, d = d, center = true, $fn = hole_fn); -} - - -module vent_cluster(p) -{ - // Small 2 x 3 vent/drain pattern. - // Pitch is in final millimetres, not original model coordinates. - pitch = 3.0; - - for (ix = [-1, 0, 1]) - for (iy = [0, 1]) - translate([ - p[0] * scale_xy + ix * pitch, - p[1] * scale_xy + iy * pitch, - 1 - ]) - cylinder(h = cut_height, d = vent_hole_d, center = true, $fn = hole_fn); -} - - -module pcb_standoff(p) -{ - // Standoff added on top of the flat STL. - // Use only if you confirm it does not block folding. - translate([p[0] * scale_xy, p[1] * scale_xy, 2.1 * scale_z]) - cylinder(h = pcb_standoff_h, d = pcb_standoff_d, center = false, $fn = hole_fn); -} - - -/* ========================= - Upper tetrahedron - ========================= */ - -module upper_part() -{ - difference() - { - base_import_scaled(); - - if (add_upper_cable_holes) - { - for (p = upper_cable_points) - vertical_hole(p, cable_hole_d); - } - - if (add_upper_hanger_hole) - { - for (p = upper_hanger_points) - vertical_hole(p, hanger_hole_d); - } - } -} - - -/* ========================= - Lower tetrahedron - ========================= */ - -module lower_part() -{ - difference() - { - union() - { - base_import_scaled(); - - if (add_lower_pcb_standoffs) - { - for (p = lower_pcb_mount_points) - pcb_standoff(p); - } - } - - if (add_lower_cable_holes) - { - for (p = lower_cable_points) - vertical_hole(p, cable_hole_d); - } - - if (add_lower_vent_holes) - { - for (p = lower_vent_centres) - vent_cluster(p); - } - - if (add_lower_pcb_mount_holes) - { - for (p = lower_pcb_mount_points) - vertical_hole(p, pcb_screw_hole_d); - } - } -} - - -/* ========================= - Output - ========================= */ - -if (PART == "upper") -{ - upper_part(); -} -else if (PART == "lower") -{ - lower_part(); -} -else if (PART == "both_preview") -{ - translate([-80, 0, 0]) - upper_part(); - - translate([80, 0, 0]) - lower_part(); -} -else -{ - echo("Invalid PART setting. Use upper, lower, or both_preview."); -} diff --git a/hardware/3D_Print-Designs/FireFly3DMechanical_v0.1.stl b/hardware/3D_Print-Designs/FireFly3DMechanical_v0.1.stl deleted file mode 100644 index a26b0dc61a143be58c39ad18b98c9cde475997c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5684 zcmbuDU1(fY5XX;&6cHs)5lUVJA=MBCo3;^c?tWPIK~nSJbD?0nBG_cHZTdl?S1~?_ z5JZVa#Wbm=6+x>Bq*QX74SlfEj|ZWIm;$ z|ID0^nVa6yp1$Xw$!&jVNB{0UFW+bW?^j7p5N4JOQ}gRgPo6%`UMaLK7;`hnBb5l4wwAq}(|Y#NR>clPC3PZO^Y@gWhv6MnNpiC_)1s`e_;Kmx7M!)lG$ zU`y+PZzK-M59V$22anJ5E^%=jS)C1d(V0Lij9e3kstAc3y{bus;+13<*G3cMP{>~K zP8_-TT>i!4A7x&T(Z$~UjmnxG`_FUyxihstiJ)B3*|=$+pcRkD#_lA90}>7U1nI%1 zrc6ua%SU33YNE_fs;##5eQ_*J)bQQXJY|XqIdYs=do>(L4!uM6S4ih8nG0#kbeafR zLlcP=t|r^)_4sJRv^{s2QI4<4%-GK@;i>d`$QrO$vO_HqI*ubxo}dQDWK5}s23v_& z=t+G7HPDJ9S6(@%(z%Ln2|SzL*yhVd9^Z*L@9D+fg%-a5jrkDA9nBJ z9>XkHTSdqkaNg*2#dPfz#QfmADX&5!PBa^*=ngft20`mhng56;wvJ4 zwG}6cma}k=nT#V(G~VzUTx-z^J=7ZesYZQ&@bV_^0MH8QjceOUtK{S8^Hq%rwBoU> zpe9)3+`-G=a$ka0m|aZ_ISpF}(F#4(#H$qfG0GKJPPUSh%9)nB#F205d^WDKqol!+qZP-r&YZA)qShE7;uG%`TA_!U7_5q1>NyfF^7#|4FWKj^ zyNTmKE7a3Oztb?hchSm^sWUcNO?ZuX1u0r<<@IcJ*2I1nx$XMU3N?J>Wr?FJ8l!VA z`${x0)0*H@OFebu`dvOBZq;x#HQ{%O?_QIgfgWn&@ak-|we`Rgz9WloHR}4Z($7&x zmQ{UXL>ZJmF}7kt-bFM)eWD`7if>V=uk{JE!h2T})aeJ(=~s71qCp*UPQ8Bw@-~4Q z7>6e4_6exd4}7N|M@v0C-5>7FOA~Y_2Gr@>Q;SyUVVdAI=k-7~~;1mqcDopjSZ9JI-Bb(7ZO& z57YZcLk(O5T$_3tdR|S_{}(Ry%M zi9EUc)&$Q()xh3SNE`Df-0k{C);EsO$(?xng^pRM26K3#^h~1BG1aaJJaz>% diff --git a/hardware/3D_Print-Designs/tetrahedron40mmC.stl b/hardware/3D_Print-Designs/tetrahedron40mmC.stl deleted file mode 100644 index 67d85f68170627b9db045f9e4e5261799eb557b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5684 zcma)AMZ)I&+s0inx-noe{B&t|%A$uDBA5(!-+!(3?e$-KpBX$b$L&7fZ++Lb zzHjxc?=C&_>T7+aEpPN~9_-s%>fKe^(Kpz?xwp5pwDij0;K0+%mk$jME%PszZQ1#H z>BV)=uJ2j3cC9IX2Iy6q?x~!uZ~CIeEa;Ng)yws%31be{@Z7U)SN3d?1m7T73iM1m zUX`DU1b{?!s1)mqb+nnJF;$-`U#M@Ye6n=mDOhrPa&i^xTfFA2iI@9t)cX71tr#;; zh$}+;CjB5Z6QpJZCAkFxJs(Oy%y?^Bz?{G(H@+ z(Qj^!BTp_LAdqwrEX6(*iLc&%VTBS}C2Unpv^gD#TBXtD+{6T`5LU@Qm5%ERyGBPo zm_R2i3lDyP&H#dJ&B%0W6X{=Zv>>lKGW2;t_HHNWOycW|E=^~LJx-k)?IGa|7NaN%3 zae8ux-FF;O_&47S*!NBr;vm>|CSa9Ts3k-ip9Fg_`z0ohmyIbk(E%y7iY-ADniH&p zrQmsFm9+^~f(OkMq%;TOUv~0YVSFXt^XwO1clU6|sYSj*Gs2$K_@C7@6L93 zF8jk)HP;wN0kZLq(tVJpiy4IH93Nh{V3pTnGnhq@={bq4MmaZoe_MUB7%N{Tq$A{G zP9m!-&PQ{?c^=k5G~Sic7Azj<;9#I zOfO#3D!NMEkK1V~=Y%ovoTc!r8H@?9<5TEhDUNPTwEI4YSg{oQ5feOLK}z>IBCUN1 zo}Za)&-!`NxGK?gy*5a>d<;CIbrpyfiLT5emS8FP)M{SJYBvy=mZTEP>bXj>g|St6 z&$XX3;XF@1c6Fs0gdZ%$R>edKG#Dw?U5-i2h zjfuO&kDFQl2vx!s#>C%gD!02$HjB?cR4;G%Xn@zj-vWiYfpY%X&!8=zZZsD%Ral=aP-hn4b`I&QU7TWsM zl(6?f)^{u2*#+H29r{aNhw3(FbmU&CE;l7ZiV2k>Yb77E_z~SwS)U^=f7^ZH)U5+g z@-G}8y!Ut9kiiOAt_HS*p6`qpqm^uQu{u6UH2d%jcWC?jQqOKKb)xoL2$n*J(`l(d zSOuy>r9kM^*POr<&Yjagi#4Wt>yNK7qg3%Mf7!?Rp%Vc2+5(X{Nd0iVmh}|~uO*4j zcJ2&^w%;SxeQqtxOp*ua2;Gv;;JFFy$b8PvN{rLZ#O|n2OMEf}yOILI)y}jsF~PMI zS0Y??e=&h|q#M{XifMQ5Ht!$tiKBGr9~bwIenw~e81Ja&XZxQ+M