5
$\begingroup$

I'm trying to send Arduino sensor data to a server using a GPRS shield (SIM900 shield from Geeetech). I have this particular set up because the data will be updated to a website and the device will be roaming. I can't use http://www.cosm.org because to the best of my knowledge that only updates every 15 minutes, I need to update about every 5-10 seconds.

In order to connect I tried the code below to form UDP connection but it does not get sent through to the receiving IP and port. I don't know why. No errors occur on the Arduino side, and the server side has been shown to work with an iPhone app that sends a UDP message.

///connect
void connectUDP()
{
 mySerial.println("AT+CSTT=\"APN\"");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIICR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIFSR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");
 delay(3000);
 ShowSerialData();
 mySerial.println();

}


///send udp packet to server 
void sendUDP()
{
 for(int x = 0; x < 30; x++){
   mySerial.println("AT+CIPSEND"); 
   delay(100);
   ShowSerialData();
   mySerial.println("\"hello world\"");
   delay(100);
   ShowSerialData();
   mySerial.println((char)26);
   delay(1000);
   ShowSerialData();
 }
 mySerial.println();
 //ShowSerialData();
}

The server side is as follows (written in python):

import SocketServer

PORTNO = 14

class handler(SocketServer.DatagramRequestHandler):
    def handle(self):
        newmsg = self.rfile.readline().rstrip()
    print (newmsg)
        self.wfile.write(self.server.oldmsg)
        self.server.oldmsg = newmsg

s = SocketServer.UDPServer(('',PORTNO), handler)
print "Awaiting UDP messages on port %d" % PORTNO
s.oldmsg = "This is the starting message."
s.serve_forever()

I can see a possible solution might be to change it to a TCP connection, but I don't know how to do that...

$\endgroup$
  • $\begingroup$ Were you able to verify that the GPRS shield can perform other functions (like dialing a phone number) based on serial port commands that you send it? $\endgroup$ – Ian May 16 '13 at 16:00
  • $\begingroup$ Yes, it can send an SMS, call a phone and receive http data all based on AT commands sent through the serial port. $\endgroup$ – ecki May 17 '13 at 2:01
  • $\begingroup$ And can you verify that echo "test123" | nc -u YOUR_SERVER_IP 14 Produces output in your server? $\endgroup$ – Ian May 17 '13 at 3:28
  • $\begingroup$ so, send that from the arduino or another device? because I already used an iphone app which can send iphone sensor data as a UDP packet. that process worked perfectly and the server was receiving the data, so nothings wrong with the server side it seems. $\endgroup$ – ecki May 17 '13 at 4:47
  • 2
    $\begingroup$ Did you ever get this working? If so, perhaps suggest an answer? I mention it mostly as this has 2k views, and it would be good to have it "resolved"... $\endgroup$ – Aerophilic Jan 13 '15 at 4:32
1
$\begingroup$

Your code appears a little incomplete - I am assuming that this is because you wished to include only the salient functions.

Once the required missing lines from the GeeTech Wiki - Arduino GPRS Shield - A Simple Source Code Examples (their typo, not mine) are added, the complete (minimal) code would seem to be:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8);

///connect
void connectUDP()
{
 mySerial.println("AT+CSTT=\"APN\"");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIICR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIFSR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");
 delay(3000);
 ShowSerialData();
 mySerial.println();
}


///send udp packet to server 
void sendUDP()
{
 for(int x = 0; x < 30; x++){
   mySerial.println("AT+CIPSEND"); 
   delay(100);
   ShowSerialData();
   mySerial.println("\"hello world\"");
   delay(100);
   ShowSerialData();
   mySerial.println((char)26);
   delay(1000);
   ShowSerialData();
 }
 mySerial.println();
 //ShowSerialData();
}

void ShowSerialData()
{
 while(mySerial.available()!=0)
   Serial.write(mySerial.read());
}

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  connectUDP();
  sendUDP();
}

As to why this isn't working, I am not sure, and I am still working on it.

As a sanity check, I presume that, in your actual Arduino sketch, you have substituted SERVER IP and SERVER PORT with actual values (i.e., a real IP address and port number)? SERVER IP and SERVER PORT are not variables (global or otherwise) nor #defines. As you have not included the entire sketch, it is difficult to tell otherwise.

In addition, make sure that the server address that you specify in the Arduino sketch matches the IP address of the server running the Python script, and that the port that you specify in the Arduino sketch matches PORTNO in the Python script. Sorry if I am stating the obvious, but, like I said, this is a sanity check.

Regarding your second point:

I can see a possible solution might be to change it to a TCP connection, but I don't know how to do that...

You simply need to change UDP to TCP in the following line1:

 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");

so that it becomes

 mySerial.println("AT+CIPSTART=\"TCP\",\"SERVER IP\",\"SERVER PORT\"");

Obviously, as I have pointed out above, you need to provide actual values for <SERVER IP> and <SERVER PORT>, for example:

 mySerial.println("AT+CIPSTART=\"TCP\",\"116.228.221.51\",\"8500\"");

On the server side, the following lines in the Python script:

s = SocketServer.UDPServer(('',PORTNO), handler)
print "Awaiting UDP messages on port %d" % PORTNO

need to be changed to:

s = SocketServer.TCPServer(('',PORTNO), handler)
print "Awaiting TCP messages on port %d" % PORTNO

Again, ensure that the PORTNO, in your server side Python script, matches the port specified in the AT command.


1 See m2msupport.net - AT+CIPSTART. The relevant notes being

AT+CIPSTART=?

+CIPSTART: ("TCP","UDP"),("(0,255).(0,255).(0,255).(0,255)"),(1,65535)
+CIPSTART: ("TCP","UDP"),("DOMAIN NAME"),(1,65535)

OK

Start a TCP connection
AT+CIPSTART="TCP","116.228.221.51","8500"

OK

Start a UDP connection
AT+CIPSTART="UDP","116.228.221.51","9600"

CONNECT OK

Note that the web page has a typo, and a period is shown where a comma should be, in the Start a UDP connection example. I have corrected this typo in the example above.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.