首页 > 解决方案 > 尝试将 arduino 连接到使用 sgcWebSockets 制作的 WebSocket 服务器时出现异常

问题描述

我有下一个问题,我一直在尝试将 arduino 连接到 Web 套接字服务器,我使用的库是:

https://github.com/Links2004/arduinoWebSockets

arduino 通过 modbus 获取数据并将纯文本发送到 WebSocket 服务器,这并不复杂,问题是当我尝试连接到 WebSocket 服务器时,出现异常:

错误协议:不支持 arduino。

这是arduino代码:

....
Modbus master(0,1,0);
modbus_t telegram;
unsigned long u32wait;
// arreglo de datos para la comunicacion modbus
int16_t au16data[16];
uint8_t u8state;
....
void setup() {
  pinMode(pD1, INPUT);
  pinMode(pD2, INPUT); 
  pinMode(pD3, INPUT);

  pinMode(LED, OUTPUT);

  digitalWrite(LED, LOW);

  Serial.begin(57600);

  while(Ethernet.begin(mac) == 0)
  Serial.println("Failed to configure Ethernet using DHCP");

  webSocket.begin("192.168.1.18", 7500);
  webSocket.onEvent(webSocketEvent);

  master.begin( 9600 );
  master.setTimeOut( 2000 );
  u32wait = millis() + 1000;
  u8state = 0;
}

void loop() {
  // put your main code here, to run repeatedly:
  reModbus();
  webSocket.loop();
}
.....
void reModbus() {
  switch( u8state ) {
  case 0: 
    if (millis() > u32wait){
      u8state++; // wait state
      Serial.println("[Modbus] modbus request process has been started.");
    }
    break;
  case 1: 
    telegram.u8id = 21; // slave address
    telegram.u8fct = 3; // function code (this one is registers read)
    telegram.u16RegAdd = 7000; //3042 3146 start address in slave
    telegram.u16CoilsNo = 14; // number of elements (coils or registers) to read
    telegram.au16reg = au16data; // pointer to a memory array in the Arduino

    master.query( telegram ); // send query (only once)
    u8state++;
    Serial.println("[Modbus] modbus query has been send.");
    break;
  case 2:
     master.poll(); // check incoming messages
     if (master.getState() == COM_IDLE) {
        Serial.println("[Modbus] modbus data has been receive.");
        u8state = 0;

        for (int i=0; i <= 6; i++){
          valorsx[i] = convertir(au16data,i*2);
          sensorModbus[i] = String(valorsx[i],6);
        }

        tomadatos1();

        TramaE = 'A'+ sValor1 
               + 'B' + sValor2 
               + 'C' + sD1 
               + 'D' + sD2 
               + 'E' + sD3 
               + 'F' + sensorModbus[0] 
               + 'G' + sensorModbus[1] 
               + 'H' + sensorModbus[2] 
               + 'I' + sensorModbus[3] 
               + 'J' + sensorModbus[4]
               + 'K' + sensorModbus[5]
               + 'L' + sensorModbus[6] 
               + 'M';  

        webSocket.sendTXT(TramaE);
        u32wait = millis() + 100;
     }    
    break;
  }
}
.....

查看我使用的 sgcWebSocket 库的源代码,在这个地方抛出异常。

....
{ RequestURL protocol }
  private
  function DoGetProtocol: string;
{ RequestURL protocol }
....
function TsgcWSConnectionServer.DoGetProtocol: string;
var
  i: Integer;
  oSProtocols, oCProtocols: TsgcDelimitedStringList;
begin
  if FHandshake.Protocols <> '' then
  begin
    oSProtocols := TsgcDelimitedStringList.Create;
    oCProtocols := TsgcDelimitedStringList.Create;
    Try
      oSProtocols.DelimitedText := Protocol;

      oCProtocols.DelimitedText := FHandshake.Protocols;

      for i := 0 to oCProtocols.Count - 1 do
      begin
        if oSProtocols.IndexOf(oCProtocols[i]) > -1 then
        begin
          Result := oCProtocols[i];
          break;
        end;
      end;

      if Result = '' then
        raise TsgcWSException.CreateFmt(S_PROTOCOL_UNSUPPORTED,
          [oCProtocols.Text]);

    Finally
      sgcFree(oCProtocols);
      sgcFree(oSProtocols);
    End;
  end;
end;

该函数在握手时调用,我尝试使用文档中的示例代码制作子协议:

unit ProtocoloArduino;

interface
{$I sgcVer.inc}

{$IFDEF SGC_PROTOCOLS}
uses
  sgcWebSocket_Protocol_Base_Server, Classes, sgcWebSocket_Classes;

type
  TsgcWSProtocol_Arduino = class(TsgcWSProtocol_Server_Base)

  { from TsgcWSComponent }
  protected
   procedure DoEventConnect(aConnection: TsgcWSConnection); override;
   procedure DoEventMessage(aConnection: TsgcWSConnection; const Text: string); override;
   procedure DoEventDisconnect(aConnection: TsgcWSConnection; Code: Integer); override;

  { from TsgcWSComponent }
  public
   constructor Create(aOwner: TComponent); override;
  end;
{$ENDIF}

implementation
{$IFDEF SGC_PROTOCOLS}

constructor TsgcWSProtocol_Arduino.Create(aOwner:TComponent);
begin
  inherited;
  // ... here add your protocol name
  FProtocol := 'arduino';
end;

procedure TsgcWSProtocol_Arduino.DoEventConnect(aConnection:TsgcWSConnection);
begin
  inherited;
  // ... add your own code when a client connects to server
end;

procedure TsgcWSProtocol_Arduino.DoEventDisconnect(aConnection: TsgcWSConnection; Code: Integer);
begin
  // ... add your own code when a client disconnects from server
  inherited;
end;

procedure TsgcWSProtocol_Arduino.DoEventMessage(aConnection: TsgcWSConnection; const Text: string);
begin
  inherited;
  // ... process messages received from clients
  // ... you can answer to client using
  WriteData(aConnection.Guid, 'your message');
  // ... you can send a message to all clients using
  BroadCast('your message');
end;
{$ENDIF}
end.

但即使我这样做

...
var
  PArduino:TsgcWSProtocol_Arduino;
begin
  PArduino.Create(self.owner);
  ServidorWebSocket.RegisterProtocol(PArduino);
end
...

异常不断出现...

如果有人可以帮助我,我将不胜感激。

标签: c++websocketarduinolazarusfreepascal

解决方案


推荐阅读