Programming the ESP8266 nodeMCU board

I'm exploring ESP8266 boards
currently using a nodeMCU board

I use Arduino 1.6.12 to program the board
Have installed ESP8266 through menu Tools>>Board>>Board Manager
Then selected board "NodeMCU 1.0 (ESP-12E Module)"

Wrote a simple test example
compiled and uploaded
and it worked :slight_smile:
so what?

As an absolute beginner with the ESP8266 i had done some reading and knew well that
for programming you have to boot with GPIO0 on GND
but this time i forgot :wink:

so why does it work then?

I can repeat it,
take the blink example
WifiScan or others,
upload without pressing the flash button
and it does...

why?

That board uses the DTR and RTS signaling to set the GPIO pins the same as pressing the button would. The upload program toggles the serial in order to properly trigger it.

@evildave_666
thanks a lot for the insight

I try to adapt some Arduino software to the ESP8266
working quite well
very interesting board, really

but I have some questions popping up :wink:

How can a program determine what mode a pin is switched to, INPUT or OUTPUT?
I am prepared to do some bit banging if I have a docu,
pointer welcome

Can I do Serial output in setup() ?
Serial output is working well in loop(), not so in setup().
while (!Serial) { ;} does not help, not even a delay...

more questions to come

I have a few sample NodeMCU/ESP8266 projects on my project page just to get you started with what can be done. No need for UserID to download source code.

Ray's Projects

To answer your serial question:

void setup() { 
 Serial.begin(57600); 
 Serial.printf("\n\nSDK version:%s\n\r", system_get_sdk_version()); 
 Serial.println(F("ESP8266 mini-sniff by Ray Burnette http://www.hackster.io/rayburne/projects"));

thanks mrburnette

so I see my error now:
I was expecting that the serial monitor would do the same magic like it did on many Arduinos
and restart the module when I open it, I was wrong.
Unplugging the chip and then restart the monitor was not fast enough to catch early serial output either.

toggling D2 does the job
or
leaving the serial monitor open while flashing next version (this used to close the monitor once) works fine too

next question:
Currently I am working with a NodeMCU board.

I want to adapt things like pin mapping based on the board type

How can my sketch determine the exact board type?
I use #ifdef ESP8266 but want to know more precisely.

thanks for your help

OutOfLine:
<...>
Currently I am working with a NodeMCU board.

I want to adapt things like pin mapping based on the board type

How can my sketch determine the exact board type?
I use #ifdef ESP8266 but want to know more precisely.

thanks for your help

Ummmmm....
"lethe" from the ESP8266.com forum has these words to say:

You should be able to obtain the flash ID with "esptool.py flash_id" without removing the shield. That command will only give you a hex manufacturer & chip ID, but fortunately the flashrom project maintains an extensive list in their source code:
http://code.coreboot.org/svn/flashrom/t ... ashchips.h

I only prototype on the NodeMCU and may then transfer the software to a 12-E for the final project; therefore I know physically in advance the flash size; to my knowledge, the external flash chip is essentially the only difference in the core ESP8266 device from model -01 through the various NodeMCU.

If you would like to dig a bit deeper into the Arduino Core for the ESP8266, then this reference is for you:
https://links2004.github.io/Arduino/d3/d58/class_e_s_p8266_web_server.html

Ray

OutOfLine:
How can my sketch determine the exact board type?

The Arduino IDE automatically defines a macro for each board selection(ARDUINO_{build.board}). For the esp8266 core they are:

  • Generic ESP8266 Module: ARDUINO_ESP8266_ESP01
  • Generic ESP8285 Module: ARDUINO_ESP8266_ESP01
  • ESPDuino (ESP-13 Module): ARDUINO_ESP8266_ESP13
  • Adafruit HUZZAH ESP8266: ARDUINO_ESP8266_ESP12
  • ESPresso Lite 1.0: ARDUINO_ESP8266_ESPRESSO_LITE_V1
  • ESPresso Lite 2.0: ARDUINO_ESP8266_ESPRESSO_LITE_V2
  • Phoenix 1.0: ARDUINO_ESP8266_PHOENIX_V1
  • Phoenix 2.0: ARDUINO_ESP8266_PHOENIX_V2
  • NodeMCU 0.9 (ESP-12 Module): ARDUINO_ESP8266_NODEMCU
  • NodeMCU 1.0 (ESP-12E Module): ARDUINO_ESP8266_NODEMCU
  • Olimex MOD-WIFI-ESP8266(-DEV): ARDUINO_MOD_WIFI_ESP8266
  • SparkFun ESP8266 Thing: ARDUINO_ESP8266_THING
  • SparkFun ESP8266 Thing Dev: ARDUINO_ESP8266_THING_DEV
  • SweetPea ESP-210: ARDUINO_ESP8266_ESP210
  • WeMos D1 R2 & mini: ARDUINO_ESP8266_WEMOS_D1MINI
  • WeMos D1(Retired): ARDUINO_ESP8266_WEMOS_D1MINI
  • ESPino (ESP-12 Module): ARDUINO_ESP8266_ESP12
  • ThaiEasyElec's ESPino: ARDUINO_ESP8266_ESP13
  • WifInfo ESP07 (1M/192K SPIFFS): ARDUINO_ESP8266_ESP07
  • WifInfo ESP12 (4M/1M SPIFFS): ARDUINO_ESP8266_ESP12
  • Core Development Module: ARDUINO_ESP8266_ESP01

Usually you would want to use a unique macro for each board but apparently the esp8266 core developers have decided to use the same macro for some of the boards that use the same ESP8266 module. Hopefully those boards are similar enough that it won't be a problem.

So you can do things like:

#ifdef ARDUINO_ESP8266_NODEMCU

which will evaluate true if you compiled the sketch for the NodeMCU 0.9 (ESP-12 Module) or NodeMCU 1.0 (ESP-12E Module) boards.

@pert many thanks, exactly the information I was looking for. :slight_smile:
works well

grepping through the source I was not able to find the magic that defines these macros
i have tried to find that before...
pointer very much appreciated :wink:

where/how are they defined?

adapting some of my programs I get the following test output:

Checking for some macros
digitalPinHasPWM	YES
analogInputToDigitalPin	YES
digitalPinToPort	YES
digitalPinToBitMask	YES
digitalPinToTimer	YES

COMPLETELY UNTESTED ON THIS BOARD
pin 0	~           port 0  0000000000000001 	PWM  
pin 1	~ 	     port 0  0000000000000010 	PWM  
pin 2	~           port 0  0000000000000100 	PWM  
pin 3	~           port 0  0000000000001000 	PWM  
pin 4	~  SDA  port 0  0000000000010000 	I2C  PWM  
pin 5	~  SCL  port 0  0000000000100000 	I2C  PWM  
pin 6              port 0  0000000001000000 	
pin 7	             port 0  0000000010000000 	
pin 8              port 0  0000000100000000 	
pin 9              port 0  0000001000000000 	
pin 10            port 0  0000010000000000 	
pin 11            port 0  0000100000000000 	
pin 12 ~  MISO 	port 0  0001000000000000 	SPI  PWM  
pin 13 ~  MOSI 	port 0  0010000000000000 	SPI  PWM  
pin 14 ~  SCK    port 0  0100000000000000 	SPI  PWM  
pin 15 ~  SS      port 0  1000000000000000 	SPI  PWM  
pin 16 ~            port 0  0000000000000000 	PWM

does this look reasonable?
well the forum software ruins all my formatting, but :frowning:

@mrburnette thank you for the reference
looks impressive
will dig deeper when I will work with WiFi

right now I am exploring processor and GPIO
adapting some programs from github.com/reppr/pulses

I have connected 4 piezzos to the ESP8266 and let them play funny sounds
3.3V gives very low level on piezzos, but maybe you can hear it in the attachment :wink:

OutOfLine:
I have connected 4 piezzos to the ESP8266 and let them play funny sounds
3.3V gives very low level on piezzos, but maybe you can hear it in the attachment :wink:

no, you can't
the forum software did not accept the format :wink:

ok, but here is an url https://filebin.net/btx3rnuhwvaap60t

OutOfLine:
grepping through the source I was not able to find the magic that defines these macros
i have tried to find that before...
pointer very much appreciated :wink:

where/how are they defined?

The value of {build.board} is set in boards.txt for each Tools > Board menu entry(Arduino/boards.txt at 2.3.0 · esp8266/Arduino · GitHub):

nodemcu.build.board=ESP8266_NODEMCU

Then {build.board} is appended to ARDUINO_ and passed as a compiler flag to define the macro in platform.txt(Arduino/platform.txt at 2.3.0 · esp8266/Arduino · GitHub):

recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} -DF_CPU={build.f_cpu} {build.lwip_flags} {build.debug_port} {build.debug_level} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_BOARD="{build.board}" {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"

Note that the esp8266 core even defines another macro, ARDUINO_BOARD with the value of {build.board} as a string so you could do something like:

Serial.println("The board name is: " ARDUINO_BOARD);

But that's an extra feature of the esp8266 core, not a standard convention like the ARDUINO_{build.board} macros, which should be defined in any core since it's part of the hardware specification.

@pert thanks a lot for this very helpful summary

I was suspecting the line in boards.txt to be the entry point
now you showed me the whole chain