2015-11-16 14:09:43 [显示全部楼层]
18385浏览
查看: 18385|回复: 16

[进阶] WiFi远程监控加网页控制智能Arduino小车制作过程介绍,持续...

[复制链接]
本帖最后由 sxmwhl 于 2015-11-16 19:32 编辑

先晒晒我的Arduino小车,加无线路由模块,刷openwrt可以实现远程监控和网页控制
WiFi远程监控加网页控制智能Arduino小车制作过程介绍,持续...图1

优酷视频观看:



制作过程,以后慢慢更新。。。


先说所需硬件:
1、小车部分主体硬件见某淘宝店
2、需另加WiFi部分,用刷了openwrt的路由器,我用的GL-inet;
3、添加lcd1602显示屏和i2c模块;
4、添加两个超声波测距模块,增加小车检测障碍面积。
硬件部分组装:
1、贴几张关键的图


详细我写的文章:《
Arduino智能小车硬件安装说明


sxmwhl  高级技师
 楼主|

发表于 2015-11-16 14:12:16

新人处女贴,自己顶起,吸引人气:victory:
回复

使用道具 举报

丄帝De咗臂  高级技匠

发表于 2015-11-16 14:29:28

很不错,顶一个,我也想做
回复

使用道具 举报

hnyzcj  版主

发表于 2015-11-16 17:58:22

顶起,求分享。
回复

使用道具 举报

大连林海  初级技神

发表于 2015-11-16 18:25:07

很不错,顶一个,我也想做
回复

使用道具 举报

sxmwhl  高级技师
 楼主|

发表于 2015-11-16 19:33:03

大连林海 发表于 2015-11-16 18:25
很不错,顶一个,我也想做

慢慢来,我也在琢磨着搞:loveliness:。。。
回复

使用道具 举报

孙毅  初级技匠

发表于 2015-11-17 09:30:27

帮顶一个!强悍
回复

使用道具 举报

dsweiliang  初级技神

发表于 2015-11-17 09:56:26

很期待,赶紧更新
回复

使用道具 举报

visionsl  初级技匠

发表于 2015-11-17 15:59:24

舵机控制超声波的部分挺有意思
回复

使用道具 举报

吹口琴的钢铁侠  初级技匠

发表于 2015-11-21 08:56:30

其实不加openwrt也能远程控制
回复

使用道具 举报

eversence213  中级技师

发表于 2015-12-10 13:42:11

期待跟新!
回复

使用道具 举报

sxmwhl  高级技师
 楼主|

发表于 2016-1-23 17:28:00

好久没来,没法编辑了,在后面给贴吧
该上代码了。
小车部分
  1. #include <IRremote.h>
  2. #include <LiquidCrystal_I2C.h>
  3. #include <Wire.h>
  4. #include <Servo.h>
  5. Servo myservo;//定义舵机变量名
  6. LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
  7. unsigned long lastMillis = millis();
  8. const int LightPin = 0;
  9. const int TemPin = 3;
  10. const int L298nIn1 = 2;
  11. const int L298nIn2 = 3;
  12. const int L298nIn3 = 4;
  13. const int L298nIn4 = 5;
  14. const int EchoPinR = 6;
  15. const int TrigPinR = 7;
  16. const int TrigPinM = 8;
  17. const int EchoPinM = 9;
  18. const int EchoPinL = 11;
  19. const int TrigPinL = 12;
  20. const int ServoPin = 10;
  21. const int IRPin = 11;
  22. const long on0 = 0x00FF6897;
  23. const long on1 = 0x00FF30CF;
  24. const long on2 = 0x00FF18E7;
  25. const long on3 = 0x00FF7A85;
  26. const long on4 = 0x00FF10EF;
  27. const long on5 = 0x00FF38C7;
  28. const long on6 = 0x00FF5AA5;
  29. const long on7 = 0x00FF42BD;
  30. const long on8 = 0x00FF4AB5;
  31. const long on9 = 0x00FF52AD;
  32. const int KeepAway = 25;
  33. const int KeepAwayS = 10;
  34. const int LookDelay = 300;
  35. const int TurnDelay = 500;
  36. const int BackDelay = 600;
  37. const int ReboundDelay = 150;
  38. String Mode = "M";
  39. IRrecv irrecv(IRPin);
  40. decode_results results;
  41. void setup()
  42. {
  43.   Serial.begin(115200);
  44.   myservo.attach(10);//定义舵机接口(9、10 都可以,缺点只能控制2 个)
  45.   lcd.init();
  46.   lcd.backlight();
  47.   pinMode(EchoPinM, INPUT);
  48.   pinMode(TrigPinM, OUTPUT);
  49.   pinMode(EchoPinL, INPUT);
  50.   pinMode(TrigPinL, OUTPUT);
  51.   pinMode(EchoPinR, INPUT);
  52.   pinMode(TrigPinR, OUTPUT);
  53.   pinMode(IRPin, INPUT);
  54.   pinMode(L298nIn1, OUTPUT);
  55.   pinMode(L298nIn2, OUTPUT);
  56.   pinMode(L298nIn3, OUTPUT);
  57.   pinMode(L298nIn4, OUTPUT);
  58.   irrecv.enableIRIn(); // Start the receiver
  59.   lcd.print("I am Dogeva!");
  60. }
  61. int readTem() {
  62.   int val;//定义变量
  63.   int dat;//定义变量
  64.   val = analogRead(TemPin); // 读取传感器的模拟值并赋值给val
  65.   dat = map(val, 0, 1023, 0, 100);
  66.   //dat = (125 * val) >> 8; //温度计算公式
  67.   return dat;
  68. }
  69. int readLight() {
  70.   int val;
  71.   val = analogRead(LightPin);
  72.   val = map(val, 0, 1023, 0, 1000);
  73.   return 1000 - val;
  74. }
  75. void goForward() {
  76.   digitalWrite(L298nIn1, HIGH);
  77.   digitalWrite(L298nIn2, LOW);
  78.   digitalWrite(L298nIn3, LOW);
  79.   digitalWrite(L298nIn4, HIGH);
  80. }
  81. void goBack() {
  82.   digitalWrite(L298nIn1, LOW);
  83.   digitalWrite(L298nIn2, HIGH);
  84.   digitalWrite(L298nIn3, HIGH);
  85.   digitalWrite(L298nIn4, LOW);
  86. }
  87. void goStop() {
  88.   digitalWrite(L298nIn1, LOW);
  89.   digitalWrite(L298nIn2, LOW);
  90.   digitalWrite(L298nIn3, LOW);
  91.   digitalWrite(L298nIn4, LOW);
  92. }
  93. void goRebound() {
  94.   digitalWrite(L298nIn1, LOW);
  95.   digitalWrite(L298nIn2, HIGH);
  96.   digitalWrite(L298nIn3, HIGH);
  97.   digitalWrite(L298nIn4, LOW);
  98.   delay(ReboundDelay);
  99.   goStop();
  100. }
  101. void turnRight1() {
  102.   digitalWrite(L298nIn1, LOW);
  103.   digitalWrite(L298nIn2, HIGH);
  104.   digitalWrite(L298nIn3, LOW);
  105.   digitalWrite(L298nIn4, HIGH);
  106. }
  107. void turnRight2() {
  108.   digitalWrite(L298nIn1, LOW);
  109.   digitalWrite(L298nIn2, HIGH);
  110.   digitalWrite(L298nIn3, LOW);
  111.   digitalWrite(L298nIn4, HIGH);
  112. }
  113. void turnLeft4() {
  114.   digitalWrite(L298nIn1, HIGH);
  115.   digitalWrite(L298nIn2, LOW);
  116.   digitalWrite(L298nIn3, HIGH);
  117.   digitalWrite(L298nIn4, LOW);
  118. }
  119. void turnLeft5() {
  120.   digitalWrite(L298nIn1, HIGH);
  121.   digitalWrite(L298nIn2, LOW);
  122.   digitalWrite(L298nIn3, HIGH);
  123.   digitalWrite(L298nIn4, LOW);
  124. }
  125. int IRNumber() {
  126.   if (irrecv.decode(&results))
  127.   {
  128.     // If it's been at least 1/4 second since the last
  129.     // IR received, toggle the relay
  130.     if (millis() - lastMillis > 250)
  131.     {
  132.       //on = !on;
  133.       //digitalWrite(13, on ? HIGH : LOW);
  134.       IRDump(&results);
  135.     }
  136.     lastMillis = millis();
  137.     irrecv.resume(); // Receive the next value
  138.     switch (results.value) {
  139.       case on0:
  140.         return 0;
  141.       case on1:
  142.         return 1;
  143.       case on2:
  144.         return 2;
  145.       case on3:
  146.         return 3;
  147.       case on4:
  148.         return 4;
  149.       case on5:
  150.         return 5;
  151.       case on6:
  152.         return 6;
  153.       case on7:
  154.         return 7;
  155.       case on8:
  156.         return 8;
  157.       case on9:
  158.         return 9;
  159.       default:
  160.         return -1;
  161.     }
  162.   }
  163. }
  164. void IRDump(decode_results *results) {
  165.   int count = results->rawlen;
  166.   if (results->decode_type == UNKNOWN)
  167.   {
  168.     Serial.println("Could not decode message");
  169.   }
  170.   else
  171.   {
  172.     if (results->decode_type == NEC)
  173.     {
  174.       Serial.print("Decoded NEC: ");
  175.     }
  176.     else if (results->decode_type == SONY)
  177.     {
  178.       Serial.print("Decoded SONY: ");
  179.     }
  180.     else if (results->decode_type == RC5)
  181.     {
  182.       Serial.print("Decoded RC5: ");
  183.     }
  184.     else if (results->decode_type == RC6)
  185.     {
  186.       Serial.print("Decoded RC6: ");
  187.     }
  188.     Serial.print(results->value, HEX);
  189.     Serial.print(" (");
  190.     Serial.print(results->bits, DEC);
  191.     Serial.println(" bits)");
  192.   }
  193.   Serial.print("Raw (");
  194.   Serial.print(count, DEC);
  195.   Serial.print("): ");
  196.   for (int i = 0; i < count; i++)
  197.   {
  198.     if ((i % 2) == 1) {
  199.       Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
  200.     }
  201.     else
  202.     {
  203.       Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
  204.     }
  205.     Serial.print(" ");
  206.   }
  207.   Serial.println("");
  208. }
  209. float checkDistance(int TrigPin, int EchoPin) {
  210.   float distance;
  211.   digitalWrite(TrigPin, LOW);
  212.   delayMicroseconds(2);
  213.   digitalWrite(TrigPin, HIGH);
  214.   delayMicroseconds(10);
  215.   digitalWrite(TrigPin, LOW);
  216.   // 检测脉冲宽度,并计算出距离
  217.   distance = pulseIn(EchoPin, HIGH) / 58.00;
  218.   return distance;
  219. }
  220. int lookAround() {
  221.   lookRight1();
  222.   int D1 = checkDistance(TrigPinM, EchoPinM);
  223.   lookRight2();
  224.   int D2 = checkDistance(TrigPinM, EchoPinM);
  225.   lookForward();
  226.   int D3 = checkDistance(TrigPinM, EchoPinM);
  227.   lookLeft4();
  228.   int D4 = checkDistance(TrigPinM, EchoPinM);
  229.   lookLeft5();
  230.   int D5 = checkDistance(TrigPinM, EchoPinM);
  231.   if (D1 > D2 && D1 > D3 && D1 > D4 && D1 > D5 && D1 > KeepAway)return 1;
  232.   if (D2 > D1 && D2 > D3 && D2 > D4 && D2 > D5 && D2 > KeepAway)return 2;
  233.   if (D3 > D2 && D3 > D1 && D3 > D4 && D3 > D5 && D3 > KeepAway)return 3;
  234.   if (D4 > D2 && D4 > D3 && D4 > D1 && D4 > D5 && D4 > KeepAway)return 4;
  235.   if (D5 > D2 && D5 > D3 && D5 > D4 && D5 > D1 && D5 > KeepAway)return 5;
  236.   return 0;
  237. }
  238. void lookRight1() {
  239.   myservo.write(5);
  240.   delay(LookDelay);
  241. }
  242. void lookRight2() {
  243.   myservo.write(45);
  244.   delay(LookDelay);
  245. }
  246. void lookForward() {
  247.   myservo.write(90);
  248.   delay(LookDelay);
  249. }
  250. void lookLeft4() {
  251.   myservo.write(135);
  252.   delay(LookDelay);
  253. }
  254. void lookLeft5() {
  255.   myservo.write(175);
  256.   delay(LookDelay);
  257. }
  258. void autoMove() {
  259.   lcd.clear();
  260.   lcd.setCursor(0, 1) ; //设置光标位置为第二行第一个位置  
  261.   lookForward();
  262.   int distanceM = checkDistance(TrigPinM, EchoPinM);
  263.   int distanceR = checkDistance(TrigPinR, EchoPinR);
  264.   int distanceL = checkDistance(TrigPinL, EchoPinL);
  265.   if (distanceM > KeepAway && distanceR > KeepAwayS && distanceL > KeepAwayS) {
  266.     goForward();
  267.   } else {
  268.     for (int i = 0; i < 100; i++)
  269.     {
  270.       goStop();
  271.       goRebound();
  272.       if (distanceR <= KeepAwayS) {
  273.         turnLeft4();
  274.         return;
  275.       }
  276.       if (distanceL <= KeepAwayS) {
  277.         turnRight2();
  278.         return;
  279.       }
  280.       switch (lookAround()) {
  281.         case 1:
  282.           turnRight1();
  283.           delay(TurnDelay);
  284.           goStop();
  285.           return;
  286.         case 2:
  287.           turnRight2();
  288.           delay(TurnDelay / 2);
  289.           goStop();
  290.           return;
  291.         case 3:
  292.           goForward();
  293.           return;
  294.         case 4:
  295.           turnLeft4();
  296.           delay(TurnDelay / 2);
  297.           goStop();
  298.           return;
  299.         case 5:
  300.           turnLeft5();
  301.           delay(TurnDelay);
  302.           goStop();
  303.           return;
  304.         default:
  305.           break;
  306.       }
  307.       goBack();
  308.       delay(BackDelay);
  309.       goStop();
  310.     }
  311.   }
  312. }
  313. void manualMove(String s) {
  314.   if (s.length() > 0)  {
  315.     lcd.clear();
  316.     lcd.setCursor(0, 1) ; //设置光标位置为第二行第一个位置   
  317.     if (s.length() == 1) {
  318.       if (String(s) == String("0")) {
  319.         lcd.print("Stop");
  320.         goStop();
  321.       }
  322.       if (String(s) == String("1")) {
  323.         lcd.print("Go Forward");
  324.         goForward();
  325.       }
  326.       if (String(s) == String("2")) {
  327.         lcd.print("Turn Left");
  328.         turnLeft5();
  329.       }
  330.       if (String(s) == String("3")) {
  331.         lcd.print("Go Back");
  332.         goBack();
  333.       }
  334.       if (String(s) == String("4")) {
  335.         lcd.print("Turn Right");
  336.         turnRight1();
  337.       }
  338.     }
  339.     if (s.length() > 1) {
  340.       lcd.print(s);
  341.     }
  342.   }
  343. }
  344. void loop()  {
  345.   String comdata = "";
  346.   while (Serial.available() > 0) {
  347.     comdata += char(Serial.read());
  348.     delay(2);
  349.   }
  350.   if (comdata == "A" && Mode != "A") {
  351.     lcd.clear();
  352.     lcd.setCursor(0, 0) ; //设置光标位置为第二行第一个位置   
  353.     lcd.print("Auto Mode");
  354.     goStop();
  355.     lookForward();
  356.     Mode = "A";
  357.   }
  358.   if (comdata == "M" && Mode != "M") {
  359.     lcd.clear();
  360.     lcd.setCursor(0, 0) ; //设置光标位置为第二行第一个位置   
  361.     lcd.print("Manual Mode");
  362.     goStop();
  363.     lookForward();
  364.     Mode = "M";
  365.   }
  366.   if (Mode == "A") autoMove();
  367.   if (Mode == "M") manualMove(comdata);
  368.   /*lcd.clear();
  369.   lcd.setCursor(0, 1) ; //设置光标位置为第二行第一个位置
  370.   lcd.print("Tep:");
  371.   lcd.print(readTem());
  372.   Serial.println(readTem());
  373.   lcd.print("C Lt:");
  374.   lcd.print(readLight());
  375.   Serial.println(readLight());
  376.   delay(1000);
  377.   String comdata = "";
  378.   while (Serial.available() > 0) {
  379.     comdata += char(Serial.read());
  380.     delay(2);
  381.   }
  382.   if (comdata.length() > 0)
  383.   {
  384.     //lcd.clear();
  385.     if (comdata.length() == 1) {
  386.       if (String(comdata) == String("0")) {
  387.         lcd.print("Stop");
  388.         goStop();
  389.       }
  390.       if (String(comdata) == String("1")) {
  391.         lcd.print("Go Forward");
  392.         goForward();
  393.       }
  394.       if (String(comdata) == String("2")) {
  395.         lcd.print("Turn Left");
  396.         turnLeft5();
  397.       }
  398.       if (String(comdata) == String("3")) {
  399.         lcd.print("Go Back");
  400.         goBack();
  401.       }
  402.       if (String(comdata) == String("4")) {
  403.         lcd.print("Turn Right");
  404.         turnRight1();
  405.       }
  406.     }
  407.     if (comdata.length() > 1) {
  408.       lcd.print(comdata);
  409.     }
  410.     if (comdata.length() > 16) {
  411.       for (int positionCounter = 0; positionCounter < comdata.length() - 16; positionCounter++) {
  412.         // scroll one position left:
  413.         lcd.scrollDisplayLeft();
  414.         // wait a bit:
  415.         delay(600);
  416.       }
  417.     }
  418.     comdata = "";
  419.   }*/
  420. }
复制代码

路由器部分
lua 脚本
  1. #!/usr/bin/lua
  2. io.output("/dev/ttyATH0")
  3. io.write(os.getenv("QUERY_STRING"))
复制代码

web网页部分
  1. <html>
  2. <head>
  3. </head>
  4. <body>
  5. <div style="float:left">
  6. <script>
  7. function sendSer(value){
  8. document.getElementById("ser").src="http://192.168.1.101/cgi-bin/web2ser?"+value;
  9. }
  10. </script>
  11. <table>
  12. <tr><td/><img id="ser" width="1" height="1">
  13. <td><input type="button" value="前进" /></td><td/></tr>
  14. <tr><td><input type="button" value="左转" /></td><td/>
  15. <td><input type="button" value="右转" /></td></tr>
  16. <tr><td/><td><input type="button" value="后退" /></td><td/></tr>
  17. <tr><td colspan="3" align="middle"> <input type="button" value="自动控制" /></td></tr>
  18. <tr><td colspan="3" align="middle"> <input type="button" value="手动控制" /></td></tr>
  19. </table>
  20. </div>
  21. </body>
  22. </html>
复制代码


回复

使用道具 举报

凌风清羽  中级技匠

发表于 2016-3-27 20:57:47

怎么能收藏帖子,想试着做一下
回复

使用道具 举报

sxmwhl  高级技师
 楼主|

发表于 2016-3-29 22:47:38

凌风清羽 发表于 2016-3-27 20:57
怎么能收藏帖子,想试着做一下

点击标题右下角的五角星就可以收藏了:victory:
回复

使用道具 举报

凌风清羽  中级技匠

发表于 2016-3-30 15:34:46

sxmwhl 发表于 2016-3-29 22:47
点击标题右下角的五角星就可以收藏了

好的,谢谢
回复

使用道具 举报

WeiSunny0910  学徒

发表于 2016-10-12 08:38:29

大大,这款能实现在非同一网络下的远程监控吗?怎么组网呢?
回复

使用道具 举报

20060606  高级技匠

发表于 2020-8-15 08:59:48

感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail