Fab Academy 8

Embeded Programing


For this project I´m using a NodeMCU development boardwith an integrated ESP8266 chip that comes with integrated WIFi and Bluethoot module antena. From the datasheet, I will highlight some things that I find usefull to me (or that I understand).

• Integrated TCP/IP protocol stack

• Supports antenna diversity

• WiFi 2.4 GHz, support WPA/WPA2

• Support STA/AP/STA+AP operation modes

• Support Smart Link Function for both Android and iOS devices

• Operating temperature range -40C ~ 125C

• Dual and single antenna Bluetooth co-existence support with optional simultaneous receive (WiFi/Bluetooth) capability.


(Datasheet Abstract)

3.1.1. General Purpose Input/Output Interface (GPIO)

There are up to 17 GPIO pins. They can be assigned to various functions by the firmware. Each GPIO can be configured with internal pull-up (except XPD_DCDC, which is configured with internal pulldown), input available for sampling by a software register, input triggering an edge or level CPU interrupt, input triggering a level wakeup interrupt, open-drain or push-pull output driver, or output source from a software register, or a sigma-delta PWM DAC. These pins are multiplexed with other functions such as I2C, I2S, UART, PWM, IR Remote Control, etc. Data I/O soldering pad is bidirectional and tri-state that include data input and output controlling buffer. Besides, I/O can be set as a specific state and remains like this. For example, if you intend to lower the power consumption of the chip, all data input and output enable signals can be set as remaining low power state. You can transport some specific state into the I/O. When the I/O is not powered by external circuits, the I/O will remain to be the state that it was used the last time. Some positive feedback is generated by the state-remaining function of the pins, therefore, if the external driving power must be stronger than the positive feedback. Even so, the driving power that is needed is within 5uA.

ESP8266 Pinset


ESP8266 12-E Chip Pinout

The ESP12-E NodeMCU Kit is one of the most used ESP8266 development boards. It features 4MB of flash memory, access to 11 GPIO pins, and one analog-to-digital converter (ADC) pin with 10 bit resolution. The board has a built-in voltage regulator and you can power up the module using the mini USB socket or the Vin pin.

Uploading code to the board is as easy as uploading code to the Arduino, there’s no need for an FTDI programmer, as it comes with a usb-to-serial converter built-in.

This is the board we use more often in our Wi-Fi and IoT projects. It is very versatile and it’s great for beginners. So, if this is your first time with the ESP8266, this module is a great choice. Take a look at the links below to find out the ESP8266 12-E NodeMCU kit on your favorite store.


ESP32 has turned into the controller I use most for my projects, since it has the possibility to connect to WiFi and/or Bluetooth, but it also has many ADC pins, which gives you more analog inputs/outputs why I think it works great for IoT devices. 

In my project POWAR, I run all the code on an ESP32, and I added a captive portal so that people can connect to a WiFi network, open it and set the username and password of the WIFi on POWAR so it can connect to the internet.

One of the things to keep in mind when using ESP32 is that you would need to add a library, and that not al the command work exactly like with the arduino, for example, it does not come with Analog Write function.

There is a pretty good documentation from Studiopieters where I took all the GPIO and pinouts information.


not all GPIOs are accessible in all development boards, but each specific GPIO works in the same way regardless of the development board you’re using. If you’re just getting started with the ESP32, we recommend reading our blog: Getting Started with the ESP32 Development Board.

At the moment, there are a wide variety of development boards with the ESP8266 chip that differ in the number of accessible GPIO’s, size, form factor, etc… There are several Development boards Like a 36 pin development board and a ESP32-Pico-Kit and several others. I don’t treat them all here, but you van use the pin definitions here as reference.


ESP32 Peripherals:

- 18 Analog-to-Digital Converter (ADC) channels
- 3 SPI interfaces
- 3 UART interfaces
- 2 I2C interfaces
- 16 PWM output channels
- 2 Digital-to-Analog Converters (DAC)
- 2 I2S interfaces
- 10 Capacitive sensing GPIOs

The ADC (Analog to Digital Converter) and DAC (Digital to Analog Converter) features are assigned to specific static pins. However, you can decide which pins are UART, I2C, SPI, PWM, etc – you just need to assign them in the code. This is possible due to the ESP32 chip’s multiplexing feature.

GPIO Input Output Notes:

0                         pulled up OK outputs PWM signal at boot
1                         TX Pin OK debug output at boot
2     OK     OK     connected to on-board LED
3     OK     RX     Pin HIGH at boot
4     OK     OK 
5     OK     OK     outputs PWM signal at boot
     X     X        connected to the integrated SPI flash
7       X     X        connected to the integrated SPI flash
8       X     X         connected to the integrated SPI flash connected to the integrated SPI flash
9      X     X         connected to the integrated SPI flash
10    X     X         connected to the integrated SPI flash
11     X     X         connected to the integrated SPI flash
12    OK   OK 
13    OK   OK     outputs PWM signal at boot
14    OK   OK     outputs PWM signal at boot
15    OK   OK 
16    OK   OK 
17    OK   OK 
18    OK   OK 
19    OK   OK 
20   OK   OK 
21    OK   OK 
22   OK   OK 
23   OK   OK 
24   OK   OK 
25   OK   OK 
26   OK   OK 
27   OK   OK 
28   OK   OK 
29   OK   OK 
30   OK   OK 
31    OK   OK 
32   OK   OK 
33   OK   OK 
34   OK  
35   OK  
36   OK   input only
37   OK    input only
38  OK    input only
39  OK    input only



Input only pins
GPIOs 34 to 39 are GPIs – input only pins. These pins don’t have internal pull-ups or pull-down resistors. They can’t be used as outputs, so use these pins only as inputs:


SPI flash integrated on the ESP-WROOM-32
GPIO 6 to GPIO 11 are exposed in some ESP32 development boards. However, these pins are connected to the integrated SPI flash on the ESP-WROOM-32 chip and are not recommended for other uses. So, don’t use these pins in your projects!


Capacitive touch GPIOs
The ESP32 has 10 internal capacitive touch sensors. These can sense variations in anything that holds an electrical charge, like the human skin. So they can detect variations induced when touching the GPIOs with a finger. These pins can be easily integrated into capacitive pads, and replace mechanical buttons. The capacitive touch pins can also be used to wake up the ESP32 from deep sleep.

Those internal touch sensors are connected to these GPIO’s.

T0 (GPIO 4)
T1 (GPIO 0)
T2 (GPIO 2)
T3 (GPIO 15)
T4 (GPIO 13)
T5 (GPIO 12)
T6 (GPIO 14)
T7 (GPIO 27)
T8 (GPIO 33)
T9 (GPIO 32)

Analog to Digital Converter (ADC)
The ESP32 has 18 x 12 bits ADC input channels (while the ESP8266 only has 1x 10 bits ADC). These are the GPIOs that can be used as ADC and respective channels.

ADC1_CH0 (GPIO 36)
ADC1_CH1 (GPIO 37)
ADC1_CH2 (GPIO 38)
ADC1_CH3 (GPIO 39)
ADC1_CH4 (GPIO 32)
ADC1_CH5 (GPIO 33)
ADC1_CH6 (GPIO 34)
ADC1_CH7 (GPIO 35)
ADC2_CH3 (GPIO 15)
ADC2_CH4 (GPIO 13)
ADC2_CH5 (GPIO 12)
ADC2_CH6 (GPIO 14)
ADC2_CH7 (GPIO 27)
ADC2_CH8 (GPIO 25)
ADC2_CH9 (GPIO 26)

How to use the ESP32 ADC pins
Note: ADC2 pins cannot be used when Wi-Fi is used. So, if you’re using Wi-Fi and you’re having trouble getting the value from an ADC2 GPIO, you may consider using an ADC1 GPIO instead, that should solve your problem.

The ADC input channels have a 12 bit resolution.
This means that you can get analog readings ranging from 0 to 4095, in which 0 corresponds to 0V and 4095 to 3.3V. You also have the ability to set the resolution of your channels on the code, as well as the ADC range.

The ESP32 ADC pins don’t have a linear behavior.
You’ll probably won’t be able to distinguish between 0 and 0.1V, or between 3.2 and 3.3V. You need to keep that in mind when using the ADC pins.

Digital to Analog Converter (DAC)
There are 2 x 8 bits DAC channels on the ESP32 to convert digital signals into analog voltage signal outputs. These are the DAC channels.


There is RTC GPIO support on the ESP32.
The GPIOs routed to the RTC low-power subsystem can be used when the ESP32 is in deep sleep. These RTC GPIOs can be used to wake up the ESP32 from deep sleep when the Ultra Low Power (ULP) co-processor is running. The following GPIOs can be used as an external wake up source.


The ESP32 LED PWM controller has 16 independent channels that can be configured to generate PWM signals with different properties. All pins that can act as outputs can be used as PWM pins (GPIOs 34 to 39 can’t generate PWM).

To set a PWM signal, you need to define these parameters in the code:

Signal’s frequency;
Duty cycle;
PWM channel;
GPIO where you want to output the signal.
The ESP32 has two I2C channels and any pin can be set as SDA or SCL.

The default I2C pins are:

By default, the pin mapping for SPI is:


All GPIOs can be configured as interrupts.

Strapping Pins
The ESP32 chip has the following strapping pins:

GPIO 5 (must be HIGH during boot)
GPIO 12 (must be LOW during boot)
GPIO 15 (must be HIGH during boot)
These are used to put the ESP32 into bootloader or flashing mode. On most development boards with built-in USB/Serial, you don’t need to worry about the state of these pins. The board puts the pins in the right state for flashing or boot mode.

However, if you have peripherals connected to those pins, you may have trouble trying to upload new code, flashing the ESP32 with new firmware or resetting the board. If you have some peripherals connected to the strapping pins and you are getting trouble uploading code or flashing the ESP32, it may be because those peripherals are preventing the ESP32 to enter the right mode. After resetting, flashing, or booting, those pins work as expected.

Pins HIGH at Boot
Some GPIO’s change its state to HIGH or output PWM signals at boot or reset. This means that if you have outputs connected to these GPIOs you may get unexpected results when the ESP32 resets or boots.

GPIO 6 to GPIO 11 (connected to the ESP32 integrated SPI flash memory – not recommended to use).

Installing ESP32
and 8266 Library
in Arduino IDE:

In your Arduino IDE, go to File> Preferences

Enter into the “Additional Board Manager URLs” field as shown in the figure below.

https://dl.espressif.com/dl/package_esp32_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.json

 Then, click the “OK” button:


Open the Boards Manager. Go to Tools > Board > Boards Manager…

Search for ESP32 and press install button for the “ESP32 by Espressif Systems“ and the ESP8266:

ESP32 and ESP8266 Add-on in Arduino IDE Windows, Mac OS X, Linux Installed

That’s it. It should be installed after a few seconds.


AVR and AtTiny:

AVR is a family of microcontrollers developed since 1996 by Atmel, acquired by Microchip Technology in 2016. These are modified Harvard architecture 8-bit RISC single-chip microcontrollers. AVR was one of the first microcontroller families to use on-chip flash memory for program storage, as opposed to one-time programmable ROM, EPROM, or EEPROM used by other microcontrollers at the time.

AVR microcontrollers find many applications as embedded systems. They are especially common in hobbyist and educational embedded applications, popularized by their inclusion in many of the Arduino line of open hardware development boards.

Atmel says that the name AVR is not an acronym and does not stand for anything in particular. The creators of the AVR give no definitive answer as to what the term "AVR" stands for.[3] However, it is commonly accepted that AVR stands for Alf and Vegard's RISC processor.[4] Note that the use of "AVR" in this article generally refers to the 8-bit RISC line of Atmel AVR microcontrollers.


Flash (program memory): 16384 bytes
EEPROM: 256 bytes
RAM: 2048 bytes
General-purpose I/O Pins: 12 (11 usable)
Digital pins: 2
ADC pins: 9 usable pins (pins marked with green color except for pin PA0). These pins must be used to read analog sensors.
PWM pins: 5 pins (pins marked with orange color and a ~ sign). These pins must be used to write PWM signals.
DAC: Yes
Serial communication: UART, SPI, I2C
Programming: UPDI
Working voltage: 1.8 - 5.5V

In order to access the I/O pins and their various functions from within our code, we need to read from/write to I/O registers of the chip. The programmer uses I/O registers to provide interfaces to the I/O peripherals of the micro-controller. Generally, registers are pins, and for each pin, there is a Data register (PORTx), a Data direction register (DDRx), and a Port input register (PINn). DDRx registers configure pins as INPUT (0) or OUTPUT (1). PINx registers store a value that can be read from the register in case it is defined as INPUT. PORTx registers write the value to pins as HIGH (1) or LOW (0). Each I/O register has a name (used by high-level language/C programmer); I/O address and an SRAM address (used in low-level assembly language).

A summary of ATtiny1614's I/O pins and how to use them:

GND: ground
VCC: power supply
PA0 - UDPI/RESET: programming (UPDI interface) & reset pin
PA6 - DAC: digital to analog converter
PA5 - VREF: the voltage reference pin used to enhance the accuracy of analog reading/writing. This pin acts as a very precise analog 'meter stick' against which the incoming analog signal is compared (as in an ADC) or the outgoing analog signal is generated (DAC).

PA1, PA2, PA3, PA4 - MOSI, MISO, SCK, SS: Master Out Slave In, Master In Slave Out, Serial Clock and Slave Select logic signals in SPI serial communication.

PB0, PB1 - SCL, SDA:
Serial Clock and Serial Data lines in I2C serial communication. PA1 and PA2 can also be used for the same purpose.

PB2, PB3 - RXD, TXD:
Receive and Transmit functions in UART serial communication. PA1 and PA2 can also be used for the same purpose.
In the case of ATtiny1614, pin names are of type Pxn, with x being the PORT instance (A, B) and n the pin number. Notation for signals is PORTx, DDRx, and PINn. The numbers 0-10 (marked with orange and blue colors) can also be used while programming in order to indicate the pins we want to refer to.


AtTinny Program
with Arduino:

This information is taken from 42Bots article:
"Programming ATtiny84 / ATTiny44 with Arduino Uno"

1 - Add an ATTiny support (core) to the Arduino Uno IDE in the board manager section.
2 - Configure the Arduino Uno to act as an a ATTiny programmer.
3 - Wire the ATTiny84 / ATTiny85 to the Arduino Uno as shown in the schematics.
4 - Upload the Blink Sketch and make sure everything works correctly.
5 - Set up the ATTiny84 to work at 8Mhz for better compatibility with Arduino Libraries..

Connect a 10 uF capacitor between “Reset” and “Ground” pins on the Arduino Uno board as shown in the diagram. The stripe of the capacitor with the negative sign (“-”) goes to the Arduino “Ground” pin. This prevents the Arduino Uno from resetting and ensures that the Arduino IDE talks to the ArduinoISP (and not the bootloader) during the upload of the sketches to the ATTiny.

Connect the ATtiny84/44 Pin 1 (with the little dot) to the 5 volt breadboard rail.

Connect the ATtiny84/44 Pin 14 to ground.

Connect the ATtiny84/44 Pin 4 (Reset) to Arduino Pin 10.

Connect the ATtiny84/44 Pin 7 to Arduino Pin 11.

Connect the ATtiny84/44 Pin 8 to Arduino Pin 12.

Connect the ATTiny84/44 Pin 9 to Arduino Pin 13

Connect the ground and 5v from the Arduino to the breadboard.

Make sure you select the option “ATTiny84 (internal 1 MHz clock)”, or “ATTiny44 (internal 1 MHz clock)” in the Tools->Board menu (depending on which version of the chip you have).

For the led blink example, keep on mind that you will need to define the led pin.


This is the schematics and the BOM I used for both projects, but since Fritzing doesn´t has NodeMCU in the library, I used a Arduino UNO to show it.

LED BLINK (PlatformIO):

To make the LED BLINK, I started with the basic arduino blink predefined code and the modified it so it makes 3 leds blink with different timings, reducing the time each time untill they all turn on at the same time.

I first did it in the Arduino IDE, but I´m going to show the process in PlatformIO, and with the NodeMCU instead of the Arduino UNO.

At the begining I didn´t know where exactly to write the code, because the software opens in the platformio.ini file, which looks like a normal code file, but it seems to be the main initialization file, but then I sicovered that you have to writte it in the main.ccp file, which actualy you can rename as you wish.

INITIAL CODE:     Arduino Blink Integrated Code.

ESP8266 12-E Chip Pinout


In that platformio.ini you have to declare the enviroment, the platform, the board and the framework like this:

    platform = espressif8266
    board = nodemcuv2
    framework = arduino

The software does it automaticaly when you create a new project and define this settings, but if you are going to add some addition external libraries you will also have to declare them here, I´ll explain a bout this in the Breathe example.

ESP8266 12-E Chip Pinout

Include Arduino Library:

Another important thing is that if you want to code it with the same arduino language, you have to call the Arduino library in the beggining of the code:

    #include <Arduino.h>

If you don´t call the library, it won´t recognize a lot of things in your code like Delay, Output, PinMode, etc.

Another thing that might be confusing between the Uno and the NodeMCU, is how they call the pins in the code, because they have three diferent numbers: GPIO(#), The reserved number in grey and a diferent number drawn on the board with a letter. So the number you should use is the number on the board with the letter. So in my case it would be        

    D8 (16 - GPIO15)

    D6 (6 - GPIO12) 

     D5 (5 - GPIO14)


Blinking a LED with Millis, gives you the benefit of not making the chip processor using a Delay code and eaiting for it to happen, but instead he sets a star of LOw or HIGH to the led, deppending on a time you assign. This means that te codeo will check the clock agin in each loop, and when is the same than the time you coded, then the LED will change.

Basicly it says: If the LED is ON, and the Current Time, minus the Starting Time (0) is bigger or equal to the designed OnTime, then turn LED OFF, and reset the current time to be 0. And the proces starts again but now to turn it off with the designated time you choose.

          if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
            ledState = LOW; // Turn it off
            previousMillis = currentMillis; // Remember the time
            digitalWrite(ledPin, ledState); // Update the actual LED
          else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
            ledState = HIGH; // turn it on
            previousMillis = currentMillis; // Remember the time
            digitalWrite(ledPin, ledState); // Update the actual LED

The tutotial goes untill lighting 2 leds with millis, yo I changed the code to work with a third led and added it.


To make the LED BREATH assignment, I followed some of the instructions of the Jled Library from the GitLab repo, and after trying the different combinations (Candle, Blink, Static, Breath, Fade, etc). The ones I liked most where the ones with multiple leds, so I keept my conection with 3 leds, and used the multiles.ino code and modified it a bit. This one mixes the Breath, Fade and Blink codes in one. It also uses the internal led as a fourth led.

Since we are using a library that is not part of the arduino, we need to add jled to our library dependencies in our platformio.ini project file like this:

        platform = espressif8266
        board = nodemcuv2
        framework = arduino
        lib_deps = jled

This is needed for the líbrary to load when you call it in your CCP code file.

Another important thing I realized, is that the breath effect and others, only work in PWM (Pulse Width Modulation) pins, which in case of the NodeMCU are D2, D5, D6 and D8. I have read that through software, you can also convert all the digital pins into PWM, but I´m not sure how to do it yet. This was interesting to me, because I have never understood what that really means untill now, and I also discovered that in the pinnout graphics they usually paint it with an ondulated line. I also dicovered that the UNO has painted lines near the numers in the PWM pins. I´m going to copy the Wikipedia description, just to remind in the future what they are.

        Pulse-width modulation:
        Pulse width modulation, or pulse-duration modulation, is a method of         reducing the average         power delivered by an electrical signal, by         effectively chopping it up into discrete parts. The         average value of         voltage fed to the load is controlled by turning the switch between supply         and load on and off at a fast rate.

This JLED Library was really usefull to do nicer things with less code, I could even do the same I did with the blinks, but with much less code.

Flashing MicroPython with RaspberryPi3

Another thing that was interesting to me was to be able to Flash the NodeMCU with Micropython with a RasperryPI3 thourgh terminal, but I think I´ll document that in networks.

pip install esptool

esptool.py --port /dev/ttyUSB0 erase_flash

esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash -- flash_size=detect 0 esp8266-20170108-v1.8.7.bin (this correspondes to the version you donwloaded)

esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect -fm dio 0 esp8266-20170108-v1.8.7.bin (this correspondes to the version you donwloaded)


web page was built with Mobirise site templates