Hello all, I started writing a driver for the SIM900A today based on the ESP8266 driver.
init is working
connect is working
getIP is working
reset is just calling init currently because I didn't find a way to reset the SIM900 by using an AT-command (for ESP8266 there is AT+RST)
I got stuck at sending a HTTP-Request through NetworkJS. What happens is, that the send-method is called over and over and after a few retries it stops. I can not see any response from the server currently. I assume that there are subtle differences in the use of the AT+CIPSEND command for ESP8266 and SIM900A. Any ideas?
Here you find the code:
Serial1.setup(115200, { rx: B7, tx : B6 });
var at;
var socks = [];
var sockData = ["","","","",""];
var MAXSOCKETS = 5;
var netCallbacks = {
create : function(host, port) {
/* Create a socket and return its index, host is a string, port is an integer.
If host isn't defined, create a server socket */
if (host===undefined) {
sckt = MAXSOCKETS;
socks[sckt] = "Wait";
sockData[sckt] = "";
at.cmd("AT+CIPSERVER=1,"+port+"\r\n", 10000, function(d) {
if (d=="OK") {
socks[sckt] = true;
} else {
socks[sckt] = undefined;
throw new Error("CIPSERVER failed");
}
});
return MAXSOCKETS;
} else {
var sckt = 0;
while (socks[sckt]!==undefined) sckt++; // find free socket
if (sckt>=MAXSOCKETS) throw new Error("No free sockets");
socks[sckt] = "Wait";
sockData[sckt] = "";
at.cmd('AT+CIPSTART='+sckt+',"TCP",'+JSON.stringify(host)+','+port+'\r\n',10000, function(d) {
if (d=="OK") {
at.registerLine(sckt + ', CONNECT OK', function() {
at.unregisterLine(sckt + ', CONNECT OK');
socks[sckt] = true;
});
at.registerLine(sckt + ', CLOSED', function() {
at.unregisterLine(sckt + ', CLOSED');
socks[sckt] = undefined;
});
} else {
socks[sckt] = undefined;
throw new Error("CIPSTART failed");
}
});
}
return sckt;
},
/* Close the socket. returns nothing */
close : function(sckt) {
at.cmd('AT+CIPCLOSE='+sckt+"\r\n",1000, function(/*d*/) {
socks[sckt] = undefined;
//console.log("?"+JSON.stringify(d));
});
},
/* Accept the connection on the server socket. Returns socket number or -1 if no connection */
accept : function(sckt) {
// console.log("Accept",sckt);
for (var i=0;i<MAXSOCKETS;i++)
if (sockData[i] && socks[i]===undefined) {
//console.log("Socket accept "+i,JSON.stringify(sockData[i]),socks[i]);
socks[i] = true;
return i;
}
return -1;
},
/* Receive data. Returns a string (even if empty).
If non-string returned, socket is then closed */
recv : function(sckt, maxLen) {
if (at.isBusy() || socks[sckt]=="Wait") return "";
if (sockData[sckt]) {
var r;
if (sockData[sckt].length > maxLen) {
r = sockData[sckt].substr(0,maxLen);
sockData[sckt] = sockData[sckt].substr(maxLen);
} else {
r = sockData[sckt];
sockData[sckt] = "";
}
return r;
}
if (!socks[sckt]) return -1; // close it
return "";
},
/* Send data. Returns the number of bytes sent - 0 is ok.
Less than 0 */
send : function(sckt, data) {
console.log(data);
if (at.isBusy() || socks[sckt]=="Wait") return 0;
if (!socks[sckt]) return -1; // error - close it
console.log("Send: " + data);
var f = function(d) {
// TODO: register for '>'
//console.log("?"+JSON.stringify(d));
if (d=="> ") {
return f;
}
};
at.cmd('AT+CIPSEND='+sckt+','+data.length+'\r\n' + data , 10000, f);
return data.length;
}
};
//Handle +IPD input data from SIM900A
function ipdHandler(line) {
var colon = line.indexOf(":");
if (colon<0) return line; // not enough data here at the moment
var parms = line.substring(5,colon).split(",");
parms[1] = 0|parms[1];
var len = line.length-(colon+1);
if (len>=parms[1]) {
// we have everything
sockData[parms[0]] += line.substr(colon+1,parms[1]);
return line.substr(colon+parms[1]+1); // return anything else
} else {
// still some to get
sockData[parms[0]] += line.substr(colon+1,len);
return "+IPD,"+parms[0]+","+(parms[1]-len)+":"; // return IPD so we get called next time
}
}
var gprsFuncs = {
ipdHandler:ipdHandler,
"debug" : function() {
return {
socks:socks,
sockData:sockData
};
},
// initialise the SIM900A
"init" : function(callback) {
var s = 0;
var cb = function(r) {
console.log(r);
switch(s) {
case 0:
if(r === 'ATE0' || r === 'OK') return cb;
else if(r) {
callback('Error in ' + s + ': ' + r);
} else {
s = 1;
at.cmd('AT+CPIN?\r\n', 100, cb);
}
break;
case 1:
if(r === '+CPIN: READY' || r === 'OK') return cb;
else if(r) {
callback('Error in ' + s + ': ' + r);
} else {
s = 2;
at.cmd('AT+CGATT?\r\n', 100, cb);
}
break;
case 2:
if(r === '+CGATT: 1' || r === 'OK') return cb;
else if(r) {
callback('Error in ' + s + ': ' + r);
} else {
s = 3;
at.cmd('AT+CIPSHUT\r\n', 100, cb);
}
break;
case 3:
if(r === 'SHUT OK') return cb;
else if(r) {
callback('Error in ' + s + ': ' + r);
} else {
s = 4;
at.cmd('AT+CIPSTATUS\r\n', 100, cb);
}
break;
case 4:
if(r === 'STATE: IP INITIAL' || r === 'OK') return cb;
else if(r) {
callback('Error in ' + s + ': ' + r);
} else {
s = 5;
at.cmd('AT+CIPMUX=1\r\n', 100, cb);
}
break;
case 5:
if(r === 'OK') return cb;
else if(r) {
callback('Error in ' + s + ': ' + r);
} else {
callback(null);
}
break;
}
return cb;
};
at.cmd("ATE0\r\n",1000,cb);
},
"reset" : function(callback) {
gprsFuncs.init(callback);
},
"getVersion" : function(callback) {
at.cmd("AT+GMR\r\n", 1000, function(d) {
callback(null,d);
});
},
"connect" : function(apn, username, password, callback) {
var s = 0;
var cb = function(r) {
switch(s) {
case 0:
if(r === 'OK') return cb;
else if(r) {
callback('Error in ' + s + ': ' + r);
} else {
s = 1;
at.cmd('AT+CIICR\r\n', 2000, cb);
}
break;
case 1:
if(r === 'OK') return cb;
else if(r) {
callback('Error in ' + s + ': ' + r);
} else {
callback(null);
}
break;
}
};
at.cmd('AT+CSTT="' + apn + '", "' + username + '", "' + password + '"\r\n', 1000, cb);
},
"getIP" : function(callback) {
var ip;
var cb = function(r) {
if(r && r != 'ERROR') {
ip = r;
return cb;
} else if(r === 'ERROR') {
callback('CIFSR Error');
} else if(!r) {
callback(null, ip);
}
};
at.cmd('AT+CIFSR\r\n', 2000, cb);
}
};
var connect = function(usart, connectedCallback) {
gprsFuncs.at = at = require("AT").connect(usart);
require("NetworkJS").create(netCallbacks);
at.register("+IPD", ipdHandler);
gprsFuncs.reset(connectedCallback);
return gprsFuncs;
};
connect(Serial1, function() {
gprsFuncs.connect('pinternet.interkom.de', '', '', function(err) {
console.log(err);
gprsFuncs.getIP(function(err, ip) {
console.log('IP:' + ip);
require("http").get("http://www.pur3.co.uk/hello.txt", function(res) {
console.log("Response: ",res);
res.on('data', function(d) {
console.log("--->"+d);
});
});
});
});
});
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
Hello all, I started writing a driver for the SIM900A today based on the ESP8266 driver.
I got stuck at sending a HTTP-Request through NetworkJS. What happens is, that the send-method is called over and over and after a few retries it stops. I can not see any response from the server currently. I assume that there are subtle differences in the use of the AT+CIPSEND command for ESP8266 and SIM900A. Any ideas?
Here you find the code: