Skip to content

Commit 23f6b12

Browse files
authored
Merge pull request #27 from mnishiguchi/feat/add-elixir-wifi-example
Add Elixir WiFi example
2 parents 312ee0d + 9e346ce commit 23f6b12

5 files changed

Lines changed: 227 additions & 0 deletions

File tree

elixir/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Some example programs can only run on specific platform. The following table su
1717
| Blinky ||||||
1818
| HelloWorld ||||||
1919
| LEDC_Example ||||||
20+
| WifiExample ||||||
2021

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

elixir/Wifi/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!---
2+
Copyright 2026 Masatoshi Nishiguchi
3+
4+
SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
5+
-->
6+
7+
# `Wifi` Application
8+
9+
Welcome to the `Wifi` AtomVM application.
10+
11+
The `Wifi` AtomVM application demonstrates how to configure an ESP32 device for both Station (STA) and Access Point (AP) modes, allowing an ESP32 device to join an existing WiFi network or to serve as a WiFi access point for other devices.
12+
13+
For more information about programming on the AtomVM platform, see the [AtomVM Programmers Guide](https://doc.atomvm.org/latest/programmers-guide.html).
14+
15+
For general information about building and executing Elixir AtomVM example programs, see the Elixir example program [README](../README.md).
16+
17+
> **IMPORTANT** If you are running this example program on a device that
18+
> supports WiFi (e.g., the ESP32), you must first edit `config/config.exs` and
19+
> set the WiFi Station (STA) SSID and PSK before building this application:
20+
>
21+
> ```elixir
22+
> config :wifi,
23+
> sta: [
24+
> dhcp_hostname: "my_device_name",
25+
> ssid: "my_sta_ssid",
26+
> psk: "my_sta_psk"
27+
> ]
28+
> ```

elixir/Wifi/config/config.exs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
import Config
22+
23+
config :wifi,
24+
ap: [
25+
ssid: "my_ap_ssid",
26+
psk: "my_ap_psk",
27+
ap_channel: 1,
28+
max_connections: 4
29+
],
30+
sta: [
31+
dhcp_hostname: "my_device_name",
32+
ssid: "my_sta_ssid",
33+
psk: "my_sta_psk"
34+
]

elixir/Wifi/lib/wifi.ex

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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 Wifi do
22+
@moduledoc """
23+
Wi-Fi example for Elixir.
24+
"""
25+
26+
@compile {:no_warn_undefined, :atomvm}
27+
@compile {:no_warn_undefined, :network}
28+
29+
@sta_config Application.compile_env!(:wifi, :sta)
30+
@ap_config Application.compile_env!(:wifi, :ap)
31+
32+
@clock_interval_ms 5_000
33+
34+
def start do
35+
case verify_platform(:atomvm.platform()) do
36+
:ok ->
37+
start_network()
38+
39+
error ->
40+
error
41+
end
42+
end
43+
44+
defp start_network() do
45+
network_config = [
46+
ap:
47+
[
48+
ap_started: &ap_started/0,
49+
sta_connected: &sta_connected/1,
50+
sta_ip_assigned: &sta_ip_assigned/1,
51+
sta_disconnected: &sta_disconnected/1
52+
] ++ @ap_config,
53+
sta:
54+
[
55+
connected: &connected/0,
56+
got_ip: &got_ip/1,
57+
disconnected: &disconnected/0
58+
] ++ @sta_config,
59+
sntp: [
60+
host: "time-d-b.nist.gov",
61+
synchronized: &sntp_synchronized/1
62+
]
63+
]
64+
65+
case :network.start(network_config) do
66+
{:ok, _pid} ->
67+
IO.puts("wifi: network started")
68+
Process.sleep(:infinity)
69+
70+
error ->
71+
error
72+
end
73+
end
74+
75+
defp ap_started, do: IO.puts("AP started")
76+
77+
defp sta_connected(mac), do: IO.puts("STA connected with mac #{inspect(mac)}")
78+
79+
defp sta_disconnected(mac), do: IO.puts("STA disconnected with mac #{inspect(mac)}")
80+
81+
defp sta_ip_assigned(address), do: IO.puts("STA assigned address #{inspect(address)}")
82+
83+
defp connected, do: IO.puts("STA connected")
84+
85+
defp disconnected, do: IO.puts("STA disconnected")
86+
87+
defp got_ip(ip_info) do
88+
IO.puts("Got IP: #{inspect(ip_info)}")
89+
_clock_pid = spawn(fn -> clock_loop() end)
90+
:ok
91+
end
92+
93+
defp sntp_synchronized(timeval = {_tv_sec, _tv_usec}) do
94+
IO.puts("Synchronized time with SNTP server #{inspect(timeval)}")
95+
end
96+
97+
defp verify_platform(:esp32), do: :ok
98+
defp verify_platform(:pico), do: :ok
99+
defp verify_platform(platform), do: {:error, {:unsupported_platform, platform}}
100+
101+
defp clock_loop do
102+
{{year, month, day}, {hour, minute, second}} = :erlang.universaltime()
103+
ms = :erlang.system_time(:millisecond)
104+
105+
:io.format(
106+
~c"Date: ~4..0B/~2..0B/~2..0B ~2..0B:~2..0B:~2..0B (~pms)~n",
107+
[year, month, day, hour, minute, second, ms]
108+
)
109+
110+
Process.sleep(@clock_interval_ms)
111+
clock_loop()
112+
end
113+
end

elixir/Wifi/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 Wifi.MixProject do
22+
use Mix.Project
23+
24+
def project do
25+
[
26+
app: :wifi,
27+
version: "0.1.0",
28+
elixir: "~> 1.17",
29+
start_permanent: Mix.env() == :prod,
30+
deps: deps(),
31+
atomvm: [
32+
start: Wifi,
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

0 commit comments

Comments
 (0)