Arduino UNO, CC3000: while(client.connected)
我正在使用连接到远程 Web 服务的 Arduino UNO 和 CC3000 扩展板.虽然我在循环脚本时遇到了问题.正如您在下面的代码中看到的,脚本应该每 5 秒以 occupied
的状态 ping 网络服务.尽管在使用 while(client.connected)
时,有些东西会使 Arduino 永远停止/挂起.即使 while(client.connected) {}
只是空的.
I'm playing around with an Arduino UNO and a CC3000 shield connecting to a remote web service.
Though I'm having a problem looping the script. As you can see in the code below, the script should ping the web service with the state of occupied
every 5 seconds. Though when using while(client.connected)
something makes the Arduino stop/hang forever. Even if the while(client.connected) {}
is just empty.
如果我不包含 while(client.connected){}
,则不会 ping 网络服务,这就是我发现自己处于两难境地的原因.请参阅下面的 Arduino Sketch 文件和下面的串行日志.
If I don't include the while(client.connected){}
the web service is not pinged, which is why I find myself in quite a dilemma. Please see Arduino Sketch file below and serial log below that.
#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;
}
}
日志
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
推荐答案
为什么不将用于已连接客户端的代码移动到您连接的 if 语句中.那么你就不需要轮询 client.connected()
函数.
Why not move the code that is for a connected client into the if statement where you connect. Then you do not need to poll the client.connected()
function.
这个逻辑好像有问题.如果客户端已连接,它可能会保持连接状态,直到循环下方的行:client.close();
这将导致循环永远不会结束.
It seems the logic is flawed. If a client is connected, it will probably remain connected until the line you have below the loop: client.close();
Which would cause the loop to never end.
或者,您也可以在循环中添加一些代码以防止它永远运行.
Alternatively you could also add some code inside the loop to prevent it from running for ever.
uint32_t theTime = millis();
while(client.connected()){
if( ( millis() - theTime ) >1000 ) break; //exit loop after one second.
}
相关文章