Hello,
I am currently working on a project that requires me to send a file to a server using the GSM shield. I am using an Arduino Mega 2560 with a Sparkfun SD shield, and Arduino GSM shield (found here http://arduino.cc/en/Main/ArduinoGSMShield.) I tried combining the GSM Webclient code (which is included as an example with the Arduino IDE) and the FTP Code (found here Arduino Playground - FTP) for use with the GSM shield, but was unable to establish a data connection. I established a connection to the server at port 21 and went through the FTP commands getting the server to enter passive mode and assign a data port, I just cannot connect to this port. The serial monitor outputs "Command Connected" followed by all successful FTP status codes (200 level,) the Data port number, and finally "Data Connection Failed" and "FTP FAIL." How can I get the GSM shield to establish two connections? Does the GSM shield support multiple connections? Is there another way to transfer a file using the GSM shield?
Here is my code:
/*
FTP passive client for IDE v1.0.1 and w5100/w5200
Posted October 2012 by SurferTim
*/
#include <SD.h>
#include <SPI.h>
#include <GSM.h>
// comment out next line to write to SD from FTP server
#define FTPWRITE
// PIN Number
#define PINNUMBER ""
// APN data
#define GPRS_APN "bluevia.movistar.es" // replace your GPRS APN
#define GPRS_LOGIN "" // replace with your GPRS login
#define GPRS_PASSWORD "" // replace with your GPRS password
// initialize the library instance
GPRS gprs;
GSM gsmAccess;
GSMClient client;
GSMClient dclient;
// URL, path & port (for example: arduino.cc)
//char server[] = "arduino.cc";
byte server[]= {xxx, xxx, xxx, xxx};
char path[] = "/";
int port = 21; // port 80 is the default for HTTP
char outBuf[128];
char outCount;
// change fileName to your file (8.3 format!)
char fileName[13] = "test.txt";
void setup()
{
Serial.begin(9600);
pinMode(53,OUTPUT);
digitalWrite(53,HIGH);
if(SD.begin(53) == 0) //changed to 53 for use with mega
{
Serial.println(F("SD init fail"));
}
Serial.println("Starting Arduino web client.");
// connection state
boolean notConnected = true;
// After starting the modem with GSM.begin()
// attach the shield to the GPRS network with the APN, login and password
while(notConnected)
{
if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
(gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY))
notConnected = false;
else
{
Serial.println("Not connected");
delay(1000);
}
}
Serial.println("connecting...");
// if you get a connection, report back via serial:
/* if (client.connect(server, port))
{
Serial.println("connected");
}
else
{
// if you didn't get a connection to the server:
Serial.println("connection failed");
}*/
digitalWrite(53,HIGH);
delay(2000);
Serial.println(F("Ready. Press f or r"));
}
void loop()
{
byte inChar;
inChar = Serial.read();
if(inChar == 'f')
{
if(doFTP()) Serial.println(F("FTP OK"));
else Serial.println(F("FTP FAIL"));
}
if(inChar == 'r')
{
readSD();
}
}
File fh;
byte doFTP()
{
#ifdef FTPWRITE
fh = SD.open(fileName,FILE_READ);
#else
SD.remove(fileName);
fh = SD.open(fileName,FILE_WRITE);
#endif
if(!fh)
{
Serial.println(F("SD open fail"));
return 0;
}
#ifndef FTPWRITE
if(!fh.seek(0))
{
Serial.println(F("Rewind fail"));
fh.close();
return 0;
}
#endif
Serial.println(F("SD opened"));
if (client.connect(server,21)) {
Serial.println(F("Command connected"));
}
else {
fh.close();
Serial.println(F("Command connection failed"));
return 0;
}
if(!eRcv()) return 0;
client.println(F("USER xxxxxx"));
if(!eRcv()) return 0;
client.println(F("PASS xxxxxx"));
if(!eRcv()) return 0;
client.println(F("SYST"));
if(!eRcv()) return 0;
client.println(F("PASV"));
if(!eRcv()) return 0;
char *tStr = strtok(outBuf,"(,");
int array_pasv[6];
for ( int i = 0; i < 6; i++) {
tStr = strtok(NULL,"(,");
array_pasv[i] = atoi(tStr);
if(tStr == NULL)
{
Serial.println(F("Bad PASV Answer"));
}
}
unsigned int hiPort,loPort;
hiPort = array_pasv[4] << 8;
loPort = array_pasv[5] & 255;
Serial.print(F("Data port: "));
hiPort = hiPort | loPort;
Serial.println(hiPort);
if (dclient.connect(server,hiPort)) {
Serial.println(F("Data connected"));
}
else {
Serial.println(F("Data connection failed"));
client.stop();
fh.close();
return 0;
}
#ifdef FTPWRITE
client.print(F("STOR "));
client.println(fileName);
#else
client.print(F("RETR "));
client.println(fileName);
#endif
if(!eRcv())
{
dclient.stop();
return 0;
}
#ifdef FTPWRITE
Serial.println(F("Writing"));
byte clientBuf[64];
int clientCount = 0;
while(fh.available())
{
clientBuf[clientCount] = fh.read();
clientCount++;
if(clientCount > 63)
{
dclient.write(clientBuf,64);
clientCount = 0;
}
}
if(clientCount > 0) dclient.write(clientBuf,clientCount);
#else
while(dclient.connected())
{
while(dclient.available())
{
char c = dclient.read();
fh.write(c);
Serial.write(c);
}
}
#endif
dclient.stop();
Serial.println(F("Data disconnected"));
if(!eRcv()) return 0;
client.println(F("QUIT"));
if(!eRcv()) return 0;
client.stop();
Serial.println(F("Command disconnected"));
fh.close();
Serial.println(F("SD closed"));
return 1;
}
byte eRcv()
{
byte respCode;
byte thisByte;
while(!client.available()) delay(1);
respCode = client.peek();
outCount = 0;
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
if(outCount < 127)
{
outBuf[outCount] = thisByte;
outCount++;
outBuf[outCount] = 0;
}
}
if(respCode >= '4')
{
efail();
return 0;
}
return 1;
}
void efail()
{
byte thisByte = 0;
client.println(F("QUIT"));
while(!client.available()) delay(1);
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
client.stop();
Serial.println(F("Command disconnected"));
fh.close();
Serial.println(F("SD closed"));
}
void readSD()
{
fh = SD.open(fileName,FILE_READ);
if(!fh)
{
Serial.println(F("SD open fail"));
return;
}
while(fh.available())
{
Serial.write(fh.read());
}
fh.close();
}
I was able to download a file from the server using FTP commands from a computer, so I think the server is functioning just fine. Thanks for your help.