User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Wed Oct 24, 2018 8:33 am

tlfong01 wrote:
Tue Oct 23, 2018 2:19 pm
tlfong01 wrote:
Tue Oct 23, 2018 8:28 am
Testing Fake Amica NodeMCU V3 ESP8266-12 Board - Part 2 - Blinky
Testing Fake Amica NodeMCU V3 ESP8266-12 Board - Part 2 - Blinky

NodeMCU Lua Blinky - newbie friendly version 1.0

-- *** togglePin02 *** #################################################### --
-- Description
-- togglePin01 modified, using tmr.create() and tmr.start() instead of tmr.alarm()

function togglePin02(pinNum, toggleTime)
setPinOutput(pinNum)
local High = true
local Low = false
pinLevel = High

function togglePin02CalllBackFunction()
if pinLevel == High
then
pinLevel = Low
setPinLevel(pinNum, pinLevel)
else
pinLevel = High
setPinLevel(pinNum, pinLevel)
end

togglePin02Timer:register(toggleTime, tmr.ALARM_AUTO, togglePin02CallBackFunction)
togglePin02Timer.create()
togglePin02Timer:start()
end
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Thu Oct 25, 2018 7:15 am

tlfong01 wrote:
Tue Oct 23, 2018 4:42 am
Lua Newbie's Sorrow
I am thinking of giving up NodeMCU/Lua for now, and perhaps resume when a NodeMCU with bigger RAM comes, ...

NodeMCU Lua Flash Store

I once thought the NodeMCU's 32kB RAM limit is a big disadvantage and I would need to wait for a big RAM esp8266. But then I just read that there is in fact something called Lua Flash Store that can solve the too little RAM problem.

So I will now try to built a firmware image to try my luck. :lol:

Appendix - Lua Flash Store (LFS) Summary Notes

Lua Flash Store (LFS)
https://nodemcu.readthedocs.io/en/master/

In September 2018 support for a Lua Flash Store (LFS) was introduced. LFS allows Lua code and its associated constant data to be executed directly out of flash-memory; just as the firmware itself is executed. This now enables NodeMCU developers to create Lua applications with up to 256Kb Lua code and read-only constants executing out of flash. All of the RAM is available for read-write data!

Lua Flash Store (LFS)

The Lua Flash Store (LFS) patch modifies the Lua RTS to support a modified Harvard architecture by allowing the Lua code and its associated constant data to be executed directly out of flash-memory (just as the NoceMCU firmware is itself executed). This now allows NodeMCU Lua developers to create Lua applications with up to 256Kb Lua code and read-only (RO) constants executing out of flash, with all of the RAM is available for read-write (RW) data.

Unfortunately, the ESP architecture provides very restricted write operations to flash memory (writing to NAND flash involves bulk erasing complete 4Kb memory pages, before overwriting each erased page with any new content). Whilst it is possible to develop a R/W file system within this constraint (as SPIFFS demonstrates), this makes impractical to modify Lua code pages on the fly. Hence the LFS patch works within a reflash-and-restart paradigm for reloading the LFS, and does this by adding two API new calls: one to reflash the LFS and restart the processor, and one to access LFS stored functions. The patch also addresses all of the technical issues 'under the hood' to make this magic happen.

Using LFS

... most Lua developers seem to prefer the convenience of our Cloud Build Service, so we have added extra LFS menu options to facilitate building LFS images:

Variable Option
LFS size (none, 32, 64, 96 or 128Kb) The default is none.
The default is none, in which case LFS is disabled. Selecting a numeric value enables LFS with the LFS region sized at this value.

SPIFFS base If you have a 4Mb flash module then I suggest you choose the 1024Kb option as this will preserve the SPIFFS even if you reflash with a larger firmware image; otherwise leave this at the default 0.

SPIFFS size (default or various multiples of 64Kb) Choose the size that you need. Larger FS require more time to format on first boot.

You must choose an explicit (non-default) LFS size to enable the use of LFS.
Most developers find it more useful to work with a fixed SPIFFS size matched to their application requirements.

Choosing your development life-cycle

...

Most Lua developers seem to start with the ESPlorer tool, a 'simple to use' IDE that enables beginning Lua developers to get started. ESPlorer can be slow cumbersome for larger ESP application, and it requires a direct UART connection. So many experienced Lua developers switch to a rapid development cycle where they use a development machine to maintain your master Lua source. Going this route will allow you use your favourite program editor and source control, with one of various techniques for compiling the lua on-host and downloading the compiled code to the ESP:

If you only need to update the Lua components, then you can work over-the-air (OTA). For example see my HTTP_OTA.lua, which pulls a new LFS image from a webservice and reloads it into the LFS region. This only takes seconds, so I often use this in preference to UART-attached loading.

...

Another option would be to include the FTP and Telnet modules in the base LFS image and to use telnet and FTP to update your system.

(Given that a 64Kb LFS can store thousands of lines of Lua, doing this isn't much of an issue.)

...

Programming Techniques and approachs

I have found that moving code into LFS has changed my coding style, as I tend to use larger modules and I don't worry about in-memory code size. This make it a lot easier to adopt a clearer coding style, so my ESP Lua code now looks more similar to host-based Lua code. Lua code can still be loaded from SPIFFS, so you still have the option to keep code under test in SPIFFS, and only move modules into LFS once they are stable.

Accessing LFS functions and loading LFS modules

...

Technical issues

...

Implementation details

...

.END
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Thu Oct 25, 2018 8:06 am

tlfong01 wrote:
Thu Oct 25, 2018 7:15 am
NodeMCU Lua Flash Store
I once thought the NodeMCU's 32kB RAM limit is a big disadvantage and I would need to wait for a big RAM esp8266. But then I just read that there is in fact something called Lua Flash Store that can solve the too little RAM problem.
So I will now try to built a firmware image to try my luck. :lol:

Flashing NodeMCU firmware with Lua Flash Store

1. I went to NodeMCU custom builds site to build.
https://nodemcu-build.com/

2. Build statistics says Builds today 50, Total builds 220,912, Unique users 91,769.
So I am one of the 90k+ builders!

3. I built with the following LFS options.
LFS size = 128kB, SPIFFS base (fixed location) = 1024 kB, SPIFF size = 64kB

4. I have selected the following 17 modules:
dht, ds18b20, file, gpio, hdc1080, http, i2c, mqtt, net, node, ow, pcm, pwm, spi, tmr, uart, wifi.

5. I got the built ready email in only 2 minutes, and I downloaded the floating point version.

6. I am using the new version of nodemcu-pyflasher to flash, everything went well.
https://github.com/marcelstoer/nodemcu-pyflasher
Attachments
nodemcu_flashing_record_2018oct2501.jpg
nodemcu_flashing_record_2018oct2501.jpg (163.37 KiB) Viewed 5903 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Thu Oct 25, 2018 8:36 am

tlfong01 wrote:
Thu Oct 25, 2018 8:06 am
Flashing NodeMCU firmware with Lua Flash Store
6. I am using the new version of nodemcu-pyflasher to flash, everything went well.

Running old Lua program with new NodeMCU firmware with Lua Flash Store

I ran my old blinky program and found everything OK. One very pleasant surprise is that I no more see the annoying non stop event detecting messages messing up the results window.

Now I am testing two Amica boards at the same time, one with, one without LFS, to check out if indeed it is the too little 32 kB RAM limit that is causing all the sorrows.

I list the program and results below.

Code: Select all

*** Blinky2018oct2501d.lua ***

function printTitle(title)
  local threeStars = '***'
  local twoNewLines = '\n\n'
  print(twoNewLines, threeStars, title, threeStars)
end

function printTitleNum(title, num)
  local twoNewLines = '\n\n'
  local fiveSpaces = '     '
  print(fiveSpaces, title, num)
end

function setPinOutput(pinNum)
  gpio.mode(pinNum, gpio.OUTPUT)  
end

function setPinHigh(pinNum)
  gpio.write(pinNum, gpio.HIGH)  
end

function setPinLow(pinNum)
  gpio.write(pinNum, gpio.LOW)  
end

function setPinLevel(pinNum, pinLevel)
  local High = true
  local Low  = false
  if pinLevel == High
    then
      setPinHigh(pinNum)
    else
      setPinLow(pinNum)
  end
end

function togglePin01(pinNum, toggleTime)
  setPinOutput(pinNum)
  local High = true
  local Low  = false
  pinLevel = High
  timerNum = 1
  timerMode = tmr.ALARM_AUTO

  tmr.alarm(
    timerNum, toggleTime, timerMode, function()

    if pinLevel == High 
      then
        pinLevel = Low
        setPinLevel(pinNum, pinLevel)
      else
        pinLevel = High
	setPinLevel(pinNum, pinLevel)
    end

  end
  )
end

function togglePin01f()
  toggleTime = 100
  togglePin01(pinNum, toggleTime)
end

function togglePin01s()
  toggleTime = 500
  togglePin01(pinNum, toggleTime)
end

function timer01(pinNum, toggleTime)
  setPinOutput(pinNum)
  High = true
  Low  = false
  pinLevel = High
  
  printTitle('togglePin02 starts')

  local highTimer = tmr.create()
  local lowTimer  = tmr.create()

  function highTimerCallBack()
    printTitle('highTimer expired 5')
    print('pinLevel =', pinLevel)
    print('pinNum =', pinNum)
  end

  function lowTimerCallBack()
    printTitle('lowTimer expired 5')
    print('pinLevel =', pinLevel)
    print('pinNum =', pinNum)
  end

  highTimer:register(2000, tmr.ALARM_SINGLE, highTimerCallBack)
  lowTimer :register(4000, tmr.ALARM_SINGLE, lowTimerCallBack)

  highTimer:start()
  lowTimer :start()
end

function coroutine01()

  -- *** Define coroutines *** --

  setPinHighCoroutine = coroutine.create(function(inString)
                                           printTitle(inString) 
					   printTitleNum('pinLevel =', pinLevel)
                                           printTitleNum('pinNum =', pinNum)
                                           coroutine.yield()
                                           printTitle('aaa')
					 end)

  setPinLowCoroutine = coroutine.create(function(inString)
                                           printTitle(inString) 
                                           printTitleNum('pinLevel =', pinLevel)
                                           printTitleNum('pinNum =', pinNum)
                                           coroutine.yield()
                                           printTitle('xxx')
					 end)

  printTitle('coroutine01 starts')

  coroutine.resume(setPinHighCoroutine, 'coroutine01H1')
  coroutine.resume(setPinLowCoroutine,  'coroutine01L1')

end

function stopTimer01(timerNumId)
  tmr.stop(timerNumId)
end

function startTimer01(timerNumId)
  tmr.start(timerNumId)
end

function togglePin02(pinNum, toggleTime)
  setPinOutput(pinNum)
  local High = true
  local Low  = false
  pinLevel = High

  tmr.alarm(
    1,toggleTime,1,function()

    if pinLevel == High 
      then
        pinLevel = Low
        setPinLevel(pinNum, pinLevel)
      else
        pinLevel = High
	setPinLevel(pinNum, pinLevel)
    end
  end
  )
end

function main()
  printTitle('blinky2018oct2501a')
  toggleTime = 500
  timerNum   = 1
  pinNum     = 4
  togglePin01(pinNum, toggleTime)
  --togglePin01f()
  --togglePin01s()
  --stopTimer01(1)
  --startTimer01(1)
  --timer01(pinNum, toggleTime)
  --coroutine01()  
  --togglePin02(pinNum, toggleTime)
end  

main()


*** ESPlorer Results ***

PORT OPEN 115200

Communication with MCU..Got answer! Communication with MCU established.
AutoDetect firmware...

Can't autodetect firmware, because proper answer not received (may be unknown firmware). 
Please, reset module or continue.
$

NodeMCU custom build by frightanic.com
	branch: master
	commit: c708828bbe853764b9de58fb8113a70f5a24002d
	SSL: false
	modules: dht,ds18b20,file,gpio,hdc1080,http,i2c,mqtt,net,node,ow,pcm,pwm,rtctime,spi,tmr,uart,wifi
 build created on 2018-10-25 07:35
 powered by Lua 5.1.4 on SDK 2.2.1(6ab97e9)
lua: cannot open init.lua

> function printTitle(title)
>> local threeStars = '***'
>> local twoNewLines = '\n\n'
>> print(twoNewLines, threeStars, title, threeStars)
>> end
> 
> function printTitleNum(title, num)
>> local twoNewLines = '\n\n'
>> local fiveSpaces = '     '
>> print(fiveSpaces, title, num)
>> end
> 
> function setPinOutput(pinNum)
>> gpio.mode(pinNum, gpio.OUTPUT)
>> end
> 
> function setPinHigh(pinNum)
>> gpio.write(pinNum, gpio.HIGH)
>> end
> 
> function setPinLow(pinNum)
>> gpio.write(pinNum, gpio.LOW)
>> end
> 
> function setPinLevel(pinNum, pinLevel)
>> local High = true
>> local Low  = false
>> if pinLevel == High
>> then
>> setPinHigh(pinNum)
>> else
>> setPinLow(pinNum)
>> end
>> end
> 
> function togglePin01(pinNum, toggleTime)
>> setPinOutput(pinNum)
>> local High = true
>> local Low  = false
>> pinLevel = High
>> timerNum = 1
>> timerMode = tmr.ALARM_AUTO
>> 
>> tmr.alarm(
>> timerNum, toggleTime, timerMode, function()
>> 
>> if pinLevel == High
>> then
>> pinLevel = Low
>> setPinLevel(pinNum, pinLevel)
>> else
>> pinLevel = High
>> setPinLevel(pinNum, pinLevel)
>> end
>> 
>> end
>> )
>> end
> 
> function togglePin01f()
>> toggleTime = 100
>> togglePin01(pinNum, toggleTime)
>> end
> 
> function togglePin01s()
>> toggleTime = 500
>> togglePin01(pinNum, toggleTime)
>> end
> 
> function timer01(pinNum, toggleTime)
>> setPinOutput(pinNum)
>> High = true
>> Low  = false
>> pinLevel = High
>> 
>> printTitle('togglePin02 starts')
>> 
>> local highTimer = tmr.create()
>> local lowTimer  = tmr.create()
>> 
>> function highTimerCallBack()
>> printTitle('highTimer expired 5')
>> print('pinLevel =', pinLevel)
>> print('pinNum =', pinNum)
>> end
>> 
>> function lowTimerCallBack()
>> printTitle('lowTimer expired 5')
>> print('pinLevel =', pinLevel)
>> print('pinNum =', pinNum)
>> end
>> 
>> highTimer:register(2000, tmr.ALARM_SINGLE, highTimerCallBack)
>> lowTimer :register(4000, tmr.ALARM_SINGLE, lowTimerCallBack)
>> 
>> highTimer:start()
>> lowTimer :start()
>> end
> 
> function coroutine01()
>> 
>> -- *** Define coroutines *** --
>> 
>> setPinHighCoroutine = coroutine.create(function(inString)
>> printTitle(inString)
>> printTitleNum('pinLevel =', pinLevel)
>> printTitleNum('pinNum =', pinNum)
>> coroutine.yield()
>> printTitle('aaa')
>> end)
>> 
>> setPinLowCoroutine = coroutine.create(function(inString)
>> printTitle(inString)
>> printTitleNum('pinLevel =', pinLevel)
>> printTitleNum('pinNum =', pinNum)
>> coroutine.yield()
>> printTitle('xxx')
>> end)
>> 
>> printTitle('coroutine01 starts')
>> 
>> coroutine.resume(setPinHighCoroutine, 'coroutine01H1')
>> coroutine.resume(setPinLowCoroutine,  'coroutine01L1')
>> 
>> end
> 
> function stopTimer01(timerNumId)
>> tmr.stop(timerNumId)
>> end
> 
> function startTimer01(timerNumId)
>> tmr.start(timerNumId)
>> end
> 
> function togglePin02(pinNum, toggleTime)
>> setPinOutput(pinNum)
>> local High = true
>> local Low  = false
>> pinLevel = High
>> 
>> tmr.alarm(
>> 1,toggleTime,1,function()
>> 
>> if pinLevel == High
>> then
>> pinLevel = Low
>> setPinLevel(pinNum, pinLevel)
>> else
>> pinLevel = High
>> setPinLevel(pinNum, pinLevel)
>> end
>> end
>> )
>> end
> 
> function main()
>> printTitle('blinky2018oct2501a')
>> toggleTime = 500
>> timerNum   = 1
>> pinNum     = 4
>> togglePin01(pinNum, toggleTime)
>> --togglePin01f()
>> --togglePin01s()
>> --stopTimer01(1)
>> --startTimer01(1)
>> --timer01(pinNum, toggleTime)
>> --coroutine01()
>> --togglePin02(pinNum, toggleTime)
>> end
> 
> main()
	***	blinky2018oct2501a	***
> 
Attachments
flash_record_2018oct2501.jpg
flash_record_2018oct2501.jpg (158.55 KiB) Viewed 5892 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Fri Oct 26, 2018 12:34 pm

tlfong01 wrote:
Thu Oct 25, 2018 8:36 am
Running old Lua program with new NodeMCU firmware with Lua Flash Store
I ran my old blinky program and found everything OK.

NodeMCU Lua is not for ordinary people

I am now using the NodeMCU firmware built with LFS (Lua Flash Store) and I have lesser troubles such as unreliable/unrepeatable execution, reboot without any known reasons, could not find global functions etc.

Earlier I wrongly thought that there was no fault in my program and it was always the fault of hardware, of the fake boards made with with product rejects, without meeting the spec of the original designers, or unreliable USB to TTL cables, bad power supply units etc.

Though after using the NodeMCU firmware with LFS, I still found unexplained problems, but much less often, I also found it was much more on my side of coding to blame, much less on the hardware.

And it was only after I carefully read the NodeMCU Developer FAQ then I realize that why I found Lua programming so hard - NodeMCU is not for hobbyists programmers like myself, but for developers.

In other words, NodeMCU Lua is not for ordinary people. Ordinary people should play with ESP8266 IDE using Arduino C++ or MicroPython.

The following summary is on NodeMCU Lua Developer FAQ, what I have read to reach my conclusion that Lua is not for ordinary people.

Appendix - NodeMCU Lua Developer FAQ

Lua FAQ
https://nodemcu.readthedocs.io/en/maste ... a-language

Event driven programming

There is little point in constructing poll loops in your NodeMCU Lua code since almost always the event that you are polling will not be delivered by the SDK until after your Lua code returns control to the SDK. The most robust and efficient approach to coding ESP8266 Lua applications is to embrace this event model paradigm, and to decompose your application into atomic tasks that are threaded by events which themselves initiate callback functions. Each event task is established by a callback in an API call in an earlier task.

Persisting global variable

All variables in Lua can be classed as globals, locals or upvalues. But by default any variable that is referenced and not previously declared as local is global and this variable will persist in the global table until it is explicitly deleted.

SDK Callbacks include:

tmr, node, wifi, net.server, net, sket, sk, gpio, mqtt, uart

If tasks take longer than 500mSec then the watchdog timer will reset the processor.

If time critical code section last more than 10µSec, system ISRs might overrun

Closures in Lua
https://www.cs.tufts.edu/~nr/cs257/arch ... -draft.pdf

Cost of using functions

Standard io and os libraries don't work, but have been largely replaced by the NodeMCU node and file libraries.

The ESP8266 uses a combination of on-chip RAM and off-chip Flash memory connected using a dedicated SPI interface. Code can be executed directly from Flash-mapped address space. In fact the ESP hardware actually executes code in RAM, and in the case of Flash-mapped addresses it executes this code from a RAM-based L1 cache which maps onto the Flash addresses.

The current NodeMCU firmware will fit comfortably in a 1Mb Flash and still have ample remaining Flash memory to support Lua IoT applications.

The NodeMCU firmware makes any unused Flash memory available as a SPI Flash File System (SPIFFS) through the file library.

Unlike Arduino or ESP8266 [also microPython?] development, where each application change requires the flashing of a new copy of the firmware, in the case of Lua the firmware is normally flashed once, and all application development is done by updating files on the SPIFFS file system. In this respect, Lua development on the ESP8266 is far more like developing applications on a more traditional PC. The firmware will only be reflashed if the developer wants to add or update one or more of the hardware-related libraries.

Those developers who are used to dealing in MB or GB of RAM and file systems can easily run out of memory resources, but with care and using some of the techniques discussed below can go a long way to mitigate this.

The ESP8266 runs the SDK over the native hardware, so there is no underlying operating system to capture errors and to provide graceful failure modes. Hence system or application errors can easily "PANIC" the system causing it to reboot. Error handling has been kept simple to save on the limited code space, and this exacerbates this tendency. Running out of a system resource such as RAM will invariably cause a messy failure and system reboot.


Ordinary People 1, 2, 3
https://www.youtube.com/watch?v=mKkcyK1VpGY
https://www.youtube.com/watch?v=3ru-kYvZjdY
https://www.youtube.com/watch?v=j-jTHMpK0co
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Sat Oct 27, 2018 1:13 pm

tlfong01 wrote:
Fri Oct 26, 2018 12:34 pm
NodeMCU Lua is not for ordinary people
And it was only after I carefully read the NodeMCU Developer FAQ then I realize that why I found Lua programming so hard - NodeMCU is not for hobbyists programmers like myself, but for developers.
In other words, NodeMCU Lua is not for ordinary people. Ordinary people should play with ESP8266 IDE using Arduino C++ or MicroPython.

Event driven NodeMCU Lua Blinky program for newbies

Now that I know that for ordinary people like me, I must go very very slowly, even writing a seemingly very trival program. For example, NodeMCU Lua blinky program using event driven mode, ie, no busy looping is indeed very complicated, well, at least for newbies like me.

So I decided to go back to square one and read all the references and tutorials again.

Appendix - NodeMCU Lus Blink Program References

NodeMCU Documentation Overview
https://nodemcu.readthedocs.io/en/master/

Uploading code
https://nodemcu.readthedocs.io/en/master/en/upload/

ESPlorer GitHub
https://github.com/4refr0nt/ESPlorer

ESPlorer Overview
https://esp8266.ru/esplorer/

ESPlorer Getting Started Guide by Rui Santos
http://esp8266.ru/download/esp8266-doc/ ... Santos.pdf

Santos Blinky Program
https://gist.githubusercontent.com/RuiS ... a/init.lua

NodeMCU Lua Program Examples - Electronic Wings
http://www.electronicwings.com/nodemcu/ ... plorer-ide

Lua Snippets - BigDan Blog
https://bigdanzblog.wordpress.com/2015/ ... ipt-files/

Listing Files in Flash

Use this snippet of code (from the API docs):

l = file.list();
for k,v in pairs(l) do
print("name:"..k..", size:"..v)
end

I put this in code snippet 0 so I just have to click on a button to get a listing of all files in flash:

Other commands
dofile("init.lua")
file.remove(“init.lua”) - to remove init.lua
file.format() - to remove all the files saved in your ESP8266
node.restart()
print(node.chipid()) => 1070052
print(node.heap()) => 42920
tmr.stop(0)

LoLa & Hauser - Moonlight Sonata 17,200,089 views
https://www.youtube.com/watch?v=AzWDs26YL9Y

Lola Astanova - Wikipedia
https://en.wikipedia.org/wiki/Lola_Astanova

Lola Astanova (born 1985 in Tashkent, former USSR) is an Uzbek pianist, noted for her interpretations of compositions by Chopin, Liszt and Rachmaninoff, as well as piano transcriptions.

Fashion

Astanova has received attention for her performance style and appearance, often wearing extremely high-heels and tiny mini skirts. She has expressed her love for fashion stating that "some extraordinary artists" work in this field. In June 2012, she was named among Top 10 Style Icons in Classical Music by Limelight magazine.

Astanova has been featured in numerous style and lifestyle publications, including Vogue, People, ¡Hola!, Haute Living and Quest.


Stjepan Hauser - Wikipedia
https://en.wikipedia.org/wiki/Stjepan_Hauser

Stjepan Hauser (born 1986) is a Croatian cellist.

Early life and musical training

Hauser was born in Pula, Croatia, SFR Yugoslavia into a musical family, where he began his musical education. His mother plays percussion. He has a sister who is a journalist in Pula. Hauser finished secondary school in Rijeka. He studied in Zagreb and London, and later in the United States under Bernard Greenhouse.

Career

Hauser has performed in more than 40 countries across all the continents including successful debuts in Wigmore Hall, Royal Albert Hall, Amsterdam Concertgebouw, Southbank Centre and many more. He is laureate of UK's international competitions and awards such as: PLG Young Artists Auditions 2009, ................................
Attachments
santos_blinky_2018oct2701.jpg
santos_blinky_2018oct2701.jpg (171.27 KiB) Viewed 5844 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Sun Oct 28, 2018 3:50 am

tlfong01 wrote:
Sat Oct 27, 2018 1:13 pm
Event driven NodeMCU Lua Blinky program for newbies
So I decided to go back to square one and read all the references and tutorials again.
ESPlorer Getting Started Guide by Rui Santos
http://esp8266.ru/download/esp8266-doc/ ... Santos.pdf
Santos Blinky Program
https://gist.githubusercontent.com/RuiS ... a/init.lua

Understanding the demo NodeMCU Lua blinky Program

After googling a long while, I finally understand why I don't understand even the demo blinky program. The reason I don't understand the blinky program is that I don't have enough knowledge on many Lua concepts including the very important one: closure

So I am thinking of spending this Sunday afternoon to dig deeper into this closure thing.
I will start with two references:

1. NodeMCU Lua Developer FAQ

2. Closures in Lua by R Ierusalimschy etal



Update 2018oct28hkt1444

I found the following Hackaday tutorial, StackOverflow Q&A and Esp8266 Forum also good for newbies.

Hackaday ESP8266 Lua Tutorials
https://hackaday.io/project/159471-esp8 ... -tutorials

Summary Notes

Blinky program

led = 3 -- NodeMCU uses a different numbering scheme
tmr.alarm(1, 1000, tmr.ALARM_AUTO, function()
gpio.write(led, gpio.LOW)
tmr.delay(100000)
gpio.write(led, gpio.HIGH)
end)

then run luatool.py twice in a row to get it to program init.lua.

If you get an error saying "No proper answer from MCU", try resetting the board, replugging the USB cable, and running the luatool multiple times in a row. This may be due to the idiosyncrasies of my laptop's USB controller, ...

All user code should be run either in a timer, or as a task.

This is because the ESP8266 has two different watchdog timers that will reset the board if the watchdog reset function isn't called periodically. This is usually referred to as "petting" the watchdog.

The software watchdog needs to be pet about every 6 seconds (an eternity to an 80MHz microcontroller!) and the hardware watchdog needs to be pet, depending on where you read, anywhere from every 2ms to 200ms.


Stack Overlfow NodeMCU Q& A
https://stackoverflow.com/questions/tagged/nodemcu

Questions tagged [nodemcu]

NodeMCU is an open-source firmware that offers a Lua API for ESP8266, ESP8285, and ESP32. There is also a ESP8266 devkit with the same name. However, questions here should relate to writing Lua code on top of the firmware. Also if you need help understanding the NodeMCU API SO is the right place. ...


ESP8266 Community Forum
https://www.esp8266.com/viewforum.php?f=17

Appendix - NodeMCU Lua Developer FAQ Summary

NodeMCU Lau Developer FAQ - So how is context passed between Lua event tasks?
https://nodemcu.readthedocs.io/en/maste ... erent-here

It is important to understand that a single Lua function is associated with/bound to any event callback task. This function is executed from within the relevant NodeMCU library C code using a lua_call(). ...

By their very nature Lua local variables only exist within the context of an executing Lua function, and so locals are unreferenced on exit and any local data (unless also a reference type such as a function, table, or user data which is also referenced elsewhere) can therefore be garbage collected between these lua_call() actions.

So context can only be passed between event routines by one of the following mechanisms:

Globals are by nature globally accessible. Any global will persist until explicitly dereferenced by assigning nil to it. Globals can be readily enumerated, e.g. by a for k, v in pairs(_G) do, so their use is transparent.

The File system is a special case of persistent global, so there is no reason in principle why it and the files it contains can't be used to pass context.

However the ESP8266 file system uses flash memory and even with the SPIFFS file system still has a limited write cycle lifetime, so it is best to avoid using the file system to store frequently changing content except as a mechanism of last resort.

The Lua Registry. This is a normally hidden table used by the library modules to store callback functions and other Lua data types. The GC treats the registry as in scope and hence any content referenced in the registry will not be garbage collected.

Upvalues. These are a standard feature of Lua as described above that is fully implemented in NodeMCU. When a function is declared within an outer function, all of the local variables within the outer scope are available to the inner function.

Ierusalimschy's paper, Closures in Lua, gives a lot more detail for those that want to dig deeper.

Closures in Lua - R Ierusalimschy etal 2013apr24
https://www.cs.tufts.edu/~nr/cs257/arch ... -draft.pdf

1. First-class functions are a hallmark of functional languages, but they are a useful concept in procedural languages too. Many procedural functions may be more generic if coded as higher-order functions.

2. Lua is a procedural scripting language widely used in the game industry that uses first-class functions extensively.

3. In Lua, as in Scheme, all functions are anonymous dynamic values created at run time.

4. First-class functions are also at the core of the Lua interpreter.1 Unlike most other interpreted languages, which offer an eval primitive to evaluate an arbitrary piece of code represented as data, Lua offers a compile primitive, called loadstring, which returns an anonymous function equivalent to the given arbitrary piece of code.

5. Lua supports first-class functions with lexical scoping via closures

6. Lua has a tiny implementation. The whole interpreter, with the compiler and the standard libraries, comprises less than 17,000 lines of C code. Lua is used often on devices with restricted memory, ... Moreover, Lua is frequently used for data representation. Lua programs representing data may have huge expressions, spanning many thousands lines of code.

7. Lua ... the concept of upvalues, which allowed nested functions to access the values of external variables, but not the variables themselves

8. Scheme, ... its semantic similarities with Lua.

9. C does not offer nested functions, and so a function cannot access local variables from another function.

10 Pascal offers nested functions ... functions may be passed as arguments to other functions, but can neither be returned
nor stored in variables, ...

11. Java does not offer nested functions, but it offers anonymous inner classes, so that a method in an anonymous class is nested inside another method.

12. Python offers nested functions, but although an inner function can access the value of an outer variable, it cannot assign to such variables.

14. Lua uses a register-based virtual machine. Each function call creates an activation record on a stack, wherein live the registers used by the function. So, each function has its own set of registers

15. The key component in the implementation of Lua closures is the upvalue structure, which intermediates the connection between a closure and a variable. ... the first field is a garbage-collection header. The next field is a pointer to the cell that holds the value of this upvalue

16. Lua offers support for stackful coroutines, that is, coroutines with independent stacks. Therefore, closures in Lua may form “cactus” structures, wherein a closure may access local variables from several different stacks.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Sun Oct 28, 2018 8:54 am

tlfong01 wrote:
Thu Oct 25, 2018 8:36 am
Running old Lua program with new NodeMCU firmware with Lua Flash Store
I ran my old blinky program and found everything OK. One very pleasant surprise is that I no more see the annoying non stop event detecting messages messing up the results window.
Now I am testing two Amica boards at the same time, one with, one without LFS, to check out if indeed it is the too little 32 kB RAM limit that is causing all the sorrows.

LX-508 USB 2.0 3m 2628AWG cable EMI filtering ferrite bead for Lua program upload

I bought a new 3m, anti EMI USB 2.0 cable to see if it has any program upload problem. I think for 115,200 baud, it is an overkill to insist using USB 3.0 cable. Double shielding with aluminium foil and braid, with EMI filtering ferrite bead is more important. I also think that shorter cables are more reliable than long ones.

Hang-Lx USB 2.0 cable with ferrite bead
https://detail.tmall.com/item.htm?spm=a ... 207:132069
Attachments
lx501_usb_cable_2018oct2801.jpg
lx501_usb_cable_2018oct2801.jpg (156.25 KiB) Viewed 5800 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Sun Oct 28, 2018 1:50 pm

tlfong01 wrote:
Thu Oct 25, 2018 8:36 am
tlfong01 wrote:
Thu Oct 25, 2018 8:06 am
Flashing NodeMCU firmware with Lua Flash Store
6. I am using the new version of nodemcu-pyflasher to flash, everything went well.
Running old Lua program with new NodeMCU firmware with Lua Flash Store
I ran my old blinky program and found everything OK. One very pleasant surprise is that I no more see the annoying non stop event detecting messages messing up the results window.
Now I am testing two Amica boards at the same time, one with, one without LFS, to check out if indeed it is the too little 32 kB RAM limit that is causing all the sorrows.

Quad Amica NodeMCU modules testing notes

Now I am testing 4 Amica modules at the same time. I used PyFlasher 3.0 to flash the same firmware I custom built on 2018Oct25.

NodeMCU PyFlasher V3.0
COM 10, COM 24, COM 25, COM 26
115200 baud, Dual I/O (DIO), Erase Flash (yes, wipes all data)
D:\work\rpi_forum\nodemcu\nodemcu_firmware_2\
nodemcu-master-18-modules-2018-10-25-07-35-58-float.bin
Attachments
quad_amica_test_2018oct2801.jpg
quad_amica_test_2018oct2801.jpg (160.25 KiB) Viewed 5789 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Sun Oct 28, 2018 2:29 pm

tlfong01 wrote:
Sun Oct 28, 2018 1:50 pm
Quad Amica NodeMCU modules testing notes
Now I am testing 4 Amica modules at the same time. I used PyFlasher 3.0 to flash the same firmware I custom built on 2018Oct25.

NodeMCU Node Module Learning Notes

I know quite a bit of C, C++, C#, Python, but I have zero experience in Java, JavaScript, NodeJS, or NodeRed. I guess this is the reason I don't quite understand what the documents referring to something called 'node', which I guess should have a special meaning in javascript like languages.

So I think I better first learn more about the node thing before I resume the stalled blinky program writing.

I am thinking of trying out the following basic node functions.

NodeMCU Node Module
https://nodemcu.readthedocs.io/en/maste ... ules/node/

The node module provides access to system-level features such as sleep, restart and various info and IDs.

node.chipid() - Returns the ESP chip ID.
node.flashsize() - Returns the flash chip size in bytes.
node.getcpufreq() - Get the current CPU Frequency.
node.heap() - Returns the current available heap size in bytes.
node.egc.meminfo() - Returns memory usage information for the Lua runtime.
node.info() - Returns NodeMCU version, chipid, flashid, flash size, flash mode, flash speed, and Lua File Store (LFS) usage statics.

node.restart() - Restarts the chip.
node.task.post() - Enable a Lua callback or task to post another task request.

node.input() - Submits a string to the Lua interpreter.
node.output() - Redirects the Lua interpreter output to a callback function.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Oct 29, 2018 4:51 am

tlfong01 wrote:
Sun Oct 28, 2018 1:50 pm
Quad Amica NodeMCU modules testing notes
Now I am testing 4 Amica modules at the same time. I used PyFlasher 3.0 to flash the same firmware I custom built on 2018Oct25.

Dual Rpi3B+ Quad Amica NodeMCU assembly notes

Now I am thinking of adding the following to the rooftop garden KY019 relay board chassis:

1. Rpi3B+ x 2

2. Amica NodeMCU x 4


The two Rpi's have the same 5V power, and the power, HDMI, and USB connections are easily swappable. It takes less than 1 minute to swap three connectors:

1. micro USB power connector

2. HDMI connector

3. USB with 4 ports (2 for wireless keyboard and mouse, two for USB flash


The Rpi/ESP8266 module has one one 12V power input, either from 220VAC to 12VDC switch power supply, or from 12V recharage battery (lead or lithium)

I am thinking of installing a TaoBao 500 yuan 50W solar power battery charger on the rooftop to charge the 12V batteries.
Attachments
dual_rpi_quad_amica_2018oct2901.jpg
dual_rpi_quad_amica_2018oct2901.jpg (142.64 KiB) Viewed 5766 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Oct 29, 2018 7:24 am

tlfong01 wrote:
Mon Oct 29, 2018 4:51 am
tlfong01 wrote:
Sun Oct 28, 2018 1:50 pm
Quad Amica NodeMCU modules testing notes
Dual Rpi3B+ Quad Amica NodeMCU assembly notes
Now I am thinking of adding the following to the rooftop garden KY019 relay board chassis:
1. Rpi3B+ x 2
2. Amica NodeMCU x 4

Dual Rpi PSU wiring notes

I am trying to make the modules as loosely coupled as possible, for easy maintenance.
Attachments
dual_rpi_wiring_2018oct2901.jpg
dual_rpi_wiring_2018oct2901.jpg (170.39 KiB) Viewed 5755 times
Last edited by tlfong01 on Mon Oct 29, 2018 2:52 pm, edited 1 time in total.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Mon Oct 29, 2018 2:51 pm

tlfong01 wrote:
Mon Oct 29, 2018 7:24 am
Quad Amica NodeMCU modules testing notes

Rpi3B+ Quad Wemos D1 Mini Pro
Attachments
rpi3b+_d1_mini_pro_x4_2018oct2901.jpg
rpi3b+_d1_mini_pro_x4_2018oct2901.jpg (167.14 KiB) Viewed 5720 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Tue Oct 30, 2018 2:23 am

tlfong01 wrote:
Mon Oct 29, 2018 2:51 pm
tlfong01 wrote:
Mon Oct 29, 2018 7:24 am
Quad Amica NodeMCU modules testing notes
Rpi3B+ Quad Wemos D1 Mini Pro

R2E4 (Rpi3B+ x 2 + Esp8266 x 4) Home Automation System v0.1 Wiring Notes
Attachments
rpi2_esp4_wiring_2018oct3001.jpg
rpi2_esp4_wiring_2018oct3001.jpg (167.89 KiB) Viewed 5704 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Tue Oct 30, 2018 2:53 am

tlfong01 wrote:
Tue Oct 30, 2018 2:23 am
tlfong01 wrote:
Mon Oct 29, 2018 2:51 pm
Rpi3B+ Quad Wemos D1 Mini Pro
R2E4 (Rpi3B+ x 2 + Esp8266 x 4) Home Automation System v0.1 Wiring Notes

Rpi3B+ ESPlorer testing notes

$ java -jar ESPlorer.jar
Attachments
rpi3b+_esplorer_test_2018oct3001.jpg
rpi3b+_esplorer_test_2018oct3001.jpg (167.28 KiB) Viewed 5697 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Tue Oct 30, 2018 3:02 am

tlfong01 wrote:
Tue Oct 30, 2018 2:53 am
Rpi3B+ ESPlorer testing notes
$ java -jar ESPlorer.jar

Rpi3B+ ESPlorer Hello World Testing Notes
Attachments
rpi_esplorer_hello_world_2018oct3001.jpg
rpi_esplorer_hello_world_2018oct3001.jpg (134.36 KiB) Viewed 5696 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Tue Oct 30, 2018 3:17 am

tlfong01 wrote:
Tue Oct 30, 2018 3:02 am
Rpi3B+ ESPlorer Hello World Testing Notes
R2E4 Home Automation System v0.1 wiring notes
Attachments
r2e4_wiring_2018oct3002.jpg
r2e4_wiring_2018oct3002.jpg (161.2 KiB) Viewed 5686 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Tue Oct 30, 2018 5:02 am

tlfong01 wrote:
Tue Oct 30, 2018 3:17 am
tlfong01 wrote:
Tue Oct 30, 2018 3:02 am
Rpi3B+ ESPlorer Hello World Testing Notes
R2E4 Blinky Testing Notes
Attachments
blinky_test_2018oct3001.jpg
blinky_test_2018oct3001.jpg (184.31 KiB) Viewed 5673 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Tue Oct 30, 2018 7:04 am

tlfong01 wrote:
Tue Oct 30, 2018 3:17 am
tlfong01 wrote:
Tue Oct 30, 2018 3:02 am
Rpi3B+ ESPlorer Hello World Testing Notes
R2E4 Home Automation System v0.1 wiring notes

R2E4 Mobile Rack
Attachments
r2e4_mobile_rack_2018oct3001.jpg
r2e4_mobile_rack_2018oct3001.jpg (167.3 KiB) Viewed 5661 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Tue Oct 30, 2018 3:15 pm

tlfong01 wrote:
Tue Oct 30, 2018 5:02 am
tlfong01 wrote:
Tue Oct 30, 2018 3:17 am
tlfong01 wrote:
Tue Oct 30, 2018 3:02 am
Rpi3B+ ESPlorer Hello World Testing Notes
R2E4 Blinky Testing Notes

Using ESPlorer Snippets

When I first read about ESPlorer snippets, I though it useless, because I can always do what I used to do in Rpi python programming, write a big program with many snippet like functions, and the user can select which function to run during execution, by entering a menu option etc.

But when I read the NodeMCU programming FAQ, I realized that my old method of running snippets won't work, because NodeMCU's RAM is too small, less than 64kB, to hold a big program (not any more, when LFS is used). So one method is to save snippets in flash, and use the snippet application to edit, save in flash, and run. One more useful thing for ESPlorer snippet is to run utility programs, such as listing the files in flash, as suggested by Big Dan the Blogging Man.

ESP8266 NodeMCU/LUA: Saving, Executing, and Compiling Script Files - Big Dan the Blogging Man 2015apr21
https://bigdanzblog.wordpress.com/2015/ ... ipt-files/

l = file.list();
for k,v in pairs(l) do
print("name:"..k..", size:"..v)
end
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Thu Nov 01, 2018 6:59 am

tlfong01 wrote:
Tue Oct 30, 2018 3:15 pm
R2E4 Blinky Testing Notes

Writing NodeMCU GPIO Snippets

Now I am thinking of writing GPIO snippets, as a first step to write blinky.
Then I will write timer snippets, and finally blinky.
Attachments
nodemcu_gpio_pinout_2018nov0101.jpg
nodemcu_gpio_pinout_2018nov0101.jpg (176.33 KiB) Viewed 5592 times
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Thu Nov 01, 2018 7:24 am

tlfong01 wrote:
Thu Nov 01, 2018 6:59 am
Writing NodeMCU GPIO Snippets

Blinky2018nov0101a Testing Notes

I started from the very beginning, testing the first version of the demo blinky program I found in almost all the NodeMCU introductory tutorials. I found this demo very unfriendly to NodeMCU Lua newbies. Anyway, this program runs without any problem, blinking D4 LED, ensuring me that my NodeMCU hardware, firmware, and ESPlorer IDE are working together happily.

Now I am trying to improve the ugly demo blinky program, step by step, to make it hopefully more and more newbie friendly.

Code: Select all

-- *** Blinky2018nov0101a tlfong01 2018nov01hkt1514 *** --

function printTitle(title)
  local threeStars = '***'
  local twoNewLines = '\n\n'
  print(twoNewLines, threeStars, title, threeStars)
end

function printTitleNum(title, num)
  local twoNewLines = '\n\n'
  local fiveSpaces = '     '
  print(fiveSpaces, title, num)
end

-- *** GPIO Functions *** -----------------------------------------------------

function setPinOutput(pinNum)
  gpio.mode(pinNum, gpio.OUTPUT)  
end

function setPinHigh(pinNum)
  gpio.write(pinNum, gpio.HIGH)  
end

function setPinLow(pinNum)
  gpio.write(pinNum, gpio.LOW)  
end

function setPinLevel(pinNum, pinLevel)
  local High = true
  local Low  = false
  if pinLevel == High
    then
      setPinHigh(pinNum)
    else
      setPinLow(pinNum)
  end
end

-- *** Toggle Pin Functions ---------------------------------------------------

-- *** togglePin01 *** --

function togglePin01(pinNum, toggleTime)
  setPinOutput(pinNum)
  local High = true
  local Low  = false
  pinLevel = High
  timerNum = 1
  timerMode = tmr.ALARM_AUTO

  tmr.alarm(
    timerNum, toggleTime, timerMode, function()

    if pinLevel == High 
      then
        pinLevel = Low
        setPinLevel(pinNum, pinLevel)
      else
        pinLevel = High
	setPinLevel(pinNum, pinLevel)
    end

  end
  )
end

-- *** Blink Fast *** --

function togglePin01f()
  toggleTime = 100
  togglePin01(pinNum, toggleTime)
end

-- *** Blink Slow *** --

function togglePin01s()
  toggleTime = 500
  togglePin01(pinNum, toggleTime)
end

-- *** Main Function *** -----------------------------------------------------

function main()

  -- *** Init *** --
  toggleTime = 500
  holdPinLowTime = 2000
  timerNum   = 1
  pinNum     = 4

  -- *** Main *** --
  printTitle('blinky2018nov0101a')
  togglePin01(pinNum, toggleTime)
end  

-- *** Main *** --------------------------------------------------------------

main()

-- *** End *** ---------------------------------------------------------------
Last edited by tlfong01 on Thu Nov 01, 2018 8:05 am, edited 1 time in total.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Thu Nov 01, 2018 7:56 am

tlfong01 wrote:
Thu Nov 01, 2018 7:24 am
Writing NodeMCU GPIO Snippets


Blinky2018nov0102a Testing Notes

The first version of blinky is difficult to understand because it uses the NodeMCU tmr.alarm function which does a couple of things together:

1. Create a static timer in non stop mode, with a given timer period.
2. Defines a callback function, in the form of a 'closure'.

This closure (lambda, anonymous function) has no name, thus causing much confusion, well, at least to the newbies.


3. Register the no name call back function with the non stop timer.
4. Starts the timer.

Now I have rewritten the above function with the callback closure moved outside the tmr.alarm definition. This callback function now, thank heavens, has a name (togglePin02cCallBack) This is not at all a big improvement. It only makes the program more readable, and more maintenable.


This version two runs without problem, blinking the LED faster as expected.

Now I am more confident that my basic GPIO functions and tmr.alarm functions are working OK.

Next step is back to basic, testing very simple GPIO write LED snippets. I am just trying to get familiar to the ESPlorer snippets which are new to me.

A Horse With No Name - 38,191,176 views
https://www.youtube.com/watch?v=zSAJ0l4OBHM

Code: Select all

-- *** Blinky2018nov0102a tlfong01 2018nov01hkt1528 *** --

function printTitle(title)
  local threeStars = '***'
  local twoNewLines = '\n\n'
  print(twoNewLines, threeStars, title, threeStars)
end

function printTitleNum(title, num)
  local twoNewLines = '\n\n'
  local fiveSpaces = '     '
  print(fiveSpaces, title, num)
end

-- *** GPIO Functions *** -----------------------------------------------------

function setPinOutput(pinNum)
  gpio.mode(pinNum, gpio.OUTPUT)  
end

function setPinHigh(pinNum)
  gpio.write(pinNum, gpio.HIGH)  
end

function setPinLow(pinNum)
  gpio.write(pinNum, gpio.LOW)  
end

function setPinLevel(pinNum, pinLevel)
  local High = true
  local Low  = false
  if pinLevel == High
    then
      setPinHigh(pinNum)
    else
      setPinLow(pinNum)
  end
end

-- *** Toggle Pin Functions ---------------------------------------------------

-- *** togglePin01 *** --

function togglePin01(pinNum, toggleTime)
  setPinOutput(pinNum)
  local High = true
  local Low  = false
  pinLevel = High
  timerNum = 1
  timerMode = tmr.ALARM_AUTO

  tmr.alarm(
    timerNum, toggleTime, timerMode, function()

    if pinLevel == High 
      then
        pinLevel = Low
        setPinLevel(pinNum, pinLevel)
      else
        pinLevel = High
	setPinLevel(pinNum, pinLevel)
    end

  end
  )
end

-- *** Blink Fast *** --

function togglePin01f()
  toggleTime = 100
  togglePin01(pinNum, toggleTime)
end

-- *** Blink Slow *** --

function togglePin01s()
  toggleTime = 500
  togglePin01(pinNum, toggleTime)
end

-- *** togglePin02 *** --------------------------------------------------------

function togglePin02(pinNum, toggleTime)
  setPinOutput(pinNum)
  local High = true
  local Low  = false
  pinLevel = High
  timerNum = 1
  timerMode = tmr.ALARM_AUTO

  function togglePin02cCallBack()
    if pinLevel == High 
      then
        pinLevel = Low
        setPinLevel(pinNum, pinLevel)
      else
        pinLevel = High
	setPinLevel(pinNum, pinLevel)
    end
  end

  tmr.alarm(timerNum, toggleTime, timerMode, togglePin02cCallBack)
end

-- *** Main Function *** -----------------------------------------------------

function main()

  -- *** Init *** --
  toggleTime = 100
  holdPinLowTime = 2000
  timerNum   = 1
  pinNum     = 4

  -- *** Main *** --
  printTitle('blinky2018nov0102a')
  --togglePin01(pinNum, toggleTime)
  togglePin02(pinNum, toggleTime)
end  

-- *** Main *** --------------------------------------------------------------

main()

-- *** End *** ---------------------------------------------------------------
Last edited by tlfong01 on Thu Nov 01, 2018 2:27 pm, edited 1 time in total.
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Thu Nov 01, 2018 2:17 pm

tlfong01 wrote:
Thu Nov 01, 2018 7:56 am
Blinky2018nov0102a Testing Notes

Blinky2018nov0105a Testing Notes

Now that I have more confidence in timer callback functions, I do more abstraction and refactoring of the developer (me!) defined lower level GPIO functions, so that it would be easy to blink other pins etc. The tmr.alarm() function now becomes so very elegantly short and clean (in Mr Green's opinion!) :mrgreen:

function togglePin03(pinNum, timerNum, toggleTime)
pinLevel = High

function togglePin03CallBack()
invertPinLevel(pinLevel)
setPinLevel(pinNum, pinLevel)
end

tmr.alarm(timerNum, toggleTime, tmr.ALARM_AUTO, togglePin03CallBack)
end

Code: Select all

-- *** Blinky2018nov0105a tlfong01 2018nov01hkt2158 *** --

High   = true
Low    = false
Output = true
Input = false

function printTitle(title)
  local threeStars = '***'
  local twoNewLines = '\n\n'
  print(twoNewLines, threeStars, title, threeStars)
end

function printTitleNum(title, num)
  local twoNewLines = '\n\n'
  local fiveSpaces = '     '
  print(fiveSpaces, title, num)
end

-- *** GPIO Functions *** -----------------------------------------------------

function setPinMode(pinNum, pinMode)
  if pinMode == Output
    then
      gpio.mode(pinNum, gpio.OUTPUT)  
    else
      gpio.mode(pinNum, gpio.INPUT) 
  end
end

function setPinHigh(pinNum)
  gpio.write(pinNum, gpio.HIGH)  
end

function setPinLow(pinNum)
  gpio.write(pinNum, gpio.LOW)  
end

function setPinLevel(pinNum, pinLevel)
  if pinLevel == High
    then
      setPinHigh(pinNum)
    else
      setPinLow(pinNum)
  end
end

function invertPinLevel(PinLevel)
  if pinLevel == High
    then
      pinLevel = Low
    else
      pinLevel = High
  end
end

-- *** togglePin03 *** --------------------------------------------------------

function togglePin03(pinNum, timerNum, toggleTime)
  pinLevel = High

  function togglePin03CallBack()
    invertPinLevel(pinLevel)
    setPinLevel(pinNum, pinLevel)
  end

  tmr.alarm(timerNum, toggleTime, tmr.ALARM_AUTO, togglePin03CallBack)
end

-- *** Main Function *** -----------------------------------------------------

function main()
  printTitle('blinky2018nov0105a')

  pinNum     = 4
  timerNum   = 1
  toggleTime = 500

  setPinMode(pinNum, Output)
  togglePin03(pinNum, timerNum, toggleTime)
end  

-- *** Main *** --------------------------------------------------------------

main()

-- *** End *** ---------------------------------------------------------------
I am an electronics and smart home hobbyist.

User avatar
tlfong01
Posts: 1312
Joined: Sat Jun 02, 2018 1:43 pm
Location: Hong Kong

Re: GPIO.input voltage levels vs edge detection

Fri Nov 02, 2018 6:01 am

tlfong01 wrote:
Thu Nov 01, 2018 2:17 pm
tlfong01 wrote:
Thu Nov 01, 2018 7:56 am
Blinky2018nov0102a Testing Notes

Problem: Cannot blink two LEDs at the same time

Now that blink the built in D2 led function looks OK, I moved on to blink another LED D0 and also found it working.

But when I tried to blink D2, then D0, only D1 blinks, D0 is not responding, and vice versa. It appears that only 1 LED or timer can be activated at the same time. I need to dig deeper again.

function main()
printTitle('blinky2018nov0201c')

pinNum = 4; timerNum = 1; toggleTime = 500
togglePin04(pinNum, timerNum, toggleTime)

pinNum = 0; timerNum = 2; toggleTime = 100
togglePin04(pinNum, timerNum, toggleTime)
end

Code: Select all

-- *** Blinky2018nov0201c tlfong01 2018nov02hkt1348 *** --

-- *** Globla Variables *** --------------------------------------------------

High   = true
Low    = false
Output = true
Input = false

-- *** Debug Print Functions *** ---------------------------------------------

function printTitle(title)
  local threeStars = '***'
  local twoNewLines = '\n\n'
  print(twoNewLines, threeStars, title, threeStars)
end

function printTitleNum(title, num)
  local twoNewLines = '\n\n'
  local fiveSpaces = '     '
  print(fiveSpaces, title, num)
end

-- *** GPIO Functions *** ----------------------------------------------------

function setPinMode(pinNum, pinMode)
  if pinMode == Output
    then
      gpio.mode(pinNum, gpio.OUTPUT)  
    else
      gpio.mode(pinNum, gpio.INPUT) 
  end
end

function setPinHigh(pinNum)
  gpio.write(pinNum, gpio.HIGH)  
end

function setPinLow(pinNum)
  gpio.write(pinNum, gpio.LOW)  
end

function setPinLevel(pinNum, pinLevel)
  if pinLevel == High
    then
      setPinHigh(pinNum)
    else
      setPinLow(pinNum)
  end
end

function invertPinLevel(PinLevel)
  if pinLevel == High
    then
      pinLevel = Low
    else
      pinLevel = High
  end
end

-- *** togglePin04 *** -------------------------------------------------------

function togglePin04(pinNum, timerNum, toggleTime)
  setPinMode(pinNum, Output)
  pinLevel = High

  function togglePin04CallBack()
    invertPinLevel(pinLevel)
    setPinLevel(pinNum, pinLevel)
  end

  tmr.alarm(timerNum, toggleTime, tmr.ALARM_AUTO, togglePin04CallBack)
end

-- *** Main Function *** -----------------------------------------------------

function main()
  printTitle('blinky2018nov0201c')
  pinNum = 4; timerNum = 1; toggleTime = 500
  togglePin04(pinNum, timerNum, toggleTime)

  pinNum = 0; timerNum = 2; toggleTime = 100
  togglePin04(pinNum, timerNum, toggleTime)
end  

-- *** Main *** --------------------------------------------------------------

main()

-- *** End *** ---------------------------------------------------------------
I am an electronics and smart home hobbyist.

Return to “Python”