
    
    
    
    
            
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
                
    
    
    
            
{"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":"Gas monitor teardown","date_published":"2025-08-29T13:49:00+01:00","id":"https:\/\/cooper-davis.net\/blog\/gas-monitor-teardown","url":"https:\/\/cooper-davis.net\/blog\/gas-monitor-teardown","content_html":"<p>This isn't so much of a blog post as a note to self documenting anything interesting I find whilst trying to repair a Senko SP-SGTP-O2 gas monitor.<\/p>\n<div class=\"notices yellow\">\n<p>Don't be stupid and try and repair a delicate piece of PPE, just buy a new one!<\/p>\n<\/div>\n<h3>Device overview<\/h3>\n<p>The Senko SP-SGTP (<a href=\"https:\/\/senkousa.com\/data\/file\/prod\/20250408141105_868870_Datasheet_En_SP-SGT-P.pdf\">datasheet<\/a>, <a href=\"https:\/\/senkousa.com\/data\/file\/prod\/20250408141015_880653_SGT-P%20Manual_Eng_20231221.pdf\">user manual<\/a>) is a personal gas monitor that is designed to measure the concentration of a specific chemical in the atmosphere and trigger an alarm if that concentration falls outside of a specified \"safe\" range.<\/p>\n<p>The \"O2\" in the product code denotes that my monitor contains an oxygen sensor. I use it when exploring abandoned mines. In these confined spaces natural bacteria can consume oxygen as they break down organic matter, reducing the concentration of oxygen in the environment and replacing it with poisonous CO2. Not wanting to asphyxiate and die, I therefore use a gas monitor to make sure that the air I'm breathing contains enough oxygen to live (and therefore <em>probably<\/em> not enough CO2 to do me harm). There are other risky gases that can build up in confined spaces, particularly abandoned mines, but they are much less likely to occur in the mines that I'm exploring (or have less severe effects than asphyxiation), and multi-gas monitors are expensive, so I have made a decision not to monitor for them and to control my risk exposure in other ways.<\/p>\n<p>The second \"P\" in the product code denotes that this is a maintainable device rather than a disposable one - i.e. you can (in theory) switch out the battery and sensor if they fail.<\/p>\n<p><a href=\"https:\/\/senko.co.kr\/\">Senko<\/a> is a South Korean company with quite a good reputation for making this type of PPE, but this particular device is definitely on the budget end of their offering.<\/p>\n<h3>What's inside?<\/h3>\n<p>At first glance this device certainly does appear to be pretty maintainable. The back of the case can be removed with 6 identical machine screws, giving easy access to the battery which just pops out for replacement.<\/p>\n<p>[insert image here]<\/p>\n<p>The circuit board is held into the front of the case with 2 shorter self tapping screws. Removing these allows the board to be removed, allowing the filter on top of the sensor to be removed and replaced.<\/p>\n<p>[insert image here]<\/p>\n<p>But what about the sensor itself? On further inspection it appears to be a fairly standard three pin electrochemical sensor, with the pins labelled on the board:<\/p>\n<ul>\n<li>\"WE\": working electrode, does the work of reducing O2 molecules by providing electrons. The number of electrons provided, and therefore the charge on this electrode, varies depending on the oxygen concentration.<\/li>\n<li>\"CE\": counter electrode, counters the working electrode by providing the electrons required to reduce the working electrode (essentially just closing the circuit) creating a current with the working electrode that can be measured.<\/li>\n<li>\"RE\": reference electrode, sits in the electrolyte but doesn't do any reducing, allowing us to have a reference potential so that the working electrode can be calibrated to...<\/li><\/ul>"},{"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 ~lies~ 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<p><img title=\"vaporwave\" alt=\"vaporwave\" class=\"p-centered\" src=\"\/images\/9\/f\/3\/0\/6\/9f3066a89a1036f82cd97eed1ad1a5b1afc0e470-vaporwave.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: mp4\n\n## Motion detectors\nbackground_subtractor:\n  motion_detector:\n    cameras:\n\n      hillview_front:\n        width: 320\n        height: 180\n\n        trigger_recorder: true\n        fps: 1\n        area: 0.01\n        threshold: 15\n        alpha: 0.1\n\n## NVR\nnvr:\n  hillview_front:<\/code><\/pre>\n<p>First...<\/p>","image":"\/user\/pages\/05.blog\/viseron-and-the-tapo-c310\/vaporwave.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\/a\/d\/8\/d\/6\/ad8d6b7248a3113bf05eef1378231ed11e7f30d0-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\/5\/3\/b\/8\/1\/53b81633313a8571c3ab3090e043e7b227fb6a66-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\/c\/d\/5\/a\/d\/cd5ad5de95b993381b5782b887d423ffe23b2664-pwa-install.jpg\" \/> <img title=\"pwa\" alt=\"pwa\" src=\"\/images\/d\/d\/8\/b\/a\/dd8ba82302aa9863e85fe6da09af74a6bba034de-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=\"\/user\/pages\/05.blog\/diystox-the-software\/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\/b\/a\/3\/7\/c\/ba37c48a4df25b8387e42463b04d8c46e723fc0e-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"}]}
