This could be achieved by adding an external antenna - but not all modules are prepared for the connection of an external antenna.
To keep it simple but effective, I added a half-wave antenna wire to the original onboard antenna of the ESP32 module.
The original print antenna is a meander-shaped, inverted F antenna with 1/4 wavelength. It is a compromise between size, omnidirectional antenna pattern if possible, and power efficiency. I found a very helpful source of information about such kind of antennas at https://www.nxp.com/docs/en/application-note/AN2731.pdf
My thought now was to increase the WIFI range of the module by a strong coupling between the on-board antenna and a newly added external half-wave antenna wire (AWG24 switch wire 0.5mm with 62mm length). However, no irreversible changes or soldering should become necessary. So I hot glued the additional antenna wire directly on the board . Note that half of the isolated antenna wire is exactly following the meandering shape of the printed F-antenna, while the other half is mounted "free". This results in a good inductive and capacitive coupling.
I did some experiments where the free end of the antenna wire ran straight or was run up at a 90 degree angle. This changed the resulting antenna pattern, which could surely be investigated much more to optimize the result in a given mounting environment
My hopeful design was now to prove!
To show the effect of my design, I mounted a modified module next to an unmodified one so that both modules should have nearly the same receiving conditions.
I have written ANNEX32 code that plots the WIFI field strength measured by both modules simultaneously on a single graph.
Module 1 (with additional antenna) logs its own WIFI RSSI and additionally requests a string with the logged RSSI from the second (unmodified) module.
I tested the effect of the additional antenna and recorded the WIFI strength under different conditions. Here I can show only an abstract of my experiments and results.
It turns out that the signal is improved by at least 3 dB overall on the modified modules with a elongated non-angled antenna wire. Under very reflective conditions, I had an improvement of almost 10 dB.
One of the reasons for the better gain is certainly the modified antenna pattern; another might be the strong coupling to a larger and somewhat more effective antenna.
Under given unfavorable conditions, this simple external antenna cannot work wonders, but it can increase the range of the ESP module or improve a less stable WIFI connection.
I modified an ESP32 CAM as described here and now have a much better signal and a very stable video connection in a place that was previously quite critical.
Code: [Local Link Removed for Guests]
'######## WIFI-GRAPH-LOGGER ####################################
' Allows to compair the two ESP-Modules which have different antennas
'
' Displays a graphical logging of two WIFI-signals in dB
' - the OWN WIFI-connection to the WIFI access point
' - the WIFI-connection of a remote ESP32 to the same AP
'
' TX = 1 => this ESP-Module returns the string with its
' WIFI-LOG-RESULT-STRING on request at http://MY_IP/msg?x=1
TX = 1
' RX = 1 => This ESP-Module regularly requests the WIFI-LOG-RESULT-STRING
' from remote module with http://REMOTE_IP/msg?x=1
RX = 0
REMOTE_IP$ = "192.168.0.141"
X_Num = 100 'Number of WIFI-MESSURES to display in the graph
WIFI_REMOTE$ = ""
onhtmlreload WEBPAGE
gosub WEBPAGE
if TX = 1 onurlmessage RETURN_WIFI_STRING
IF RX = 1 onwgetasync RECEIVE_REMOTE_STRING
timer0 500, LOG_MY_WIFI_CONNECTION
if RX = 1 timer1 1000, GET_REMOTE_WIFI_LOG_STRING
wait
'###############################################################
LOG_MY_WIFI_CONNECTION:
w=0
for i = 1 to 50
w = wifi.rssi + w
next i
w=W/(i-1) ' Thanks for the hint Fernando !
WIFI_LOCAL$= trim$(WIFI_LOCAL$ + " " +str$(wifi.rssi,"%2.1f"))
c = word.count(WIFI_LOCAL$," ")
p = instr(1, WIFI_LOCAL$, " ")
P = len(WIFI_LOCAL$) - p
If c > X_NUM then WIFI_LOCAL$ = right$(WIFI_LOCAL$, p )
'wlog WIFI_LOCAL$ , c
jscall |traceme(0,"| + WIFI_LOCAL$ + |");|
if WIFI_REMOTE$ <> "" jscall |traceme(1,"| + WIFI_REMOTE$ + |");|
return
'###############################################################
RETURN_WIFI_STRING:
URLMSGRETURN WIFI_LOCAL$
return
'###############################################################
GET_REMOTE_WIFI_LOG_STRING:
wgetasync ("http://" + REMOTE_IP$+ "/msg?x=1")
return
'###############################################################
RECEIVE_REMOTE_STRING:
WIFI_REMOTE$ = WGETRESULT$
return
'###############################################################
WEBPAGE:
cls
' loads the library
jsexternal "/xy.min.js"
cnt = 0
a$ = ""
a$ = a$ + |<p>WIFI Graph for two ESP32-modules .. <br> |
a$ = a$ + |GREEN = WITH additional antenna <br> RED === with original antenna |
a$ = a$ + |</p><canvas id="canvas1" width="800" height="400"></canvas>|
html a$
pause 500
' define che datasets
A$ = ""
A$ = A$ + |var datasets = [|
A$ = A$ + | {|
A$ = A$ + | lineColor : 'rgba(20,100,100,1)',|
A$ = A$ + | pointColor : 'rgba(20,20,20,1)',|
A$ = A$ + | pointStrokeColor : '#fff',|
A$ = A$ + | data : []|
A$ = A$ + | },|
A$ = A$ + | {|
A$ = A$ + | lineColor : 'rgba(151,30,0,1)',|
A$ = A$ + | pointColor : 'rgba(151,80,0,1)',|
A$ = A$ + | pointStrokeColor : '#fff',|
A$ = A$ + | data : []|
A$ = A$ + | }|
A$ = A$ + |];|
A$ = A$ + |var ctx2 = document.getElementById('canvas1').getContext('2d');|
A$ = A$ + ||
A$ = A$ + |var xy = new Xy(ctx2, {rangeX:[0,| + STR$(X_NUM)+ |], rangeY:[-80,-45], smooth:0.05, pointCircleRadius:2, pointStrokeWidth:1 });|
A$ = A$ + ||
A$ = A$ + |function traceme(set, data){|
A$ = A$ + | var s = data.split(" ");|
A$ = A$ + | for (var i=0; i<s.length; i++) {|
A$ = A$ + | datasets[set].data[i] = [i, s[i]];|
A$ = A$ + | }|
A$ = A$ + | xy.draw(datasets);|
A$ = A$ + |}|
jscript a$
A$ = "" ' clean memory
return