132 lines
3.1 KiB
C++
132 lines
3.1 KiB
C++
#include <ModbusMaster.h>
|
|
#include <TinyGPS++.h>
|
|
#include <SoftwareSerial.h>
|
|
#include "register_map_pm8000.h"
|
|
|
|
#define SIM808_RX 2
|
|
#define SIM808_TX 3
|
|
#define RS485_DE_RE 4
|
|
#define RS485_RX 8
|
|
#define RS485_TX 7
|
|
#define LED_A 3
|
|
#define LED_B 5
|
|
|
|
SoftwareSerial sim808(SIM808_RX, SIM808_TX);
|
|
SoftwareSerial rs485(RS485_RX, RS485_TX);
|
|
ModbusMaster modbus;
|
|
TinyGPSPlus gps;
|
|
|
|
const char APN[] = "your_apn_here";
|
|
const char SERVER_URL[] = "http://your-server-url.com/upload";
|
|
const int SLAVE_ID = 101;
|
|
const long INTERVAL = 60000; // 1 minute
|
|
|
|
unsigned long lastSendTime = 0;
|
|
|
|
void setup() {
|
|
Serial.begin(9600);
|
|
sim808.begin(9600);
|
|
rs485.begin(9600);
|
|
|
|
pinMode(RS485_DE_RE, OUTPUT);
|
|
pinMode(LED_A, OUTPUT);
|
|
pinMode(LED_B, OUTPUT);
|
|
|
|
digitalWrite(RS485_DE_RE, LOW);
|
|
digitalWrite(LED_A, LOW);
|
|
digitalWrite(LED_B, LOW);
|
|
|
|
modbus.begin(SLAVE_ID, rs485);
|
|
|
|
// Initialize SIM808
|
|
sim808.println("AT+CGNSPWR=1"); // Turn on GNSS
|
|
delay(1000);
|
|
sim808.println("AT+CGNSSEQ=\"RMC\""); // Set NMEA sentence to RMC
|
|
delay(1000);
|
|
sim808.println("AT+CGDCONT=1,\"IP\",\"" + String(APN) + "\"");
|
|
delay(1000);
|
|
sim808.println("AT+HTTPINIT");
|
|
delay(1000);
|
|
|
|
Serial.println("Setup complete");
|
|
}
|
|
|
|
void loop() {
|
|
unsigned long currentTime = millis();
|
|
|
|
// Read GPS data
|
|
while (sim808.available()) {
|
|
gps.encode(sim808.read());
|
|
}
|
|
|
|
if (currentTime - lastSendTime >= INTERVAL) {
|
|
lastSendTime = currentTime;
|
|
|
|
String data = createDataString();
|
|
sendDataToServer(data);
|
|
}
|
|
}
|
|
|
|
String createDataString() {
|
|
String data = "";
|
|
|
|
// Add GPS data
|
|
if (gps.location.isValid()) {
|
|
data += String(gps.location.lat(), 6) + "," + String(gps.location.lng(), 6) + ",";
|
|
} else {
|
|
data += "0.000000,0.000000,";
|
|
}
|
|
|
|
// Read Modbus registers
|
|
for (int i = 0; i < sizeof(registers) / sizeof(registers[0]); i++) {
|
|
uint16_t result = modbus.readHoldingRegisters(registers[i].address - 1, 2);
|
|
|
|
if (result == modbus.ku8MBSuccess) {
|
|
switch (registers[i].type) {
|
|
case 2: // Float
|
|
data += String(modbus.getResponseBuffer(0)) + ",";
|
|
break;
|
|
case 1: // Integer
|
|
data += String(modbus.getResponseBuffer(0)) + ",";
|
|
break;
|
|
case 0: // Long
|
|
uint32_t longValue = (modbus.getResponseBuffer(0) << 16) | modbus.getResponseBuffer(1);
|
|
data += String(longValue) + ",";
|
|
break;
|
|
}
|
|
} else {
|
|
data += "ERROR,";
|
|
digitalWrite(LED_B, HIGH);
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
void sendDataToServer(String data) {
|
|
sim808.println("AT+HTTPDATA=" + String(data.length()) + ",10000");
|
|
delay(1000);
|
|
sim808.println(data);
|
|
delay(1000);
|
|
sim808.println("AT+HTTPACTION=1"); // POST request
|
|
|
|
// Wait for response
|
|
unsigned long start = millis();
|
|
while (millis() - start < 10000) {
|
|
if (sim808.available()) {
|
|
String response = sim808.readString();
|
|
if (response.indexOf("+HTTPACTION: 1,200") != -1) {
|
|
digitalWrite(LED_A, HIGH);
|
|
delay(200);
|
|
digitalWrite(LED_A, LOW);
|
|
Serial.println("Data sent successfully");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
digitalWrite(LED_B, HIGH);
|
|
delay(200);
|
|
digitalWrite(LED_B, LOW);
|
|
Serial.println("Failed to send data");
|
|
} |