The Shetland Attack Pony 6 (SAP6) Cave Surveying Device

Basic Use

  • SAP6 is operated by 2 buttons, A (nearer the laser) and B

  • Turn ON to take readings (this is measure mode): Press A twice in quick succession

  • Turn OFF: Press A twice in quick succession

  • Switch/toggle between menu and measure modes: Hold down B

  • Select a menu item: Press A

  • Move to next menu item: Press B

  • Return to main menu: cycle though menu items to BACK option

  • You can always double click A to turn OFF and then start again (eg if you unintentionally go into calibration mode)

  • To charge the SAP6, unscrew the end cap and use a USB C cable. It takes approx 2 hours for a full charge. Do not charge the device from a powerbank whilst taking readings as this may cause interference with the magnetic readings

  • You can use the USB C cable to access files on the SAP6 and to update software for the SAP6 (details below)

Measure Mode (to take readings)

Press A to take a reading. You will get an error if the device is not already calibrated. You can choose either a short press of A (the reading is taken just after the button is released) or a long press of A (the reading is taken after about a second, or can trigger a countdown timer which can be configured). Play with each mode and see what suits you.

If the reading is successful you will see three numbers on the screen:

  • compass at the top (degrees or grad)

  • inclination (+ or - and degrees or grad)

  • distance (m or feet) at the bottom

If the reading fails you will hear an error double beep and see an error message. The laser will also flash rapidly several times.

The laser stays on in measure mode. This does not require much power

Press B to cycle through previous readings. If you have enabled show extents, you will first see the horizontal and vertical extents of the current leg. You can tell which reading you are looking at by the small number at the right side of the display. Double click B to go back to the most recent reading.

If three successive readings are similar they are interpreted as a leg rather than a splay and the device will give a success beep (rising) and flash the laser twice. Similar means that, for each of the three pairwise comparisons between the three readings, the angular difference is less than 1.7 degrees and the change in distance is less than 5cm.

There is a bluetooth indicator on the top right of the screen: bt_on if connected, bt_off if not. If you lose the bluetooth connection, the device will store up to 20 readings in the RAM memory. Readings are sent automatically when the bluetooth connection is restored.

Readings can be saved to the flash drive to provide a backup. A reading taken more than 8 hours since the previous reading will be stored in a new trip file.

There is a battery level indicator on the bottom right of the screen. If you want to save power, turn off the device between stations.

Battery Life

Test results in ideal circumstances (room temperature, about 4m range to a white wall, 10 seconds between successive readings, display on):

  • ~4500 readings taken

  • 14 hours run time

There are some factors that affect battery consumption:

  • Temperature - poorer capacity with colder temperatures

  • Range - increased battery usage with longer legs

  • Cave colouration: increased battery usage with darker targets

Troubleshooting

_images/end_with_labels.jpg

LEDs

You may see some flashing LEDs at the position indicated.

LED

Pattern

Meaning

Solid Green

Device is charging

Yellow (or red+green), 3 flashes

Device is in safe mode

Red, 2 flashes

Device has crashed

Hard Reset

Very occasionally the device will get a hard crash. The simplest thing to do is to perform a hard reset. The hard reset button is surface mounted on the PCB next to the USB socket. Use a toothpick to feel for this button on the PCB in the area indicated. You will need to press down rather than in (in the direction of the arrow on the image), and you should feel a definite click when you have found it. This will restart your device from safe mode and after a crash.

USB Drive not appearing

Occasionally you may get a condition where the device is unresponsive and it will not appear as a hard drive when connected to a laptop (or it repeatedly appears and disappears). In this situation it can be useful to deliberately enter safe mode. Safe mode is a special mode where the code on the device does not run, but the usb drive is available.To enter safe mode, press the reset button twice with about a 1 second gap. You should then see repeated yellow flashes x3.

You should now be able to connect it, update the firmware and possibly repair the filesystem - use fsck on Linux, or chkdsk on Windows.

Finally press the reset button one more time to go back to the normal mode.

Still having problems

If you are still having problems please email me. Include the contents of error.log, calibration_data.json, and config.json if they are present on the device.

Updating your software and hacking

Software updates

You can update the software on the SAP6 with newer versions downloaded from GitHub (https://github.com/furbrain/STIC/releases/latest). You can check the software version currently running on your SAP6 using the Info menu under Device.

To update your software, first connect the SAP6 to a computer - it will appear as a drive called SAP6. Next download firmware.zip from the github repository, and extract all the files to the firmware directory on the SAP6. Warning - all files should be replaced at the same time as there are various dependencies across the files and the SAP6 may not work if only a single file is updated. Check that the device is working immediately after updating.

Hacking

This is an open source project - feel free to make your own devices, make adaptations and improvements. All the hardware and software designs can be found on GitHub (https://github.com/furbrain/STIC).

SAP6 uses CircuitPython. All the code to run it is available on the device itself - just plug it into a laptop using a USB C cable and you’ll see a USB drive appear.

You can change the code as you see fit. The version of CircuitPython that comes with the SAP6 has several additional libraries built into it:

  • mag_cal: This contains all the maths needed for calibration

  • rm3100: This is a device driver for the RM3100 magnetometer

  • laser_egismos: This is a device driver for the laser module 2 by Egismos

  • caveble: This module is a cave survey specific module to talk to cave surveying apps such as SexyTopo

You can get this special version of CircuitPython from https://github.com/furbrain/SAP6_board/releases/download/1.0/sap6_cp_9.0.0.uf2

File layout

In the top level director of the USB Drive, you may see:

firmware

Directory with the application code

fonts

Directory with the fonts used by the device

images

Directory with the images used by the device

readings

Directory with any saved trips

boot.py

The code that runs on startup, before all the other python code runs

code.py

This code simply calls run in firmware/main.py

config.json

The calibration and settings data for the device

manual.pdf

This documentation

calibration_data.json

A record of all the calibration shots you took the last time you tried to calibrate

error.log

Debug info stored here if the device crashes or encounters an error

DEBUG

If this file is present, then the device is in debug mode. You can also use debug.txt, or in fact any file with debug (any capitalisation) as the basename. You won’t see the normal battery charging screen, but you can double click A and start the main device running. You also get a serial connection on /dev/ttyACM0 or /dev/ttyUSB0 on linux or COM1 on windows, which will show debug information.

Make Your Own

You can build your own SAP6! You will need access to a 3d printer and ideally a laser cutter. You will also need to make some PCBs - you can etch these yourself or get a company to do it. Seeed and JLCPCB are some of the many companies that can do this for you.

PCB

Get the gerbers from GitHub (https://github.com/furbrain/STIC/releases/latest): download pcb.zip. That will contain the gerbers for the main board and also the button board. The traces are all pretty wide so you can mill or etch the board yourself.

See the bom.csv in pcb.zip for the list of components and where to get them

Solder the components onto the board - they are all fairly chunky so you don’t need to be a whizz at soldering. Don’t solder the display on initially, this is easier to do while attaching the board to the mount. Note the button 3-pin connector goes on the bottom of the board.

Plastic parts

From GitHub (https://github.com/furbrain/STIC/releases/latest) download hardware.zip

You will need to 3d print the following STLs:

  • abs\shell.stl

  • abs\cap.stl

  • abs\bezel.stl

  • abs\shim.stl

  • abs\mount.stl

The bezel and cap may be best printed upside down. You may find it easier to print the cap_with_vanes - this has some very thin tabs to help support it as it is being printed which can then be removed. Once printed, use a soldering iron to push 4 brass M3 inserts into the holes on the end of the shell. You will also need to push one into the hole in the mount.

TPU parts

Print tpu\Boot.stl in the softest TPU you can get away with.

Acrylic parts

Ideally, you should laser cut the following DXFs from 3mm clear acrylic. However, the designs are fairly simple so you may well be able to cut these by hand

  • acrylic\End plate.dxf

  • acrylic\Window.dxf

Gaskets

  • Rubber\Cap Washer.dxf

  • Rubber\Refined Gasket.dxf

You can use 1mm silicone sheet or EVA foam for these pieces. Note that EVA foam works well but permanently deforms when used so will need replacing if you ever disassemble the device. Alternatively, generous use of silicone grease can mean you don’t need these parts at all.

Making the sled

  • First solder everything apart from the display onto both PCBs. Note you can either use a mini-SPOX connector or JST PH-2.0 connector for the battery. Check it is the right way round for your battery connector. Attaching the battery reversed may cause permanent damage.

  • Put the display in it’s location on the mount and put the main pcb on top.

  • Screw the PCB in place using a brass M3 screw, and solder the display in place.

  • Attach the cable to the laser module and the PCB.

  • Screw the laser module in place using M2 or #2 brass screws.

  • Attach your battery to the board, but don’t glue it in place just yet.

Installing software

You will first need a copy of my version of CircuitPython, which comes bundled with a few extra modules to save space, you can download it from https://github.com/furbrain/SAP6_board/releases/download/1.0/sap6_cp_9.0.0.uf2. The extra modules are listed in Hacking

You also need to put the device in bootloader mode: press the reset button twice in quick succession and plug into your computer - it should show up as a drive called “XIAO_SENSE”

Linux

If you have access to a linux computer, then there is a script in firmware\installer called installer.py:

usage: installer.py [-h] [-f] [-t] [-c] [-hw HW_VERSION] [-d] [-l]

Installer for the SAP6

optional arguments:
  -h, --help            show this help message and exit
  -f, --skip-firmware   Do not try to update the CircuitPython Firmware
  -t, --skip-tests      Skip the testing section - just install the code
  -c, --skip-code       Skip the code installation
  -hw HW_VERSION, --hw-version HW_VERSION
                        Specify the hardware version, set to 0 to skip
  -d, --debug           Place a DEBUG file in the root directory, putting
                        device in debug mode
  -l, --calibration     Place a calibration file in the root
                        directory,allowing to perform a (incorrect)
                        calibration

Copy the Circuitpython inyo the installer directory and call it firmware.uf2

Next run the script without any arguments; it will find the device, install the CircuitPython firmware, and then take you through a testing procedure for the board - it will check that everything is working; you will need to press button A, you should hear two beeps of different tones, then the display will ask you to press button B.

It will then install the rest of the code and you should be up and running

Windows

Installation instructions not done yet…

Final Assembly

You can see a video of this process at https://www.youtube.com/watch?v=XkpvDELlksQ.

  • Attach the cable to the connector on the PCB

  • Apply some silicone grease to the bottom of the boot and place on the button PCB. Make sure that A is at the end opposite where the cable comes out

  • Apply some silicone grease to the “shelf” on the boot

  • Push the boot and PCB into the shell. Make sure A is nearest the end. The cable should be pointing into the shell

  • Push the shim into the shell - it should hold it firmly in place. You may need to press the shell down against a hard surface

  • If you have used a mini-SPOX connector for the battery, bend it about 45 degrees towards the laser

  • Put a blob of glue on top of the laser and put the battery on it. This step is not in the video

  • Connect the cable from the button to the main PCB

  • Push the sled into the shell, keeping the button cable out of the way

  • The side tabs on the sled should mate into some dents in the inner wall of the shell

  • Smear some silicone grease on the end of the shell, then put the gasket on

  • Put more grease on the gasket, and put the acrylic end plate on, and screw into place with brass M3 screws.

  • Put a little grease in the channel in the base of the cap, and put the cap washer in, then a little more grease on the washer

  • Screw the cap on - and you’re done.

You will next need to calibrate the device before you use it. If you are successful in building your own, please let me know, especially if you have any suggestions to make for this guide.

Make A Derivative

Want to use different hardware? Planning to use different sensors or displays - or even processors? Here’s how to adapt the code to include your own hardware. You will need to be comfortable with enclosure design, PCB design and CircuitPython programming. This section covers the changes you will need to make to the code.

Select a hardware version

Please select a number greater than 20 as the main version number for your series of ponies! This allows me to make my own increments and keep my major version numbers sensible.

Creating a new hardware class

This is only needed if you have changed the sensors or display. You will need to create a new file in the versions directory - you can name this what you want. It should contain a class called Hardware that subclasses HardwareBase from hardware.py. It should override all the methods marked as @abstractmethod, and should have all the members described. Note that Magnetometer and Accelerometer classes should have properties acceleration and magnetic respectively: see https://docs.circuitpython.org/en/latest/docs/design_guide.html#sensor-properties-and-units. This means that most of the CircuitPython sensor drivers for accelerometers and magnetometers will “just work” if you create an instance of them.

See versions\hardware_v1.py for an example of how to implement this. Note the __init__ function takes a pins parameter - this allows you to have different versions of your setup with different PCB layouts without needing to keep updating the hardware class. You can create a new Pins class in pins.py

Creating a new display class

versions\display128x64.py is a display implementation for a 128x64 display. If you wish to use a different size display you will need to subclass DisplayBase from display.py - again you will need to override all the @abstractmethod functions. You will then need to ensure your Hardware class returns an instance of this class when create_display() is called.

Creating a new layout

Once these two steps are complete, you will need to create a Layout - this represents a specific physical implementation of the device. For example, there are two versions of the SAP6, the second (v6.2) is slightly shorter so it will fit into a Peli Micro case. You can see that there are two different layouts in layout.py - one has a slightly shorter laser offset. This could allow you to create a different enclosure, even have the PCB at right angles to how it normally is, and just add a new layout file without needing to change anything else.

Start by creating a new Layout with the same mag and grav axes and laser_offset. Set the pins entry to the name of your Pins class, and the hardware entry to the name of your hardware file.

In version.py add an entry to the LAYOUTS dict, with the version numbers for your layout.

Working out correct values for axes and laser_offset

You need to tell the pony which way round its magnetic and gravitational sensors are. With the laser pointing away from you and the display upwards, the X axis is positive to your right, the Y axis is positive away from you (along the laser beam) and the Z axis is upwards. You can use Settings->Info->Raw Data to visualise the raw output of the magnetometer and accelerometer. You specify the orientation as follows (taken from CircuitPython_mag_cal documentation):

For each axis XYZ of your device, state the corresponding axis of your sensor. Add a + or - in front to let us know if it is inverted. So for a sensor that is correctly mounted it will be “+X+Y+Z”. If the sensors Y axis points to the left of the device, the X is forwards and Z is down, specify this as “-Y+X-Z”

To determine the value for laser_offset, run the laser calibration procedure, then check config.json for the value to use as a default.

Telling the pony what it is

You need to put the hardware version in the pony’s non-volatile memory - this is stored even when turned off and is not affected if the filesystem is wiped. To set the hardware version, access the serial console and enter the following:

import microcontroller
microcontroller.nvm[-3:] = bytearray((XX,YY,ZZ))

where XX, YY, ZZ are your version numbers

When it’s all done and working, create a pull request and I will merge it into the main repo.

Why not just fork the repo and overwrite the hardware code?

Well you could! This is open source after all. However, by going through the steps above means that you can continue to benefit from any updates to the main SAP6 codebase - you can just download and copy over new versions of the firmware and everything should just work.