[solved] Arduino wifi shield - “No Socket available”

Hi,

I'am Building a weather station that sends data to my own web server (like the Wifi Pachube sensor client).

I am using:

  • Visual Studio with plug in for Arduino. (Same issue when i use the Arduino 1.0.5)
  • Arduino uno R3
  • Arduino wifi shield with WiFi firmware version: 1.1.0. (upgraded firmware to last version).

I have following issue:
After 4 cycles is the error message “No Socket available” raised and no data is transmitted via WiFi. The cycles continue to run in ever endless loop, and in every new cycle is the message “No Socket available” raised.

I have don following:

  • tested with Arduino example WiFiWebClient and get the same error.
  • compared and used parts of the code in the sketch (WiFiPachubeClient).
  • search Google for similar issues but starting to run out of ideas...
  • checked the power and for test reason connected an extra +5 V power supply direct on the shield.

Code

#include <SPI.h>
#include <WiFi.h>

#define APIKEY         "cRwlkNas"					// api key
#define FEEDID         "00001"						// feed ID
#define USERAGENT      "Environment Data"			// project name

byte mac[] = {0x90, 0xA2, 0xDA, 0x0E, 0x96, 0xCA};	// the media access control (ethernet hardware) address for the shield:
// 78:c4:0e:01:9b:57
byte ip[] = { 192,168,0,198};						// the IP address for the shield:The Arduino device IP address
//byte subnet[] = { 255,255,255,0};					// the subnet:
//byte gateway[] = { 192,168,0,1};					// the router's gateway address:

char ssid[] = "***";								// your network SSID (name) 
char pass[] = "***";								// your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;									// your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;						// status of the wifi connection

WiFiClient client;									// Initialize the Wifi client library
char server[] = "www.***.se";						// server address:
unsigned long lastConnectionTime = 0;				// last time you connected to the server, in milliseconds
boolean lastConnected = false;						// state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000;		// delay between updates, in milliseconds

boolean incomingData = false;

void setup()
{
	//--------------------------------------------------------------
	//Initialize serial and wait for port to open:
	Serial.begin(9600); 
	while (!Serial) {
		; // wait for serial port to connect. Needed for Leonardo only
	}
	//--------------------------------------------------------------
	// check for the presence of the shield:
	if (WiFi.status() == WL_NO_SHIELD) {
		Serial.println("--- WiFi shield not present"); 
		// don't continue:
		while(true);
	} 
	//--------------------------------------------------------------
	// attempt to connect to Wifi network:
	while ( status != WL_CONNECTED) { 
		Serial.print("--- Attempting to connect to SSID: ");
		Serial.println(ssid);
		// Connect to WPA/WPA2 network. Change this line if using open or WEP network:    
		status = WiFi.begin(ssid, pass);

		// wait 10 seconds for connection:
		delay(10000);
	} 
	//--------------------------------------------------------------
	// you're connected now, so print out the status:
	printWifiStatus();

}

void loop()
{
	Serial.println("========================");
	Serial.println("--- START ---");
	//--------------------------------------------------------------
	// ToDo: read the sensors:
	//
	//--------------------------------------------------------------
	// if there's no net connection, but there was one last time
	// through the loop, then stop the client:
	if (!client.connected() && lastConnected) {
		Serial.println();
		Serial.println("--- disconnecting_client_1.");
		client.stop();
	}
	//--------------------------------------------------------------
	// if you're not connected, and ten seconds have passed since
	// your last connection, then connect again and send data:
	if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
		// if there's a successful connection:
		sendDataOverWiFi();
	}
	//--------------------------------------------------------------
	// store the state of the connection for next time through
	// the loop:
	lastConnected = client.connected();
		
	//--------------------------------------------------------------
	// wait 60 seconds
	Serial.println("--- wait 10 seconds ---");
	delay(10000);
	Serial.println("--- wait done");
	Serial.println("--- END ---");
	
}

// this method makes a HTTP connection to the server:
void sendDataOverWiFi() {

	Serial.println("--- connecting to server ---");
	if (client.connect(server, 80)) {
		Serial.println();
		Serial.println("--- sending data");
		// send the HTTP PUT request:
		client.print("PUT /");
		client.print(FEEDID);
		client.println(".csv HTTP/1.1");
		client.println("Host: www.***.se");
		client.print("ApiKey: ");
		client.println(APIKEY);
		client.print("User-Agent: ");
		client.println(USERAGENT);
		client.print("Content-Length: ");

		// calculate the length of the sensor reading in bytes:
		// 8 bytes for "sensor1," + 8 bytes for "sensor1," + number of digits of the data:
		int thisLength = 27; //getLength(sensor1) + getLength(sensor2);
		client.println("27");

		// last pieces of the HTTP PUT request:
		client.println("Content-Type: text/csv");
		client.println("Connection: close");
		client.println();

		// here's the actual content of the PUT request:
		client.print("sensor1;"); // air
		client.println("18.8");
		client.print("sensor2;"); // water
		client.println("12.3");
		client.println(" ");

		// wait 10 seconds:
		delay(1000);
		// note the time that the connection was made:
		lastConnectionTime = millis();
		Serial.println("--- sending data done");
	}
	else {
		// if you couldn't make a connection:
		Serial.println("--- connection failed");
		Serial.println("--- disconnecting_client_2.");
	}

	//-------------------------------------------------------------
	// give the server time to respond
	delay(1000);

	//--------------------------------------------------------------
	// if there's incoming data from the net connection.
	// send it out the serial port.  This is for debugging
	// purposes only:	
	while (client.available()) {
		if (incomingData == false)
		{
			Serial.println();
			Serial.println("--- Incoming data Start ---");
			incomingData = true;
		}
		char c = client.read();
		Serial.write(c);
	}
	// Debugging --------------------------------------------------
	if (incomingData == true)
	{
		Serial.println("--- Incoming data End");
		incomingData = false; 
	}
	if (status == WL_CONNECTED){
		Serial.println("--- WiFi connected");
	}
	else{
		Serial.println("--- WiFi not connected");
	}
}

// This method calculates the number of digits in the
// sensor reading.  Since each digit of the ASCII decimal
// representation is a byte, the number of digits equals
// the number of bytes:

int getLength(int someValue) {
	// there's at least one byte:
	int digits = 1;
	// continually divide the value by ten, 
	// adding one to the digit count for each
	// time you divide, until you're at 0:
	int dividend = someValue /10;
	while (dividend > 0) {
		dividend = dividend /10;
		digits++;
	}
	// return the number of digits:
	return digits;
}

Output to serial monitor.
Se attached file:

Thanks for comments.
John

Output To Serial Monitor.pdf (103 KB)

1 Like

Once you get all the data from a client, you do not close the client connection. After a while, all the sockets are in use. That appears to be the issue you are having. Closing the client connection after getting all the data is needed.

Your while loop to get the client data needs to check client.connected(), too. When the client no longer has data available, call client.flush() and client.stop().

2 Likes

Thanks!!!

I just tried with the changes (added blue text) that you [PaulS] suggested and now it's working great. :slight_smile:

//--------------------------------------------------------------
// if there's incoming data from the net connection.
// send it out the serial port. This is for debugging
// purposes only:
while (client.available() && status == WL_CONNECTED) {
if (incomingData == false)
{
Serial.println();
Serial.println("--- Incoming data Start ---");
incomingData = true;
}
char c = client.read();
Serial.write(c);
}
client.flush();
client.stop();

Many many Thanks!!!
/John

2 Likes

I am pretty interested in this problem.

I have set up an Arduino Uno with a WiFi shield and it tweets the temperature (from a DHT22) sensor but once it has tweeted the first reading it stops, and as I´ve read in this thread it 'disconnects'. I am trying to adapt to my sketch PaulS and jomikk´s suggestion to mine and I am not able to get it to work properly. I´d appreciate any help! Thanks.

This is my code.

#include <SPI.h> // needed in Arduino 0019 or later
#include <WiFi.h>
#include <Twitter.h>
#include "DHT.h"

DHT dht;

char ssid[] = "WIFISSID";
char pass[] = "WIFIPASSWD"; 

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("TOKENHERE");

char buffer [14];
float temperature;

void setup() {
  dht.setup(2); //DHT´s pin is 2
  Serial.begin(9600);
  //strcat("This is temp", buffer);
  delay(1000);
  WiFi.begin(ssid, pass);
  // or you can use DHCP for automatic IP address configuration.
  // WiFi.begin(mac);
  delay(10000);
}


void loop () {
  delay(dht.getMinimumSamplingPeriod());
  temperature = dht.getTemperature();
  //strcat("This is temp ", buffer);
  dtostrf(temperature, 2, 1, buffer);
  //sprintf("La temperatura actual es %.1s ºC", buffer); //Results in ? ªC
  Serial.println("connecting ...");
  if (twitter.post (strcat("La temperatura actual es ", buffer))) {
    // Specify &Serial to output received response to Serial.
    // If no output is required, you can just omit the argument, e.g.
    // int status = twitter.wait();
    int status = twitter.wait(&Serial);
    if (status == 200) {
      Serial.println("OK.");
    } else {
      Serial.print("failed : code ");
      Serial.println(status);
    }
  } else {
    Serial.println("connection failed.");
  }
  Serial.println(sprintf(buffer, "La temperatura actual es %.1s ºC"));
  Serial.println(strcat(buffer, "This is temperature "));
  delay(90000);
}/code]

Hello guys, I would like to do something similar.
I have a DHT22 sensor. I would like to see the temperature and humidity data through a page in PHP using socket connect to that later I can save the sensor information in a database.

My biggest problem is the connection between the Arduino with PHP, and then read the sensor data.

I did not think anything like this on the web, so that you do understand how it works.

If anyone knows of any similar tutorial, please help me.

Thank U !!

would like to see the temperature and humidity data through a page in PHP using socket connect

Why? The usual method is to make a GET request to the PHP script.

My biggest problem is the connection between the Arduino with PHP, and then read the sensor data.

My biggest problem is that you haven't posted any code, or described what that code actually does, or how that differs from what you want it to do. Nor have you posted the PHP script.