2022-11-14 02:29:11 +00:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< title > sensor watch | jack bond-preston< / title >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "../../style/stylesheet.css" >
< link rel = "icon" type = "image/png" href = "data:image/png;base64,iVBORw0KGgo=" >
< style >
body {
padding: 0;
margin: 0;
min-height: 100vh;
}
.wrapper {
display: grid;
grid-template-columns: 30rem auto;
grid-template-rows: auto;
gap: 0;
min-height: 100vh;
}
2022-11-19 11:56:01 +00:00
.article {
padding: 5rem;
padding-bottom: 1rem;
}
2022-11-14 02:29:11 +00:00
.side {
background-image: url(images/f91w-strap.svg);
background-repeat: repeat-y;
}
.side > svg {
width: 30rem;
position: fixed;
}
@media only screen and (max-width: 1200px) {
.wrapper {
grid-template-columns: 10rem auto;
grid-template-rows: auto;
}
.side > svg {
width: 10rem;
}
.article {
padding-left: 1rem;
padding-right: 1rem;
padding-top: 1rem;
font-size: 1rem;
}
}
@media only screen and (max-width: 600px) {
.side {
display: none;
}
.wrapper {
grid-template-columns: auto;
grid-template-rows: auto;
}
.article {
padding: 10px;
font-size: 0.8rem;
}
}
< / style >
< / head >
< body >
< div class = "wrapper" >
< div class = "side" >
< svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 300 500" >
< defs >
< style > . c l s - 1 { f i l l : # 0 c 1 1 1 3 ; } . c l s - 2 { f i l l : n o n e ; s t r o k e : # f 6 b 4 c 1 ; s t r o k e - m i t e r l i m i t : 1 0 ; s t r o k e - w i d t h : 2 p x ; } . c l s - 3 { f i l l : # f 6 b 4 c 1 ; }
< / style >
< / defs >
< g id = "Layer_5" data-name = "Layer 5" >
< rect class = "cls-1" width = "300" height = "500" / >
< / g >
< g id = "Layer_1" data-name = "Layer 1" >
< path class = "cls-2" d = "M150,335.07c-21-.18-53.88.56-76.78-1-1.15.37-6.4-1.85-7.11-3.33-11.43-13.68-14.6-19.62-14.67-31.33-1-13-1.27-26.4-2-49.34" / >
< path class = "cls-2" d = "M150,329.83c-20.3-.19-49.15.57-71.32-1-1.12.37-7.19-1.87-7.89-3.38-11.06-13.86-13.12-19.87-13.19-31.74-.92-13.2-1-20.39-1.73-43.63" / >
< path class = "cls-2" d = "M150,352.07S59.42,351,58.31,350.52s-20.67-32.89-21.11-34-2.89-66.45-2.89-66.45" / >
< path class = "cls-2" d = "M150,364.3s-93.23-1-94.34-1.42S28.31,318.3,27.86,317.19s-2.65-67.12-2.65-67.12" / >
< polyline class = "cls-2" points = "27.68 315.07 20.48 310.24 17.14 264.91 25.21 257.91" / >
< path class = "cls-2" d = "M150,335.07c21-.18,53.87.56,76.78-1,1.15.37,6.39-1.85,7.11-3.33,11.43-13.68,14.6-19.62,14.67-31.33.94-13,1.26-26.4,2-49.34" / >
< path class = "cls-2" d = "M150,329.83c20.29-.19,49.15.57,71.32-1,1.11.37,7.19-1.87,7.88-3.38,11.06-13.86,13.13-19.87,13.2-31.74.91-13.2,1-20.39,1.73-43.63" / >
< path class = "cls-2" d = "M150,352.07s90.56-1.11,91.67-1.55,20.66-32.89,21.11-34,2.89-66.45,2.89-66.45" / >
< path class = "cls-2" d = "M150,364.3s93.22-1,94.33-1.42,27.34-44.58,27.78-45.69,2.65-67.12,2.65-67.12" / >
< polyline class = "cls-2" points = "272.29 315.07 279.5 310.24 282.83 264.91 274.76 257.91" / >
< path class = "cls-2" d = "M150,165c-21,.19-53.88-.56-76.78,1-1.15-.36-6.4,1.85-7.11,3.33C54.66,183,51.49,189,51.42,200.67c-1,13-1.27,26.39-2,49.33" / >
< path class = "cls-2" d = "M150,170.24c-20.3.19-49.15-.56-71.32,1-1.12-.36-7.19,1.88-7.89,3.38-11.06,13.86-13.12,19.88-13.19,31.74-.92,13.21-1,20.39-1.73,43.63" / >
< path class = "cls-2" d = "M150,148s-90.56,1.11-91.67,1.56-20.67,32.88-21.11,34S34.31,250,34.31,250" / >
< path class = "cls-2" d = "M150,135.78s-93.23,1-94.34,1.41-27.33,44.59-27.78,45.7S25.21,250,25.21,250" / >
< polyline class = "cls-2" points = "27.68 185 20.48 189.83 17.14 235.17 25.21 242.17" / >
< path class = "cls-2" d = "M150,165c21,.19,53.87-.56,76.78,1,1.15-.36,6.39,1.85,7.11,3.33,11.43,13.69,14.6,19.62,14.67,31.34.94,13,1.26,26.39,2,49.33" / >
< path class = "cls-2" d = "M150,170.24c20.29.19,49.15-.56,71.32,1,1.11-.36,7.19,1.88,7.88,3.38,11.06,13.86,13.13,19.88,13.2,31.74.91,13.21,1,20.39,1.73,43.63" / >
< path class = "cls-2" d = "M150,148s90.56,1.11,91.67,1.56,20.66,32.88,21.11,34S265.67,250,265.67,250" / >
< path class = "cls-2" d = "M150,135.78s93.22,1,94.33,1.41,27.34,44.59,27.78,45.7S274.76,250,274.76,250" / >
< polyline class = "cls-2" points = "272.29 185 279.5 189.83 282.83 235.17 274.76 242.17" / >
< / g >
< g id = "Layer_3" data-name = "Layer 3" >
< path class = "cls-2" d = "M224.67,250c-.35,3.5,1,31.12-1.07,33.66-1.35,4.06-5.75,5.94-9.78,5.9H86.51c-4,0-8.43-1.84-9.77-5.9-2-2.3-.74-30.41-1.07-33.66.35-3.58-.92-20.74,1.07-23.77,1.34-4.06,5.75-5.95,9.77-5.9H213.82c4,0,8.43,1.84,9.78,5.9C225.57,229.27,224.35,246.4,224.67,250Z" id = "screen" / >
< path class = "cls-2" d = "M229.33,247.11c-.36,4.09,1,36.37-1.13,39.33-1.43,4.75-6.09,6.95-10.35,6.89H83c-4.26.06-8.92-2.14-10.35-6.89-2.13-2.69-.78-35.53-1.13-39.33.37-4.19-1-24.23,1.13-27.77,1.43-4.75,6.09-7,10.35-6.89H217.85c4.26-.06,8.92,2.14,10.35,6.89C230.28,222.89,229,242.91,229.33,247.11Z" / >
< g id = "CASIO" >
< path class = "cls-2" d = "M97.31,181.28a3.36,3.36,0,0,0-.2-1.34,1.91,1.91,0,0,0-.44-.63,3.49,3.49,0,0,0-1.28-.31c-.36-.06-1.72-.14-2.14-.14a20.79,20.79,0,0,0-3.11.17c-.14.14-.72.28-.89.5a2.43,2.43,0,0,0-.47,1.16v1.78c0,.47-.06,1.84,0,2a2.64,2.64,0,0,0,.53,1.06,3,3,0,0,0,1.22.44,23.26,23.26,0,0,0,2.8.09,23.2,23.2,0,0,0,2.42,0,1.9,1.9,0,0,0,1.06-.41,1.32,1.32,0,0,0,.5-1.05,4.25,4.25,0,0,1,0-.78" / >
< path class = "cls-2" d = "M100,186.71c0-1.13,3.1-5.88,3.69-7.25a1.45,1.45,0,0,1,.23-.47c.17-.16.35-.14.93-.13s.64,0,.73.16c.75,1.48,2.61,5.22,3,5.9a4.31,4.31,0,0,1,.79,1.79" / >
< line class = "cls-2" x1 = "101.07" y1 = "184.13" x2 = "108.15" y2 = "184.13" / >
< path class = "cls-2" d = "M120,180.36c.15-2.21-2.17-1.64-4.08-1.67-1,0-2.47,0-2.75.36-1.37,1-1.23,3.06.74,3.41,1.57.31,4.21-.33,5.5.07,1.56.79,1.58,3.44-.5,3.55-1.56-.08-6.23.93-6.63-1.5" / >
< path class = "cls-2" d = "M123.92,177.83s.14,6.61,0,9.13" / >
< path class = "cls-2" d = "M128.06,182.59a6.3,6.3,0,0,0,.11,2.08c.25.5.86,1.35,1.52,1.4s3.31,0,3.31,0a25.08,25.08,0,0,0,2.61,0c.28-.1.92-.1,1.06-.68s.3-.66.27-1.26-.08-2.19-.08-2.19a13.37,13.37,0,0,0,0-1.92,1.37,1.37,0,0,0-.59-.92,14.78,14.78,0,0,0-1.53-.39H132a12.52,12.52,0,0,0-2.3,0c-.28.14-.95.19-1.17.5a2.33,2.33,0,0,0-.41,1.19C128.11,180.79,128.06,182.59,128.06,182.59Z" / >
< / g >
< g id = "F-91W" >
< path class = "cls-2" d = "M167.94,186.22a18.32,18.32,0,0,1,.64-2.94s.56-2.79.64-2.95a45.6,45.6,0,0,1,5.34,0" / >
< path class = "cls-2" d = "M173.06,183.28c-.92-.11-4.48,0-4.48,0" / >
< path class = "cls-2" d = "M176.69,183.85c2,.15,3-.31,5.25,0" / >
< path class = "cls-2" d = "M186.39,184.94c.84,1.58,3.78.91,4.83,0,1.69-2.54,1.8-4.89-2-4.55-6.28,1.92,2.2,5.1,3.06,1.13" / >
< path class = "cls-2" d = "M197.39,186.83c.09-1.6.57-2.3.92-4.25a13.46,13.46,0,0,0,.63-2.83c.09,2.21-2,2-3.58,1.92" / >
< path class = "cls-2" d = "M204.08,179.75s0,3.52.06,4,.12,1.9.12,1.9h1.16s1.52-2.69,1.86-3.44a4.41,4.41,0,0,1,.52-1l.32-.59,1.25,0s0,.21,0,.93-.09,3.95-.09,3.95h1.35l.41-.68c.27-.46,2.39-3.53,2.39-5.11" / >
< / g >
< path class = "cls-2" d = "M18.29,211.06H10.53s-1.46-.81-1.46,8.11c0,8.42,2.17,7.78,2.17,7.78h6.34" onmouseover = "document.getElementById('screen').style.fill='blue';" onmouseleave = "document.getElementById('screen').style.fill='none';" / >
< path class = "cls-2" d = "M18.29,288.94H10.53s-1.46.81-1.46-8.11c0-8.42,2.17-7.78,2.17-7.78h6.34" / >
< path class = "cls-2" d = "M281.71,288.94h7.76s1.46.81,1.46-8.11c0-8.42-2.17-7.78-2.17-7.78h-6.34" / >
< / g >
< g id = "Layer_4" data-name = "Layer 4" >
< path class = "cls-2" d = "M150,306.44H125.88c-1.36,0-2,.2-2.44.84-.28.44-.28.44-.56,1.94a24.24,24.24,0,0,0,0,6.59,9.45,9.45,0,0,0,2.39,4.66c1.22,1,3.81,3.56,5.47,3.61s19.25,0,19.25,0" / >
< polygon class = "cls-3" points = "63.43 307.26 118.99 307.26 118.99 309.26 63.91 309.26 63.43 307.26" / >
< polyline class = "cls-2" points = "149.99 110.44 63.43 110.44 55.66 137.19" / >
< polygon class = "cls-3" points = "62.63 195.75 149.99 195.75 149.99 193.75 63.11 193.75 62.63 195.75" / >
< line class = "cls-2" x1 = "65.99" y1 = "110.44" x2 = "65.99" / >
< line class = "cls-2" x1 = "65.99" y1 = "389.42" x2 = "65.99" y2 = "500" / >
< polyline class = "cls-2" points = "149.99 389.42 63.43 389.42 55.66 362.67" / >
< path class = "cls-2" d = "M150,306.44h24.11c1.36,0,2,.2,2.45.84.27.44.27.44.55,1.94a24.24,24.24,0,0,1,0,6.59,9.45,9.45,0,0,1-2.39,4.66c-1.22,1-3.8,3.56-5.47,3.61s-19.25,0-19.25,0" / >
< polygon class = "cls-3" points = "236.56 307.26 181 307.26 181 309.26 236.08 309.26 236.56 307.26" / >
< polyline class = "cls-2" points = "150 110.44 236.56 110.44 244.33 137.19" / >
< polygon class = "cls-3" points = "237.36 195.75 150 195.75 150 193.75 236.89 193.75 237.36 195.75" / >
< line class = "cls-2" x1 = "234" y1 = "110.44" x2 = "234" / >
< line class = "cls-2" x1 = "234" y1 = "389.42" x2 = "234" y2 = "500" / >
< polyline class = "cls-2" points = "150 389.42 236.56 389.42 244.33 362.67" / >
< / g >
< / svg >
< / div >
< div class = "content" >
< div class = "article" >
<!-- article body { -->
< h1 id = "title" > < a href = "." > sensor watch< / a > < / h1 >
< h2 id = "premable" > < a href = "#preamble" > preamble< / a > < / h2 >
< p >
some time back I was browsing < a href = "https://www.crowdsupply.com/" > Crowd Supply< / a > when I came
across < a href = "https://www.crowdsupply.com/oddly-specific-objects/sensor-watch" > the Sensor
2022-11-14 03:13:58 +00:00
Watch project< / a > by < a href = "https://github.com/joeycastillo" > Joey Castillo< / a > . I had wanted some
kind of "hackable" watch for a while, and had looked at things like
< a href = "https://www.crowdsupply.com/sqfmi/watchy" > Watchy< / a > , but this project hit the sweet spot
for me. I love my existing F91-W, and this project was a good combination of open source with
community software support. one key feature that was important to me is battery life - the Sensor
Watch battery life in an average usage scenario is so long that
2022-11-14 02:29:11 +00:00
< a href = "https://twitter.com/josecastillo/status/1590066358351298560" > Joey's is still going
strong< / a > !
< / p >
< p >
I was excited to pick one up and start messing around with it, but the first issue I came across
was availability - the delivery date for Crowd Supply orders was summer 2023 (I think they ended up
being delivered sooner than this, not sure). on top of this, shipping and import fees made it
pretty prohibitively expensive. I've always found this to be an issue with Crowd Supply as someone
based in the UK, even some things designed in the UK are very expensive from Crowd Supply as they
2022-11-14 03:13:58 +00:00
are assembled in/shipped from the US. so I decided to build one myself! of course, this is more
expensive than just buying it, but this was a learning experience and < a href = "https://www.reddit.com/r/AskReddit/comments/dxosj/what_word_or_phrase_did_you_totally_misunderstand/c13pbyc/" >
knowledge is power< / a > !
2022-11-14 02:29:11 +00:00
< / p >
< h2 id = "component-acquisition" > < a href = "#component-acquisition" > component acquisition< / a > < / h2 >
< p >
the first challenge was acquiring all the necessary parts to actually build one. I downloaded
< a href = "https://github.com/joeycastillo/Sensor-Watch/tree/main/PCB/Main%20Boards" > the PCB files< / a >
and generated a < a href = "https://en.wikipedia.org/wiki/Bill_of_materials" > BOM< / a > to figure
out exactly what I needed to acquire. I'm sure in ordinary times this would be easy enough, but the
current state of some electronics/silicon supply chains had other things to say. some parts are of
course still easy to come across, e.g. 10pF 0402 caps and 10k 0603 resistors; most of the
components of the Sensor Watch are this kind of commonplace part. what quickly became clear from
some scouring of the internet was that my main problem was going to be two parts: the
< a href = "https://www.microchip.com/en-us/product/ATSAML22J18A" > ATSAML22J18A-MUT< / a > (the processor
driving the Sensor Watch), and the < a href = "https://www.hirose.com/en/product/series/FH19C__FH19SC" >
FH19C-9S-0.5SH(10)< / a > (the connector used to attach the extra sensor boards).
< / p >
< h3 > ATSAML22J18A-MUT< / h3 >
< p >
the former of these was a fairly well discussed shortage that had been ongoing for a while. it was
< a href = "https://www.crowdsupply.com/oddly-specific-objects/sensor-watch/updates/blue-boards-shipping-check-your-address-green-boards-delayed-and-other-news-of-the-watch" >
the driving force of the Sensor Watch Crowd Supply delay< / a > . I spent quite a lot of time searching
around the internet, looking at various sites on the English-speaking and Chinese-speaking web.
sadly this part was clearly in very short supply, and prices could get pretty insane from vendors
that did have some stock. I received quotes for unit prices that include the following (USD/GBP):
$79.35, $6.56, $13.61, $6.83 (MOQ 4000), £6.45. I guess some people are desperate enough to pay
$79.35 :(. I spent so long looking for them that they ended up randomly coming back in stock on
< a href = "https://www.microchipdirect.com/" > MicrochipDirect< / a > . as of the time of writing this
article,
< a href = "https://www.microchipdirect.com/product/ATSAML22J18A-MUT" > they are again out of stock< / a > .
the unit price I bought them for was £3.92, shipping and handling was ~£12.
< / p >
< h3 > FH19C-9S-0.5SH(10)< / h3 >
< p >
this part was out of stock everywhere I initially looked (the usual contenders for parts). I
searched around in a similar manner as the ATSAML22J18A-MUT, and found some similarly wild pricing.
I ended up purchasing a small quantity at a unit price of £0.44 from a website called
< a href = "http://archive.today/2022.11.13-230943/https://www.dacikeys.net/" > dacikeys< / a > . yes, the
site is actually called this. yes, the unit price is cheaper than digikey and mouser. yes, I
actually received all of my order, consisting of working parts. I was definitely shocked that this
happened, but sometimes bravery pays off I guess. I still can't endorse this shop.
< / p >
< h3 > PCB and stencil< / h3 >
< p >
for the PCB I opted to go with < a href = "https://jlcpcb.com/" > JLCPCB< / a > . I simply uploaded the
relevant gerbers, and adjusted the necessary settings. notably,
< a href = "https://github.com/joeycastillo/Sensor-Watch/issues/14#issuecomment-922974276" > < / a > the
thickness should be 0.6mm< / a > - this does narrow the choice of manufacturer (for example, OSH Park
doesn't go this thin). I haven't yet ordered any sensor board PCBs, but
< a href = "https://www.pcbway.com/" > PCBWay< / a > seems to be < i > the< / i > option there. The PCB turned
out great, although the silkscreen is a little hard to read at this size due to lack of sharpness:
< img src = "images/pcb.jpg" / >
< / p >
< h2 id = "assembly" > < a href = "#assembly" > assembly< / a > < / h2 >
< p >
I decided to assemble myself. partially because the logistics of paying for assembly when I had to
source parts from many different providers seemed like a headache, partially because I thought it
would be a fun challenge and learning experience!
< / p >
< p >
a few things were necessary to solder the components to this PCB. I'm sure someone talented could
hand solder this with an iron, but I can name a lot of things I'd rather do than try to do that
(especially the < a href = "https://en.wikipedia.org/wiki/Flat_no-leads_package" > QFN< / a > SAML) - and
that list includes unpleasant things. I opted to go with
< a href = "http://www.flyelectric.org.uk/hot_plate.htm" > hotplate soldering< / a > , which is a cheaper
way to access the ease of reflow soldering. for a PCB like the Sensor Watch, where almost all the
components are on one side, it's ideal. the hotplate I have is the ever-popular
< a href = "https://www.miniware.com.cn/product/mhp30-mini-hot-plate-preheater/" > MHP30< / a > , which I
run < a href = "https://github.com/Ralim/IronOS" > IronOS< / a > on. I highly recommend it, it's great! my
soldering iron is the iconic
< a href = "https://pine64.com/product/pinecil-smart-mini-portable-soldering-iron/" > Pinecil< / a > (not
the < a href = "https://www.pine64.org/2022/07/28/july-update-a-pinecil-evolved/" > fancy new V2< / a >
though :[) which also runs IronOS. nice!
< / p >
< h3 > process< / h3 >
< p >
the assembly process is as follows:
< ul >
< li >
apply solder paste to the PCB with the stencil. make sure the stencil is really flush and just
kind of squeegee it on with a plastic card. I used tape to hold it in place. then carefully
removed the stencil, avoiding smudging the paste in doing so.
< / li >
< li >
place components on the PCB. this was by far the most painful part of the whole process. a
steady hand is not something I was blessed with, and some of these parts are really small. I used a
microscope from Amazon for this, the ample manouverable lighting was a big help. a lot of time and
patience is required, but it's very first time doable with no prior experience! simply go through
the parts one by one, or by area of the board - whatever you prefer. then pick up the respective
part with some fine tweezers, and slowly put in place on the solder paste. thankfully, the paste
will lightly stick the component in place once you've done this (it is not knock-proof though!).
< / li >
< li >
carefully (really!) place the PCB onto the hotplate and heat up. keep on until everything seems
to be melted, and the components have hopefully been pulled into place. that's the top side done!
let it cool down, then move on to the bottom.
< / li >
< li >
time for some hand soldering. the button is pretty small, and very fiddly to do. I found you don't
need too much precision, but you have to be really careful with your iron as the plastic button
will melt if you touch it. once that's in place, it's just a matter of
< a href = "https://youtu.be/Zr0pKeC2VFU?t=185" > removing the buzzer connector from your old PCB and
soldering it onto the back of the Sensor Watch PCB.< / a > this will feel blissfully easy after the
button! you also have to place the battery clip, but no soldering needed here :).
< / li >
< / ul >
< / p >
< p >
one area I found particularly difficult was the area with the oscillator crystal and the two 0402
capacitors, C7 and C8. things are a bit cramped here, so extra care was needed:
< img src = "images/c7c8.jpg" / >
< / p >
< h2 id = "software" > < a href = "#software" > software< / a > < / h2 >
< p >
at this point the watch was assembled with all components in place. did it work? at this stage, no
idea. hopefully yes, and I could progress to the more familiar world of embedded software.
< / p >
< h3 > bootloader< / h3 >
< p >
the next necessary step is to flash the bootloader, so that we can put the firmware in place.
unfortunately this requires a little more real-world action. we need to access the SWD points on
the board to write the bootloader. ideally you could do this with some kind of
< a href = "https://en.wikipedia.org/wiki/Pogo_pin" > pogo pin< / a > jig - and if you were doing any
number exceeding about 5 I'm sure this would be worth the time. however, I decided to just solder
some jump wires (stripped on one end, solid tip female on the other) to the points on the board.
they're all close, but it's easy enough to do (albeit ugly). then I connected these to my
< a href = "https://www.adafruit.com/product/1501" > Adafruit Trinket M0< / a > (PyRuler would also work).
the pin mapping is as follows: SWD=0, SWC=1, RST=3, V+=3V, GND=GND.
< / p >
< p >
I used the
< a href = "https://github.com/joeycastillo/Sensor-Watch/blob/main/utils/flash_watch_pyruler/flash_watch_pyruler.ino" >
flasher from the sensor watch repo to flash the bootloader< / a > . note that you could build the
bootloader yourself first and put the generated binary into bootloader.h - the source is located
< a href = "https://github.com/joeycastillo/uf2-samdx1" > here< / a > . personally, I just used the prebuilt
version from the repo. I had to change part of the Adafruit DAP library and add the SAM L22 DID to
get this to work,
< a href = "https://github.com/joeycastillo/Sensor-Watch/issues/83#issuecomment-1229353899" > I provided
the diff of this change< / a > in a Sensor Watch GitHub issue (I just now am remembering I promised to
upstream this, oops!). mercifully, I got the red blinky LED, and all was good! I unsoldered the
wires from the board, and tried to clean up most of the solder blob to keep the board fairly flat.
< / p >
< h3 > movement< / h3 >
< p >
now the bootloader is in place, the main firmware can be installed!
< a href = "https://www.sensorwatch.net/docs/movement/" > the community firmware, Movement< / a > is great,
so this is what I installed. there are a bunch of different useful faces available, and more
functionality is always being added.
< / p >
< p >
flashing firmware was easy: I plugged the PCB into the end of a USB Micro B cable (plugged on the
other end into my computer) and double tapped the reset button (I find this has to be done quite
quickly, using my fingernail was the trick to doing this reliably on such a small button). done
successfully, the LED on the board pulses and a new drive labelled "WATCHBOOT" appears on the
computer. now a built UF2 firmware file can just be dragged onto the device to flash, thanks to the
bootloader flashed earlier. for the initial test, I just used a
< a href = "https://www.sensorwatch.net/docs/firmware/prebuilt/" > prebuilt image< / a > to check
everything was working. I flashed this, and the LED pulsed and turned off, signalling success.
< / p >
< p >
from here I just assembled the watch with the Sensor Watch PCB, and it worked! I verified LED and
buzzer function by playing around with various functionality. success!
< / p >
< h2 id = "developing-movement" > < a href = "#developing-movement" > developing on movement< / a > < / h2 >
< p >
one face I found particularly cool was the < a href = "https://github.com/joeycastillo/Sensor-Watch/blob/main/movement/watch_faces/complication/totp_face.c" >
TOTP face< / a > . I use < a href = "https://en.wikipedia.org/wiki/Time-based_one-time_password" > TOTP< / a >
< a href = "https://en.wikipedia.org/wiki/Multi-factor_authentication" > 2FA< / a > on various accounts, so
having access to the codes on my wrist at all times was really appealing. at the time, the TOTP
face only supported one key - so I decided to improve it.
< / p >
< p >
thankfully, Sensor Watch has an emulator for development. without this, development would be pretty
tiresome with the flashing and reassembling of the watch getting tiring if you needed to iterate on
some code and test it on the watch. the emulator runs inside the browser and uses
< a href = "https://en.wikipedia.org/wiki/Emscripten" > Emscripten< / a > .
< a href = "https://github.com/joeycastillo/Sensor-Watch#using-the-movement-framework" > some minimal
instructions on how to build this is available on the README< / a > . this allowed me to extend the
TOTP face easily and allow for multiple keys.
< a href = "https://github.com/joeycastillo/Sensor-Watch/pull/84" > my PR was merged< / a > , and the
functionality is now available for anyone to use. the keys are added at compile time, so they are
baked into the firmware on flashing. for my purposes this is fine, as I never really change them.
however, with the recent addition of a
< a href = "https://os.mbed.com/blog/entry/littlefs-high-integrity-embedded-fs/" > LittleFS< / a >
filesystem, the community have added < a href = "https://github.com/joeycastillo/Sensor-Watch/blob/main/movement/watch_faces/complication/totp_face_lfs.c" >
a version of the face which stores the keys on the filesystem< / a > . awesome!
< / p >
< p >
some more details on using Sensor Watch for TOTP is available
< a href = "https://blog.singleton.io/posts/2022-10-17-otp-on-wrist/" > on this blog post< / a >
(< a href = "https://news.ycombinator.com/item?id=33243434" > HN discussion, if you dare< / a > ). it's even
running my code :)!
< / p >
< h2 id = "epilogue" > < a href = "#epilogue" > epilogue< / a > < / h2 >
< p >
some summary thoughts:
< ul >
< li >
shoutout to Joey Castillo. for creating the Sensor Watch as a beautifully open source project (the
fact I could independently make my own is what it's all about!). for being
< a href = "https://github.com/joeycastillo/Sensor-Watch/issues/83" > so helpful and kind< / a > when I
asked for help. for having such a positive attitude towards those in the community who are using
Sensor Watch to learn about all kinds of things (seriously, check out the
< a href = "https://discord.gg/NtMVTBNca7" > Oddly Specific Objects Discord< / a > to see how much this guy
is giving to the community).
< / li >
< li >
sometimes it's worth just trying things that are difficult. this is my first time successfully
doing and small-scale soldering of this kind, and it worked out great with some patience. having
the motivation from making something I thought was really cool was an important factor here I think.
< / li >
< li >
if you have a Sensor Watch (or are planning to!) please go ahead and < a href = "https://github.com/joeycastillo/Sensor-Watch" >
contribute to movement< / a > if you have a cool idea. I'm sure some reviews would be helpful to spot
any issues on existing PRs before a maintainer gets to them to save some time.
< / li >
< li >
the one issue I've had with using my Sensor Watch for TOTP is clock accuracy. the clock drifts over
time, so I have to set the time once or twice a week to keep it nice and accurate for the TOTP
functionality to be nice to use. but a community member is working on this, and it's going to get a
lot better. check out the Discord channel to see some seriously cool engineering going into this
calibration effort.
< / li >
< / ul >
< / p >
2022-11-14 03:13:58 +00:00
< p >
< img src = "images/watch1.jpg" / >
< img src = "images/watch2.jpg" / >
< img src = "images/wrist.jpg" / >
< / p >
2022-11-14 02:29:11 +00:00
< br / >
< br / >
< p >
< a href = "mailto:jackbondpreston@outlook.com" > email me< / a > to have a conversation
< / p >
<!-- } -->
< / div >
< / div >
< / div >
< / body >
< / html >