This the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Documentation

This is a combined documentation for everything related to DaSCR - score and more.

You can find the corresponding documentation to the different pieces of software on the left side in the navigation menu or down below.

1 - DaSCR-Board

Find all relevant information to use DaSCR-Board here!

1.1 - Overview

Get started with DaSCR-Board, the score tracking app.

Get up and running in no time.

What is it?

DaSCR-Board is a score tracking app written in go and SvelteKit. It consists of a RESTful backend api and a webfrontend.

Why do I want it?

You are tired of typing in the score when playing darts? So this one might be for you.

  • What is it good for?: DaSCR-Board can keep your darts score while playing darts for you. You can use it with a recognition software to automate the process or you can use it like any other darts scoring app. You can even host it online to play network games with your friends.

  • What is it not good for?: If you want to keep track of statistics and such this one might not be for you. Also it is not preventing one from typing in scores for other players during game.

  • What is it not yet good for?: Features who are about to be implemented in the future are certainly more games.

Where should I go next?

1.2 - Getting Started

Get ready to install things :D

This project requires basic command line knowledge

This section will lead you through different steps to get up and running in not time.

  • Checking Prerequirements
  • Getting the code
  • Installing dependencies
  • Building Backend and Frontend

This guide assumes you are using linux. The instructions easily transfer to other operating systems if you know your way around the tools used.

1.2.1 - Prerequirements

Checking and installing prerequirements

For this software to work you will need a few prerequirements:

  • Git
  • Go
  • Nodejs
  • Yarn

Git

You will need to have git to checkout the code we will use to build the software. As an alternative you could just download the main branch as .zip file and unzip it instead.

I am using the current git version:

❯ git --version
git version 2.30.0

Go

The backend is written in go. So you will need to get that and install it for your operating system. The version of go I am using as the time of writing is:

❯ go version
go version go1.17 linux/amd64

GCC

The backends sqlite library needs to use CGO. That’s why you will need gcc on your system. The version I use is:

❯ gcc -v
--- output ommited ---
gcc version 11.1.0 (GCC)

Read more about CGO here

NodeJS & npm

The frontend is written in SvelteKit. Therefore you will need to get NodeJS to build it. I am also using pnpm as a package manager. The Makefile which we will use in the next step is using pmpm. Therefore I recommend installing and using it.

As the time of writing I am using the following versions:

❯ node --version
v14.17.5

❯ pnpm
Version 6.13.0

All Prerequirements met?

Continue with the basic setup:

1.2.2 - Installation

Fetch the code and install DaSCR-Board

Fetch the code

Navigate to a folder where you want the app to reside in and clone it’s repository using git (or unzip the master.zip downloaded from GitHub Repo there):

git clone https://github.com/dascr/dascr-board
cd dascr-board

Content of the root directory

As this is a monorepo where the backend and the frontend reside, it might be a bit confusing at first. But fear not as I will describe how that works now.

.
├── api
├── config
├── database
├── docker-compose.yml
├── Dockerfile
├── frontend <--- Frontend App (SvelteKit)
├── game
├── go.mod
├── go.sum
├── LICENSE
├── logger
├── main.go
├── Makefile
├── player
├── podium
├── README.md
├── score
├── settings
├── throw
├── undo
├── uploads
├── utils
└── ws

Everything except the frontend folder is the backend app. The frontend Svelte app resides in the frontend folder. It is that easy.

Content of frontend folder for reference:

.
├── caddy
├── Dockerfile
├── jsconfig.json
├── node_modules
├── package.json
├── postcss.config.cjs
├── src
├── static
├── svelte.config.js
└── tailwind.config.cjs

DaSCR is using “.env”

What does that mean? There are different variables which are not read from a config file, but which are read from the environment. So you could for example do this:

export API_IP=0.0.0.0

This would set the variable API_IP used by the backend for this very session of your terminal. To ease the pain I am using .env files with my Makefile. Consider this as a kind of a config file itself.

So to use the Makefile you will need to create two files.

Backend

In the root folder of the project create a fille called .env. The content of it is:

API_IP=0.0.0.0
API_PORT=8000
DEBUG=FALSE

Here is the explanation of the content:

  • API_IP: This one will determine to which ip address the backend server is bound to. 0.0.0.0 means to any interface address. It could also read something like 192.168.1.X to bound it to a local network address.
  • API_PORT: This one will determine to which port the backend server is bound to.
  • DEBUG: This one will control how much output the application is giving you. Most of the time the value FALSE is good enough. But if you want to develop this you might want to choose TRUE instead.

Frontend

In the frontend folder also create a file called .env. The content of it is:

VITE_API_URL=http://localhost:8000/api
VITE_API_BASE=http://localhost:8000/
VITE_WS_URL=ws://localhost:8000/ws

This example reflects hosting it on a system in host only mode. You will not be able to use it other than on the system itself this way.

Here is the explanation of the content:

  • API_URL: This one points to the api endpoint of the backend which is protocol://ip address:port/api
  • API_BASE: This one points to the base address and has to match everything above but leaving out /api
  • WS_URL: This one points to the websocket endpoint of the backend. Instead of api it should read ws

Checked out code and created .env * 2?

Continue with building either one of those:

1.2.3 - Backend

Build the Backend API

Build using Makefile

To build the backend you can simply use the provided Makefile. Possible make targets to build the backend are:

  • build-linux_64
  • build-linux_386
  • build-mac
  • build-armv5
  • build-armv6
  • build-armv7 (Raspberry Pi 3 + 4)
  • build-armv8_64

So if you want to build on linux you for example issue:

❯ make build-linux_64
[*] go mod dowload
[*] Building for linux x64
[OK] App binary was created!
[OK] Your backend binary is at ./dist/<os>/

Now you have a binary ready to use:

dist
└── linux_amd64
    └── dascr-board

Windows?

In Windows you can also build this project. I tested it using MSYS2. After installing this I followed this instructions to setup my MSYS2 environment.

After setting up accordingly you can build like (from root directory of project within MSYS2 cli):

go mod download
go build -o dist/windows_amd64/dascr-board.exe

What’s next?

You could either run it right now using the Makefile (which will use the previously created .env file) and issue make run-dev-backend or run it like so (from the ./dist/<os>/ folder):

API_IP=0.0.0.0 API_PORT=8000 DEBUG=FALSE ./dascr-board

Want to have a Web UI?

  • Frontend: Go ahead and build the frontend

1.2.4 - Frontend

Build the Frontend Web UI

Build using Makefile

Your best bet is to use the Makefile on this, too. Just issue:

❯ make build-frontend
[*] Cleanup SvelteKit App
[OK] Cleanup done
[*] Building SvelteKit App

> dose@1.0.0 tailwind:build
> cross-env TAILWIND_MODE=build cross-env NODE_ENV=production postcss src/styles/tailwind.css -o src/styles/tailwind-output.css

warn - You have enabled the JIT engine which is currently in preview.
warn - Preview features are not covered by semver, may introduce breaking changes, and can change at any time.
Source path: redacted
Setting up new context...
Finding changed files: 3.293ms
Generate rules: 32.227ms
Build stylesheet: 0.688ms
Potential classes:  2550
Active contexts:  1
Content match entries 1126
JIT TOTAL: 113.848ms

> dose@1.0.0 build:only
> svelte-kit build

[... snip ...]

3:56:22 PM [vite-plugin-svelte] The following packages did not export their `package.json` file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.
- ky
103 modules transformed.

[... snip ...]

[dotenv][DEBUG] did not match key and value when parsing line 4:
vite v2.5.1 building SSR bundle for production...
transforming (70) .svelte-kit/build/runtime/internal/singletons.js

[... snip ...]

3:56:25 PM [vite-plugin-svelte] The following packages did not export their `package.json` file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.
- ky
105 modules transformed.
.svelte-kit/output/server/app.js   329.07 KiB

Run npm run preview to preview your production build locally.

> Using @sveltejs/adapter-static
done
[OK] SvelteKit App was built
[OK] Serve content of ./frontend/build via a webserver

Content of the build folder for reference

.
├── _app
├── css
├── favicon.ico
├── fonts
├── img
├── index.html
├── js
├── player
├── sounds
└── webfonts

What’s next?

Now everything left to do is to server the content of frontend/build via a webserver like Apache2, Nginx or Caddy2.

You could instead also run it right now using the Makefile (which will use the previously created .env file in frontend folder) and issue make run-dev-frontend.

Ready to throw darts?

1.3 - Usage

How do I use it?

This section will tell you how to use DaSCR-Board

This section will lead you through different steps to setup player and run games.

  • Managing player
  • Choose your ID
  • Setup a game and start
  • Different views

1.3.1 - Page Overview

What pages are there?

TL;DR?

  • Setup a player at /player
  • Start a game at /<your-game-id>/game
  • Point the scoreboard browser to /<your-game-id>/scoreboard
  • Point the browser you want to add in throws with to /<your-game-id>/controller
  • Enjoy

The pages

There are different pages you can navigate to when using DaSCR-Board. After setting up your players you will only be needing to navigate to two pages, though. Here is an overview of the different pages one can go to:

  • General Index
  • Player Management
  • Game Index
  • Game Setup and Start
  • Scoreboard
  • Controller

Choose the page you want to learn about in the navigation menu on the left.

For the ease of writing I will refer to the pages with url paths and ommiting the part http://localhost:8000.

1.3.2 - General Index Page

This page is the one you might see first

General Index Page

Path

You can see this page at /. It will let you have an overview of the different games running in the table at the page bottom. Also it will give you short instructions on how to start. The navigation symbol top left lets you navigate through different pages.

1.3.3 - Player Management

This page will let you manage players

Player Management

Path

You can see this page at /player. It will let you add and remove player to the machine. There is no gameid specific player management. So all players added will be available to choose.

Add

Add a player by insterting the name and the nickname (optional) in the corresponding form fields. You may want to upload a avatar picture. If so you can scale it in the players preview card to the right of the creation form using the mouse.

If you do not upload an image one out of 9 animal avatar images will be chosen randomly.

Delete

You can delete a player by hitting the Delete button in the available player card.

1.3.4 - Game Specific Index

This page is the game index page of a specific game id

Game Index

Path

You can see this page at /<game-id>/start. This page is supposed to be displayed at a big screen where everyone can see it. You can for example hang a big screen right above the dart board at the front or maybe use a projector to beam this page on a wall.

Purpose

This page can let your players scan the QR code with a smartphone for example and then setup a game. After starting a game this page will automatically redirect to the corresponding scoreboard page and show the score of the ongoing game.

1.3.5 - Game Setup Page

This page is the game setup page of a specific game id

Game Setup

Path

You can see this page at /<game-id>/game. This page is supposed to be displayed at a small screen like the one of a smartphone or tablet.

Purpose

The page will let you setup the game you want to play and also show you the rules which are applied to the game. After starting a game this page will automatically redirect to the corresponding controller page and let you handle the game.

1.3.6 - Scoreboard

This page is the scoreboard of a specific game id

Scoreboard

Path

You can see this page at /<game-id>/scoreboard. This page is supposed to be displayed at a big screen at the front.

Purpose

The page will let you see the score of a game. It will also look different for every gametype you choose. After ending a game it will automatically redirect back to the game specific index page and waits for another game to start.

Further Screenshots

Scoreboard

Scoreboard

Scoreboard

1.3.7 - Controller

This page is the controller of a specific game id

Controller

Path

You can see this page at /<game-id>/controller. This page is supposed to be displayed at a small screen like a smartphone or a tablet.

Purpose

The page will let you control the game, insert throws, undo actions and end the game. see the score of a game. It will also look different for every gametype you choose. After ending a game it will automatically redirect back to the game setup page and let you start another game.

Further Screenshots

Controller

Controller

Controller

1.4 - Deploy

Learn how to use it in production

Choose from an option and deploy

Options

You can either deploy it using Docker or you do it by hand. As you may already have built the project following the getting started instructions you can also do it by hand.

Example Environment

The two described options docker and manual will be using an example environment you can relate to.

The environment will be described in this section.

Consider a root server running Debian hosted by a provider online. You have root access to it via ssh and you have a domain pointing towards the public IP of this root server. Let’s assume the domain you own is dascr.org.

❯ host dascr.org
dascr.org has address 45.142.179.121

patrick@ssh-dascr-org ❯ pwd
/home/patrick/projects/dascr-board

You already at least have the prerequirements setup and cloned the code to disk on this root server.

Now you might wanna look at one or both of the deployment options then.

1.4.1 - Docker Deployment

How to use docker do deploy it

Instead of building everything by hand like described in the getting started guide you can also use docker.

Locally

There are two Dockerfiles, one in the root of the directory and one in the frontend directory. Those will build two independant docker images you can run like this:

docker build . -t dascr-board-backend
docker build ./frontend -t dascr-board-frontend

Running it

When running you need to be sure to let them run in the same network and to expose the corresponding ports (5000 - frontend, 8000 - backend) to be able to use the container.

Docker-Compose

As there is a docker-compose-local.yml in the root folder you can do all of this by just issuing:

docker network create dascr
docker-compose -f docker-compose-local.yml up

Different IP Address than localhost

By default the procedure above will build the docker image in a way where the scoreboard will only work on the system it was built on. If you need to separate the “viewing client” from the client running the scoreboard, you will need to use the Makefile to build and first run the docker image.

Step 1 will be to create a file called .env in the folder frontend as described at Installation#Frontend and fill in the corresponding ip address of the host running the scoreboard. Then you issue make run-docker for the customization to be applied at build time.

It should run the Scoreboard on port 8080 on that ip you chose and also it should be reachable and functional from within your network.

For the second startup docker-compose -f docker-compose-local.yml up should be enough.

Docker Release Image

If you do not want to build the docker images yourself this repository also has the latest version as an Release Package. I provide the file docker-compose-repo.yml for easy running as well.

docker network create dascr
docker-compose -f docker-compose-repo.yml up

After a successful startup you can access the web ui at port 8080.

What’s next?

When running the container successfully you can continue with webserver setup.

  • Caddy2: You might wanna continue setting up caddy2 server to serve the frontend UI

1.4.2 - Manual Deployment

How to build and autostart DaSCR-Board using systemd

Basically it is as easy as running through the getting started guide on your remote server.

Autostart backend using systemd

If you have successfully built the backend and the frontend you will have the backend binary in place and the public folder for serving with for example caddy2.

You can now use this systemd service file to automate the startup of the backend binary like so:

[Unit]
Description=DaSCR Board - Backend API
After=network.target

[Service]
Type=simple
User=patrick
Group=patrick
Restart=always
RestartSec=5s

Environment=API_IP=0.0.0.0
Environment=API_PORT=8000

WorkingDirectory=/home/patrick/projects/dascr-board
ExecStart=/home/patrick/projects/dascr-board/dist/linux_amd64/dascr-board
SyslogIdentifier=dascr-board

[Install]
WantedBy=multi-user.target

Save it at /etc/systemd/system/dascr-board.service.

Then run:

sudo systemctl daemon-reload
sudo systemctl start dascr-board
sudo systemctl enable dascr-board

Now the service should be up and running and be started at system boot time automatically.

You can check running sudo systemctl status dascr-board.

What’s next?

  • Caddy2: You might wanna continue setting up caddy2 server to serve the frontend UI

1.4.3 - Webserver setup

How to use caddy2 to serve the frontend UI

This section can also be solved using Apache2 or Nginx. I personally like Caddy2 much so I used it to deploy it. Therefore I will show my config as an example here.

You will need to install it yourself, though. It is kinda easy, I guess.

Caddyfile

My caddy file written to /etc/caddy/Caddyfile looks like this:

dascr.org {
	root * /home/patrick/projects/dascr-board/frontend/build
	encode gzip

	handle /api/* {
		reverse_proxy localhost:8000
	}

	handle /images/* {
		reverse_proxy localhost:8000
	}

	handle /uploads/* {
		reverse_proxy localhost:8000
	}

	handle /ws/* {
		reverse_proxy localhost:8000
	}

	handle {
		try_files {path} {file} /index.html
		file_server
	}

	header {
	# enable HSTS
	Strict-Transport-Security max-age=31536000;

	# disable clients from sniffing the media type
	X-Content-Type-Options nosniff

	# clickjacking protection
	X-Frame-Options DENY

	# keep referrer data off of HTTP connections
	Referrer-Policy no-referrer-when-downgrade
	}

	log {
		output file /var/log/caddy/dascr-board.log {
			roll_size 1gb
			roll_keep 5
			roll_keep_for 720h
		}
	}
}

Running this config you should have the frontend up and running at the domain https://dascr.org.

Basic Auth

If you want to protect your page from beeing used publicly you can also apply basic authentication by generating a user:pass combination like so (’test’ is the password in this example):

caddy hash-password -plaintext test
JDJhJDE0JGw1Ti43eW8ycW5vVTc1TDZVbDZBc09XVnI2YVJmYkM1VlguV0lHL1RsMkNBejkvLlFBUFFx

You can also completely omit -plaintext ... and will be prompted to insert the password without it landing in the history of the server.

Then you add this configuration bit to the Caddyfile:

basicauth * {
		username JDJhJDE0JGw1Ti43eW8ycW5vVTc1TDZVbDZBc09XVnI2YVJmYkM1VlguV0lHL1RsMkNBejkvLlFBUFFx
	}

What’s next?

  • Development: Wanna contribute? Have ideas? Go ahead!
  • API: Wanna use your own recognition software? Read the API specs.

1.5 - Develop

You want to contribute? This one is for you.

I have way to less time to explain my code here. If you are thinking about adding features or fixing bugs I consider you are already familiar with go and JavaScript/SvelteKit, as well as the tooling used around developing backend and frontend services.

I will take every pull request seriously. So go ahead, fork me, do your thing, create a pull request and I’ll review it.

1.6 - API

See the API documentation here

1.7 - FAQ

Those are the Frequently Asked Questions and known Bugs.

If you find something is behaving odd, you should look here first.

My Scoreboard page is not updating when entering score?

This might come from the fact, that dascr-board is now using sound. As the frontend is using an await to resolve a so called promise when playing sounds the frontend will not get updated if the sound does not play properly. I discovered firefox and google chrome to sometimes prevent from playing sounds properly, thus the frontend is not updating at all. Make sure to allow sound and video for the url (ip address) you are hosting you frontend with.

2 - DaSCR-Machine

Find all relevant information to use DaSCR-Machine here!

2.1 - Overview

Get started with DaSCR-Machine, your very own softdart machine

You ready for some soft dart goodness?

What is it?

DaSCR-Machine is an Arduino based soft dart machine sending your score to DaSCR-Board as a score tracking app. The software components are written in C++ on the Arduino side and the service communicating with the scoreboard is written in go.

Why do I want it?

You are tired of cheap soft dart boards breaking after a few weaks intensive game play? You want a machine like a “Löwen Dart HB8” but not wanna pay 1500 bugs for it? So this one might be for you.

  • What is it good for?: DaSCR-Machine is a cool project to work on in your spare time. It will give you a fully fledged darts machine in high quality when succeeding.

  • What is it not good for?: I did not and will not add display, segment display or such to this software. As it is open source you are very welcome to implement it yourself.

Where should I go next?

  • Hardware: Get started with DaSCR-Machine

2.2 - Hardware

You need to know what hardware you are supposed to have - so look in here!

I will split this section in what I bought to build this bad boy and what I already had by hand. You will need to apply this to your situation as you might not have everything layin around readily available, though.

2.2.1 - Electronics

Everything you will need which has to do with electronics

This is what I bought to build the machine:

2.2.2 - Tools

A basic overview of tools and little parts I used to build the machine

This tools and parts I had laying around:

  • Solder Iron
  • Cables
  • Prototyping Breadboard
  • Perforate board
  • Resistor set
  • Shrink tube
  • LED strip 12V

2.2.3 - Case

Everything you need to buy to build the case itself

I was following this Youtube Video to design my case and therefore bought:

MDF (medium-density fiberboard)

  • For the segments: 480mm X 520mm X 12mm

Plywood

  • matrix: 520mm x 520mm x 18mm
  • door: 600mm x 750mm x 12mm
  • back panel: 600mm x 750mm x 12mm
  • 3 times front board: 750mm x 200mm x 12mm
  • bottom: 750mm x 200mm x 12mm

2.3 - Overall Cost

Calculation of the overall cost

As I was asked a lot lately here are the overall costs

  • Arduino: 16,00 €
  • PCB: 7,50 €
  • Raspberry Pi: 58,00 €
  • SD Card: 7,00 €
  • Button: 8,00 €
  • Piezos: 10,00 €
  • Ultrasonic Sensor: 4,00 €
  • Löwen set with matrix: 190,00 €
  • Case Lock: 10,00 €
  • MDF: 2,50 €
  • Plywood: 45,00 €
  • Color: 9,00 €
  • Inking roller: 4,50 €
  • Self-adhesive numbers: 20,00 €

Not taken into account

  • LED strip: about 15,50 €
  • Power supply: 20,00 €
  • Little parts like wires, resistors, shrink tube, …: 25,00 €

Overall

The cost of this machine is about: 452 € total.

2.4 - Pinout

This is the pinout used with the Arduino Mega 2560

To ease the pain of wiring this all to the arduino I created a pcb to function as a header on the Arduino Mega 2560. You can find it in the Github Repo and can order it online for example here.

Component PIN Arduino PIN
Push Button LED + 3
LED - GND
Signal + 2
Signal - GND
Ultrasonic Sensor VCC 5V
TRIG 9
ECHO 8
GND GND
Piezo 1 S A0
- GND
Piezo 2 S A1
- GND
Matrix socket 1 22
2 24
3 26
4 28
5 30
6 32
7 34
8 36
9 38
10 40
11 42
12 44
13 46
14 48
15 50
16 52
17 53
18 51
19 49
20 47

2.5 - Build the case

Now you need to use your tools

This instructions will be devided into different steps.

Use the menu to go throught the process of building the case.

2.5.1 - Step 1 - Segment section

Build the segment section with spider

The segment section is made of MDF and is 480mm X 520mm x 12mm.

Segment section
Board for segment section

First you define the center of the board for the router to be locked in place. Then you might want to test your jig to see if you are able to cut a perfect circle. We did so with a leftover wood piece.

Segment section
Mark the middle
Segment section
Test cut in leftover wood

So now for the fun part. First you take of 2 mm of the outer radius of the spider for it to be even to the board later on. Then you cut through the board with the inner radius for the spider to be able to stick through the board later on.

We did so by doing the cut from one side until half the thickness of the board. Then we flipped over the board and did the final cut from the other side. This way you will prevent from having splinters all over the place.

Segment section
Cut outer radius 2 mm deep
Segment section
Outer radius finished
Segment section
Cut through board after flipping over
Segment section
Spider fits through hole

Now you can fit the spider through the hole and screw it to the board. Be sure to align it properly first. At the back side of the board it is supposed to be plane even so it can be fitted to the matrix section later on.

Finally you can now screw the catch ring segments to the front side of the segement section by screwing them in place from the back side of the board.

Segment section
Screw catch ring segments in place
Segment section
Screw catch ring segments in place

The segment section with spider is now finished. Continue with building the matrix section.

2.5.2 - Step 2 - Matrix Section

Build the matrix section

The matrix section is made of plywood and is 520mm X 520mm x 18mm.

Matrix section
Board for matrix section

You need to measure the exact middle of the board and then you draw a cross like in the picture. Although the matrix has a paper on its sticky side you should be able to see through an perfectly align the matrix. Also for orientation you might want to use the pressure points of the matrix.

Matrix section
Matrix is aligned and fixated with sticky tape

At this point you do not yet stick the matrix to the board using its sticky back. You better fit the segment section to the matrix section now and test the function.

If that is the case you mark the position of the matrix with a sharpie or pencil on the board, then remove the protective paper from the sticky side of the matrix and then apply it to the board in the marked position. Again, be aware of the marked position and perfectly align the matrix again.

Matrix section
Finished unit

Finally you can screw the segment section to the matrix section. Be sure not to screw through any traces of the matrix below.

The unit is now finished. Continue with aligning the unit on the back panel.

2.5.3 - Step 3 - Back panel and unit alignment

Build the back panel and align the unit on it

The back panel is made of plywood and is 750mm X 600mm x 12mm.

You now need to align the unit on the back panel. Leave enough space at the bottom to fit the electronics and also be sure to center align it horizontally.

Back panel
Finished unit is perfectly aligned on back panel

Then you drill through the matrix board and the back panel in every of the 4 corners. I just glued in threaded screws to the back side of the back panel to be able to fixate the unit from the top side of it.

Back panel
Glueing in the threaded screws
Back panel
Screws are in place
Back panel
Fixate unit

This step is now finished. Next up: the door.

2.5.4 - Step 4 - The door

Build the door

The door is made of plywood and is 750mm X 600mm x 12mm.

You need to measure and project the exact middle of the dart board (segment section) to the door to be able to cut out the hole for the dart board using your router and the jig.

Door
Drill hole for router in the middle of the board

Now you can cut a hole with the radius of the dart board into the door. Be sure to make it about 1,5 mm bigger as the radius of the board to be able to apply the edge protector later on.

Door
Cut the door

Now you can test the fitting of the door.

Door
Door fits with edge protector applied

Finally you drill the hole for the button.

Door
Button in door

The door is now finished. You can continue by applying the side panels then.

2.5.5 - Step 5 - Side panels

Build the side panels

The side panels are made of plywood and are 750mm X 200mm x 12mm each.

We fitted the side panels onto the back panel from behind. We started by doing the side ones and then fitted another one on the top.

Side panels
Side panel screwed to back panel

Repeat for all side panels (left, right, top) and then continue with painting the case.

2.5.6 - Step 6 - Painting the case

I see a red door, and I want it painted black sings

Next I painted all the parts black. I used a mat black paint. I applied it using a roller. I also just applied it once as the wood pattern was still shining through what I find to look very sexy. If you want that not to happen you might have to paint it a second time.

Painting
Door is painted black
Painting
Rest of case painted black

While the painting dries you can continue by finishing the unit by adding the rest of the segments.

2.5.7 - Step 7 - Segments and piezo sensors

Finish the unit by adding rest of segments and the piezo sensors

While the color on the case dries you can add the rest of the segments to the segment section.

Finishing unit
Spider has all segments now

You will need to separate the segemnt section from the matrix section to do that. So while you are already in you can as well just stick the piezo sensors with a bit of sticky tape to the segment section and let the electronics hang from the side like pictured below.

Finishing unit
Piezo with electronics hanging from the side

Case is dry now? Well then you can fit the electronics in place.

2.5.8 - Step 8 - Fitting electronics

Install the electronics

I decided to use jumper cables from a prototyping set and just apply shrink tube to the ends for it to look like a plug. So later on it can just be plugged into my custom designed PCB.

Electronics
Shrink tubes are now plugs

You need to mark the holes for the Arduino and the Raspberry Pi on the right spots, then drill a hole and fixate them. I used plastic standoffs for this job.

Electronics
Arduino and Pi secured in casing

Finally you screw the unit back into place.

Electronics
Unit is connected to back plate again

It’s now time to manage all the cables.

2.5.9 - Step 9 - Cable management

Run all the cables through the cabinet

Now you can run all the cables through the machine.

I installed the ultrasonic sensor from above drilling two holes in the top plate and ran the cables from behind into the machine and down to the Arduino.

I fixated the cables with duct type here and there. There might be better ways to manage the cables though. After about 2 years now the duct tape starts to come loose. You might want to better apply other, cleaner cable management techniques.

Electronics
Cables running to the Arduino
Electronics
Complete view into cabinet
Electronics
Machine standing upright
Electronics
Ultrasonic detail view

It is now the time to lock the door of the machine.

2.5.10 - Step 10 - Door with lock

Lock the door!

Now you can fixate the edge protection with a stapler to the hole where the segments go through like in the picture below.

Door lock
Door now has edge protection and fits perfectly

To better lock the door in place I drilled a little hole from the sides and from above through the side panels right into the door. So you can insert a nail as lock machism #1, as you can see from this picture.

Door lock
Nail inserted from above into the door

Finally you place the actual lock into the doors bottom edge for example. Be sure to apply a piece of wood to the casing where the lock can lock into place. I sure bet you can figure this without a picture :D

Door lock
Machine standing upright

Let there be light!

2.5.11 - Step 11 - LED strip

And we said, Let there be light: and there was light.

For the light cover I used angular wood, painted it and glued it to the front of the casing as you can see from the picture below.

light
Covers are glued to the case
light
Covers are done

Now there is enough room to stick the LED strip onto the covers bottom side. To prepare for this I cut the strips to size and soldered the cables for the power to them already.

The strip has a sticky side itself which I applied to the bottom side of the covers. I also secured them temporarily with additional sticky tape.

light
LED strips are glued to the covers

The black and yellow cables on the side of the case are the LEDs power cables. I ran them at the top outside the machine like I did with the ultrasonic sensor and drilled them back into the case at the bottom level so no one will see any cables while playing.

The power supply has one 12V, 5A side where I connected the LED strips to. The are not controlled by the Pi or the Arduino, but will just light up as the machine gets power. You might as well want to run them through one of the systems to be able to control when they light up. Then you could let them blink and such. I decided not to.

light
Power supply is in place

I drilled a hole into the bottom bit of the machine to be able to run a connecting cable into the the power supply, as well as a network cable.

The black and red cables are connected to the Raspberry Pi and will deliver power to it.

You need to count on the next one!

2.5.12 - Step 12 - Applying numbers

Stick the self adhesive numbers to the door

To be actually able to tell where you need to hit the board you will need numbers on the door. I ordered self sticking numbers for that purpose.

numbers
Numbers layed out onto the door

I used a template I made to find the middle of each segment. This helped me to align and stick the numbers to the right place.

numbers
Template in action

Well, what should I say. Let there be patience and a sharp eye and eventually you are finished and your numbers now look like this.

numbers
All numbers applied

This is how the machine will look like with numbers applied and LEDs turned on.

numbers
Finished

Next is the PCB (optional).

2.5.13 - Step 13 - Finish PCB

Solder connectors in place

I designed this PCB to fit all my connectors comfortably and then connect in place onto the Arduino. This way you can quickly disconnect everything and reconnect it back again.

pcb
PCB (old version) unprovisioned
pcb
Back side

Now all you need to do is solder male sockets facing downwards onto the back side and solder angeled male sockets to the top side as pictured below.

pcb
PCB provisioned top view (old version)
pcb
PCB provisioned back view

I applied the angled mail sockets in a really steep angle so the connects fit better later on.

pcb
PCB provisioned profile view

Now you can connect everything in place, which will look like so.

pcb
Everything connected together

You are done now. This was the easy part (if you are more the woodworking guy) or the hard part (if you are more the software guy). Either way you can now continue with setting up OS, Software and such.

2.6 - Arduino

Flash the Arduino Mega 2560

For the inputs to handle we use an Arduino Mega 2560 which has a microcontroller. The controller is running a simple C++ program you can find in the GitHub Repository, readily available to be flashed.

You can either use Arduino IDE to do so. Just open the sketch, choose the right board type and port and then upload it to the Arduino.

Another possibility would be to use something like an Arduino-Makefile to transfer the ino sketch to a hex file and then flash it using avrdude.

For simplicity I suggest using Arduino IDE as it runs on all major Operating Systems.

2.7 - Raspberry Pi

Setup the Raspberry Pi

So I am using a Raspberry Pi 4 to connect the Arduino to. On the Raspberry Pi there runs a connector service which will handle the output of the Arduino and give it to the Scoreboard (in my case this is DaSCR-Board as you can tell).

For this purpose I am using go once again. You also can run DaSCR-Board and DaSCR-Machine all from that single Pi inside your darts machine. This should be enough ressources to handle both of it.

Prerequirements

Also you system needs to have a running operating system (I chost raspbian for simplicity) and be integrated into a network. You can do that either using WIFI or a cable. Best would be to connect to the system via SSH for the next steps.

Installing Software

Clone or download the repository to that Raspberry Pi. In the folder called service you will find the go program.

Issue those commands to build it:

go mod download
go build -ldflags "-s -w" -o dist/dascr-machine

Now you will have an executable called dascr-machine in the folder called dist.

You can test run it from that folder calling the command from the listing below. Be sure to have the Arduino connected to the Pi.

INT=any ./dist/dascr-machine

You should see something like this when running:

INT=any ./dist/dascr-machine
INFO   [2021-02-08 13:18:50] Navigate to http://0.0.0.0:3000 to configure your darts machine
INFO   [2021-02-08 13:18:51] Connected to websocket @ wss://demo.dascr.org/ws/dascr
....

Configure and autostart

You are almost already there. Now you just need to know how to configure it and how to autostart it when powering on the machine. That is pretty much simple.

First you need to understand that the webserver will be served on the IP address of whatever interface you provide with the environment variable INT. In the example above I chost it to be any which will just bind it to every interface. Most of the time this is the best option. You could have bound it to ethX or wifiX or whatever you Pi communicates with. I suggest you use any as I did.

Next up you can setup autostart using a systemd service file:

[Unit]
Description=DaSCR Machine
After=network.target

[Service]
Type=simple
User=patrick
Group=patrick
Restart=always
RestartSec=5s

Environment=INT=any

WorkingDirectory=/home/patrick/projects/dascr-machine/service/dist
ExecStart=/home/patrick/projects/dascr-machine/service/dist/dascr-machine
SyslogIdentifier=dascr-machine

[Install]
WantedBy=multi-user.target

Put the content of this listing into a file /etc/systemd/system/dascr-machine.service and then call:

sudo systemctl daemon-reload
sudo systemctl start dascr-machine
sudo systemctl enable dascr-machine

This will reload the systemd service and start the machine connector service. Also it will mark it to be autostarted when the machine powers on.

You can check the status of the service with this command:

sudo systemctl status dascr-machine

Final steps

Now you can navigate to the Raspberries IP address on port 3000 to setup the connection. When using any as interface it will tell you it’s 0.0.0.0 but it is not. You then will need to use the real IP address of your Pi like for example http://192.168.1.175:3000.

Navigate to it to configure your machine to use the Scoreboard and the Arduino.

home screen
Home Screen of DaSCR-Machine

You will see the start page and click on the Admin link in the top left to see the setup dialog.

setup screen
Setup Screen of DaSCR-Machine

Be sure to fill in everything correctly:

  • Ultrasonic delay will tell the machine how long to wait until switching to next player after it was triggerd

  • Piezo threshold is a variable to controll the senitivity of the piezo sensors which will detect missed darts bouncing from the case or landing into the outer catch ring. 20 is a default which was working quite well for me. So my guess is you could just leave it there

  • Serial port needs to represent the connection of your Arduino. It will be listed in the directory /dev of your operating system and will almost certainly be of type ttyAXXX. So running ls /dev/ttyA* in your PIs ssh session could tell you what to put here.

Hit ‘Save’ then to save the configuration.

Then proceed with scoreboard configuration

You need to fill in ip address and port of the system running the scoreboard. If you are running it on the same Raspberry Pi in the machine you can put localhost and port 8000 I suppose. Otherwise refer to the system with the public IP address and the API Port. You also need to choose the game id the machine should send the score to.

When running against a publicly available instance of DaSCR-Board like I did in the screenshot above you might need to put in Basic Auth credentials and choose wether to use HTTPS or not.

If you ran through the guide of DaSCR-Board and how to get it up and running you certainly know what to put here.

Shutdown button:

There is a shutdown button to stop the underlying Raspberry Pi. If you want to use that you might need to issue this to allowing your user to shutdown the Pi:

sudo chmod 4755 /sbin/shutdown

2.8 - Custom designed PCB

This is about the custom PCB I designed to fit the Arduino

Using EasyEDA I designed the header PCB to fit on top of the Arduino Mega 2560.

Using it is totally optional, although I recommend using it for easier connecting the cables to the Arduino.

You can find it in the repository as a gerber files bundle in zip format.

I ordered mine from here and it took about a few days and was kinda really cheap. Although I needed to order 5 pieces it was about 7,50 € including shipping to Germany.

pcb
PCB design
pcb
PCB provisioned top view (old version)