Built-in project · ESP32-C3-DevKitM-1

WiFi: fetch the weather, on an ESP32-C3

HTTPClient against a simulated origin, with the numbers on a dial in the Cloud panel, and a request to the real internet that is refused, in as many words. The whole build, an ESP32-C3, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

IntermediateRuns in your browser. Free, and no account needed.

WiFi: fetch the weather · ESP32-C3-DevKitM-1live0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · ESP32-C3-DevKitM-1
/*
 * WiFi: fetch the weather.
 *
 * SIMULATED, all of it. The radio is simulated, and so is the internet: the
 * only names that resolve are time.mokxi, weather.mokxi, echo.mokxi, api.mokxi
 * and the board's own address. Nothing here reaches the network your browser
 * is on, ever. Open the Cloud panel to watch the requests go out and to
 * change the numbers weather.mokxi answers with.
 *
 * The code is the code you would write for a real board.
 */
#include <HTTPClient.h>
#include <WiFi.h>
#include <WiFiClient.h>

const char *SSID = "Mokxi-Lab";
const char *PASSWORD = "breadboard";

/* Pull one number out of a JSON body without a JSON library: find the key,
   step over the colon, copy what follows. Good enough for a lesson, and it
   keeps the sketch to the one thing it is about. */
static bool jsonValue(const char *body, const char *key, char *out, int size) {
  String text(body);
  int at = text.indexOf(key);
  if (at < 0) return false;
  at += (int)strlen(key);
  while (text[(size_t)at] == '"' || text[(size_t)at] == ':' || text[(size_t)at] == ' ') at++;
  int used = 0;
  while (used + 1 < size) {
    char c = text[(size_t)at + (size_t)used];
    if (c == ',' || c == '}' || c == '\0') break;
    out[used++] = c;
  }
  out[used] = '\0';
  return used > 0;
}

void fetchWeather() {
  WiFiClient client;
  HTTPClient http;
  http.begin(client, "http://weather.mokxi/");
  int code = http.GET();
  if (code <= 0) {
    Serial.print("request failed: ");
    Serial.println(HTTPClient::errorToString(code));
    http.end();
    return;
  }
  Serial.print("HTTP ");
  Serial.println(code);
  String body = http.getString();
  Serial.print("body: ");
  Serial.println(body);

  char value[24];
  if (jsonValue(body.c_str(), "temperatureC", value, sizeof value)) {
    Serial.print("temperature: ");
    Serial.print(value);
    Serial.println(" C");
  }
  if (jsonValue(body.c_str(), "humidity", value, sizeof value)) {
    Serial.print("humidity: ");
    Serial.print(value);
    Serial.println(" %");
  }
  http.end();
}

void setup() {
  Serial.begin(115200);
  Serial.println("Simulated WiFi and a simulated internet: .mokxi names only.");
  WiFi.begin(SSID, PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(250);
  }
  Serial.println();
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  /* A name that is not under .mokxi does not resolve, and says so. */
  HTTPClient outside;
  outside.begin("http://example.com/");
  int code = outside.GET();
  Serial.print("example.com -> ");
  Serial.println(HTTPClient::errorToString(code));
  outside.end();
}

void loop() {
  fetchWeather();
  delay(5000);
}

Parts list

2 parts, plus the jumper wires. Every one is in the editor's parts bin.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.