DoitCar 产品说明书

基于DoitCar的AP案例

  本案例详细讲解了基于DoitCar的AP操作过程。程序使NodeMCU的工作在AP模式,通过建立TCP服务器,在指定端口监听TCP连接。手机软件(Car_AP.apk)可以连接到TCP服务器并发送控制指令实现小车的控制。

  本案例程序源码见资料包。   

init.lua文件

  NodeMCU在启动时预留了init.lua作为应用程序入口,如果没有该文件则忽略,如果存在则开始执行该文件。利用这个特性可以在init.lua中写入需要执行的代码,以便上电自动运行。

  本案例使用的init文件如下所示。 资料包中文件名为“init.lua”。


1     print("\n")
2     print("ESP8266 Started")
3     
4     local exefile="DoitCarControl"
5     local luaFile = {exefile..".lua"}
6     for i, f in ipairs(luaFile) do
7         if file.open(f) then
8           file.close()
9           print("Compile File:"..f)
10           node.compile(f)
11           print("Remove File:"..f)
12           file.remove(f)
13         end
14      end
15     
16     if file.open(exefile..".lc") then
17         dofile(exefile..".lc")
18     else
19         print(exefile..".lc not exist")
20     end
21     exefile=nil;luaFile = nil
22     collectgarbage()

  程序第1、2行打印字符信息。

  第3行定义编译后需要执行的lc文件名,注意不包含后缀“.lc”或者“.lua”。

  第5行定义需要编译的lua文件名。

  第6行是使用for循环完成多个文件的操作。

  第7行判断文件是否存在,如果存在则执行编译。如果不存在则忽略。

  第8行是关闭已经打开的文件。

  第9~12行完成编译,自动生成“DoitCarControl.lc”文件。

  第16~20行判断文件是否存在,如果存在则执行刚刚编译完成的lc文件。

  第21~22行是回收内存。   

DoitCarControl.lua文件

  在DoitCarControl.lua文件中完成ap模式的建立和启动、初始化GPIO端口,设置定时器对速度进行调节,建立TCP服务器端口并实现端口监听。在建立连接并收到数据后,对数据进行解析,实现DoitCar小车电机的控制。

  源码如下。


1     --GPIO Define
2     function initGPIO()
3     --1,2EN     D1 GPIO5
4     --3,4EN     D2 GPIO4
5     --1A  ~2A   D3 GPIO0
6     --3A  ~4A   D4 GPIO2
7     
8     gpio.mode(0,gpio.OUTPUT);--LED Light on
9     gpio.write(0,gpio.LOW);
10     
11     gpio.mode(1,gpio.OUTPUT);gpio.write(1,gpio.LOW);
12     gpio.mode(2,gpio.OUTPUT);gpio.write(2,gpio.LOW);
13     
14     gpio.mode(3,gpio.OUTPUT);gpio.write(3,gpio.HIGH);
15     gpio.mode(4,gpio.OUTPUT);gpio.write(4,gpio.HIGH);
16     
17     pwm.setup(1,1000,1023);--PWM 1KHz, Duty 1023
18     pwm.start(1);pwm.setduty(1,0);
19     pwm.setup(2,1000,1023);
20     pwm.start(2);pwm.setduty(2,0);
21     end
22     
23     function setupAPMode()
24     print("Ready to start soft ap")
25         
26     cfg={}
27     cfg.ssid="DoitWiFi";
28     cfg.pwd="12345678"
29     wifi.ap.config(cfg)
30     
31     cfg={}
32     cfg.ip="192.168.1.1";
33     cfg.netmask="255.255.255.0";
34     cfg.gateway="192.168.1.1";
35     wifi.ap.setip(cfg);
36     wifi.setmode(wifi.SOFTAP)
37     
38     str=nil;
39     ssidTemp=nil;
40     collectgarbage();
41     
42     print("Soft AP started")
43     end
44     
45     --Set up AP
46     setupAPMode();
47     
48     print("Start DoitRobo Control");
49     initGPIO();
50     
51     spdTargetA=1023;--target Speed
52     spdCurrentA=0;--current speed
53     spdTargetB=1023;--target Speed
54     spdCurrentB=0;--current speed
55     stopFlag=true;
56     
57     --speed control procedure
58     tmr.alarm(1, 200, 1, function()
59         if stopFlag==false then
60             spdCurrentA=spdTargetA;
61             spdCurrentB=spdTargetB;
62             pwm.setduty(1,spdCurrentA);
63             pwm.setduty(2,spdCurrentB);
64         else
65             pwm.setduty(1,0);
66             pwm.setduty(2,0);
67         end
68     end)
69     
70     --Setup tcp server at port 9003
71     s=net.createServer(net.TCP,60);
72     s:listen(9003,function(c) 
73         c:on("receive",function(c,d) 
74           print("TCPSrv:"..d)
75           if string.sub(d,1,1)=="0" then --stop
76             pwm.setduty(1,0)
77             pwm.setduty(2,0)
78             stopFlag = true;
79             c:send("ok\r\n");
80           elseif string.sub(d,1,1)=="1" then --forward
81             gpio.write(3,gpio.HIGH)
82             gpio.write(4,gpio.HIGH)
83             stopFlag = false;
84             c:send("ok\r\n");
85           elseif string.sub(d,1,1)=="2" then --backward
86             gpio.write(3,gpio.LOW)
87             gpio.write(4,gpio.LOW)
88             stopFlag = false;
89             c:send("ok\r\n");
90           elseif string.sub(d,1,1)=="3" then --left
gpio.write(3,gpio.LOW)
92             gpio.write(4,gpio.HIGH)
93             stopFlag = false;
94             c:send("ok\r\n");
95           elseif string.sub(d,1,1)=="4" then --right
96             gpio.write(3,gpio.HIGH);
97             gpio.write(4,gpio.LOW);
98             stopFlag = false;
99             c:send("ok\r\n");
100  elseif string.sub(d,1,1)=="6" then --A spdUp
101             spdTargetA = spdTargetA+50;if(spdTargetA>1023) then spdTargetA=1023;end
102             c:send("ok\r\n");
103           elseif string.sub(d,1,1)=="7" then --A spdDown
104             spdTargetA = spdTargetA-50;if(spdTargetA《0) then spdTargetA=0;end
105             c:send("ok\r\n");
106           elseif string.sub(d,1,1)=="8" then --B spdUp
107             spdTargetB = spdTargetB+50;if(spdTargetB>1023) then spdTargetB=1023;end
108             c:send("ok\r\n");
109           elseif string.sub(d,1,1)=="9" then --B spdDown
110             spdTargetB = spdTargetB-50;if(spdTargetB《0) then spdTargetB=0;end
111             c:send("ok\r\n");        
112           else  print("Invalid Command:"..d);c:send("Invalid CMD\r\n");end;
113           collectgarbage();
114         end) --end c:on receive
115     
116         c:on("disconnection",function(c) 
117             print("TCPSrv:Client disconnet");
118             collectgarbage();
119         end) 
120         print("TCPSrv:Client connected")
121     end)

  程序第1~21行定义initGPIO()函数,初始化GPIO口。

  第23~43行定义setupAPMode()函数,用于建立AP热点。SSID设置为:“DoitWiFi”,密码设置为“12345678”。

  第46行执行setupAPMode()函数。

  第49行执行initGPIO()函数。

  第51~54行定义了四个变量,用于记录左轮、右轮的当前速度和目标设置速度。

  第55行定义一个标志,用于记录停止状态。

  第58~68行启动了周期性定时器1,每隔200毫秒对当前速度和目标速度进行计算,实现速度控制。其基本思路是:apk设置目标速度,程序在定时器中,将当前速度直接作为PWM占空比设置值进行输出。   第71行建立TCP服务器,设置客户端断开超时时间为60秒。

  第72~121行建立监听端口,注册连接函数、断开连接函数、数据接收函数,在数据接收函数中对数据进行解析。

  第73行是注册数据接收函数。第116行是注册断开连接函数。

  第74~114行是数据接收函数的实现代码。在这里面判断接收数据,并根据不同数据执行响应的动作。

  第113行,使用了collectgarbage()函数显示的回收内存。   

程序Log

     程序运行Log如下。   


1     NodeMCU 0.9.6 build 20150406  powered by Lua 5.1.4
2
3
4 ESP8266 Started 5 Ready to start soft ap 6 Soft AP started 7 Start DoitRobo Control 8 TCPSrv:Client connected 9 TCPSrv:1 10
11 TCPSrv:2 12
13 TCPSrv:3 14
15 TCPSrv:4 16
17 TCPSrv:0 18
19 TCPSrv:8 20
21 TCPSrv:9 22
23 TCPSrv:6 24
25 TCPSrv:7 26
27 TCPSrv:0 28
29 TCPSrv:Client disconnet