Arduino UNO,CC3000:while(client.connected)

时间:2014-10-07 14:24:01

标签: c++ mysql c arduino

我正在玩Arduino UNO和连接远程Web服务的CC3000屏蔽。 虽然我在循环脚本时遇到问题。正如您在下面的代码中看到的那样,脚本应该每5秒以occupied状态ping一次Web服务。虽然使用while(client.connected)时会让Arduino永久停止/挂起。即使while(client.connected) {}只是空的。

如果我没有包含while(client.connected){},那么网络服务就没有被激活,这就是为什么我发现自己处于相当困境的原因。请参阅下面的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

1 个答案:

答案 0 :(得分:2)

为什么不将连接客户端的代码移动到连接的if语句中。然后,您无需轮询client.connected()函数。

似乎逻辑是有缺陷的。如果客户端已连接,它可能会保持连接,直到您在循环下面的行:client.close();这将导致循环永远不会结束。

或者你也可以在循环中添加一些代码,以防止它永远运行。

uint32_t theTime = millis();

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