Conrad 10215 Operation Manual

BEFORE WE START
When you first connect the IoT-WiFi-board (hereinafter also: NanoESP-) the computer may not find the required driver for the USB-to-Serial con­verter automatically. In this case, download the driver from
www.iot.fkainka.de/driver and install it manually. The Arduino- software will then
You also need to make some settings for working with the serial monitor. The Baud rate used is 19200 Baud. To send commands, you also need to select the
options CR and NL next to the menu for the Baud rate.
The proper settings in the Arduino environment
I worked with Arduino IDE versions 1.6.5 – 1.6.6. Older versions may cause prob­lems. The current Arduino IDE version is available on the website
www.arduino.cc.
If you have any difficulties or problems with the board or the learning package, you
can visit www.iot.fkainka.de for help. The page also contains a forum, new user projects and all programs presented here in the latest version.
The learning package contains a pinboard on which you can pin the NanoESP as illustrated below. This leaves you the most space for experiments, while the WLAN module protrudes over the plug board at the rear. The Micro USB cable can then be plugged in as shown in the picture in the following section and will barely be in the way. More detailed setup images are enclosed with the indi­vidual chapters.
The IoT-WiFi-board (NanoESP)
The main element of this learning package is the IoT-WiFi-board (NanoESP). As you can see quite well on the PCB, the board is made up of two components. The left half is an Arduin-compatible micro controller system that can be compared to the Arduino Nano. The right part is the WLAN module with the designation
ESP8266.
These two components communicate via a serial interface generated by software.
The NanoESP on the plug board
The pin layout of the board
The board has many different elements, such as the pins, some of which have special functions, or the LEDs, the function of which is not always evident at first glance. To prevent you from losing the overview, the following image lists the most important functions of the individual elements.
The most important pins and designations of the board
The WLAN module is controlled with AT commands. For this, the Arduino part of the board is connected to the WLAN module via pins 11 and 12. A small circuit converts the 5-V-levels into compatible 3.3-V-levels. Pins 11 and 12 should not be used in your own projects for this reason.
Further important hardware properties of the board are summarised in the follow­ing table.
Technical Data
Microcontroller: ATmega328 Flash memory: 32 kB (including 0.5 kB for the boot loader) SRAM: 2 kB EEPROM: 1 kB Cycle rate: 16 MHz I/O-pins: 20 (including 2 for communication with the WLAN
module)
U
including PWM: 6
U
including analogue inputs: 6
USB-to-Serial chip: CH340G Operating voltage: 5 V Recommended input voltage: 7 – 12 V Maximum current per I/O-pin: 40 mA Resilience of the 3.3-V-output: 50 mA
WLAN-module: ESP8266 SPI-Flash 4 Mbit Operating voltage: 3.3 V WLAN standards: 802.11 b/g/n WLAN modes: Wi-Fi Direct (P2P), Soft-AP Firmware: AT-Firmware Version 0.22 Other Features: Integrated TCP/IP-stack +19.5 dBm output power in the 802.11b-mode Integrated Low-Power-32-bit-CPU Communication via UART
COMPONENTS IN THE LEARNING PACKAGE
Find an overview of the parts contained in the learning package below. 1 IoT-WiFi-board (NanoESP) 1 pinboard 1 m circuit wire 2 button 1 9-V-clip 1 LED (red) 1 RGB-LED (4 connection legs) 1 resistor 10 kOhm (brown-black-orange) 1 resistor 1 kOhm (brown-black-red) 1 photo transistor (2 connection legs) 1 NTC 10 kOhm 1 Piezo speaker 1 potentiometer 10 kOhm with red dial switch
GETTING TO KNOW THE MODULE
This first chapter is about the general functions of the WLAN-modules. The mod­ule is controlled with AT commands. All example programs shown here, help and further information can be found at www.iot.fkainka.de
It is easiest to download the entire ZIP directory and copy the unpacked folder into your sketch folder completely. Then you can open all programs comfortably in sequence from the Arduino interface.
1.1
|
Basic AT commands
For a first impression how to use the AT-commands, best just try them out. There­fore, this section will introduce you to some of the basic commands for the module.
For this, open the program P01_SoftwareSerial in the Arduino-IDE. This is a very simple program that does nothing but pass on all data received via the serial
hardware interface of the micro controller to the ESP controller via a self-defined software interface. The entire thing works in the opposite direction as well. As you can see in the source text, the two connections of the software interface are pins 11 and 12. They should not be used as GPIO-pins in your own projects. You also need the SoftwareSerial-Library that is pre-installed already in most Arduino versions – if not, download the library via the manager.
After the program has been uploaded, you can start the serial monitor of the Ardu­ino interface. Before you can start, two important settings must be made to the Serial Monitor, i.e. the baud rate must be set to 19200 in the lower right corner
and the setting CR and NL must be made in the box to its left.
Now you can see a message, i.e. AT and a few lines below OK. The command
AT was sent to the ESP module by the micro controller and the module answered OK. You can see by this that the WLAN module works and is ready for use.
Terminal settings: CR and NL and a Baud rate of 19200
1.1.1 | Basic commands
You can now try out some basic commands of the module by simply entering the command and sending it to the module with
[Enter]
. Capitalisation of the com-
mand is important. You can submit the first command of your own by entering
AT
in the serial monitor and pressing
[Enter]
. The uploaded program passes on the command to the ESP module, which in turn answers AT and then OK. The next command that you can test is:
AT+GMR
This command outputs the current firmware and version number. The command
AT+RST
resets the module. You will see a few illegible characters on the terminal first, followed by ready, which says that the module is now ready. Another command is:
ATE0
This permits deactivating the echo of the module. This means that the command you sent will not be returned, but only the answer will be. For example, if you send AT, the response will not be AT and then OK, but only OK. However, for your first attempts, it is recommended to reactivate the echo with
ATE1
.
First attempts with the AT-commands
1.1.2 | WLAN-commands
The following WLAN-commands can be used to change the WLAN properties of the module. Some commands not only permit specification of a condition, but also requesting the current condition. This is done by entering a question mark after the command, e.g.
AT+CWMODE?
The returned value usually will be
+CWMODE=2
followed by OK. If you enter
AT+CWMODE=?
, the module will answer with the possible parameters for the command, in this case 1-3. CWMODE is a command that you can use to specify the WLAN-mode, by the way.
There are therefore three operating modes that I will explain below.
1
AT+CWMODE=2 – the module as Access Point (AP-mode)
In the delivery condition, the module is an Access Point. This means that you can directly connect to the module with a WLAN-capable device, such as a smartphone or a PC. For this, simply find the open WLAN with the name NanoESP and connect to it. In the default condition, no password is assigned, so that connection is not a problem. If you are connected to the module, you have no connection to the internet, since the module is not a router with a dedicated connection to the phone network. This WLAN-mode is still sensible, however, for example if you need a closed, safe network. Speaking of safety: There is also the option of assigning a password to the network, using the command:
AT+CWSAP
You need to enter parameters in the following order and separated with a comma:
U
the name of the network in quotation marks,
U
the password in quotation marks,
U
the channel ID (any value between 1 and 13),
U
and the encryption mode (value from 0-4).
One possible setting would be:
AT+CWSAP="MyNanoESP", "MyPassword", 5,3
After a short period, OK appears as confirmation. If an ERROR appears, check your input again, and in particular check the quotation marks. If an ERROR ap­pears anyway, check that the CWMODE is actually set to 2.
If everything works, you can connect to the board with a WLAN-capable device. All devices connected to the module can be displayed with IP and MAC addresses with the command
AT+CWLIF
.
The module in station mode. The IP of the connected computer is highlighted.
2
AT+CWMODE=1 – the module in station mode
The command
AT+CWMODE=1
sets the module to station mode. This mode permits connecting to your WLAN­router. This will also connect the module to the Internet and give it a lot more op­tions.
You can first use the command
AT+CWLAP
to list all networks in range to check if your network is within reception range. To connect to your router, you need the command
AT+CWJAP
Similar to the CWSAP-command, this has important parameters, i.e. the name of the WLAN-network (also called the SSID) and the password, each again in quota­tion marks and separated by a comma. Connecting to a second module that is set with the data according to the previous section would look as follows:
AT+CWJAP="MyNanoESP", "MyPassword"
It may take a few seconds to establish the connection. Then OK should be re­turned. You can call the IP of the module that the router assigns with the com­mand
AT+CIFSR
. This will be important later when you want to connect to the TCP-server of the module. The command
AT+CWQAP
will disconnect the connection with your router again.
The board connects to a second NanoESP.
3
AT+CWMODE=3 – dual mode
The third possible mode for the WLAN setting is dual mode. As the name sug­gests, it permits operating the module in station and AP-mode. This means that devices can establish a direct WLAN connection to the module, or reach the mod­ule through the router as an interim station. It is a practical mode, e.g. when you
are planning an internal network with several modules, but want one module to serve as the server that supplies all data to the network. We will get back to this later.
1.2 | Automatic configuration
The basic commands can be tested manually already. This chapter is to explain
how the commands can be automatically operated via the controller. You will also learn another command that you can use to test if a computer in the network or a server online can be reached. In this example, the Google server will be pinged. The example program P02_GooglePing mostly automates the processes that you entered manually in the first example. The controller sends commands to the ESP module in sequence, thus connecting to the WLAN, among others. The differently long time-out times give the module enough time to answer.
Before the program can work properly, you need to enter your WLAN data after #de­fine SSID and #define PASSWORD right at the beginning of the program source code. The module needs access to the Internet to execute its last command. The command
AT+PING
pings other devices in the network. Pinging means a query whether a computer can generally be reached. Here, the Google server is pinged with AT+PING="www.google.de". When a response returns, a success message ap­pears on the serial monitor and the LED labelled D3 that is connected to pin D13 at the board is activated. The first communication with the Internet is successful.
The program
We will analyse the program functions step by step below. First, we will cover com­munication with the module.
1
Serial communication
This works via the serial software interface that is provided with the Software­Serial-Library. When initialising, you also need to indicate the pins used: in this case these are pins 11 and 12.
001
#include <SoftwareSerial.h>
002
SoftwareSerial esp8266(11, 12);
Just as for the normal serial interface, you can then transfer bytes or entire lines with the commands esp8266.print or esp8266.println. The commands esp8266.find and esp8266.findUntil, with which an incoming stream can be checked for specific character strings, are particularly useful as well. This makes it rather simple to catch the matching response from the module. However, if an expected character string does not appear, it may take a while until the program continues. The waiting time (time-out) is defined byesp8266.setTimeout. findUntil() can also be used to define a second character spring in which the search function stops and returns false as the return value. We will use this in the function send­Com():
001
//-------Controll ESP--------
002
003
boolean sendCom(String command, char respond[])
004
{
005
esp8266.println(command);
006
if (esp8266.findUntil(respond, "ERROR"))
007
{
008
return true;
009
}
010
else
011
{
012
debug("ESP SEND ERROR: " + command);
013
return false;
014
}
015
}
When you call the function, you therefore need to submit the command and the expected return value to the function, e.g. AT and the expected return value OK. println() transmits the command and finally waits until the expected return value or an ERROR is received. When the expectation is met, the function returns the val­ue true. Otherwise, the module will use the debug()-function to return an ESP SEND ERROR and the sent command, so that it is easy to check which command caused the problem.
Not all AT-commands have a unique or one-line return value. If, e.g., the IP ad­dress is queried, there usually is no previously known value. Therefore, a second sendCom()-function exists that only needs the parameter command and will then return the entire received string. The string should not be too long, since the buffer of SoftwareSerial can overflow.
001
String sendCom(String command)
002
{
003
esp8266.println(command);
004
return esp8266.readString();
005
}
2
Troubleshooting
There will often be errors and complication when developing programs. To have any chance at all at finding them, there are two debug-functions that are activated or deactivated via a parameter at the very beginning of the program.
#define DEBUG true
The first function does nothing but provide a simplified output of text via the serial interface defined as standard. When the constant DEBUG is true, the content of the string Msg will be sent.
001
void debug(String Msg)
002
{
003
if (DEBUG)
004
{
005
Serial.println(Msg);
006
}
007
}
The second function is also explained quickly. When the function serialDebug is called, the program will switch to a permanent loop and will from then onwards behave like the first tested SoftwareSerial-program. This means that all data that are sent to the controller via the serial monitor will be passed on di­rectly to the module and vice versa. In case of error, you can therefore call the function and send manual commands to see where the error is located.
001
//---Debug Functions---
002
void serialDebug() {
003
while (true)
004
{
005
if (esp8266.available())
006
Serial.write(esp8266.read());
007
if (Serial.available())
008
esp8266.write(Serial.read());
009
}
010
}
3
Configuration
To improve overview of the programs in general, most settings have also been removed into individual functions, first of all the function espConfig, in which the most important parameters for the respective program are set.
001
//---Config ESP8266---
002
boolean espConfig()
003
{
004
boolean success = true;
005
esp8266.setTimeout(5000);
006
success &= sendCom("AT+RST", "ready");
007
esp8266.setTimeout(1000);
008
009
if (configStation(SSID, PASSWORD)) {
010
success &= true;
011
debug("WLAN Connected");
012
debug("My IP is:");
013
debug(sendCom("AT+CIFSR"));
014
}
015
else
016
{
017
success &= false;
018
}
019
020
success &= sendCom("AT+CIPMODE=0", "OK");
021
success &= sendCom("AT+CIPMUX=0", "OK");
022
023
return success;
024
}
At the beginning of the function, the variable success is set to true first, since this variable is now and-linked to various functions. This means that even if only one of the functions that have the value returns false, success will also immediately be­come false and the entire configuration will have failed. The first AT-command to be reviewed for success this way is the Reset-command, which is nearly always performed at the beginning of the program to ensure that prior tests are not still using the module. However, it may take up to five seconds until the module returns the message ready. Therefore, the time-out for esp8266.findUtil is increased just before thesendCom()-function. After the reset, the time-out is returned to the stan­dard value of one second.
This is followed by calling a self-defined function called configStation(), which will be discussed in the next section. It is used to connect the module to your home network. For this, the parameters SSID and PASSWORD will be transmitted that you entered at the beginning of the program. If the connection has been success­fully established, the success message and then the current IP of the module are transferred to the serial monitor. At the end of the function, parameters will be set that I will deal with later. Last, the variable success will be returned, which hope­fully has kept the value true.
001
boolean configStation(String vSSID, String vPASSWORT)
002
{
003
boolean success = true;
004
success &= (sendCom("AT+CWMODE=1", "OK"));
005
esp8266.setTimeout(20000);
006
success &= (sendCom("AT+CWJAP=\"" + String(vSSID) + "\",\"" + String(vPASSWORT) + "\"", "OK"));
007
esp8266.setTimeout(1000);
008
return success;
009
}
The function configStation() has been called in the espConfig()-function. Here, setting of the WLAN-mode to station mode with the command CWMODE and then connection to the network via the CWJAP-command are performed. It can take quite a long time until the connection is established. Therefore, the time-out is briefly raised to 20 seconds here. If you prefer dual WLAN-mode, you can set CWMODE to 3 here.
001
boolean configAP()
002
{
003
boolean success = true;
004
005
success &= (sendCom("AT+CWMODE=2", "OK"));
006
success &= (sendCom("AT+CWSAP=\"NanoESP\",\"\",5,0", "OK"));
007
008
return success;
009
}
The function configAP() is not called here, but should be mentioned briefly any­way. It is the counterpart to the configStation()-function, since it is used to set the module to Access Point. A long time-out is not necessary here, since the module can process the CWSAP-command much faster. In later tests, the espConfig()­function instead of the configStation() will be used to call the configAP()-function.
001
void setup()
002
{
003
// Open serial communications and wait for port to open:
004
Serial.begin(19200);
005
// set the data rate for the SoftwareSerial port
006
esp8266.begin(19200);
007
008
if (!espConfig()) serialDebug();
009
else debug("Config OK");
010
011
if (sendCom("AT+PING=\"www.google.de\"", "OK"))
012
{
013
Serial.println("Ping OK");
014
digitalWrite(13, HIGH);
015
}
016
else
017
{
018
Serial.println("Ping Error");
019
}
020
}
021
022
void loop() // run over and over
023
{
024
//Start serial Debug Mode - Type commands over serial Monitor
025
serialDebug();
026
}
The most important functions that you will find in nearly every program have now been covered. These functions will now be used in the known Arduino functions setup() and loop(). First, however, the two serial interfaces with 19200 Baud will be initialised. Only then will the function espConfig() be called. In case of error, the serialDebug()-function will be started at once. If everything went well, a success message is sent. In later programs, the LED at Pin 13 that is marked with D3 on
the board will also light up after successful configuration. This also gives you feed­back when the module is not connected to a PC with serial monitor. In this experi­ment, however, the LED is needed for the feedback of the ping status. The query takes place right in the next line of the configuration, too. The AT+PING-command will be sent with the Google address as a parameter. You can query an IP address from your local network instead of this address as well. In case of success, a mes­sage will appear and the LED D3 as mentioned will be activated. As the last ac­tion, the program will jump to the loop-function, which in turn will call the serialDe­bug()-function. You can therefore, test further commands after the program and thus ping, e.g., further addresses.
1.3 | Recognition of a network
This chapter is, among others, about a smaller hardware setup for the first time. The target of the project is a kind of alarm system that will react when a specific network comes into range or is switched on.
Only two parts and some wire are used. The pre­cise setup can be taken from the setup images.
Connection of the Piezo speaker
The source text for this project differs from the previous experiment mostly in the following functions:
001
void findSSID()
002
{
003
esp8266.println("AT+CWLAP");
004
if (esp8266.findUntil(ToFindSSID,"OK")) alarm();
005
else debug("SSID not found!");
006
}
007
008
void alarm()
009
{
010
debug("alarm!");
011
012
digitalWrite(LED_ALARM, HIGH);
013
014
for (int i; i <=30; i++)
015
{
016
tone(PIEZO, 400, 500);
017
delay(500);
018
tone(PIEZO, 800, 500);
019
delay(500);
020
}
021
022
digitalWrite(LED_ALARM, LOW);
023
}
The function findSSID() is called about every 30 seconds in the loop-routine and
will then scan for all networks in the environment. When the network you are look­ing for has been found, the function alarm() will be tripped, which switches on the LED D3 and emits a signal sound at the piezo. In the example program, we scan for a network with the SSID NanoESP, i.e. actually other NanoESP-networks in range. You can also enter another SSID in #define ToFindSSID at the beginning of the program. Then you can check, for example, how far your WLAN-network goes.
UDP AND IP
This chapter covers general data exchange between two systems via a WLAN­network. We will deal with subjects such as IP, ports and the UDP protocol. First, let us explain these basic terms.
What is an IP-address?
An IP-address works like a postal address. It can be used to clearly identify and address a computer in the network. An IP-address according to the still-common IPv4-standard looks as follows:
192.168.4.1
These are four numbers, or rather four bytes. This means that the value of each number cannot exceed 255. Generally, there are local IP-addresses, i.e. IPs that are assigned, e.g., to the computers and devices in your home network, and global IPs.
Local IPs are usually assigned by your router. They usually start 192.168. The following number differs from router to router. If the NanoESP acts as Access Point and computers can connect to its network, PCs will receive an address that starts with 192.168.4. This opens a subnetwork at the same time. Fritz!Box routers usually assign local IP-addresses according to the structure 192.168.178.X. You can find out your IP by entering, e.g. the command ipconfig in the Windows com-
mand prompt (under Start -> Programs -> Accessories -> Prompt ). A longer list will appear, which includes, among others, the item IPv4-address with your local IP in the network.
Global IPs are usually assigned by your internet service provider. This is, e.g., the address via which your router can be reached in the global network. The router opens the local network and distributes the data to the clients. One way of finding out your global IP is calling the website http://www.meine-aktuelle-ip.de/. That
website shows further data that can be viewed by a web server as well. You are not as anonymous online as you may think.
What is a port?
When comparing to a postal address, the port would be similar to the front door in an apartment house. A computer with a unique IP can provide different services via different ports. You can reach the server via the IP, but you use the port to choose the service to be used. For example, this can be port 20 for FTP data transmission or port 23 for a Telnet connection. You can usually select the port freely; however, there are standardised ports that make handling web applications easier. A list of standardised ports can be found at
https://de.wikipedia.org/wiki/Liste_der_standardisierten_Ports
What is UDP?
UDP is short for User Datagram Protocol. This is a minimal, connection-free net­work protocol. Generally, it is more minimalist and simpler than other internet pro­tocols, such as TCP, which we will deal with later. The comparison is not particu­larly simple here yet, but you may remember the following regarding the protocol's properties:
U
UDP is broadcast-capable.
U
It does not review the data for accuracy or correct errors.
U
There is therefore no guarantee that data have been successfully
transmitted.
U
There also is no guarantee that data have not been falsified on the
way or listened in on by third parties.
U
You do not need to establish a connection first. Quick data exchange
is possible.
U
There are barely any transmission delay fluctuations.
U
The format is suitable, e.g., for VoIP (Voice over IP – i.e. phone calls
via internet).
These are the most important basics on the terms for the following projects. The subject can be dealt with in more detail still, and further information will follow in a suitable location. First, let us deal with the practical part.
2.1 | Exchanging data between the board und PC by UDP
In this project on the subject of UDP, data are exchanged between the board and the PC via the WLAN. The prerequisite for this is that your computer has a WLAN adapter. A program on the PC-side ensures successful receipt of the messages. You will not need any special hardware setup for this experiment.
The program
When you load the program P04_UDPBasics.ino onto the controller, the controller
is configured as an access point and you can see an open network called NanoESP NanoESP. Before connecting to the network, first download a program from the Internet. In my experiments, I used the program Packet Sender by Dan Nagle which you can download from the following link:
https://packetsender.com/ After loading and installing the program, you can connect your PC to the open
network of the NanoESP. Ensure that the firewall recognises the network as a home network, to avoid blocking data. Your computer should now have the IP
192.168.4.2. You can check this by sending the command
AT+CWLIF
to the module via the serial monitor. This command shows all computers con­nected to the access point with IP and MAC addresses.
Start the program Packet Sender, set the UDP server port to 90 in Settings -> Network and click the checkbox Enable UDP Server. In Usually, the lower left should say UDP:90. If it does not, you need to restart the software once.
The proper settings in the program Packet Sender
The program on the computer is now used as UDP server, while the controller is
set as UDP client. The differentiation between client and server is not clear in the UDP protocol, but in this case it means that you will send data from your controller to the computer.
The message has been successfully transmitted.
To send data, use the command:
AT+CIPSEND=7
The 7 means the number of characters to be sent. The character > is returned. This means that you can now send your message. Enter Hello and confirm with
[Enter]
again. The module returns SEND OK, although you have only entered five characters. This is because after your input, Carriage Return and New Line are sent as well, i.e. two characters more that you need to include in your mes­sage length calculation.
When you switch back to the Packet Sender and look at Traffic Log there, you can see the receipt of the message. In the ASCII view, you will even see the two en­closed characters, represented by \r and \n.
The message has been received by Packet Sender.
001
boolean configUDP()
002
{
003
boolean success = true;
004
005
success &= (sendCom("AT+CIPMODE=0", "OK"));
006
success &= (sendCom("AT+CIPMUX=0", "OK"));
007
success &= sendCom("AT+CIPSTART=\"UDP\",\"192.168.4.2\",90", "OK"); //UDP-Server
008
return success;
009
}
In the Arduino program, the function configUDP() is particularly decisive for the communication path. The settings important for transmission are made there. First, use CIPMODE to set the data transparency mode to 0. Finally, use CIPMUX=0 to set that only one single connection is permitted. The decisive command is CIP­START. It is used to establish a commutation, specifically to IP 192.168.4.2, i.e. to your PC, and to PORT 90, where the program Packet Sender is listening with its UDP-server. These are the steps that are initially necessary to establish the first communication.
2.2 | Sending and receiving data with UDP
In the preceding project, the UDP communication was tested in one direction, i.e. from the board to the PC. In this program, the module is set so that communication in the other direction is possible as well, almost like in a chat.
The program
This program generally only contains a very small change that has a great effect on the communication with the UDP protocol. When you upload the program, an­other access point with which you can connect to a PC is generated. Again, you will need Packet Sender or a comparable program. Start the program and make the same settings as before (File -> Settings -> Network: Enable UDP Server, Port
90). Then you need to enter the address of the module in the main window in the IP Address field (192.168.4.1), set the Port to 91 and select the item UDP in the dropdown menu farther to the right. When these settings have been made and the serial monitor has been opened, you can send the first message to the module by entering, e.g., Hi in the field labelled ASCII.
If you click Send now, the Serial Monitor will show:
001
+IPD,2:Hi
002
OK
The Packet Sender has successfully submitted »Hi«.
The message has been received. You can answer by using the CIPSEND com­mand again, i.e. for example:
001
AT+CIPSEND=7
002
>Hello
The difference from the previous program is only in a single line:
success &= sendCom("AT+CIPSTART=\"UDP\",\"192.168.4.2 \",90,91", "OK");
As you can see, a second port was indicated. This port, here the one with number 91, is the port through which the module listens for incoming data in turn. By attach-
Loading...
+ 60 hidden pages