Thursday, March 19, 2015

Example: Blink a LED

Like in the Arduino case one of the first thinks to try it is to blink an LED.

The following link contains the code for blink an LED.

Materials:

  • ESP-01 - or other version 
  • LED 
  • SERIAL to USB

If you have my setup described here 

1. put the the archive into this directory

/opt/Espressif/ESP8266_SDK   

2. untar the file

tar -xvf blinky.tar

3. enter in the app directory

cd blinky

4. compile the code

make clean ; make.

5. Upload the resulting files ( from the firmware directory) to your ESP after this steps

5.1 Unplug the VCC power pin
5.2 Connect the GPIO0 pin to ground
5.3.Use the command to write the firmware

./burnESP


Anatomy of the code

 The main application file is the user_main.c file located in 
/opt/Espressif/ESP8266_SDK/blinky/user

The file content is:


#include "ets_sys.h"
#include "osapi.h"
#include "gpio.h"
#include "os_type.h"
#include "user_config.h"

#define user_procTaskPrio        0
#define user_procTaskQueueLen    1
os_event_t    user_procTaskQueue[user_procTaskQueueLen];
static void user_procTask(os_event_t *events);

static volatile os_timer_t some_timer;


void some_timerfunc(void *arg)
{
    //Do blinky stuff
    if (GPIO_REG_READ(GPIO_OUT_ADDRESS) & BIT2)
    {
        //Set GPIO2 to LOW - TURN OFF the LED
        gpio_output_set(0, BIT2, BIT2, 0);
    }
    else
    {
        //Set GPIO2 to HIGH - TURN ON the LED
        gpio_output_set(BIT2, 0, BIT2, 0);
    }
}

//Do nothing function
static void ICACHE_FLASH_ATTR  user_procTask(os_event_t *events)
{
    os_delay_us(10);
}

//Init function 
void ICACHE_FLASH_ATTR user_init()
{
    // Initialize the GPIO subsystem.
    gpio_init();

    //Set GPIO2 to output mode
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);

    //Set GPIO2 low
    gpio_output_set(0, BIT2, BIT2, 0);

    //Disarm timer
    os_timer_disarm(&some_timer);

    //Setup timer
    os_timer_setfn(&some_timer, (os_timer_func_t *)some_timerfunc, NULL);

    //Arm the timer, &some_timer is the pointer 1000 is the fire time in ms
    //0 for once and 1 for repeating timer
    os_timer_arm(&some_timer, 1000, 1);
    
    //Start os task
    system_os_task(user_procTask, user_procTaskPrio,user_procTaskQueue, user_procTaskQueueLen);
}


and is pretty much self explanatory.

1. Include the necessary headers. See that user_config.h is empty so if you can use this app as a skeleton for your future applications. 

2. In user_init() function the GPIO is initialized, GPIO2 is set up as an output pin and is set
to 0 (LOW, GND).

3. A timer is defined (some_timer) and initialized and the  callback function is set to be called every 1000ms (1sec) interval. 

4. Callback function some_timerfunc is doing all the stuff, if the LED is ON turn it to OFF,
otherwise turn the LED ON.


If you want to add extra functionality check this post for how to have arduino like functions
to manipulate your GPIO. 

Happy codding !!! 

9 comments:

  1. I was looking to make my first program of Espressif official sdk, and you helped me a lot. Thanks

    ReplyDelete
  2. Hi,

    interreting post but where have you connected the LED ?

    tkx,
    Domi.

    ReplyDelete
    Replies
    1. LED is connected to the GPIO2.

      Delete
    2. Thanks for your fast answer.
      I have tested a led on GPIO2 (BIT2) and GPIO0 (BIT0), this works fine; any idea why a led connected to other GPIO (ex: GPIO16 [BIT16], GPIO14 [BIT14], GPIO12 [BIT12]) doesn't work ?

      Thanks in advance,
      Domi.

      Delete
    3. Did you modified also the PIN_FUNC_SELECT ?

      Delete
  3. yes, no way, same problem, have change to :

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPI14);

    for a led connected to GPIO14 with all the BIT set to BIT5 (line D5)

    Domi.

    ReplyDelete
  4. Try this:



    /* GPIO | SDK board | */
    /* ----------------------------------*/
    int gpio_pin_register[16] = {PERIPHS_IO_MUX_GPIO0_U, // 0 |
    PERIPHS_IO_MUX_U0TXD_U, // 1 |
    PERIPHS_IO_MUX_GPIO2_U, // 2 |
    PERIPHS_IO_MUX_U0RXD_U, // 3 |
    PERIPHS_IO_MUX_GPIO4_U, // 4 gpio 4 DHT |
    PERIPHS_IO_MUX_GPIO5_U, // 5 gpio 5 buzzer |
    PERIPHS_IO_MUX_SD_CLK_U, // 6 |
    PERIPHS_IO_MUX_SD_DATA0_U, // 7 |
    PERIPHS_IO_MUX_SD_DATA1_U, // 8 |
    PERIPHS_IO_MUX_SD_DATA2_U, // 9 gpio 9 |
    PERIPHS_IO_MUX_SD_DATA3_U, // 10 gpio 10 |
    PERIPHS_IO_MUX_SD_CMD_U, // 11 |
    PERIPHS_IO_MUX_MTDI_U, // 12 gpio12 blue |
    PERIPHS_IO_MUX_MTCK_U, // 13 gpio13 green |
    PERIPHS_IO_MUX_MTMS_U, // 14 gpio14 white |
    PERIPHS_IO_MUX_MTDO_U}; // 15 gpio15 red ??|

    #define GPIO_PIN_ADDR(i) (GPIO_PIN0_ADDRESS + i*4)

    void ICACHE_FLASH_ATTR pinMode(uint8_t pin, uint8_t mode, uint8_t pullup) {
    if ((0x1 << pin) & 0b110101) {
    PIN_FUNC_SELECT(gpio_pin_register[pin], 0); //0,2,4,5
    } else {
    PIN_FUNC_SELECT(gpio_pin_register[pin], 3);
    }
    //PIN_PULLDWN_DIS(gpio_pin_register[pin]);
    if(pullup)
    PIN_PULLUP_EN(gpio_pin_register[pin]);
    else
    PIN_PULLUP_DIS(gpio_pin_register[pin]);
    if (mode) {
    GPIO_REG_WRITE(GPIO_ENABLE_W1TC_ADDRESS, 1<>pin) & 1;
    }



    And use it like this:

    pinMode(14, OUTPUT, 0);
    digitalWrite(14, 1);



    ReplyDelete
  5. void ICACHE_FLASH_ATTR digitalWrite(uint8_t pin, uint8_t state) {
    if (state) {
    GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1<>pin) & 1;
    }

    ReplyDelete
  6. int ICACHE_FLASH_ATTR digitalRead(uint8_t pin) {
    return (GPIO_REG_READ(GPIO_OUT_ADDRESS)>>pin) & 1;
    }

    ReplyDelete