FAQ eforth

on ESP32


Prof. Ricardo Michel from RJ sent us this great resume of activities :


I liked very much this mix of ESP32 + eForth v.6.3

It's amazing in simplicity and power!!!


1) I'm messing around with ESP32_eForthv.6.3 and would like to share some experiences.

Sure there are some curious things, things I would like to change and some things I simply didn't get yet,

but must of things run smoothly - I found only one (possible) problem.

There are many, many things I don't know yet on eForth and ESP32, so it is certain I used wrong words and definitions - all corrections are welcome.



To read an ADC value:

"36 adc" reads the voltage present at gpio36.

To turn HIGH an gpio (gpio16, for instance):

first, you must enable the gpio on the port p0: "327680 p0ens"

then you turn it HIGH by setting its position on p0: "327680 p0s"

I had some initial difficulties with "adc" and "pin" being identified by their gpio <numbers>

(like "36 adc ." or "19 2 pin")

while you need a 32 bit word to identify the gpio for "p0ens", "p0enc", "p0s" and "p0c".

I mean:

you need to write "327680 p0ens 327680 p0s" to turn gpio16 HIGH

("327680" is the 32 bit mask related to the gpio16).

If you use "16 p0ens 16 p0s" you would turn high the gpio4, not gpio16

("16" is the 32 bit mask related to gpio4).

For now, since the 32 bit masks for each gpio are difficult to remember,

I'm using these definitions for them:

4 constant GPIO2

16 constant GPIO4

327680 constant GPIO16

655360 constant GPIO17

262144 constant GPIO18

589824 constant GPIO19

It's important to remember:

If you want to turn gpio19 HIGH or LOW, use "gpio19 p0ens" followed by "gpio19 p0s" or "gpio19 p0c".


if you want to, say, attach pwm_channel_3 to gpio19, DO NOT use "gpio19 3 pin" - use "19 3 pin".

Two useful words at this point are:

: toHIGH dup p0ENS p0S ;

: toLOW dup p0ENS p0C ;

after this, "GPIO2 toHIGH" turns "ON" gpio2, the onboard blue led, and "GPIO2 toLOW" turns it off.


P0IN returns a word that doesn't go to the stack,

making difficult to check for inputs.

Anyway, I'm using "$3FF4403C peek" (or "1072971836 peek")

and a mask to get the inputs ("$3FF4403C peek GPIO4 AND" that produces "16" when the input is high on gpio4).



To use the PWM:

19 1 pin ( attach pwm_channel_1 to gpio19 )

90 1 freq ( define 90Hz as the frequency to pwm_channel_1 )

127 1 duty ( set duty cycle of pwm_channel_1 as 50%, since duty cycle goes from 0 to 255 )

If, after this, you write:

21 1 pin

the freq and duty cycle of the pwm_channel_1 will also be applied to gpio21.

After changing the pwm_channel frequency, the corresponding gpio goes off, and it is necessary to set the duty cycle again.

While a pin is attached to a pwm_channel, it's not possible (?) to set it HIGH or LOW.

I mean:

I cannot use p0ENS, p0S or p0C with this gpio again after attaching it to a pwm channel

- to command the gpio by use of the port address it is necessary to reset the board.

Once I attach a pin to a pwm channel, I'm not seeing an easy way to unattach it.

So, to turn the pin HIGH or LOW after that, I'm setting duty cycle to 0 or 255

(but this affects all gpios attached to the same pwm_channel).

How to unattach a pin from a PWM channel?

There is a "ledcDetachPin" command in ESP32 core, maybe it's the way to go (or ledc_stop?).

Well, this is a nuisance only when you are "testing capabilities" - probably is unnecessary to worry about the unattachment for most real situations.

PWM channels 2 and 3 have some superposition - maybe some ESP32 thing I didn't get yet.

I mean:

when I update channel 2 freq, the same freq is applied to channel 3

(instantly, with no turning off and no need to set the duty cycle again could be useful)

(and exactly the other way around when I update channel 3 freq).

How to replicate this (sure, why not?):


19 2 pin ( attachs pwm_channel_2 to gpio19 )

20 2 freq ( sets pwm_channel_2 to the frequency of 20 Hz )

127 2 duty ( sets duty cycle of pwm_channel 2 to 127 )

21 3 pin ( attachs pwm_channel_3 to gpio21 )

10 3 freq ( sets pwm_channel_3 to the frequency of 10 Hz ) (immediately gpio19 changes to 10Hz)

80 3 duty ( sets duty cycle of pwm_channel_3 to 80 )

1 3 freq ( changes pwm_channel_3 freq to 1Hz, gpio21 turns off and needs a new duty cycle command, but gpio19, pwm_channel_2, also gets to 1Hz and keeps merrily blinking!)

80 3 duty ( gpio21 resumes to blink at 1Hz)

> I didn't see this superposition on others pwm_channels, 1&2, 3&4, 4&5, 1&4, 1&3 etc., only on 2&3, but then I didn't check all combinations.


On ADCs:

I completely forgot that ADC2 will not work while wifi is on...

Maybe it was all the wine and food from this holydays, but this took me longer to solve than I would like to admit

So, time to use ADC1:

36 constant ADC1_0

39 constant ADC1_3

32 constant ADC1_4

33 constant ADC1_5

34 constant ADC1_6

35 constant ADC1_7


THINGS to remember:

Some other "findings" about gpio's:

gpio 5 outputs pwm signal at boot (and was pre-attached in the eForth ino sketch)

gpio 14 outputs pwm signal at boot

gpio 15 outputs pwm signal at boot

gpio 12 must be LOW at boot

(these pins can be used, but one must know about this behavior at boot time)

These gpios are connected to the internal flash memory (better to not use them for now):







Are these GPIOs input only? (not even PWM! Also I didn't find the 32 bit words for them)







After this play with GPIOs, I tried the built_in words. Almost everything went smoothly.

I had some problems with the "?key" and "key" words.

Initially I thought that it would work by entering a character in the webpage, but it doesn't.

"?key" (qrx) uses the serial.read, but I can't send characters through the serial monitor to the ESP32.

This still eludes me.

This "?key" word is much needed! It's the only problem I would say I encountered so far.