I’m just about to have a go at one of the larger boards – the ESP12 (or 201)… so can someone save me (and others) re-inventing the wheel.
Here’s what I do to initialise an ESP-01 port bit GPIO0 as an output.
Firstly the setup..
// For GPIO2 just change the 0 to 2 – there is one init line.
#define LED_GPIO 0
#define LED_GPIO_MUX PERIPHS_IO_MUX_GPIO0_U
#define LED_GPIO_FUNC FUNC_GPIO0
then initialisation
and here it is set to 1.
As you can see, I’ve already figured out how to do the same with GPIO2 (though I’ve not used GPIO2 as an output yet)
So – what other pins can we use in exactly the same way and are the numbers as you would expect or different?? This general principle also seems to work for GPO4 and 5 but not for the higher numbers.
Didn’t know where to ask this but surely someone can help here. To test I have a LED connected to GPIO2 on my ESP-1, and I can turn it on/off with MQTT without problems by setting the GPIO2 output mode to 1 after it’s booted.
However, when the ESP-1 (re)boots, putting GPIO2 in HIGH mode puts it in bootloader mode preventing a normal start. Is there a way to get around this, without having to use a 47K resistor or button for example? Prefer not to use those if possible, to keep it as small as possible (and the resistor dims the LED light considerably).
I use the following code in user_main.c:
(header section)
#define LED_GPIO 2
#define LED_GPIO_MUX PERIPHS_IO_MUX_GPIO2_U
#define LED_GPIO_FUNC FUNC_GPIO2
and my “user_init” function starts like this:
void user_init(void)
{
uart_init(BIT_RATE_115200, BIT_RATE_115200);
os_delay_us(1000000);
CFG_Load();
PIN_FUNC_SELECT(LED_GPIO_MUX, LED_GPIO_FUNC);
I’m sure it’s a simple thing
Patrick – surely it is GPIO0 that does that? I get around that by basing any connections on + not -.. so a LED from the port bit via a resistor to + rather than ground.
To build the Eclipse environment I followed these instructions to the letter. http://www.esp8266.com/viewtopic.php?f=9&t=820
I recently over-wrote the relevant directories with the SDK update (including the two patched files).
Importing MQTT for example into this environment works a treat though if you’re starting from scratch you’ll need to ensure you have a .project file.
Actually, i have not tested that library with v0.9.5. I tested a clean sdk 0.9.5 install with one of the basic examples (could have been blinky). It compiled and uploaded just fine but the esp had a infinite crash loop with some message about “MEM CHK FAIL” on the console. So i threw the whole sdk out. I will try upgrading the sdk again once tuanpmt/esp_mqtt upgrades to 0.9.5 or higher.
Hi
I am using the tuanpmt/esp_mqtt with the latest 0.9.5 + patch SDK – worked out of the box.
Pete
I will give 0.9.5 one more try then. Did you build the environment with https://github.com/pfalcon/esp-open-sdk ?
Some time ago i got tired of juggling all these gpio_id, gpio_name and func bits. They made my code very messy and inflexible.
So i wrote this simple helper library: https://github.com/eadf/esp8266_easygpio.
To use it you can just copy/clone the easygpio folder into your project and point to it in the Makefile (modules)
This is great but for the end comment — that the latest SDK breaks it.. have you resolved this? The reason I ask is that the 0.9.5 SDK is the nearest we have to something that does not fall over so really… getting it to work with that SDK is important – I wonder if anyone can help given that you let us know what the problem is?
I’ve found the problem. For the basic test code of my drivers i have no need for WiFi. So i used to set:
wifi_set_opmode(NULL_MODE);
I don’t know if it turned off the wifi chip or not, but it did make the console shut up about networking stuff. This was under 0.9.4.
In 0.9.5 there seems to be a timer starting at wifi_set_opmode(). And it has nothing to do, so it times-out. And time-out on a timer raises an exception that halts the entire system.
This setting seems to be persistent. So if i once flashed code that called wifi_set_opmode(NULL_MODE), it would remain in the chip. Crashing the next program i flash as well. This would go on until a program calls wifi_set_opmode with some of the ‘legal’ values. (STATION_MODE, SOFTAP_MODE, STATIONAP_MODE).
I use two outs, one input, 3pwm’s and adc.
This shows 15 being used but in fact it has to be held low as far as my tests have gone.
I dob’t use gpio0, although I could if I wanted.
#define LED_GPIO_14 14
#define LED_GPIO_MUX_14 PERIPHS_IO_MUX_MTMS_U
#define LED_GPIO_FUNC_14 FUNC_GPIO14
#define LED_GPIO_2 2
#define LED_GPIO_MUX_2 PERIPHS_IO_MUX_GPIO2_U
#define LED_GPIO_FUNC_2 FUNC_GPIO2
#define LED_GPIO_5 5
#define LED_GPIO_MUX_5 PERIPHS_IO_MUX_GPIO5_U
#define LED_GPIO_FUNC_5 FUNC_GPIO5
#define LED_GPIO_15 15
#define LED_GPIO_MUX_15 PERIPHS_IO_MUX_MTDO_U
#define LED_GPIO_FUNC_15 FUNC_GPIO15
++++++++++++
This for adc and no preparation required ….
uint8_t buffer[16];
uint16 adc = system_adc_read();
adc = adc/10;
ets_sprintf( buffer, “%d”, adc );
MQTT_Publish(client, “/echo”, buffer, 3, 0, 0);
This sets up gpio’s ……
PIN_FUNC_SELECT(LED_GPIO_MUX_14, LED_GPIO_FUNC_14);
PIN_FUNC_SELECT(LED_GPIO_MUX_2, LED_GPIO_FUNC_2);
PIN_FUNC_SELECT(LED_GPIO_MUX_5, LED_GPIO_FUNC_5);
PIN_FUNC_SELECT(LED_GPIO_MUX_15, LED_GPIO_FUNC_15);
GPIO_DIS_OUTPUT(5); /* should make input */
PIN_PULLUP_EN(LED_GPIO_MUX_5);
/*GPIO_OUTPUT_SET(LED_GPIO_12, 1); */
GPIO_OUTPUT_SET(LED_GPIO_15, 0);
GPIO_OUTPUT_SET(LED_GPIO_14, 1);
GPIO_OUTPUT_SET(LED_GPIO_2, 1);
This sets up and drives pwm …
servo_param.pwm_freq = 500;
servo_param.pwm_duty[0]=255;
servo_param.pwm_duty[1]=255;
servo_param.pwm_duty[2]=255;
pwm_init(servo_param.pwm_freq,servo_param.pwm_duty);
pwm_set_duty(servo_param.pwm_duty[1], 1);*/
pwm_set_duty(pwm_duty1, 0);
pwm_set_duty(pwm_duty2, 1);
pwm_set_duty(pwm_duty3, 2);
pwm_start();
I copied some routines for the intial setup of frequency,pwm. I have given credit before somewhere .
In the routine a pointer is required to the pwm duty.
I copied over the pwm c & h files from the Iot example.
in the pwm.header I defined what ports I required to use ..
#define PWM_DEPTH 255
#define PWM_1S 1000000
#define PWM_0_OUT_IO_MUX PERIPHS_IO_MUX_MTDI_U
#define PWM_0_OUT_IO_NUM 12
#define PWM_0_OUT_IO_FUNC FUNC_GPIO12
#define PWM_1_OUT_IO_MUX PERIPHS_IO_MUX_GPIO4_U /*MTDO_U */
#define PWM_1_OUT_IO_NUM 4
#define PWM_1_OUT_IO_FUNC FUNC_GPIO4
#define PWM_2_OUT_IO_MUX PERIPHS_IO_MUX_MTCK_U
#define PWM_2_OUT_IO_NUM 13
#define PWM_2_OUT_IO_FUNC FUNC_GPIO13
Just a quick response .. hope it helps
That is really useful not only to me but presumably to others – thanks!
+2 on that, answered > 20 questions I had!
So from what I’ve gathered from the above, assuming pin 15 is a no-go, we now have the setup for input or output use of 0,2,4,5 and 14.
What about 12, 13 and 16?
Do you know which pins PWM is available on?
I’m pretty sure i’ve copied your example for the ESP-01 with the only change being:
#define PWM_0_OUT_IO_NUM 12
#define PWM_0_OUT_IO_FUNC FUNC_GPIO12
change to:
#define PWM_0_OUT_IO_NUM 2
#define PWM_0_OUT_IO_FUNC FUNC_GPIO2
I have an LED connected to GPIO2 and simple on/off switching works fine but I get no response when trying to set PWM to that pin.
I’m starting to think the pins available on the ESP-01 just can’t do PWM but then http://g-lab.ca/esp8266ex-gpio-registers/ seems to indicate that ALL pins can.
well I’ve answered my own question again 🙂
GPIO2 _can_ do PWM!
For those playing along at home:
I made the below change in pwm.h:
#define PWM_0_OUT_IO_NUM 12
#define PWM_0_OUT_IO_FUNC FUNC_GPIO12
change to:
#define PWM_0_OUT_IO_NUM 2
#define PWM_0_OUT_IO_FUNC FUNC_GPIO2
In user_main.c:
pwm_init(500, 0);
pwm_set_freq((uint16_t)myFreq, 0);
pwm_start();
Now the pwm_init command is not right… the code in pwm.c expect an array to be passed instead of just ‘0’ but I found when doing that I receive: Fatal Exception(28) every time so I made an additional change in pwm.c.
From:
LOCAL void ICACHE_FLASH_ATTR
pwm_set_freq_duty(uint16 freq, uint8 *duty)
{
uint8 i;
pwm_set_freq(freq);
for (i = 0; i < PWM_CHANNEL; i++) {
pwm_set_duty(duty[i], i);
}
}
to:
LOCAL void ICACHE_FLASH_ATTR
pwm_set_freq_duty(uint16 freq, uint8 *duty)
{
uint8 i;
pwm_set_freq(freq);
for (i = 0; i < PWM_CHANNEL; i++) {
pwm_set_duty(0, i);
}
}
Finally back in user_main.c I set up a timer to call a quick function to cycle through the duty (0-255) every 30ms:
LOCAL void ICACHE_FLASH_ATTR pwmtest_cb(void *arg)
{
myDuty = myDuty + dir;
pwm_set_duty(myDuty, 0);
pwm_start();
if (myDuty > 250) {
dir = dir * -1;
}
if (myDuty < 10) {
dir = dir * -1;
}
os_delay_us(10000);
os_printf("Duty: %d\n",myDuty);
}
The result is an LED that slowly fades from nothing up to full brightness then slowly back down to nothing and repeats!
Im using Pin14 for the DS18B20
//set gpio14 as gpio pin
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14);
//disable pulldown
PIN_PULLDWN_DIS(PERIPHS_IO_MUX_MTMS_U);
//enable pull up R
PIN_PULLUP_EN(PERIPHS_IO_MUX_MTMS_U);
// Configure the GPIO14 with internal pull-up
// PIN_PULLUP_EN( gpio );
GPIO_DIS_OUTPUT( 14);
Thank you Aaron.