Skip to content

Commit c8a1ad9

Browse files
committed
Add Elixir ESP NVS and RTC examples
1 parent 9e346ce commit c8a1ad9

7 files changed

Lines changed: 300 additions & 2 deletions

File tree

elixir/EspNvs/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!---
2+
Copyright 2026 Masatoshi Nishiguchi
3+
4+
SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
5+
-->
6+
7+
# `EspNvs` Application
8+
9+
Welcome to the `EspNvs` AtomVM application.
10+
11+
The `EspNvs` AtomVM application uses ESP32 non-volatile storage (NVS) to store a small value.
12+
If the NVS storage has not been set for this application, it will store a default value once. The application then logs the result and restarts every 10 seconds.
13+
14+
For more information about programming on the AtomVM platform, see the [AtomVM Programmers Guide](https://doc.atomvm.org/latest/programmers-guide.html).
15+
16+
For general information about building and executing Elixir AtomVM example programs, see the Elixir example program [README](../README.md).

elixir/EspNvs/lib/esp_nvs.ex

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#
2+
# This file is part of AtomVM.
3+
#
4+
# Copyright 2026 Masatoshi Nishiguchi
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
#
20+
21+
defmodule EspNvs do
22+
@moduledoc """
23+
Demonstrates ESP32 NVS usage by storing a small value once.
24+
"""
25+
26+
@compile {:no_warn_undefined, :atomvm}
27+
@compile {:no_warn_undefined, :esp}
28+
29+
@nvs_namespace :esp_nvs
30+
@nvs_key :word
31+
@default_word "Hello"
32+
@restart_interval_ms 10_000
33+
34+
def start do
35+
case verify_platform(:atomvm.platform()) do
36+
:ok ->
37+
case :esp.nvs_fetch_binary(@nvs_namespace, @nvs_key) do
38+
{:ok, word} when is_binary(word) ->
39+
IO.puts("Fetched word from NVS: #{word}")
40+
41+
{:error, :not_found} ->
42+
IO.puts("No word found. Storing default word to NVS once: #{@default_word}")
43+
:ok = :esp.nvs_put_binary(@nvs_namespace, @nvs_key, @default_word)
44+
45+
_ ->
46+
IO.puts("Error reading NVS. Skipping write.")
47+
end
48+
49+
IO.puts("Restarting in 10 seconds ...")
50+
Process.sleep(@restart_interval_ms)
51+
:esp.restart()
52+
53+
error ->
54+
error
55+
end
56+
end
57+
58+
defp verify_platform(:esp32), do: :ok
59+
defp verify_platform(platform), do: {:error, {:unsupported_platform, platform}}
60+
end

elixir/EspNvs/mix.exs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#
2+
# This file is part of AtomVM.
3+
#
4+
# Copyright 2026 Masatoshi Nishiguchi
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
#
20+
21+
defmodule EspNvs.MixProject do
22+
use Mix.Project
23+
24+
def project do
25+
[
26+
app: :esp_nvs,
27+
version: "0.1.0",
28+
elixir: "~> 1.17",
29+
start_permanent: Mix.env() == :prod,
30+
deps: deps(),
31+
atomvm: [
32+
start: EspNvs,
33+
flash_offset: 0x250000
34+
]
35+
]
36+
end
37+
38+
# Run "mix help compile.app" to learn about applications.
39+
def application do
40+
[
41+
extra_applications: [:logger]
42+
]
43+
end
44+
45+
# Run "mix help deps" to learn about dependencies.
46+
defp deps do
47+
[
48+
{:exatomvm, git: "https://github.com/atomvm/ExAtomVM/", branch: "main"}
49+
]
50+
end
51+
end

elixir/EspRtcMemory/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!---
2+
Copyright 2026 Masatoshi Nishiguchi
3+
4+
SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
5+
-->
6+
7+
# `EspRtc` Application
8+
9+
Welcome to the `EspRtc` AtomVM application.
10+
11+
The `EspRtc` AtomVM application uses ESP32 RTC slow memory to record the number of times the device has restarted.
12+
If no value has been stored in RTC slow memory yet, the counter is initialized to 0. The device will then sleep for 10 seconds and restart. After each restart, the counter is incremented and stored back to RTC slow memory.
13+
14+
For more information about programming on the AtomVM platform, see the [AtomVM Programmers Guide](https://doc.atomvm.org/latest/programmers-guide.html).
15+
16+
For general information about building and executing Elixir AtomVM example programs, see the Elixir example program [README](../README.md).
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#
2+
# This file is part of AtomVM.
3+
#
4+
# Copyright 2026 Masatoshi Nishiguchi
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
#
20+
21+
defmodule EspRtcMemory do
22+
@moduledoc """
23+
Demonstrates ESP32 RTC slow memory usage by persisting a restart counter.
24+
"""
25+
26+
@compile {:no_warn_undefined, :atomvm}
27+
@compile {:no_warn_undefined, :esp}
28+
29+
@restart_delay_ms 10_000
30+
31+
defstruct count: 0
32+
33+
def start do
34+
case verify_platform(:atomvm.platform()) do
35+
:ok ->
36+
load_state()
37+
|> increment_state()
38+
|> save_state()
39+
40+
IO.puts("Restarting in 10 seconds ...")
41+
Process.sleep(@restart_delay_ms)
42+
:esp.restart()
43+
44+
error ->
45+
error
46+
end
47+
end
48+
49+
defp load_state do
50+
IO.puts("Loading count from RTC slow memory ...")
51+
52+
encoded_term =
53+
try do
54+
:esp.rtc_slow_get_binary()
55+
catch
56+
:error, :badarg ->
57+
IO.puts("This device has not recorded the number of starts. Initializing to 0.")
58+
:erlang.term_to_binary(%__MODULE__{})
59+
end
60+
61+
case safe_binary_to_term(encoded_term) do
62+
{:ok, %__MODULE__{count: count} = state} when is_integer(count) and count >= 0 ->
63+
state
64+
65+
_ ->
66+
IO.puts("Error: bad value, resetting to 0.")
67+
%__MODULE__{}
68+
end
69+
end
70+
71+
defp safe_binary_to_term(encoded_term) when is_binary(encoded_term) do
72+
try do
73+
{:ok, :erlang.binary_to_term(encoded_term)}
74+
catch
75+
:error, _ ->
76+
:error
77+
end
78+
end
79+
80+
defp save_state(current_state) do
81+
IO.puts("Saving count to RTC slow memory ...")
82+
83+
current_state
84+
|> :erlang.term_to_binary()
85+
|> :esp.rtc_slow_set_binary()
86+
end
87+
88+
defp increment_state(%__MODULE__{count: count} = state) when is_integer(count) and count >= 0 do
89+
new_count = count + 1
90+
IO.puts("This device has restarted #{new_count} time(s).")
91+
%__MODULE__{state | count: new_count}
92+
end
93+
94+
defp increment_state(_) do
95+
IO.puts("Error: bad value, resetting to 0.")
96+
%__MODULE__{}
97+
end
98+
99+
defp verify_platform(:esp32), do: :ok
100+
defp verify_platform(platform), do: {:error, {:unsupported_platform, platform}}
101+
end
102+

elixir/EspRtcMemory/mix.exs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#
2+
# This file is part of AtomVM.
3+
#
4+
# Copyright 2026 Masatoshi Nishiguchi
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
#
20+
21+
defmodule EspRtcMemory.MixProject do
22+
use Mix.Project
23+
24+
def project do
25+
[
26+
app: :esp_rtc_memory,
27+
version: "0.1.0",
28+
elixir: "~> 1.17",
29+
start_permanent: Mix.env() == :prod,
30+
deps: deps(),
31+
atomvm: [
32+
start: EspRtcMemory,
33+
flash_offset: 0x250000
34+
]
35+
]
36+
end
37+
38+
# Run "mix help compile.app" to learn about applications.
39+
def application do
40+
[
41+
extra_applications: [:logger]
42+
]
43+
end
44+
45+
# Run "mix help deps" to learn about dependencies.
46+
defp deps do
47+
[
48+
{:exatomvm, git: "https://github.com/atomvm/ExAtomVM/", branch: "main"}
49+
]
50+
end
51+
end

elixir/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ Some example programs can only run on specific platform. The following table su
1616
|-----------------|-------|-------|------|--------|--------------|
1717
| Blinky ||||||
1818
| HelloWorld ||||||
19-
| LEDC_Example ||||||
20-
| WifiExample ||||||
19+
| LEDC ||||||
20+
| Wifi ||||||
21+
| EspNvs ||||||
22+
| EspRtcMemory ||||||
2123

2224
✦ Works, but requires editing to use onboard LED, see the README in the examples directory.
2325

0 commit comments

Comments
 (0)