logo elektroda
logo elektroda
X
logo elektroda

ESP32: Web page with reading and writing data from the controller via I2C?

margas60 297 9
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 21481668
    margas60
    Level 7  
    Hey. I know you're all very busy and don't have time to deal with trivialities, but maybe someone will have mercy and help me finish my scribbles and run them on ESP32 as a web page with the possibility of reading and entering data which will be written and read from the controller via I2C. This is what I managed to scribble in the troublesome ARDUINO and this is where my possibilities end.
    
    #include <ESP8266WiFi.h>
    #include <Wire.h>
    
    //==================================================
    // tu w planach definicja transmisji RS232
    // wysyłanie i pobieranie danych z falownika 
    // wraz z komunikacja poprzez wifi z programem WATCHPOWER
    // zainstalowanym na komputerze w sieci LAN np: laptopie
    //==================================================  
    // zaloguj do WiFi
    const char* ssid = "VISCOM";
    const char* password = "Norwida@1/11";
    WiFiServer server(80);  // port 80
    String header;
    
    //=====================================================================
    // wymiana danych po I2C do sterownika
    #define dane_adr 0x10
    // Bufory danych
    uint8_t tx_buffer[64];
    uint8_t rx_buffer[64];
    
    void send_data_to_dane(uint8_t *data, uint8_t length) {
        Wire.beginTransmission(atmega_adr);
        for (uint8_t i = 0; i < length; i++) {
            Wire.write(data[i]);
        }
        Wire.endTransmission();
    }
    
    void receive_data_from_dane(uint8_t *data, uint8_t length) {
        Wire.requestFrom(atmega_adr, length);
        uint8_t index = 0;
        while (Wire.available()) {
            data[index++] = Wire.read();
        }
    }
    
    //=========================================================================
    float napiecie_pv1, prad_pv1, moc_pv1, napiecie_pv2, prad_pv2, moc_pv2;
    float napiecie_gen, prad_gen, moc_gen, napiecie_aku, prad_aku, moc_aku;
    float aku_min, aku_max;
    uint8_t out1, out2, out3, out4, out5, out6, out7, out8;;
    uint8_t zwloka_out1, zwloka_out2, zwloka_out3, zwloka_out4, zwloka_out7; 
    
    // deklaracje brakujacych zmiennych
    bool toggleState = false;
    int delayValue = 1000;                    // domyslny delay
    // Definicje pinów
    const int alarm_key = D3;                 // Przycisk aktywacji / dezaktywacji alarmu
    const int door_sensor = D4;               // Czujnik drzwiowy
    const int led_blink = D7;                 // Sygnalizacja uzbrojonego alarmu
    const int alarm_syrena = D8;              // Syrena alarmowa
    
    // Zmienne stanu
    bool alarmActive = false;                 // Czy alarm jest aktywny
    bool alarm_syrenaActive = false;          // Czy syrena jest aktywna
    bool ledBlinkState = false;               // Stan migania diody
    unsigned long ledBlinkLastTime = 0;       // Czas ostatniej zmiany stanu diody
    unsigned long alarm_syrenaStartTime = 0;  // Czas rozpoczęcia alarmu
    const int alarm_syrenaDuration = 15;      // Czas trwania syreny w sekundach
    //**************************************************************************
    void setup() 
    {
      pinMode(alarm_key, INPUT_PULLUP);       // Przycisk z podciąganiem
      pinMode(door_sensor, INPUT_PULLUP);     // Czujnik drzwiowy z podciąganiem
      pinMode(led_blink, OUTPUT);             // sygnalizacja uzbrojenia alarmu
      pinMode(alarm_syrena, OUTPUT);          // syrena alarmowa
      Serial.begin(115000);                   // szybkośc transmisji na port szregowy
    
      // wysłanie danych na port szeregowy - wyswietl polaczenie z WiFi
      WiFi.begin(ssid, password);
      Serial.print("Connecting to ");
      Serial.println(ssid);
      while (WiFi.status() != WL_CONNECTED) 
      {
        delay(500);
        Serial.print(".");
      }
      
      Serial.println("");
      Serial.println("WiFi connected.");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());         // polaczony z IP
      server.begin();
    }
    //***************************************************************************
    void loop() 
    {
      // Dane do przesyłania (przykład)
      uint8_t variables_to_send[] = { napiecie_pv1, prad_pv1, moc_pv1, napiecie_pv2, prad_pv2, moc_pv2,
                                      napiecie_gen, prad_gen, moc_gen, napiecie_aku, prad_aku, moc_aku,
                                      aku_min, aku_max,out1, out2, out3, out4, out5, out6, out7, out8,
                                      zwloka_out1, zwloka_out2, zwloka_out3, zwloka_out4, zwloka_out7 };
      send_data_to_data(variables_to_send, sizeof(variables_to_send));
    
      // Odbieranie danych
      uint8_t received_data[64];
      receive_data_from_data(received_data, sizeof(received_data));
    
      // Debugowanie przez UART
      for (uint8_t i = 0; i < sizeof(received_data); i++) {
          Serial.print("Odebrano: ");
          Serial.println(received_data[i]);
      }
        delay(1000);
      // Odczyt stanu przycisku i czujnika
      static bool lastAlarmKeyState = HIGH;
      bool alarmKeyState = digitalRead(alarm_key);
      int doorState = digitalRead(door_sensor);
    
      // OBSŁUGA ALARMU BRZPIECZEŃSTWA PRZEZ ESP8266
      // Obsługa alarm_key
      if (alarmKeyState == LOW && lastAlarmKeyState == HIGH) { // Reakcja na zbocze opadające
        delay(10);                                             // deboucing
        alarmActive = !alarmActive; // Przełącz stan alarmu
        if (alarmActive) {
          Serial.println("Alarm aktywowany!");
        } else {
          Serial.println("Alarm dezaktywowany!");
          digitalWrite(led_blink, LOW); // Wyłącz diodę
          ledBlinkState = false;
        }
      }
      lastAlarmKeyState = alarmKeyState;
    
      // Jeśli alarm jest aktywny
      if (alarmActive) {
        // Miganie diody co 0,5 sekund
        unsigned long currentTime = millis();
        if (currentTime - ledBlinkLastTime >= 500) {
          ledBlinkState = !ledBlinkState;
          digitalWrite(led_blink, ledBlinkState ? HIGH : LOW);
          ledBlinkLastTime = currentTime;
        }
    
        // Obsługa czujnika drzwiowego
        if (doorState == LOW && !alarm_syrenaActive) {
          alarm_syrenaActive = true;
          alarm_syrenaStartTime = millis();
          digitalWrite(alarm_syrena, HIGH);
          Serial.println("Syrena włączona!");
        }
    
        // Wyłączanie syreny po upływie czasu
        if (alarm_syrenaActive) {
          unsigned long elapsedTime = (millis() - alarm_syrenaStartTime) / 1000; // Oblicz czas
          int remainingTime = alarm_syrenaDuration - elapsedTime;                // Pozostały czas
    
          Serial.print("Czas alarmu: ");
          Serial.println(remainingTime);
    
          if (remainingTime <= 0) {
            digitalWrite(alarm_syrena, LOW);
            alarm_syrenaActive = false;
            Serial.println("Syrena wyłączona!");
          }
        }
      }
    
      // komunikacja przez WIFI
      WiFiClient client = server.accept();    // Nasłuchuj na nadchodzące połączenia
      if (client) 
      {
        Serial.println("New Client.");
        String currentLine = "";              // ciąg przechowywania danych przychodzące od klienta
        while (client.connected()) 
        {
          if (client.available()) 
          {
            char c = client.read(); // czytaj
            header += c;
            if (c == '\n') 
            {
              if (currentLine.length() == 0) 
              {
                sendHTMLResponse(client);
                break;
              } 
              else 
              {
                currentLine = "";
              }
            } 
            else if (c != '\r') 
            {
              currentLine += c;
            }
    
            // Parse the HTTP request
            if (header.indexOf("GET /toggle") >= 0) 
            {
              toggleState = !toggleState;
              Serial.print("Toggle State: ");
              Serial.println(toggleState);
            }
            if (header.indexOf("GET /delay?value=") >= 0) 
            {
              int index = header.indexOf("value=") + 6;
              delayValue = header.substring(index).toInt();
              Serial.print("Delay Value: ");
              Serial.println(delayValue);
            }
          }
        }
        // czysc zmienne
        header = "";
        client.stop();
        Serial.println("Client disconnected.");
      }
    }
    
    void sendHTMLResponse(WiFiClient& client) 
    {
      String html = R"rawliteral(
    <!DOCTYPE html>
    <html lang="pl">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>HOME SOLAR SYSTEM</title>
        <meta http-equiv="refresh" content="15"> <!-- Refresh every x second -->
        <style>
            body { 
                font-family: Arial, sans-serif; 
                text-align: center; 
                margin: 0; /* Usuń domyślne marginesy przeglądarki */
                display: flex; /* Flexbox na całe ciało strony */
                justify-content: center; /* Wyśrodkowanie w poziomie */
                align-items: center; /* Wyśrodkowanie w pionie */
                height: 100vh; /* Wysokość ekranu */
                background-color: black; /* #f4f4f4 Jasne tło dla lepszej czytelności */
            }
            .container { 
                width: 80%; /* Maksymalna szerokość kontenera */
                max-width: 1280px; /* Limit szerokości kontenera */
                background: lightgrey; /* #ffffff Białe tło dla treści */
                padding: 20px; /* Wewnętrzne odstępy */
                border-radius: 10px; /* Zaokrąglone rogi */
                box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Delikatny cień */
            }
            .row { 
                display: flex; /* Układ elastyczny w wierszu */
                justify-content: flex-start; /* Elementy wyrównane do początku */
                align-items: center; /* Wyrównanie w pionie */
                margin-bottom: 8px; /* Odstęp między wierszami */
            }
            .row > * {
                margin-right: 30px; /* Odstęp między kolumnami */
            }
            .btn-opis { 
                padding: 10px 20px; /* Rozmiar klawisza "Opis funkcji" */
                font-size: 18px; /* Rozmiar tekstu */
                border: none; /* Brak obramowania */
                /*cursor: pointer; */ 
                color: #000; /* zmiana koloru czcionki opisu */ 
                border-radius: 10px; 
                width: 550px; /* Szerokość klawisza "Opis funkcji" */
                height: 50px; 
                background-color: orange; /* tło dla "opisu funkcji" */
            }
            .btn-toggle { 
                padding: 15px 30px; /* Rozmiar klawisza "Włącz/Wyłącz" */
                font-size: 18px; 
                border: none; 
                cursor: pointer; 
                color: #000; /* kolor czcionki klawisza "Włącz/Wyłącz" */ 
                border-radius: 10px; 
                width: 180px; /* Szerokość klawisza "Włącz/Wyłącz" */
                height: 50px; 
            }
            .btn-toggle.green { 
                background-color: lightgreen; /* klawisz w trybie wyłaczony */
            }
            .btn-toggle.red { 
                background-color: red; /* klawisz w trybie załaczony */
            }
            .input { 
                width: 70px; /* Szerokość pola wejściowego */
                text-align: center; /* Wyśrodkowanie tekstu */
                font-size: 18px; /* Rozmiar tekstu */
                padding: 5px; /* Odstępy wewnętrzne */
            }
        </style>
    </head>
    <body>
        <div class="container">
            <h1>PANEL STEROWANIA HOME SOLAR SYSTEM</h1>
              
            <!-- Wiersz 1 -->
            <!-- sterowanie i status wyjścia właczony czy wyłaczony zmiana barwy klawisza zmienna out1 -->
            <div class="row">
                <button class="btn-opis" onclick="alert('Opis funkcji wiersza 1')">Sterowanie zasilaniem obwodu audio i RTV</button>
                <button id="toggleButton1" class="btn-toggle green" onclick="toggleState(1)">out1</button>
                <div>
                    <!-- wyświetlanie ustawionej miennej zwloka_out1-->
                    <input id="delayInput1" class="input" type="number" min="0" max="9" value="0" onchange="setDelay(1)">
                    <label>h</label>
                </div>
            </div>
    
            <!-- Wiersz 2 -->
            <!-- sterowanie i status wyjścia właczony czy wyłaczony zmiana barwy klawisza zmienna out2-->
            <div class="row">
                <button class="btn-opis" onclick="alert('Opis funkcji wiersza 2')">Sterowanie zasilaniem obwodu płyty ceramicznej</button>
                <button id="toggleButton2" class="btn-toggle green" onclick="toggleState(2)">out2</button>
                <div>
                    <!-- wyświetlanie ustawionej zmiennej zwloka_out2-->
                    <input id="delayInput2" class="input" type="number" min="0" max="9" value="0" onchange="setDelay(2)">
                    <label>h</label>
                </div>
            </div>
    
            <!-- Wiersz 3 -->
            <!-- sterowanie i status wyjścia właczony czy wyłaczony zmiana barwy klawisza zmienna out3-->
            <div class="row">
                <button class="btn-opis" onclick="alert('Opis funkcji wiersza 3')">Sterowanie zasilaniem obwodu microfali</button>
                <button id="toggleButton3" class="btn-toggle green" onclick="toggleState(3)">out3</button>
                <div>
                    <!-- wyświetlanie ustawionej zmiennej zwloka_out3-->
                    <input id="delayInput3" class="input" type="number" min="0" max="9" value="0" onchange="setDelay(3)">
                    <label>h</label>
                </div>
            </div>
    
            <!-- Wiersz 4 -->
            <!-- sterowanie i status wyjścia właczony czy wyłaczony zmiana barwy klawisza out4-->
            <div class="row">
                <button class="btn-opis" onclick="alert('Opis funkcji wiersza 4')">Sterowanie obwodem generatora</button>
                <button id="toggleButton4" class="btn-toggle green" onclick="toggleState(4)">out4</button>
                <div>
                    <!-- wyświetlanie ustawionej zmiennej zwloka_out4-->
                    <input id="delayInput4" class="input" type="number" min="0" max="9" value="0" onchange="setDelay(4)">
                    <label>h</label>
                </div>
            </div>
    
            <!-- Wiersz 5 -->
            <!-- monitorowanie statusu falownika właczony czy wyłaczony zmiana barwy klawisza -->
            <div class="row">
                    <!-- wyświetlanie statusu falownika zmienna out_5-->
                    <button class="btn-opis" onclick="alert('Opis funkcji wiersza 5')">Status falownika i progi napieciowe zał/wył</button>
                    <button id="toggleButton5" class="btn-toggle green" onclick="toggleState(5)">out5</button>
                <div>
                    <!-- wyświetlanie ustawionej zmiennej zezwolenie na załaczenie falownika -->
                    <input id="delayInput5" class="input" type="number" min="23.6" max="24.9" step=0.1 ,value="1" onchange="setDelay(5)">
                    <label>V</label>
                    <!-- wyświetlanie ustawionej miennej automatycznego wyłaczenie falownika -->
                    <input id="delayInput6" class="input" type="number" min="25.0" max="27.0" step=0.1 ,value="1" onchange="setDelay(6)">
                    <label>V</label>
                </div>
            </div>
    
            <!-- Wiersz 6 -->
            <!-- monitorowanie statusu zasilacza właczony czy wyłaczony zmiana barwy klawisza -->
            <div class="row">
                    <!-- wyświetlanie statusu zasilacza zmienna out_6 -->
                    <button class="btn-opis" onclick="alert('Opis funkcji wiersza 6')">Status zasilacz buforowego</button>
                    <button id="toggleButton" class="btn-toggle green" onclick="toggleState(6)">out6</button>
                <div>
                    
                </div>
            </div>
    
            <!-- Wiersz 7 -->
            <!-- właczanie i wyłaczanie systemu alatmowego oraz nastawa czas trwania alarmu -->
            <div class="row">
                    <!-- wyświetlanie statusu falownika zmienna alarm_syrena-->
                    <button class="btn-opis" onclick="alert('Opis funkcji wiersza 5')">Alarm załącz/wyłącz - czas trwania</button>
                    <button id="toggleButton7" class="btn-toggle green" onclick="toggleState(7)">alarm</button>
                <div>
                    <!-- wyświetlanie ustawionej miennej zezwolenie na załaczenie falownika -->
                    <input id="delayInput7" class="input" type="number" min="1" max="60",value="1" onchange="setDelay(7)">
                    <label>sek</label>
                </div>
            </div>
    
            <!-- Wiersz 8 POMIARY PANEL 1 -->
            <!-- wyświetlanie zmiennych napiecie_pv1, prąd_pv1, moc_pv1,-->
            <div class="row">
                <button class="btn-opis" onclick="alert('Opis funkcji wiersza 10')">Obwód fotowoltaiczny nr.1</button>
                
                <div>
                    <button id="toggleButton" class="btn-toggle blue" >27,6V</button>
                    <button id="toggleButton" class="btn-toggle blue" >8,0A</button>
                    <button id="toggleButton" class="btn-toggle blue" >220W</button>
                </div>
            </div>
    
            <!-- Wiersz 9 POMIARAY PANEL 2 -->
            <!-- wyświetlanie zmiennych napiecie_pv2, prad_pv2, moc_pv2, -->
            <div class="row">
                <button class="btn-opis" onclick="alert('Opis funkcji wiersza 10')">Obwód fotowoltaiczny nr.2</button>
                
                <div>
                    <button id="toggleButton" class="btn-toggle lightblue" >27,6V</button>
                    <button id="toggleButton" class="btn-toggle lightblue" >8,0A</button>
                    <button id="toggleButton" class="btn-toggle lightblue" >220W</button>
                </div>
            </div>
    
            <!-- Wiersz 10 POMIARY GENERATOR -->
            <!-- wyświetlanie zmiennych prad_pv1, napiecie_x, prad_x, moc_x; -->
    
            <div class="row">
                <button class="btn-opis" onclick="alert('Opis funkcji wiersza 10')">Obwód ogniwa paliwowego</button>
                
                <div>
                    <button id="toggleButton" class="btn-toggle lightblue" >0,00V</button>
                    <button id="toggleButton" class="btn-toggle lightblue" >0A</button>
                    <button id="toggleButton" class="btn-toggle lightblue" >0W</button>
                </div>
            </div>
    
            <!-- Wiersz 11 POMIARY AKUMULATOR -->
            <!-- wyświetlanie zmiennych napiecie_aku, prad_aku, moc_out; -->
            <div class="row">
                <button class="btn-opis" onclick="alert('Opis funkcji wiersza 10')">Obwód akumulatora</button>
                
                <div>
                    <button id="toggleButton" class="btn-toggle lightblue" >24,2V</button>
                    <button id="toggleButton" class="btn-toggle lightblue" >1A</button>
                    <button id="toggleButton" class="btn-toggle lightblue" >24W</button>
                </div>
            </div>
        </div>
    
        <script>
            function toggleState(row) {
                const button = document.getElementById(`toggleButton${row}`);
                fetch(`/toggle?row=${row}`)
                    .then(response => {
                        if (button.classList.contains('green')) {
                            button.classList.remove('green');
                            button.classList.add('red');
                            button.textContent = 'Wyłącz';
                        } else {
                            button.classList.remove('red');
                            button.classList.add('green');
                            button.textContent = 'Załącz';
                        }
                    });
            }
    
            function setDelay(row) {
                const value = document.getElementById(`delayInput${row}`).value;
                fetch(`/delay?row=${row}&value=${value}`);
            }
        </script>
    </body>
    </html>
    )rawliteral";
    
      // Wyślij odpowiedź HTTP
      client.println("HTTP/1.1 200 OK");
      client.println("Content-type:text/html");
      client.println("Connection: close");
      client.println();
      client.println(html);
    }
    .
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • ADVERTISEMENT
  • ADVERTISEMENT
  • #3 21482424
    margas60
    Level 7  
    And why not this section ... ? Let's start with the fact that I already made the entrance BYK because I have ESP8266 and not ESP32. Nice for the hint but I will not benefit much because adopting your solution for my needs is not feasible with my level of knowledge.
  • #4 21482437
    michal.zd
    Level 28  
    I was expecting this answer. However, I think my code is much easier to extend the functionality than the mess you show.
    margas60 wrote:
    why not this section .... ?
    we have a proper section about microcontrollers and their programming.
  • #5 21482480
    inot
    Level 37  
    It would be necessary to write down what exactly you have a problem with.
  • ADVERTISEMENT
  • #6 21482499
    michal.zd
    Level 28  
    inot wrote:
    Would you please write what exactly you have a problem with.
    .
    And additionally, do you know html and will you make/write a format in html to provide this data and send it to the http server e.g. as a post?
  • #7 21485531
    margas60
    Level 7  
    Ok. I have an Atmeda based controller with a four channel timer and several channels for measuring voltages and currents in low voltage circuits. It's 12 years old and if it breaks down I may not buy an atmegai anymore so I tried to do something on an STM but I totally bailed on it. So I went back to the atmegoi and made new boards, as the old ones were damaged by modifications, but in order to have remote control and monitoring capabilities I need an intermediary which will communicate via I2C with the ESP8266 controller as a web server. The controller already has the additional function of activating a small alarm siren mounted above the door from a radio remote control I carry with me, with a specific time set in the controller to alert the neighbours if I am unconscious or have other cardiac problems. Punching in PINs and 112 and then explaining to the operator that I'm not a camel may not be possible.
  • #8 21485594
    inot
    Level 37  
    Ok, but it is still not clear what is not working in this presented programme. It is easier to look for a given problem as to analyse the whole programme.
  • ADVERTISEMENT
  • #9 21485637
    michal.zd
    Level 28  
    @margas60
    If you have a finished html page with a format for data entry, then it's easy to transfer it literally to my http server. I will help you, you just need to have those html pages.
  • #10 21488673
    michal.zd
    Level 28  
    @margas60
    Given your programming skills (or rather lack of them) I would still urge you to change your approach to this topic.
    What you want to do the easiest way is to buy a ready-made Raspberry pi zeroW minicomputer.
    It's cheap, it has outputs and inputs, it has uart, i2c, it has wifi high computing power, a normal operating system, and most importantly ready-made tools for this kind of task.You add a set of relays to it. There will be a slight problem with voltage measurement. The rpi doesn't have an adc, but with a nucleo (do you still have one?) you transfer the results to the rpi via usb.
    As you can write something there, simple code is not a problem for you, maybe try to do it on node-red. After all, the thread was in the Smart Home iot section.
    It's a cool platform installed on this Raspberry pi, it's designed just for control. There are quite a few pre-made 'nodes' to use, and adding your own is easy, I think JavaScript won't be a problem for you. You don't need to write much, just manipulate data objects. It's much simpler than writing the whole thing in c or c++.
    Node-red is supported by a web interface, so you have a ready-made solution on a tray.
    Take a look at the courses on node-red.

Topic summary

The discussion centers on implementing a web interface on an ESP32 (or ESP8266) microcontroller to read and write data via I2C communication. The original poster attempts to create a web server using Arduino code to interact with a controller through I2C, aiming for remote control and monitoring capabilities. The controller is based on an Atmega microcontroller with timers and analog measurement channels, integrated with an alarm siren triggered by a radio remote. Responses suggest clarifying specific programming issues and inquire about the user's familiarity with HTML for data input forms. Alternative solutions include using a Raspberry Pi Zero W for enhanced processing power, built-in WiFi, and easier integration with I2C and UART peripherals, along with software platforms like Node-RED for simplified control and monitoring. The conversation highlights challenges in adapting existing code, the need for clear problem definition, and the potential benefits of switching to more capable hardware for IoT applications.
Summary generated by the language model.
ADVERTISEMENT