Hi All
Has anybody managed to connect to www.google.com and download its home page from a SM5100B Cellular Shield?
Hi All
Has anybody managed to connect to www.google.com and download its home page from a SM5100B Cellular Shield?
Yeh done it…
Anybody need help??
DaleR
What did you use for the carrier settings? Which carrier did you use?
yeah, i’m trying to figure out how to communicate over HTTP too. any examples out there?
A good place to start would be RFC 2616-
Any help with this would be really great.
I can’t make a socket connection using an Arduino Duemilanove.
Currently, my code looks like this :
#define BUFFSIZ 90
#include <NewSoftSerial.h> //Include the NewSoftSerial library to send serial commands to the cellular module.
#include <string.h> //Used for string manipulations
int sockConnect = 0; //checks to see if the sockets is connected
int dataIn = 0; //is there data in the buffer?
boolean modemOnline=false; // is the modem online yet?
char incoming_char=0; //Will hold the incoming character from the Serial Port.
int firstTimeInLoop = 1; //is this the first time we're starting?
int GPRS_registered;
int GPRS_AT_ready;
char buffidx;
char at_buffer[BUFFSIZ];
String statusRegistered="\r\n+SIND: 4";
NewSoftSerial cell(2,3); //Create a 'fake' serial port. Pin 2 is the Rx pin, pin 3 is the Tx pin.
//read the inciming strings from the modem to check for conection to the cell network
void readATString(void) {
char c;
buffidx= 0; // start at begninning
while (1) {
if(cell.available() > 0) {
c=cell.read();
if (c == -1) {
at_buffer[buffidx] = '\0';
return;
}
if (c == '\n') {
continue;
}
if ((buffidx == BUFFSIZ - 1) || (c == '\r')){
at_buffer[buffidx] = '\0';
return;
}
at_buffer[buffidx++]= c;
}
}
}
/* Processes the AT String to determine if GPRS is registered and AT is ready */
void ProcessATString() {
if( strstr(at_buffer, "+SIND: 8") != 0 ) {
GPRS_registered = 0;
Serial.println("GPRS Network Not Available");
}
if( strstr(at_buffer, "+SIND: 11") != 0 ) {
GPRS_registered=1;
Serial.println("GPRS Registered");
//blinkLed(redLedPin,5,100);
}
if( strstr(at_buffer, "+SIND: 4") != 0 ) {
GPRS_AT_ready=1;
Serial.println("GPRS AT Ready");
}
}
//does this
void makeEuro(){
cell.print("AT+SBAND=4");
Serial.println("AT+SBAND=4");
cell.print(0x0D);
waitForOK();
}
void gprsinit(){
cell.print("AT+CGATT=?");
Serial.println("AT+CGATT=?");
cell.print(0x0D);
waitForOK();
cell.print("AT+CGDCONT=1,'IP','telenor'");
Serial.println("AT+CGDCONT=1,'IP','telenor'");
cell.print(0x0D);
waitForOK();
cell.print("AT+CGPCO=0,'dj','dj',1");
Serial.println("AT+CGPCO=0,'dj','dj',1");
cell.print(0x0D);
waitForOK();
cell.print("AT+CGACT=1,1");
Serial.println("AT+CGACT=1,1");
cell.print(0x0D);
waitForOK();
}
void datasendandreceive(){
cell.print("at+sdataconf=1,\"TCP\",\"www.google.com\",80");
Serial.println("at+sdataconf=1,\"TCP\",\"www.google.com\",80");
cell.print(0x0D);
waitForOK();
cell.print("at+sdatastart=1,1");
Serial.println("at+sdatastart=1,1");
cell.print(0x0D);
waitForOK();
cell.print("at+sdatastatus=1");
Serial.println("at+sdatastatus=1");
cell.print(0x0D);
Serial.println("Socket Status to Follow");
waitForSockStatus();
cell.print("at+sdatasend=1,10"); // where 10 is how many bytes to send
cell.print("1");
cell.print(0x1A);
waitForOK();
//check to see if data has been received +STCPD:1
hasDataBeenReceived();
if(dataIn==1){
cell.print("AT+SDATATREAD=1"); // read the data
cell.print(0x0D);
getMessage();
}
else{
//start over
}
cell.print("AT+SDATASTART=1,0"); // close the connection
waitForOK();
}
//reads through the buffer until it reaches the letter 'K'
void waitForOK(){
while(cell.available())
{
incoming_char=cell.read(); //Get the character from the cellular serial port.
Serial.print(incoming_char);
delay(2);
}
Serial.println();
}
//waits to connect to the socket
void waitForSockStatus(){
//Patterns to look for
String prefix="+SOCKSTATUS: 1,";
String input="";
char value;
while(cell.available()<1){
//wait for a cycle
}
while(cell.available()>0){
incoming_char=cell.read(); //read the buffer
Serial.println(incoming_char);
input+=incoming_char; //add it to the string
if(input.substring(0)==prefix) //if it matches our expected string
{
break;
}
}
incoming_char=cell.read();
//Serial.println(incoming_char);
if(incoming_char=='1'){
Serial.println("Socket connected");
sockConnect=1;
}
else{
Serial.println("Socket NOT connected");
sockConnect=0;
}
//clear the buffer
while(cell.available()>0){
incoming_char=cell.read();
}
}
void getMessage(){
//Patterns
String prefix="+SDATA: 1, ";
String input="";
String ourM="\r\n";
boolean y=false;
boolean m=false;
//print the message
cell.print('AT+SDATATREAD=1');
cell.print(0x0D);
while(cell.available()<1){
//wait for a cycle
}
//First, find the prefix
while(cell.available()>0){
incoming_char=cell.read(); //read the buffer
input+=incoming_char; //add it to the string
if(input.substring(0)==prefix) //if it matches our expected string
{
//Data is present
y=true;
break;
}
}
//read message until we reach the comma, which is the start of the new message
while(cell.available()&&y==true)
{
if(incoming_char!=','){
incoming_char=cell.read();
}
else{
break;
}
}
//get our message
while(cell.available()>0){
incoming_char = cell.read(); //read the buffer
messageToSign.concat(incoming_char); //add it to the string
if(messageToSign.endsWith(ourM))
{
break;
}
}
messageToSign=messageToSign.trim();
}
void hasDataBeenReceived(){
// this needs to run until we get a 1
//a 0 means we are still connecting...........
//Pattern
String hopeItsThere= "+STCPD:1";
String input="";
while(cell.available()<1){
//wait for a cycle
}
while(cell.available()>0){
incoming_char=cell.read(); //read the buffer
input+=incoming_char; //add it to the string
if(input.substring(0)==hopeItsThere) //if it matches our expected string
{
//Data is present
dataIn=1;
}
else{
//no data
dataIn=0;
}
}
}
void setup()
{
//Initialize serial ports for communication.
Serial.begin(9600);
cell.begin(9600);
delay(1000);
//Let's get started!
Serial.println("Booting up...");
}
void loop() {
//check on startup to see if we have registered on the network
if(firstTimeInLoop) {
firstTimeInLoop = 0;
while (GPRS_registered == 0 || GPRS_AT_ready == 0) {
readATString();
ProcessATString();
}
}
gprsinit();
datasendandreceive();
}
All it returns is this :
Booting up…
GPRS Registered
GPRS AT Ready
AT+CGATT=?
AT+CGDCONT=1,‘IP’,‘telenor’
AT+CGPCO=0,‘dj’,‘dj’,1
AT+CGACT=1,1
at+sdataconf=1,“TCP”,“google.com”,80
at+sdatastart=1,1
at+sdatastatus=1
Socket Status to Follow
Which is weird, because I would expect to see the cell’s printout whenever waitForOK() is called…
Some cleaned up code, but still no love from the modem.
Now I’m getting the following from the serial monitor :
Starting SM5100B Communication…
GPRS Network Not Available
GPRS AT Ready
Setting up PDP Context
OK
Sending Password
OK
Activating PDP Context
Configuring TCP connection to TCP Server
OK
Starting TCP Connection
Checking Connection Status
RzµÕ¤ø
+SOCKSTATUS: 1,0,0100,0,0,0
OK
Checking Connection Status
+SOCKSTATUS: 1,0,0100,0,0,0
With this code :
#include <NewSoftSerial.h> //Include the NewSoftSerial library to send serial commands to the cellular module.
#include <string.h>
#define POWERPIN 4
#define BUFFSIZ 90
char at_buffer[BUFFSIZ];
char buffidx;
int firstTimeInLoop = 1;
int GPRS_registered;
int GPRS_AT_ready;
char incoming_char=0; //Will hold the incoming character from the Serial Port.
char buffer[60];
String myString="1";
NewSoftSerial cell(2,3); //Create a 'fake' serial port. Pin 2 is the Rx pin, pin 3 is the Tx pin.
// Do system wide initialization here in this function
void setup()
{
Serial.begin(9600);
cell.begin(9600);
//Let's get started!
Serial.println("Starting SM5100B Communication...");
delay(5000);
/* Currently GPRS is not registered and AT is not ready */
GPRS_registered = 0;
GPRS_AT_ready = 0;
}
/* Reads AT String from the SM5100B GSM/GPRS Module */
void readATString(void) {
char c;
buffidx= 0; // start at begninning
while (1) {
if(cell.available() > 0) {
c=cell.read();
if (c == -1) {
at_buffer[buffidx] = '\0';
return;
}
if (c == '\n') {
continue;
}
if ((buffidx == BUFFSIZ - 1) || (c == '\r')){
at_buffer[buffidx] = '\0';
return;
}
at_buffer[buffidx++]= c;
}
}
}
/* Processes the AT String to determine if GPRS is registered and AT is ready */
void ProcessATString() {
if( strstr(at_buffer, "+SIND: 8") != 0 ) {
GPRS_registered = 0;
Serial.println("GPRS Network Not Available");
}
if( strstr(at_buffer, "+SIND: 11") != 0 ) {
GPRS_registered=1;
Serial.println("GPRS Registered");
}
if( strstr(at_buffer, "+SIND: 4") != 0 ) {
GPRS_AT_ready=1;
Serial.println("GPRS AT Ready");
}
}
void loop() {
/* If called for the first time, loop until GPRS and AT is ready */
if(firstTimeInLoop) {
firstTimeInLoop = 0;
while (GPRS_registered == 0 && GPRS_AT_ready == 0) {
readATString();
ProcessATString();
}
Serial.println("Setting up PDP Context");
cell.println("AT+CGDCONT=1,\"IP\",\"epc.tmobile.com\"");
delay(1000);
while(cell.available()){
incoming_char=cell.read();
Serial.print(incoming_char);
}
Serial.println("Sending Password");
cell.println("AT+CGPCO=0,\"\",\"\", 1");
delay(1000);
while(cell.available()){
incoming_char=cell.read();
Serial.print(incoming_char);
}
Serial.println("Activating PDP Context");
cell.println("AT+CGACT=1,1");
delay(1000);
while(cell.available()){
incoming_char=cell.read();
Serial.print(incoming_char);
}
Serial.println("Configuring TCP connection to TCP Server");
cell.println("AT+SDATACONF=1,\"TCP\",\"88.87.58.126\",5000");
delay(1000);
while(cell.available()){
incoming_char=cell.read();
Serial.print(incoming_char);
}
Serial.println("Starting TCP Connection\n");
cell.println("AT+SDATASTART=1,1");
}
Serial.println("Checking Connection Status\n");
cell.println("AT+SDATASTATUS=1");
delay(1000);
while(cell.available()){
incoming_char=cell.read();
Serial.print(incoming_char);
}
Anyone done this successfully know why I can’t connect?
Has anyone figured this out yet? I am stalled here myself. I have done the same sequence of commands and can’t get a web page to respond properly.
I am talking directly to the shield through a terminal emulator.
If anyone has a sample of a successful connection to a web page, please post it.
Thanks
daleread:
Yeh done it…Anybody need help??
DaleR
Yes. I have been fighting for days trying to get the SM5100 to see the network. Link Sprite support says the default band is gsm900, which is right for China. But for North America it must be changed to 850 using AT+SBAND=7. But this command always returns an error for me.
Were you able to make your work in North America?
Thanks,
Mike
thebecwar is right
you need to read the HTTP standard and figure out how to send a valid HTTP GET command.
Then the server will send the page.
If you only make a TCP connection, how is the server going to know what to do?
If you install wireshark, start her up, create a filter with www.google.com, look at the transactions that take place between your computer and www.google.com
You will see that a TCP connection is only the first step.
I’m using post because thats my application, and my code is quite dynamic, but if your always sending the same GET command, its doesn’t need all the variables in there. It could be a fixed packet.
Be careful if you are connecting to an IP, that the ‘host’ value is actually the web address and not the IP. If you use the IP the server wont know what to do with it. This is because there might be more than one web server on that IP… likely not the case for google.com, but to be sure.
Read the standard, and get used to reading, because reading is king in development… you need to do it… alot.
//"AT+SDATASEND=1, "..."
Serial1.print("AT+SDATATSEND=1, ");
Serial1.print(packetSize);
Serial1.print(CR);
delay(100);
/*--------------------Sart TCP Packet--------------------------*/
/*--------------------Sart HTTP Header-------------------------*/
Serial1.print("POST "); //5
Serial1.print(webExt); //var
Serial1.print(" http/1.1"); //9
Serial1.print(CR); //1
Serial1.print(LF); //1
Serial1.print("Host: "); //6
Serial1.print(webAdd); //var
Serial1.print(CR); //1
Serial1.print(LF); //1
Serial1.print("User-Agent: "); //12
Serial1.print(userAgent); //var
Serial1.print(CR); //1
Serial1.print(LF); //1
Serial1.print("Content-Type: application/x-www-form-urlencoded"); //47
Serial1.print(CR); //1
Serial1.print(LF); //1
Serial1.print("Content-Length: "); //16
Serial1.print(contentSize); //var
Serial1.print(CR); //1
Serial1.print(LF); //1
Serial1.print(CR); //1
Serial1.print(LF); //1
/*--------------------End HTTP Header-------------------------*/
/*-------------------Start of Content-------------------------*/
Serial1.print("s=");
for (int k=0; k<12; k++){
Serial1.print(payload[k]);
}
if (howmanyInt>0){
Serial1.print("&f=");
for (int i=0; i<howmanyInt; i++){
for (int k=0; k<12; k++){
Serial1.print(payload[(i*12)+k]);
}
if (i<(howmanyInt-1)){
Serial1.print(",");
}
}
}
if (reboot == true){
Serial1.print("&e=");
Serial1.print(Err_Reset);
reboot = false;
}
Serial1.print(CR); // Carridge return //1
/*--------------------End of Content--------------------------*/
/*--------------------End TCP Packet--------------------------*/
Serial1.print(UC); // Up caret
Was just implementing a GET.
Its got some quirks… thats for sure…
Once you have the tcp connection setup use this
AT+SDATARXMD=,1,0
Makes the data the comes out ASCII, and also makes sure you get the +STCPD: when data is received.
Then
Serial1.print("AT+SDATATSEND=1, ");
Serial1.print(packetSize);
Serial1.print(CR);
delay(100);
/*--------------------Sart TCP Packet--------------------------*/
/*--------------------Sart HTTP Header-------------------------*/
Serial1.print("GET "); //4
Serial1.print(getExt); //var
Serial1.print(" HTTP/1.0"); //9
Serial1.print(CR); //1
Serial1.print(LF); //1
Serial1.print("Connection: Keep-Alive"); //22
Serial1.print(CR); //1
Serial1.print(LF); //1
Serial1.print(CR); //1
Serial1.print(LF); //1
/*--------------------End HTTP Header-------------------------*/
/*-------------------Start of Content-------------------------*/
/*--------------------End of Content--------------------------*/
/*--------------------End TCP Packet--------------------------*/
wait for OK, however you implement
then wait for +STCPD:
(some code below… its kinda crap but works)
waiting = true;
while (waiting == true){
if(Serial1.available() > 7){
inByte = getbyteSerial1();
if (inByte=='+'){
for (k=0 ; k<7 ; k++){
searchString[k]=getbyteSerial1();
}
if ( searchString[0]=='S'
&& searchString[1]=='T'
&& searchString[2]=='C'
&& searchString[3]=='P'
&& searchString[4]=='D'
&& searchString[5]==':'
&& searchString[6]=='1'){ // 1 in this line is the TCP connection ID
Serial1.println("AT+SDATAREAD=1");
waiting = false;
#ifdef debug_ctv2
Serial.println("Data!");
#endif
}
else{
#ifdef debug_ctv2
Serial.println("No Data");
#endif
return some error;
}
}
}
}
handle the returned data…
I noticed that If I waited too long the socket gets closed by the server and then the module deletes the data…
so the read has to happen immediately after the message of data availability
I haven’t field tested this, but it seems to be working fine.
Hope it helps.
Definitely with Keep Alive disabled this module would be useless…
I have an apache server running and it had keep alive disabled, it was making getting the data intermittent. Sometimes it was fast enough, sometimes not… with Keep Alive enabled on the server, and I set the timeout to 5 seconds, it now appears to be working correctly.
I’m no expert on these matters, but I have found the following:
Anyone getting the same issues as shfitz might want to adjust the following code:
while (GPRS_registered == 0 && GPRS_AT_ready == 0) {
readATString();
ProcessATString();
}
Should be an AND statement (note the two || characters instead of &&):
while (GPRS_registered == 0 || GPRS_AT_ready == 0) {
readATString();
ProcessATString();
}
Otherwise, script could run without getting full network and that will lead to a fail.
If you get CME ERROR: 33 - this seems to be as a result of calling AT+SDATACONF too early or PDP Context not activating. I put a 5 second delay after AT+CGACT=1,1 and it works a dream every time now.
The two characters “||” constitute an OR logical operator, not an AND logical operator. Is that what you meant?
As an aside, to avoid mistakes and make the logical operator precedence clear to others, it is usually a good idea to use extra parentheses as follows
if ( (GPRS_registered == 0) || (GPRS_AT_ready == 0) ) {
Not having any luck with the cellular shield either.
I modified the AT+CGDCONT & AT+CGPCO sends to match my carrier, added SIM PIN, and took hints from http://www.sparkfun.com/datasheets/Cell … 20Note.pdf where solutions to CME Error 28 is mentioned, I get:
Starting SM5100B Communication...
Inputting SIM PIN
GPRS Registered
GPRS AT Ready
Setting up PDP Context
OK
Sending Password
OK
Activating PDP Context
+CME ERROR: 28
DE-Activating PDP Context
NO CARRIER
Activating PDP Context
+CME ERROR: 28
DEtaching GRPS Network
+CME ERROR: 65536014
Attaching GPRS Network
+CME ERROR: 65536014
Activating PDP Context
+CME ERROR: 28
Configuring TCP connection to TCP Server
OK
Starting TCP Connection
Checking Connection Status
RôµªHø
+SOCKSTATUS: 1,0,0100,0,0,0
OK
Checking Connection Status
+SOCKSTATUS: 1,0,0100,0,0,0
Any ideas?
Hey everyone, I managed to get this guy working with HTTP GET and POST requests. I’ve posted my code up on github, I hope it’s helfpul for some: https://github.com/tobek/SM5100B-GPRS. If it doesn’t work for you but you find something that does, let me know so I can update it!