2013-11-10 2 views
1

Теперь я использую Arduino + WiFiShield для создания дверного шкафчика, который может удаленно управлять дверным замком с помощью портативного устройства с его браузером. Но, похоже, моя программа получила ошибку, и я понятия не имею, почему это происходит.Arduino выполняет несколько раз одну и ту же команду из веб-браузера (используя WiServer.h)

Ниже приведена моя ошибка.

Мой Arduino отправляется несколько раз из той же команды, отправленной из веб-браузера. Другими словами, если я нажму кнопку, появляющуюся в веб-браузере, мой Arduino перейдет к , выполнив соответствующую функцию, которую я написал в Arduino не один раз, а несколько раз (обычно 3 раза, иногда только дважды ...).

Возьмите мой код, например, если я нажму кнопку FORWARD в веб-браузере, мой Arduino будет запускать подфункцию «closedoor();» 3 раза. Серийный монитор дает обратно журнал, как показано ниже:

Server connected 
Processing request for /?V=C 
STOP : 
closingdoor : 
TX 329 bytes 
STOP : 
closingdoor : 
TX 329 bytes 
STOP : 
closingdoor : 
TX 174 bytes 
Server connection closed 
Server connected 
Processing request for /favicon.ico 
TX 19 bytes 
Server connection closed 

Если я раскомментировать «Serial.println (URL);», я получаю следующий журнал от последовательного монитора:

Server connected 
Processing request for /?V=C 
/?V=C 
STOP : 
closingdoor : 
TX 329 bytes 
/?V=C 
STOP : 
closingdoor : 
TX 329 bytes 
/?V=C 
STOP : 
closingdoor : 
TX 174 bytes 
Server connection closed 
Server connected 
Processing request for /favicon.ico 
/favicon.ico 
TX 19 bytes 
Server connection closed 

Если кто-то знает что-то, пожалуйста, дайте мне предложение. Мне действительно нужно понять это.

Следующий мой код. Пожалуйста, смотрите!

#include <WiServer.h> 

const int LMD18245_Brake = 4; // Pin 4 of Motoduino  
const int LMD18245_Direction = 5; // Pin 5 of Motoduino 

// Wireless configuration parameters ---------------------------------------- 
unsigned char local_ip[] = {192,168,1,5}; // IP address of WiShield 
unsigned char gateway_ip[] = {192,168,1,1}; // router or gateway IP address 
unsigned char subnet_mask[] = {255,255,255,0}; // subnet mask for the local network 
char ssid[]     = {"Johnny"}; // max 32 bytes 
unsigned char security_type = 2;    // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2 

// WPA/WPA2 passphrase 
const prog_char security_passphrase[] PROGMEM = {"xxxxxxxx"}; // max 64 characters 

byte sampledata=50; 
char link[]="http://motoduino.com/"; //link data 

// WEP 128-bit keys 
prog_uchar wep_keys[] PROGMEM = { 
    0x61, 0x62, 0x63, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 0 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Key 3 
}; 

// setup the wireless mode; infrastructure - connect to AP; adhoc - connect to another WiFi device 
#define WIRELESS_MODE_INFRA 1 
#define WIRELESS_MODE_ADHOC 2 
unsigned char wireless_mode = WIRELESS_MODE_INFRA; 
unsigned char ssid_len; 
unsigned char security_passphrase_len; 
// End of wireless configuration parameters ---------------------------------------- 

boolean mainpage() 
{ 
      WiServer.print("<html><head></head>"); 
      WiServer.print("<body>"); 
      WiServer.print("<table border= 0>"); 
      WiServer.print("<tr>"); 
      WiServer.print("<th> </th>"); 
      WiServer.print("<th>"); 
      WiServer.print("<form method=get>"); 
      WiServer.print("<input type=hidden name=V value=C /><br />"); 
      WiServer.print("<input type=submit value=FORWARD>"); 
      WiServer.print("</form>"); 
      WiServer.print("</th><th> </th>"); 
      WiServer.print("</tr>"); 
      WiServer.print("<tr><th>"); 
      WiServer.print("<form method=get >"); 
      WiServer.print("<input type=hidden name=V value=O /><br />"); 
      WiServer.print("<input type=submit value=LEFT>"); 
      WiServer.print("</form>"); 
      WiServer.print("</th><th>"); 
      WiServer.print("<form method=get >"); 
      WiServer.print("<input type=hidden name=V value=S /><br />"); 
      WiServer.print("<input type=submit value=STOP>"); 
      WiServer.print("</form>"); 
      WiServer.print("</th><th> "); 
      WiServer.print("<form method=get >"); 
      WiServer.print("<input type=hidden name=V value=R /><br />"); 
      WiServer.print("<input type=submit value=RIGHT>"); 
      WiServer.print("</form>"); 
      WiServer.print("</th></tr> <tr> <th> </th> <th> "); 
      WiServer.print("<form method=get >"); 
      WiServer.print("<input type=hidden name=V value=B /><br />"); 
      WiServer.print("<input type=submit value=BACKWARD>"); 
      WiServer.print("</form>"); 
      WiServer.print(" </th> <th> </th> </tr>"); 
      WiServer.print("</table>"); 
      WiServer.print("<br/>"); 
      WiServer.print("<font color=#888888 size=1>Project_Test</font><font size=3>"); 
      WiServer.print("<br /></font><font size=3> Johnny</font><br />"); 
      WiServer.print("</body>"); 
      WiServer.print("</html>"); 

      return true; 
} 

boolean controlpage(char* URL) 
{ 
// Serial.println(URL); 
    if (strcmp(URL, "/") == 0) 
    { 
      mainpage(); 
     return true; 
    } 
    else 
    { 
     if(URL[1] == '?') 
     { 
      if((URL[2] == 'V') && (URL[3] == '=')) 
      { 
       switch(URL[4]) 
       { 

       case 'C': 
          closedoor(); 
          break; 
       case 'O': 
          opendoor(); 
          break; 
       case 'S': 
          stopmode(); 
          break; 
       default: 
       //Do nothing 
          break;    
       } 
      mainpage(); 
      return true;  
      } 
      mainpage(); 
      return true;   
     }  

    } 
} 

void opendoor() 
{ 
    digitalWrite(LMD18245_Brake, 0); 
    digitalWrite(LMD18245_Direction, 1); 
    delay(200); 
    stopmode(); 

    Serial.println("openingdoor : "); 
} 

void closedoor() 
{ 
    digitalWrite(LMD18245_Brake, 0); 
    digitalWrite(LMD18245_Direction, 0); 
    delay(200); 
    stopmode(); 

    Serial.println("closingdoor : "); 
} 

void stopmode() 
{ 
    digitalWrite(LMD18245_Brake, 1); 
    digitalWrite(LMD18245_Direction, 0); 

    Serial.println("STOP : "); 
} 

void setup() { 
    Serial.begin(9600); 

    // set all color leds as output pins 
    pinMode(LMD18245_Brake, OUTPUT); 
    pinMode(LMD18245_Direction, OUTPUT); 

    WiServer.init(controlpage); 
    digitalWrite(LMD18245_Brake, 1); 
    // Enable Serial output and ask WiServer to generate log messages (optional) 
    WiServer.enableVerboseMode(true); 
} 

void loop(){ 

    // Run WiServer 
    WiServer.server_task(); 

    delay(10); 
} 
+0

Что вы получаете, когда раскомментируете первую строку управления функциями (Serial.println (URL)). Ваш выход «urlname: закрытие двери: STOP:» повторяется три раза или это что-то еще. Я думаю, что результат здесь должен дать нам некоторые идеи. – sraok

+0

Hi @sraok, Спасибо за ваш ответ! Если я раскомментирую «Serial.println (URL)»; Я получаю повторную 3-х разную обратную связь в одном соединении. Я обновил журнал с серийным монитором после того, как я раскомментировал «Serial.println (URL);». – JohnnyZsefb

ответ

1

Это из-за небольшого буфера на atmega328 (или аналогичном), для которого была создана библиотека wishield.

Atmega328 имеет очень ограниченную ОЗУ, поэтому они вынуждены использовать небольшой буфер. Если вы «Grep» для SIZE в библиотеке, я считаю, что это линия, которая определяет его:

uipopt.h: #define UIP_BUFSIZE 400

Так как только заголовки пакетов IP в, по-видимому для полезной нагрузки осталось около 329 байт.

Итак, что произойдет, если ваша страница содержит больше этого?

Библиотека просто вызывает вашу страницу снова и снова и вспоминает, когда она была в последний раз, а в следующий раз она передает следующий сегмент 329 байт, пока последние сегменты не поместится в 329 байт, а затем это будет сделано.

Я не вижу другого способа пойти на него, но он может иметь раздражающие побочные эффекты, если вы не передаете одну и ту же вещь каждый раз. У вас есть для передачи одной и той же вещи каждый раз, пока это не будет сделано.

Казалось, они планировали реализовать метод, чтобы сказать вам, что это «в процессе», но код не существует:

boolean Server::sendInProgress() { 
     return false; // FIX ME 
} 

Итак, в двух словах, это нормально, но убедитесь, вы передаете один и тот же контент каждый раз, и размер того, что вы передаете, никогда не изменяется для данной страницы.

Излишне говорить, что это было предназначено для передачи статических страниц, а не для запуска чего-то слишком необычного с динамическим контентом, созданным «на лету», хотя это может быть сделано в определенной степени, если вы будете осторожны.

Кстати, я не стал бы менять размер # define'd там, потому что тогда вам не хватит места в стеке, прежде чем вы это узнаете, и это может быть довольно сложно отладить.

Если вам действительно нужно вызываться только один раз, вам необходимо сбрить часть того, что вы передаете для данного URL, пока она не окажется под 329 байтами (согласно вашим журналам). Затем он должен позвонить вам только один раз.

+0

Спасибо за ваше объяснение. По крайней мере, я выяснил, в чем проблема. Я думаю, что я попытаюсь изменить свой код и убедиться, что он передаст данный URL под 329 байт. – JohnnyZsefb

Смежные вопросы