Skip to content

Instantly share code, notes, and snippets.

@danielkp1234
Created April 20, 2022 13:57
Show Gist options
  • Save danielkp1234/ab2ea90e5b47bd3070b7c0707d06bb61 to your computer and use it in GitHub Desktop.
Save danielkp1234/ab2ea90e5b47bd3070b7c0707d06bb61 to your computer and use it in GitHub Desktop.
The DFRobot Sim7000 library with the none working attacthService void
#include <DFRobot_SIM7000.h>
DFRobot_SIM7000::DFRobot_SIM7000(Stream *s):DFRobot_SIMcore(s)
{
_s = s;
}
bool DFRobot_SIM7000::setBaudRate(long rate)
{
int count = 0;
while(count <3){
if( rate == 1200){
if(checkSendCmd("AT+IPR=1200\r\n","OK")){
_baudrate = 1200;
break;
}else{
count++;
delay(200);
}
}else if(rate == 2400){
if(checkSendCmd("AT+IPR=2400\r\n","OK")){
_baudrate = 2400;
break;
}else{
count++;
delay(200);
}
}else if(rate == 4800){
if(checkSendCmd("AT+IPR=4800\r\n","OK")){
_baudrate = 4800;
break;
}else{
count++;
delay(200);
}
}else if(rate == 9600){
if(checkSendCmd("AT+IPR=9600\r\n","OK")){
_baudrate = 9600;
break;
}else{
count++;
delay(200);
}
}else if(rate == 19200){
if(checkSendCmd("AT+IPR=19200\r\n","OK")){
_baudrate = 19200;
break;
}else{
count++;
delay(200);
}
}else if(rate == 38400){
if(checkSendCmd("AT+IPR=38400\r\n","OK")){
_baudrate = 38400;
break;
}else{
count++;
delay(200);
}
}else{
Serial.println("No such rate");
return false;
}
}
if(count == 3)
return false;
return true;
}
bool DFRobot_SIM7000::checkSIMStatus(void)
{
int count = 0;
while(count < 3){
if(checkSendCmd("AT\r\n","OK")){
break;
}else{
count++;
delay(300);
}
}
if(count == 3){
return false;
}
count = 0;
while(count < 3){
if(checkSendCmd("AT+CPIN?\r\n","READY")){
break;
}else{
count++;
delay(300);
}
}
if(count == 3)
return false;
return true;
}
bool DFRobot_SIM7000::setNetMode(eNet net)
{
if(net == eNB){
_mode_t=0;
if(checkSendCmd("AT+CNMP=38\r\n","OK")){
delay(300);
if(checkSendCmd("AT+CMNB=2\r\n","OK")){
return true;
}else{
return false;
}
}else{
return false;
}
}else if(net == eGPRS){
_mode_t=1;
if(checkSendCmd("AT+CNMP=13\r\n","OK")){
delay(300);
if(checkSendCmd("AT+CMNB=1\r\n","OK")){
return true;
}else{
return false;
}
}
}else{
Serial.println("No such mode!");
}
return false;
}
bool DFRobot_SIM7000::attacthService(void)
{
char gprsBuffer[32];
cleanBuffer(gprsBuffer,32);
sendCmd("AT+CGATT=1\r\n");
while(1){
readBuffer(gprsBuffer, 320);
if(NULL != strstr(gprsBuffer, "OK")){
delay(100);
Serial.println("t1");
break;
}
if(NULL != strstr(gprsBuffer, "ERROR")){
Serial.println("t2");
return false;
}
}
cleanBuffer(gprsBuffer,32);
Serial.println("t3");
if(_mode_t){
//My only modification to the file was changing this apn info from cmnet to internet that my provider uses
sendCmd("AT+CSTT=\"internet\"\r\n");
Serial.println("t4");
}else{
//My only modification to the file was changing this apn info from cmnet to internet that my provider uses
sendCmd("AT+CSTT=\"internet\"\r\n");
Serial.println("t5");
}
while(1){
readBuffer(gprsBuffer, 32);
if(NULL != strstr(gprsBuffer, "OK")){
Serial.println("t55");
delay(200);
break;
}else if(NULL != strstr(gprsBuffer,"ERROR")){
Serial.println("t6");
return false;
}
}
Serial.println("t7");
sendCmd("AT+CIICR\r\n");
while(1){
readBuffer(gprsBuffer, 32, 4000);
if(NULL != strstr(gprsBuffer, "OK")){
delay(200);
break;
}else if(NULL != strstr(gprsBuffer,"ERROR")){
return false;
}
}
if(checkSendCmd("AT+CIFSR\r\n","ERROR",4000)){
return false;
}
Serial.println("t7");
return true;
}
int DFRobot_SIM7000::checkSignalQuality(void)
{
char signalBuffer[26];
int i = 0,j = 0,k = 0;
char *signalQuality;
cleanBuffer(signalBuffer,26);
sendCmd("AT+CSQ\r\n");
readBuffer(signalBuffer,26);
if(NULL != (signalQuality = strstr(signalBuffer, "+CSQ:"))){
i = *(signalQuality + 6) - 48;
j = *(signalQuality + 7) - 48;
k = (i * 10) + j;
}else{
return 0;
}
if( k == 99){
return 0;
}else{
return k;
}
}
bool DFRobot_SIM7000::openNetwork(eProtocol ptl,const char *host, int port)
{
char num[4];
char resp[96];
if(ptl == eTCP){
sendCmd("AT+CIPSTART=\"TCP\",\"");
sendCmd(host);
sendCmd("\",");
itoa(port, num, 10);
sendCmd(num);
sendCmd("\r\n");
}else if(ptl == eUDP){
sendCmd("AT+CIPSTART=\"UDP\",\"");
sendCmd(host);
sendCmd("\",");
itoa(port, num, 10);
sendCmd(num);
sendCmd("\r\n");
}else{
Serial.println("No such mode!");
return false;
}
while(1){
while(checkReadable()){
cleanBuffer(resp, 96);
readBuffer(resp, 96);
if(NULL != strstr(resp,"CONNECT OK")){
return true;
}
if(NULL != strstr(resp,"ERROR")){//
return false;
}
}
}
}
bool DFRobot_SIM7000::turnON(void)
{
pinMode(12,OUTPUT);
if(checkSendCmd("AT\r\n", "OK", 100)){
sendCmd("AT+CPOWD=1\r\n");
delay(4000);
}
delay(100);
digitalWrite(12, HIGH);
delay(1000);
digitalWrite(12, LOW);
delay(7000);
if(checkSendCmd("AT\r\n", "OK", 100)){
return true;
}else{
return false;
}
}
bool DFRobot_SIM7000::initPos(void)
{
if(checkSendCmd("AT+CGNSPWR=1\r\n","OK")){
delay(50);
return true;
}else{
return false;
}
}
bool DFRobot_SIM7000::send(char *data)
{
char num[4];
char resp[20];
int len = strlen(data);
itoa(len, num, 10);
sendCmd("AT+CIPSEND=");
sendCmd(num);
if(checkSendCmd("\r\n",">")){
sendCmd(data);
while(1){
while(checkReadable()){
readBuffer(resp,20);
if(NULL != strstr(resp,"OK")){
return true;
}
if(NULL != strstr(resp,"ERROR")){
return false;
}
}
}
}else{
return false;
}
}
bool DFRobot_SIM7000::send(char *buf, size_t len)
{
char num[4];
itoa(len, num, 10);
sendCmd("AT+CIPSEND=");
sendCmd(num);
if(checkSendCmd("\r\n",">")){
if(checkSendCmd(buf,"OK")){
return true;
}else{
return false;
}
}else{
return false;
}
}
bool DFRobot_SIM7000::mqttConnect(const char* iot_client, const char* iot_username, const char* iot_key)
{
if(checkSendCmd("AT+CIPSEND\r\n",">")){
char MQTThead[10]={0x00,0x04,0x4d,0x51,0x54,0x54,0x04,(char)0xC2,0x0b,(char)0xb8};
char MQTTbuff[50]={0};
MQTTbuff[0] = 0x10;
sendBuff(MQTTbuff,1);
int leng = 10;
leng += strlen(iot_client)+2;
leng += strlen(iot_username)+2;
leng += strlen(iot_key)+2;
MQTTbuff[0] = leng ;
sendBuff(MQTTbuff,1);
sendBuff(MQTThead,10);
sendBuff(MQTThead,1);
MQTTbuff[0] = strlen(iot_client);
sendBuff(MQTTbuff,1);
sendCmd(iot_client);
sendBuff(MQTThead,1);
MQTTbuff[0] = strlen(iot_username);
sendBuff(MQTTbuff,1);
sendCmd(iot_username);
sendBuff(MQTThead,1);
MQTTbuff[0] = strlen(iot_key);
sendBuff(MQTTbuff,1);
sendCmd(iot_key);
if(checkSendCmd("","CLOSED")){
return false;
}else{
return true;
}
}
return false;
}
bool DFRobot_SIM7000::mqttPublish(const char* iot_topic, String iot_data)
{
if(checkSendCmd("AT+CIPSEND\r\n",">")){
DBG("aa");
char MQTTdata[2]={0x00,0x04};
char MQTTbuff[50]={0};
MQTTbuff[0] = 0x32;
sendBuff(MQTTbuff,1);
MQTTbuff[0] = strlen(iot_topic)+iot_data.length()+4;
sendBuff(MQTTbuff,2);
MQTTbuff[0] = strlen(iot_topic);
sendBuff(MQTTbuff,1);
sendCmd(iot_topic);
sendBuff(MQTTdata,2);
iot_data.toCharArray(MQTTbuff,iot_data.length());
sendString(iot_data.c_str());
if(checkSendCmd("","CLOSED")){
return false;
}else{
return true;
}
}else{
return false;
}
}
bool DFRobot_SIM7000::mqttSubscribe(const char* iot_topic)
{
if(checkSendCmd("AT+CIPSEND\r\n",">")){
char MQTTbuff[10]={0};
MQTTbuff[0] = 0x82;
MQTTbuff[1] = strlen(iot_topic)+5;
MQTTbuff[3] = 0x0a;
MQTTbuff[5] = strlen(iot_topic);
sendBuff(MQTTbuff,6);
sendCmd(iot_topic);
MQTTbuff[0] = 0x01;
sendBuff(MQTTbuff,1);
if(checkSendCmd("","CLOSED")){
return false;
}else{
return true;
}
}
return false;
}
bool DFRobot_SIM7000::mqttUnsubscribe(const char* iot_topic)
{
if(checkSendCmd("AT+CIPSEND\r\n",">")){
char MQTTbuff[10]={0};
MQTTbuff[0] = 0xa2;
MQTTbuff[1] = strlen(iot_topic)+4;
MQTTbuff[3] = 0x0a;
MQTTbuff[5] = strlen(iot_topic);
sendBuff(MQTTbuff,6);
sendCmd(iot_topic);
if(checkSendCmd("","CLOSED",1000)){
return false;
}else{
return true;
}
}else{
return false;
}
}
bool DFRobot_SIM7000::mqttRecv(char* iot_topic, char* buf, int maxlen)
{
char MQTTbuff[maxlen+30];
char *p;
cleanBuffer(MQTTbuff,maxlen+30);
int i = readBuffer(MQTTbuff,maxlen+30);
for(int j=0;j<i;j++){
if(NULL != (p = strstr(MQTTbuff+j,iot_topic))){
memcpy(buf,p+strlen(iot_topic),maxlen+30);
return true;
}
}
return false;
}
bool DFRobot_SIM7000::mqttDisconnect(void)
{
if(checkSendCmd("AT+CIPSEND\r\n",">")){
const char MQTTdata[2]={(char)0xe0,0x00};
sendBuff(MQTTdata,2);
if(checkSendCmd("","CLOSED")){
return true;
}else{
return false;
}
}else{
return false;
}
}
bool DFRobot_SIM7000::httpInit(eNet net)
{
if(net == eNB){
if(!checkSendCmd("AT+SAPBR=3,1,\"APN\",\"ctnb\"\r\n","OK")){
return false;
}
}else if(net == eGPRS){
if(!checkSendCmd("AT+SAPBR=3,1,\"APN\",\"cmnet\"\r\n","OK")){
return false;
}
}
if(!checkSendCmd("AT+SAPBR=1,1\r\n","OK")){
return false;
}
if(!checkSendCmd("AT+SAPBR=2,1\r\n","OK")){
return false;
}
return true;
}
bool DFRobot_SIM7000::httpConnect(const char *host)
{
httpDisconnect();
delay(1000);
if(!checkSendCmd("AT+HTTPINIT\r\n","OK")){
return false;
}
if(!checkSendCmd("AT+HTTPPARA=\"CID\",\"1\"\r\n","OK")){
return false;
}
sendCmd("AT+HTTPPARA=\"URL\",\"");
sendCmd(host);
if(!checkSendCmd("\"\r\n","OK")){
return false;
}
return true;
}
bool DFRobot_SIM7000::httpPost(const char *host , String data)
{
if(!httpConnect(host)){
return false;
}
char resp[40];
sendCmd("AT+HTTPDATA=");
itoa(data.length(), resp, 10);
sendString(resp);
if(!checkSendCmd(",4000\r\n","DOWNLOAD",5)){
return false;
}
delay(500);
DBG(data.c_str());
sendString(data.c_str());
while(1){
readBuffer(resp,20);
if(NULL != strstr(resp,"OK")){
break;
}
if(NULL != strstr(resp,"ERROR")){
return false;
}
}
sendCmd("AT+HTTPACTION=1\r\n");
while(1){
readBuffer(resp,40);
if(NULL != strstr(resp,"200")){
break;
}
if(NULL != strstr(resp,"601")){
return false;
}
}
//delay(11000);
sendCmd("AT+HTTPREAD\r\n");
return true;
}
void DFRobot_SIM7000::httpGet(const char *host)
{
char resp[40];
if(!httpConnect(host)){
return;
}
sendCmd("AT+HTTPACTION=0\r\n");
while(1){
readBuffer(resp,40);
if(NULL != strstr(resp,"200")){
break;
}
if(NULL != strstr(resp,"601")){
Serial.println("ERROR !");
return;
}
}
//delay(11000);
// if(checkSendCmd("AT+HTTPACTION=0\r\n","601")){
// }
sendCmd("AT+HTTPREAD\r\n");
get_String();
}
void DFRobot_SIM7000::httpDisconnect(void)
{
sendCmd("AT+HTTPTERM\r\n");
}
int DFRobot_SIM7000::recv(char* buf, int maxlen)
{
char gprsBuffer[maxlen];
cleanBuffer(gprsBuffer,maxlen);
int i=readBuffer(gprsBuffer,maxlen,1000);
Serial.print(i);
memcpy(buf,gprsBuffer,i);
return i;
}
bool DFRobot_SIM7000::getPosition(void)
{
char posBuffer[150];
char *position;
cleanBuffer(posBuffer,150);
sendCmd("AT+CGNSINF\r\n");
readBuffer(posBuffer,150);
DBG(posBuffer);
if(NULL != strstr(posBuffer,"+CGNSINF: 1,1")){
setCommandCounter(4);
}else{
return false;
}
if(getCommandCounter() == 4){
position = strstr(posBuffer,".000");
memcpy(_latitude , position+5 , 7);
memcpy(_longitude, position+15, 7);
setCommandCounter(5);
return true;
}else{
return false;
}
}
const char* DFRobot_SIM7000::getLatitude(void)
{
if(getCommandCounter() >= 5){
setCommandCounter(6);
return _latitude;
}else{
return "error";
}
}
const char* DFRobot_SIM7000::getLongitude(void)
{
if(getCommandCounter() >= 5){
setCommandCounter(6);
return _longitude;
}else{
return "error";
}
}
bool DFRobot_SIM7000::closeNetwork(void)
{
if(checkSendCmd("AT+CIPSHUT\r\n","OK",2000)){
return true;
}else{
return false;
}
}
int DFRobot_SIM7000::batteryPower(void)
{
char batteryBuff[26];
char *pBattery;
int i=0,j=0,k=0;
cleanBuffer(batteryBuff,26);
sendCmd("AT+CBC\r\n");
readBuffer(batteryBuff,26);
pBattery = strstr(batteryBuff,"+CBC:");
i = *(pBattery + 8) - 48;
j = *(pBattery + 9) - 48;
k = (i * 10) + j;
return k;
}
/*!
* @file DFRobot_SIM7000.h
* @brief Define the basic structure of DFRobot_SIM7000 class
* @details This is a stable low-power communication module, and it supports multiple frequency bands of LTE- tdd / LTE- fdd / GSM / GPRS / EDGE. The upload and download data flow peak at 375kbps.
* @copyright Copyright (c) 2021 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [TangJie](jie.tang@dfrobot.com)
* @version V1.0.1
* @date 2021-09-16
* @url https://github.com/DFRobot/DFRobot_SIM7000
*/
#ifndef __DFROBOT_SIM7000_H__
#define __DFROBOT_SIM7000_H__
#include "DFRobot_SIMcore.h"
#include "Arduino.h"
#include "String.h"
#define ON 0
#define OFF 1
#if 0
#define DBG(...) {Serial.print("["); Serial.print(__FUNCTION__); Serial.print("(): "); Serial.print(__LINE__); Serial.print(" ] "); Serial.println(__VA_ARGS__);}
#else
#define DBG(...)
#endif
class DFRobot_SIM7000 : public DFRobot_SIMcore{
public:
/**
* @enum eProtocol
* @brief Select Network communication protocol
*/
typedef enum {
eCLOSED = 0,
eTCP = 1,
eUDP = 2,
}eProtocol;
/**
* @enum eNet
* @brief Select data communication mode
*/
typedef enum {
eGPRS,
eNB,
}eNet;
public:
/**
* @fn DFRobot_SIM7000
* @brief DFRobot_SIMcore constructor of abstract class. Construct serial ports.
* @param s The pointer to abstract class, where you can fill in the pointer to serial object.
* @return None
*/
DFRobot_SIM7000(Stream *s);
~DFRobot_SIM7000(){};
/**
* @fn recv
* @brief Receive
* @param buf Receive data content
* @param maxlen Receive data length
* @return Get data length
*/
int recv(char* buf, int maxlen);
/**
* @fn checkSignalQuality
* @brief Check signal quality
* @return 0-30:Signal quality
*/
int checkSignalQuality(void);
/**
* @fn batteryPower
* @brief Battery power
* @return Battery power
*/
int batteryPower(void);
/**
* @fn setNetMode
* @brief Set net mode
* @param net The net mode
* @n GPRS: GPRS mode
* @n NB: NB-IOT mode
* @return bool type, indicating the status of setting
* @retval ture Success
* @retval false Failed
*/
bool setNetMode(eNet net);
/**
* @fn attacthService
* @brief Open the connection
* @return bool type, indicating the status of opening the connection
* @retval true Success
* @retval false Failed
*/
bool attacthService(void);
/**
* @fn setBaudRate
* @brief Set baud rate to avoid garbled
* @param rate Baud rate value
* @n Possible values:1200 2400 4800 9600 19200 38400
* @note SIM7000 default baud rate is 115200, reduce the baud rate to avoid distortion
* @return bool type, indicating the status of setting
* @retval true Success
* @retval false Failed
*/
bool setBaudRate(long rate);
/**
* @fn checkSIMStatus
* @brief Check SIM card
* @return bool type, indicating the status of checking SIM card
* @retval true Success
* @retval false Failed
*/
bool checkSIMStatus(void);
/**
* @fn openNetwork
* @brief Start up connection
* @param ptl Choose connection protocol
* @n TCP Choose TCP
* @n UDP Choose UDP
* @param host Host domain name
* @param port Contented port
* @return bool type, indicating the status of opening Network
* @retval true Success
* @retval false Failed
*/
bool openNetwork(eProtocol ptl, const char *host, int port);
/**
* @fn closeNetwork
* @brief End the connection
* @return bool type, indicating the status of closing Network
* @retval true Success
* @retval false Failed
*/
bool closeNetwork(void);
/**
* @fn turnON
* @brief Turn ON SIM7000
* @return bool type, indicating the status of turning on
* @retval true Success
* @retval false Failed
*/
bool turnON(void);
/**
* @fn initPos
* @brief Init SIM7000 positioning module
* @return bool type, indicating the initialization status
* @retval true Success
* @retval false Failed
*/
bool initPos(void);
/**
* @fn mqttConnect
* @brief MQTT connect request
* @param iot_client Client name user-defined
* @param iot_username The user name identifies the name of the user who is connecting
* @param iot_key The password for user
* @return bool type, indicating the connection status
* @retval true Success
* @retval false Failed
*/
bool mqttConnect(const char* iot_client, const char* iot_username, const char* iot_key);
/**
* @fn mqttPublish
* @brief MQTT send command
* @param iot_topic Target topic
* @param iot_data The data you want to send
* @return bool type, indicating status of sending
* @retval true Success
* @retval false Failed
*/
bool mqttPublish(const char* iot_topic, String iot_data);
/**
* @fn mqttSubscribe
* @brief Subscribe MQTT channel
* @param iot_topic The subscribed MQTT key
* @return bool type, indicating subscription status
* @retval true Success
* @retval false Failed
*/
bool mqttSubscribe(const char* iot_topic);
/**
* @fn mqttUnsubscribe
* @brief Unsubscribe MQTT channel
* @param iot_topic The unsubscribed MQTT key
* @return bool type, indicating unsubscribe status
* @retval true Success
* @retval false Failed
*/
bool mqttUnsubscribe(const char* iot_topic);
/**
* @fn mqttRecv
* @brief MQTT send data
* @param iot_topic Subscribe channel key
* @param buf Send data
* @param maxlen Send data length
* @return bool type, indicating subscription status
* @retval true Success
* @retval false Failed
*/
bool mqttRecv(char* iot_topic, char* buf,int maxlen);
/**
* @fn mqttDisconnect
* @brief MQTT disconnection
* @return bool type, indicating disconnection status
* @retval true Success
* @retval false Failed
*/
bool mqttDisconnect(void);
/**
* @fn httpInit
* @brief Initialize HTTP service
* @param net The net mode
* @n eGPRS: GPRS mode
* @n eNB: NB-IOT mode
* @return bool type, indicating initialization status
* @retval true Success
* @retval false Failed
*/
bool httpInit(eNet net);
/**
* @fn httpConnect
* @brief Connect to server
* @param host Server IP
* @return bool type, indicating connection status
* @retval true Success
* @retval false Failed
*/
bool httpConnect(const char *host);
/**
* @fn httpPost
* @brief HTTP POST
* @param host URL
* @param data POST data
* @return bool type, indicating request status
* @retval true Success
* @retval false Failed
*/
bool httpPost(const char *host , String data);
/**
* @fn httpGet
* @brief HTTP GET This function print the get data
* @param host URL
*/
void httpGet(const char *host);
/**
* @fn httpDisconnect
* @brief Disconnect from server and cancel initialization
*/
void httpDisconnect(void);
/**
* @fn send
* @brief Send data with specify the length
* @param buf The buffer for data to be send
* @param len The length of data to be send
* @return bool type, indicating status of sending
* @retval true Success
* @retval false Failed
*/
bool send(char *buf,size_t len);
/**
* @fn send
* @brief Send data
* @param data The data to send
* @return bool type, indicating status of sending
* @retval true Success
* @retval false Failed
*/
bool send(char *data);
/**
* @fn getPosition
* @brief Get the current position
* @return bool type, indicating the status of getting position
* @retval true Success
* @retval false Failed
*/
bool getPosition(void);
/**
* @fn getLatitude
* @brief Get latitude
* @return Latitude value
*/
const char* getLatitude(void);
/**
* @fn getLongitude
* @brief Get longitude
* @return Longitude value
*/
const char* getLongitude(void);
private:
char _latitude[8];
char _longitude[8];
int _mode_t=0;
long _baudrate = 19200;
Stream *_s;
};
#endif
#include <DFRobot_SIMcore.h>
DFRobot_SIMcore::DFRobot_SIMcore(Stream *s)
{
_s = s;
}
bool DFRobot_SIMcore::begin(void)
{
int count = 0;
delay(1000);
while(count < 3){
if(checkSendCmd("AT\r\n","OK")){
break;
}else{
count++;
delay(300);
}
}
if(count == 3){
closeCommand();
return false;
}
count = 0;
while(count < 3){
if(checkSendCmd("AT+CPIN?\r\n","READY")){
break;
}else{
count++;
delay(300);
}
}
if(count == 3){
closeCommand();
return false;
}
setCommandCounter(1);
return true;
}
bool DFRobot_SIMcore::turnOFF(void)
{
if(checkSendCmd("AT+CPOWD=1\r\n","NORMAL POWER DOWN")){
closeCommand();
return true;
}else{
return false;
}
}
void DFRobot_SIMcore::setPhoneNumber(char *n)
{
_phoneNumber = n;
}
char* DFRobot_SIMcore::getPhoneNumber(void)
{
return _phoneNumber;
}
void DFRobot_SIMcore::setPort(int p)
{
_port = p;
}
int16_t DFRobot_SIMcore::getPort(void)
{
return _port;
}
void DFRobot_SIMcore::setCommandCounter(uint8_t c)
{
_commandCounter = c;
}
uint8_t DFRobot_SIMcore::getCommandCounter(void)
{
return _commandCounter;
}
void DFRobot_SIMcore::setCommandError(uint8_t n)
{
_commandError = n;
}
uint8_t DFRobot_SIMcore::getCommandError(void)
{
return _commandError;
}
void DFRobot_SIMcore::setOngoingCommand(eSIMCommand_t c)
{
_ongoingCommand = c;
}
DFRobot_SIMcore::eSIMCommand_t DFRobot_SIMcore::getOngoingCommand(void)
{
return _ongoingCommand;
}
void DFRobot_SIMcore::openCommand(eSIMCommand_t c)
{
setCommandError(0);
setCommandCounter(1);
setOngoingCommand(c);
}
void DFRobot_SIMcore::closeCommand()
{
setCommandError(0);
setCommandCounter(0);
setOngoingCommand(eNONE);
}
bool DFRobot_SIMcore::checkSendCmd(const char* cmd, const char* resp, uint32_t timeout)
{
char SIMbuffer[100];
cleanBuffer(&SIMbuffer[0],100);
sendCmd(cmd);
readBuffer(&SIMbuffer[0],100, timeout);
DBG(SIMbuffer);
if(NULL != strstr(SIMbuffer,resp)){
return true;
}else{
return false;
}
}
int DFRobot_SIMcore::checkReadable(void)
{
return _s->available();
}
void DFRobot_SIMcore::sendCmd(const char* cmd)
{
_s->write(cmd);
}
void DFRobot_SIMcore::sendBuff(const char* buff,size_t num)
{
_s->write(buff,num);
}
void DFRobot_SIMcore::sendString(const char* buff)
{
DBG(buff);
_s->print(buff);
}
void DFRobot_SIMcore::cleanBuffer(char *buffer,int count)
{
int i;
for(i=0; i < count; i++){
buffer[i] = '\0';
}
}
uint16_t DFRobot_SIMcore::readBuffer(char *buffer, uint16_t count, uint32_t timeout)
{
uint16_t i = 0;
uint64_t timecnt = millis();
while(1){
if(_s->available()){
buffer[i++] =(char)_s->read();
timecnt = millis();
}
if(i == count)
return i;
if((millis()-timecnt) > (timeout)){
DBG(buffer);
DBG(i);
break;
}
}
return i;
}
void DFRobot_SIMcore::get_String(void)
{
uint64_t t1 = millis();
while(1){
if(checkReadable()){
Serial.print(char(_s->read()));
t1 = millis();
}
if((millis() - t1) > 10000){
return;
}
}
}
/*!
* @file DFRobot_SIMcore.h
* @brief Basic structure of DFRobot_SIMcore class
* @details A basic class library for SIM product series communication.
* @copyright Copyright (c) 2021 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author [TangJie](jie.tang@dfrobot.com)
* @version V1.0.1
* @date 2021-09-16
* @url https://github.com/DFRobot/DFRobot_SIM
*/
#ifndef __DFRobot_SIMCORE_H__
#define __DFRobot_SIMCORE_H__
#include <Arduino.h>
#include <stdint.h>
#include <Wire.h>
#include <stdio.h>
#include "SoftwareSerial.h"
#if 0
#define DBG(...) {Serial.print("["); Serial.print(__FUNCTION__); Serial.print("(): "); Serial.print(__LINE__); Serial.print(" ] "); Serial.println(__VA_ARGS__);}
#else
#define DBG(...)
#endif
#define DEFAULT_TIMEOUT 5 //seconds
#define DEFAULT_INTERCHAR_TIMEOUT 1500 //miliseconds
class DFRobot_SIMcore{
public:
/**
* @enum eSIMCommand_t
* @brief SIM mode select command
*/
typedef enum {
eXON,
eNONE,
eMODEMCONFIG,
eALIVETEST,
eBEGINSMS,
eENDSMS,
eAVAILABLESMS,
eFLUSHSMS,
eVOICECALL,
eANSWERCALL,
eHANGCALL,
eRETRIEVECALLINGNUMBER,
eATTACHGPRS,
eDETACHGPRS,
eCONNECTTCPCLIENT,
eDISCONNECTTCP,
eBEGINWRITESOCKET,
eENDWRITESOCKET,
eAVAILABLESOCKET,
eFLUSHSOCKET,
eCONNECTSERVER,
eGETIP,
eGETCONNECTSTATUS,
eGETLOCATION,
eGETICCID
}eSIMCommand_t;
/**
* @fn DFRobot_SIMcore
* @brief DFRobot_SIMcore constructor of abstract class. Construct serial ports.
* @param s The pointer to abstract class, where you can fill in the pointer to serial object.
*/
DFRobot_SIMcore(Stream *s);
~DFRobot_SIMcore(){};
/**
* @fn begin
* @brief Init specified module
* @return bool type, indicating initialization status
* @retval true Success
* @retval false Failed
*/
bool begin(void);
/**
* @fn checkSendCmd
* @brief Send data and judge the accuracy the returned data
* @param cmd Command to be sent
* @param resp The returned data to be judged
* @param timeout Timeout value (unit: ms)
* @return bool type, indicating the status of judging the returned data
* @retval true same
* @retval false different
*/
bool checkSendCmd(const char* cmd = NULL, const char* resp = NULL, uint32_t timeout = 1000);
/**
* @fn checkReadable
* @brief Check the number of data in serial port
* @return Return the number of data in serial port
*/
int checkReadable(void);
/**
* @fn sendCmd
* @brief Send command
* @param cmd The sent command
*/
void sendCmd(const char* cmd);
/**
* @fn sendBuff
* @brief Send data
* @param buff Data to be sent
* @param num Length of data to be sent
*/
void sendBuff(const char* buff, size_t num);
/**
* @fn sendString
* @brief Send string through serial port
* @param buff Buffer for string to be sent
*/
void sendString(const char* buff);
/**
* @fn cleanBuffer
* @brief Clear data in buffer
* @param buffer Buffer to be cleared
* @param count Length of data to be cleared
*/
void cleanBuffer(char *buffer, int count);
/**
* @fn readBuffer
* @brief Parse the data returned by the serial port
* @param buffer Buffer for data to be received
* @param count Length of data to be received
* @param timeout Timeout value (unit: ms)
* @return Receive data length
*/
uint16_t readBuffer(char *buffer = NULL, uint16_t count = 1, uint32_t timeout =1000);
/**
* @fn turnOFF
* @brief Turn off SIM7000X module
* @return bool type, indicating closing status
* @retval true Success
* @retval false Failed
*/
bool turnOFF(void);
/**
* @fn setCommandCounter
* @brief Set command counter
* @param c Command value
*/
void setCommandCounter(uint8_t c);
/**
* @fn getCommandCounter
* @brief Get command counter
* @return Command count value
*/
uint8_t getCommandCounter();
/**
* @fn get_String
* @brief Print the string returned by the serial port
*/
void get_String(void);
/**
* @fn closeCommand
* @brief Close control command
*/
void closeCommand(void);
private:
void setPhoneNumber(char *n);
char* getPhoneNumber();
void setPort(int p);
int16_t getPort(void);
void setCommandError(uint8_t n);
uint8_t getCommandError(void);
void setOngoingCommand(eSIMCommand_t c);
eSIMCommand_t getOngoingCommand(void);
void openCommand(eSIMCommand_t c);
char* _phoneNumber;
uint8_t _commandCounter;
int16_t _port;
uint8_t _commandError;
eSIMCommand_t _ongoingCommand;
Stream *_s;
long _baudrate = 19200;
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment