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

我们写lua用这个软件

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

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

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

让这个灯亮

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

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口就可以了

所以呢让继电器吸合

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吧

第一种方案这样写

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,所以这个定时器就关闭了

1.uart.on("data", 0,function(Revdata)  
2.  
3.            uart.write(0,Revdata)  
4.              
5.    end, 0)  

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

uart.write(0,Revdata)

现在用串口助手测试一下

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

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

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

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

假设程序很大

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

然后看这里

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

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

还有

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

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

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

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

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,关键是自己去做,,自己去做,,自己去做.........

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java技术栈

分布式 | Dubbo 架构设计详解

Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度...

17320
来自专栏北京马哥教育

Python爬虫基本知识:什么是爬虫?

豌豆贴心提醒,本文阅读时间5分钟 一、网络爬虫的定义 网络爬虫,即Web Spider,是一个很形象的名字。 把互联网比喻成一个蜘蛛网,那么Spider就是...

35360
来自专栏阿杜的世界

【转】Dubbo架构设计详解总体架构核心要点参考资料

Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度...

12150
来自专栏月牙寂

k8s源码分析------第三方库go-restful分析

第一时间获取文章,可以关注本人公众号 月牙寂道长 yueyajidaozhang

42060
来自专栏Java架构

阿里分布式服务框架Dubbo的架构总结总体架构参考补充

21040
来自专栏代码世界

Python之线程

操作系统线程理论 线程概念的引入背景 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种...

61980
来自专栏静晴轩

浅谈android中的目录结构

之前在android游戏开发中就遇到本地数据存储的问题:一般情形之下就将动态数据写入SD中存储,在没有SD卡的手机上就需另作处理了;再有在开发android应用...

351100
来自专栏JAVA高级架构

一些设计上的基本常识

最近给团队新人讲了一些设计上的常识,可能会对其它的新人也有些帮助, 把暂时想到的几条,先记在这里。 1. API与SPI分离 框架或组件通常有两类客户...

12410
来自专栏技术小讲堂

iBatis.Net(2):基本概念与配置

写完第一篇,有朋友给我发邮件,说想让我配合实例写会不会更好一些,可是呢,我觉得这就相当于那些北大的什么鸟给无辜的孩子们吃快餐一样,我是坚决反对那样的,知其然不知...

28770
来自专栏周明礼的专栏

一步一步带你搭建一个“摩登”的前端开发环境

最近几年也陆续推出了多种不同的js类型系统用于增强js的健壮性,其中像 typescript 就是其中的佼佼者。当然我今天要讲的并不是typescript,而是...

1.5K00

扫码关注云+社区

领取腾讯云代金券