Header Image

Jak vyrobit (téměř) cokoliv

Week 9

Weekly tasks

  • Control your circuit over your local wireless network.
  • Send or get data from the Internet.
  • There is magic in the air, and it's called Wifi

    Wireless communication was the topic of this week. During the preparation for this week I could really sence that I don´t belong here. It is quite magical for me, but we (I) can't be afraid of it.

    The new hero

    It is time we officially throw away beloved Arduino and put our hands on something else. Its name is ESP32 - the workflow is similar to Arduino: you try to send some code, push chaotically some buttons and eventually it would work.

    The biggest difference (for me, as a total electrically uncultured swine) between Arduino and Esp32 is that it can work with Wifi or f.e. Bluetooth.

    I decided to make moving Servo - it would be usefull for my final project where it would work like a switch. I also made a website where you can push "on" or "off" buttons. And because I irrationally hate Bluetooth I used Wifi as a medium of communication.

    Code

        
         #include <WiFi.h>
             #include <ESP32Servo.h>
             
             Servo myservo;  
             
             // GPIO the servo is attached to
             static const int servoPin = 13;
             
             // Replace with your network credentials
             const char* ssid     = "es109_JVC";
             const char* password = "temercoko1i";
             
             // Set web server port number to 80
             WiFiServer server(80);
             
             String header;
             
             unsigned long currentTime = millis();
             unsigned long previousTime = 0; 
             const long timeoutTime = 2000;
             
             void setup() {
               Serial.begin(115200);
               myservo.attach(servoPin);
               myservo.write(0);  // Start at 0 degrees
             
               WiFi.begin(ssid, password);
               Serial.print("Connecting to WiFi");
               while (WiFi.status() != WL_CONNECTED) {
                 delay(500);
                 Serial.print(".");
               }
               Serial.println("\nWiFi connected.");
               Serial.print("IP address: ");
               Serial.println(WiFi.localIP());
             
               server.begin();
             }
             void moveServoSmooth(int fromAngle, int toAngle, int delayPerStep = 15) {
               if (fromAngle < toAngle) {
                 for (int pos = fromAngle; pos <= toAngle; pos++) {
                   myservo.write(pos);
                   delay(delayPerStep);  // controls speed
                 }
               } else {
                 for (int pos = fromAngle; pos >= toAngle; pos--) {
                   myservo.write(pos);
                   delay(delayPerStep);
                 }
               }
             }
             
             
             void loop() {
               WiFiClient client = server.available();
             
               if (client) {
                 currentTime = millis();
                 previousTime = currentTime;
                 Serial.println("New Client.");
                 String currentLine = "";
             
                 while (client.connected() && currentTime - previousTime <= timeoutTime) {
                   currentTime = millis();
             
                   if (client.available()) {
                     char c = client.read();
                     Serial.write(c);
                     header += c;
             
                     if (c == '\n') {
                       if (currentLine.length() == 0) {
                         // Send response headers
                         client.println("HTTP/1.1 200 OK");
                         client.println("Content-type:text/html");
                         client.println("Connection: close");
                         client.println();
             
                         // Control logic based on URL
                         if (header.indexOf("GET /on") >= 0) {
                           moveServoSmooth(0, 60);
                           Serial.println("Servo ON (60 deg)");
                         } else if (header.indexOf("GET /off") >= 0) {
                           moveServoSmooth(60, 0);
                           Serial.println("Servo OFF (0 deg)");
                         }
             
                         // HTML page
                         client.println("&lt;!DOCTYPE html&gt;&lt;html&gt;");
     client.println("&lt;head&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;");
     client.println("&lt;style&gt;body{text-align:center;font-family:Arial;}button{padding:20px 40px;font-size:24px;margin:10px;}&lt;/style&gt;&lt;/head&gt;");
     client.println("&lt;body&gt;&lt;h1&gt;ESP32 Servo Control&lt;/h1&gt;");
     client.println("&lt;p&gt;&lt;a href=&quot;/on&quot;&gt;&lt;button&gt;ON&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;");
     
                       client.println("&lt;p&gt;&lt;a href=&quot;/off&quot;&gt;&lt;button&gt;OFF&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;");
     
                         client.println("&lt;/body&gt;&lt;/html&gt;");
             
                         client.println();
                         break;
                       } else {
                         currentLine = "";
                       }
                     } else if (c != '\r') {
                       currentLine += c;
                     }
                   }
                 }
                 header = "";
                 client.stop();
                 Serial.println("Client disconnected.\n");
               }
             }
             
             
            
          

    Final result

    The final process

    Widget

    The other task was to get some data from the internet. I decided to make weather widget and get data from Openweathermap.
      
        
        const apiKey = 'f8d52c7acb6a806eeaadb6582a14f842'; 
        const url = `https://api.openweathermap.org/data/2.5/weather?id=3067696&appid=${apiKey}&units=metric&lang=cz`;
      
        fetch(url)
          .then(response => response.json())
          .then(data => {
            const icon = data.weather[0].icon;
            const iconUrl = `https://openweathermap.org/img/wn/${icon}.png`;
            const temp = Math.round(data.main.temp);
            const description = data.weather[0].description;
      
            document.getElementById('sidebar-weather').innerHTML = `
              <img src="${iconUrl}" alt="${description}"> ${description}, ${temp}°C
            `;
          })
          .catch(error => {
            document.getElementById('sidebar-weather').textContent = 'Nepodařilo se načíst.';
          });