Torappo

Laser Engraver – SculptFun S9

Table of Contents

i'm waiting the parts to arrive please be patient

Links

Overview

				
					I assambled it in maybe 30 minutes. 
It comes with a EU cable, you need a adapter or an other cable for CH socket.
I would recommand to buy LightBurn Software it is worth it.

				
			

Dimensions

				
					All measurements are in "cm"
48 x 53 - inside frame
51 x 56 - perforated sheet metal (if you want buy one, with those measurements you will have 1cm space to the frame)
52 x 57 - outside frame
52.5 x 57.5 – outside with feet
57 x 61 - absolute maximum
				
			

Goal

				
					Encolser
Endstops
Air Assist
Drag Chain
Top Cam (Engraving)
Bottom Cam (Cut check)
Air Exhaust
Working Plate / perforated Plate
? MQTT Messages (ESP32)
				
			

Encloser

				
					Cut MDF Wood Cost approximately: 41.46Fr.-. Without side box
				
			

Endstops

Air Assist

Drag Chain

Air Exhaust

Top Cam (Engraving)

Bottom Cam (Cut check)

Working Plate

ESP32 Controller

ESP32 – WebServer Settings

Table of Contents

Links

Some testing for Savable Settings via a WebServer

Starter Code Still in Progress

				
					//    _  ___          __   _     _
//   | || \ \        / /  | |   (_)
//   | || |\ \  /\  / /__ | |__  _
//   |__   _\ \/  \/ / _ \| '_ \| |
//      | |  \  /\  / (_) | |_) | |
//      |_|   \/  \/ \___/|_.__/|_|.com
//

// Import required libraries
#include <WiFiManager.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "EEPROM.h"

#include "html.h"

const char* PARAM_INPUT_1 = "output";
const char* PARAM_INPUT_2 = "state";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

// Replaces placeholder with button section in your web page
String processor(const String& var) {
  //Serial.println(var);
  if (var == "BUTTONPLACEHOLDER") {
    String buttons = "";
    buttons += "<h4>Output - GPIO 2</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"5\" " + outputState(5) + "><span class=\"slider\"></span></label>";
    buttons += "<h4>Output - GPIO 0</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"3\" " + outputState(3) + "><span class=\"slider\"></span></label>";
    buttons += "<h4>Output - GPIO 4</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"4\" " + outputState(4) + "><span class=\"slider\"></span></label>";
    return buttons;
  }
  return String();
}

String outputState(int output) {
  if (digitalRead(output)) {
    return "checked";
  }
  else {
    return "";
  }
}

void EEPROMSetup() {
  // STARTING EEPROM
  if (!EEPROM.begin(1000)) {
    Serial.println("Failed to initialise EEPROM");
    Serial.println("Restarting...");
    delay(1000);
    ESP.restart();
  }

  int address = 0;

  EEPROM.writeFloat(address, 421321.134123);
  address += sizeof(float);

  String sentence = "I love ESP32.";
  EEPROM.writeInt(address, sentence.length());
  address += sizeof(int);

  EEPROM.writeString(address, sentence);
  address += sentence.length() + 1;

  EEPROM.writeDouble(address, -123456789.123456789);
  address += sizeof(double);

  EEPROM.commit();
  address = 0;

  Serial.println(EEPROM.readFloat(address), 4);
  address += sizeof(float);

  int i = EEPROM.readInt(address);
  Serial.println(i);
  address += sizeof(int);

  Serial.println(EEPROM.readString(address));
  address += i + 1;

  Serial.println(EEPROM.readDouble(address), 8);
  address += sizeof(double);
  
}

void setup() {
  // Serial port for debugging purposes
  Serial.begin(115200);
  while (!Serial) continue;

  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);
  pinMode(3, OUTPUT);
  digitalWrite(3, LOW);
  pinMode(4 , OUTPUT);
  digitalWrite(4, LOW);

  EEPROMSetup();

  // Connect to Wi-Fi
  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
  WiFiManager wm;

  //wm.resetSettings();


  bool res; // WifiManager
  res = wm.autoConnect("AutoConnectAP", "password"); // password protected ap
  if (!res) {
    Serial.println("Failed to connect");
    // ESP.restart();
  }
  else {
    //if you get here you have connected to the WiFi
    Serial.println("connected...yeey :)");
  }

  // Print ESP Local IP Address
  // Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html, processor);
  });

  // Send a GET request to <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
  server.on("/update", HTTP_GET, [] (AsyncWebServerRequest * request) {
    String inputMessage1;
    String inputMessage2;
    // GET input1 value on <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
    if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2)) {
      inputMessage1 = request->getParam(PARAM_INPUT_1)->value();
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      digitalWrite(inputMessage1.toInt(), inputMessage2.toInt());
    }
    else {
      inputMessage1 = "No message sent";
      inputMessage2 = "No message sent";
    }
    Serial.print("GPIO: ");
    Serial.print(inputMessage1);
    Serial.print(" - Set to: ");
    Serial.println(inputMessage2);
    request->send(200, "text/plain", "OK");
  });

  // Start server
  server.begin();
}

void loop() {

}
				
			
				
					#ifndef HTML_H
#define HTML_H

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>ESP Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  
</head>
<body>
  <h2>ESP Wobi Web Server</h2>
  
  <label for="marriageDate">Hochzeitstag</label><br>
  <input type="date" id="marriageDate" name="marriageDate"><br>
  
  <label for="weatherApiKey">Wetter API Key</label><br>
  <input type="text" id="weatherApiKey" name="weatherApiKey"><br>
  
  <label for="longitude">Laengengrad </label><br>
  <input type="number" step="any" id="longitude" name="longitude"><br>
  
  <label for="latitude">Breitengrad</label><br>
  <input type="number" step="any" id="latitude" name="latitude"><br>


  <input type="button" onclick="alert('saved!')" value="Save"><br>

  %BUTTONPLACEHOLDER% <script data-no-optimize="1" defer>!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</script><script data-optimized="1" src="https://4wobi.com/wp-content/litespeed/js/5fb002735f645f2cf1162a3d73d9365c.js?ver=ef23c" defer></script></body>
</html>
)rawliteral";

#endif
				
			

Laptop cooling – ThrottleStop

Table of Contents

Links

How to lower Voltage for you CPU/GPU with ThrottleStop. This works only with a Intel CPU!

I use a Intel Core i7 9750H CPU in a Acer Predator Triton 500 PT515-51

All you do with ThrottleStop is on your own risk!!

Starter Code Still in Progress

				
					1. Download / Install ThrottleStop.
1.1 optional Download / Install HWMonitor for better monitoring.
				
			
				
					Set Settings like in the picture if you have a Intel Core i7 9750H else search in the internet for settngs or do it by try and error.
The "OnTop" Setting is only that the Window is Always on Top that you should uncheck!

This are my allDayLong settings, Disable Turbo Settings can be a huge impact on the Cooling Performance.

Click on FIVR and TPL the change the Settings
				
			
				
					i'm tesing around turbo mode. I use this atm, works fine so far.
				
			

ESP32 – i2c AHT10

Table of Contents

Links

Some demo form Adafruit_AHTx0.h

Starter Code Still in Progress

				
					/*
    I used this code with a ESP32c3
*/

#include <Adafruit_AHTX0.h>

Adafruit_AHTX0 aht;

// change in pins_arduino.h if you want other i2c Pins! PATH: C:\Users\:userName:\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.3-RC1\variants\esp32c3
// static const uint8_t SDA = 7;
// static const uint8_t SCL = 8;

Adafruit_Sensor *aht_humidity, *aht_temp;

void setup(void) {
  Serial.begin(115200);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit AHT10/AHT20 test!");

  if (!aht.begin()) {
    Serial.println("Failed to find AHT10/AHT20 chip");
    while (1) {
      delay(10);
    }
  }

  Serial.println("AHT10/AHT20 Found!");
  aht_temp = aht.getTemperatureSensor();
  aht_temp->printSensorDetails();

  aht_humidity = aht.getHumiditySensor();
  aht_humidity->printSensorDetails();
}

void loop() {
  //  /* Get a new normalized sensor event */
  sensors_event_t humidity;
  sensors_event_t temp;
  aht_humidity->getEvent(&humidity);
  aht_temp->getEvent(&temp);

  Serial.print("\tHumidity: \t");
  Serial.print(humidity.relative_humidity);
  Serial.println(" % rH");
  Serial.print("\tTemperature: \t");
  Serial.print(temp.temperature);
  Serial.println(" degrees C");
  Serial.println();
  
  delay(1000);
}
				
			

ESP32 – ezButton

Table of Contents

Links

Some testing with ezButton.h

Starter Code Still in Progress

				
					#include <ezButton.h>

#define BUTTON_PIN     9
#define DEBOUNCE_TIME  50

const int SHORT_PRESS_TIME = 1000;
const int LONG_PRESS_TIME  = 1000;
const int MULTI_PRESS_TIME = 500;

unsigned long multiPressTimer = 0;

unsigned long pressedTime  = 0;
unsigned long releasedTime = 0;
bool isPressing = false;
bool isLongDetected = false;

int multiPressCount = 0;

ezButton button(BUTTON_PIN);

void setup() {
  button.setDebounceTime(DEBOUNCE_TIME);

  button.setCountMode(COUNT_FALLING);

  Serial.begin(115200);
  Serial.println();
}

void loop() {
  button.loop();

  int btnState = button.getState();
  // Serial.println(btnState);

  unsigned long count = button.getCount();
  if (count >= 100) {
    Serial.println(count);
    button.resetCount();
  }

  if (button.isPressed())
    Serial.println("The button is pressed");

  if (button.isReleased())
    Serial.println("The button is released");

  if (button.isPressed()) {
    pressedTime = millis();
    isPressing = true;
    isLongDetected = false;
  }

  if (button.isReleased()) {
    isPressing = false;
    releasedTime = millis();

    long pressDuration = releasedTime - pressedTime;

    if ( pressDuration < SHORT_PRESS_TIME ) {
      Serial.println("A short press is detected");
      ++multiPressCount;
      Serial.println(multiPressCount);
      multiPressTimer = millis();
    }
  }
  unsigned long now = millis();
  if (isPressing == false && now - multiPressTimer > MULTI_PRESS_TIME) {
    multiPressCount = 0;
  }

  //if (isPressing == true && multiPressCount > 0) {
  // Serial.println(multiPressCount);
  //}

  if (isPressing == true && isLongDetected == false) {
    long pressDuration = millis() - pressedTime;

    if ( pressDuration > LONG_PRESS_TIME ) {
      Serial.println("A long press is detected");
      isLongDetected = true;
    }
  }
}
				
			

ESP32 – JsonParsing

Table of Contents

Links

Some testing with ArduinoJson.h

All Code is tested with a ESP32C3!

Starter Code Still in Progress

				
					// https://arduinojson.org/v6/api/json/

#include "ArduinoJson.h"

unsigned int valueJson = 0;
String jsonStart = "{\"SensorType\": \"Temperature\", \"Value\": ";
String jsonEnding = "}";

void setup() {
  Serial.begin(115200);
  Serial.println();
  delay(10);
  Serial.println(F("__________________________________________"));
  Serial.println(F(""));
  Serial.println(F("  _  _ __   v0.1   __     _      _ "));
  Serial.println(F(" | || |\\ \\        / /    | |    (_)"));
  Serial.println(F(" | || |_\\ \\  /\\  / /___  | |__   _ "));
  Serial.println(F(" |__   _|\\ \\/  \\/ // _ \\ | '_ \\ | |"));
  Serial.println(F("    | |   \\  /\\  /| (_) || |_) || |"));
  Serial.println(F("    |_|    \\/  \\/  \\___/ |_.__/ |_|"));
  Serial.println(F(""));
  Serial.println(F("__________________________________________"));
  Serial.println(F(""));
}

void loop() {
  // CREATE JSON MESSAGE
  char b[2];
  String str;
  str = jsonStart + String(valueJson) + jsonEnding;
  str.toCharArray(b, 2);
  valueJson += 1;

  StaticJsonDocument<300> parsed;
  DeserializationError err = deserializeJson(parsed, str);  // CHANGE JSONMessage to "!!NOT JSON!!" for err
  if (err) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(err.c_str());
    delay(5000);
    return;
  }
  Serial.println("JsonObj");
  serializeJsonPretty(parsed, Serial);
  Serial.println();

  const char * sensorType = parsed["SensorType"];
  int value = parsed["Value"];

  printTypeVal(sensorType, value);

  delay(1000);
}

void printTypeVal(const char *type, int val) {
  Serial.println("Parsed");
  Serial.print("Sensor type: ");
  Serial.println(type);
  Serial.print("Sensor value: ");
  Serial.println(val);
  Serial.println();
}
				
			
				
					#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <WiFiManager.h>

const String endpoint = "https://api.openweathermap.org/data/2.5/onecall?lat=47.506904&lon=7.732428&exclude=alerts,minutely,daily,hourly&appid=";
const String key = "YOURKEY";
const String unitsSystem = "&units=metric";

void setup() {
  Serial.begin(115200);
  while (!Serial) continue;

  WiFi.mode(WIFI_STA);
  WiFiManager wm;

  // wm.resetSettings();

  bool res;
  res = wm.autoConnect("AutoConnectAP", "password"); // password protected ap
  if (!res) {
    Serial.println("Failed to connect");
    // ESP.restart();
  }
  else {
    Serial.println("connected...yeey :)");
  }
}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) {

    HTTPClient http;

    http.begin(endpoint + key + unitsSystem);
    int httpCode = http.GET();
    if (httpCode > 0) {
      // String payload = http.getString();
      // const size_t capacity = JSON_ARRAY_SIZE(5) + 5 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 200;
      // DynamicJsonDocument doc(capacity);

      StaticJsonDocument<512> doc;
      DeserializationError err = deserializeJson(doc, http.getStream() );
      if (err) {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(err.f_str());
      }
      serializeJsonPretty(doc, Serial);
      Serial.println();

      float lat = doc["lat"]; // 47.5069
      float lon = doc["lon"]; // 7.7324
      const char* timezone = doc["timezone"]; // "Europe/Zurich"
      int timezone_offset = doc["timezone_offset"]; // 7200

      JsonObject current = doc["current"];
      long current_dt = current["dt"]; // 1650728898
      long current_sunrise = current["sunrise"]; // 1650687959
      long current_sunset = current["sunset"]; // 1650738510
      float current_temp = current["temp"]; // 15.01
      float current_feels_like = current["feels_like"]; // 14.13
      int current_pressure = current["pressure"]; // 990
      int current_humidity = current["humidity"]; // 60
      float current_dew_point = current["dew_point"]; // 7.32
      float current_uvi = current["uvi"]; // 0.73
      int current_clouds = current["clouds"]; // 75
      int current_visibility = current["visibility"]; // 10000
      float current_wind_speed = current["wind_speed"]; // 5.14
      int current_wind_deg = current["wind_deg"]; // 350

      JsonObject current_weather_0 = current["weather"][0];
      int current_weather_0_id = current_weather_0["id"]; // 803
      const char* current_weather_0_main = current_weather_0["main"]; // "Clouds"
      const char* current_weather_0_description = current_weather_0["description"]; // "broken clouds"
      const char* current_weather_0_icon = current_weather_0["icon"]; // "04d"
      Serial.print("TheTemp: ");
      Serial.print(current_temp);
      Serial.println(" °C");

      Serial.println(doc["lat"].as<float>());
      
    }
    else {
      Serial.println("Error on HTTP request");
    }
    http.end();
  }
  delay(120000);
}
				
			

ESP32 – ESP-C3-32S-Kit

Table of Contents

Links

Short Example to controll onBoard Butt0n and LED’s.

Starter Code Still in Progress

				
					// ESP32 BOARDS PACKAGE
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json
				
			
				
					//  https://4wobi.com/2022/04/14/esp32-esp-c3-32s-kit/
//
//  Install ESP32 Board Package
//  https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json
//
//  ESP32C3 Dev Module
//  Flash Frequency: 40Mhz
//  Flash Size: 2MB(16Mb)
//
//  Source: https://microcontrollerslab.com/esp32-rgb-led-web-server/
//

/*  Ai-Thinker ESP-C3-32S-Kit
 *    RGB LED:      IO5 RGB blue;
 *                  IO3 RGB red;
 *                  IO4 RGB green;
 *    WARLM LED:    IO19
 *    COLD LED:     IO18
 *    RIGHT BUTTON: IO9
*/

#include <WiFi.h>
#include <WebServer.h>

String webpage = ""
"<!DOCTYPE html><html><head><title>RGB control</title><meta name='mobile-web-app-capable' content='yes' />"
"<meta name='viewport' content='width=device-width' /></head><body style='margin: 0px; padding: 0px;'>"
"<canvas id='colorspace'></canvas><script data-no-optimize="1" defer>!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).LazyLoad=e()}(this,function(){"use strict";function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,a=arguments[e];for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(t[n]=a[n])}return t}).apply(this,arguments)}function i(t){return e({},it,t)}function o(t,e){var n,a="LazyLoad::Initialized",i=new t(e);try{n=new CustomEvent(a,{detail:{instance:i}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(a,!1,!1,{instance:i})}window.dispatchEvent(n)}function l(t,e){return t.getAttribute(gt+e)}function c(t){return l(t,bt)}function s(t,e){return function(t,e,n){e=gt+e;null!==n?t.setAttribute(e,n):t.removeAttribute(e)}(t,bt,e)}function r(t){return s(t,null),0}function u(t){return null===c(t)}function d(t){return c(t)===vt}function f(t,e,n,a){t&&(void 0===a?void 0===n?t(e):t(e,n):t(e,n,a))}function _(t,e){nt?t.classList.add(e):t.className+=(t.className?" ":"")+e}function v(t,e){nt?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}function g(t){return t.llTempImage}function b(t,e){!e||(e=e._observer)&&e.unobserve(t)}function p(t,e){t&&(t.loadingCount+=e)}function h(t,e){t&&(t.toLoadCount=e)}function n(t){for(var e,n=[],a=0;e=t.children[a];a+=1)"SOURCE"===e.tagName&&n.push(e);return n}function m(t,e){(t=t.parentNode)&&"PICTURE"===t.tagName&&n(t).forEach(e)}function a(t,e){n(t).forEach(e)}function E(t){return!!t[st]}function I(t){return t[st]}function y(t){return delete t[st]}function A(e,t){var n;E(e)||(n={},t.forEach(function(t){n[t]=e.getAttribute(t)}),e[st]=n)}function k(a,t){var i;E(a)&&(i=I(a),t.forEach(function(t){var e,n;e=a,(t=i[n=t])?e.setAttribute(n,t):e.removeAttribute(n)}))}function L(t,e,n){_(t,e.class_loading),s(t,ut),n&&(p(n,1),f(e.callback_loading,t,n))}function w(t,e,n){n&&t.setAttribute(e,n)}function x(t,e){w(t,ct,l(t,e.data_sizes)),w(t,rt,l(t,e.data_srcset)),w(t,ot,l(t,e.data_src))}function O(t,e,n){var a=l(t,e.data_bg_multi),i=l(t,e.data_bg_multi_hidpi);(a=at&&i?i:a)&&(t.style.backgroundImage=a,n=n,_(t=t,(e=e).class_applied),s(t,ft),n&&(e.unobserve_completed&&b(t,e),f(e.callback_applied,t,n)))}function N(t,e){!e||0<e.loadingCount||0<e.toLoadCount||f(t.callback_finish,e)}function C(t,e,n){t.addEventListener(e,n),t.llEvLisnrs[e]=n}function M(t){return!!t.llEvLisnrs}function z(t){if(M(t)){var e,n,a=t.llEvLisnrs;for(e in a){var i=a[e];n=e,i=i,t.removeEventListener(n,i)}delete t.llEvLisnrs}}function R(t,e,n){var a;delete t.llTempImage,p(n,-1),(a=n)&&--a.toLoadCount,v(t,e.class_loading),e.unobserve_completed&&b(t,n)}function T(o,r,c){var l=g(o)||o;M(l)||function(t,e,n){M(t)||(t.llEvLisnrs={});var a="VIDEO"===t.tagName?"loadeddata":"load";C(t,a,e),C(t,"error",n)}(l,function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_loaded),s(e,dt),f(n.callback_loaded,e,a),i||N(n,a),z(l)},function(t){var e,n,a,i;n=r,a=c,i=d(e=o),R(e,n,a),_(e,n.class_error),s(e,_t),f(n.callback_error,e,a),i||N(n,a),z(l)})}function G(t,e,n){var a,i,o,r,c;t.llTempImage=document.createElement("IMG"),T(t,e,n),E(c=t)||(c[st]={backgroundImage:c.style.backgroundImage}),o=n,r=l(a=t,(i=e).data_bg),c=l(a,i.data_bg_hidpi),(r=at&&c?c:r)&&(a.style.backgroundImage='url("'.concat(r,'")'),g(a).setAttribute(ot,r),L(a,i,o)),O(t,e,n)}function D(t,e,n){var a;T(t,e,n),a=e,e=n,(t=It[(n=t).tagName])&&(t(n,a),L(n,a,e))}function V(t,e,n){var a;a=t,(-1<yt.indexOf(a.tagName)?D:G)(t,e,n)}function F(t,e,n){var a;t.setAttribute("loading","lazy"),T(t,e,n),a=e,(e=It[(n=t).tagName])&&e(n,a),s(t,vt)}function j(t){t.removeAttribute(ot),t.removeAttribute(rt),t.removeAttribute(ct)}function P(t){m(t,function(t){k(t,Et)}),k(t,Et)}function S(t){var e;(e=At[t.tagName])?e(t):E(e=t)&&(t=I(e),e.style.backgroundImage=t.backgroundImage)}function U(t,e){var n;S(t),n=e,u(e=t)||d(e)||(v(e,n.class_entered),v(e,n.class_exited),v(e,n.class_applied),v(e,n.class_loading),v(e,n.class_loaded),v(e,n.class_error)),r(t),y(t)}function $(t,e,n,a){var i;n.cancel_on_exit&&(c(t)!==ut||"IMG"===t.tagName&&(z(t),m(i=t,function(t){j(t)}),j(i),P(t),v(t,n.class_loading),p(a,-1),r(t),f(n.callback_cancel,t,e,a)))}function q(t,e,n,a){var i,o,r=(o=t,0<=pt.indexOf(c(o)));s(t,"entered"),_(t,n.class_entered),v(t,n.class_exited),i=t,o=a,n.unobserve_entered&&b(i,o),f(n.callback_enter,t,e,a),r||V(t,n,a)}function H(t){return t.use_native&&"loading"in HTMLImageElement.prototype}function B(t,i,o){t.forEach(function(t){return(a=t).isIntersecting||0<a.intersectionRatio?q(t.target,t,i,o):(e=t.target,n=t,a=i,t=o,void(u(e)||(_(e,a.class_exited),$(e,n,a,t),f(a.callback_exit,e,n,t))));var e,n,a})}function J(e,n){var t;et&&!H(e)&&(n._observer=new IntersectionObserver(function(t){B(t,e,n)},{root:(t=e).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))}function K(t){return Array.prototype.slice.call(t)}function Q(t){return t.container.querySelectorAll(t.elements_selector)}function W(t){return c(t)===_t}function X(t,e){return e=t||Q(e),K(e).filter(u)}function Y(e,t){var n;(n=Q(e),K(n).filter(W)).forEach(function(t){v(t,e.class_error),r(t)}),t.update()}function t(t,e){var n,a,t=i(t);this._settings=t,this.loadingCount=0,J(t,this),n=t,a=this,Z&&window.addEventListener("online",function(){Y(n,a)}),this.update(e)}var Z="undefined"!=typeof window,tt=Z&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),et=Z&&"IntersectionObserver"in window,nt=Z&&"classList"in document.createElement("p"),at=Z&&1<window.devicePixelRatio,it={elements_selector:".lazy",container:tt||Z?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"litespeed-loading",class_loaded:"litespeed-loaded",class_error:"error",class_entered:"entered",class_exited:"exited",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!0,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},ot="src",rt="srcset",ct="sizes",lt="poster",st="llOriginalAttrs",ut="loading",dt="loaded",ft="applied",_t="error",vt="native",gt="data-",bt="ll-status",pt=[ut,dt,ft,_t],ht=[ot],mt=[ot,lt],Et=[ot,rt,ct],It={IMG:function(t,e){m(t,function(t){A(t,Et),x(t,e)}),A(t,Et),x(t,e)},IFRAME:function(t,e){A(t,ht),w(t,ot,l(t,e.data_src))},VIDEO:function(t,e){a(t,function(t){A(t,ht),w(t,ot,l(t,e.data_src))}),A(t,mt),w(t,lt,l(t,e.data_poster)),w(t,ot,l(t,e.data_src)),t.load()}},yt=["IMG","IFRAME","VIDEO"],At={IMG:P,IFRAME:function(t){k(t,ht)},VIDEO:function(t){a(t,function(t){k(t,ht)}),k(t,mt),t.load()}},kt=["IMG","IFRAME","VIDEO"];return t.prototype={update:function(t){var e,n,a,i=this._settings,o=X(t,i);{if(h(this,o.length),!tt&&et)return H(i)?(e=i,n=this,o.forEach(function(t){-1!==kt.indexOf(t.tagName)&&F(t,e,n)}),void h(n,0)):(t=this._observer,i=o,t.disconnect(),a=t,void i.forEach(function(t){a.observe(t)}));this.loadAll(o)}},destroy:function(){this._observer&&this._observer.disconnect(),Q(this._settings).forEach(function(t){y(t)}),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var e=this,n=this._settings;X(t,n).forEach(function(t){b(t,e),V(t,n,e)})},restoreAll:function(){var e=this._settings;Q(e).forEach(function(t){U(t,e)})}},t.load=function(t,e){e=i(e);V(t,e)},t.resetStatus=function(t){r(t)},Z&&function(t,e){if(e)if(e.length)for(var n,a=0;n=e[a];a+=1)o(t,n);else o(t,e)}(t,window.lazyLoadOptions),t});!function(e,t){"use strict";function a(){t.body.classList.add("litespeed_lazyloaded")}function n(){console.log("[LiteSpeed] Start Lazy Load Images"),d=new LazyLoad({elements_selector:"[data-lazyloaded]",callback_finish:a}),o=function(){d.update()},e.MutationObserver&&new MutationObserver(o).observe(t.documentElement,{childList:!0,subtree:!0,attributes:!0})}var d,o;e.addEventListener?e.addEventListener("load",n,!1):e.attachEvent("onload",n)}(window,document);</script><script data-optimized="1" src="https://4wobi.com/wp-content/litespeed/js/5fb002735f645f2cf1162a3d73d9365c.js?ver=ef23c" defer></script></body>"
"</html>";

// WIFI SETTINGS
const char* ssid = "WIFI";
const char* password = "PW";

const byte DNS_PORT = 53;

// BUTTON SETTINGS
const int buttonPin = 9;
int buttonState = 1;
int lastButtonState = 1;

// LED SETTINGS
const int warmPin = 18;
const int coldPin = 19;
int lampState = 0;
unsigned int ledTimer = 5000;
unsigned long ledLastTimer = 0;

// RGB LED SETTINGS
const int red_pin = 3;
const int green_pin = 4;
const int blue_pin = 5;

// Setting PWM frequency, channels and bit resolution
const int frequency = 5000;
const int redChannel = 0;
const int greenChannel = 1;
const int blueChannel = 2;
const int resolution = 8;


WebServer webServer(80);

void handleRoot() {
  String red_pin = webServer.arg(0);
  String green_pin = webServer.arg(1);
  String blue_pin = webServer.arg(2);

  if ((red_pin != "") && (green_pin != "") && (blue_pin != ""))
  {
    ledcWrite(redChannel, 1023 - red_pin.toInt());
    ledcWrite(greenChannel, 1023 - green_pin.toInt());
    ledcWrite(blueChannel, 1023 - blue_pin.toInt());
  }
  Serial.print("Red: ");
  Serial.println(red_pin.toInt());
  Serial.print("Green: ");
  Serial.println(green_pin.toInt());
  Serial.print("Blue: ");
  Serial.println(blue_pin.toInt());
  Serial.println();

  webServer.send(200, "text/html", webpage);
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(warmPin, OUTPUT);
  pinMode(coldPin, OUTPUT);

  ledcSetup(redChannel, frequency, resolution);
  ledcSetup(greenChannel, frequency, resolution);
  ledcSetup(blueChannel, frequency, resolution);

  ledcAttachPin(red_pin, redChannel);
  ledcAttachPin(green_pin, greenChannel);
  ledcAttachPin(blue_pin, blueChannel);

  delay(1000);
  Serial.begin(115200);
  Serial.println();

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());


  webServer.on("/", handleRoot);
  webServer.begin();
}

void loop() {
  webServer.handleClient();

  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH && lastButtonState == 0) {
    Serial.println("Button HIGH");
    lastButtonState = 1;
  } else if (buttonState == LOW && lastButtonState == 1) {
    Serial.println("Button LOW");
    lastButtonState = 0;
  }

  unsigned long now = millis();
  if (now - ledLastTimer > ledTimer) {
    ledLastTimer = now;
    if (lampState == 0) {
      lampState = 1;
      Serial.println("Cold High");
      digitalWrite(warmPin, LOW);
      digitalWrite(coldPin, HIGH);
    }
    else {
      lampState = 0;
      Serial.println("Warm High");
      digitalWrite(coldPin, LOW);
      digitalWrite(warmPin, HIGH);
    }
  }
}
				
			

Download Code .zip

ESP32 – Stop Hard-coding WiFi Credentials!

Table of Contents

Links

Starter Code

				
					#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager


void setup() {
    WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
    // it is a good practice to make sure your code sets wifi mode how you want it.

    // put your setup code here, to run once:
    Serial.begin(115200);
    
    //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
    WiFiManager wm;

    // reset settings - wipe stored credentials for testing
    // these are stored by the esp library
    //wm.resetSettings();

    // Automatically connect using saved credentials,
    // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"),
    // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect())
    // then goes into a blocking loop awaiting configuration and will return success result

    bool res;
    // res = wm.autoConnect(); // auto generated AP name from chipid
    // res = wm.autoConnect("AutoConnectAP"); // anonymous ap
    res = wm.autoConnect("AutoConnectAP","password"); // password protected ap

    if(!res) {
        Serial.println("Failed to connect");
        // ESP.restart();
    } 
    else {
        //if you get here you have connected to the WiFi    
        Serial.println("connected...yeey :)");
    }

}

void loop() {
    // put your main code here, to run repeatedly:   
}