Links2004 / arduinoWebSockets

arduinoWebSockets
GNU Lesser General Public License v2.1
1.85k stars 549 forks source link

Using the WebSockets library for the GSM SIM800 modem #328

Open Djaison opened 6 years ago

Djaison commented 6 years ago

Hello! I'm using the wonderful library arduinoWebSockets on ESP32. I want to use a GSM modem to connect my client running on ESP32 with a remote server via Websocket. The SIM800 modem has its own TCP / IP stack and involves working with AT commands. But this mode of operation does not fit. However, it can be switched to point to point over serial (PPPoS) mode. I'd like to use the TCP Arduino stack with the WebSockets library. Question: Is it possible to connect a websockets connection to a serial interface as the simplest solution? Or do I need to write the TCP Client and Server class for the SIM800 and then include them in the arduino WebSockets library? (I'm new to C ++ (6 months +))

P.S. It would be nice if @Links2004 pays attention to my question :-) Thank you in advance!

Links2004 commented 6 years ago

Hi,

the code require a Arduino Client or Server class, you can program the class to send all data via serial, not sure how the PPPoS protocol is looking like. but all you need is a abstraction layer with the arduino client class Interface. a simply TCP to Serial via abstraction layer is easy done, but the question is if the PPPoS protocol is requiring additional stuff.

if you have this kind of Abstraktion the rest is easy. simply set the defines to your class, like its done for different TCP stack here: https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.h#L148-L164

Djaison commented 6 years ago

I assumed that I would have to create a Client class (I'm using the websocket client). If I understand correctly, to create such a Class, I need to properly configure lwiP PPPoS and use the standard API library lwIP in my class Arduino Client GSM?

Links2004 commented 6 years ago

you are not forced to use lwiP but it one way to do it. you need to implement the Client class:

https://www.arduino.cc/en/Reference/ClientConstructor https://github.com/esp8266/Arduino/blob/master/cores/esp8266/Client.h

Djaison commented 6 years ago

Thanks for the quick answers! But somehow the functionality of PPPoS is laid in lwIP? If I understand correctly in my Client class, I need to configure PPPoS and through this channel send a raw TCP stream on top of which is the websocket. Or is it enough for me in my class ClientGSM to inherit from the base class arduino Client.h and override in it such methods as: read (); and write (); to output to Serial?

Links2004 commented 6 years ago

you only need to wirte a ClientGSM, the class need to send all commands to your GSM module via serial that are needed to open the TCP socket and read and write to it.

I have no glue on how complexe PPPoS is but it need to be handled in the ClientGSM. if your class is offloading some of the protocol work to lwIP or not is up to you.

if you implement all the functions for the client class it will work fine. this is how all the different Arduino network stacks are working.

if its fully integrated in to lwIP you may only need to register the GSM modem as new interface in to lwIP. then you not need any class, since the WiFiClient class basically is a lWIP client class its not bound to WiFi ;)

imranaalam commented 5 years ago

Any progress on your side?

ghost commented 4 years ago

Any progress ?

ehsan9ir commented 3 years ago

Hi Didn't you find a solution to this problem after all these years to support the web socket on sim800? @Djaison

Djaison commented 3 years ago

Hello. Yes, I was able to use websocket using sim800 modem. I did not use PPPoS mode, but used the internal TCP stack of the GSM modem. As Marcus said, it is enough to implement your Client class, in which you implement all the methods of this class. Initialize the modem and establish a permanent TCP connection to the server. Your payload messages, along with the websocket protocol headers, are simply passed as TCP stack messages

ekadesign commented 3 years ago

@Djaison could you publish implementation ?

Miftakhunnurudin commented 3 years ago

Hey bro could you publish the final result?

Sandi2211 commented 3 years ago

@Djaison I'm also interested. Would be great if you could share the code mate.

WTHfloyd commented 3 years ago

Hi @Djaison - Yes if you could share code on how you did this - huge thanks!

re-vax commented 3 years ago

Hi there! I'm also playing around SIM800 on ESP32. It would be nice to have a working stack to use SIMM800 as a modem. Please share, even if it's not production ready ;)

WTHfloyd commented 3 years ago

I emailed espressif and asked them to update their esp-idf websocket stack to include GSM(4G) modules support (not just wifi). They said maybe...if more people ask them...maybe they will add websocket support....

SunboX commented 3 years ago

@Djaison Are you willing to send me a code snipped? Might save me some time. I need to test a socket connection using a T-Call 1.4 I can send you some money if you like. You can PM me mail@andrefiedler.de

WTHfloyd commented 3 years ago

SunboX - I askes Espressif and they said:

Dear Philip,

Thank you for your feedback and for bringing this to our attention. We are so happy to hear you are pleased with the document. Our aim is to build more user-friendly technical documentation.

Regarding your suggestions [adding websockets support] , first of all, you can find an example on how to connect GSM modem to ESP32 using ESP-IDF here [ https://github.com/espressif/esp-idf/tree/master/examples/protocols/pppos_client ] . Besides, we will definitely take your suggestion into consideration and will add some instructions related to this topic into our ESP-FAQ repository in the near future, please look forward.

WTHfloyd commented 3 years ago

Hi SunboX,

I just got an interesting email from Espressif...

Arduino core for ESP32 is maintained by the community and Espressif does not develop Arduino libraries to support specific third-party hardware.

As for ESP-IDF, you can use web sockets with https://github.com/espressif/esp-idf/tree/master/examples/protocols/pppos_client example suggested in my other e-mail (apologies for the repetition as you seem to prefer using Arduino). This example will connect to the network (the same way as Wi-Fi) and you can run a WS client the same way as the MQTT client (used in the original example). To do so the MQTT code should be replaced with WS client code that can be taken from https://github.com/espressif/esp-idf/tree/master/examples/protocols/websocket.

https://github.com/espressif/esp-idf/tree/master/examples/protocols/pppos_client

from https://github.com/espressif/esp-idf/tree/master/examples/protocols/websocket

Let me know if you get it working!

kunal-gour commented 2 years ago

Hello Guys, Any recent update on this? I found this thread when I was trying to connect my ESP8266 to a web server using the GSM module and the connection is to be made via websockets. Any leads will be very much valuable.

vinothkannan369 commented 2 years ago

i am not able to open the link?? any update https://github.com/espressif/esp-idf/tree/master/examples/protocols/pppos_client

braysonjohn148 commented 1 year ago

Any update. i have a SIM800L, making http request takes very long. i think websockets would works. Can someone please share any script to enable websockets using sim800, esp32

WTHfloyd commented 1 year ago

Maybe that will help...get https connection with AT commands, then upgrade to websockets... And check out https://m1cr0lab-esp32.github.io/remote-control-with-websocket/websocket-setup/

braysonjohn148 commented 1 year ago

Thank you, nice explanations they have there. The issue am facing is I have a separate SIM800L which acts as an internet connection.

I tried this code, but it ends up at the modem.gprsConnect(apn, user, pass) bring error and stack right there.

`#include

include

include

SocketIOclient socketIO;

define SerialMon Serial

define SerialAT Serial1

define TINY_GSM_MODEM_SIM7000SSL

define TINY_GSM_RX_BUFFER 1024

define SerialAT Serial1

include

ifdef DUMP_AT_COMMANDS

include

StreamDebugger debugger(SerialAT, SerialMon); TinyGsm modem(debugger);

else

TinyGsm modem(SerialAT);

endif

define UART_BAUD 9600

define PIN_DTR 25

define PIN_TX 27

define PIN_RX 26

define PWR_PIN 4

define LED_PIN 12

const char apn[] = "h2g2"; const char user[] = ""; const char pass[] = "";

void modemPowerOn() { pinMode(PWR_PIN, OUTPUT); digitalWrite(PWR_PIN, LOW); delay(1000); //Datasheet Ton mintues = 1S digitalWrite(PWR_PIN, HIGH); }

void modemPowerOff() { pinMode(PWR_PIN, OUTPUT); digitalWrite(PWR_PIN, LOW); delay(1500); //Datasheet Ton mintues = 1.2S digitalWrite(PWR_PIN, HIGH); }

void modemRestart() { modemPowerOff(); delay(1000); modemPowerOn(); }

void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) { switch(type) { case sIOtype_DISCONNECT: Serial.printf("Disconnected!"); break; case sIOtype_CONNECT: Serial.printf("Connected to url: %s\n", payload);
} }

void setup() { SerialMon.begin(115200);

pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);

modemPowerOn();

SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);

delay(10000);

String modemInfo = modem.getModemInfo();
SerialMon.print("Modem: ");
SerialMon.println(modemInfo);

SerialMon.print("Waiting for network...");
if (!modem.waitForNetwork(240000L)) 
{
    SerialMon.println(" fail");
    delay(10000);
    return;
}
SerialMon.println(" OK");

if (modem.isNetworkConnected()) 
{
  SerialMon.println("Network connected");
}

SerialMon.print(F("Connecting to APN: "));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, user, pass)) 
{
  SerialMon.println(" fail");
  delay(10000);
  return;
}

socketIO.begin("wss://demo.piesocket.com/v3/channel_1?api_key=VCXCEuvhGcBDP7XhiJJUDvR1e1D3eiVjgZ9VRiaV&notify_self",443);
socketIO.onEvent(socketIOEvent);

}

void loop() {}`

shardul10 commented 1 year ago

I am also trying to use TinyGsmClient (which is derived from Client). This is what I have done so far:

  1. In WebSockets.h defined new WEBSOCKETS_NETWORK_TYPE

define NETWORK_GSM (6)

  1. Added code

elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_GSM)

include

define WEBSOCKETS_NETWORK_CLASS TinyGsmClient

The first challenge I am facing is it also requires WEBSOCKETS_NETWORK_SERVER_CLASS to be defined. As per the answer in post above, it says only Client or Server class is required. How do I exclude the Server?

Secondly, in the WebSocketsClient.cpp, the _client.tcp is initialised as:

_client.tcp = new WEBSOCKETS_NETWORK_CLASS();

As far I understand TinyGsm needs initlization as:

define SerialAT Serial2

TinyGsm modem(SerialAT); TinyGsmClient client(modem);

Any suggestions how this can be done without modifying the code in WebSocketsClient.cpp?

Fareed99 commented 1 year ago

Hello @Djaison, I'm also working on a similar project, connecting my ESP32 controller based board to a WebSocket server using SIM7000. I am facing the exact same issue. I know its alot to ask you to share your code, but could you please shed some light on the solution to this. Thanks in advance!

VinodVermaVR commented 1 year ago

After implementing the necessary changes, I was able to successfully resolve the issue. My code is now working seamlessly in both sending and receiving data through WebSocket and SIM800 module. As per the WebSocket protocol, I made sure to establish the initial handshake before sending any data. This helped to ensure that the data transmission was in accordance with the WebSocket standard. If you require any further assistance or have any questions, feel free to contact me at vinodvermare@gmail.com

grems13 commented 5 months ago

I am also trying to use TinyGsmClient (which is derived from Client). This is what I have done so far:

  1. In WebSockets.h defined new WEBSOCKETS_NETWORK_TYPE

define NETWORK_GSM (6)

  1. Added code

elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_GSM)

include #define WEBSOCKETS_NETWORK_CLASS TinyGsmClient

The first challenge I am facing is it also requires WEBSOCKETS_NETWORK_SERVER_CLASS to be defined. As per the answer in post above, it says only Client or Server class is required. How do I exclude the Server?

Secondly, in the WebSocketsClient.cpp, the _client.tcp is initialised as:

_client.tcp = new WEBSOCKETS_NETWORK_CLASS();

As far I understand TinyGsm needs initlization as:

define SerialAT Serial2 TinyGsm modem(SerialAT); TinyGsmClient client(modem);

Any suggestions how this can be done without modifying the code in WebSocketsClient.cpp?

I think the same as you, and I wanted to ask whether you managed to implement it or not?

shardul10 commented 5 months ago

I am also trying to use TinyGsmClient (which is derived from Client). This is what I have done so far:

  1. In WebSockets.h defined new WEBSOCKETS_NETWORK_TYPE

define NETWORK_GSM (6)

  1. Added code

elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_GSM)

include #define WEBSOCKETS_NETWORK_CLASS TinyGsmClient

The first challenge I am facing is it also requires WEBSOCKETS_NETWORK_SERVER_CLASS to be defined. As per the answer in post above, it says only Client or Server class is required. How do I exclude the Server? Secondly, in the WebSocketsClient.cpp, the _client.tcp is initialised as: _client.tcp = new WEBSOCKETS_NETWORK_CLASS(); As far I understand TinyGsm needs initlization as:

define SerialAT Serial2 TinyGsm modem(SerialAT); TinyGsmClient client(modem);

Any suggestions how this can be done without modifying the code in WebSocketsClient.cpp?

I think the same as you, and I wanted to ask whether you managed to implement it or not?

Not really. I am using another socket library.

grems13 commented 5 months ago

I am also trying to use TinyGsmClient (which is derived from Client). This is what I have done so far:

  1. In WebSockets.h defined new WEBSOCKETS_NETWORK_TYPE

define NETWORK_GSM (6)

  1. Added code

elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_GSM)

include #define WEBSOCKETS_NETWORK_CLASS TinyGsmClient

The first challenge I am facing is it also requires WEBSOCKETS_NETWORK_SERVER_CLASS to be defined. As per the answer in post above, it says only Client or Server class is required. How do I exclude the Server? Secondly, in the WebSocketsClient.cpp, the _client.tcp is initialised as: _client.tcp = new WEBSOCKETS_NETWORK_CLASS(); As far I understand TinyGsm needs initlization as:

define SerialAT Serial2 TinyGsm modem(SerialAT); TinyGsmClient client(modem);

Any suggestions how this can be done without modifying the code in WebSocketsClient.cpp?

I think the same as you, and I wanted to ask whether you managed to implement it or not?

Not really. I am using another socket library.

If everything works, please share your implementation.

shardul10 commented 5 months ago

Take a look at gilmaimon/ArduinoWebsockets. It allows you to use any client - so you can use EthernetClient and TinyGsmClient. There is not much implementation - just declare this clients and initialise WebSocketClient with these clients (instead of default WiFiClient.

grems13 commented 5 months ago

Take a look at gilmaimon/ArduinoWebsockets. It allows you to use any client - so you can use EthernetClient and TinyGsmClient. There is not much implementation - just declare this clients and initialise WebSocketClient with these clients (instead of default WiFiClient.

Thank you very much .

grems13 commented 4 months ago

WiFiClient

Friend, I still can’t initialize WebSocketClient with a client other than WiFiClient. The examples do not contain the required implementation and in the library itself I did not find how to pass tinyGsmClient when initializing the WebSocketClient. Could you post a piece of code on how you implemented this?

shardul10 commented 4 months ago

Try this approach:

TinyGsm gsmModem(Serial1);
TinyGsmClient gsmClient(gsmModem);
std::shared_ptr<network::TcpClient> gClient = std::make_shared<network::GsmTcpClient>(gsmClient);
WebsocketsClient gSock(gClient);
grems13 commented 4 months ago

Try this approach:

TinyGsm gsmModem(Serial1);
TinyGsmClient gsmClient(gsmModem);
std::shared_ptr<network::TcpClient> gClient = std::make_shared<network::GsmTcpClient>(gsmClient);
WebsocketsClient gSock(gClient);

Esp32-Client:49:93: error: template argument 1 is invalid std::shared_ptr gClient = std::make_shared(client); exit status 1 'GsmTcpClient' is not a member of 'websockets::network'

shardul10 commented 4 months ago

oh yes, sorry. I remember now it was a bit more involved. It's been a while since I did this and the project is not active anymore. Let me see if I can dig out some old code.

grems13 commented 4 months ago

oh yes, sorry. I remember now it was a bit more involved. It's been a while since I did this and the project is not active anymore. Let me see if I can dig out some old code.

I would be very grateful.