Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions elixir/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Some example programs can only run on specific platform. The following table su
| Blinky | ✅ | ✅ | ✅ | ✦ | ❌ |
| HelloWorld | ✅ | ✅ | ✅ | ✅ | ✅ |
| LEDC_Example | ✅ | ❌ | ❌ | ❌ | ❌ |
| WifiExample | ✅ | ❌ | ❌ | ✅ | ❌ |

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

Expand Down
28 changes: 28 additions & 0 deletions elixir/Wifi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!---
Copyright 2026 Masatoshi Nishiguchi

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
-->

# `Wifi` Application

Welcome to the `Wifi` AtomVM application.

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.

For more information about programming on the AtomVM platform, see the [AtomVM Programmers Guide](https://doc.atomvm.org/latest/programmers-guide.html).

For general information about building and executing Elixir AtomVM example programs, see the Elixir example program [README](../README.md).

> **IMPORTANT** If you are running this example program on a device that
> supports WiFi (e.g., the ESP32), you must first edit `config/config.exs` and
> set the WiFi Station (STA) SSID and PSK before building this application:
>
> ```elixir
> config :wifi,
> sta: [
> dhcp_hostname: "my_device_name",
> ssid: "my_sta_ssid",
> psk: "my_sta_psk"
> ]
> ```
34 changes: 34 additions & 0 deletions elixir/Wifi/config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#
# This file is part of AtomVM.
#
# Copyright 2026 Masatoshi Nishiguchi
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

import Config

config :wifi,
ap: [
ssid: "my_ap_ssid",
psk: "my_ap_psk",
ap_channel: 1,
max_connections: 4
],
sta: [
dhcp_hostname: "my_device_name",
ssid: "my_sta_ssid",
psk: "my_sta_psk"
]
113 changes: 113 additions & 0 deletions elixir/Wifi/lib/wifi.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#
# This file is part of AtomVM.
#
# Copyright 2026 Masatoshi Nishiguchi
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

defmodule Wifi do
@moduledoc """
Wi-Fi example for Elixir.
"""

@compile {:no_warn_undefined, :atomvm}
@compile {:no_warn_undefined, :network}

@sta_config Application.compile_env!(:wifi, :sta)
@ap_config Application.compile_env!(:wifi, :ap)

@clock_interval_ms 5_000

def start do
case verify_platform(:atomvm.platform()) do
:ok ->
start_network()

error ->
error
end
end

defp start_network() do
network_config = [
ap:
[
ap_started: &ap_started/0,
sta_connected: &sta_connected/1,
sta_ip_assigned: &sta_ip_assigned/1,
sta_disconnected: &sta_disconnected/1
] ++ @ap_config,
sta:
[
connected: &connected/0,
got_ip: &got_ip/1,
disconnected: &disconnected/0
] ++ @sta_config,
sntp: [
host: "time-d-b.nist.gov",
synchronized: &sntp_synchronized/1
]
]

case :network.start(network_config) do
{:ok, _pid} ->
IO.puts("wifi: network started")
Process.sleep(:infinity)

error ->
error
end
end

defp ap_started, do: IO.puts("AP started")

defp sta_connected(mac), do: IO.puts("STA connected with mac #{inspect(mac)}")

defp sta_disconnected(mac), do: IO.puts("STA disconnected with mac #{inspect(mac)}")

defp sta_ip_assigned(address), do: IO.puts("STA assigned address #{inspect(address)}")

defp connected, do: IO.puts("STA connected")

defp disconnected, do: IO.puts("STA disconnected")

defp got_ip(ip_info) do
IO.puts("Got IP: #{inspect(ip_info)}")
_clock_pid = spawn(fn -> clock_loop() end)
:ok
end

defp sntp_synchronized(timeval = {_tv_sec, _tv_usec}) do
IO.puts("Synchronized time with SNTP server #{inspect(timeval)}")
end

defp verify_platform(:esp32), do: :ok
defp verify_platform(:pico), do: :ok
defp verify_platform(platform), do: {:error, {:unsupported_platform, platform}}
Comment thread
UncleGrumpy marked this conversation as resolved.

defp clock_loop do
{{year, month, day}, {hour, minute, second}} = :erlang.universaltime()
ms = :erlang.system_time(:millisecond)

:io.format(
~c"Date: ~4..0B/~2..0B/~2..0B ~2..0B:~2..0B:~2..0B (~pms)~n",
[year, month, day, hour, minute, second, ms]
)

Process.sleep(@clock_interval_ms)
clock_loop()
end
end
51 changes: 51 additions & 0 deletions elixir/Wifi/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#
# This file is part of AtomVM.
#
# Copyright 2026 Masatoshi Nishiguchi
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
#

defmodule Wifi.MixProject do
use Mix.Project

def project do
[
app: :wifi,
version: "0.1.0",
elixir: "~> 1.17",
start_permanent: Mix.env() == :prod,
deps: deps(),
atomvm: [
start: Wifi,
flash_offset: 0x250000
]
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:exatomvm, git: "https://github.com/atomvm/ExAtomVM/", branch: "main"}
]
end
end