{"id":25747805,"url":"https://github.com/elixir-circuits/circuits_quickstart","last_synced_at":"2026-04-01T19:07:38.396Z","repository":{"id":37895364,"uuid":"183940240","full_name":"elixir-circuits/circuits_quickstart","owner":"elixir-circuits","description":"Try out Elixir Circuits on Nerves!","archived":false,"fork":false,"pushed_at":"2026-03-16T23:34:40.000Z","size":2593,"stargazers_count":102,"open_issues_count":1,"forks_count":17,"subscribers_count":8,"default_branch":"main","last_synced_at":"2026-03-17T09:55:37.632Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elixir-circuits.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSES/CC0-1.0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-04-28T17:44:23.000Z","updated_at":"2026-03-16T23:34:42.000Z","dependencies_parsed_at":"2022-07-07T23:12:47.072Z","dependency_job_id":"377433e6-32d4-499a-921d-88892c645c8d","html_url":"https://github.com/elixir-circuits/circuits_quickstart","commit_stats":null,"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/elixir-circuits/circuits_quickstart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-circuits%2Fcircuits_quickstart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-circuits%2Fcircuits_quickstart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-circuits%2Fcircuits_quickstart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-circuits%2Fcircuits_quickstart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elixir-circuits","download_url":"https://codeload.github.com/elixir-circuits/circuits_quickstart/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-circuits%2Fcircuits_quickstart/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291068,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-26T12:18:11.342Z","updated_at":"2026-04-01T19:07:38.364Z","avatar_url":"https://github.com/elixir-circuits.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\n  SPDX-FileCopyrightText: None\n  SPDX-License-Identifier: CC0-1.0\n--\u003e\n# Elixir Circuits Quickstart Firmware\n\n[![CircleCI](https://dl.circleci.com/status-badge/img/gh/elixir-circuits/circuits_quickstart/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/elixir-circuits/circuits_quickstart/tree/main)\n[![REUSE status](https://api.reuse.software/badge/github.com/elixir-circuits/circuits_quickstart)](https://api.reuse.software/info/github.com/elixir-circuits/circuits_quickstart)\n\nThe Elixir Circuits quickstart firmware lets you try out the Elixir Circuits\nprojects on real hardware without needing to create a Nerves project, install\nElixir on Raspbian on a Raspberry Pi or compiling any Elixir code at all.\nWithin minutes, you'll have a device running Nerves. You'll be able to explore\nthe Nerves environment with [toolshed](https://hexdocs.pm/toolshed/readme.html),\nand you'll be able to blink LEDs from the device itself. You'll also be able to\nexplore the other Elixir Circuits libraries and experiment with\n[I2C](https://hex.pm/packages/circuits_i2c),\n[SPI](https://hex.pm/packages/circuits_spi),\n[GPIOs](https://hex.pm/packages/circuits_gpio), and\n[UARTs](https://hex.pm/packages/circuits_uart).\n\n## Prerequisites\n\nTo work through this tutorial, you'll need any Raspberry Pi or BeagleBone\ndevice. The Circuits Quickstart firmware configures Raspberry Pi Zero, Zero W, 3\nModel A+, and any BeagleBone-compatible device in what's called gadget mode. In\ngadget mode, the device uses a USB cable for power, serial console, and\nnetworking. We recommend using these devices if they're available. The other\ndevices require a HDMI monitor and keyboard or a wired Ethernet connection.\n\nFor this tutorial, you'll also need the following:\n\n* 1 MicroSD card\n* [fwup](https://github.com/fhunleth/fwup) or [etcher](https://www.balena.io/etcher/) for burning firmware to the MicroSD card\n* 1 LED\n* 1 100-500 Ohm resistor\n* 1 breadboard\n* 2 male-to-female jumper cables\n\n## Downloading the Firmware\n\nFind the appropriate firmware or zip file\n[here](https://github.com/elixir-circuits/circuits_quickstart/releases). If\nyou're using `fwup` to write images to MicroSD cards, download the `.fw`\nextension and if you're using `etcher`, get the `zip` file. Releases are named\nby the boards they support:\n\n* `bbb` - BeagleBone Black, BeagleBone Green, PocketBeagle, etc.\n* `grisp2` - [GRiSP2](https://www.grisp.org/) (Experimental)\n* `rpi0` - Raspberry Pi Zero or Zero W\n* `rpi` - The original Raspberry Pi Model B\n* `rpi2` Raspberry Pi 2 Model B\n* `rpi3` - Raspberry Pi 3 Model B and Model B+\n* `rpi3a` - Raspberry Pi 3 Model A+ and Raspberry Pi Zero 2 W\n* `rpi4` - Raspberry Pi 4 Model B\n* `rpi5` - Raspberry Pi 5\n* `osd32mp1` - Octavo OSD32MP1-BRK\n* `npi_imx6ull` - Seeed Studio imx6ull (select the MicroSD boot mode switches)\n* `mangopi_mq_pro` - An Allwinner D1 (RISC-V) board\n\nSome of these are easier than others to use. If you have a choice, the Raspberry\nPi Zero, Raspberry Pi 4 and BeagleBones are good ones to try first. These boards\nhave a lot of functionality and connecting them to a network is a little easier\nthan the others.\n\n\u003e **Note:** For an easier experience, you can use [Nerves\n\u003e Burner](https://github.com/nerves-project/nerves_burner) to download and write\n\u003e firmware images directly to your MicroSD card. Nerves Burner provides a\n\u003e user-friendly interface that handles the download and burning process for you.\n\n## Burning the Firmware for devices that boot from MicroSD\n\nThese instructions will work for the Raspberry Pi, Beaglebones and other devices\nthat either boot off MicroSD cards or can be configured to do so. If you're\nusing a GRiSP 2, see the GRiSP 2 installation section.\n\nNavigate to the directory where you downloaded the firmware. Either `fwup` or\n`etcher` can be used to burn the firmware.\n\nTo be clear, this formats your SD card, and you will *lose all data on the SD\ncard*. Make sure you're OK with that.\n\n### `fwup`\n\nYou'll need to install `fwup` if you don't have it. On Mac, run `brew install\nfwup`. For Linux and Windows, see the [fwup installation\ninstructions](https://github.com/fwup-home/fwup#installing).\n\n```console\n$ fwup circuits_quickstart_rpi0.fw\nUse 15.84 GB memory card found at /dev/rdisk2? [y/N] y\n```\n\nDepending on your OS, you'll be asked to authenticate this action. You can also\nuse `sudo`. Go ahead and do so.\n\n```console\n|====================================| 100% (31.81 / 31.81) MB\nSuccess!\nElapsed time: 3.595 s\n```\n\nIf you're using a WiFi-enabled device and want the WiFi credentials to be\nwritten to the MicroSD card, initialize the MicroSD card like this instead:\n\n```sh\nNERVES_WIFI_SSID='access_point' NERVES_WIFI_PASSPHRASE='passphrase' fwup circuits_quickstart_rpi0.fw\n```\n\nYou can still change the WiFi credentials at runtime using\n`VintageNetWiFi.quick_configure/2`, but this helps you don't have an easy\nalternative way of accessing the device to configure WiFi.\n\nIt's quite fast. Now you have Nerves ready to run on your device.  Skip ahead to\nthe next section.\n\n### `etcher`\n\nStart [`etcher`](https://www.balena.io/etcher/), point it to the zip file, and\nfollow the prompts:\n\n![etcher screenshot](assets/etcher.png)\n\nIMPORTANT: There's no way to configure the initial WiFi credentials with\n`etcher`. If you have a device that you can only access via WiFi (so no way of\nsetting credentials), then check out the `fwup` instructions above.\n\n## GRiSP 2 installation\n\nBefore you start, take a quick skim of the\n[instructions](https://github.com/grisp/grisp_demo/tree/sylane/make-image) for\nre-installing the GRiSP demo app. If that doesn't look that hard, then let's\ncontinue:\n\nAssuming you don't already have a Nerves firmware on your GRiSP 2, you'll need\nto do a first time install. Even if you do have Nerves on your GRiSP 2, you can\nstill follow these instructions.\n\nFirst, download `circuits_quickstart_grisp2.img.gz`from the latest\n[releases](https://github.com/elixir-circuits/circuits_quickstart/releases).\n\n1. Copy `circuits_quickstart_grisp2.img.gz` to a FAT-formatted MicroSD card:\n\n        $ cp circuits_quickstart_grisp2.img.gz /Volumes/...\n\n2. Unmount the MicroSD card and insert it into the GRiSP 2.\n\n3. Connect the GRiSP 2 to your computer via USB via `picocom` or another\n   serial terminal program. The GRiSP 2 shows up as two serial ports. Connect to\n   second one. On MacOS, it's `/dev/tty.usbserial-0\u003cGRiSP Serial Number\u003e1`.\n\n4. Press the reset button on the GRiSP 2. Press a key on the serial console to\n   get a Barebox prompt.\n\n5. At the Barebox prompt, run:\n\n        :/ uncompress /mnt/mmc/circuits_quickstart_grisp2.img.gz /dev/mmc1\n        :/ reset\n\n6. The GRiSP 2 will reboot into the Circuits Quickstart firmware. The first boot\n   takes a little longer due to it initializing the application data partition.\n\nOnce it boots, you can use the IEx prompt over the USB cable or connect over\nEthernet. There's a sticker on the back of the GRiSP with the serial number. The\ndevice will be at `nerves-\u003cserial number\u003e.local` on the network.\n\nTo configure WiFi, run:\n\n```elixir\nVintageNetWiFi.quick_configure(\"ssid\", \"password\")\n```\n\n`VintageNet.info` will show the current state of the network connections.\n\nThe normal Nerves firmware update methods will work. Since the GRiSP 2 port\nis so new, it may be required to perform a fresh install using the above\ninstructions in the future.\n\nTo see the current progress of the GRiSP 2 port to Nerves, see\n[nerves_system_grisp2](https://github.com/fhunleth/nerves_system_grisp2).\n\n## Testing the Firmware\n\nEject the SD card and insert it into the device that you're using. Power up and\nconnect the device with a USB cable. In the case of the `rpi0`, the micro USB\ndoes both.\n\nOnce the device boots, you can now connect to it. There are three ways to\nconnect to the device: `ssh`, `picocom`, and distributed Erlang. We'll take a\nlook at `ssh`.\n\n### `ssh`\n\nThe `circuits_quickstart` project configures the user as `circuits` with the\nhost `nerves.local` and has the password set as `circuits`. With that in mind,\nwe can use the `ssh` command to get to the `iex` prompt.\n\n```console\nλ ~/ ssh circuits@nerves.local\nWarning: Permanently added 'nerves.local,172.31.112.97' (RSA) to the list of known hosts.\nElixir Circuits Quickstart\nhttps://github.com/elixir-circuits/circuits_quickstart\n\nssh circuits@nerves.local # Use password \"circuits\"\n\nPassword:\nInteractive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)\nToolshed imported. Run h(Toolshed) for more info.\n\n                ;kX'\n              ,0XXXl\n             xNXNNXX.\n           'KNNXXXXX0.\n          ;XNNNNNNNNN0.\n         ;XNNNNNNNNNNNX:\n        .XNNNXXXXXXXXXXXO.\n        kNNNXNNNNXXNXXNNXNo\n       .NNNXNNNNNXXNNXNNXXXO\n       cXXXNNNNNNXXNNNNNNNNNd\n       lNNNNNNNNNXXNXXXNNNNNK\n       'NNXNXNXXXXXXXXXNNNNNk\n        oNXNXXXXXNXXXNNNNXXX.\n         :KXXXXXXNXXXNNNNXk.\n           ;xXNXXXXNXXX0o.\n              .',::;,.\n\n      Elixir Circuits Quickstart\n\nAll of the Elixir Circuits projects are available in this firmware\nimage. See https://github.com/elixir-circuits/circuits_quickstart for\nmore details.\n\nView log messages with `RingLogger.next` or `RingLogger.attach`. Toolshed\nhelpers are available. Type `h Toolshed` for details.\n\nIf connecting via ssh, type `exit` or `\u003center\u003e~.` to disconnect.\n\niex(circuits_quickstart@nerves.local)1\u003e\n```\n\nIn a matter of minutes, you have Nerves running on a device. As the text\nsuggests, let's play around with `Toolshed` to see what's going on.  Run `h\nToolshed` to see some of the helpers you can use. Let's take a look at a couple.\n`top` lists you the top processes in your system which can help in debugging and\ngeneral system observability.\n\n```elixir\niex(circuits_quickstart@nerves.local)3\u003e top\nTotal processes: 165\n\nApplication  Name or PID                   Reds/Δ      Mbox/Δ     Total/Δ      Heap/Δ     Stack/Δ\nundefined    erl_prim_loader               175K/175K      0/0       84K/84K     10K/10K       5/5\nundefined    application_controller        153K/153K      0/0       73K/73K     28K/28K       7/7\nundefined    \u003c0.1048.0\u003e=Elixir.IEx.Evalua   95K/95K       0/0       25K/25K    6772/6772    383/383\nkernel       code_server                    88K/88K       0/0      220K/220K    28K/28K       3/3\nssh          \u003c0.1043.0\u003e=ssh_connection_ha   77K/77K       0/0       13K/13K    2586/2586     12/12\nnerves_runti Elixir.Nerves.Runtime.KV       66K/66K       0/0       73K/73K     28K/28K      10/10\nnerves_netwo Nerves.Network.Interface.usb   48K/48K       0/0       14K/14K    4185/4185     10/10\nmdns         Elixir.Mdns.Server             38K/38K       0/0       17K/17K    6772/6772     10/10\nsystem_regis Elixir.SystemRegistry.Proces   27K/27K       0/0      9358/9358   2586/2586     10/10\nssh          \u003c0.1044.0\u003e=ssh_client_channe   21K/21K       0/0       13K/13K    6772/6772     10/10\n```\n\nThere are Linux system commands like `ls` as well.\n\n```elixir\niex(circuits_quickstart@nerves.local)4\u003e ls\nlib          releases\n```\n\nFinally, since this is `iex` you can write Elixir code.\n\n```elixir\niex(circuits_quickstart@nerves.local)5\u003e defmodule A do\n...(circuits_quickstart@nerves.local)5\u003e def b, do: :hello\n...(circuits_quickstart@nerves.local)5\u003e end\n{:module, A,\n \u003c\u003c70, 79, 82, 49, 0, 0, 3, 244, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 123,\n   0, 0, 0, 14, 8, 69, 108, 105, 120, 105, 114, 46, 65, 8, 95, 95, 105, 110,\n   102, 111, 95, 95, 7, 99, 111, 109, 112, ...\u003e\u003e, {:b, 0}}\niex(circuits_quickstart@nerves.local)6\u003e A.b\n:hello\n```\n\nNow we're going to take a slight detour and introduce the breadboard — first\nexit from `iex` with `exit` and return. Then, disconnect the RPI from the power\nsource.\n\n## Breadboard\n\nAt this point, we have Nerves running on a supported device, but there's no way\nto manipulate any LEDs because we currently have none connected. To connect an\nLED, we'll use a breadboard. If you're not sure or have never used a breadboard,\nSparkFun has a detailed\n[introduction](https://learn.sparkfun.com/tutorials/how-to-use-a-breadboard/all)\n(Sparkfun, by the way, is an excellent resource for electronics basics and\ncomponents).\n\nWe'll give a high-level overview of what a breadboard is and how to use it here,\ntoo. Breadboards are useful for prototyping or creating temporary circuits; you\ncan adjust connections and parts as needed without soldering. Soldering isn't\ndifficult and it's useful when you're ready to make more permanent versions of\nyour circuits.\n\nThe linked SparkFun article explains in detail how breadboards work, so for our\npurposes, we'll walk through creating a simple circuit to power an LED.\n\nInsert the LED somewhere on the breadboard. Note that the longer leg of the LED\nis the positive side, and the shorter side is the negative side. Then take the\nresistor and bend the legs down as shown in the image. Insert one leg of the\nresistor in the same row as the positive side of the LED and the other leg in an\nunused row.\n\nThe resistor impedes the electrical current so that it doesn't overload the LED.\n\nInsert one of the jumper wires in the same row as the resistor and the other in\nthe row with the negative leg of the LED. The result should look like the\nfollowing image.\n\n![breadboard with LED, resistor, and jumper wires](assets/breadboard_circuit.jpg)\n\nWe're finished with the breadboard. You've almost created your first circuit.\nLet's close the circuit by attaching the jumper wires to the GPIO header pins on\nthe device.\n\n### Pinout.xyz\n\nBut which GPIO do you use? [Pinout.xyz](https://pinout.xyz/) holds the answer. Pinout\nlays out the GPIO for the Raspberry Pi. We need only two things: Broadcom pin\nnumber (BCM) and ground. The BCM is what controls the LED's status - on or off -\nand the ground grounds the circuit. You can see in the following diagram that\nthe ground pins are colored black and the BCM pins we're interested in are\ncolored green. There are other pins for power, UART, etc. and even BCM pins that\nserve specific functions; for now, know they exist but ignore them.\n\n![raspberry pi GPIO layout by Pinout](https://pinout.xyz/resources/raspberry-pi-pinout.png)\n\nIn the image, the last two pins on the bottom row on the right are what we need\n(you can choose another combination if you wish). Put the jumper wire that's\nattached on the negative end of the LED to the ground pin on the device. Next,\nconnect the other jumper wire---the one connected to the positive leg of the LED---to BCM 26.\nThe following image should help orient you.\n\n![rpi0 header with jumper wires attached](assets/rpi_jumper.jpg)\n\n## Flashing Lights\n\nNow that we have everything wired up, let's try turning the light off and on.\nThe first thing we'll do is `alias` `Circuits.GPIO` for convenience. If you're\nnot familiar with `alias`, see the\n[guides](https://elixir-lang.org/getting-started/alias-require-and-import.html#alias).\n\n```elixir\niex(circuits_quickstart@nerves.local)8\u003e alias Circuits.GPIO\nCircuits.GPIO\n```\n\nNext, we'll open `GPIO` `26`. That's the one we put the jumper wire that leads\nto the positive leg of the LED.\n\n```elixir\niex(circuits_quickstart@nerves.local)9\u003e GPIO.open(26, :output)\n{:ok, #Reference\u003c0.1415452060.268566532.135024\u003e}\n```\n\nSince that returned as expected, we can now pattern match to the `ref` and\nassign it to `led`. `v()` runs the last command again.\n\n```elixir\niex(circuits_quickstart@nerves.local)10\u003e  {:ok, led} = v()\n{:ok, #Reference\u003c0.1415452060.268566532.135024\u003e}\n```\n\nNow we're ready to blink the light. Using `write/2`, we give the function the\n`ref` for the LED and `1` which turns the light on.\n\n```elixir\niex(circuits_quickstart@nerves.local)11\u003e GPIO.write(led, 1)\n: OK\n```\n\nNow you should see the light illuminated.\n\n![illuminated LED connected to rpi0](assets/rpi_led.jpg)\n\nTo turn it off, use `write/2` again and pass in the same `ref` but this time\nwith `0` to turn the light off.\n\n```elixir\niex(circuits_quickstart@nerves.local)12\u003e GPIO.write(led, 0)\n:ok\n```\n\nThat's about it. You've accomplished a great deal in not a lot of time.\n\n## Going further\n\nThe Quickstart firmware contains all of the Elixir Circuits projects. By\nconnecting other hardware to your devices, you can explore more hardware\ninterfaces and how they're supported in Elixir. Click on the following links for\nmore information:\n\n* [GPIO](https://hex.pm/packages/circuits_gpio)\n* [I2C](https://hex.pm/packages/circuits_i2c)\n* [SPI](https://hex.pm/packages/circuits_spi)\n* [UART](https://hex.pm/packages/circuits_uart)\n\nAt some point you may want to create your own firmware. See the [Nerves\nInstallation](https://hexdocs.pm/nerves/installation.html) and [Getting\nStarted](https://hexdocs.pm/nerves/getting-started.html) guides for details.\n\nTo build the Elixir Circuits Quickstart firmware, make sure that you have run\nthrough the Nerves installation steps. Then open a terminal window and run the\nfollowing:\n\n```console\n$ git clone https://github.com/elixir-circuits/circuits_quickstart.git\n$ cd circuits_quickstart\n\n# Set the MIX_TARGET to the desired platform (rpi0, bbb, rpi3, etc.)\n$ export MIX_TARGET=rpi0\n$ mix deps.get\n$ mix firmware\n\n# Insert a MicroSD card\n$ mix burn\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felixir-circuits%2Fcircuits_quickstart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felixir-circuits%2Fcircuits_quickstart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felixir-circuits%2Fcircuits_quickstart/lists"}