请教:项目“网页控制Arduino”如何扩展多路LED开关?-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 16712|回复: 16

[已解决] 请教:项目“网页控制Arduino”如何扩展多路LED开关?

[复制链接]
发表于 2014-6-9 19:04 | 显示全部楼层 |阅读模式
我实验的板子是OpenJumper进阶套件中的Zbuino Ethernet,尝试在源代码基础上扩展D2~9共8路LED输出,每个单路都正常,但最多扩展到4路,而且极不稳定。另外一个问题:如果网页上设置8路16个button,通常是“网页无反应”。

已经实验了3天了...(我要疯了)
 楼主| 发表于 2014-6-9 19:05 | 显示全部楼层
附上修改后的代码:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);
EthernetServer server(80);
EthernetClient client;
String readString;
int Light2=2;  /* 2-9, Total 8 line OUT */
int Light3=3;
int Light4=4;
int Light5=5;
int Light6=6;
int Light7=7;
int Light8=8;
int Light9=9;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  
  pinMode(Light2,OUTPUT);
  pinMode(Light3,OUTPUT);
  pinMode(Light4,OUTPUT);
  pinMode(Light5,OUTPUT);
  pinMode(Light6,OUTPUT);
  pinMode(Light7,OUTPUT);
  pinMode(Light8,OUTPUT);
  pinMode(Light9,OUTPUT);

  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  client = server.available();// 监听连入的客户端
  if (client)
  {
    Serial.println("new client");// 一次http请求结束都带有一个空行   
    boolean currentLineIsBlank = true;
    while (client.connected())
        {
      if (client.available())
          {
        char c = client.read();
        //将收到的信息都保存在readString函数中
        readString += c;
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank)
                {
          Serial.print(readString);
          // 发送HTML文本
          SendHTML();
          break;
        }
                // 检测是否有换行符
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
                // 检测是否有回车符
        else if (c != '\r')
                        {
                          // you've gotten a character on the current line
                          currentLineIsBlank = false;
                }
      }
    }
    // 等待浏览器接收数据
        delay(1);

    //关闭连接
    client.stop();
        Serial.println("client disonnected");

/*====================== On ==========================*/
// 检查收到的信息中是否有”/2?on”,有则开灯
  if(readString.indexOf("/2?on") >0)//checks for on
  {
        digitalWrite(Light2, HIGH);
        Serial.println("Led 2 On");
  }
// 检查收到的信息中是否有”/3?on”,有则开灯
  if(readString.indexOf("/3?on") >0)//checks for on
  {
        digitalWrite(Light3, HIGH);
        Serial.println("Led 3 On");
  }
// 检查收到的信息中是否有”/4?on”,有则开灯
  if(readString.indexOf("/4?on") >0)//checks for on
  {
        digitalWrite(Light4, HIGH);
        Serial.println("Led 4 On");
  }

// 检查收到的信息中是否有”/5?on”,有则开灯
  if(readString.indexOf("/5?on") >0)//checks for on
  {
        digitalWrite(Light5, HIGH);
        Serial.println("Led 5 On");
  }

// 检查收到的信息中是否有”/6?on”,有则开灯
  if(readString.indexOf("/6?on") >0)//checks for on
  {
        digitalWrite(Light6, HIGH);
        Serial.println("Led 6 On");
  }
// 检查收到的信息中是否有”/7?on”,有则开灯
  if(readString.indexOf("/7?on") >0)//checks for on
  {
        digitalWrite(Light7, HIGH);
        Serial.println("Led 7 On");
  }
// 检查收到的信息中是否有”/8?on”,有则开灯
  if(readString.indexOf("/8?on") >0)//checks for on
  {
        digitalWrite(Light8, HIGH);
        Serial.println("Led 8 On");
  }
// 检查收到的信息中是否有”/9?on”,有则开灯
  if(readString.indexOf("/9?on") >0)//checks for on
  {
        digitalWrite(Light9, HIGH);
        Serial.println("Led 9 On");
  }

/*====================== Off ==========================*/
// 检查收到的信息中是否有”/2?off”,有则关灯
    if(readString.indexOf("/2?off") >0)//checks for off
    {
      digitalWrite(Light2, LOW);    // set pin 2 low
      Serial.println("Led 2 Off");
    }
// 检查收到的信息中是否有”/3?off”,有则关灯
    if(readString.indexOf("/3?off") >0)//checks for off
    {
      digitalWrite(Light3, LOW);    // set pin 3 low
      Serial.println("Led 3 Off");
    }
// 检查收到的信息中是否有”/4?off”,有则关灯
    if(readString.indexOf("/4?off") >0)//checks for off
    {
      digitalWrite(Light4, LOW);    // set pin 4 low
      Serial.println("Led 4 Off");
    }

// 检查收到的信息中是否有”/5?off”,有则关灯
    if(readString.indexOf("/5?off") >0)//checks for off
    {
      digitalWrite(Light5, LOW);    // set pin 5 low
      Serial.println("Led 5 Off");
    }

// 检查收到的信息中是否有”/6?off”,有则关灯
    if(readString.indexOf("/6?off") >0)//checks for off
    {
      digitalWrite(Light6, LOW);    // set pin 6 low
      Serial.println("Led 6 Off");
    }
// 检查收到的信息中是否有”/7?off”,有则关灯
    if(readString.indexOf("/7?off") >0)//checks for off
    {
      digitalWrite(Light7, LOW);    // set pin 7 low
      Serial.println("Led 7 Off");
    }
// 检查收到的信息中是否有”/8?off”,有则关灯
    if(readString.indexOf("/8?off") >0)//checks for off
    {
      digitalWrite(Light8, LOW);    // set pin 8 low
      Serial.println("Led 8 Off");
    }
// 检查收到的信息中是否有”/9?off”,有则关灯
    if(readString.indexOf("/9?off") >0)//checks for off
    {
      digitalWrite(Light9, LOW);    // set pin 9 low
      Serial.println("Led 9 Off");
    }

    readString="";
  }
}

// 用于输出HTML文本的函数
void SendHTML()
{
// 发送标准的HTTP响应
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("Connection: close");
  client.println("");
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<head><title>TEST !</title></head>");

// 每十秒刷新一次
  client.println("<meta http-equiv=\"refresh\" content=\"10\">");
  client.println("<body>");
  
  client.println("<div style=\"font-size: 30px;\">");  
  client.println("Light intensity: "); //显示室内光照度
  client.println(analogRead(A0)); // 即将A0采集到的模拟值输出
  client.println("<br />");
  
  // 2 on按钮
  client.println("<a href=\"/2?on\" target=\"inlineframe\"><button>2 on</button></a>");
  // 2 off按钮
  client.println("<a href=\"/2?off\" target=\"inlineframe\"><button>2 off</button></a>");
  client.println("&nbsp;");

  // 3 on按钮
  client.println("<a href=\"/3?on\" target=\"inlineframe\"><button>3 on</button></a>");
  // 3 off按钮
  client.println("<a href=\"/3?off\" target=\"inlineframe\"><button>3 off</button></a>");
  client.println("&nbsp;");

  // 4 on按钮
  client.println("<a href=\"/4?on\" target=\"inlineframe\"><button>4 on</button></a>");
  // 4 off按钮
  client.println("<a href=\"/4?off\" target=\"inlineframe\"><button>4 off</button></a>");
  client.println("&nbsp;");

  // 5 on按钮
  client.println("<a href=\"/5?on\" target=\"inlineframe\"><button>5 on</button></a>");
  // 5 off按钮
  client.println("<a href=\"/5?off\" target=\"inlineframe\"><button>5 off</button></a>");
  client.println("&nbsp;");

  // 6 on按钮
  client.println("<a href=\"/6?on\" target=\"inlineframe\"><button>6 on</button></a>");
  // 6 off按钮
  client.println("<a href=\"/6?off\" target=\"inlineframe\"><button>6 off</button></a>");
  client.println("&nbsp;");   

  // 7 on按钮
  client.println("<a href=\"/7?on\" target=\"inlineframe\"><button>7 on</button></a>");
  // 7 off按钮
  client.println("<a href=\"/7?off\" target=\"inlineframe\"><button>7 off</button></a>");
  client.println("&nbsp;");

  // 8 on按钮
  client.println("<a href=\"/8?on\" target=\"inlineframe\"><button>8 on</button></a>");
  // 8 off按钮
  client.println("<a href=\"/8?off\" target=\"inlineframe\"><button>8 off</button></a>");
  client.println("&nbsp;");   

  // 9 on按钮
  client.println("<a href=\"/9?on\" target=\"inlineframe\"><button>9 on</button></a>");
  // 9 off按钮
  client.println("<a href=\"/9?off\" target=\"inlineframe\"><button>9 off</button></a>");
  client.println("&nbsp;");

  client.println("<IFRAME name=inlineframe style=\"display:none\" >");         
  client.println("</IFRAME>");
  client.println("<br /> ");
  
  client.println("</body>");
  client.println("</html>");  
}
 楼主| 发表于 2014-6-9 19:21 | 显示全部楼层
设置4路输出网页是可以显示的。查看串口通讯记录:
GET /4?on HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Referer: http://192.168.1.177/
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64client disonnected
(这里停顿了几秒钟,然后继续下面的内容,估计是没读到上面“/4?on”,直接读下面空内容了)
new client
GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding: gziclient disonnected
 楼主| 发表于 2014-6-9 19:25 | 显示全部楼层
今天测试3路可以,但是4路就不行了...

3路LED输出,代码中是直接注释掉网页中设置5~9按钮部分的内容。
发表于 2014-6-9 19:34 | 显示全部楼层
咱可以定两个参数不  一个是按钮号  一个状态  然后用switch  或者 方法来判断   
你这一堆ifif的    再说这一堆if 能不能替换成if……else if 结构
还有后面一堆输出,好多内容都是重复的  咱弄个 for或者while 循环多好啊
发表于 2014-6-9 19:59 | 显示全部楼层
同楼上,你这样写太耗费时间了,用switch case或者if else
 楼主| 发表于 2014-6-9 20:19 | 显示全部楼层
你们是觉得代码运行效率太低了吗?这些代码都是书写是没什么效率,但也不影响执行效率啊,都是并列的顺序结构便于实验排查。不是,最关键的原因是:网页不能响应同时16个按钮,这是什么问题?还有超过4组按钮就不能点亮LED了,why?

(代码我以后会去优化的,如果能稳定工作了的话,感谢关注)
 楼主| 发表于 2014-6-9 20:52 | 显示全部楼层
本帖最后由 nbsp 于 2014-6-9 20:55 编辑

回楼上:我把if语句换成如下了

        if( readString.charAt(6)=='T' )
                digitalWrite((readString.charAt(5)-'0'), HIGH);
        if( readString.charAt(6)=='F' )
                digitalWrite((readString.charAt(5)-'0'), LOW);
带回开关按钮原来是“/2?on”,现在改成“/2T”,T-On、F-Off
 楼主| 发表于 2014-6-9 21:03 | 显示全部楼层
我靠~~~~~~~~~~~~~~~~~~~~~~~~~~~就改了上面的if语句,现在测试8路完全无压力啊

附上代码:(明天去掉不必要的串口通讯和A0输入,再测测)

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,177);
EthernetServer server(80);
EthernetClient client;
String readString;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  for( int i=2; i<=9; i++ )
          pinMode(i,OUTPUT);
  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  int switchButton;
  client = server.available();// 监听连入的客户端
  if (client)
  {
    Serial.println("new client"); // 一次http请求结束都带有一个空行   
    boolean currentLineIsBlank = true;
    while (client.connected())
        {
      if (client.available())
          {
        char c = client.read();        
        readString += c; //将收到的信息都保存在readString函数中
        if (c == '\n' && currentLineIsBlank)
                {
          Serial.println(readString);         
          SendHTML(); // 发送HTML文本
          break;
        }               
        if (c == '\n') // 检测是否有换行符
          currentLineIsBlank = true;
        else if (c != '\r') // 检测是否有回车符                       
                          currentLineIsBlank = false;
      }
    }   
        delay(1); // 等待浏览器接收数据   
    client.stop(); //关闭连接
        Serial.println("client disonnected");

        if( readString.charAt(6)=='T' )
                digitalWrite((readString.charAt(5)-'0'), HIGH);
        if( readString.charAt(6)=='F' )
                digitalWrite((readString.charAt(5)-'0'), LOW);

    readString="";
  }
}

// 用于输出HTML文本的函数
void SendHTML()
{
// 发送标准的HTTP响应
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("Connection: close");
  client.println("");
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<head><title>TEST !</title></head>");

// 每十秒刷新一次
  client.println("<meta http-equiv=\"refresh\" content=\"10\">");
  client.println("<body>");
  
  client.println("<div style=\"font-size: 30px;\">");  
  client.println("Light intensity: "); //显示室内光照度
  client.println(analogRead(A0)); // 即将A0采集到的模拟值输出
  client.println("<br />");
  
  // 2 on按钮
  client.println("<a href=\"/2T\" target=\"inlineframe\"><button>2 on</button></a>");
  // 2 off按钮
  client.println("<a href=\"/2F\" target=\"inlineframe\"><button>2 off</button></a>");

  // 3 on按钮
  client.println("<a href=\"/3T\" target=\"inlineframe\"><button>3 on</button></a>");
  // 3 off按钮
  client.println("<a href=\"/3F\" target=\"inlineframe\"><button>3 off</button></a>");

  // 4 on按钮
  client.println("<a href=\"/4T\" target=\"inlineframe\"><button>4 on</button></a>");
  // 4 off按钮
  client.println("<a href=\"/4F\" target=\"inlineframe\"><button>4 off</button></a>");

  // 5 on按钮
  client.println("<a href=\"/5T\" target=\"inlineframe\"><button>5 on</button></a>");
  // 5 off按钮
  client.println("<a href=\"/5F\" target=\"inlineframe\"><button>5 off</button></a>");

  // 6 on按钮
  client.println("<a href=\"/6T\" target=\"inlineframe\"><button>6 on</button></a>");
  // 6 off按钮
  client.println("<a href=\"/6F\" target=\"inlineframe\"><button>6 off</button></a>");

  // 7 on按钮
  client.println("<a href=\"/7T\" target=\"inlineframe\"><button>7 on</button></a>");
  // 7 off按钮
  client.println("<a href=\"/7F\" target=\"inlineframe\"><button>7 off</button></a>");

  // 8 on按钮
  client.println("<a href=\"/8T\" target=\"inlineframe\"><button>8 on</button></a>");
  // 8 off按钮
  client.println("<a href=\"/8F\" target=\"inlineframe\"><button>8 off</button></a>");  

  // 9 on按钮
  client.println("<a href=\"/9T\" target=\"inlineframe\"><button>9 on</button></a>");
  // 9 off按钮
  client.println("<a href=\"/9F\" target=\"inlineframe\"><button>9 off</button></a>");

  client.println("<IFRAME name=inlineframe style=\"display:none\" >");         
  client.println("</IFRAME>");
  client.println("<br /> ");
  
  client.println("</body>");
  client.println("</html>");  
}
 楼主| 发表于 2014-6-9 21:14 | 显示全部楼层
本帖最后由 nbsp 于 2014-6-9 21:17 编辑

目前估计是String实体的indexOf( )方法对于处理器工作压力大,一般来说if并列多条应该影响不大,有时间我会再去测测if并列情况(比如同时支持几条?)
以后优化:代码可以不用string的readString += c,我用计数循环,计到第5、6位取出就去处理响应;
那么后面也不需要charAt()的方法啦,效率更高。



十分感谢楼上2位帮助与提示,这个问题困扰我几天了,今天终于可以安心地去打把游戏然后睡觉了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 03:33 , Processed in 0.108008 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表