User Manual for WiFi Car by NodeMCU (DoitCar)

3.1 Code for AP case on DoitCar

This Subsection present the AP operation for the DoitCar in detail. In this case, when NodeMCU works at AP mode, it will listen the TCP connection at the designated port By using the TCP server. Then, the APP (can be downloaded at http://bbs.smartarduino.com/showthread.php?tid=4) can be connected to the TCP server, and can send the control command to control the car.

init.lua

When NodeMCU starts to work, init.lua is used as the entrance of the application. If this file exists, then all the actions can start automatically. Therefore, by this characteristics, some codes can be written here to start automatically.

The code for init. lua is shown as.

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()

Code Parse:

lines 1 and 2: print the characters;

line 4: deine the compiled and run lc file name. Note that, this file name is not including the suffix .lc and/or .lua;

line 5: define the need to compile .lua file name;

line 6: use for to complete the many operation for files;

line 7: judge whether the files exist. If exists, then compile, or ignore it.

line 8: close the opened file;

line 9-12: complete the compile, and generate automatically "DoitCarControl.lc" file;

line 16-20: judge whether the file exists, if exist, then run the compiled lc file;

line 21-22: release memory.

DoitCarControl.lua

In the DoitCarControl.lua document, it will complete the set-up, start, initiation for GPI, set the adjust of speed by the timer, set-up and listen the TCP server port. After receive the data when finishing the set-up, the program analyze the received data, and realize the control for DoitCar. The source code is listed as follows.

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)

line 1~21: define initGPIO() function, init GPIO port;

line 23-43: define setupAPMode() function used to set up AP mode. SSID is set as "DoitWiFi", password is "12345678";

line 46: run setupAPMode() function;

line 49: run initGPIO() function;

line 51-54: define 4 variables used to remember the current and objective speed for left and right wheels;

line 55: define a label used to remember the stop state;

line 58-68: start timer1, compute the current and objective speed after each 200ms to control the speed. the main idea is that, apk set the objective speed, then by the timer, the current speed output as the cycle of PWM;

line 71: set up TCP server, set the disconnect time as 60s from the client;

line 72-121: set up the listening port, register connect funciton, disconnect function, data-received function. The received-data is parsed in the received function;

line 73: register the data-received function, and line 116 is the disconnection function;

line 74-114: realization of data-received function. judge the received-data, and then present different reponse by the different received data;

line 113: use collectgarbage() to show the release memory.

Log

After run, the log is shown as follows.

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