Checking AT Commands on Electron

Hello, I am wondering if there is a way to verify a response after sending an AT command to an Electron.
When I send the AT commands to a device like FIONA808 the response is either OK or ERROR.
Now with Electron I try the following
Serial.print(“AT\r\n”);
delay(500);
When I read the response with Serial.read(), what I get is

AT
DSsDSsDSsDSsD*nN

Where AT is actually the command sent with Serial.print(“AT\r\n”). The response DSsDSsDSsDSsD*nN doesn’t make sense.
I need to verify that any AT command I send returns a valid response before continuing.
In other words how can I sent an AT command and then verify the response. I have directly tried
Adafruit_GPS::sendCommand(const char *str) to send and Adafruit_GPS::read(void) to read but still getting strange replies.

I think if you are sending the command via Serial.print() you should not get anything back from an external device, since Serial goes to the USB port and Electron’s USB port is not natively supported as a host do connect other devices to.

On the other hand, if you are using Serial1 (or any of the other USART interfaces), then you need to check if you have set the correct baud rate and bit/parity settings.

If you want more specific info, you’d need to state what pins you are using for the communication and post your actual code.

Hello,
I suspected that the only reason for this is certainly because the outputs are not sent as you say. I use Serial.print() and it didn’t work. I then wrote a code that use Serial1. When using serial1, I cannot longer test with hyperterminal because when I launch it it says the port is being used by another program. I have not set any any pin for Communication. Maybe this is what I need. I have seen some code that defines SoftwareSerial serial(pinRX, pinTX) but SoftwareSerial is already defined in the AssertTracker library which I cm currently modifying to do what I want. Here is how the code I am using looks like. Important is that I need to get the response of a command that I send to the device before I continue.

#include "helper.h" //in this header file AssetTracker.h is included

char gImei[16];

SYSTEM_MODE(MANUAL)
SYSTEM_THREAD(ENABLED)

int SendAtCommand(char* ATcommand, char* expected_answer, int timeout);
int led1 = D7; 

AssetTracker t = AssetTracker();
Helper helper = Helper();
 
void setup()
{
  t.begin();
  t.gpsOn();

  pinMode(led1, OUTPUT);
  Serial.begin(9600);
  /*
   helper.GetIMEI(gImei);
   */
}
  
void loop()
{
  t.updateGPS();
  Serial.println(t.preNMEA());

  digitalWrite(led2, LOW);
  
  int err = SendAtCommand("AT", "OK", 1000);
  if (err == ERR_ITEM_FOUND) { //We know AT commands works
	digitalWrite(led2, HIGH);
	delay(100);
  }
 else {
	digitalWrite(led1, HIGH);
	delay(100);
  }

  //We can only continue is the SendAtCommand() is OK 
 // err = SendAtCommand("AT+CREG?", "+CREG: 0,", 1000);
}

int SendAtCommand(char* ATcommand, char* expected_answer, int timeout) 
{
	int x = 0,  err = ERR_NO_RESPONSE;
	char response[100];
	unsigned long previous;

	memset(response, '\0', 100);    // Initialize the string

	delay(100);

	while(Serial.available() > 0)
		Serial.read();   // Clean the input buffer

	Serial.println(ATcommand); // Send the AT command

	x = 0;
	previous = millis();
	// this loop waits for the response
	do {
		// if there are data in the UART input buffer, reads it and checks for the response
		if (Serial.available() != 0 && x < 100) {
			x++;
			if (strstr(response, expected_answer) != NULL)
				return ERR_ITEM_FOUND; // Found
		}
	}
	// Waits for the response with time out
	while((err == ERR_NO_RESPONSE) && ((millis() - previous) < timeout));

	return err;
}

Nope, there is no implementation of SoftwareSerial for the Particle devices.
The reference to that library is a legacy of the Arduino library the AssetTracker library is based on.

You need to clarify some bits for me.
Have you got Hyperterminal connected to the Electrons USB interface?
Have you got the Electron placed in the Particle AssetTracker shield?
Which pins have you got your FONA808 connected to?
You want to send AT commands to the FONA808 and not to the cellular modem nor to the GPS module of the AssetTracker shield?

But most importantly: Why do you need a FONA808 when you have an Electron and a Particle AssetTracker Shield anyway? :confused:

Okay.
I have even seen this article here how to send SMS with Electron Sending SMS from Particle Electron using AT Commands

Bus it can’t help me because they don’t seem to check the return code. You see code like this
sprintf(szCmd, “AT+CMGS=”+%s",145\r\n", szPhoneNumber);

Serial.print("Sending command ");
Serial.print(szCmd);
Serial.println();

On my module I have RX and TX pins which I believe are being used automatically for this communication.

If you are using your Electron in the Particle AssetTracker Shield, you can't use RX/TX for anything else, since these pins are already occupied by the shield's own GPS module.
You'd neet to use one of the other free USART interfaces of the Electron

https://docs.particle.io/reference/firmware/electron/#serial

Seen my questions above?
Please answer them too.

And about this

You are missing the important bit here. These Serial.print() statements are only for debugging purposes and don't actually send the AT command to the module.
The actual sending of the command is a bit further down in the code!

    Cellular.command(callback, szReturn, TIMEOUT, "AT+CMGF=1\r\n");
    Cellular.command(callback, szReturn, TIMEOUT, szCmd);
    Cellular.command(callback, szReturn, TIMEOUT, pMessage);
    
    sprintf(szCmd, "%c", CTRL_Z);
    
    int retVal = Cellular.command(callback, szReturn, TIMEOUT, szCmd);

and the return code retVal is checked and additinal information could be got via the szReturn parameter.

Additionally if you look in the AssetTracker library, you'll see how module responses are dealt with
e.g. https://github.com/spark/AssetTracker/blob/master/firmware/AssetTracker.cpp

boolean Adafruit_GPS::LOCUS_StartLogger(void) {
  sendCommand(PMTK_LOCUS_STARTLOG);
  recvdflag = false;
  return waitForSentence(PMTK_LOCUS_STARTSTOPACK);
}
...
boolean Adafruit_GPS::waitForSentence(const char *wait4me, uint8_t max) {
  char str[20];

  uint8_t i=0;
  while (i < max) {
    if (newNMEAreceived()) { 
      char *nmea = lastNMEA();
      strncpy(str, nmea, 20);
      str[19] = 0;
      i++;

      if (strstr(str, wait4me))
	return true;
    }
  }

  return false;
}

And for newNMEAreceived() you'll find at the root Serial1.read() used for requesting the data (since the AssetTracker uses Serial1 for the communication with the on-board module).

Thanks for the questions. Let me go through them.
First I am not using FONA808 with any of the particle devices. FONA 808 was the first device we were using for the proof of concept in developing this IOT GPS application. FONA was used with Raspberry Pi for the test.

  1. Have you got Hyperterminal connected to the Electrons USB interface? YES (mapped on my PC to COM4)
  2. Have you got the Electron placed in the Particle AssetTracker shield? YES. See image attached
  3. Which pins have you got your FONA808 connected to? I am not using FONA in this project.
  4. You want to send AT commands to the FONA808 and not to the cellular modem nor to the GPS module of the AssetTracker shield? NO. I am sending the command to the particle cellular/GPS Module.
  5. Why do you need a FONA808 when you have an Electron and a Particle AssetTracker Shield anyway? As already said FONA808 is just mentioned here because we already used it for POC and has codes that works fines on it.

Thanks!! I think the hints you have given here are really good enough to get me move forward. I have been wasting a whole lot of time thinking that Serial.println() actually sends commands to the device.

To clarify here.
On the Electron the cellular moduel is completely seperated from the GPS module of the AssetTracker Shield.
The former would be accessed via the Cellular object (which uses a USART interface not exposed to the user directly), while the latter would be accessed via the Adafruit_GPS class object which ultimately uses Serial1.

What am I doing here wrong. This is now a simple program to test AT commands but it fails:

#include "AssetTracker.h"

SYSTEM_MODE(MANUAL) 

int callback(int type, const char* buf, int len, char* param)
{
    Serial.print("Return: ");
    Serial.write((const uint8_t*)buf, len);
    Serial.println();
    return WAIT;
}

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.println("Codedsoft");
  
 char response[32] = "";
 int err = Cellular.command(callback, response, 10000, "AT\r\n");
  if (err == RESP_OK)
  {
      Serial.printlnf("Reponse: %s\n", response);
  }
  else
  {
     Serial.printlnf("AT Command fails. Response: %s, ErrNo: %d", err);
  }
}

What I get is:
Codedsoft
AT Command fails. Response: , ErrNo: 0

Response 0 -> NOT_FOUND. I have tried order AT command like AT+CGSN and get same response. When I change the timeout from 10000 to 1000, I get as error -1 -> time out.
I have tried with SYSTEM(MANUAL) , SYSTEM(SEMI_AUTOMATIC) and AUTOMATIC all to no avail.
It appears the callback function callback() is not executed. I am not seeing the output “Return: …”

Thanks in advance

When I comment out SYSTEM(MANUAL); I get some results

Since you said you tried SEMI_AUTOMATIC and AUTOMATIC already, I had dismissed that thought, but with this new info things are a bit more understandable, since you need the cellular modem to be on (which it isn't in MANUAL) in order to talk to it.

So with MANUAL try adding Cellular.on() in setup().

Just to stress the point: When you state something like

when it's not quite so, you keep us from being able to help properly.

I have tried all possible options for since yesterday and nothing really works. In the forum here I have seen a lot of messages from users about their struggle to get this running. What I have done to even succeed is just a coincident.
Once I put SYSTEM_THREAD(ENABLED) in my code all works. So I think the issue may not be commented out SYSTEM(AUTOMATIC)
It’s really hard to know what does what. Anywhere I am still struggling to get to a point where I can put down some getting started manual cause we have to work with this device

For this test, remove the Electron from the AssetTracker Shield and try without.

I’m going to flash your code to one of my devices and see for myself.

Okay, will try that.
I am actually having some difficulties which I am still to face. I have not even succeeded to get the GPS LED stop blinking which means its not getting a fix. Once it gets a fix according to the doc,the LED stops blinking. There is actually no silver bullet to get things working from the box.

Have you got clear sight of the sky or are you inside?

When I put my Electron with the AssetTracker software on it in the AssetTracker Shield plugged the battery in and put the device out side I got a fix after about 10 minutes (cold start takes longer), but after that it keeps getting a fix in less than a minute each time.

@rlingeh, the onboard antenna is passive and if you are indoors, a lock will be difficult to get. You can either put your Asset Tracker near a window to hopefully get a lock, place it where it has a clear veiw of the sky or purchase and connect and external active (ie amplified) antenna. In my experience, adding such an antenna makes locking fast and works well indoors (within reason). :smile:

Thanks alot. I have bought an external antenna and will be trying with it. I have mostly been working indoor

1 Like

I have now tried your code with only Cellular.on() and it works just fine - as exected :wink:

Thanks. Do know if it’s ideal to put Cellular.on() and Cellular.connect() in setup() or in loop() ?