User Manual for WiFi Car by NodeMCU (DoitCar)

3.2 Code for STA Case on DoitCar

This Subsection presents the STA mode in detail. NodeMCU would be work at STA mode to connect the wireless router. by setting-up TCP client, can connect to the remote server, and realize the remote control by Wechat, web-page and phone APP. 

The example is including init.lua, sta.lua, and DoitCarControlSTA.lua.

init.lua and sta.lua

init.lua is the entrance when NodeMCU starts. If no init.lua, then ignore it; if has, then start to run it. Therefore, If necessory, some code can be put here to start automatically. the code for init.lua is shown as follows.

23     print("\n")
24     print("ESP8266 Started")
25     
26     local exefile="sta"
27     local luaFile = {exefile..".lua","DoitCarControlSTA.lua"}
28     for i, f in ipairs(luaFile) do
29         if file.open(f) then
30           file.close()
31           print("Compile File:"..f)
32           node.compile(f)
33           print("Remove File:"..f)
34           file.remove(f)
35         end
36      end
37     
38     if file.open(exefile..".lc") then
39         dofile(exefile..".lc")
40     else
41         print(exefile..".lc not exist")
42     end
43     exefile=nil;luaFile = nil
44     collectgarbage()

line 1-2: print character;

line 4: define the compiled and run lc file. Note that, not including the suffix ".lc" and/or ".lua";

line 5: define the compiled lua file name;

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

line 7: judge whether the file exists; if no, ignor it, or compile it;

line 8: close the opened file;

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

line 16-20: judge whether the file exists, if yes, then compile the lc file;

line 21-22: release the memory.

DoitCarControlSTA.lua

In the DoitCarControlSTA.lua, would complete the initiation of GPIO port, setting-up for TCP client, try to connect periodically, and adjust of speed by timer. after successful connection and the received-data, would parse the data, and then realize the control of DoitCar. The source code is as follows.

122     --GPIO Define
123     function initGPIO()
124     --1,2EN     D1 GPIO5
125     --3,4EN     D2 GPIO4
126     --1A  ~2A   D3 GPIO0
127     --3A  ~4A   D4 GPIO2
128
129     gpio.mode(0,gpio.OUTPUT);--LED Light on
130     gpio.write(0,gpio.LOW);
131
132     gpio.mode(1,gpio.OUTPUT);gpio.write(1,gpio.LOW);
133     gpio.mode(2,gpio.OUTPUT);gpio.write(2,gpio.LOW);
134
135     gpio.mode(3,gpio.OUTPUT);gpio.write(3,gpio.HIGH);
136     gpio.mode(4,gpio.OUTPUT);gpio.write(4,gpio.HIGH);
137
138     pwm.setup(1,1000,1023);--PWM 1KHz, Duty 1023
139     pwm.start(1);pwm.setduty(1,0);
140     pwm.setup(2,1000,1023);
141     pwm.start(2);pwm.setduty(2,0);
142     end
143
144     --Control Program
145     print("Start DoitRobo Control");
146     initGPIO();
147
148     spdTargetA=1023;--target Speed
149     spdCurrentA=0;--current speed
150     spdTargetB=1023;--target Speed
151     spdCurrentB=0;--current speed
152     stopFlag=true;
153
154     tmr.alarm(1, 200, 1, function()
155         if stopFlag==false then
156             spdCurrentA=spdTargetA;
157             spdCurrentB=spdTargetB;
158             pwm.setduty(1,spdCurrentA);
159             pwm.setduty(2,spdCurrentB);
160         else
161             pwm.setduty(1,0);
162             pwm.setduty(2,0);
163         end
164     end)
165
166     local flagClientTcpConnected=false;
167     print("Start TCP Client");
168     tmr.alarm(3, 5000, 1, function()
169         if flagClientTcpConnected==false then
170         print("Try connect Server");
171         local conn=net.createConnection(net.TCP, false) 
172         conn:connect(6005,"182.92.178.210");
173         conn:on("connection",function(c) 
174             print("TCPClient:conneted to server");
175             flagClientTcpConnected = true;
176             end) 
177         conn:on("disconnection",function(c) 
178             flagClientTcpConnected = false;
179             conn=nil;
180             collectgarbage();
181         end) 
182         conn:on("receive", function(conn, m) 
183             print("TCPClient:"..m);
184             if string.sub(m,1,1)=="b" then
185                 conn:send("cmd=subscribe&topic=".."car".."\r\n");
186             elseif string.sub(m,1,1)=="0" then --stop
187                 pwm.setduty(1,0)
188                 pwm.setduty(2,0)
189                 stopFlag = true;
190                 conn:send("ok\r\n");
191             elseif string.sub(m,1,1)=="1" then --forward
192                 gpio.write(3,gpio.HIGH)
193                 gpio.write(4,gpio.HIGH)
194                 stopFlag = false;
195                 conn:send("ok\r\n");
196             elseif string.sub(m,1,1)=="2" then --backward
197                 gpio.write(3,gpio.LOW)
198                 gpio.write(4,gpio.LOW)
199                 stopFlag = false;
200                 conn:send("ok\r\n");
201             elseif string.sub(m,1,1)=="3" then --left
202                 gpio.write(3,gpio.LOW)
203                 gpio.write(4,gpio.HIGH)
204                 stopFlag = false;
205                 conn:send("ok\r\n");
206             elseif string.sub(m,1,1)=="4" then --right
207                 gpio.write(3,gpio.HIGH);
208                 gpio.write(4,gpio.LOW);
209                 stopFlag = false;
210                 conn:send("ok\r\n");
211             elseif string.sub(m,1,1)=="6" then --A spdUp
212                 spdTargetA = spdTargetA+50;if(spdTargetA>1023) then spdTargetA=1023;end
213                 conn:send("ok\r\n");
214             elseif string.sub(m,1,1)=="7" then --A spdDown
215                 spdTargetA = spdTargetA-50;if(spdTargetA《0) then spdTargetA=0;end
216                 conn:send("ok\r\n");
217             elseif string.sub(m,1,1)=="8" then --B spdUp
218                 spdTargetB = spdTargetB+50;if(spdTargetB>1023) then spdTargetB=1023;end
219                 conn:send(spdTargetA.." "..spdTargetB.."\r\n");
220             elseif string.sub(m,1,1)=="9" then --B spdDown
221                 spdTargetB = spdTargetB-50;if(spdTargetB<0) then spdTargetB=0;end
222                 conn:send(spdTargetA.." "..spdTargetB.."\r\n");
223             else  print("Invalid Command:"..m);end;
224                 collectgarbage();
225             end)
226         end 
227     end)

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

line 25: run initGPIO() function;

line 27-30: define 4 variable used to remember the current and objective speed of left and right wheels;

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

line 33-34: start the periodic timer1. It would compute the current and objective speed after each 200ms to realize the control of speed. By the timer, the current speed ouputs as a PWM cycle.

line 45: use the variable flagClientTcpConnected to remember the connection state of TCP client;

line 47: use the periodic timer3 to handle the TCP connection after each 5ms. Judge whether it is necessory to send a connection requirment by the flagClientTcpConnected. In this section, the server IP IS "182.92.178.210", port="6005";

line 52-60: register the "connection" and "disconnection" case for the TCP Client, respectively;

line 61-104: show the code for realization of the received-data. By the different received-data, can do the relative response. In addtion, line 64 is sent the device name. When NodeMCU is connected to the remote server, then the character "b" is returned. At this time, the device name is need to submitted to the server. Note that, this device name can be used for the control by phone APP, web-page, and/or Wechat. In this section, the device name is tank;

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

Log for this program

30     NodeMCU 0.9.6 build 20150406  powered by Lua 5.1.4
31
32
33     ESP8266 Started
34     Compile File:sta.lua
35     Remove File:sta.lua
36     Compile File:DoitCarControlSTA.lua
37     Remove File:DoitCarControlSTA.lua
38     Ready to Set up wifi mode
39     > Trying Connect to Router, Waiting...
40     Trying Connect to Router, Waiting...
41     Config done, IP is 192.168.1.111
42     Start DoitRobo Control
43     Start TCP Client
44     Try connect Server
45     TCPClient:conneted to server
46     TCPClient:b
47
48     TCPClient:cmd=subscribe&res=1
49
50     Invalid Command:cmd=subscribe&res=1
51
52     TCPClient:1
53
54     TCPClient:2
55
56     TCPClient:3
57
58     TCPClient:4