实现Socket通讯


1.网页测试工具

2.串口调试工具llcom  相关信息输出到串口,便于掌握程序的运行情况

3.

本程序:使用socket实现通信,DTU向服务器发送"ready"表示设备上线,服务端向DTU发送1或2控制DTU上LED灯的颜色,3关闭所有socket,设备下线;服务端发回的其他信息可打印到串口

注意选择开发板为M5Stack Atom

#include 
#include 

ATOM_DTU_NB DTU;
const char* hex = "0123456789ABCDEF";
String data1 = "ready";
String readstr;

String str_hex;
String hex_str;

char getValue(char x){//将一个表示十六进制字符转换为相应的数值
  for(int i=0;i<16;i++){
    if(hex[i] == x)return i;
  }
}
int s,ed;
void stringToHex(String thedata){//将字符串转为HEX码
  for (int i = 0; i < thedata.length(); i++){
    str_hex += String(thedata[i],HEX);
  }
}
void hexToString(String thedata){
  hex_str = "";
  for(int i=0;i2){
    char c = getValue(thedata.charAt(i));
    c = c<<4;
    char d = getValue(thedata.charAt(i+1));
    c = c+d;
    hex_str += c;
  }
}

void setup() {
  M5.begin(true,true,true);
  DTU.Init(&Serial2,19,22); 
  DTU.sendMsg("AT+COPS=0\r\n");
  delay(2); 

  DTU.sendMsg("AT+COPS?\r\n");
  do{
    readstr = DTU.waitMsg(1000);
    Serial.print(".");
  }while(!readstr);
  Serial.print(readstr);
  if(readstr.endsWith("OK\r\n")){
      Serial.print("连接到运营商\n");
  }else{
      Serial.print("未连接到运营商\n");  
      return;
  }
  
  DTU.sendMsg("AT+CSOC=1,1,1\r\n");
  delay(2); 
  DTU.sendMsg("AT+CSOCON=0,37652,112.125.89.8\r\n");
  do{
    readstr = DTU.waitMsg(1000);
  }while(!readstr);
  Serial.print(readstr);
  if(readstr.endsWith("OK\r\n")){
      Serial.print("socket建立成功\n");
  }else{
      Serial.print("socket建立失败\n");
      return;
  }
  stringToHex(data1);
  String tmp1 = "AT+CSOSEND=0,10,";
  tmp1 += str_hex;
  tmp1 += "\r\n";
  DTU.sendMsg(tmp1); //向服务端发送"ready"
}

void loop() {
  DTU.sendMsg("AT+CSORXGET?\r\n");
  readstr = DTU.waitMsg(1000);
  s = readstr.lastIndexOf(",");//返回,的索引
  if(s != -1){//说明有数据返回
    ed = readstr.lastIndexOf("\r");
    hexToString(readstr.substring(s+1,ed));
    if(hex_str.equals("1")){
       M5.dis.drawpix(0, 0x00ff00);//显示绿色
    }
    else if(hex_str.equals("2")){
      M5.dis.drawpix(0, 0x0000ff);//显示蓝色
    }
    else if(hex_str.equals("3")){//关闭所有socket
      DTU.sendMsg("AT+CSOCL=0\r\n");
      DTU.sendMsg("AT+CSOCL=1\r\n");
      DTU.sendMsg("AT+CSOCL=2\r\n");
      DTU.sendMsg("AT+CSOCL=3\r\n");
      DTU.sendMsg("AT+CSOCL=4\r\n");
    }
    else Serial.print(hex_str);
  }
}
第一版

更加严谨的第二版 

要注意的是DTU.waitMsg()读到的字符串都是以"\r\n"开头和结束的,笔者在这上面跌了跟头,使用startsWith和endsWith()函数多次因为没注意到这一点产生bug

#include 
#include 

ATOM_DTU_NB DTU;
const char* hex = "0123456789ABCDEF";
String data1 = "ready";
String readstr;

String str_hex;
String hex_str;
String tmp1;
char socket_id;
char getValue(char x){//将一个表示十六进制字符转换为相应的数值
  for(int i=0;i<16;i++){
    if(hex[i] == x)return i;
  }
}
int s,ed;
void stringToHex(String thedata){//将字符串转为HEX码
  for (int i = 0; i < thedata.length(); i++){
    str_hex += String(thedata[i],HEX);
  }
}
void hexToString(String thedata){
  hex_str = "";
  for(int i=0;i2){
    char c = getValue(thedata.charAt(i));
    c = c<<4;
    char d = getValue(thedata.charAt(i+1));
    c = c+d;
    hex_str += c;
  }
}
void myRead(){
  do{
    readstr = DTU.waitMsg(1000);
  }while(!readstr);
  Serial.print(readstr);
}
void setup() {
  M5.begin(true,true,true);
  DTU.Init(&Serial2,19,22); 
  DTU.sendMsg("AT+COPS=0\r\n");
  delay(2); 
  DTU.sendMsg("AT+COPS?\r\n");
  myRead();
  
  if(readstr.endsWith("OK\r\n")){
      Serial.print("连接到运营商\n");
  }else{
      Serial.print("未连接到运营商\n");  
  }

  DTU.sendMsg("AT+CSOC=1,1,1\r\n");
  delay(2); 
  myRead();
  socket_id = readstr.charAt(readstr.indexOf("+CSOC: ")+7);
  tmp1 = "AT+CSOCON=*,34026,112.125.89.8\r\n";
  tmp1.setCharAt(tmp1.indexOf("*"),socket_id);
  DTU.sendMsg(tmp1);
  readstr = DTU.waitMsg(3000);
  if(readstr.endsWith("OK\r\n")){
      Serial.print("socket建立成功\n");
  }else{
      Serial.print("socket建立失败\n");
  }
  stringToHex(data1);
  tmp1 = "AT+CSOSEND=*,10,";
  tmp1.setCharAt(tmp1.indexOf("*"),socket_id);
  tmp1 += str_hex;
  tmp1 += "\r\n";
  DTU.sendMsg(tmp1); //向服务端发送"ready"
}

void loop() {
  myRead();
  if(readstr.startsWith("\r\n+CSONMI:")){
    s = readstr.lastIndexOf(",");//返回,的索引
    if(s != -1){//说明有数据返回
     ed = readstr.lastIndexOf("\r");
     hexToString(readstr.substring(s+1,ed));
     if(hex_str.equals("1")){
        M5.dis.drawpix(0, 0x00ff00);//显示绿色
     }
     else if(hex_str.equals("2")){
        M5.dis.drawpix(0, 0x0000ff);//显示蓝色
     }
     else if(hex_str.equals("3")){//关闭所有socket
       DTU.sendMsg("AT+CSOCL=0\r\n");
       DTU.sendMsg("AT+CSOCL=1\r\n");
       DTU.sendMsg("AT+CSOCL=2\r\n");
       DTU.sendMsg("AT+CSOCL=3\r\n");
       DTU.sendMsg("AT+CSOCL=4\r\n");
     }
     else Serial.print(hex_str);
    }
  }
}

 

 应用跑完,关闭掉所有的socket连接,是一个好习惯。

相关