Не распознаётся массив в websoket

прошу прощения, написал фигню.
Что за идиотская привычка использовать <= в for :slight_smile: - запутывает!!

#include <ArduinoJson.h>
#include <ArduinoJson.hpp>

#ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include "index.h"

const char *ssid = **********";
const char *password = "**************";

#ifdef ARDUINO_ARCH_ESP8266
const int LED_PIN = LED_BUILTIN;
#define LED_ON LOW
#define LED_OFF HIGH
byte const SENSOR_PIN = A0;
#else
const int LED_PIN = 2;
#define LED_ON HIGH
#define LED_OFF LOW
byte const SENSOR_PIN = 34;
#endif

#include "DHT.h"  //https://github.com/adafruit/Adafruit_Sensor
#define DHTPIN D1
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

bool ledState = false;
//byte const pinLED = LED_BUILTIN;

int sensor = 0;
float humidity = 0;
float tempC = 0;
float tempF = 0;

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

#define LATCHPIN D2     //GREEN 9 chip CD4021
#define DATAPIN D3      //YELLOW 3 chip CD4021
#define CLOCKPIN D4     // GREY 10 chip CD4021
byte switchVar1 = 72;   //01001000 регистр сдвига CD4021
byte switchVar2 = 159;  //10011111

void setup() {
  Serial.begin(74880);
  while (!Serial) { ; }
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LED_OFF);
  pinMode(LATCHPIN, OUTPUT);
  pinMode(CLOCKPIN, OUTPUT);
  pinMode(DATAPIN, INPUT);
  pinMode(D2, OUTPUT);
  digitalWrite(D2, LOW);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print('.');
  }
  timeoutNet();
  // attach AsyncWebSocket
  ws.onEvent(onWsEvent);
  server.addHandler(&ws);
  // respond to GET requests on URL /heap
  server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *r) {
    r->send_P(200, "text/html", htmlPage);
  });

  server.on("/health", HTTP_GET, [](AsyncWebServerRequest *r) {
    r->send(200, "text/plain", "ok");
  });
  server.begin();
}

void loop() {
  ws.cleanupClients();
  JsonDocument doc;
  static unsigned long last = 0;
  if (millis() - last > 3000) {
    last = millis();

    // cheek register СВ4021, contact with rezistors 1,5kOm
    digitalWrite(LATCHPIN, 1);
    delayMicroseconds(20);
    digitalWrite(LATCHPIN, 0);
    //--- 1 register СВ4021
    switchVar1 = shiftIn(DATAPIN, CLOCKPIN);
    for (int n = 0; n <= 7; n++) {
      if (switchVar1 & (1 << n)) {       // array[0-7]
        ws.textAll(String("P=") + "1");  //nclose
      } else {
        ws.textAll(String("P=") + "0");  //nopen
      }
    }
    //--- 2 register СВ4021
    switchVar2 = shiftIn(DATAPIN, CLOCKPIN);
    for (int n = 0; n <= 7; n++) {
      if (switchVar2 & (1 << n)) {       // array[7-15]
        ws.textAll(String("P=") + "1");  //nclose
      } else {
        ws.textAll(String("P=") + "0");  //nopen
      }
    }

    updateSensors();
    ws.textAll(String("TEMP:") + tempC);
    ws.textAll(String("HUMID:") + byte(humidity));
    ws.textAll(String("SENSOR:") + byte(sensor));
    // Write JSON document
    //serializeJsonPretty(doc, client);

  }
}
void updateSensors() {
  sensor = map(analogRead(SENSOR_PIN), 0, 1023, 0, 100);
  humidity = dht.readHumidity();
  tempC = dht.readTemperature();      // Read temperature as Celsius
  tempF = dht.readTemperature(true);  // Read temperature as Fahrenheit (isFahrenheit = true)
  //if any value is isnan (not a number) then there is an error
  if (isnan(humidity) || isnan(tempC) || isnan(tempF)) {
    Serial.println("Error reading from the DHT11.");
  } else {
    String data = "";
    data = String(data + sensor);
    data = String(data + "|");
    data = String(data + byte(humidity));
    data = String(data + "|");
    data = String(data + tempC);
    data = String(data + "|");
    data = String(data + tempF);
    Serial.println(data);  // display the data in the serial monitor
  }
}
void onWsEvent(AsyncWebSocket *srv, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
  if (type == WS_EVT_CONNECT) {
    client->text(ledState ? "ON" : "OFF");
    return;
  }
  if (type == WS_EVT_DATA) {
    AwsFrameInfo *info = (AwsFrameInfo *)arg;
    if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
      String msg;
      msg.reserve(len);
      for (size_t i = 0; i < len; i++) msg += (char)data[i];
      if (msg == "TOGGLE") {
        ledState = !ledState;
        digitalWrite(LED_PIN, ledState ? LED_ON : LED_OFF);
        ws.textAll(ledState ? "ON" : "OFF");
      }
    }
  }
}
void timeoutNet() {  // connection with timeout
  int count = 0;
  digitalWrite(LED_BUILTIN, HIGH);
  while ((WiFi.status() != WL_CONNECTED) && count < 17) {
    Serial.print(".");
    count++;
    delay(500);
  }
  digitalWrite(LED_BUILTIN, LOW);
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("");
    Serial.print("Failed to connect to ");
    while (1)
      ;
  }
  Serial.println(ssid);
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
}
// 2 регистра сдвига
byte shiftIn(int DATA, int CLK) {
  int i;
  int temp = 0;
  byte pinState;
  byte inDATE = 0;
  pinMode(CLK, OUTPUT);
  pinMode(DATA, INPUT);
  for (i = D2; i >= 0; i--) {
    digitalWrite(CLK, 0);
    delayMicroseconds(2);
    temp = digitalRead(DATA);
    if (temp) {
      pinState = 1;
      // несмотря ни на что, задаем биту значение «0»:
      inDATE = inDATE | (1 << i);
    } else {
      pinState = 0;
    }
    digitalWrite(CLK, 1);
  }
  return inDATE;
}

Страница то вообще грузится?
смотри строку 194, // это в html не комментирует строку, в html так должно быть <!– –>
208 строка тож неправильно.
в js явно не хватает скобок, но это так на первый взгляд.

Тут не WS не работает, тут ваще страница криво собрана, да еще и скрипт перед body он откуда будет брать const $s = document.getElementById(‘status’); и прочее когда их еще нет?

в css не силен , надеюсь все нормально.

Пойду чая попью, потом еще гляну.

есть косяки дома все было ок, сейчас на работе поэтому перенёс по памяти и что то криво срослось , сам пробую исправить

нашел что функция byte shiftIn(DA,CLK) надо переименовать т.к. есть такая же, но с др. параметрами. например SHIFT(D,C)

// 2 регистра сдвига
byte SHIFT(int DATA, int CLK) {
  int i;
  int temp = 0;
  byte pinState;
  byte inDATE = 0;
  pinMode(CLK, OUTPUT);
  pinMode(DATA, INPUT);
  for (i = D2; i >= 0; i--) {
    digitalWrite(CLK, 0);
    delayMicroseconds(2);
    temp = digitalRead(DATA);
    if (temp) {
      pinState = 1;
      // несмотря ни на что, задаем биту значение «0»:
      inDATE = inDATE | (1 << i);
    } else {
      pinState = 0;
    }
    digitalWrite(CLK, 1);
  }
  return inDATE;
}
      // cheek register СВ4021, contact with rezistors 1,5kOm
      digitalWrite(LATCHPIN, 1);
      delayMicroseconds(20);
      digitalWrite(LATCHPIN, 0);
      //--- 1 register СВ4021
      switchVar1 = SHIFT(DATAPIN, CLOCKPIN);
      for (int n = 0; n <= 7; n++) {
        if (switchVar1 & (1 << n)) {  // array[0-7]
          client.print("1");
          client.print("|");  //nclose
        } else {
          client.print("0");
          client.print("|");  //nopen
        }
      }
      //--- 2 register СВ4021
      switchVar2 = SHIFT(DATAPIN, CLOCKPIN);
      for (int n = 0; n <= 7; n++) {
        if (switchVar2 & (1 << n)) {  // array[7-15]
          client.print("1");
          client.print("|");  //nclose
        } else {
          client.print("0");
          client.print("|");  //nopen
        }
      }

В общем проблема с HTML и JS.

В коде тоже бардак, но причесывать не буду. Тут уж сам.

Смотри я отключил все что касается регистров и DHT11 у меня этого нет.
Температура и влажность передаются рандомные, все работает, а данные с регистров надо передавать одним пакетом, иначе будет постоянно терять соединение. css тоже немного исправил, с цветами была беда.
например такой пакет
{“t”:32,“h”:54,“r11”:0,“r12”:0,“r13”:0,“r14”:0,“r15”:0,“r16”:0,“r17”:0,“r18”:0,“r21”:0,“r22”:0,“r23”:0,“r24”:0,“r25”:0,“r26”:0,“r27”:0,“r28”:0}
если здесь ArduinoJson Assistant 7 вставить JSON то конструктор нарисует код. все просто.
на стороне клиента получаем JSON и распихиваем по ячейкам значения, там вообще все циклами можно сделать если количество передаваемых параметров статично.

ino

#include <ArduinoJson.h>
#include <ArduinoJson.hpp>

#ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include "index.h"

const char *ssid = "***";
const char *password = "***";

#ifdef ARDUINO_ARCH_ESP8266
const int LED_PIN = LED_BUILTIN;
#define LED_ON LOW
#define LED_OFF HIGH
byte const SENSOR_PIN = A0;
#else
const int LED_PIN = 2;
#define LED_ON HIGH
#define LED_OFF LOW
byte const SENSOR_PIN = 34;
#endif

//#include "DHT.h"  //https://github.com/adafruit/Adafruit_Sensor
#define DHTPIN D1
#define DHTTYPE DHT11
//DHT dht(DHTPIN, DHTTYPE);

bool ledState = false;
//byte const pinLED = LED_BUILTIN;

int sensor = 0;
float humidity = 0;
float tempC = 0;
float tempF = 0;

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

//#define LATCHPIN D2     //GREEN 9 chip CD4021
//#define DATAPIN D3      //YELLOW 3 chip CD4021
//#define CLOCKPIN D4     // GREY 10 chip CD4021
byte switchVar1 = 72;   //01001000 регистр сдвига CD4021
byte switchVar2 = 159;  //10011111

void setup() {
  Serial.begin(115200);
  while (!Serial) { ; }
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LED_OFF);
  //pinMode(LATCHPIN, OUTPUT);
  //pinMode(CLOCKPIN, OUTPUT);
  //pinMode(DATAPIN, INPUT);
  //pinMode(D2, OUTPUT);
  //digitalWrite(D2, LOW);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print('.');
  }
  timeoutNet();
  // attach AsyncWebSocket
  ws.onEvent(onWsEvent);
  server.addHandler(&ws);
  // respond to GET requests on URL /heap
  server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *r) {
    r->send_P(200, "text/html", htmlPage);
  });

  server.on("/health", HTTP_GET, [](AsyncWebServerRequest *r) {
    r->send(200, "text/plain", "ok");
  });
  server.begin();
}

void loop() {
  ws.cleanupClients();
  JsonDocument doc;
  static unsigned long last = 0;
  if (millis() - last > 3000) {
    last = millis();

    // cheek register СВ4021, contact with rezistors 1,5kOm
    //digitalWrite(LATCHPIN, 1);
    //delayMicroseconds(20);
    //digitalWrite(LATCHPIN, 0);
    //--- 1 register СВ4021
    //switchVar1 = shiftIn(DATAPIN, CLOCKPIN);

    //здесть ненадо дергать сокет, надо собрать 1 пакет данных и отправить 
    // на стороне клиена расшифровать и расставить по ячейкам.
    /*
    switchVar1 = 125;
    for (int n = 0; n <= 7; n++) {
      if (switchVar1 & (1 << n)) {       // array[0-7]
        ws.textAll(String("P=") + "1");  //nclose
      } else {
        ws.textAll(String("P=") + "0");  //nopen
      }
    }
    //--- 2 register СВ4021
    //switchVar2 = shiftIn(DATAPIN, CLOCKPIN);
    switchVar2 = 252;
    for (int n = 0; n <= 7; n++) {
      if (switchVar2 & (1 << n)) {       // array[7-15]
        ws.textAll(String("P=") + "1");  //nclose
      } else {
        ws.textAll(String("P=") + "0");  //nopen
      }
    }
*/
    updateSensors();
    ws.textAll(String("TEMP:") + tempC);
    ws.textAll(String("HUMID:") + byte(humidity));
    ws.textAll(String("SENSOR:") + byte(sensor));
    // Write JSON document
    //serializeJsonPretty(doc, client);

  }
}
void updateSensors() {
  sensor = map(analogRead(SENSOR_PIN), 0, 1023, 0, 100);
  humidity = random(0,100);
  tempC = random(-273,100);      // Read temperature as Celsius
  tempF = random(459,212);  // Read temperature as Fahrenheit (isFahrenheit = true)

  /*humidity = dht.readHumidity();
  tempC = dht.readTemperature();      // Read temperature as Celsius
  tempF = dht.readTemperature(true);  // Read temperature as Fahrenheit (isFahrenheit = true)
  */
  //if any value is isnan (not a number) then there is an error
  if (isnan(humidity) || isnan(tempC) || isnan(tempF)) {
    Serial.println("Error reading from the DHT11.");
  } else {
    String data = "";
    data = String(data + sensor);
    data = String(data + "|");
    data = String(data + byte(humidity));
    data = String(data + "|");
    data = String(data + tempC);
    data = String(data + "|");
    data = String(data + tempF);
    Serial.println(data);  // display the data in the serial monitor
  }
}
void onWsEvent(AsyncWebSocket *srv, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
  if (type == WS_EVT_CONNECT) {
    client->text(ledState ? "ON" : "OFF");
    return;
  }
  if (type == WS_EVT_DATA) {
    AwsFrameInfo *info = (AwsFrameInfo *)arg;
    if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
      String msg;
      msg.reserve(len);
      for (size_t i = 0; i < len; i++) msg += (char)data[i];
      if (msg == "TOGGLE") {
        ledState = !ledState;
        digitalWrite(LED_PIN, ledState ? LED_ON : LED_OFF);
        ws.textAll(ledState ? "ON" : "OFF");
      }
    }
  }
}
void timeoutNet() {  // connection with timeout
  int count = 0;
  //digitalWrite(LED_BUILTIN, HIGH);
  while ((WiFi.status() != WL_CONNECTED) && count < 17) {
    Serial.print(".");
    count++;
    delay(500);
  }
  //digitalWrite(LED_BUILTIN, LOW);
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("");
    Serial.print("Failed to connect to ");
    while (1)
      ;
  }
  Serial.println(ssid);
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
}
// 2 регистра сдвига
byte shiftIn(int DATA, int CLK) {
  int i;
  int temp = 0;
  byte pinState;
  byte inDATE = 240;

  /*
  pinMode(CLK, OUTPUT);
  pinMode(DATA, INPUT);
  for (i = D2; i >= 0; i--) {
    digitalWrite(CLK, 0);
    delayMicroseconds(2);
    temp = digitalRead(DATA);
    if (temp) {
      pinState = 1;
      // несмотря ни на что, задаем биту значение «0»:
      inDATE = inDATE | (1 << i);
    } else {
      pinState = 0;
    }
    digitalWrite(CLK, 1);
  }
  */
  return inDATE;
}

index.h

const char htmlPage[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>ESP WebSocket</title>
    <style>
        body {
            font-family: system-ui, -apple-system, Arial, sans-serif;
            max-width: 640px;
            margin: 48px auto;
            padding: 0 16px;
            background: black;
        }

        h1 {
            color: aqua;
            font-family: sans-serif;
            font-weight: normal;
            margin: 3px;
        }

        th {
            color: orangered;
            font-family: sans-serif;
            font-size: 15px;
            padding-left: 8px;
            padding-right: 8px;
            border: 1px solid white;
            border-radius: 10px;
        }

        td {
            color: black;
            font-family: cursive;
            text-align: center;
            font-size: 20px;
            padding: 1px 3px;
            border: 1px solid #3e3e3e;
            border-radius: 5px;
        }

        .form {
            border: 3px solid grey;
            margin-bottom: 20px;
            box-shadow: 5px 8px 20px 0px grey;
        }

        .card {
            background: #fff;
            padding: 24px;
            border-radius: 12px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, .06);
        }

        .status {
            font-size: 18px;
            padding: 12px;
            border-radius: 8px;
            margin: 12px 0;
            text-align: center;
        }

        .on {
            background: #2e7d32;
            color: #fff;
        }

        .off {
            background: #c62828;
            color: #fff;
        }

        button {
            width: 100%;
            padding: 14px 16px;
            font-size: 16px;
            border: 0;
            border-radius: 10px;
            cursor: pointer;
            background: #1976d2;
            color: #fff;
        }

        .mono {
            font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
        }
    </style>
</head>
<body>
    <div class="card">
        <h1>ESP WebSocket</h1>
        <div id="status" class="status off">Соединение...</div>
        <button id="btn">Переключить светодиод</button>

        <div class="form">
            <h1>СЕНСОРЫ</h1>
            <table>
                <!-- таблица отображаемых данных -->
                <tr>
                    <td>TEMP</td>
                    <td>HUMIDITY</td>
                    <td>SENSOR</td>
                    <td>SOCKET</td>
                </tr>
                <tr>
                    <td><span id="temp" class="mono"></span><span> &degC</span></td>
                    <td><span id="humidity" class="mono"></span><span> %</span></td>
                    <td><span id="sensor" class="mono"></span><span> %</span></td>
                    <td><span id="conn" class="mono"></span></td>
                </tr>
                <!-- register -->
                <tr>
                    <td><span id='pin_0'></span></td>
                    <td><span id='pin_1'></span></td>
                    <td><span id='pin_2'></span></td>
                    <td><span id='pin_3'></span></td>
                </tr>
                <tr>
                    <td><span id='pin_4'></span></td>
                    <td><span id='pin_5'></span></td>
                    <td><span id='pin_6'></span></td>
                    <td><span id='pin_7'></span></td>
                </tr>
                <tr>
                    <td><span id='pin_8'></span></td>
                    <td><span id='pin_9'></span></td>
                    <td><span id='pin_12'></span></td>
                    <td><span id='pin_13'></span></td>
                </tr>
            </table>
        </div>
    </div>

    <script>
        let ws = null;
        let timer = null;
        const $s = document.getElementById('status');
        const $c = document.getElementById('conn');
        const $d = document.getElementById('sensor');
        const $b = document.getElementById('btn');
        const $t = document.getElementById('temp');
        const $h = document.getElementById('humidity');

        function setConn(x) {
            $c.textContent = x ? 'подключено' : 'отключено';
            $c.style.color = x ? 'green' : 'red';
        }

        function reconnect() {
            if (timer) return;
            timer = setTimeout(() => {
                timer = null;
                connect();
            }, 2000);
        }

        function connect() {
            try {
                ws = new WebSocket('ws://' + window.location.host + '/ws');
            } catch (e) {
                reconnect();
                return;
            }
            ws.onopen = () => setConn(true);
            ws.onmessage = e => {
                const m = e.data || '';
                console.log(`lDataJSON - ${m}`);
                if (m === 'ON') {
                    $s.className = 'status on';
                    $s.textContent = 'Светодиод включён';
                } else if (m === 'OFF') {
                    $s.className = 'status off';
                    $s.textContent = 'Светодиод выключён';
                } else if (m.startsWith('SENSOR:')) {
                    $d.textContent = m.split(':')[1];
                } else if (m.startsWith('TEMP:')) {
                    $t.textContent = m.split(':')[1];
                } else if (m.startsWith('HUMID:')) {
                    $h.textContent = m.split(':')[1];
                }
            };
            ws.onclose = (e) => {
                setConn(false);
                $s.className = 'status off';
                $s.textContent = 'Соединение потеряно';
                console.log('Socket is closed. Reconnect will be attempted in 2 seconds.', e.reason);
                reconnect();
            };
            ws.onerror = (err) => {
                console.error('Socket encountered error: ', err.message, 'Closing socket');
                ws.close();
            };
        }

        $b.addEventListener('click', () => {
            if (ws && ws.readyState === WebSocket.OPEN) ws.send('TOGGLE');
            else alert('Нет соединения');
        });

        connect();
    </script>
</body>
</html>
)rawliteral";

Если запутаешься пиши, попробуем настроить.

думаю отправить так { “pin”: [ 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1 ] }

void loop() {
  ws.cleanupClients();

  static unsigned long last = 0;
  if (millis() - last > 2000) {
    last = millis();

    JsonDocument doc;
    // Create the "digital" array
    JsonArray pin = doc["pin"].to<JsonArray>();
    for (int i = 0; i = 15; i++) {
      // cheek register СВ4021, contact with rezistors 1,5kOm
      uint8_t valueOfPin = sr.get(i);  //read value of pin [i] on register 
      char b = valueOfPin;
      pin.add(b);
    }
    serializeJson(doc, pin);
  }
}

просто отправить массив не получается

ошибки не пойму

Compilation error: grpc: error while marshaling: string field contains invalid UTF-8

Вот тут решение есть, видимо кириллица где-то в пути в библиотекам

Такой цикл работать не будет

3 лайка

собрал на 1 регистре

void loop() {
  ws.cleanupClients();
  static unsigned long last = 0;
  if (millis() - last > 1000) {
    last = millis();
    JsonDocument doc;
    // Create the "digital" array
    // cheek register СВ4021, contact with rezistors 1,5kOm
    digitalWrite(LATCHPIN, 1);
    delayMicroseconds(20);
    digitalWrite(LATCHPIN, 0);
    //--- 1 register СВ4021
    JsonArray pin = doc["pin"].to<JsonArray>();
    switchVar1 = SHIFT(DATAPIN, CLOCKPIN);
    Serial.println(switchVar1);
    for (int n = 0; n <= 7; n++) {
      if (switchVar1 & (1 << n)) {  // array[0-7]
        pin.add(1);
        Serial.print("1");
        Serial.print("|");  //nclose
      } else {
        pin.add(0);
        Serial.print("0");
        Serial.print("|");  //nopen
      }
    }
    String output;
    doc.shrinkToFit();  // optional
    serializeJson(doc, Serial);
  }
}
20:03:57.124 -> 0|0|0|0|0|0|0|0|{"pin":[0,0,0,0,0,0,0,0]}0

изменения есть при замыкании 1-8 входов

теперь данные надо вывести в браузере. ??? т.е. как то сдесь все описать

const $p = document.getElementById('pin')        

ws.onmessage = e => {
const m = e.data || '';
if (m.startsWith('pin')) {
 var arrayS == e.data.split(,);
 for (var i = 0; i < 8; i++) {
 if (m === '1') {
  $p.textContent = m.split('|')[1];
    } else if (m === '0') {
      $p.textContent = m.split('|')[1];
    }