Arduino Protocol

Ross Pickthall5 years ago

Hi Cuantic, I certainly will. I won't be in a position to share until Sunday now but have no problem putting the code up here when I can.
In a previous project, I struggled to get a TCP connection and doing everything else I needed to do with the ATmega328 due to program size, but I'm using libraries, how are you finding working within the constraints of it. I must admit I didn't actually consider the 328 again for this project, I just assumed my program would be too big, although, in reality, it's probably smaller than previous ones. Do you have code you're able to share?

treblig5 years ago

@Ross Pickthall:
I haven't used U-Center in a good while but I seem to remember it's not obvious to save the config to the module "for good". From (my aging) memory, there's a button to send the config to the module and a menu entry to actually save it in the flash memory.
It's also possible to put the config in the Arduino program and send it to the GPS whenever the Arduino prog runs. If my memory serves me well, it's possible to get the config commands in the U-Center prog and copy them in the Arduino prog. Sorry I can't be more precise: it's something I did for work a few years ago and I since retired. I believe I got the idea after watching a youtube video by "iforce2d". He's more into RC planes but he's got a few videos dedicated to GPS and SIMcom modules, all fully documented.

Let us know how it goes with reducing the power consumption.

Treblig

Ross Pickthall5 years ago

Here's a copy of my code, I haven't had a chance to do any more on this recently and I'm self taught in this so it might not be the best... :

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <gprs.h>

#define SIM800Reset 5 // SIM 800 module reset pin
#define ignitionSensor 0 //sensor pin for ignition running or not. 
#define SIM800pwr 18// pin to control SIM800 power pin. 

//TIME CONSTANTS BETWEEN SENDING VALUES>
long longTC = 15; //multiplies by 8s
long shortTC = 8; //multiplies by 8s

//Storage for battery voltage
unsigned int ADCValue;//Battery voltage readings
double Voltage;//Battery voltage readings
double Vcc;//Battery voltage readings

// For GPRS Connection - can't remember why these need to be global, I think it breaks if they;re not though
char buffer[0];
char http_cmd [512];

GPRS gprs; // the gprs opject

static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;


void setup() {

  Serial.begin(115200);
  //Save Power by writing all Digital IO LOW - note that pins just need to be tied one way or another, do not damage devices!
  pinMode(0, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(18, OUTPUT);
 
  digitalWrite(SIM800pwr, LOW);  //turn on power to the SIM800 module. 
  digitalWrite(SIM800Reset, LOW);
  delay(500);
  digitalWrite(SIM800Reset, HIGH);
  Serial1.begin(9600);
  Serial.println(F("Traccar Client v0.6 (24/09/2019) - R PICKTHALL >>>"));
  Serial.println();
  Serial.println(gprs.sendCmdAndWaitForResp("AT\r\n", "OK", 10));
  gprs.preInit();
  gprs.init();

  setupWDT();

}

long readVcc() {  //Get the actual VCC voltage for battery voltage measurement instead of assuming 5v.
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA, ADSC));
  result = ADCL;
  result |= ADCH << 8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
}


float voltageMeasure() {
  const float r1 = 9730;   // measured resistor values for voltage calculation
  const float r2 = 4650;
  Vcc = readVcc() / 1000.0;  
  ADCValue = analogRead(0);
  Voltage = (ADCValue / 1023.0) * Vcc;
  Voltage = Voltage * (r1 + r2) / r2 ;  
  Serial.print("Voltage: ");
  Serial.println(Voltage);
  return Voltage;
}

void setupWDT() { //this needs to run once as part of the setup routine
  //SETUP WDT
  WDTCSR = (24); //change enable and WDE bits
  WDTCSR = (33); //prescalers only, clear WDE and WDCE (Change enable) setting to 8s
  WDTCSR |= (1 << 6); //enables the interrupt mode.
  //Enable sleep  on 328
  SMCR |= (1 << 2); //power down mode. Move the 1 across two places
  SMCR |= 1; //Enable sleep
}


void goToSleep() { //Here we activate the power down mode of the arduino and the brown out detection disable.
  long TC;


  for (int i = 0; i < TC; i++) {//This multiplies the WDT timeout by i. The device will wake itself up only to put itself immediately back to sleep.

    if (checkIgnitionState() == 1) {
      TC = shortTC;
    } else if (checkIgnitionState() == 0) {
      TC = longTC;
    }

    //BOD disable
    MCUCR |= (3 << 5); // Sets both BODS & BODSE at the same time
    MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); //then set BODS and clear BODSE at the same time.
    ADCSRA &= ~(1 << ADEN); //Disable ADC, this helps with power down efficiency
    __asm__ __volatile__("sleep");
  }

}

bool checkIgnitionState() {
  bool ignitionState = digitalRead(ignitionSensor);
  return ignitionState;
}

void loop() {

  //Serial.println("loop");
  //delay(1000);  //just for testing... 
    while (Serial1.available() > 0)  //if serial information is available from the GPS, read it.
    if (gps.encode(Serial1.read()))
  getGPS();
  //delay(2000);

}


void getGPS()
{
  

      
        Serial.print(F("Location: "));
        if (gps.location.isValid())
        {
          Serial.print(gps.location.lat(), 6);
          Serial.print(F(","));
          Serial.print(gps.location.lng(), 6);
        }
        else
        {
          Serial.print(F("INVALID"));
        }

        Serial.print(F("  Date/Time: "));
        if (gps.date.isValid())
        {
          Serial.print(gps.date.month());
          Serial.print(F("/"));
          Serial.print(gps.date.day());
          Serial.print(F("/"));
          Serial.print(gps.date.year());
        }
        else
        {
          Serial.print(F("INVALID"));
        }

        Serial.print(F(" "));
        if (gps.time.isValid())
        {
          if (gps.time.hour() < 10) Serial.print(F("0"));
          Serial.print(gps.time.hour());
          Serial.print(F(":"));
          if (gps.time.minute() < 10) Serial.print(F("0"));
          Serial.print(gps.time.minute());
          Serial.print(F(":"));
          if (gps.time.second() < 10) Serial.print(F("0"));
          Serial.print(gps.time.second());
          Serial.print(F("."));
          if (gps.time.centisecond() < 10) Serial.print(F("0"));
          Serial.print(gps.time.centisecond());
        }
        else
        {
          Serial.print(F("INVALID"));
        }

        Serial.println();

      
      if (gps.location.isValid())
      {
        char latitude[10];
        char longitude[10];
        dtostrf(gps.location.lat(), 1, 6, latitude);
        dtostrf(gps.location.lng(), 1, 6, longitude);

        Serial.print(latitude);
        Serial.print(longitude);
        sendData(latitude, longitude);
      }
}


void sendData(char data[], char data2[]) {
      digitalWrite(SIM800pwr, LOW); // turn on the module
    Serial.println("SIM ON");
  delay(500);
  //gprs.sendCmd("AT+CGATT=1\r\n");
  gprs.preInit();
  gprs.init();
  Serial.println(gprs.sendCmdAndWaitForResp("AT+CMEE=1\r\n", "OK", 10));
  Serial.println(gprs.sendCmdAndWaitForResp("AT+CGATT=1\r\n", "OK", 10));

  const char *startCommand = "GET /?id=001&lat=";
  const char *middleCommand = "&lon=";
  const char *ignition = "&in1=";
  const char *battvolt = "&v=";
  const char *endCommand = " HTTP/1.1\r\nHost: pickthall.ddns.net\r\n\r\n";

  char batteryVoltage[6];
  dtostrf(voltageMeasure(), 6, 3, batteryVoltage);
char ign[1] = { checkIgnitionState() };

  http_cmd [0] = '\0';
  strcat(http_cmd, startCommand);
  strcat(http_cmd, data);
  strcat(http_cmd, middleCommand);
  strcat(http_cmd, data2);
  strcat(http_cmd, ignition);
  strcat(http_cmd, ign);
  strcat(http_cmd, battvolt);
  strcat(http_cmd, batteryVoltage);
  strcat(http_cmd, endCommand);

  Serial.println("SENDING DATA");
  Serial.println(http_cmd);
  delay(10000);

  int retries = '0';
  while (0 == gprs.join("hologram")) { //change "cmnet" to your own APN
    Serial.println("gprs join network error");
    retries ++;
    Serial.write(retries); Serial.print("\n\r");
    if (retries == '5') {
      gprs.sendCmd("AT+CGATT=0\r\n");
      delay(50);
      digitalWrite(SIM800Reset, LOW);
      delay(500);
      digitalWrite(SIM800Reset, HIGH);
      gprs.init();
      delay(10000);
      delay(1);
      retries = '0';
    }
  }

  // successful DHCP
  Serial.print("IP Address is ");
  Serial.println(gprs.getIPAddress());
  Serial.println("Init success, start to connect server...");

  if (0 == gprs.connectTCP("pickthall.ddns.net", 5055)) {
    Serial.println("connect server success");
  } else {
    Serial.println("connect error");
    sendData(data, data2);
  }

  gprs.sendTCPData(http_cmd);
 
  Serial.println("Moving on");
delay(500);
  ///  Serial.println("close");

  // gprs.sendCmd("AT+CGATT=0\r\n");
  //Serial.println(gprs.sendCmdAndWaitForResp("AT+CGATT=0\r\n", "OK", 10));

  // digitalWrite(SIM800Reset, LOW);
  //  delay(500);
  // digitalWrite(SIM800Reset, HIGH);
    Serial.println("Sim OFFF");
  delay(1000);
digitalWrite(SIM800pwr, HIGH); //Turn off the SIM 800 module for power saving. 
    goToSleep();
  delay(2000);
}


ISR(WDT_vect) {
  //DON'T FORGET THIS!  Needed for the watch dog timer.  This is called after a watch dog timer timeout - this is the interrupt function called after waking up
  ADCSRA |= (1 << ADEN); //Re-enable the ADC
}// watchdog interrupt
treblig5 years ago

Here are 2 YT videos by iforce2d : one about the SIM800, the other about the SIM808, both running with an Arduino.
Not only iforce2d explains in great details how these setups work but he also provides the Arduino sketches (links in his videos descriptions). It's no big deal to adapt them to your own Traccar server.

jaroja44 years ago

Hi. I am interested in sending information to Arduino from Traccar.
For example: Send the shutdown command from the server so that the arduino turns off the car lights.

treblig4 years ago

@jaroja4: Traccar has no facility to interact with devices on the car.

alirezasaberi7 months ago

@Ross Pickthall
Hi dear Ross Pickthall, can you explain more about making the device with Arduino? About wiring and board and code and ...
I want to make a GPS device with sim800l , ublox-6 and arduino nano, which is stable and works with traccar server ..
tanks