B4R Question Connecting two Arduinos via WiFi

Hi everybody, I'm trying to connect two Arduinos devices (1 NodeMCU ESP 12E + 1 ESPDuino) making use of a dedicated WiFi Network.

I programmed the Espduino in "AccessPoint mode" to act as a "server" listening on Port "12345", by the following code:

B4X:
Sub Process_Globals
   
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Private Wifi As ESP8266WiFi
    Private Server As WiFiServerSocket
    Private SerStream As AsyncStreams
    Private NetStream As AsyncStreams
    Private WifiEx As ESP8266extras
    'Private Timer1 As Timer
   
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
       
    WifiEx.ConfigAP("192.168.4.1","0.0.0.0","255.255.255.0")
    Log("StartAP :",Wifi.StartAccessPoint2("ESPWifi","Password"))
    Log("My AP ip:",Wifi.AccessPointIp)
       
    SerStream.Initialize(Serial1.Stream,"SerStream_NewData","SerStream_Error")
   
    Server.Initialize(12345,"Server_NewConnection")
    Server.Listen
                       
End Sub


Sub Server_NewConnection (NewSocket As WiFiSocket)
   
    If NewSocket.Connected=True Then Log("Client Connected")
    NetStream.Initialize(NewSocket.Stream,"NetStream_NewData","NetStream_Error")
    NetStream.Write("HTTP/1.1 200").Write(CRLF)
    NetStream.Write("Content-Type: text/html").Write(CRLF).Write(CRLF)
    NetStream.Write("ciao")
   
End Sub

Sub SerStream_NewData (Buffer() As Byte)
   
    Log(Buffer)
    NetStream.Write(Buffer)
   
End Sub

Sub SerStream_Error
       
    Log("Error receiving data from Serial")
   
End Sub

Sub NetStream_NewData (Buffer() As Byte)
   
    Log(Buffer)
       
End Sub

Sub NetStream_Error 
   
    Log("Error receiving data from NetStream")
    Server.Listen
       
End Sub

And I made use of this additional code on the NodeMCU to let it connect to server listening port :

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
   
    Private WiFi As ESP8266WiFi
    Private WifiEx As ESP8266extras
    Private Sock1 As WiFiSocket
    Private Stream As AsyncStreams
    Private ServerIP() As Byte = Array As Byte(192,168,4,1)
    Private ThisIP() As Byte = Array As Byte(192,168,4,9)
    Private SubNet() As Byte = Array As Byte(255,255,255,0)
    Private Gateway() As Byte = Array As Byte(0,0,0,0)
    Private DNS1() As Byte = Array As Byte(0,0,0,0)
    Private DNS2() As Byte = Array As Byte(0,0,0,0)
    Private const serverPort As UInt = 12345
    Private PinLed16 As Pin
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
   
    WifiEx.ConfigNetwork(ThisIP,ServerIP,SubNet,ServerIP,ServerIP)
   
    WiFi.Connect2("ESPWifi","Password")
    If WiFi.IsConnected=True Then 
        Log ("Connected to WiFi with IP:", WiFi.LocalIp," SSID: ",WifiEx.SSID) 
    End If
   
    PinLed16.Initialize(16,PinLed16.MODE_OUTPUT)
       
    If(Sock1.ConnectIP(ServerIP,serverPort)) Then
        Stream.Initialize(Sock1.Stream,"Stream_NewData","Stream_Error")
    End If
      
End Sub

Sub Stream_NewData (Buffer() As Byte)
   
    Dim bc As ByteConverter
    Dim cmd As String = bc.StringFromBytes(Buffer)
    Log(cmd)
    If cmd="ON" Then
        PinLed16.DigitalWrite(False)
    Else
        PinLed16.DigitalWrite(True)
    End If
               
End Sub

Sub Stream_Error
   
    Log("Errore ricezione pacchetto")
   
End Sub

As you may see, my goal, in order to test it, is to send data received from the serial of Espduino to the NodeMCU in order to light on the built LED.

Unfortunately it doesn't work!!

I noticed that :

If I try to connect to the Espduino (AP) via a mobile phone, I received the correct replies from it
(putting the 192.168.4.1:12345 address in html browser, I receive the correct reply "ciao"), but the NodeMCU (client) is not capable to connect to it and to send any request; the code stops at line :

Sock1.ConnectIP(ServerIP,serverPort)

If, on the contrary, I make use of a external router (i.e. the hotspot of my mobile phone) and both boards (Espduino and NodeMCU) connect to it in STA mode, everything works fine.

Could anyone kindly help me to solve this issue?

Thanks in advance!

Maurizio
 

Erel

Administrator
Staff member
Licensed User
Why are you using HTTP? This is not a good protocol for hardware to hardware communication.
Why are there two AsyncStreams in the one of the programs?
Why aren't you initializing AsyncStreams in prefix mode?

Best protocol: https://www.b4x.com/android/forum/t...ceive-objects-instead-of-bytes.72404/#content

Start with this PC to Arduino example: https://www.b4x.com/android/forum/threads/esp-configurator-based-on-b4rserializator.81452/
If it works for you then there is no reason that you cannot implement a similar solution with two Arduinos.
 
Dear Erel, many thanks for your prompt reply. I try to answer your questions :

Why are you using HTTP?

It was not my intention to use HTTP protocol. I only opened a port(12345) on the server to listen from incoming connections. Maybe I've done something wrong, but, on my opinion, this is not a HTTP port, is it?

Why are there two AsyncStreams in the one of the programs?

I used one Stream to read from serial (SerStream) and another one (NetStream) to write to the client connected via wifi.

Why aren't you initializing AsyncStreams in prefix mode?

I've always been working without the prefix mode for other projects and I received no errors in trasmitting packets of bytes. Keep in mind that I have no problem, with the same code, to let the two Arduinos communicate correctly when I use an external router (i.e. the two Arduinos are both in STA mode connected to a common wifi network). I encounter problems only when I use the Arduino "server" acting as an Access Point and I don't understand the reason why.

B4RSerializator &

I followed your suggestion about the protocol and I studied deeply. Unfortunately, my problem in the "client" code is at this point :

B4X:
Sock1.ConnectIP(ServerIP,serverPort)
The Arduino is not capable to connect to the Arduino "server" and to open the relative socket. Otherwise, if I make use of a browser on a Laptop or on an Android phone, I receive a correct reply from the server. This is another unexplainable mystery to me...
 
Thanks, I implemented the AsyncStreams in prefix mode but it still doesn't wotk. I'll also implement shortly the B4RSerializator in order to simplify the code and I'll let you know. The "ESP configurator" example works fine for me. I took a look at the code and I noticed that the Sock.Initialize method is slightly different to the one implemented in B4R (invoked with different number of parametrs and types..), do you think that I could affect the its way to operate? I cannot cope with the fact that the connection by the server is accepted only when it's required by a PC, Laptop, Android device, etc. and it's rejected when it's required by another Arduino...

I'll continue to investigate it!
 

Alberto Iglesias

Well-Known Member
Licensed User
Hi everybody, I'm trying to connect two Arduinos devices (1 NodeMCU ESP 12E + 1 ESPDuino) making use of a dedicated WiFi Network.

I programmed the Espduino in "AccessPoint mode" to act as a "server" listening on Port "12345", by the following code:

B4X:
Sub Process_Globals
  
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Private Wifi As ESP8266WiFi
    Private Server As WiFiServerSocket
    Private SerStream As AsyncStreams
    Private NetStream As AsyncStreams
    Private WifiEx As ESP8266extras
    'Private Timer1 As Timer
  
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
      
    WifiEx.ConfigAP("192.168.4.1","0.0.0.0","255.255.255.0")
    Log("StartAP :",Wifi.StartAccessPoint2("ESPWifi","Password"))
    Log("My AP ip:",Wifi.AccessPointIp)
      
    SerStream.Initialize(Serial1.Stream,"SerStream_NewData","SerStream_Error")
  
    Server.Initialize(12345,"Server_NewConnection")
    Server.Listen
                      
End Sub


Sub Server_NewConnection (NewSocket As WiFiSocket)
  
    If NewSocket.Connected=True Then Log("Client Connected")
    NetStream.Initialize(NewSocket.Stream,"NetStream_NewData","NetStream_Error")
    NetStream.Write("HTTP/1.1 200").Write(CRLF)
    NetStream.Write("Content-Type: text/html").Write(CRLF).Write(CRLF)
    NetStream.Write("ciao")
  
End Sub

Sub SerStream_NewData (Buffer() As Byte)
  
    Log(Buffer)
    NetStream.Write(Buffer)
  
End Sub

Sub SerStream_Error
      
    Log("Error receiving data from Serial")
  
End Sub

Sub NetStream_NewData (Buffer() As Byte)
  
    Log(Buffer)
      
End Sub

Sub NetStream_Error
  
    Log("Error receiving data from NetStream")
    Server.Listen
      
End Sub

And I made use of this additional code on the NodeMCU to let it connect to server listening port :

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
  
    Private WiFi As ESP8266WiFi
    Private WifiEx As ESP8266extras
    Private Sock1 As WiFiSocket
    Private Stream As AsyncStreams
    Private ServerIP() As Byte = Array As Byte(192,168,4,1)
    Private ThisIP() As Byte = Array As Byte(192,168,4,9)
    Private SubNet() As Byte = Array As Byte(255,255,255,0)
    Private Gateway() As Byte = Array As Byte(0,0,0,0)
    Private DNS1() As Byte = Array As Byte(0,0,0,0)
    Private DNS2() As Byte = Array As Byte(0,0,0,0)
    Private const serverPort As UInt = 12345
    Private PinLed16 As Pin
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
  
    WifiEx.ConfigNetwork(ThisIP,ServerIP,SubNet,ServerIP,ServerIP)
  
    WiFi.Connect2("ESPWifi","Password")
    If WiFi.IsConnected=True Then
        Log ("Connected to WiFi with IP:", WiFi.LocalIp," SSID: ",WifiEx.SSID)
    End If
  
    PinLed16.Initialize(16,PinLed16.MODE_OUTPUT)
      
    If(Sock1.ConnectIP(ServerIP,serverPort)) Then
        Stream.Initialize(Sock1.Stream,"Stream_NewData","Stream_Error")
    End If
     
End Sub

Sub Stream_NewData (Buffer() As Byte)
  
    Dim bc As ByteConverter
    Dim cmd As String = bc.StringFromBytes(Buffer)
    Log(cmd)
    If cmd="ON" Then
        PinLed16.DigitalWrite(False)
    Else
        PinLed16.DigitalWrite(True)
    End If
              
End Sub

Sub Stream_Error
  
    Log("Errore ricezione pacchetto")
  
End Sub

As you may see, my goal, in order to test it, is to send data received from the serial of Espduino to the NodeMCU in order to light on the built LED.

Unfortunately it doesn't work!!

I noticed that :

If I try to connect to the Espduino (AP) via a mobile phone, I received the correct replies from it
(putting the 192.168.4.1:12345 address in html browser, I receive the correct reply "ciao"), but the NodeMCU (client) is not capable to connect to it and to send any request; the code stops at line :

Sock1.ConnectIP(ServerIP,serverPort)

If, on the contrary, I make use of a external router (i.e. the hotspot of my mobile phone) and both boards (Espduino and NodeMCU) connect to it in STA mode, everything works fine.

Could anyone kindly help me to solve this issue?

Thanks in advance!

Maurizio
Ciao Maurizio,

With this code is possible to show the webpage after someone connect with ESP8266? is work like Captive Portal?
 

KMatle

Expert
Licensed User
With this code is possible to show the webpage after someone connect with
If you mean to create a simple webpage on the ESP then:

- listen to port 80 (like webservers do)
- open a browser and type the ESP's IP
- reply with e.g. "<b>Hello<\b>" and see what the browser shows (maybe it shows Hello)
- try some other html code (like buttons, etc.)
 

Alberto Iglesias

Well-Known Member
Licensed User
If you mean to create a simple webpage on the ESP then:

- listen to port 80 (like webservers do)
- open a browser and type the ESP's IP
- reply with e.g. "<b>Hello<\b>" and see what the browser shows (maybe it shows Hello)
- try some other html code (like buttons, etc.)
This is exactly what we DON'T want... to open manually the browser
 
Top