last updated: 2022-11-11
From this link: https://arduino-esp8266.readthedocs.io/en/3.0.2/:
NOTE: The default analogWrite range was 1023 in releases before 3.0, but this lead to incompatibility with external libraries which depended on the Arduino core default of 256. Existing applications which rely on the prior 1023 value may add a call to analogWriteRange(1023) to their setup() routine to return to their old behaviour.
Newer Wemos D1 mini pro boards V1.1 from China have a CH9102F
IC instead of the old CP2104
for USB to serial bridge. You have to add the following line to your udev file in linux:
# Wemos D1 mini pro with CH9102
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", GROUP="plugdev", MODE="0666"
Now we get a serial port (but ttyACM
instead of ttyUSB
!).
But the chip can not be programmed in Arduino because GPIO0
is not properly pulled down by RTS
(more infos: http://weigu.lu/microcontroller/esp_programmer/index.html) as the following oscilloscope screen shows (right image, blue signal):
In the left image we see the signal as it should be. A workaround is to connect GPIO0
(D3
) shortly to GND
while programming with Arduino (thanks Daniel :)).
I found the culprit. If I'm not mistaken, they soldered a dual transistor SOT363 from LRC (MUN531DW1T1, marking 12) with a 22 k resistor between emitter and base (measured) and a 22 k resistor to the base. The original UMH3N from Rohm (right picture, marking H3) have only a 4.7 k to the base. These transistors are needed to tie down GPIO0
to GND
.
I de-soldered an UMH3N from a bricked Wemos and exchanged the chips. This solved the problem!
Connect GPIO0
(IO0
) shortly to GND
, just after the programming in Arduino starts.
As this is tedious if you have to program your chip multiple times, here a little helper program. Connect pin 33
of a a working ESP32 to GPIO0
(D3
, IO0
) of your ESP32 or ESP8266 with the false dual transistor chip, and interconnect the two grounds. Start the helper program and after this the programming of the problematic chip. The program detects the begin of the programming and pulls GPIO0
to GND
at the needed moment for the needed time.
/* workaround_no_UHM3N.ino
* weigu.lu
* connect ESP32 pin 33 or Uno pin A0 to GPIO0 (D3 or IO0) and
* GND ESP32 (Uno) to GND ESP32 or ESP8266 with false chip
*/
const byte PIN = A0; //Arduino Uno A0, ESP32 GPIO 33
const unsigned int THRESHOLD = 500; // 500 for Uno 3500 for ESP32
unsigned int GPIO0_VALUE;
void setup() {
Serial.begin(115200);
}
void loop() {
GPIO0_VALUE = analogRead(PIN);
while (GPIO0_VALUE > THRESHOLD) {
GPIO0_VALUE = analogRead(PIN);
Serial.println(GPIO0_VALUE);
}
delay(20);
GPIO0_VALUE = analogRead(PIN);
while (GPIO0_VALUE > THRESHOLD) {
GPIO0_VALUE = analogRead(PIN);
Serial.println(GPIO0_VALUE);
}
Serial.println("Tie it to GND");
pinMode(PIN,OUTPUT);
delayMicroseconds(20);
digitalWrite(PIN,LOW);
delay(20);
pinMode(PIN,INPUT);
delay(10000);
Serial.println("Do it again");
}
Copy the following line:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
to "File > Preferences > Additional Boards Manager URLs:
".
Go to "Tools > Board:".." > Boards Manager...
" and scroll down. Then click install
.
In Linux you have to use udev rules! if you don't want to work as root. See here
It is important to use the right pins, to avoid conflicts. A really good tutorial can be found here: https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/.
On the V1.1 boards the 5 V pin should be considered as an output pin, because it's powered through a diode from VBUS (5 V from USB). The diode prevents destroying the USB host if a higher voltage is applied, but reduces the voltage to 4.7 V.
If you want to power the chip from this pin it's better to bypass the diode with a wire, because reboot is not always functioning. Another possibility is to unsolder the diode and short circuit the pins.
On the newer V2.0 boards (green) there is no diode but a 0.5 A fuse, so there should be no problem.
The wifi password must be 8 or more for the Access Point to work (WiFi.softAP(ssid, password) function)! To be shure check the return value :).
Hardware serial (opened with Serial.begin(9600)
) on Wemos D1 mini pro uses UART0 of ESP8266, which is mapped to pins TX (GPIO1) and RX (GPIO3).
Serial1 (opened with Serial1.begin(115200)
) uses UART1 which is a transmit-only UART. UART1 TX pin is D4 (GPIO2, LED!!).
If you use serial (UART0) to communicate with hardware, you can't use the Arduino Serial Monitor at the same time to debug your program! The best way to debug is to use Serial1.println()
and connect RX of an USB2Serial adapter (FTDI, Profilic, CP210, ch340/341) to D4
and use a terminal program like CuteCom or CleverTerm to listen to D4
.
Serial (UART0) may be remapped to D8 (TX, GPIO15, 10k Pull-down?) and D7 (RX,GPIO13) by calling Serial.swap(); after Serial.begin();. Calling swap again maps UART0 back to TX and RX.
The SPI Flash Filing System is designed for SPI flash devices on micro-controller systems with little RAM. It uses statically sized ram buffers (independent of number of files), posix-like API (open, close, read, write, ...) and implements static wear leveling to prolong the life of system flash.
SPIFFS uses a flat structure (no directories). Creating a file with path homie/config.json
will create a file called homie/config.json
instead of a config.json
under directory homie
. Write operation might be slow, so it is best used at start up, shut down or when time critical activities are not scheduled.
Here some info on the Wemos boards. Arduino lets you chose the amount of SPIFFS for some boards (newest Arduino and ESP8266 core (2.4!)).
Wemos D1 mini lite v1.0.0 | 1M bytes (0-512kB SPIFFS) |
Wemos D1 mini v3.0 | 4MB FLASH (1MB or 3MB SPIFFs |
Wemos D1 mini pro v1.1.0 | 16MB FLASH (15MB SPIFFS) |
Wemos LOLIN32 Pro v1.0.0 | 4MB FLASH & 4MB PSRAM |
Wemos LOLIN32 lite v1.0.0 | 4MB FLASH |
Wemos LOLIN32 v1.0.0 | 4MB FLASH |
Programming a new sketch will not modify the file system contents. This allows to use file system to store sketch data, configuration files, or content for Web server.
The following diagram illustrates flash layout used in Arduino environment:
|--------------|-------|---------------|--|--|--|--|--|
^ ^ ^ ^ ^
Sketch OTA update File system EEPROM WiFi config (SDK)
The following example sketch CheckFlashConfig.ino
can be found in your core examples (File-Examples-ESP8266-CheckFlashConfig
). You see the size in your serial monitor.
Download the plugin from here and unzip the file. Create a folder ESP8266FS
in the Arduino tools
directory and in this folder a new folder tool
. Copy the esp8266fs.jar
file into the tool
folder (Arduino\tools\ESP8266FS\tool\esp8266fs.jar
). If there is only a .java
file you have to compile it first sudo ./make.sh
. After a restart you find a menu item ESP8266_Sketch_Data_Upload
in the Arduino Tools
menu.
Go to sketch directory Sketch > Show Sketch Folder
and create a directory named data
. Load all your files you want to be in SPIFFS to that folder.
After this make sure you have selected your board, port, and closed the serial monitor.
Select Tools > ESP8266 Sketch Data Upload
. This starts uploading the files into ESP8266 flash file system (be patient; its done when the IDE status bar displays SPIFFS Image Uploaded
).
Here is a code snippet lend from Steve Quinn to read a SPIFFS file (first load up your file (e.g. /homie/config.json) to SPIFFS as described below):
#include <string.h>
#include "FS.h"
bool spiffsActive = false;
#define TESTFILE "/homie/config.json"
void setup() {
Serial.begin(115200);
delay(1000);
if (SPIFFS.begin()) { // Start filing subsystem
Serial.println("SPIFFS Active");
spiffsActive = true;
} else {
Serial.println("Unable to activate SPIFFS");
}
delay(1000);
}
void loop() {
if (spiffsActive) {
if (SPIFFS.exists(TESTFILE)) {
File f = SPIFFS.open(TESTFILE, "r");
if (!f) {
Serial.print("Unable to open ");
Serial.print(TESTFILE);
} else {
String s;
Serial.print("Contents of file ");
Serial.println(TESTFILE);
while (f.position()<f.size()) {
s=f.readStringUntil('\n');
s.trim();
Serial.println(s);
}
f.close();
}
Serial.println();
} else {
Serial.print("Unable to find ");
Serial.println(TESTFILE);
}
}
while (true){
yield();
}
}
More infos here http://www.instructables.com/id/Using-ESP8266-SPIFFS/ and here http://esp8266.github.io/Arduino/versions/2.3.0/doc/filesystem.html
Wee need the python esp tools for this. You find them in /packages/esp8266/hardware/esp8266/2.5.2/tools/esptool/
. With the following command we read the flash:
sudo python ./esptool.py -p /dev/ttyUSB0 -b 460800 read_flash 0 0x400000 flash_contents.img
The parameter are the port (-p
), the bitrate (-b
), the beginning and ending address and the name of the file. esptool
Uploading to the ESP8266 is done with:
sudo python ./esptool.py -p /dev/ttyUSB0 -b 460800 write_flash -fm qio 0x00000 flash_contents.img
After this we need to reset the chip. We specified the flash-mode qio (-fm qio
). If this doesn't work, try the dout method instead (-fm dout
).
After uploading a sketch using WiFi your SSID and Wifi password are stored in cleartext in the flash. So it's a good idea to erase the flash if you want to give the board to other persons.
sudo python ./esptool.py -p COM5 erase_flash
To connect an external antenna you have to unsolder the 0Ω resistance near the ceramic antenna and resolder it direction the miniature RF connector (U.FL).
Look here.
We need to use the linker attribute ICACHE_RAM_ATTR
for our Interrupt Service Routines. With this attribute we say that the function should be stored in RAM instead in Flash. As the entire flash is used for the program and storage, reading and writing to the flash can be done only over 1 thread. Accessing the flash simultaneously over 2 different threads will crash the ESP and trigger a watchdog reset.
ICACHE_RAM_ATTR void ISR() {
flag = true;
}