前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二,ESP8266 GPIO和SPI和定时器和串口(基于Lua脚本语言)

二,ESP8266 GPIO和SPI和定时器和串口(基于Lua脚本语言)

作者头像
杨奉武
发布2018-04-18 16:17:40
1.1K0
发布2018-04-18 16:17:40
举报
文章被收录于专栏:知识分享

我们写lua用这个软件

http://pan.baidu.com/s/1kVN09cr 密码:pfv7

如果点击的时候提示安装,,安装就行,,如果没有提示呢可以,按照下面链接的提示自己安装哈,,,,,或者自己百度

http://jingyan.baidu.com/article/3c343ff70bc6ea0d377963df.html

让这个灯亮

这个灯连接到了GPIO2,低电平点亮

代码语言:javascript
复制
gpio.mode(4,gpio.OUTPUT)--输出模式  
gpio.write(4,0)--输出低电平  

这样的话这个灯就亮了

可能会有疑问,明明是GPIO2为什么填4

看资料

https://nodemcu.readthedocs.io/en/master/en/modules/gpio/#gpio-module

还有一个简介版的资料

链接:http://pan.baidu.com/s/1pL3FHgf 密码:l2nm

对照表

现在下进去

可以先复位一下然后再执行操

对了要是经常出现编译或者下载到模块出问题.........一定是串口模块和WIFI模块通信之间有问题.....尽量使用好的杜邦线,,,尽量短,,,,,再者可以考虑换成pl2303或者CP2102等.......因为自己测试的这两种模块比较可靠

保存到芯片里面

现在控制板子上的继电器,改一下IO口就可以了

所以呢让继电器吸合

代码语言:javascript
复制
gpio.mode(2,gpio.OUTPUT)  
gpio.write(2,1)  

关于

gpio.read()

引脚是低电平返回0,外部引脚是高电平返回1

如果设置的输出高电平,但是如果拉低了引脚,也是返回0,,,,和控制状态没有关系,只与

当前引脚的实际高低电平有关系

现在看定时器函数

第一个参数 一共可以同时使用7个定时器,,id号呢是0-6

第二个参数是延时多少ms执行最后面的函数

第三个参数是设置是只执行一次,,还是调用启动函数时执行一下,还是一直间隔第二个参数的时间执行最后面的函数

就让它每隔1s打印一下串口打印111111

[html] view plain copy

  1. gpio.mode(4,gpio.OUTPUT)  
  2. gpio.write(4,1)  
  3. function aa()--定义一个函数  
  4.   print("111111")  
  5. end  
  6. tmr.alarm(0, 1000, 1, aa)  

0代表用的标号为0的定时器

1000代表延时1000ms执行aa

1代表

当然您填tmr.ALARM_AUTO也行,,,,,太长啦.....我还是选择填1

如果填写0,那么会延时1000ms然后打印一下111111,,就是第二个参数

如果还想执行一下就调用tmr.start(0)这个里面的0代表的标号为0的定时器....

当然啦关闭这个定时器tmr.start(0)

感觉第一个参数  tmr.ALARM_SINGLE = -1...只是感觉没有试过

更方便点呢

[html] view plain copy

  1. gpio.mode(4,gpio.OUTPUT)  
  2. gpio.write(4,1)  
  3. tmr.alarm(1, 1000, 1, function()  
  4.     print("111111")  
  5. end)  

可以看一下我这篇文章

http://www.cnblogs.com/yangfengwu/p/6404695.html

剩余的定时器的方法呢有可能tmr.delay(us) 会用到,,就是延时多少us......

看一下串口....

说一下哈...配置串口是一件及其危险的事情,为什么这样说呢!!

我们烧固件是通过串口,把我们编写的.lua文件保存到模块里面也是通过串口

如果说哈模块一上电就执行了我们配置的串口程序,,,,,那么我们想把新写的程序发给模块就可能写不进去.....造成一个bug了,,,,,

解决方案是

一,重新烧写固件

但是呢也有可能重新烧写固件也不能把以前写的.lua文件清除

二,先烧写别的固件,再烧写现在的

比如:可以先烧写一个AT指令的固件,让它运行一下,然后再重新烧写lua开发版本的,但是也有可能不能把以前写的.lua文件清除

三,修改程序保存的偏移量

您想哈,,我们的.lua程序肯定也在flash里面,,,我烧写固件时把偏移量调大肯定能把我们写的.lua代码给清除掉.要是调整后出现一直发乱码,,恭喜你哈,肯定覆盖到了先前的.lua了...然后呢我再把偏移量调整到0000重新烧写就好啦...

四,其实呢根本解决方案是烧写一个空的bin文件把原先的全都清空

这是空的bin文件

链接:http://pan.baidu.com/s/1cHFko2 密码:g6nu

可以看这个,关于各个型号的模块的Flash大小

http://wiki.ai-thinker.com/_media/esp8266/esp8266_module_list.png

如果出现

 等着格式化文件系统,,就等着哈

好现在做一个程序我发给串口什么数据,串口就回给我什么数据

下面的功能可以实现但是别这样写,我只是来解释函数....否则亲们就按照上面的方法刷固件把

第一个参数只有"data",,说明是接收串口的数据

第二个参数写0就是说串口接收的数据存在了Revdata里面,,,说一下哈Revdata是一个字符串变量,,接着看后面也会提及...写小于255的数就代表,接收到这个数目才执行uart.write(0,Revdata) ,,,,如果写别的"X" ,就代表接收到字符X后就执行uart.write(0,Revdata) 

第三个参数是函数,串口接收到数据就会调用这个函数,并把接收到的数据存到Revdata里面然后调用uart.write(0,Revdata) 把数据再传回串口,,,参数0是说用串口0,,当然咱们使用的就是串口0,,,.其实还有串口1,,不过呢串口1只有TX引脚引了出来,还有串口2,不过呢

即使uart.write(2,Revdata) 写上串口2,信息还会默认发给串口0

第四个参数写0吧

第一种方案这样写

代码语言:javascript
复制
gpio.mode(4,gpio.OUTPUT)
gpio.write(4,1)


tmr.alarm(1, 2000, 0, function()

    uart.on("data", 0,function(Revdata)

            uart.write(0,Revdata)
            
    end, 0)
    
end)

程序启动以后等待2s执行下面的函数,,定时器第三个参数写的0,所以这个定时器就关闭了

代码语言:javascript
复制
1.uart.on("data", 0,function(Revdata)  
2.  
3.            uart.write(0,Revdata)  
4.              
5.    end, 0)  

只要一执行这个函数,那么以后串口接收到数据就会执行

代码语言:javascript
复制
uart.write(0,Revdata)

现在用串口助手测试一下

现在我假如修改了程序想重新写入芯片

复位芯片后赶紧点击,,当然有两秒时间

如果程序小有时候可以直接

如果程序大点,,可以再复位一下模块然后再...当然假设下载的时间不会超过两秒

假设程序很大

复位芯片后赶紧点击,,当然有两秒时间

然后看这里

只要移除掉init.lua一切都好办

那我先右击准备好点击,,,,然后呢我复位一下模块,然后在两秒之前点击就移除了init.lua

还有

也是复位后再点击是,,,移除芯片内部所有文件..........这个随时可以用,,不用像上面似的事先编译

当然这只是在自己配置了串口之后的特殊情况下才会遇到的问题哈

做到这里有些人会想,能不能配置收到什么数据就去干点什么

我们就配置收到H 就控制继电器引脚输出高电平,收到L就控制继电器引脚输出低电平

代码语言:javascript
复制
print("Relay=1")
print("Relay=0")

相当于printf,,,,把里面的字符串内容发送到串口

不过呢这个慎用,,因为遇到'\0'就默认发送'\0'以前的数据,,,所以对于 byte类型的 0

它认为是 '\0',,,用它打印字符串还是蛮不错的

[html] view plain copy

  1. gpio.mode(4,gpio.OUTPUT)  
  2. gpio.mode(2,gpio.OUTPUT)  
  3. gpio.write(4,1)  
  4. tmr.alarm(1, 2000, 0, function()  
  5.     uart.on("data", 0,function(Revdata)  
  6.             if Revdata == "H" then  
  7.                gpio.write(2,1)  
  8.                print("Relay=1")  
  9.             end  
  10.             if Revdata == "L" then  
  11.                gpio.write(2,0)  
  12.                print("Relay=0")  
  13.             end  
  14.             uart.write(0,Revdata) 
  15.     end, 0)  
  16. end)  

现在用串口调试助手测试

好现在换一下命令,配置收到++H 就控制继电器引脚输出高电平,收到++L就控制继电器引脚输出低电平

如果按照下面写竟然不管来了

[html] view plain copy

  1. gpio.mode(4,gpio.OUTPUT)  
  2. gpio.mode(2,gpio.OUTPUT)  
  3. gpio.write(4,1)  
  4. tmr.alarm(1, 2000, 0, function()  
  5.     uart.on("data", 0,function(Revdata)  
  6.             if Revdata == "++H" then  
  7.                gpio.write(2,1)  
  8.                print("Relay=1")  
  9.             end  
  10.             if Revdata == "++L" then  
  11.                gpio.write(2,0)  
  12.                print("Relay=0")  
  13.             end  
  14.             uart.write(0,Revdata) -- unregister callback function  
  15.     end, 0)  
  16. end)  

现在发送的时候多加一个加号

也就是+++H    +++L

用串口调试助手来调试,,ESPlorer 这个软件的串口有些问题

您会发现居然这样可以

告诉您原因

其实是因为串口先接收了一个+ 然后又接收的++H 所以可以控制

所以先前的++H  是串口先接收了一个+  然后又接收了 +H  所以不能控制了

不信的话可以打印一下,,修改为下面的程序

[html] view plain copy

  1. gpio.mode(4,gpio.OUTPUT)  
  2. gpio.mode(2,gpio.OUTPUT)  
  3. gpio.write(4,1)  
  4. tmr.alarm(1, 2000, 0, function()  
  5.     uart.on("data", 0,function(Revdata)  
  6.             if Revdata == "++H" then  
  7.                gpio.write(2,1)  
  8.                print("Relay=1")  
  9.             else  
  10.                print(Revdata)----LOOK  LOOK  LOOK      
  11.             end  
  12.             if Revdata == "++L" then  
  13.                gpio.write(2,0)  
  14.                print("Relay=0")  
  15.             end  
  16.             uart.write(0,Revdata) -- unregister callback function  
  17.     end, 0)  
  18. end)  

其实

这地方写0,就代表了串口接收到1个数据就会进入中断函数function(Revdata)

解决方法

我是不愿意使用控制接收到多少个字节,或者加入一个标志,,,,还记得AT指令要加换行不......那是因为"\r".接收到换行....

我的做法...我用定时器做空闲检测

关于Lua的部分语法可以看,,其实了解就行,,当时自己以为需要把lua学的很好才能用lua开发8266,,,最后才知道只需要了解些语法就好了,,剩下的看8266的API文档看怎么使用那些函数就行.....

http://www.cnblogs.com/yangfengwu/p/6357838.html

http://www.cnblogs.com/yangfengwu/p/6358444.html

http://www.cnblogs.com/yangfengwu/p/6366428.html

http://www.cnblogs.com/yangfengwu/p/6376098.html

[html] view plain copy

  1. gpio.mode(4,gpio.OUTPUT)  
  2. gpio.mode(2,gpio.OUTPUT)  
  3. gpio.write(4,1)  
  4. ReadData=""  
  5. ReadDataCopy=""  
  6. ReadCnt=0  
  7. ReadCntt =0
  8. tmr.alarm(2, 5, 1, function()  
  9.     if  ReadCnt ~= 0 then  
  10.         if  ReadCnt == ReadCntt then  
  11. ReadCnt = 0  
  12. ReadCntt = 0  
  13. ReadDataCopy = ReadData  
  14. ReadData = ""  
  15.             if  ReadDataCopy == "++H" then  
  16.                 gpio.write(2,1)  
  17.             end  
  18.             if  ReadDataCopy == "++L" then  
  19.                 gpio.write(2,0)  
  20.             end  
  21.         else  
  22. ReadCntt = ReadCnt      
  23.         end  
  24.     end  
  25. end)  
  26. tmr.alarm(1, 2000, 0, function()  
  27.     uart.on("data", 0,function(Revdata)  
  28. ReadData = ReadData..Revdata  
  29. ReadCnt = ReadCnt + 1   
  30.     end, 0)  
  31. end)  

空闲中断.............. 可以先看一下自己51的程序

串口中断接收数据

定时器做检测

可以参考的文章

http://www.cnblogs.com/yangfengwu/p/6746403.html  这个较早,后期改进了

http://www.cnblogs.com/yangfengwu/p/7341056.html  在文章中找哈

http://www.cnblogs.com/yangfengwu/p/6921832.html  在文章中找哈

现在说一下SPI,,其实呢为什么说spi呢,,,,咱的模块最终99.99%都会设计成,发给模块串口的数据自动转发到网络,,,,,模块网络接收的数据自动转发到模块的串口对吧!!!!

那么如果想灵活的配置模块要么通过串口,要么通过其它方式比如说SPI方式....串口刚才说了主要用于用户传输数据使用.....那么我们自己写的灵活配置模块的程序也需要通过一种通信方式告诉模块哈...当然也可以选择IIC,或者自己控制模块的引脚自己编一个

感觉这篇说的够多的了,下一篇再说SPI,关键是自己去做,,自己去做,,自己去做.........

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-09-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • gpio.read()
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档