Skip to content

API Network and WiFi

WiFi connectivity and HTTP client.

WiFi connectivity functions (Pico 2W only).

Checks if WiFi hardware is present.

  • Parameters: None
  • Returns: (boolean) true if WiFi is available (Pico 2W), false otherwise
if picocalc.wifi.isAvailable() then
picocalc.wifi.connect("MySSID", "password")
end

Connects to a WiFi network (non-blocking).

  • Parameters:
    • ssid (string): Network SSID
    • password (string, optional): Network password (omit for open networks)
  • Returns: None
picocalc.wifi.connect("MyWiFi", "password123")

Disconnects from the current WiFi network.

  • Parameters: None
  • Returns: None

Returns the current WiFi connection status.

  • Parameters: None
  • Returns: (number) Status code (see constants below)
if picocalc.wifi.getStatus() == picocalc.wifi.STATUS_CONNECTED then
print("Connected! IP: " .. picocalc.wifi.getIP())
end

Returns the current IP address as a string.

  • Parameters: None
  • Returns: (string or nil) IP address (e.g., "192.168.1.100"), or nil if not connected

Returns the SSID of the current connection.

  • Parameters: None
  • Returns: (string or nil) SSID, or nil if not connected

Check if the device has working internet connectivity (beyond just WiFi connection).

  • Parameters: None
  • Returns: (boolean) true if internet is reachable
if picocalc.wifi.hasInternet() then
-- Safe to make external requests
end

ConstantDescription
picocalc.wifi.STATUS_DISCONNECTEDNot connected
picocalc.wifi.STATUS_CONNECTINGConnection in progress
picocalc.wifi.STATUS_CONNECTEDConnected successfully
picocalc.wifi.STATUS_FAILEDConnection failed
picocalc.wifi.STATUS_ONLINEInternet connectivity confirmed

HTTP client for making network requests. Requires WiFi to be connected first. Up to 8 simultaneous connections are supported. HTTPS (SSL/TLS) is supported via mbedTLS and verifies the server certificate by default (chain to the OS root bundle, validity dates, host name). Failures read "TLS: certificate not trusted …", "… expired" or "… does not match the host name". Because validity needs the wall clock, a verifying connection is refused with an error starting "clock not set" until SNTP has set the time; retry a few seconds later.

HTTP connections are objects with method syntax (conn:get(...), conn:read(), etc.). Callbacks are fired automatically — you do not need to poll manually.

Returns the current network status.

  • Parameters: None
  • Returns: (number) One of the kStatus* constants
if picocalc.network.getStatus() == picocalc.network.kStatusConnected then
-- Safe to make HTTP requests
end

picocalc.network.setEnabled(flag [, callback])

Section titled “picocalc.network.setEnabled(flag [, callback])”

Enables or disables WiFi. The optional callback is fired synchronously with nil (reserved for a future async result).

  • Parameters:
    • flag (boolean): true to enable, false to disable
    • callback (function, optional): Called synchronously with nil
  • Returns: None
picocalc.network.setEnabled(true, function()
print("WiFi enable requested")
end)

Check if the WiFi hardware has been disabled (e.g. by video playback).

  • Parameters: None
  • Returns: (boolean) true if the WiFi hardware is disconnected
if picocalc.network.isHwDisconnected() then
print("WiFi hardware is off")
end

ConstantValueDescription
picocalc.network.kStatusNotConnected0WiFi present but not connected
picocalc.network.kStatusConnected1Connected and ready
picocalc.network.kStatusNotAvailable2No WiFi hardware, or connection failed

picocalc.network.http — HTTP Connection Objects

Section titled “picocalc.network.http — HTTP Connection Objects”

picocalc.network.http.new(server [, port [, usessl]])

Section titled “picocalc.network.http.new(server [, port [, usessl]])”

Creates a new HTTP/HTTPS connection object. Does not connect immediately — call conn:get() or conn:post() to start a request.

  • Parameters:
    • server (string): Hostname (e.g., "api.example.com")
    • port (number, optional): TCP port. Defaults to 80 for HTTP, 443 for HTTPS.
    • usessl (boolean, optional): true to use HTTPS/TLS. Defaults to false.
  • Returns: (userdata) Connection object, or nil, errstr if the connection pool is full
-- Plain HTTP
local conn = picocalc.network.http.new("api.example.com")
-- HTTPS (port 443 is the default when usessl=true)
local conn = picocalc.network.http.new("api.example.com", 443, true)
if not conn then
print("Pool full")
end

All methods are called on the connection object with colon syntax.


Issues an HTTP GET request.

Returns false (“a request is already in progress”) unless the connection is idle or its last request finished. POST bodies are binary-safe.

  • Parameters:
    • path (string): URL path (e.g., "/api/data")
    • headers (string or table, optional): Extra headers. Can be a raw "Key: Value " string, a flat array of "Key: Value" strings, or a {key=value} table.
  • Returns: (boolean) true if request started, or false, errstr on immediate failure
conn:get("/api/data")

Issues an HTTP POST request.

Returns false (“a request is already in progress”) unless the connection is idle or its last request finished. POST bodies are binary-safe.

  • Parameters:
    • path (string): URL path
    • headers (string or table, optional): Extra headers (omit to pass data as third arg)
    • data (string): Request body
  • Returns: (boolean) true if request started, or false, errstr on immediate failure
conn:post("/submit", '{"value":42}')
-- or with headers:
conn:post("/submit", {["Content-Type"] = "application/json"}, '{"value":42}')

Closes the connection and frees the connection pool slot. The object is unusable afterwards.

  • Returns: None

Enables HTTP keep-alive (Connection: keep-alive). Must be called before get/post.

  • Parameters:
    • flag (boolean)
  • Returns: None

Adds a Range: bytes=from-to header to the next request (for partial content / resumable downloads). Must be called before get/post.

  • Parameters:
    • from (number): Start byte (inclusive)
    • to (number): End byte (inclusive)
  • Returns: None

Sets the TCP connection timeout. Default is 10 seconds.

  • Parameters:
    • seconds (number): Timeout in seconds (fractions allowed)
  • Returns: None

Sets the timeout waiting for response data after connecting. Default is 30 seconds.

  • Parameters:
    • seconds (number): Timeout in seconds (fractions allowed)
  • Returns: None

Resizes the receive ring buffer. Must be called before get/post. Defaults to 4096 bytes. Maximum is 2097152 bytes (2 MiB).

  • Parameters:
    • bytes (number): Buffer size in bytes
  • Returns: None

Before get/post: true skips certificate verification and the clock check for this connection only (self-signed development servers). Logs a warning.


Returns the last error string, if any.

  • Returns: (string or nil) Error description, or nil if no error
local err = conn:getError()
if err then print("HTTP error: " .. err) end

Returns download progress.

  • Returns: (number, number) bytesReceived, totalBytes — totalBytes is -1 if unknown (no Content-Length header or chunked encoding)
local received, total = conn:getProgress()
if total > 0 then
print(string.format("%d%%", received * 100 // total))
end

Returns the number of bytes currently available to read from the receive buffer.

  • Returns: (number) Bytes available

Reads data from the receive buffer.

  • Parameters:
    • length (number, optional): Maximum bytes to read. Defaults to all available. Capped at 131072 bytes per call.
  • Returns: (string or nil) Data, or nil if nothing is available yet
local chunk = conn:read()
if chunk then buffer = buffer .. chunk end

Returns the HTTP response status code.

  • Returns: (number or nil) e.g. 200, 404 — nil if headers not yet received

Returns the response headers as a key-value table (lowercase keys).

  • Returns: (table or nil) {["content-type"]="text/json", ...} — nil if headers not yet received
local hdrs = conn:getResponseHeaders()
if hdrs then
print("Content-Type: " .. (hdrs["content-type"] or "unknown"))
end

Content-Length, chunked and close-delimited bodies are supported, with keep-alive reuse. A body cut short (reset, early close, out of memory) fails; it never reports complete. Callbacks never nest: a callback that sleeps leaves later events for the outer call. The read timeout runs from the moment the request is sent.

Callbacks are fired automatically from within the app’s execution loop — no polling needed.

Called each time new body data arrives. fn receives no arguments; use conn:read() to consume data.

Called once when all response headers have been received. Use conn:getResponseStatus() and conn:getResponseHeaders() inside this callback.

Called when the response body is fully received.

Called when the connection closes, either cleanly or due to an error. Check conn:getError() to distinguish.


-- Check WiFi is up
if picocalc.network.getStatus() ~= picocalc.network.kStatusConnected then
print("Not connected")
return
end
local conn = picocalc.network.http.new("httpbin.org")
local body = ""
conn:setHeadersReadCallback(function()
print("Status: " .. conn:getResponseStatus())
end)
conn:setRequestCallback(function()
local chunk = conn:read()
if chunk then body = body .. chunk end
end)
conn:setRequestCompleteCallback(function()
print("Done. Body length: " .. #body)
conn:close()
end)
conn:setConnectionClosedCallback(function()
local err = conn:getError()
if err then print("Error: " .. err) end
end)
conn:get("/get")
-- Keep looping until the request completes
local done = false
conn:setRequestCompleteCallback(function()
print("Done. Body length: " .. #body)
done = true
end)
while not done do
picocalc.input.update()
if picocalc.input.getButtonsPressed() & picocalc.input.BTN_ESC ~= 0 then
conn:close()
return
end
picocalc.sys.sleep(16)
end
conn:close()