Конфликт библиотек?

JonHappy1
Offline
Зарегистрирован: 11.06.2018

есть скетч для arduino nsno + w500 - работает с серверос websocket без проблем.

есть скетч для arduino nano + VL53L0X(лазерный дальномер) работает норммально - измеряет, отобразает через Serial

второй скетч использует Wire.h для связи ардуино с дальномером.

если в первый скетч просто добавляю #include <Wire.h> то он начинает работать странно, не может определить что связь идет по протоколу websocket.

что может влиять? и как выяснить что влияет?

JonHappy1
Offline
Зарегистрирован: 11.06.2018

есть подозрение, что i2c конфликтует из-за прерываний , но прерывания от VL53L0X не используются.

просмотр протокола обмена w500 с сервером с помощью wireShark показывает , что Wire.h отправка с сервера идет нужная, вот только ардуинка не может принять правильно.

и именно в самом начале когда происходит коннект к серверу.

как-то можно отложить работу по  подключению и настройке i2c? чтоб сначало w5500 отработал

sadman41
Offline
Зарегистрирован: 19.10.2016

Ничего не понял, но Wire.h осуждаю за то, что он запрещает принимать. Легалайз надо обсуждать.

Вот вам таблетка - https://github.com/Testato/SoftwareWire

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Ничего не понял   -   могу попытаться ещё подробнее, не вопрос. укажи что нужно для понимания проблемы.

что означает "запрещает принимать" ?

что делает сия таблетка?

чем она отличается от стандартной?

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Мне ничего не нужно. У меня нет проблемы работы Ethernet и I2C, потому что они не пересекаются в принципе.

Но если нужно что-то вам, то выражайтесь более ясно, приводите максимально сокращенный код, который не работает, схему подключения и пр. Тащить это из вас никто не собирается, угадывать что такое w500 - тоже.

Библиотека SoftwareWire всем отличается от стандартной. Если со стандартной у вас процесс обмена останавливается и вы не умеете/не хотите локализовать проблему - замените библиотеку. Возможно, что повезет и все зафурычит.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

я нехотел никого обижать, мне нужно разобраться почему не работает, поэтому готов ответить на любые вопросы, которые помогут выяснить причину.

w500 - это описка , правильное название модуля  w5500  http://iarduino.ru/shop/Expansion-payments/setevoy-modul-w5500-tsr-ip-et...

для него нужна библиотека https://github.com/adafruit/Ethernet2

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

void loop() {
  detachInterrupt(1);
  wsclient.monitor();
  attachInterrupt(1, EventListener, FALLING    );
}

где


static void  EventListener() {

    uint8_t d[] = "xxx03|sssssssssssss";
    uint8_t* g;
    g = (uint8_t*)(&d);

    wsclient.send(g, sizeof(d));
  
}

VL53L0X(лазерный дальномер)   - http://roboparts.ru/products/gy-530-lazerniy-dalnomer ,

библиотека взята тут https://www.arduinolibraries.info/libraries/vl53-l0-x

подключён без использования вывода G (GPIO1)

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

А что происходит, если "прерывания не отключать"? Сколько я читал эти Ethernet.h - в них перывания, которые могли бы использоваться, не обрабатываются вовсе. Поэтому ваше описание пока больше загадок порождает, чем разгадок. Что в вашей конструкции привязано к INT1 ?

JonHappy1
Offline
Зарегистрирован: 11.06.2018

происходит потеря данных , т.е. если во время приёма данных срабатыаеи прерывание - оно блокирует прохождение прерываний от w5500. хотя ч видел рекомендации о подключении данного модуля без вывода прерывания, но у меня это не сработало.

видимо w5500 более крутая , чем w5100 :) для неё есть "специальная" библиотека Ethernet2.h

пока у меня привязана к INT1 кнопка через RS-триггер на 555ТМ2 (т.е. дребезга нет). в дальнейшем планируется использование нескольких кнопок, с чтением нажатой через реиистры выводов d6-d9.

меня больше всего смущает, что для "сбойной работы" достаточно только подключить #include <Wire.h>

по подключению - я в инете видел как с подтягивающими резисторами , так и без них - это может влиять?

влияние проявляется как потеря нескольких первых байт сообщения из w5500.

http://radioprog.ru/post/233
TWI модуль вызывает прерывание, когда заканчивает работу, чтобы уведомить процессор об изменениях состояния (включая успешность операций и/или ошибки).

в этом плане наверное https://github.com/Testato/SoftwareWire имет преимущество. только тогда меня интересует вопрос - может ли VL53L0X работать в режиме запрос-ответ? (я этим всем работаю первый раз).
или как-то отключать прерывания от I2C. что мне кжется былобы предпочтительнее

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Ей-богу какая-то каша у вас с этими прерываниями. Во-первых - деаттачем вы не отключаете прерывания, а просто игнорируете кнопку. Никаких обработчиков прерываний, насколько мне известно, библиотеки EthernetX не содержат. INT сетевого модуля, как я подозреваю, тоже висит в воздухе.

Если TWI мешается под ногами Ethernet-у, то и простой пример типа WebServer/Webclient тоже должен сразу переставать функционировать нормально, если добавить к нему Wire. Так происходит?

JonHappy1
Offline
Зарегистрирован: 11.06.2018

согласно http://arduino.ru/Reference/DetachInterrupt

detachInterrupt(interrupt)   - Выключает обработку внешнего прерывания (грубо - отключает прерывания)

INT сетевого модуля в воздухе не висит, первоначально не было подключено - не работало.

такой код работает

void loop() {
  detachInterrupt(1);
  wsclient.monitor();
  attachInterrupt(1, EventListener, FALLING    );
  Serial.println(sensor.readRangeSingleMillimeters());
  if (sensor.timeoutOccurred()) {
    Serial.print(" TIMEOUT");
  }
}

т.е. отрабатывает и связь c сервером и как по инициативе сервера, та и по иниуиативе клиента по нажатю на кнопку.
единственно что при старте я не получаю правильное рукопожатие - т.е. клиент (ардуино) отправляет
https://learn.javascript.ru/websockets#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%81%D0%BE%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Origin: http://javascript.ru
Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==
Sec-WebSocket-Version: 13

сервер отвечает, но клиент не принимает ответ, по факту получается , что сервер с клентом "договорились" о протоколе websocket, хотя я в коде не могу этого проконтрольровать, код, отвечающий за данное сообщение сервера, его не получает (при подключенной библиотекt Wire) , но в дальнейшем всё  работает по протоколу ws .... вроде правильно. вот это "вроде" не устраивает, если первоначально не принимает ответ, где гарантия, что и остальные данные не искажены/не пропущены
к сожалению отправка данных с дальномера ещё не сделана, поэтому не могу гарантировать что не пропадают какие-то данные.
есть подозрение, что глюк происходит на момент инициализации обеих модулей.
существует ли возможность отложить включение инициализации модуля I2C ? т.е. уже после всех действий по подключению w5500 и получения ответа с сервера.

sadman41
Offline
Зарегистрирован: 19.10.2016

detachInterrupt действительно отключает обработчик внешнего прерывания, а точнее - перестает вызывать из штатного обработчика вашу функцию. Другие прерывания при этом не прекращают приниматься и обрабатываться. Если вы наблюдаете проблему, когда у вас подключен собственный обработчик, выносите из него все в loop() и исполняйте весь блок инструкций там, ориентируясь на флаг, поднимаемый в обработчике. Вполне вероятно, что вы там висите слишком долго и это сказывается на остальном процессе. Потому что как раз в этом-то случае остальные прерывания обрабатываться перестают.

Задержать Wire, наверное можно через поздний вызов begin(), но я думаю, что дело не в этой библиотеке.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

сделал "полный цикл" -
 

void loop() {
  detachInterrupt(1);
  wsclient.monitor();

  uint16_t  dist = sensor.readRangeSingleMillimeters();

  if (sensor.timeoutOccurred()) {
    Serial.print(" TIMEOUT");
  }
  uint8_t d[] = "xxx03|         ";
  int i = 10;
  while (dist > 0) {
    d[i--] = uint8_t ((0x30 + dist % 10));
    dist /= 10;
  }
  uint8_t* g;
  g = (uint8_t*)(&d);
  wsclient.send(g, sizeof(d));
  attachInterrupt(1, EventListener, FALLING    );

}

работает как надо.
однако при старте глюк остался.
(если можно данный код сократить/улучшить/ускорить - подскажите что можн сним сделать)

sadman41
Offline
Зарегистрирован: 19.10.2016

1) Перестать деаттачить обработчик
2) Поднимать в обработчике флаг, после send-а опускать. Читать сенсор/слать данные, когда флаг поднят.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

чем плохо деаттачить обработчик?
нажатия кнопки имеют низкий приоритет, поэтому пусть всё спокойно завершится и только потом обработает кнопку,
поднять флаг, опустить  флаг - это который флаг?
не есть ли работа с этим флоагом и detachInterrupt(1)/attachInterrupt ?

sadman41
Offline
Зарегистрирован: 19.10.2016

Вы же хотите оптимизировать? Ну так вот - смысла в аттачах/детачах нет. Только процессор зря напрягается. В обработчике ставьте переменную sendNow = true, а в лупе делайте то, что было в обработчике ранее только если sendNow == true. Меньше дергаете датчики/модули - больше тактов сохраняете для других дел. Не забывайте про ключевое слово volatile для переменных, меняющихся в обработчике.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

sadman41 пишет:
Только процессор зря напрягается.
в чем заключается напряжение процессора? вроде как это минимум команд? прерывания и созданы для облегчения жизни процессоров.

ведь после инициализации всего всё работает как надо и прерывания обрабатываются нормально. весь баг только в начальной стадии.

sadman41
Offline
Зарегистрирован: 19.10.2016

В таком случае - какое улучшение/сокращение/ускорение приведенного фрагмента кода вы планировали получить, если у вас всё ок?

JonHappy1
Offline
Зарегистрирован: 11.06.2018

там есть такой кусок

11   int i = 10;
12   while (dist > 0) {
13     d[i--] = uint8_t ((0x30 + dist % 10));
14     dist /= 10;
15   }
16   uint8_t* g;
17   g = (uint8_t*)(&d);
18   wsclient.send(g, sizeof(d));
10   uint8_t d[] = "xxx03|         ";

вот про него речь.

а по прерываниям - http://robotosha.ru/arduino/arduino-interrupts.html
есть чему удивиться.

и , всё-таки, есть какие-нибудь идеи как разрулить процесс инициализации?

идея с таблеткой, конечно , вариант, но хочется более детально разобраться с причиной, чтоб знать что обходить...

sadman41
Offline
Зарегистрирован: 19.10.2016

Наверное еще где-то есть неправильно написанный код, как и в случае выше. Искать его и не повторять - это и есть работа программиста.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

вот только кода совсем мало
основной код
 

#include <Ethernet2.h>
#include <EthernetClient.h>
#include <Wire.h>
#include "WebSocketClient.h"

#include <VL53L0X.h>
VL53L0X sensor;

// Ethernet Configuration
EthernetClient eclient;
byte mac[] = {  0x90, 0xA2, 0xDA, 0x00, 0xF2, 0x78};
IPAddress ip(192, 168, 3, 20);
IPAddress gateway(192, 168, 3, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress myDns(8, 8, 8, 8); // google puble dns


WebSocketClient wsclient;


void setup() {
  Serial.begin(230400);

  Wire.begin();

  sensor.init();
  sensor.setTimeout(300);


  Serial.println(F("Demo example on WSClient usage")); delay(500);
  Ethernet.begin(mac, ip, myDns, gateway, subnet); // initialize ethernet
  Serial.println(Ethernet.localIP()); // printout IP address for debug purposes

  wsclient.connect("192.168.3.4", "/lino_test/WS_server", 8080); //по правилам здесь необходима 
// проверка возвращаемого значения и если true продолжать, иначе аларм и прекращение работы.

  wsclient.setDataArrivedDelegate(dataArrived);

}
void loop() {
  detachInterrupt(1);
  wsclient.monitor();

  uint16_t  dist = sensor.readRangeSingleMillimeters();

  if (sensor.timeoutOccurred()) {
    Serial.print(" TIMEOUT");
  }
  uint8_t d[] = "xxx03|         ";
  int i = 10;
  while (dist > 0) {
    d[i--] = uint8_t ((0x30 + dist % 10));
    dist /= 10;
  }
  uint8_t* g;
  g = (uint8_t*)(&d);
  wsclient.send(g, sizeof(d));
  attachInterrupt(1, EventListener, FALLING    );

}


void dataArrived(WebSocketClient wsclient, String data1) {
  Serial.println("Data Arrived: " + data1);
}



static void  EventListener() {

  uint8_t d[] = "xxx03|987654321";
  uint8_t* g;
  g = (uint8_t*)(&d);

  wsclient.send(g, sizeof(d));

}

WebSocketClient.cpp
 

#include "WebSocketClient.h"
#include <WString.h>
#include <string.h>
#include <stdlib.h>


const String clientHandshake = "GET ® HTTP/1.1\r\n"
                               "Upgrade: webSocket\r\n"
                               "Connection: Upgrade\r\n"
                               "Host:±\r\n"
                               "Origin: moto_1\r\n"
                               "Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==\r\n"
                               "Sec-WebSocket-Version: 13\r\n";




//*********************************************************************************
bool WebSocketClient::connect(char hostname[], char path[], int port) {
  bool result = false;
  int response;
  if (_client.connect(hostname, port)) {

    sendHandshake(hostname, path);
    response = readHandshake();
    if (response == 101) {
      result = true;
    }

    if (response == 200) {
      sendHandshake(hostname, path);
      response = readHandshake();
    }
  }
  Serial.print("ответ  ");  //здесь должно напечатать 101 при нормальной инициализации
  Serial.println(response);
  return result;
}
//*********************************************************************************

bool WebSocketClient::connected() {
  return _client.connected();
}
//*********************************************************************************
void WebSocketClient::disconnect() {
  _client.stop();
}
//*********************************************************************************
void WebSocketClient::monitor () {
  uint8_t character;
  String data = "";
  bool endReached = false;

  if (_client.available() > 0 && (character = _client.read()) != 0xFF) {

    data += (char)character;

    while (!endReached) {
      character = _client.read();
      endReached = character == 0xFF;

      if (!endReached) {
        data += (char)character;
      }

    }

    if (_dataArrivedDelegate != NULL) {
      _dataArrivedDelegate(*this, data);
    }

  }

}
//*********************************************************************************
void WebSocketClient::setDataArrivedDelegate(DataArrivedDelegate dataArrivedDelegate) {
  _dataArrivedDelegate = dataArrivedDelegate;
}
//*********************************************************************************

void WebSocketClient::sendHandshake(char hostname[], char path[]) {


  String query = clientHandshake;

  query.replace("®", path);
  query.replace("±", hostname);

  _client.println(query);
  _client.println();
}
//*********************************************************************************
int WebSocketClient::readHandshake() {

  int result = 0;

  char character;
  String handshake = "", line;
  int maxAttempts = 300, attempts = 0;

  while (_client.available() == 0 && attempts < maxAttempts)
  {
    attempts++;
    delay(50);
  }

  while ((line = readLine()) != "") {
    handshake += line + '\n';
  }
  Serial.println(handshake);  // здесь выводит ответ сервера при отсутствии Wire.h 
// и ничего не выводит при подключении Wire.h
  result = handshake.indexOf("HTTP/1.1 101")  != -1;

  if (result) {
    return 101;  // здесь происходит выход при нормальном завершении
  }
  result = handshake.indexOf("HTTP/1.1 200")  != -1;
  if (result) {
    //    _client.stop();
    return 200;
  }

  return 0;  // выход здесь при при подключении Wire.h
}
//*********************************************************************************
String WebSocketClient::readLine() {
  String line = "";
  char character;

  while (_client.available() > 0 && ((character = _client.read()) != '\n' || character != '\r' || character != -1)) {
    line += character;
  }

  return line;
}
//*********************************************************************************
void WebSocketClient::send ( uint8_t* data, int len) {

  byte n = (byte)(--len);
  byte z[n];

  byte x[6] = { 0x81, (byte)(n | 0x80), 0xff, 0xff, 0xff, 0xff};
  int i = 0;
  do {
    z[i] = (byte)(( *(data + i)) ^ 0xff);
  } while (++i < n );
  _client.write(x, 6);
  _client.write(z, n);
}

WebSocketClient.h

#ifndef WEBSOCKETCLIENT_H
#define WEBSOCKETCLIENT_H_

#include <string.h>
#include <stdlib.h>
#include <WString.h>
#include <Ethernet2.h>
#include "Arduino.h"

//Uncomment this to use WIFLY Client
//#define WIFLY true

class WebSocketClient {

  public:
    typedef void (*DataArrivedDelegate)(WebSocketClient client, String data);
    bool connect(char hostname[], char path[] , int port );
    bool connected();
    void disconnect();
    void send(uint8_t* data, int len);
    void monitor();


    void setDataArrivedDelegate(DataArrivedDelegate dataArrivedDelegate);
  private:
    String getStringTableItem(int index);
    void sendHandshake(char hostname[], char path[]);
    DataArrivedDelegate _dataArrivedDelegate;
    EthernetClient _client;

    int readHandshake();
    String readLine();
};


#endif

 

JonHappy1
Offline
Зарегистрирован: 11.06.2018

нашёл место глюка, в чем причина не могу понять
 

String WebSocketClient::readLine() {
  String line = "";
  char character;
  character = _client.read();
  Serial.print(character);
  while (_client.available() > 0 && (character  != '\n' || character != '\r' || character != -1)) {
    character = _client.read();
    line += character;
    Serial.print(line);  // здесь выводит переменную line, в каждом выводе на 1 символ длиннее,
// выводит правильную строку
  }

  Serial.println("----------");
  Serial.println(line);  // здесь выводит только один символ ? 
  Serial.println("----------");
  return line;
}

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

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

это, канешна, не поможет, но переставь 7 строку перед 11-й

и character никада -1 не будет, иба он беззнаковый. 

sadman41
Offline
Зарегистрирован: 19.10.2016

byte не будет, а char - вполне себе. Только вот стримовский read(), например, возвращает int, который или -1 или 0..255. Так же, как я помню, проверка available() == 0 равносильна read() == -1, так что тут имеется избыточное условие.

String WebSocketClient::readLine() {
  String line = "";
  char character;

  while (_client.available() > 0) {
    character = _client.read();
    Serial.print(character);

    if (character == '\n' || character == '\r') { break; }
    line += character;
    Serial.print(line);
  }

  Serial.println("----------");
  Serial.println(line);  // здесь выводит только один символ ? 
  Serial.println("----------");
  return line;
}

А вообще, как я подозреваю, тут есть какая-то проблема с памятью, ибо единственное, что поганого делает Wire - это резервирует под буфера ОЗУ. Плюс тут есть String, который растет, как хочет. Ставлю на то, что если сбросить стринги и работать с char[] - то всё нормализуется.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

sadman41 пишет:

 Плюс тут есть String, который растет, как хочет. Ставлю на то, что если сбросить стринги и работать с char[] - то всё нормализуется.

скорее всего соглашусь, вот только как ? длина строки заранее не известна.

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, а вы думаете, что String никак не ограничен пределом ОЗУ? Надо или парсить на лету или брать SoftwareWire и сэкономить на буферах или использовать общий выделенный глобальный char[] для всех функций, передавая указатель туда-сюда. Чудес-то не бывает.

На крайний случай - проверять что там String выделил... Как-то ЕвгенийП описывал способы в посте про мазохизм.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

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

рабочий вариант такой
 

int WebSocketClient::readHandshake() {
  
  char character;
  String handshake = "";
  int attempts = 0;
  while (_client.available() == 0 && attempts < 500)
  {
    attempts++;
  }

  while (_client.available() > 0 && ((character = _client.read() ) != character != -1)) {
    handshake += character;
  }

if (handshake.indexOf("HTTP/1.1 101")  != -1) {
    return 101;
  }

  return 0;
}

WebSocketClient::readLine выкинул.

sadman41
Offline
Зарегистрирован: 19.10.2016

И что, работает без readLine() ?

в readHandshake() уж точно можно обойтись без String - размер строки для сравнения точно известен.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

sadman41 пишет:

И что, работает без readLine() ?

в readHandshake() уж точно можно обойтись без String - размер строки для сравнения точно известен.

да , всё прекрасно работает. readLine() был в первоисточнике данного кода, для каких целей - не известно. что в нем было не понятно - при выходе из цикла while  строка терялась.

ардуинка считывает с дальномера, фильрует, отправляет на сервер, сервер с помощю "серверного рендеринга" строит svg полилайн  и отправляет браузеру, браузер вставляет в элемент svg - и на экране бегущая линия - изменение расстояния во времени от положения датчика.

без string обойтись можно, известно что сравнивать и даже где это должно быть , но пока это не критично :) на быстродействие это не скажется , а вот на память. ведь после выхода их функции память занятая под стринг освобождается? или надо как-то её освободить/вернуть основному процессу?

 

sadman41
Offline
Зарегистрирован: 19.10.2016

В данном случае, думаю, что все будет ок, но если привыкнуть и начать к стрингу добавлять символы в разных местах программы, то дыр он понаделает в ОЗУ. Думаю, что с байтмассивом быстрее будет, чем с классом. Не по человеческим меркам, по процессорным.

А перед Wire придется извиниться - не виноват он оказался...

JonHappy1
Offline
Зарегистрирован: 11.06.2018

А перед Wire придется извиниться - не виноват он оказался...
но ведь он как-то влияет, ведь без него было нормально , жаль , что это влияние не удалось вычислить
 

sadman41
Offline
Зарегистрирован: 19.10.2016

А я вот 90% вероятности даю, что String выжирал всю память на входящем реквесте.

Wire только ускорил диагностику. А так бы вешалось всё раз в месяц и вообще бы ничего не понимали б. Я так с ENC28J60 развлекался - эта гадина раз в две недели вешалась у меня. Пока методом тыка нашёл причину - пара месяцев прошла. Так что спасибо скажите такой жирной библиотеке.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DetSimen пишет:

и character никада -1 не будет, иба он беззнаковый. 

Отнюдь.

Он имеет право быть как знаковым, так и беззнаковым.

Более того, у разных моделей Ардуин этот вопрос решается по-разному.

Поэтому, действительно, сравнивать с -1 - плохая идея.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

ну вообщето сравнивается с 0xFF, что и является -1
я не думаю что там вставляется команда на обнуление старшего бита.
и в функции  WebSocketClient::monitor () так и сравнивается . и там  uint8_t character;
что повлекло за собой  data += (char)character;
причем в обоих случаях character = _client.read()  вне зависимости от типа character

Более того, у разных моделей Ардуин этот вопрос решается по-разному.
причем сдесь модели? если это программная среда
 

JonHappy1
Offline
Зарегистрирован: 11.06.2018

А я вот 90% вероятности даю, что String выжирал всю память на входящем реквесте.

я тоже к этому склоняюсь, вот только как объснить, что в цикле while - нормально, а после - фигфам?

sadman41
Offline
Зарегистрирован: 19.10.2016

Какой замысловатый алгоритм. Хорошо, что я не читал этот WebSocketClient на ночь.

sadman41
Offline
Зарегистрирован: 19.10.2016

JonHappy1 пишет:

я тоже к этому склоняюсь, вот только как объснить, что в цикле while - нормально, а после - фигфам?

Этого я не наблюдал, а вот то, что код в той функции спохмела писан - похоже.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Какой замысловатый алгоритм. Хорошо, что я не читал этот WebSocketClient на ночь.
замысловатость - это проходящее, зато какой кайф от его использоавния, я от ws тащусь в самого момента их появления.
у меня отображение в браузере в темпе считывания с датчика и сервер вообще не нагружен. ни каких запросов ajax.
 

JonHappy1
Offline
Зарегистрирован: 11.06.2018

счас осталость modbus прикрутить и ПИД регулирование....

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

JonHappy1 пишет:

Более того, у разных моделей Ардуин этот вопрос решается по-разному.

причем сдесь модели? если это программная среда
 

-1 - это программная среда?

Объясняю еще раз: значение 0xFF, занесенное в переменную типа char, в зависимости от типа Ардуины трактуется либо как -1, либо как 255.

sadman41
Offline
Зарегистрирован: 19.10.2016

Websockets, как я понимаю, хороши для ситуативной визуализации процессов без ведения архива?

JonHappy1
Offline
Зарегистрирован: 11.06.2018

andriano пишет:

Объясняю еще раз: значение 0xFF, занесенное в переменную типа char, в зависимости от типа Ардуины трактуется либо как -1, либо как 255.

чем трактуется? кодом?

JonHappy1
Offline
Зарегистрирован: 11.06.2018

sadman41 пишет:

Websockets, как я понимаю, хороши для ситуативной визуализации процессов без ведения архива?

не и в архив (в базу можно сливать в том же темпе) эта фишка в полном дуплексе с любым устройством с браузером, андроидом, ардуино подобными .
для сервера они абсолютно одинаковы, все клиенты отличаются только по id сессии, ну и логикой кода присваивается имя , чтоб определять клиента по имени его регистрации на сервере.
вот к примеру с регулилировкой, ардуинка с своём темпе обрабатывает/регулирует и отдаёт данные серверу.
серверуне надо запрвшивать переодически нарушая темп работы ардуинки. сервер получает данные если есть необходимость пишет их в базу, если у клиента открыта страница где выводятся данные в темпе обработки ардуикой(т.е. в реальном времени) - сервер будет отправлять клиенту , продолжая писать в базу.

это как один из многих вариантов использования

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

JonHappy1 пишет:

чем трактуется? кодом?

Компилятором.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

andriano пишет:

JonHappy1 пишет:

чем трактуется? кодом?

Да.

т.е. Си зависит от железа? где об этом почитать?
слава богу , что таого в java нет :)

Logik
Offline
Зарегистрирован: 05.08.2014

JonHappy1 пишет:

не и в архив (в базу можно сливать в том же темпе) эта фишка в полном дуплексе с любым устройством с браузером, андроидом, ардуино подобными .

Целиком разделяю восторг от ws. Алгоритм его не сложный (ну понятно кроме альтернативно одаренных ;). По простоте интеграции в проект как на ПК так и на ардуине и скорости работы просто нет равных. На ESP его лепить просто блеск.  Только вот почему на ардуинке клиент, а не сервер я не совсем понял. Учитывая что в броузере тоже клиент, получается несколько громоздко. Я обычно на ардуинке делаю сервер выдающий данные пришедшим клиентам (ну и исполняющим их команды если надо). Тогда с любого броузера штатным JS  зайти и посмотреть динамичные данные можна, а нужно в БД - так она законектится клиентом и получит свое.

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Logik пишет:

 Только вот почему на ардуинке клиент, а не сервер я не совсем понял. Учитывая что в броузере тоже клиент, получается несколько громоздко. Я обычно на ардуинке делаю сервер выдающий данные пришедшим клиентам (ну и исполняющим их команды если надо). Тогда с любого броузера штатным JS  зайти и посмотреть динамичные данные можна, а нужно в БД - так она законектится клиентом и получит свое.

цели разные, у меня управляет всем сервер на java, и таких клиентов несколько.

Logik
Offline
Зарегистрирован: 05.08.2014

Да, Sec-WebSocket-Key по большому счету надо на клиенте генерить псевдослучайно, это требование по безопасности.

Logik
Offline
Зарегистрирован: 05.08.2014

JonHappy1 пишет:

Logik пишет:

 Только вот почему на ардуинке клиент, а не сервер я не совсем понял. Учитывая что в броузере тоже клиент, получается несколько громоздко. Я обычно на ардуинке делаю сервер выдающий данные пришедшим клиентам (ну и исполняющим их команды если надо). Тогда с любого броузера штатным JS  зайти и посмотреть динамичные данные можна, а нужно в БД - так она законектится клиентом и получит свое.

цели разные, у меня управляет всем сервер на java, и таких клиентов несколько.

А как броузером ходить? Или не используете такое. То, что таких устройств несколько не проблема для броузера, просто с одной страницы на JS пишу конект к сколько надо. Прикольно получается по скорости. Никаким аяксом такого не получиш. При регулировку крутиш на планшете крутилку и устройство отрабатывает с незаметной задержкой. При регулировке чего либо это очень важно. Я на ESP по протоколу WS такое http://arduino.ru/forum/apparatnye-voprosy/polzuet-li-kto-wifi-moduli-esp8266-podelites-vpechatleniyami?page=20#comment-262075 делал :)

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Logik пишет:

Да, Sec-WebSocket-Key по большому счету надо на клиенте генерить псевдослучайно, это требование по безопасности.

это да, но у меня  система замкнутая на внутренности, поэтому такой вариант допустим, я даже wss не планирую

JonHappy1
Offline
Зарегистрирован: 11.06.2018

Logik пишет:

А как броузером ходить? Или не используете такое. То, что таких устройств несколько не проблема для броузера, просто с одной страницы на JS пишу конект к сколько надо.

у меня сервер все разруливает, и с браузером и с ардунками, возможности сервера намного больше. и он отвечает не только за работу ардуинок.

JonHappy1
Offline
Зарегистрирован: 11.06.2018