2014-10-07 148 views
1

我正在玩Arduino UNO和CC3000屏蔽連接到遠程Web服務。 雖然我在循環腳本時遇到問題。正如您在下面的代碼中看到的那樣,腳本應該每隔5秒對狀態爲occupied的Web服務執行ping操作。雖然當使用while(client.connected)東西使Arduino停止/永遠掛起。即使while(client.connected) {}只是空的。Arduino UNO,CC3000:while(client.connected)

如果我沒有包含while(client.connected){}這個web服務沒有被ping通,這就是爲什麼我發現自己處於一個相當困境的原因。請參閱下面的Arduino Sketch文件和下面的串行日誌。

#include <Adafruit_CC3000.h> 
#include <ccspi.h> 
#include <SPI.h> 
#include <string.h> 
#include "utility/debug.h" 

// These are the interrupt and control pins 
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin! 
// These can be any two pins 
#define ADAFRUIT_CC3000_VBAT 5 
#define ADAFRUIT_CC3000_CS 10 
// Use hardware SPI for the remaining pins 
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11 
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, 
SPI_CLOCK_DIV2); // you can change this clock speed but DI 

#define WLAN_SSID  "WIFI"  // cannot be longer than 32 characters! 
#define WLAN_PASS  "WIFI_PW" 
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2 
#define WLAN_SECURITY WLAN_SEC_WPA2 

    uint32_t ip; 

    int ledPin = 8; // choose the pin for the LED 
    int ledPinSecond = 7; 
    int inputPin = 2;    // choose the input pin (for PIR sensor) 
    int pirState = LOW;    // we start, assuming no motion detected 
    int val = 0; // variable for reading the pin status 
    String occupied; 

/**************************************************************************/ 
/*! 
@brief Sets up the HW and the CC3000 module (called automatically 
on startup) 
*/ 
/**************************************************************************/ 
void setup(void) 
{ 
    Serial.begin(115200); 
    Serial.println(F("Hello, CC3000!\n")); 

    displayDriverMode(); 
    Serial.print("Free RAM: "); 
    Serial.println(getFreeRam(), DEC); 

    pinMode(ledPin, OUTPUT); // declare LED as output 
    pinMode(ledPinSecond, OUTPUT);  
    pinMode(inputPin, INPUT);  // declare sensor as input 

    /* Initialise the module */ 
    Serial.println(F("\nInitialising the CC3000 ...")); 
    if (!cc3000.begin()) 
    { 
    Serial.println(F("Unable to initialise the CC3000! Check your wiring?")); 
    while(1); 
    } 

    /* Optional: Update the Mac Address to a known value */ 
    /* 
    uint8_t macAddress[6] = { 0x08, 0x00, 0x28, 0x01, 0x79, 0xB7 }; 
    if (!cc3000.setMacAddress(macAddress)) 
    { 
    Serial.println(F("Failed trying to update the MAC address")); 
    while(1); 
    } 
    */ 

    uint16_t firmware = checkFirmwareVersion(); 
    if ((firmware != 0x113) && (firmware != 0x118)) { 
    Serial.println(F("Wrong firmware version!")); 
    for(;;); 
    } 

    displayMACAddress(); 

    /* Delete any old connection data on the module */ 
    Serial.println(F("\nDeleting old connection profiles")); 
    if (!cc3000.deleteProfiles()) { 
    Serial.println(F("Failed!")); 
    while(1); 
    } 

    /* Attempt to connect to an access point */ 
    char *ssid = WLAN_SSID;    /* Max 32 chars */ 
    Serial.print(F("\nAttempting to connect to ")); 
    Serial.println(ssid); 

    /* NOTE: Secure connections are not available in 'Tiny' mode! */ 
    if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) { 
    Serial.println(F("Failed!")); 
    while(1); 
    } 

    Serial.println(F("Connected!")); 

    /* Wait for DHCP to complete */ 
    Serial.println(F("Request DHCP")); 
    while (!cc3000.checkDHCP()) 
    { 
    delay(1000); // ToDo: Insert a DHCP timeout! 
    } 

    /* Display the IP address DNS, Gateway, etc. */ 
    while (! displayConnectionDetails()) { 
    delay(1000); 
    } 

#ifndef CC3000_TINY_DRIVER  
    /* Try looking up the webservice */ 
    Serial.print(F("www.webservice.com -> ")); 
    if (! cc3000.getHostByName("www.webservice.com", &ip)) { 
    Serial.println(F("Could not resolve!")); 
    } 
    else { 
    cc3000.printIPdotsRev(ip); 
    } 

    Serial.print(F("\n\rPinging ")); 
    cc3000.printIPdotsRev(ip); 
    Serial.print("..."); 
    uint8_t replies = cc3000.ping(ip, 5); 
    Serial.print(replies); 
    Serial.println(F(" replies")); 
    if (replies) 
    Serial.println(F("Ping successful!")); 
#endif 

    /* You need to make sure to clean up after yourself or the CC3000 can freak out */ 
    /* the next time you try to connect ... */ 
// Serial.println(F("\n\nClosing the connection")); 
// cc3000.disconnect(); 
} 

void loop(void) 
{ 
val = digitalRead(inputPin); // read input value 

    occupied = "Occupied"; 
    Serial.print("Room state: "); 
    Serial.println(occupied); 

sendGET(); 
delay(5000); 
} 

void sendGET() //client function to send/receive GET request data. 
{ 
    Serial.print(F("Initializing SendGET request\n")); 
    Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80); 
    char serverName[] = "www.webservice.com"; //webservice host 
    if (client.connect(serverName, 80)) { 
    //starts client connection, checks for connection 
    Serial.print(F("Adding state to DB\n")); 
    client.println("GET /folder/sensor.php?occupied="+ occupied +" HTTP/1.1"); //download text 
    client.println("Host: webservice.com"); 
    client.println("Connection: close"); //close 1.1 persistent connection 
    client.println(); //end of get request 
    Serial.print(F("Ending connection to DB\n")); 
    } else { 
    Serial.println("Connection to server failed"); //error message if no client connect 
    Serial.println(); 
    } 

    Serial.print(F("Checking connection for bytes\n")); 
    while (client.connected()) { 
    while (client.available()) { 
    //Read answer 
    char c = client.read(); 
    } 
    } 

    Serial.print(F("Checked for bytes\n")); 
    Serial.print("disconnecting."); 
    Serial.print("=================="); 
    client.close(); //stop client 

    } 

/**************************************************************************/ 
/*! 
@brief Displays the driver mode (tiny of normal), and the buffer 
size if tiny mode is not being used 

@note The buffer size and driver mode are defined in cc3000_common.h 
*/ 
/**************************************************************************/ 
void displayDriverMode(void) 
{ 
#ifdef CC3000_TINY_DRIVER 
    Serial.println(F("CC3000 is configure in 'Tiny' mode")); 
#else 
    Serial.print(F("RX Buffer : ")); 
    Serial.print(CC3000_RX_BUFFER_SIZE); 
    Serial.println(F(" bytes")); 
    Serial.print(F("TX Buffer : ")); 
    Serial.print(CC3000_TX_BUFFER_SIZE); 
    Serial.println(F(" bytes")); 
#endif 
} 

/**************************************************************************/ 
/*! 
@brief Tries to read the CC3000's internal firmware patch ID 
*/ 
/**************************************************************************/ 
uint16_t checkFirmwareVersion(void) 
{ 
    uint8_t major, minor; 
    uint16_t version; 

#ifndef CC3000_TINY_DRIVER 
    if(!cc3000.getFirmwareVersion(&major, &minor)) 
    { 
    Serial.println(F("Unable to retrieve the firmware version!\r\n")); 
    version = 0; 
    } 
    else 
    { 
    Serial.print(F("Firmware V. : ")); 
    Serial.print(major); 
    Serial.print(F(".")); 
    Serial.println(minor); 
    version = major; 
    version <<= 8; 
    version |= minor; 
    } 
#endif 
    return version; 
} 

/**************************************************************************/ 
/*! 
@brief Tries to read the 6-byte MAC address of the CC3000 module 
*/ 
/**************************************************************************/ 
void displayMACAddress(void) 
{ 
    uint8_t macAddress[6]; 

    if(!cc3000.getMacAddress(macAddress)) 
    { 
    Serial.println(F("Unable to retrieve MAC Address!\r\n")); 
    } 
    else 
    { 
    Serial.print(F("MAC Address : ")); 
    cc3000.printHex((byte*)&macAddress, 6); 
    } 
} 


/**************************************************************************/ 
/*! 
@brief Tries to read the IP address and other connection details 
*/ 
/**************************************************************************/ 
bool displayConnectionDetails(void) 
{ 
    uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 

    if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv)) 
    { 
    Serial.println(F("Unable to retrieve the IP Address!\r\n")); 
    return false; 
    } 
    else 
    { 
    Serial.print(F("\nIP Addr: ")); 
    cc3000.printIPdotsRev(ipAddress); 
    Serial.print(F("\nNetmask: ")); 
    cc3000.printIPdotsRev(netmask); 
    Serial.print(F("\nGateway: ")); 
    cc3000.printIPdotsRev(gateway); 
    Serial.print(F("\nDHCPsrv: ")); 
    cc3000.printIPdotsRev(dhcpserv); 
    Serial.print(F("\nDNSserv: ")); 
    cc3000.printIPdotsRev(dnsserv); 
    Serial.println(); 
    return true; 
    } 
} 

LOG

Hello, CC3000! 

    RX Buffer : 131 bytes 
    TX Buffer : 131 bytes 
    Free RAM: 1047 

    Initialising the CC3000 ... 
    Firmware V. : 1.24 
    MAC Address : MAC_ADDRESS 

    Deleting old connection profiles 

    Attempting to connect to 64 Allen Street - East 
    Connected! 
    Request DHCP 

    IP Addr: XXX.XXX.XX.X 
    Netmask: 255.255.255.0 
    Gateway: 192.168.0.1 
    DHCPsrv: 192.168.0.1 
    DNSserv: XXX.XX.X.X 
    www.webservice.com -> XX.XX.XXX.XXX 

    Pinging XX.XX.XXX.XXX...5 replies 
    Ping successful! 
    Room state: Free 
    Initializing SendGET request 
    Adding state to DB 
    Ending connection to DB 
    Checking connection for bytes 

回答

2

爲什麼不動那就是代碼連接的客戶端進入您連接if語句。那麼你不需要輪詢client.connected()函數。

看來邏輯是有缺陷的。如果客戶端已連接,它可能會保持連接狀態,直到您處於循環之下的線路爲止:client.close();這會導致循環永不結束。

或者,您也可以在循環中添加一些代碼,以防止它永遠運行。

uint32_t theTime = millis(); 

while(client.connected()){ 
    if((millis() - theTime) >1000) break; //exit loop after one second. 
} 
+0

感謝您的建議。已經嘗試都沒有成功。將考慮重建所有內容並確保所有內容都在邏輯上執行。也懷疑連接代碼可能有問題,因爲它只在while(client.connected)執行時才起作用,並且不會被定時器破壞。將盡快更新此線程。再次感謝。 – Thomas 2014-10-13 14:12:43