Wemos Lolin ESP32 OLED Module For Arduino ESP32 OLED WiFi + Bluetooth

I always liked, and still do like, Arduino Due, with 84MHz available for 12$ from China.

Recently I stumbled over the Lolin module and ordered it for <10$:

Normally clocked at 80MHz, it seems to be possible to run at 160MHz and 240MHz as well. Most importantly, while there are many ways to program it, it can be just programmed via Arduino IDE as well:

For the low price it brings not only WiFi and Bluetooth, but has mounted a 128x64 OLED display as well:

Graphics can be accessed by the Arduino SSD1306 library:

My first application will be "ground altimeter" for Raspberry Pi Zero W flying aceess point
https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=190407&p=1198530#p1198530

on RC airplane:

Later maybe for streaming video from the airplane bottom mounted camera as well (on bigger, ILI9341 320x240 color LCD -- the videos are currently full HD and stored on SD card).

I thought this new Arduino might be of interest for others as well,

Hermann.

P.S:
The module has a dual core 32bit CPU, one core does WiFi, Bluetooth and other stuff, the second is for you only:

After I received a new Raspberry Pi Zero W I went ahead and worked on ground altimeter for the Lolin ESP32.

In the mean time I learned from other threads that "Wemos" may be incorrectly have been added to the module name, that can be found here:

So today (after having seen REALLY good Wifi distance, see below) I first wanted to verify that it is a real ESP32.

This simple for loop computes the sum of squares up to 100.000.000:

   long i,j,t0,t1, N=100000000;
    t0 = micros();
    for(i=0,j=0; i<N; ++i) { j+=i; }
    t1 = micros();
    DRAW(String((t1-t0)/0.001/N)+"\n"+String(j));

On OLED display I could read 887459712, which is correct modulo 2^32:

$ bc -q
(100000000*99999999/2)%(2^32)
887459712

1000/8.39
119

And I read 8.39 (ns per loop), which says that 119.000.000 loops per second can be computed, which is proof that CPU has >80MHz.

Now to WLAN far distance link quality between ESP32 and Pi Zero W, yesterday I was able to see 38/70 link quality (-72dBm) over a distance of 55m, and that inhouse!

Currently we are in youth hostel Friedrichshafen/Germany at Lake Constance, and I did measure the distance between Pi Zero W on one end of a very long floor and ESP 32 on the other end with Gmaps pedometer as 55m:

Here you can see the 38/70 and copied in 37/70 measurements I made at the other end of the floor on the ESP32 OLED display (zoom in to see the details):

So if inhouse 55m is possible, I hope for more distance possible outside with Pi Zero W flying with RC airplane, and ESP32 OLED displaying altimeter information on ground.

Now I describe the Arduino IDE code for ESP32, and the Raspberry Pi Zero W code.

The ESP32 starts as wireless access point (192.168.4.1) and waits for some computer to connect.
When Pi Zero W starts, it connects to that AP by these lines in WPA config:

pi@raspberrypi05:~ $ sudo tail -5 /etc/wpa_supplicant/wpa_supplicant.conf 
network={
ssid="MyESP32AP"
psk="testpassword"
}

I did install Apache webserver on the Pi, so that it serves "http://192.168.4.2/wifi" web page. This web page gets refreshed every second by this script started via /etc/rc.local:

pi@raspberrypi05:~ $ tail -3 /etc/rc.local 
/home/pi/iwconfig.Link &

exit 0
pi@raspberrypi05:~ $ cat /home/pi/iwconfig.Link 
#!/bin/bash
while (true)
do
  export iw=`iwconfig wlan0 | grep Link`
  echo $iw | cut -f2 -d\  > /var/www/html/wifi
  echo $iw | cut -f3-5 -d\  >> /var/www/html/wifi
  sleep 1
done
pi@raspberrypi05:~ $

The content of /var/www/html/wifi looks like this:

pi@raspberrypi05:~ $ cat /var/www/html/wifi 
Quality=70/70
Signal level=-38 dBm
pi@raspberrypi05:~ $

OK, this was the Raspberry side, now the Arduino IDE code for the ESP32 with OLED.
The sketch is based on BasicHttpClient.ino, but instead of connecting to an AP, the ESP32 gets AP itself via WiFi.softAP(). After Pi Zero W connects to ESP32 AP, the loop() does GET requests to "http://192.168.4.2/wifi", and in case of success, draws the response on OLED. 16 point font is a little bit too large, but only leading "S" and trailing "m" are missing for 2nd line. The code relies on Pi Zero W becoming 192.168.4.2, which seems to always be the case. No idea whether this is always the case, or how to determine the Pi Zero W IP address on ESP32 side:

/*
 *  Based on BasicHTTPClient.ino
 *  Instead of connecting ESP32 to AP, be one itself (softAP)
 *  Use SSD1306 lib for Lolin32 OLED display output
 *  https://www.banggood.com/search/lolin-esp32.html
 */

#include <Arduino.h>

#include <WiFi.h>
#include <WiFiMulti.h>

#include <HTTPClient.h>

#include "SSD1306.h"

WiFiMulti wifiMulti;

SSD1306  display(0x3c, 5, 4);

#define DRAW(s) \
    display.clear(); \
    display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH); \
    display.drawString(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, s); \
    display.display()

void setup() {

    //wifiMulti.addAP("ssid", "password");
    WiFi.softAP("MyESP32AP", "testpassword");
    
    display.init();
    display.flipScreenVertically();
    display.setContrast(255);
  
    display.setFont(ArialMT_Plain_16);
    display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);

    DRAW("waiting");

    while (!WiFi.softAPgetStationNum()) delay(1000);

    DRAW(String(WiFi.softAPgetStationNum()));
}

void loop() {
    HTTPClient http;

    http.begin("http://192.168.4.2/wifi"); //HTTP

    int httpCode = http.GET();

    if(httpCode > 0) {
        if(httpCode == HTTP_CODE_OK) {
            String payload = http.getString();
            DRAW(payload);
        }
    } else {
//        USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }

    http.end();

    delay(200);
}

I had to remove all Serial output lines from BasicHttpClient.ino, because otherwise the sketch does not work without a laptop connected, which is needed for ground altimeter. A final test showed that ESP32 and Pi Zero W work fine just powered, ESP32 has to be started first so that Pi Zero W can connect to AP:

After that scenario worked, I did order another Lolin ESP32 OLED module for 10.49$ with free shipping :wink:

Hermann.

First let me say that I have no relationship to Espressif/ESP32 or the seller of that ESP32 OLED module or Raspberry. I am just thrilled of the inhouse Wifi working distance between ESP32 and Pi ZeroW, that is why I document what I found here. Find the new Arduino sketch for the new youtube video below:

As with a previous video where I walked the 55m youth hostel corridor and recorded ESP32 OLED display

the new OLED screen has an action indicator that shows each update in the sketch loop(). New is bottom right continuous display of clients connected to ESP32 AP (I tested with laptop connecting to the AP and 2 got displayed).

In Böblingen/Germany IBM lab we have >20 connected buildings, and I used the longest straight line basement corridor I could find. To my surprise the 170m (again measured with Gmaps pedometer) of that corridor were not enough to see any Wifi connectivity issues!

Link quality was in 30-33/70 range, and signal level was in -(77-80)dBm range!

(I always had the plan to use the very long straight basement corridors of IBM Böblingen lab, but the plan was to do so for max. speed measurements of my fast driving autonomous robots)

Hermann.

/*
 *  Based on BasicHTTPClient.ino
 *  Instead of connecting ESP32 to AP, be one itself (softAP)
 *  Use SSD1306 lib for Lolin32 OLED display output
 *  https://www.banggood.com/search/lolin-esp32.html
 */

#include <Arduino.h>

#include <WiFi.h>
#include <WiFiMulti.h>

#include <HTTPClient.h>

#include "SSD1306.h"

WiFiMulti wifiMulti;

SSD1306  display(0x3c, 5, 4);

int pos1=0,pos0=0;

#define LINE(i) \
    display.setColor(INVERSE); \
    display.drawVerticalLine(pos##i, DISPLAY_HEIGHT-8-10*i, 8); \
    pos##i = (++pos##i % 100); \
    display.setColor(WHITE); \
    display.display()
        
#define DRAW1(s) \
    display.setColor(BLACK); \
    display.fillRect(112,48,16,16); \
    display.setTextAlignment(TEXT_ALIGN_LEFT); \
    display.setColor(WHITE); \
    display.drawString(112, 48, s); \
    display.display()

#define DRAW(s) \
    display.clear(); \
    display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH); \
    display.drawString(DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2, s); \
    display.display()

void setup() {

    //wifiMulti.addAP("ssid", "password");
    WiFi.softAP("MyESP32AP", "testpassword");
    
    display.init();
    display.flipScreenVertically();
    display.setContrast(255);
  
    display.setFont(ArialMT_Plain_16);
    display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);

    DRAW("waiting");

    while (!WiFi.softAPgetStationNum()) delay(1000);

    DRAW(String(WiFi.softAPgetStationNum()));
}

void loop() {
  if (WiFi.softAPgetStationNum()) {
    HTTPClient http;
    http.setTimeout(800);

    http.begin("http://192.168.4.2/wifi"); //HTTP
    LINE(1);

    int httpCode = http.GET();

    if(httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        DRAW(payload);
    } else {
        LINE(0);
    }
    http.end();
  }
  
  DRAW1(String(WiFi.softAPgetStationNum()));
  
  delay(200);
}

Yesterday I did try to fly RC airplane with ground altimeter. These were the only changes in Arduino sketch needed:

$ diff sketch_aug30a/sketch_aug30a.ino sketch_sep03a/sketch_sep03a.ino 
53c53
<     display.setFont(ArialMT_Plain_16);
---
>     display.setFont(ArialMT_Plain_24);
68c68
<     http.begin("http://192.168.4.2/wifi"); //HTTP
---
>     http.begin("http://192.168.4.2/height");
$

The airplane wheight did increase to 40.9g by the added BMP180 pressure sensor. The airplane was not able to fly high, and therefore I removed the bottom camera and screws, which reduced weight by 3.0g landing in range of previous weight. After the airplane did not climb more than 5m today, I did even remove the now unneeded camera ribbon cable and its tape. This reduced wheight by another 0.9g. Still no luck in getting airplane fly high. I assume that the GND/VCC/SCL/SDA connectors from BMP180 soldered on Pi ZeroW do too much harm to the airplane upswing, and that the Pi ZeroW needs to be mounted somewhere else, perhaps below the airplane. Will try when back home at end of he week:

At least I found a good and non-intrusive way to connect the Wifi ground altimeter to remote control:

Hermann.

P.S:
I used an endless loop python script with time.sleep(1) based on this article, started via /etc/rc.local, to determine altitude and provide via .../height URL:

I will provide the details when back home, interesting was that the (endless) python script always stopped 4 hours after startup. That is no problem since the Lipos will never hold for that time.

Hi, how can we add this board to the Arduino IDE ?
thanks!

gilalmogy:
Hi, how can we add this board to the Arduino IDE ?
thanks!

As stated in 1st posting of this thread, it can be just programmed via Arduino IDE as well, see "Installation Instructions":

It seems that the ESP32 CPU clock is 160MHz, by above done measurement and the spec:

I stumbled over an integer performance comparison for many microcontrollers I did in an Arduino Due thread:
https://forum.arduino.cc/index.php?topic=397480.msg2854537#msg2854537

The sketch used is attached to this posting.

I did compute both values (-Os and -O3) for the ESP32 board this thread is about.
And I added Pi Zero W row, as well as W541 row because of 6μs time:

model -Os -O3 speed processor Wifi
MKR1000 1038 825 48MHz SAMD21 Cortex-M0+ yes
Zero - - 48MHz ATSAMD21G18 -
101 846 791 32MHz Intel® Curie -
Due 548 494 84MHz ATSAM3X8E -
-
ESP8266-12E 612 304 80MHz Tensilica Xtensa LX106 yes
Lolin ESP32 191 149 160MHz Dual core Xtensa LX6 yes
-
Raspberry Pi Zero [W] - 30 1000MHz Broadcom BCM2835 [yes]
Raspberry Pi 2B - 27 900MHz Quad core BCM2835 -
Raspberry Pi 3B - 17 1200MHz Quad core BCM2835 yes
Raspberry Pi 3B+ - 14 1400MHz Quad core BCM2835 yes
-
(W541) - 6 2.8GHz Intel i7-4810MQ

added Pi 3B+, corrected all Pi values after having forced CPU to run at highest speed
added Pi 3B
corrected Pi Zero [W] times, added Pi 2B

 47| 29|101|
113| 59|  5|
 17| 89| 71|

149us

Hermann.

Below sketch might be useful as starter for both, Wifi processing as well as OLED display output. I learned from several sketches out there and combined what I needed. Multiple .addAP() calls allow the Lolin32 to work with several access points without recompile. And display.setLogBuffer(5,30) seems to be a nice alternative to Serial output. Sketch connects to Wifi AP, reports its IP address and then logs RSSI (Received Signal Strength Indicator) in a new line every second.

I had problems to take a focused photo of OLED with my Android cameras, only fuzzy photos. So I used PS3 Eye as webcam. Same problem with that in both settings of its adjustable fixed focus zoom lens. Then I learned that I can manually set focus continuously and so I got this photo I wanted:

Hermann.

#include <WiFi.h>
#include <WiFiMulti.h>

WiFiMulti wifiMulti;

#include "SSD1306.h"

SSD1306  display(0x3c, 5, 4);

void setup() {
  display.init();

  display.flipScreenVertically();

  display.setContrast(255);

  display.clear();

  wifiMulti.addAP("FRITZ!Box ... 1", "verySecret");
  wifiMulti.addAP("FRITZ!Box ... 2", "foobar");

  display.setLogBuffer(5, 30);
  display.println("Connecting Wifi...");
  display.drawLogBuffer(0, 0);
  display.display();
  
  if(wifiMulti.run() == WL_CONNECTED) {
    display.println("WiFi connected");
    display.println("IP address: ");
    display.println(WiFi.localIP());
    display.drawLogBuffer(0, 0);
    display.display();
  }
}

void loop() {
  if(wifiMulti.run() != WL_CONNECTED) {
    display.println("WiFi not connected!");
    display.clear();
    display.drawLogBuffer(0, 0);
    display.display();
    delay(1000);
  }
  
  long rssi = WiFi.RSSI();
  display.clear();
  display.print("RSSI:");
  display.println(rssi);
  display.drawLogBuffer(0, 0);
  display.display();
  delay(1000);
}

P.S:
This diff gives a more compact display:

$ diff sketch_oct06e/sketch_oct06e.ino sketch_oct06f/sketch_oct06f.ino 
9a10,11
> int i=0;
> 
29c31
<     display.println("IP address: ");
---
>     display.print("IP ");
47,48c49,51
<   display.print("RSSI:");
<   display.println(rssi);
---
>   display.print(rssi);
>   display.print(" ");
>   if (i++%7==6) display.println();
$

I made one ESP32 the AP, and the other connect to it. Best signal strength (-10dBm) happens when placing both antennas side by side.

I placed the ESP32 acting as AP on window sill in 1st floor of our house and moved with the 2nd connected to the AP far away outdoor. I got RSSI values (updated each second on OLED) even at 200m distance (with few trees in line of sight), connection dropped at 208m distance. These long distances don't make much sense though since I did not test sending data sofar. And signal strength was in the high -80s and low -90s dBm range which makes functionality unlikely, see table here:

After power cycling, the sketch on mobile ESP32 tried to connect to AP, and I walked back on the field direction our house. It was able to connect to AP and display its IP address on the OLED at distance 168m, but again with signal strength in the -80s dBm range. I walked further back direction house until signal level was -70dBm (with a small tree in line of sight). The distance to AP on window sill at that point was 87m.

Will use advanced sketches to transfer data (over HTTP request) for investigating how far reliable packet delivery is possible. And will move the AP ESP32 (battery/Lipo powered) on the field as well for direct line of sight connection long distance measurements.

Hermann.

As the table pointed to indicates, anything more than -70dBm should not be considered. I tested on distances with around -75dBm and every 20th-30th request is slow (>1000ms), but successful.

I built a 1-URL Web server and access point on one Lolin ESP32, and a HTTP Client on 2nd, you can find sketches below.

It turned out that I got best connectivity if ESP32 Wifi antennas pointing up and the ESP32s point to each other. This shows where I took the measurements yesterday evening, web server and access point on window sill of my secondary living place, HTTP client on rail of Schönbuchbahn:

I was not able to get a focused photo with Android camera. But viewing the photo on Android I was able to see that this is displayed:

67-69#0 52-69#1 66-69#2
66-69#0 52-69#1 66-69#2
67-69#0 51-69#1 67-69#2
66-69#0 50-70#1 67-69#2
67-69#0 51-70#1

The first number is millisecond time to send GET request and receive response. The 2nd (negative) number is RSSI connectivity, and the number after '#' is a 0-2 conter value received from web server. The RSSI value was always 69-70 (I watched 600 requests) without any slow, all requests take <70ms, "middle" always <55ms, distance was 58m in this case:

Hermann.

1-URL Web server and access point:

/*
 *  access point & 1-URL HTTP server (http://192.168.4.1/foobar)
 */
#include <WiFi.h>

#include "SSD1306.h"

SSD1306  display(0x3c, 5, 4);

WiFiServer server(80);

char req[]={'G','E','T',' ','/','f','o','o','b','a','r',' '};
char plain[]="HTTP/1.1 200 OK\nContent-type:text/plain\n\n";

int c=0;
#define N 3

void setup() {
  display.init();
  display.flipScreenVertically();
  display.setContrast(255);

  display.setLogBuffer(5, 30);
  
  WiFi.softAP("ESP32_TestAP", "esp32example");

  display.clear();
  display.println("AP");
  display.drawLogBuffer(0, 0);
  display.display();

  server.begin();
}

void loop(){
  WiFiClient client = server.available();

  if (client) {
    int i=0;
    while (client.connected() && i<sizeof(req)) {
      if (client.available()) {
        if (req[i] != client.read())
          break;
        ++i;
      }
    }

    display.clear();

    if (i==sizeof(req)) {
      while (client.connected() && client.available())
        client.read();

      if (client.connected()) {
        client.print(plain);
        client.print(c % N);
        display.print(".");
      } else {
        display.print("@");        
      }  
    } else {
        display.print("#");            
    }

    if (c++ % N == N-1)
      display.println();

    display.drawLogBuffer(0, 0);
    display.display();

    client.stop();
  }

  delay(100); 
}

Measuring HTTP client:

/*
 *  HTTP client endlessly doing GET(http://192.168.4.1/foobar)
 *  "67-45#2" means: t(GET)=67ms, RSSI=-45, 2 returned counter
 */
#include <Arduino.h>

#include <WiFi.h>
#include <WiFiMulti.h>

#include <HTTPClient.h>

#include "SSD1306.h"

SSD1306  display(0x3c, 5, 4);

WiFiMulti wifiMulti;
HTTPClient http;

unsigned long t0, t1, c=0, r;
#define N 3

void setup() {
  display.init();
  display.flipScreenVertically();
  display.setContrast(255);

  display.setLogBuffer(5, 30);
  
  wifiMulti.addAP("ESP32_TestAP", "esp32example");

  while (wifiMulti.run() != WL_CONNECTED) {
    delay(500);
    display.clear();
    display.print(".");
    display.drawLogBuffer(0, 0);
    display.display();
  }


  display.clear();
  display.println(WiFi.localIP());
  display.drawLogBuffer(0, 0);
  display.display();
}

void loop() {
  if((wifiMulti.run() == WL_CONNECTED)) {
    long rssi = WiFi.RSSI();
    t0 = millis();
    http.begin("http://192.168.4.1/foobar");
    if(http.GET() == HTTP_CODE_OK) {
      r = http.getString().toInt();
    } else {
      r = 9;
    }
    http.end();
    t1 = millis();
    display.clear(); display.print(t1-t0); display.print(rssi);
    display.print("#"); display.print(r); display.print(" ");
    if (c % N == N-1)
      display.println();
    display.drawLogBuffer(0, 0);
    display.display();
    if (r<9)
      c++;
  }

  delay(250);
}

Wow, saw video to this code in action with >200fps on 2.4" OLED display. The display dimension was same as for the Lolin OLED (128x64). I wanted to try, but had no MPU6050 at hand here in secondary living place. So I just deleted all MPU calls, added missing variable definitions and fixed OLED pin numbers, see small diff below. I awaited to see a fixed view display, but to my surprise a complete 3D movie got displayed with >300fps! Maximum reported was 334fps:
4

As always I had problems with focus of my Android phone camera, but you get the idea on how this looks.
Here is a 8s 720p youtube video I took:

Hermann.

$ diff Rotatey_Balls.ino sketch_oct12a/sketch_oct12a.ino 
8c8
< #include "mpu6050rotatey.h" /* Source http://tocknlab.hatenablog.com/entry/2017/03/11/182703 */
---
> float angleX,angleY,angleZ,lastAngleX,lastAngleY,lastAngleZ;
18,19c18,19
< int sdaPin = 21;
< int sclPin = 22;
---
> int sdaPin = 5;
> int sclPin = 4;
164,165d163
<   mpu_init(sdaPin, sclPin);// sda, scl
<   mpu_calibrate();
168d165
<   calcRotation(); // read from MPU
186d182
<   calcRotation(); // read from MPU
374a371
> 
$

I got the original demo with MPU6050 running on Lolin ESP32 with OLED.

Only this minimal set of changes is needed compared to github:

$ diff Rotatey_Balls.ino sketch_oct13a/sketch_oct13a.ino 
18,19c18,19
< int sdaPin = 21;
< int sclPin = 22;
---
> int sdaPin = 5;
> int sclPin = 4;
$ 
$ diff mpu6050rotatey.h sketch_oct13a/mpu6050rotatey.h 
42c42
<   Wire.begin(21, 22);
---
>   Wire.begin(sda, scl);
$

Connections:

6050  Lolin ESP32
VCC   3V3
GND   GND
SCL   4
SDA   5
XDA   nc
XCL   nc
AD0   nc
INT   14

Short youtube video:

P.S.
I2cScanner from Arduino playground is helpful, for Lolin ESP32 this is the only change needed:

$ diff i2c_scanner.ino sketch_oct13b/sketch_oct13b.ino 
35c35
<   Wire.begin();
---
>   Wire.begin(5,4);
$

The scanner detects the OLED (0x3C) as well as MPU6050 (0x68):

⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
I2C Scanner
Scanning...
I2C device found at address 0x3C  !
I2C device found at address 0x68  !
done

Scanning...
...

P.P.S.
The same diff makes short MPU6050 example from Arduino Playground work:

$ diff mpu6050_test.ino sketch_oct13c/sketch_oct13c.ino 
9c9
<   Wire.begin();
---
>   Wire.begin(5,4);
$

I use http://bitlash.net/ as debug shell for my other Arduinos (for Raspberry Pi Zero I use my Android as Terminal Smartphone as terminal for Pi Zero(!) - Raspberry Pi Forums for bash shell).

Because bitlash works for AVR processors only, it is not an option for ESP32.
I was guided to the solution for ESP32 debug shell on esp32.org forum.
Micropython allows to read/write GPIO pins, set direction and even access OLED with few commands:
Micropython as debug shell for ESP32 (and its OLED) - ESP32 Forum

Micropython can be flashed with two esptool.py commands, and easily used with "screen /dev/ttyUSB0 115200". Of course I will do normal programming of the ESP32 module with Arduino IDE -- I will use Micropython for debugging only, eg. after soldering.

P.S:
I just learned how Arduino IDE Blink Example sketch looks like in Micropython:

import machine, time
pin12 = machine.Pin(12, machine.Pin.OUT)
while True:
    pin12.value(1)
    time.sleep(1)
    pin12.value(0)
    time.sleep(1)

I got help and made much progress, now it is easily possible to debug+dev the ESP32 board mobile wireless in Android JuiceSSH telnet session (who needs a laptop for that?). Details can be found in this posting, the MicroPython version I used is attached to that posting:

MicroPython is cool on its own (I was able to let boot.py connect to Android AP, start Telnet and FTP server, and do initial OLED screen). Especially it allows you to start jobs on both of the ESP32 240MHz cores.

Currently I will continue to program that module via Arduino IDE though. Only if I need a (wireless) debug session (eg. after soldering) I will flash that MicroPython in between for debugging.

Hermann.

OK, now I want to use the ESP32 module to control 12V motors and soldered male headers to the module.

Without any change I powered the module, and the boot display from last posting appeared.
Next I enabled wireless hotspot on my Android, and after 2 seconds the ESP32 was shown as connected.
Next I connected to the wireless Android AP from my laptop and did "telnet 192.168.43.128" into the ESP32 (I got the ESP32 IP address from Android as described here):

$ telnet 192.168.43.128
Trying 192.168.43.128...
Connected to 192.168.43.128.
Escape character is '^]'.
MicroPython ESP32_LoBo_v2.0.8 - 2017-11-04 on ESP32 board with ESP32
Login as: micro
Password: 
Login succeeded!
Type "help()" for more information.

>>>

After having verified voltages on 5V, GND and 3V3 pins I skipped RX/TX and connected to pin 15.
This simple code verified that I did solder pin 15 correctly:

>>> pin = machine.Pin(15, machine.Pin.OUT)
>>> pin.value(0)
>>> pin.value(1)

Next I need to find out how to verify the non-number pins.

Since analogWrite() is not available on the module's Arduino IDE I will have have to use LEDC for 16 channel PWM:

But I want to find out how to test PWM from MicroPython as well.

On the robot I wanted to power the ESP32 from a Lipo different to the 1000mAh 25C 3S Lipo used to power the motors. So I tried a 3.8V loaded Lipo with male micro connector I soldered for Raspberry PIs with this 0.36$ USB-5-P-Port-Male-Plug-Socket-Connector:
https://www.aliexpress.com/wholesale?SearchText=Right+Angle+Micro+USB+5+P+Port+Male+Plug

While even 3.4V from Lipo are enough to power a Pi Zero, 3.8V did not make Lolin ESP32 module boot.

So I remembered that I have a Polulu 5V step-up converter

and decided to create a female/male micro USB plugin between ESP32 module and Lipo micro USB connector I already had. And it works, from the 5.09V generated by step up converter when not connected to ESP32 module I can measure 4.77V between GND and 5V pins of ESP32 module when connected as in this photo:

P.S:
Lolin ESP32 module found new home as wireless motor control for testing new steering omni wheel robot:

I did connect two unidirectional MOSFETs that were mounted on robot already to the three 1500rpm gear motors (two back wheels are controlled from same MOSFET). I could have used the Lipo for powering the ESP32 module, but for testing cable was fine for me.

This is wireless test start (robot is jacked on Lego platform):

Login succeeded!
Type "help()" for more information.

>>> p12 = machine.Pin(12); pwm12 = machine.PWM(p12); pwm12.duty(0)
>>> p13 = machine.Pin(13); pwm13 = machine.PWM(p13); pwm13.duty(0)
>>> pwm12.duty(512)
>>> pwm12.duty(0)

Unidirectional motor controller is OK for two back wheels, but steering wheel motor will need a bidirectional controller:

P.S:
This robot already has weight 533g, and Raspberry Pi Zero with camera for high framerate (≥180fps) video processing is yet missing ...

P.P.S:
"So this is kind of another level of debugging, not single pins anymore, but motor functionality."

I wanted to use a (Bluetooth) BLE remote gamepad to controll the robot ESP32 module:

But I found out that (Bluetooth) BLE support is unlikely to be available in ESP32 MicroPython or ESP32 Arduino IDE in the near future.

Then I wanted to use the other ESP32+Oled module I had to connect an Arduino joystick and send telnet commands to the MicroPython on robot ESP32 module in order to be able to remotely control the robot. But this time my soldering was bad and I killed the 2nd ESP32 module :frowning: Immediately after that I did order 2 new ESP32+Oled modules with free shipping for <10$ each from banggood.com (because there shipping time is only 7-20 days).

Next I remembered that I do have two Wemos D1 modules (ESP8266 in Arduino Uno form factor):

While waiting for the new ESP32+Oleds modules I decided to give the D1 modules a try (did cost 6.50$ with free shipping two years ago, now 3.50$). Most important thing I had to remember was to use "D5" in sketch instead of "5" for Arduino pin D5 ...

First I installed a temperature and humidity sensor in a location of interest in our house and connected to a D1 module over 3m of three thin cables. I only modified one function of "Examples->ESP8266WebServer->HelloServer" and used DHT11 library for the sensor:

void handleRoot() {
  digitalWrite(led, 1);
  String message = "<head><meta http-equiv='refresh' content='5'></head>DHT11, \t";
  int chk = DHT.read11(DHT11_PIN);
  switch (chk)
  {
    case DHTLIB_OK:  
    message += "OK,\t"; 
    break;
    case DHTLIB_ERROR_CHECKSUM: 
    message += "Checksum error,\t"; 
    break;
    case DHTLIB_ERROR_TIMEOUT: 
    message += "Time out error,\t"; 
    break;
    default: 
    message += "Unknown error,\t"; 
    break;
  }
  // DISPLAY DATA
  message += String(DHT.humidity);
  message += "% r.F.\t";
  message += String(DHT.temperature);
  message += "&deg;C [" + String(millis()) + "]";
  server.send(200, "text/html", message);
  digitalWrite(led, 0);
}

Surprisingly easy, now I have my 1st IOT device in our house, and it refreshes every 5 seconds in browser:
DHT11, OK, 66.00% r.F. 18.90°C [16381020]

(r.F. is German for r.H. or relative humidity).

Now I try to get "Examples->Ethernet(esp8266)->TelnetClient" to connect to robot ESP32 module wirelessly for robot remote control.

Bad news first on the steering omni wheel robot. I played with telnet commands "right()" and "sbrake()" with maximal speed "pwmb.duty(1023)". While the robot turned quite fast on carpet, I tried on floor tiles and the results was really bad. Turning on floor tile without moving forward just does not work well (unclear whether it is as bad with moving forward).

Then I tried to run robot "blind" across big free space in our living room. And that with maximal forward speed, timed and with full brake after one second:

pwma.duty(1023)
forward();  time.sleep(1); brake();

Braking distance was something in 5-15cm range only. And the robot had to accelerate from stand still. Despite that the robot moved 10 tiles forward and 4 tiles to the right, with 31.5cm tile lenght. This demonstrated an average robot forward speed of 3.4m/s of >12km/h already!!

$ bc -ql
sqrt(10^2+4^2)*0.315
3.39265382849473753968
sqrt(10^2+4^2)*0.315*3.6
12.21355378258105514284

All three motors are 12V 1500rpm gear motors, back wheel diameter is 65mm ➫ in theory 5.10m/s maximal robot forward speed:

$ echo "pi=4*a(1); 1500/60*pi*0.065" | bc -ql
5.10508806208341401246
$

I got some of these a while back, and keep one on my keychain as a ssid scanner, here's my code:

I recently bought and recieved a Wemos Lolin32 OLED Module board. It took me a lot of effort to put the little online documentation together but I got it all working.

Now it runs a little webserver with DS18B20 temperature server. It displays the startup proces on the display and at the end of the startup proces it displayes the associated accespoint and IP-adres. On the little internal website I got the ability to read the temperature and operate the attached red power-led and green activity-led.

In the future I want to add UI cards with the temperature, access point, IP-adres, digital clock and analog clock.

While searching for information about the board I discovered this topic. It is nice to see the information about the board and DIY projects of others.

This pos got my attention:

mikerr:
I got some of these a while back, and keep one on my keychain as a ssid scanner, here's my code:

GitHub - mikerr/arduino-oled: Arduino / esp8266 code using an 128x64 0.96" OLED module

These sketches seems to be very usefull. Thank you for sharing! I definately will try them sometime!

One last thing: can anyone tell me whether it is possible to connect one or more buttons to this board? And if so: does the board have internal pullup or pulldown resistors? If not: what would be the steps to do this by my self.
At the moment I only have a little experience with a Teensy 2.0 which has internal pullups resistors and a nice Bounce library to nicely interact with momentary push buttons.