2025-01-06T13:55:01.png
合宙AIR001 Nano开发板

合宙的这块板价格便宜,可以使用arduino进行编程,价格便宜,体积小,非常好看。

然而它与arduino nano相比没有EEPROM,flash空间也小很多,没有板载ch340芯片

所以,下载时记住按住BOOT键再上电,点击下载,下载完成后再松手。

另外,windows的用户名不能有中文,否则arduino编译时路径有中文,无法编译通过。

资料下载中心网址 https://product.abrobot.club

2025-01-06T14:03:20.png

2025-01-06T14:00:05.png

const char *deviceName = "CAR2";

// GPS 数据缓冲区
char gpsBuffer[100]; // 存储 GPS 数据的缓冲区
bool gpsDataReady = false;

// 函数声明
void sendCommand(const char *cmd);
void parseGPSData(const char *data);
void sendMQTTMessage(float latitude, float longitude);

// 初始化
void setup() {
  // 设置串口通信
  Serial.begin(9600);  // 串口通信

  // 等待模块启动
  delay(8000);

  // 初始化 GPS 定位
  sendCommand("AT+MGPSC=1\r\n"); // 开启 GPS 功能
  delay(500);
  sendCommand("AT+MGPSGET=0\r\n"); // 暂时关闭 NMEA 数据输出
  delay(500);

  // 设置 4G MQTT 连接
  sendCommand("AT+MDISCONNECT\r\n"); // 断开已有 MQTT 连接
  delay(200);
  sendCommand("AT+MIPCLOSE\r\n");    // 关闭当前会话
  delay(200);
  sendCommand("AT+QICSGP=1,1,\"\",\"\",\"\"\r\n"); // 设置 APN
  delay(200);
  sendCommand("AT+NETOPEN\r\n");     // 打开网络
  delay(3000);

  // 配置 MQTT 连接
  sendCommand("AT+MCONFIG=\"设备名称\",\"\",\"\",0,0,0,\"1883\",\"2024\"\r\n");
  delay(200);
  sendCommand("AT+MIPSTART=\"nbzch.cn\",1883,3\r\n"); // 连接 MQTT Broker
  delay(2000);
  sendCommand("AT+MCONNECT=0,60\r\n"); // 连接到 MQTT 服务器
  delay(200);
  sendCommand("AT+MGPSGET=ALL,1\r\n");
  delay(200);

  // 向 gps/lastLocation 发送 online 消息
  char onlineMessage[100];
  snprintf(onlineMessage, sizeof(onlineMessage), "{\"name\":\"%s\",\"msg\":\"online\"}", deviceName);

  char mqttCommand[100];
  snprintf(mqttCommand, sizeof(mqttCommand), "AT+MPUBEX=\"gps/lastLocation\",0,0,%d\r\n", strlen(onlineMessage));

  sendCommand(mqttCommand);       // 发送 MQTT 发布指令
  Serial.print(onlineMessage); // 发送消息内容
}

void loop() {

  static int index = 0;
  while (Serial.available()) {
    char c = Serial.read();

    if (c == '\n') {
      gpsBuffer[index] = '\0';
      index = 0;
      gpsDataReady = true;
    } else if (c != '\r') {
      gpsBuffer[index++] = c;
    }

    if (gpsDataReady) {
      gpsDataReady = false;
      if (strncmp(gpsBuffer, "$GNGLL", 6) == 0) {
        parseGPSData(gpsBuffer);
      }
    }
  }
}

// 发送 AT 指令
void sendCommand(const char *cmd) {
  Serial.print(cmd);
  delay(500); // 等待模块响应
}

// 转换 GPS 数据中的纬度和经度格式
float convertToDecimalDegrees(float rawValue) {
  int degrees = (int)(rawValue / 100);           // 提取度部分
  float minutes = rawValue - (degrees * 100);    // 提取分部分
  return degrees + (minutes / 60.0);             // 转换为十进制度
}

// 解析 GPS 数据
void parseGPSData(const char *data) {
  // 创建一个可以修改的字符数组
  char dataCopy[100];
  strncpy(dataCopy, data, sizeof(dataCopy) - 1); // 复制 data 到 dataCopy
  dataCopy[sizeof(dataCopy) - 1] = '\0';  // 确保字符串结尾

  char *token;
  char gpsLat[15], gpsLon[15], latDirection, lonDirection;
  float latitude, longitude;

  token = strtok(dataCopy, ",");  // 跳过 GNGLL
  token = strtok(NULL, ",");      // Latitude
  strcpy(gpsLat, token);

  token = strtok(NULL, ",");      // Latitude Direction (N/S)
  latDirection = *token;

  token = strtok(NULL, ",");      // Longitude
  strcpy(gpsLon, token);

  token = strtok(NULL, ",");      // Longitude Direction (E/W)
  lonDirection = *token;

  token = strtok(NULL, ",");      // UTC time (忽略)

  token = strtok(NULL, ",");      // Status (A = Active, V = Void)
  char status = *token;

  if (status == 'A') { // 如果定位有效
    latitude = atof(gpsLat);       // 原始纬度
    longitude = atof(gpsLon);     // 原始经度

    // 将纬度和经度转换为十进制度
    latitude = convertToDecimalDegrees(latitude);
    longitude = convertToDecimalDegrees(longitude);

    // 根据 N/S 和 E/W 修改经纬度符号
    if (latDirection == 'S') latitude = -latitude;
    if (lonDirection == 'W') longitude = -longitude;

    // 通过 MQTT 发送 GPS 数据
    sendMQTTMessage(latitude, longitude);
  } 
}


// 发送 MQTT 消息
void sendMQTTMessage(float latitude, float longitude) {
  char latBuffer[15]; // 用于存储纬度的字符串
  char lonBuffer[15]; // 用于存储经度的字符串

  // 转换浮点数为字符串
  dtostrf(latitude, 0, 6, latBuffer); // 6 表示保留 6 位小数
  dtostrf(longitude, 0, 6, lonBuffer);

  char mqttMessage[100]; // 增大缓冲区
  snprintf(mqttMessage, sizeof(mqttMessage), "{\"name\":\"%s\",\"lat\":%s,\"lon\":%s}", deviceName, latBuffer, lonBuffer);

  char mqttCommand[100];
  snprintf(mqttCommand, sizeof(mqttCommand), "AT+MPUBEX=\"gps/location\",0,0,%d\r\n", strlen(mqttMessage));

  sendCommand(mqttCommand);       // 发送 MQTT 发布指令
  Serial.print(mqttMessage); // 发送消息内容
}

发表评论