
    
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
            
{"version":"https:\/\/jsonfeed.org\/version\/1","title":"cooper-davis.net posts","home_page_url":"https:\/\/cooper-davis.net\/blog","feed_url":"https:\/\/cooper-davis.net\/blog.json","description":"When Ari stumbles across something that might be of interest to others he posts about it on his website. This RSS feed is updated whenever he posts something new!","author":{"name":"Ari Cooper-Davis"},"items":[{"title":"Flushing with rainwater: choosing your butt","date_published":"2026-07-21T11:04:00+01:00","id":"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-choosing-your-butt","url":"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-choosing-your-butt","content_html":"<div class=\"notices blue\">\n<p>This is the third post in a series about plumbing my toilet to flush with harvested rainwater (here are <a href=\"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-regulations-airgaps\">the first<\/a> and <a href=\"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-system-reliability\">the second<\/a>). This one is a bit of a deep-dive into how you choose the ideal water-butt for a rainwater harvesting system.<\/p>\n<\/div>\n<h2>Practical considerations<\/h2>\n<p>Now I am very lucky as I already have a perfectly suitable water-butt on the downpipe at the front of my garage. To reduce my environmental impact as much as possible I'm going to use the one I've already got, but if I had to buy one specifically for this purpose I'd be looking for one that is:<\/p>\n<ul>\n<li>Large: for maximum rainwater storage;<\/li>\n<li>Tall: for maximum hydraulic head to minimise the effort that the pump has to put in to raise water to the loft tank;<\/li>\n<li>Plain: textured \"wood effect\" faces can make it harder to add bulkheads if you need to add an outlet, as the ridges can prevent them from sealing property;<\/li>\n<li>Attractive: or at least, not unattractive; and<\/li>\n<li>Cleanable: having a threaded outlet at the very bottom of the tank makes it much easier to clean out the butt-sludge (there go all my readers with Safe Search on!) that otherwise can build up and clog up your pump or discolour your water.<\/li>\n<\/ul>\n<p>I quite like the water-butts that Graf \/ Garantia make - they tend to be high volume and reasonably practical. That being said they are intended for the European market, so the taps provided with them are much bigger than you see on the UK market, which makes it quite hard to find compatible hoses. The threads are 3\/4\" BSP female though, which suits us fine. Here are some examples of theirs:<\/p>\n<p><img title=\"Marketing photos for three different Graf water-butts\" alt=\"graf-water-butts\" src=\"\/user\/pages\/05.blog\/flushing-with-rainwater-choosing-your-butt\/graf-water-butts.webp\"><\/p>\n<p>From left to right the above water-butts are <span class=\"mathjax mathjax--inline\">\\(400 \\text{l}\\)<\/span>, <span class=\"mathjax mathjax--inline\">\\(1,300 \\text{l}\\)<\/span> , and <span class=\"mathjax mathjax--inline\">\\(500 \\text{l}\\)<\/span>. Which brings me onto...<\/p>\n<h2>Choosing the volume<\/h2>\n<p>Obviously the bigger the water-butt the less likely it is to run out, but at some point your water-butt will be so large that it'll be very unlikely to ever fill, at which point that extra volume is just an eyesore and not actually giving you any meaningful functionality. So how do we work out where this point is?<\/p>\n<h3>Empirical methods<\/h3>\n<p>BS 8515 (Rainwater harvesting systems: Code of practice) has an easy and boring method called the \"intermediate approach\" which says:<\/p>\n<blockquote>\n<p>storage capacity should be [...] the lesser of <span class=\"mathjax mathjax--inline\">\\(5 \\%\\)<\/span> of the annual rainwater yield or <span class=\"mathjax mathjax--inline\">\\(5 \\%\\)<\/span> of the annual non-potable water demand<\/p>\n<\/blockquote>\n<h4>How much water runs off your roof?<\/h4>\n<p>The amount of water that ends up in your water butt when it rains is:<\/p>\n<p class=\"mathjax mathjax--block\">\\[\n    \\text{runoff volume} = \\text{catchment area} \\times \\text{rainfall depth} \\times (1 - \\text{loss factor})\\]<\/p>\n<p>This is heavily simplified - for example rain doesn't fall down vertically, it is carried by the wind, so a pitched roof facing the prevailing wind will capture a larger volume of rainfall than one facing away from it, and downpipe diverters become less efficient at higher downpipe discharge rates...<\/p>","image":"\/user\/pages\/05.blog\/flushing-with-rainwater-choosing-your-butt\/Screen Shot 2026-07-21 at 18.08.23.png"},{"title":"Flushing with rainwater: system reliability","date_published":"2026-07-20T12:32:00+01:00","id":"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-system-reliability","url":"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-system-reliability","content_html":"<div class=\"notices blue\">\n<p>This is the second post in a series about plumbing my toilet to flush with harvested rainwater (<a href=\"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-regulations-airgaps\">here's the first<\/a>). This one is about how we design our system to ensure a reliable supply of water to our toilet cistern, to minimise the likelihood of failure, and to facilitate use. Read on to find out how...<\/p>\n<\/div>\n<p><a href=\"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-regulations-airgaps\">Last time<\/a>, in the post introducing my desire to be able to flush my toilet with harvested rainwater, I pinned down some objectives for my system, and boldly claimed that an \"indirect system\" was the best way to achieve them. Let's design out what such a system would actually look like in practical terms.<\/p>\n<h2>Specifications<\/h2>\n<p>I would like my system to:<\/p>\n<ul>\n<li>refill the cistern with rainwater when available;<\/li>\n<li>when no rainwater is available, refill with potable water;<\/li>\n<li>allow the toilet to be flushed even when there's a power cut;<\/li>\n<li>fail \"safe\" so that I don't flood my house or start a fire;<\/li>\n<li>easily disable the system in the event of a failure; and perhaps most importantly<\/li>\n<li>prevent backflow of rainwater into the potable water system.<\/li>\n<\/ul>\n<p>We can achieve almost all of these objectives with a simple header tank.<\/p>\n<h2>Header tank<\/h2>\n<p>A header tank, or loft tank, is a volume of water that sits high up in your house (usually in the loft) so that it can provide a reliable supply of water at a consistent pressure to feed your appliances. The pressure comes from the hydraulic head of the tank - as it's higher than your appliances gravity pulls water down into them.<\/p>\n<p><img title=\"Header%20tank\" alt=\"Header%20tank\" src=\"\/user\/pages\/05.blog\/flushing-with-rainwater-system-reliability\/Header%20tank.webp\"><\/p>\n<p>The header tank is supplied by the mains via a top-up valve, which opens when the water-level in the tank drops, and closes again once the water has filled back up to a set level. This refilling happens even in the event of a power-cut, as mains water is supplied under enough pressure to get it up to my loft.<\/p>\n<p>Top-up valves are usually simple ball valves, but as discussed last time we need an air-gap to prevent backflow from contaminating the potable supply, so we require something like a <a href=\"https:\/\/www.freeflush.co.uk\/products\/rainaid-ra20-mains-backup-rainwater-harvesting-water-butt-valve\">RainAid<\/a> instead.<\/p>\n<p>A warning pipe acts as an overflow, so if our valve fails we won't flood our house - the excess will be routed outside where we'll see it coming out of the pipe and go and fix it.<\/p>\n<p>This simple system checks off nearly all of our objectives:<\/p>\n<ul>\n<li>refill the cistern with rainwater when available; &#10060;<\/li>\n<li>when no rainwater is available, refill with potable water; &#9989;<\/li>\n<li>allow the toilet to be flushed even when there's a power cut; &#9989;<\/li>\n<li>fail \"safe\" so that I don't flood my house or start a fire; &#9989;<\/li>\n<li>easily disable the system in the event of a failure; and perhaps most importantly &#9989;<\/li>\n<li>prevent backflow of rainwater into the potable water system. &#9989;<\/li>\n<\/ul>\n<p>The only thing missing is using rainwater to fill the loft tank when it's available.<\/p>\n<h2>\"Dumb\" rainwater harvesting<\/h2>\n<p>To fill our header tank with harvested rainwater we can...<\/p>","image":"\/user\/pages\/05.blog\/flushing-with-rainwater-system-reliability\/Smart rainwater harvesting.webp"},{"title":"Flushing with rainwater: regulation and air-gaps","date_published":"2026-06-01T13:15:00+01:00","id":"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-regulations-airgaps","url":"https:\/\/cooper-davis.net\/blog\/flushing-with-rainwater-regulations-airgaps","content_html":"<div class=\"notices blue\">\n<p>This is the first post in a series about plumbing my toilet to flush with harvested rainwater. This post is about how wanting a mains back-up will necessitate complying with strict legislation, including ensuring the potable supply is air-gapped. Read on to learn what on earth that means...<\/p>\n<\/div>\n<p>My job is all about managing surface water (i.e. rainwater) better. Done properly, surface water management builds resilience to drought and heavy rainfall, protects the environment, reduces water treatment costs, adds system redundancy etc.<\/p>\n<h2>Surface water management<\/h2>\n<p>When we think about managing surface water we choose our interventions based on a priority pyramid:<\/p>\n<canvas id=\"target_7e9a494fd414a66de16052ff7ed64e83\"><\/canvas><script id=\"nomnoml_7e9a494fd414a66de16052ff7ed64e83\" type=\"text\/plain\">\n[<sender> Reuse]\n[<transceiver> Disconnect]\n[<receiver> Attenuate]\n<\/script><script>window.addEventListener(\"load\", function(){var canvas = document.getElementById(\"target_7e9a494fd414a66de16052ff7ed64e83\");var source_7e9a494fd414a66de16052ff7ed64e83 = document.getElementById(\"nomnoml_7e9a494fd414a66de16052ff7ed64e83\");var source_7e9a494fd414a66de16052ff7ed64e83 = source_7e9a494fd414a66de16052ff7ed64e83.innerHTML;nomnoml.draw(canvas, source_7e9a494fd414a66de16052ff7ed64e83);});<\/script>\n<p><br>\nOur best possible option is to <em>reuse<\/em> surface water: reducing water demand whilst also eliminating the challenge of getting rid of the surface water. This isn't environmentally perfect, ecosystems and aquifers need rainwater too, but as our reuse opportunity is pretty limited there'll still be loads to go around.<\/p>\n<p><em>Disconnection<\/em> is all about using the natural environment to handle surface water rather than our drainage networks. Allowing runoff to soak into the ground allows ecosystems to take it up, reducing drought impacts, maintaining river flow rates, and preventing us from having to deal with it downstream. Evaporation also cools the surrounding air, which is increasingly important in our warming world.<\/p>\n<p>Finally, if we have no other option but to use drainage networks to manage our surface water, then at least we can <em>attenuate<\/em> the rate at which it enters them. This is just slowing runoff down so that it doesn't enter drains all at once and overwhelm them, but does so slowly and gradually, spread out over time so that our networks don't surcharge.<\/p>\n<h2>Reuse<\/h2>\n<p>Disconnection is relatively easy - just shove your downpipe into a soakaway and let nature do the rest. Attenuation isn't all that difficult either, you just put a water-butt in this system which slowly drains into your lawn. The real challenge, and the surface water management holy grail, is how you engineer domestic water systems to allow for reuse.<\/p>\n<p>The easy answer is you store it in a water-butt and using it in the garden, or to wash the car. That's great, but the average UK householder with a water-butt uses &lt;45L of water from it per month, so this isn't a feasible solution for the quantity of surface water we have to deal with. We need a way to take this water and use it domestically, and the perfect use case is...<\/p>\n<h3>Flushing toilets<\/h3>\n<p>Flushing toilets feels like the biggest waste of potable water in our homes. It goes straight into a dirty toilet bowl and then down the drain - it's the perfect use case for relatively clean, but not potable, rainwater. So here are some specifications for a system that allows us to flush our loo with rainwater:<\/p>\n<ul>\n<li>refill the cistern with rainwater when available;<\/li>\n<li>when no rainwater is available, refill with potable...<\/li><\/ul>","image":"\/user\/pages\/05.blog\/flushing-with-rainwater-regulations-airgaps\/air-gaps.png"},{"title":"&quot;Screen time&quot; as a loss function","date_published":"2025-08-26T16:22:00+01:00","id":"https:\/\/cooper-davis.net\/blog\/screen-time-loss-function","url":"https:\/\/cooper-davis.net\/blog\/screen-time-loss-function","content_html":"<p>My life has been hijacked by my smartphone. In some ways it's my fault, because I made a series of incremental choices that led me here, but in many ways it's not my fault, because each individual choice wasn't unreasonable. How could my poor primitive primate&sup1; brain possibly know what it was getting itself in for?<\/p>\n<p>The <a href=\"https:\/\/web.archive.org\/web\/20250826151226\/https:\/\/fluidfocus.s3.eu-west-1.amazonaws.com\/The+Impact+of+Smartphones+on+Education+in+2025+[230625].pdf\">2025 Smartphones in Education (SIE) report<\/a> suggests that \"the average student now spends 5.5 hours per day on their phone-equivalent to 25 years of their lifetime\", and perhaps more strikingly, \"68% want to reduce [their] phone usage\" but presumably feel unable to.<\/p>\n<p><img title=\"Bar chart illustrating phone use for surveyed students. On average, students spend 5h30m daily on their phones.\" alt=\"Screenshot%20From%202025-08-26%2017-10-56\" src=\"\/user\/pages\/05.blog\/screen-time-loss-function\/Screenshot%20From%202025-08-26%2017-10-56.png\"><\/p>\n<p>My numbers aren't quite that bad, but they're still <em>really bad<\/em>, and I'm 30 and supposed to be in control of my life in a way that adolescents aren't. So what am I doing about it?<\/p>\n<h3>Muscle memory<\/h3>\n<p>What I'm complaining about are my own bad habits, and it's interesting just how unconscious these are. My mind can be entirely elsewhere but I can still unlock my phone and open an app with zero conscious effort - it's baked-in muscle memory. Fingerprint readers and facial recognition unlock have facilitated this; it's easier than ever to unlock your phone without having to engage any mental faculties.<\/p>\n<p>Recognising that these are habits is helpful because it gives us the tools to fight them, and that is to interrupt them.<\/p>\n<h3>Add friction<\/h3>\n<p>It's very difficult to make it impossible to access Facebook, or LinkedIn, or BBC News on a smart-phone - but you don't need to make it impossible, you just need to interrupt the habit and give your conscious brain the chance to object. So I've uninstalled my worst offending apps&sup2; and blocked their web equivalents using uBlock Origin on my phone's web browser.<\/p>\n<p>Now, when my muscle memory gets me unlocking my phone and opening something that wastes my life away, I am interrupted for just long enough to be slightly disgusted with myself. I am incredibly grateful for this disgust, because it is negative enough to prevent me from just working around the simple block that I've implemented.<\/p>\n<h3>Is it worth the sacrifices?<\/h3>\n<p>This isn't perfect. I want to know what's going on in the world, and blocking my news outlets prevents me from doing so. I want to hear about peoples caving discoveries on <a href=\"https:\/\/ukcaving.com\/\">UKCaving<\/a> and <a href=\"https:\/\/buddlepit.co.uk\/\">Buddle Pit<\/a>, and that's harder for me now. There are sacrifices to be made with this, but they're not that substantial. Ultimately, I'm happy to be making them, because I think it's making me happier, and healthier, and more interested, and more interest<em>ing<\/em>.<\/p>\n<p>I think \"screen time\" (particularly \"phone screen time\") is quite a nice loss function to be trying to target, because it doesn't have that many negative consequences. Even if I stopped using my phone entirely I don't think my life would look all that different - there would just be some more areas of inconvenience.<\/p>\n<h3>It's personal<\/h3>\n<p>So if I could ditch my smart phone entirely, why...<\/p>","image":"\/user\/pages\/05.blog\/screen-time-loss-function\/5868625180358723881.jpg"},{"title":"Unsolicited opinions: caving torches","date_published":"2024-12-14T11:14:00+00:00","id":"https:\/\/cooper-davis.net\/blog\/caving-torches","url":"https:\/\/cooper-davis.net\/blog\/caving-torches","content_html":"<p>Caving (and mine exploring) is an unusual outdoor pursuit in that it's time spent almost entirely in darkness. As such you need a good source of light - usually a torch.<\/p>\n<p>After 10 years of caving (and mine exploring) I now feel that I have earned the right to give my unsolicited opinion on what makes a good caving torch.<\/p>\n<p><strong>TLDR<\/strong>: Caving introduces some niche requirements for torches. Feel free to <a href=\"#recommendations\">skip to my recommendations<\/a>.<\/p>\n<h2>Considerations<\/h2>\n<p>Before I make some recommendations, let's look at some things that you need to consider when choosing a caving light. I've split this up into three lists; <em>must haves<\/em>, <em>nice to haves<\/em>, and <em>don't wants<\/em>.<\/p>\n<h3>Must haves<\/h3>\n<ul>\n<li>\n<p><strong>Brightness<\/strong>: a caving torch must produce enough light to cave with. This isn't actually all that much light, in fact early cavers and miners used candles as their only source of light. A candle has a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Luminous_flux\">luminous\nflux<\/a> (good luck with that rabbit hole!) of about 12.5 lumens. They had a horrible time though, so let's go for a minimum brightness of 10x that: 125 lumens.<\/p>\n<p>However... lumens alone aren't all that useful as a metric, as it doesn't consider the area that this light is spread across. A candle spreads a small number of lumens over a large sphere, whereas a laser pointer crams it all into a tiny spot. Most torches have a tolerable beam-shape, though, so I'll relegate beam shape to the \"nice to haves\" section.<\/p>\n<\/li>\n<li>\n<p><strong>Robustness<\/strong>: you (really!) need your torch to survive your trip. For me, this means it has to be <strong>waterproof<\/strong>. Thankfully we have <a href=\"https:\/\/en.wikipedia.org\/wiki\/IP_code\">a nice ingress protection standard<\/a> that allows us to directly compare waterproofness. As you may well be wading, swimming, crawling through puddles, or even going entirely underwater for sumps and ducks, I think IPX7 is a good minimum.<\/p>\n<p><img title=\"Ingress protection rating key.\" alt=\"IPRATING_uitleg_MM\" src=\"\/user\/pages\/05.blog\/caving-torches\/IPRATING_uitleg_MM.png\"><\/p>\n<p>Robustness should also include <strong>impact resistance<\/strong>. Now we do have <a href=\"https:\/\/en.wikipedia.org\/wiki\/EN_62262\">a standard for this too<\/a>, but it's not very human readable, and has such hasn't seen very widespread adoption. Instead you have to judge robustness on manufacturer <sub>lies<\/sub> claims, user reviews, and an instinctive assessment of the material and design of the product itself.<\/p>\n<\/li>\n<li>\n<p><strong>Head mount<\/strong>: you need your hands when you're caving, so your torch has to live on your helmet. However, I have chosen to use \"head mount\" here, because your backup light(s) shouldn't rely on you still having your helmet - what if you've <a href=\"https:\/\/ukcaving.com\/board\/index.php?threads%2Foh-shi.32355%2F=1#post-399792\">dropped it down a pitch<\/a> and smashed it to smithereens?<\/p>\n<p>Head mount also encompasses <strong>weight<\/strong> and <strong>bulk<\/strong> as you have to be able to wear it on your head for hours at a time. I don't know what my limits are for weight really, except having worn a 160g headlight (inc. batteries) once or twice I wouldn't want to exceed that by much.<\/p>\n<\/li>\n<li>\n<p><strong>Friendly UI<\/strong>: so that you can access all those nice brightness modes. This is a matter of preference, but it's really important that your torch is...<\/p><\/li><\/ul>","image":"\/user\/pages\/05.blog\/caving-torches\/emisar-dw4.jpg"},{"title":"Viseron and the Tapo C310","date_published":"2024-08-26T16:03:00+01:00","id":"https:\/\/cooper-davis.net\/blog\/viseron-and-the-tapo-c310","url":"https:\/\/cooper-davis.net\/blog\/viseron-and-the-tapo-c310","content_html":"<h3>What?<\/h3>\n<p>A <a href=\"https:\/\/www.tapo.com\/uk\/product\/smart-camera\/tapo-c310\/\">TP-link Tapo C310<\/a> security camera streaming audio\/video to the FOSS <a href=\"https:\/\/viseron.netlify.app\/\">Viseron NVR<\/a> software running on an <a href=\"https:\/\/www.odroid.co.uk\/hardkernel-odroid-c2-board\">Odroid-C2<\/a> single board computer\/home server.<\/p>\n<h3>Why?<\/h3>\n<p>Because I couldn't resist the temptation of a technical challenge, despite my dislike of surveillance in general (sorry principles!).<\/p>\n<div class=\"notices red\">\n<p>Editors note: since writing this blog post I have since taken down my security camera as I couldn't help but profoundly dislike being watched all the time!<\/p>\n<\/div>\n<p><img title=\"niv-singer-LkD_IH8_K8k-unsplash\" alt=\"niv-singer-LkD_IH8_K8k-unsplash\" src=\"\/user\/pages\/05.blog\/viseron-and-the-tapo-c310\/niv-singer-LkD_IH8_K8k-unsplash.jpg\"><\/p>\n<h3>How?<\/h3>\n<h4>Tapo C310<\/h4>\n<p>The Tapo C310 makes a couple of authenticated RTSP streams available at <code>rtsp:\/\/camera.local.ip.address:554<\/code>:<\/p>\n<ul>\n<li><code>\/stream1<\/code>: a high res stream (1920x1080 or 2304x1296 depending on how you set it up)<\/li>\n<li><code>\/stream2<\/code>: a low res stream (640x360)<\/li>\n<\/ul>\n<p>These streams are a bit quirky; they're fixed at 15 fps, and use the <code>pcm_alaw<\/code> audio and <code>h264<\/code> video codecs. This audio codec choice is a pain, as it means you have to re-encode if you want to put it in <code>.mp4<\/code> containers rather than <code>.mkv<\/code> containers, which aren't as well supported (<a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi\" id=\"1422891\">I'm looking at you, Firefox!<\/a>).<\/p>\n<p>Still, this is enough for us to plug into a Network Video Recorder (NVR) program which can pull the feed, process it, and save it.<\/p>\n<h4>Viseron<\/h4>\n<p>Viseron is a fairly straightforward open source NVR program that should be just the job. I like it because it's modular, written in python, and quite efficient. This means that you don't have to play with all the bells and whilstles of AI object detection or graphics cards if you don't want to. It'll manage all the boring stuff, like deleting old video files, making the setup fairl simple.<\/p>\n<p>Even better, it's shipped in Docker containers so it's super easy to spin it up and get it going without worrying about dependencies, daemons, or other faff like that! So we spin up a container<\/p>\n<pre><code>docker run \\\n   -v \/mnt\/nvr\/segments:\/segments \\\n   -v \/mnt\/nvr\/recordings:\/recordings \\\n   -v \/mnt\/nvr:\/config \\\n   -v \/etc\/localtime:\/etc\/localtime:ro \\\n   -p 8888:8888 \\\n   --restart unless-stopped \\\n   --detach \\\n   --name viseron \\\n   roflcoopter\/viseron:latest<\/code><\/pre>\n<p>Note that we're binding some directories on our filesystem as volumes in the container. This allows the recordings and config files to be stored on an external HDD plugged into the server, rather than doing all that writing on fragile flash memory (which is a great way to kill your micro-SD card\/eMMC!). We're also port forwarding on 8888 to allow us to view the admin interface on the local network. And finally we're using the <code>detach<\/code> and <code>restart<\/code> flags to keep the process alive in the background.<\/p>\n<p>What about setting up Viseron itself? Well the documentation for <a href=\"https:\/\/viseron.netlify.app\/docs\/documentation\/configuration\">configuring Viseron<\/a> is pretty good, and as we're only using the basic <code>ffmpeg<\/code> camera and <code>background_subtractor<\/code> motion detection components the setup is quite simple:<\/p>\n<pre><code class=\"language-yaml\">## Cameras\nffmpeg:\n  camera:\n    hillview_front:\n\n      ### Recording stream\n      name: Tapo C310\n      host: cameras.local.ip.address\n      port: 554\n      path: \/stream1\/\n      username: username_set_in_tapo_app\n      password: password_set_in_tapo_app\n\n      audio_codec: aac\n      codec: h264\n      fps: 15\n      width: 2304\n      height: 1296\n\n      ### Low-res stream\n      substream:\n        path: \/stream2\/\n        port: 554\n\n        audio_codec: aac\n        codec: h264\n        fps: 15\n        width: 640\n        height: 360\n\n      recorder:\n        lookback: 20\n        extension:...<\/code><\/pre>","image":"\/user\/pages\/05.blog\/viseron-and-the-tapo-c310\/niv-singer-LkD_IH8_K8k-unsplash.jpg"},{"title":"3D Scanning of Abandoned Mines","date_published":"2024-08-14T13:13:00+01:00","id":"https:\/\/cooper-davis.net\/blog\/3d-scanning-abandoned-mines","url":"https:\/\/cooper-davis.net\/blog\/3d-scanning-abandoned-mines","content_html":"<p>I have recently been working on a project exploring how I can use the laser surveying tool that I'm developing to produce high resolution surveys and 3D scans of abandoned mines and caves.<\/p>\n<p>With the support of an innovation grant from the <a href=\"https:\/\/deepdigitalcornwall.org\/\">Deep Digital Cornwall<\/a> project, run by the experts at the Camborne School of Mines and the University of Exeter, I have been able to accelerate the development of my surveying tool and obtain some more advanced hardware for collecting high resolution LiDAR scans at survey stations.<\/p>\n<p>Whilst the surveys of the mines will take a significant amount of time to draw up, the first 3D scans are now processed and ready for viewing. I was very lucky to be invited to view these models using <a href=\"https:\/\/deepdigitalcornwall.org\/visualisation-suite-info\/\">DDC's Visualisation Suite<\/a>, which gives an incredible virtual reality view of these environments, which otherwise require considerable ropework and mine exploration skills to experience.<\/p>\n<p>I will also make these models publicly available so that you can explore them at home.<\/p>\n<ul>\n<li>\n<p>Stacked Deads<\/p>\n<p>This scale model shows a level in Wheal Pell, an abandoned mine in the St Agnes Consols Sett in West Cornwall. Waste rock (\u201cdeads\u201d) are stacked up against one wall.<\/p>\n<iframe title=\"Wheal Pell - Stacked Deads\" frameborder=\"0\" allowfullscreen mozallowfullscreen=\"true\" webkitallowfullscreen=\"true\" allow=\"autoplay; fullscreen; xr-spatial-tracking\" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share src=\"https:\/\/sketchfab.com\/models\/b17079ba1c364a20a1473ee096dd123f\/embed?autostart=0&preload=1&dnt=1\" style=\"min-width: 100%;min-height: 20rem;\"> <\/iframe>\n<\/li>\n<li>\n<p>Barrow in Passage<\/p>\n<p>This scale model shows a level in Wheal Pell, an abandoned mine in the St Agnes Consols Sett in West Cornwall. A wooden wheel-barrow lies abandoned on the floor next to a winze (an internal shaft between levels).<\/p>\n<iframe title=\"Wheal Pell - Barrow in Passage\" frameborder=\"0\" allowfullscreen mozallowfullscreen=\"true\" webkitallowfullscreen=\"true\" allow=\"autoplay; fullscreen; xr-spatial-tracking\" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share src=\"https:\/\/sketchfab.com\/models\/3e0125f1bb1045518c50b99f7c9ec5d1\/embed?autostart=0&preload=1&dnt=1\" style=\"min-width: 100%;min-height: 20rem;\"> <\/iframe>\n<\/li>\n<li>\n<p>Kibble in Passage<\/p>\n<p>This scale model shows a level in Wheal Pell, an abandoned mine in the St Agnes Consols Sett in West Cornwall. An ore kibble, a metal bucket used to haul ore up shafts, lies rusting and abandoned in the passage.<\/p>\n<iframe title=\"Wheal Pell - Barrow in Passage\" frameborder=\"0\" allowfullscreen mozallowfullscreen=\"true\" webkitallowfullscreen=\"true\" allow=\"autoplay; fullscreen; xr-spatial-tracking\" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share src=\"https:\/\/sketchfab.com\/models\/6c936b365b9b4d3f8174883d7327e1e1\/embed?autostart=0&preload=1&dnt=1\" style=\"min-width: 100%;min-height: 20rem;\"> <\/iframe>\n<\/li>\n<\/ul>","image":"\/user\/pages\/05.blog\/3d-scanning-abandoned-mines\/Screenshot 2023-07-06 at 11-53-49 Wheal Pell - Stacked Deads_small.jpg"},{"title":"Liberating digital OS Maps","date_published":"2022-09-12T12:00:00+01:00","id":"https:\/\/cooper-davis.net\/blog\/digital-os-maps","url":"https:\/\/cooper-davis.net\/blog\/digital-os-maps","content_html":"<p>When I buy something I like to own it. I'm not against rental or subscription services by any means, in fact in our consumerist world I'd like to see much more sharing of resources within communities, but when I buy something for myself I want to be able to (within reason!) do what I want with it.<\/p>\n<p>Ordnance Survey, Great Britain's national mapping agency, sells its excellent paper maps with a digital download code that allows you to download the map onto your phone for use in their OS Maps app. This is an excellent feature, and their app is very good indeed, but I'd love to be able to browse these maps offline on my computer, or view them in a different mapping app, or change their compression slightly to improve their file size a little. After all, I've bought those digital maps, haven't I?<\/p>\n<div class=\"notices yellow\">\n<p>Using the maps you've bought in the software of your choice is justifiable, but sharing these map files with others who have not paid for them is not. Please <strong>don't share your map files<\/strong> - purchasing OS's excellent maps supports their development.<\/p>\n<\/div>\n<p>So I've been doing a little exploring of the OS Maps app to see if I can extract the map files from its storage.<\/p>\n<h3>Finding the Maps<\/h3>\n<p>First things first, I've be doing all this on an Android device because it's what I am most familiar with. The first hurdle that I encoutered is that the OS Maps app doesn't store its data in a user accessible folder, unsurprisingly. There are a couple of things we can try to get around this:<\/p>\n<ol>\n<li>Use <code>adb backup<\/code> to try and pull the app data<\/li>\n<li>Use a rooted device to explore the app data<\/li>\n<\/ol>\n<p>The <a href=\"https:\/\/developer.android.com\/studio\/command-line\/adb\">Android Debug Bridge (adb)<\/a> developer tool has historically allowed users to take backups of their app data using the <code>adb backup<\/code> command. The user can then extract this backup file in order to inspect the app data stored in folders not accessible to the user. However, this isn't sure to work - developers can opt-out of backing up their app data using an attribute in the app manifest (which is what the OS Maps app developers have done), on top of which the adb tool has recently deprecated the backup tool entirely, and may remove it in future releases.<\/p>\n<p>So instead we try inspecting the app data using a rooted android device. Now I happen to have a rooted android phone, but if you don't you can <a href=\"https:\/\/developer.android.com\/studio\/run\/managing-avds\">emulate an android device in Android studio<\/a> and <a href=\"https:\/\/developer.android.com\/studio\/run\/managing-avds#system-image\">choose a system image with elevated priviledges<\/a>. These images don't come loaded with Google Play, so you may have to download the OS Maps .apk file from elsewhere, but once it's installed you'll be able to use the file browser built-into Android studio to have a poke around its app data.<\/p>\n<p>The first promising thing I noticed is the <code>\/data\/data\/uk.co.ordnancesurvey.osmaps\/files\/mbgl-offline.db<\/code> file. The file name implies that it is an \"offline\" file saved using the...<\/p>","image":"\/user\/pages\/05.blog\/digital-os-maps\/screenshot.jpg"},{"title":"What can I rig?","date_published":"2022-03-04T12:00:00+00:00","id":"https:\/\/cooper-davis.net\/blog\/what-can-i-rig","url":"https:\/\/cooper-davis.net\/blog\/what-can-i-rig","content_html":"<p>When planning a caving trip there are lots of things to consider; whether the difficulty matches your groups abilities, whether the trip will be safe given the weather, and whether you've got the right equipment to actually do the trip. In the Yorkshire Dales this last one is particularly relevant, as so many of the caves are vertical in nature and require substantial amounts of rope to abseil down into.<\/p>\n<p><img title=\"rope\" alt=\"rope\" src=\"\/images\/0\/9\/8\/b\/4\/098b4ec3b6520544db9bc1466cd9528d3cd77164-rope.jpg\" \/><\/p>\n<p>This planning complexity tends to limit the trips that people go on, not because there aren't other trips that would be suitable, but because it's difficult to evaluate all these considerations if you haven't been on the same trip before. Guide books are extremely helpful, as they compile all this information (and more) into one easy reference, but some regions have multiple guidebooks, and even so you'd have to manually flick through every listed trip if you wanted to explore all your options.<\/p>\n<h3>What can I rig?<\/h3>\n<p>Enter <a href=\"https:\/\/aricooperdavis.github.io\/what-can-I-rig\/\">What can I rig?<\/a>, a website that takes a list of exactly the rope lengths that you've got, and spits out all of the possible trips that you could do (in the Yorkshire Dales) with those ropes.<\/p>\n<p><a href=\"https:\/\/aricooperdavis.github.io\/what-can-I-rig\/\"><img title=\"what-can-i-rig\" alt=\"what-can-i-rig\" src=\"\/images\/6\/f\/6\/2\/2\/6f62244437ed4036f25b94094895d4759e3dd63e-what-can-i-rig.png\" \/><\/a><\/p>\n<p>To work this out it uses <a href=\"https:\/\/github.com\/aricooperdavis\/what-can-I-rig\/blob\/main\/pitchlengths.txt\">a list<\/a> of trips and the rope lengths required to undertake them, compiled from a number of websites and guidebooks including:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.braemoor.co.uk\/caving\/directory.shtml\">Breamoor<\/a><\/li>\n<li><a href=\"https:\/\/www.resinanchor.co.uk\/6.html\">Simon Wilson<\/a><\/li>\n<li><a href=\"https:\/\/cncc.org.uk\/\">CNCC<\/a><\/li>\n<li><a href=\"https:\/\/starlessriver.com\/shop\/not-for-the-faint-hearted\/\">Not for the Faint-Hearted<\/a><\/li>\n<li><a href=\"https:\/\/northerncaves.co.uk\/\">Northern Caves<\/a><\/li>\n<\/ul>\n<h3>The code: PWAs and CI\/CD<\/h3>\n<p>As it's <a href=\"https:\/\/github.com\/aricooperdavis\/what-can-I-rig\">hosted on Github<\/a> it's very easy for the community to keep expanding this list as new discoveries are made - I'll try and keep an eye on the CNCC website but pull requests are greatly appreciated!<\/p>\n<p>I've designed the site so that all the processing takes place in the browser using javascript. This means that I don't need any resources to host it (thank you Github Pages), but also that it was very easy to turn it into a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Progressive_web_apps\/Introduction\">Progressive Web App<\/a> that can be installed on your phone and used offline, which is particularly useful in remote signal-less caving huts.<\/p>\n<p><img title=\"pwa-install\" alt=\"pwa-install\" src=\"\/images\/b\/b\/4\/f\/6\/bb4f6ab81812abc52ceb57f466deff98cb663e8f-pwa-install.jpg\" \/> <img title=\"pwa\" alt=\"pwa\" src=\"\/images\/a\/a\/4\/a\/6\/aa4a6d160d11798faadb0dd0122a4829b7a54b15-pwa.jpg\" \/><\/p>\n<p>I've also taken this opportunity to learn a bit more about CI\/CD and Github Actions. Now, when changes are committed to the <code>main<\/code> branch of the repository, a GitHub action minifies the javascript, CSS, and HTML in the repo and pushes these changes back to the <code>gh-pages<\/code> branch, from where another GitHub action builds and deploys the site on Github Pages!<\/p>\n<p>If you're interested in implementing something like this in your own projects you can might find <a href=\"https:\/\/github.com\/aricooperdavis\/what-can-I-rig\/blob\/main\/.github\/workflows\/minify.yml\">the workflow <code>.yaml<\/code><\/a> file a useful reference.<\/p>","image":"\/user\/pages\/05.blog\/what-can-i-rig\/rope.jpg"},{"title":"SSSI Cave Entrances","date_published":"2021-12-01T12:00:00+00:00","id":"https:\/\/cooper-davis.net\/blog\/sssi-cave-entrances","url":"https:\/\/cooper-davis.net\/blog\/sssi-cave-entrances","content_html":"<p>Sites of Special Scientific Interest, or SSSIs, are nature conservation areas given legal protection from damage, development, and neglect in order to safeguard the natural features that they contain. As their name implies, they are used to conserve features of particular biological or geological interest. Caves and mines often play host to such features; because of the unique biological habitats that they provide, and because of the geological nature of their formation\/excavation. <\/p>\n<p>Earlier this year I received an email from a caver who wanted to explore how well recorded (and therefore protected) these features are. Their idea was to search through all SSSI citations for keywords such as \"cave\", \"ogof\", and \"uamh\", to determine which SSSIs made reference to these features. A dataset of known cave and mine features would then be prepared and those that fall within an SSSI boundary extracted. These two datasets could then be compared to assess how many SSSI citations acknowledge these features.<\/p>\n<p>I was tasked with compiling the database of known cave and mine features and performing the point-in-polygon intersection with the SSSI boundarys.<\/p>\n<h3>Sourcing the data<\/h3>\n<p>Whilst there is no national database of cave and mine features in Great Britain, the British Caving Association (BCA) does work with regional caving councils to maintain regional registries. As the BCAs Cave Registry &amp; Archive working group has developed these registries they all take a similar format, which means that they can be easily scraped. I scraped entries from:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.cambriancavingcouncil.org.uk\/registry\/ccr_registry.php\">Cambrian Caving Council | Registry<\/a><\/li>\n<li><a href=\"https:\/\/dcuc.org.uk\/registry\/r\/registrysearch.php\">Devon &amp; Cornwall Underground Council | Registry<\/a><\/li>\n<li><a href=\"https:\/\/www.fodccag.org.uk\/registry\/registrysearch.php\">Forest of Dean Cave Conservation &amp; Access Group | Registry<\/a><\/li>\n<li><a href=\"https:\/\/registry.gsg.org.uk\/sr\/registrysearch.php\">Grampian Speleological Group | Registry<\/a><\/li>\n<li><a href=\"https:\/\/www.mcra.org.uk\/registry\/registrysearch.php\">Mendip Cave Registry and Archive | Registry<\/a><\/li>\n<\/ul>\n<p>Other regional councils have developed their own database of cave and mine features, which I was also able to scrape. This was a slightly tricker task due to the differing design of each registry, and stronger built-in scraping protection. I sourced data from:<\/p>\n<ul>\n<li><a href=\"https:\/\/cncc.org.uk\/caving\/caves\/index.php?keyword=&amp;sort=last_updated%20DESC\">Council of Northern Caving Clubs | Caves List<\/a><\/li>\n<li><a href=\"https:\/\/peakdistrictcaving.info\/home\/the-caves\/search\">Derbyshire Caving Association | Peak District Caving<\/a><\/li>\n<\/ul>\n<p>Finally, one of the famous caving guide books has also developed an online dataset of cave and mine features which I was able to scrape for entries that might not appear in other datasets:<\/p>\n<ul>\n<li><a href=\"https:\/\/northerncaves.co.uk\/caves\/\">Northern Caves | Caves Index<\/a><\/li>\n<\/ul>\n<p>Each of the devolved governments maintain their own publically available SSSI datasets, so it was fairly straightforward to download shapefiles for the SSSIs:<\/p>\n<ul>\n<li>England: <a href=\"https:\/\/naturalengland-defra.opendata.arcgis.com\/datasets\/Defra::sites-of-special-scientific-interest-england\/about\">Natural England<\/a><\/li>\n<li>Scotland: <a href=\"https:\/\/gateway.snh.gov.uk\/natural-spaces\/dataset.jsp?dsid=SSSI\">Scottish Natural Heritage<\/a><\/li>\n<li>Wales: <a href=\"https:\/\/lle.gov.wales\/catalogue\/item\/ProtectedSitesSitesOfSpecialScientificInterest\/?lang=en\">Natural Resources Wales<\/a><\/li>\n<\/ul>\n<h3>GIS<\/h3>\n<p>I used Python to scrape each of the data sources. I won't share this code publically as I had to work around some anti-scraping measures, but I ensured that a suitable delay was used so as not to overload any of the servers hosting the data.<\/p>\n<p>Once I had scraped features from each data-source, I compiled the resultant features into a geospatial dataset of point features and performed some fuzzy deduping based on feature name and location, also in Python.<\/p>\n<p>I then used QGIS to load up the SSSI shapefiles and...<\/p>","image":"\/user\/pages\/05.blog\/sssi-cave-entrances\/map.png"},{"title":"DIYstoX: The Software","date_published":"2020-01-17T12:00:00+00:00","id":"https:\/\/cooper-davis.net\/blog\/diystox-the-software","url":"https:\/\/cooper-davis.net\/blog\/diystox-the-software","content_html":"<div class=\"notices green\">\n<p>This is the third post about a project to build a cave surveying device. You might want to read the <a href=\"\/blog\/diystox-the-wiring\">previous post<\/a> before embarking on this one.<\/p>\n<\/div>\n<p>So far we've worked out how we can decode readings from the LDM, and how we can wire it up to a microcontroller with a magnetometer and accelerometer, then add an external battery to make it portable. In this post we'll look at the code running on that microcontroller that takes readings from the LDM, magnetometer, and accelerometer and converts them to distance, heading, and inclination respectively.<\/p>\n<h3>The Software<\/h3>\n<p>The general structure of the software on the microcontroller is illustrated by the process flow diagram on the right.<\/p>\n<p>Since Bluetooth will not always be available the measurements will be stored in an array where they can be sent when possible. The taking of readings from the magnetometer and inclinometer will be triggered by receiving readings over serial from the LDM. This means that only one button, the one on the LDM, needs to be pressed to initiate readings from all of the sensors and add them to a queue for sending.<\/p>\n<p><img title=\"flow\" alt=\"flow\" src=\"\/images\/a\/a\/c\/e\/4\/aace45fd33f97dd948d83f6cc32124d488713e36-flow.png\" \/><\/p>\n<p>With a limited amount of memory available on the Feather it is important to ensure that our variables are assigned and used properly. To facilitate this all of our variable initialisation will be done at the start of the program, and we will only access and modify variables in the main running loop.<\/p>\n<p>The downside to this is that it means we need to specify a fixed limit on the number of measurements that can be stored in the array waiting to be sent. <\/p>\n<h3>Code available on GitHub<\/h3>\n<p>I'm not going to go through the code in detail, as I find it exceptionally tedious, but you can find it <a href=\"https:\/\/github.com\/aricooperdavis\/diYstoX\">on GitHub<\/a> where it is reasonably well documented. It is currently still being developed - for example it is sending measurements over serial rather than Bluetooth LE , and it's not following the same <a href=\"https:\/\/drive.google.com\/file\/d\/1WRYI8mA1SiTgkDp7fFhNl3OldfOlY2tg\/\">communication protocol<\/a> as the DistoX2. Keep an eye out for updates as I keep working on it.<\/p>\n<h3>What's next?<\/h3>\n<p>So far we've managed to get our microcontroller to take readings from the magnetometer and 3-axis accelerometer when it receives readings from the LDM.<\/p>\n<p>The next step is to work out how to turn those magnetometer and accelerometer measurements into a compass heading and inclination reading, which will require some calibration. We'll explore the simple maths behind those calculations in the next post.<\/p>","image":"\/user\/pages\/05.blog\/diystox-the-software\/flow.png"},{"title":"DIYstoX: The Wiring","date_published":"2019-12-18T12:00:00+00:00","id":"https:\/\/cooper-davis.net\/blog\/diystox-the-wiring","url":"https:\/\/cooper-davis.net\/blog\/diystox-the-wiring","content_html":"<div class=\"notices green\">\n<p>This is the second post about a project to build a cave surveying device. You might want to <a href=\"\/blog\/diystox-the-laser-distance-meter\">read the first post<\/a> before embarking on this one.<\/p>\n<\/div>\n<p>So far we've worked out how to read the distance measurements that the device writes on the serial pins of its MCU, but we've been doing this by hand on a computer. In this post we'll look at how we can use a microcontroller to read those distance measurements, along with measurements of heading and inclination from an accelerometer and magnetometer, and send them over serial to other devices.<\/p>\n<h3>The Microcontroller<\/h3>\n<p>There are a whole range of microcontrollers suitable for this sort of task, but I'm working with the <a href=\"https:\/\/www.adafruit.com\/product\/4062\">Adafruit Feather nRF52840 Express<\/a>. I chose this board to facilitate the use of Bluetooth LE, but many other boards are suitable. If you use an arduino-compatible board then you may even be able to copy and paste the code that we write for it with very few changes.<\/p>\n<p><img title=\"board1\" alt=\"board1\" src=\"\/images\/f\/d\/9\/9\/6\/fd99652bdc5198b2672665b81dcbbe3ccdea60bb-board1.png\"><\/p>\n<p>There are a few features of the Feather nRF52840 Express in particular that are desirable for this project:<\/p>\n<ul>\n<li>Hardware UART pins enable us to read serial data from the LDM whilst still being able to write to the USB serial for debugging<\/li>\n<li>The built-in nRF52840 radio is Bluetooth LE compatible, and libraries already exist to facilitate comms<\/li>\n<li>Built-in voltage regulators and connectors facilitate the use and charging of LiPo batteries<\/li>\n<li>An addressable multicolour NeoPixel LED and 'USER' switch extend control and feedback options<\/li>\n<\/ul>\n<h3>The acceler\/magnet-ometer<\/h3>\n<p>In order to determine the inclination and compass heading of the unit we need a magentometer and 3-axis accelerometer. To simplify the wiring I have chosen to use a board that contains both; <a href=\"https:\/\/www.adafruit.com\/product\/1120\">Adafruit's LSM303DLHC<\/a>.<\/p>\n<p><img title=\"board2\" alt=\"board2\" src=\"\/user\/pages\/05.blog\/diystox-the-wiring\/board2.png\"><\/p>\n<p>This communicates using I2C, and Adafruit has already developed libraries that make it easily addressable.<\/p>\n<h3>Connecting the LDM<\/h3>\n<p>With built-in hardware UART pins it's very easy to hook up the LDM to the serial port; connect:<\/p>\n<ul>\n<li>TxD contact on the LDM to the RX pin on the Feather<\/li>\n<li>RxD contact on the LDM to the TX pin on the Feather<\/li>\n<li>-ve battery terminal on the LDM to the Feather's gnd pin to give a reliable reference voltage. <\/li>\n<\/ul>\n<p><img title=\"wiring1\" alt=\"wiring1\" src=\"\/user\/pages\/05.blog\/diystox-the-wiring\/wiring1.png\"><\/p>\n<p>There aren't built-in pull-up resistors on the Feather's TX\/RX pins but since we're not expecting the signal to be floating at any point then this isn't an issue. I have put a couple of resistors on those pins to protect them from me being an idiot whilst I was first experimenting with the circuit, but I don't think that they're strictly necessary.<\/p>\n<h3>Connecting the LSM303DLHC<\/h3>\n<p>It's very easy to wire up the LSM303DLHC module to the Feather as it communicates over I2C and the Feather has available SCL\/SDA pins. As such you just need to connect:<\/p>\n<ul>\n<li>SCL on the LSM303 to SCL on the Feather<\/li>\n<li>SDA on the LSM303 to SDA on the Feather<\/li>\n<li>gnd on the LSM303 to gnd on the Feather<\/li>\n<li>3.3v on the LSM303 to 3.3v on the Feather<\/li>\n<\/ul>\n<p><img title=\"wiring2\" alt=\"wiring2\" src=\"\/user\/pages\/05.blog\/diystox-the-wiring\/wiring2.png\"><\/p>\n<p>All the necessary pull-up resistors...<\/p>","image":"\/user\/pages\/05.blog\/diystox-the-wiring\/board1.png"},{"title":"DIYstoX: The Laser Distance Meter","date_published":"2019-11-19T12:00:00+00:00","id":"https:\/\/cooper-davis.net\/blog\/diystox-the-laser-distance-meter","url":"https:\/\/cooper-davis.net\/blog\/diystox-the-laser-distance-meter","content_html":"<p>In the Venn-diagram of my main hobbies there's a significant subset of Caving and Amateur electronics; in fact <a href=\"https:\/\/bcra.org.uk\/\">the British Cave Research Association<\/a> has an entire journal, the <a href=\"https:\/\/bcra.org.uk\/creg\/\">Cave Radio &amp; Electronics Group<\/a>, dedicated to the subject. This project falls perfectly into that subset.<\/p>\n<p>I'm reverse engineering a SNDWAY Laser Distance Meter (LDM) so that I can add magnetometer, accelerometer, and Bluetooth modules in order to make a DIY <a href=\"https:\/\/paperless.bheeb.ch\/\">DistoX2 paperless cave surveying tool<\/a>. This will never compete with the accuracy, robustness, or usability of a DistoX2, but it's not supposed to compete, it's just a bit of fun for me. It's also a lot cheaper than me buying a proper one. This also isn't the first attempt at <a href=\"https:\/\/web.archive.org\/web\/20190819080621\/https:\/\/hackaday.com\/2018\/05\/22\/hacking-a-cheap-laser-rangefinder\/\">reverse engineering a laser rangefinder<\/a>, but as these devices differ greatly I still think that it is worth documenting my progress with this one.<\/p>\n<h3>The LDM<\/h3>\n<p>I wanted a reasonably cheap LDM with a long range for this project, so I went for the <a href=\"https:\/\/web.archive.org\/web\/20191206165848\/https:\/\/www.ebay.co.uk\/itm\/SNDWAY-100M-Handheld-Digital-Laser-Distance-Meter-Range-Volume-Finder-Measure-D1-\/362539784013?nma=true&amp;si=OsgdOoaFCRm%252Fm1A7QFd30TFP3c8%253D&amp;orig_cvip=true&amp;nordt=true&amp;rt=nc&amp;_trksid=p2047675.l2557\">D1 SW-T100 100m LDM from SNDWAY<\/a>. These knock-off LDMs go for about &pound;25 on eBay, but are poorly labelled and shipped from China so you rarely know exactly what you're going to get until you actually get it. Even the case on them doesn't always correspond with what's inside them. This is what I actually received:<\/p>\n<p><img title=\"LDM board front\" alt=\"ldm1\" src=\"\/images\/4\/4\/a\/6\/9\/44a695977ea0354dade7e00b126a61c13f8f9e83-ldm1.png\"> <img title=\"LDM board back\" alt=\"ldm2\" src=\"\/images\/8\/1\/b\/1\/e\/81b1e5e064abf1c53d080e8e39492f61cceea00c-ldm2.png\"><\/p>\n<p>This is the main board. It is accessed by removing the front case, unclipping the ribbon cables between the LCD and button boards and removing them, then unscrewing the board from the back case. Things of note are:<\/p>\n<ul>\n<li>ARM STM32F030C8T6 Microcontroller\n<ul>\n<li>LQFP48 48-pin package<\/li>\n<li>RxD\/TxD pins broken out to contacts on the board<\/li>\n<\/ul><\/li>\n<li>Piezo-speaker\n<ul>\n<li>This will be significantly magnetic so will need to be removed before I add the magnetometer<\/li>\n<\/ul><\/li>\n<\/ul>\n<h3>Establishing Serial Communications<\/h3>\n<p>So having found RxD\/TxD contacts on the board, and confirmed that they match up with appropriate pins on the MCU, I soldered some jumpers to them and hooked them up to a breadboard. I then sampled them using an oscilloscope as I powered on the device:<\/p>\n<p><img title=\"Oscilloscope trace\" alt=\"scope\" src=\"\/user\/pages\/05.blog\/diystox-the-laser-distance-meter\/scope.png\"><\/p>\n<p>As the device powers on it starts pulling a nice clear signal on the TxD pin. A quick measure of the duration of a single bit using the scope gives us the baud rate; 115.2kbaud. Hooking it up to serial monitor such as PuTTY facilitates decoding the signal. There's a great tutorial on how to <a href=\"https:\/\/web.archive.org\/web\/20191112113029\/https:\/\/hardwarefun.com\/tutorials\/using-arduino-as-a-bridge-to-connect-serial-devices-with-pc\">use an Arduino as a USB Serial Bridge<\/a> if you don't have a dedicated one. The decoding itself is thankfully easy as the signal is just ASCII with NL&amp;CR line-endings in 8N1.\nSo when we power up the device we receive 3 lines:<\/p>\n<ol>\n<li><code>SPP:setName = SNDWAY LDM STUDIO<\/code><\/li>\n<li><code>SPP:setBR 9600<\/code><\/li>\n<li><code>SPP:saveConfigure<\/code><\/li>\n<\/ol>\n<p>Some initial observations:<\/p>\n<ul>\n<li>The communications are following the Serial Port Profile. This profile describes how bluetooth devices can emulate serial cable connections over RFCOMM.<\/li>\n<li>The initial configuration sets a new baud rate of 9600 baud for future communications.<\/li>\n<\/ul>\n<p>So we reconfigure PuTTY to read at 9600 baud rather than 115.2kbaud and turn...<\/p>","image":"\/user\/pages\/05.blog\/diystox-the-laser-distance-meter\/ldm1.png"}]}
