Modifying AltSoftSerial_Boards.h to run on a Pro Micro

I have successfully implemented a GPS/GSM tracker according to this See post 11 ( Thanks Dev), with the modified code at the end of the post .

With pin arrangement :- Pin 8 as RX to SIM800 TX, Pin 9 as TX (to SIM800 RX) and pin 0 as RX to GPS TX.

On a Pro Mini,but Ive got stuck on the next stage, some help would be much appreciated.

I would now like to get it working on a Pro Micro. I believe from reading other posts that I need to modify

AltSoftSerial_Boards.h as described in this post

I have tried a number of variations to account for the Micro having no pin 13, but all have been unsuccessful. I’m guessing its something to do with which timers are in use in Dev’s code.
The best I got was with GPS into Pin 4 as Rx and GSM on 8 and 9, when I was getting NMEA data in the Serial Monitor

// Arduino Leonardo & Yun (from Cristian Maglie)
//
#elif defined(ARDUINO_AVR_YUN) || defined(ARDUINO_AVR_LEONARDO) || defined(__AVR_ATmega32U4__)



  //define ALTSS_USE_TIMER1
  //define INPUT_CAPTURE_PIN   4  // receive
  //#define OUTPUT_COMPARE_A_PIN  9 // transmit
  //#define OUTPUT_COMPARE_B_PIN  10 // unusable PWM
  //#define OUTPUT_COMPARE_C_PIN  11 // unusable PWM

  #define ALTSS_USE_TIMER3
  #define INPUT_CAPTURE_PIN   13 // receive
  #define OUTPUT_COMPARE_A_PIN    5 // transmit

The Code that works using a Pro Mini

//Taken from Post No 11 https://forum.arduino.cc/index.php?topic=548903.0 Thanks to -Dev

//Using An Arduino Pro Mini, ARCELI SIM800L V2.0 5V Wireless GSM GPRS Module Quad-Band W/Antenna Cable Cap ,
//NEO-6M GPS GY-GPS6MV2 Module with EEPROM and Built-in Active Antenna
//Dev's code modified to output a text that is a clickable googlemaps link.

#include <AltSoftSerial.h>
AltSoftSerial GPRS; // 8 = RX (to SIM800 TX), 9 = TX (to SIM800 RX)

   #define gpsPort Serial  // 0 = RX (to GPS TX),

#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

bool requestReceived = false    ; // SMS track request received?
char expected[]      = "STATE"; // watch for this in the SMS text


void setup()
{
  Serial.begin( 9600 );
  Serial.print("STANDING BY");
  //Serial.print("Hello?");
  Serial.flush();
 
  gpsPort.begin( 9600 );

  GPRS.begin(9600);
  GPRS.println("AT+CMGF=1"); // text mode for SMS
  delay(1000);
  GPRS.println("AT+CNMI=2,2,0,0,0"); // forward SMS to Arduino when received
  delay(1000);
}

void loop()
{
  yield();

  // When a request was received *AND* a valid location is ready,
  //    send our current location.
  if (requestReceived and fix.valid.location) {
    requestReceived = false; // reset for next time

    Serial.println("AT+CMGF=1\r");
    GPRS.write("AT+CMGF=1\r"); //sending SMS in text mode
    delay(1000);

    Serial.println("AT+CMGS=\"+************\"\r");//input the phone number to which the text will be sent
    GPRS.write("AT+CMGS=\"+************\"\r"); // input the phone number to which the text will be sent
    delay(1000);

    //This section commented out in favour of section below so that text returns a Googlemaps link
    
    /*Serial.println( fix.latitude(), 6 );
     *
    Serial.println( fix.longitude(), 6 );
    GPRS.println( fix.latitude(), 6 );
    GPRS.println( fix.longitude(), 6 );
    GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
    delay(1000);
    */
    
    
    
    
    Serial.print ("www.google.com.ph/maps/place/");
    Serial.print( fix.latitude(), 6 );
    Serial.print(F(","));
    Serial.print( fix.longitude(), 6 );
    GPRS.print ("www.google.com.ph/maps/place/");
    GPRS.print( fix.latitude(), 6 );
    GPRS.print(F(","));
    GPRS.print( fix.longitude(), 6 );
    GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
    delay(1000);




    

    Serial.println("SMS sent successfully");
  }

} // loop

//-------------------------------------------
//  yield() gets called from delay and loop.
//     Watch for serial data from everything
//     so no characters get lost.

void yield()
{
  //  Listen for commands from the PC Serial Monitor window
//  if (Serial.available()) {
//    // if data is available on hardwareserial port ==> data is coming from PC or notebook
//    GPRS.write(Serial.read()); // write it to the GPRS shield
//  }

  // Listen to the SIM800
  if (GPRS.available()) {
    char c = GPRS.read();
    Serial.write( c );  // echo what the SIM800 is sending
    requestReceived |= watchForRequest( c );
  }

  // Listen to the GPS port
  if (gps.available( gpsPort )) {
    fix = gps.read(); // save the latest GPS fields in one struct
    Serial.print( '.' ); // show that GPS data is being received.
  }

} // yield

//----------------------------------------------------
//  This non-blocking routine watches for the "expected" string.
//  Call it constantly from so it can watch for
//     the characters to gradually arrive.  When all of them
//     have been received, it returns true.

size_t  expectedLen  = strlen( expected );
size_t  matchCount   = 0;     // how many chars have matched so far


bool watchForRequest( char c )
{
  bool found = false;

  if (c == expected[ matchCount ]) {

    // Just compare the next character
    matchCount++;
    if (matchCount == expectedLen) {
      found      = true;
      matchCount = 0;   // reset for next time
    }

  } else {

    // Backtrack
    int origIndex = matchCount;
    while (matchCount > 0) {

      // First, search for the current char
      matchCount--;
      if (c == expected[matchCount]) {

        // Then check the previously found characters
        //   for the current submatch.
        size_t diff = origIndex - matchCount;
        size_t i;
        for (i = 0; i < matchCount; i++) {
          if (expected[i] != expected[i + diff])
            break;
        }

        // If we successfully got through the previous loop,
        //   we found a previous submatch.
        if (i == matchCount) {
          matchCount++;
          break;
        }
      }
    }
  }

  return found;

} // watchForRequest

Are you aware that a Pro Micro has a spare HardwareSerial port on pins 0 and 1 (like a Leonardo).

...R

Robin2:
Are you aware that a Pro Micro has a spare HardwareSerial port on pins 0 and 1 (like a Leonardo).

...R

No, I wasnt, Robin. Unfortunately my level of experience wont let me make use of that info. I can follow code, just about, modifying what others have done but that's about it. I wouldnt know how that means I need to change the code.

The spare HardwareSerial port on a ProMicro is accesses as Serial1. For example Serial1.begin(115200); and Serial1.read(); etc

In other words it is just the same as Serial but with a '1' on the end.

...R

Robin2:
The spare HardwareSerial port on a ProMicro is accesses as Serial1. For example Serial1.begin(115200); and Serial1.read(); etc

In other words it is just the same as Serial but with a '1' on the end.

...R

Thanks R, I have now tried all sorts of combinations of this throughout the code but still no luck.

I dont understand the code well enough but from looking at AltSoftSerial_Boards.h, Neogps.h and reading posts about defining which ALTSS_USE_TIMER? to use Im convinced its something to do with that because of the use of TIMERS in other parts of the main code.

I have tried BigEyeTuna's solution here, but no joy for me.

If only -dev would chime in , I'm sure he'd have the answer.
If I cant resolve it, Ill just have to stick with using a Pro Mini, which works perfectly- I just wanted to reduce the overall size in the enclosure as much as possible.

ppuxley:
Thanks R, I have now tried all sorts of combinations of this throughout the code but still no luck.

Please post the program that represents your best attempt and tell us in detail what it actually does and what you want it to do that is different. It will make it much easier to focus on the parts you need help with rather than wasting time on things that you can do.

...R

Code as for Pro Mini and posted above in post 1

here it is again

//Taken from Post No 11 https://forum.arduino.cc/index.php?topic=548903.0 Thanks to -Dev

//Using An Arduino Pro Mini, ARCELI SIM800L V2.0 5V Wireless GSM GPRS Module Quad-Band W/Antenna Cable Cap ,
//NEO-6M GPS GY-GPS6MV2 Module with EEPROM and Built-in Active Antenna
//Dev's code modified to output a text that is a clickable googlemaps link.

#include <AltSoftSerial.h>
AltSoftSerial GPRS; // 8 = RX (to SIM800 TX), 9 = TX (to SIM800 RX)

  #define gpsPort Serial  // 0 = RX (to GPS TX),

#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

bool requestReceived = false    ; // SMS track request received?
char expected[]      = "STATE"; // watch for this in the SMS text


void setup()
{
 Serial.begin( 9600 );
 Serial.print("STANDING BY");
 //Serial.print("Hello?");
 Serial.flush();

 gpsPort.begin( 9600 );

 GPRS.begin(9600);
 GPRS.println("AT+CMGF=1"); // text mode for SMS
 delay(1000);
 GPRS.println("AT+CNMI=2,2,0,0,0"); // forward SMS to Arduino when received
 delay(1000);
}

void loop()
{
 yield();

 // When a request was received *AND* a valid location is ready,
 //    send our current location.
 if (requestReceived and fix.valid.location) {
   requestReceived = false; // reset for next time

   Serial.println("AT+CMGF=1\r");
   GPRS.write("AT+CMGF=1\r"); //sending SMS in text mode
   delay(1000);

   Serial.println("AT+CMGS=\"+************\"\r");//input the phone number to which the text will be sent
   GPRS.write("AT+CMGS=\"+************\"\r"); // input the phone number to which the text will be sent
   delay(1000);

   //This section commented out in favour of section below so that text returns a Googlemaps link
  
   /*Serial.println( fix.latitude(), 6 );
    *
   Serial.println( fix.longitude(), 6 );
   GPRS.println( fix.latitude(), 6 );
   GPRS.println( fix.longitude(), 6 );
   GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
   delay(1000);
   */
  
  
  
  
   Serial.print ("www.google.com.ph/maps/place/");
   Serial.print( fix.latitude(), 6 );
   Serial.print(F(","));
   Serial.print( fix.longitude(), 6 );
   GPRS.print ("www.google.com.ph/maps/place/");
   GPRS.print( fix.latitude(), 6 );
   GPRS.print(F(","));
   GPRS.print( fix.longitude(), 6 );
   GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
   delay(1000);




  

   Serial.println("SMS sent successfully");
 }

} // loop

//-------------------------------------------
//  yield() gets called from delay and loop.
//     Watch for serial data from everything
//     so no characters get lost.

void yield()
{
 //  Listen for commands from the PC Serial Monitor window
//  if (Serial.available()) {
//    // if data is available on hardwareserial port ==> data is coming from PC or notebook
//    GPRS.write(Serial.read()); // write it to the GPRS shield
//  }

 // Listen to the SIM800
 if (GPRS.available()) {
   char c = GPRS.read();
   Serial.write( c );  // echo what the SIM800 is sending
   requestReceived |= watchForRequest( c );
 }

 // Listen to the GPS port
 if (gps.available( gpsPort )) {
   fix = gps.read(); // save the latest GPS fields in one struct
   Serial.print( '.' ); // show that GPS data is being received.
 }

} // yield

//----------------------------------------------------
//  This non-blocking routine watches for the "expected" string.
//  Call it constantly from so it can watch for
//     the characters to gradually arrive.  When all of them
//     have been received, it returns true.

size_t  expectedLen  = strlen( expected );
size_t  matchCount   = 0;     // how many chars have matched so far


bool watchForRequest( char c )
{
 bool found = false;

 if (c == expected[ matchCount ]) {

   // Just compare the next character
   matchCount++;
   if (matchCount == expectedLen) {
     found      = true;
     matchCount = 0;   // reset for next time
   }

 } else {

   // Backtrack
   int origIndex = matchCount;
   while (matchCount > 0) {

     // First, search for the current char
     matchCount--;
     if (c == expected[matchCount]) {

       // Then check the previously found characters
       //   for the current submatch.
       size_t diff = origIndex - matchCount;
       size_t i;
       for (i = 0; i < matchCount; i++) {
         if (expected[i] != expected[i + diff])
           break;
       }

       // If we successfully got through the previous loop,
       //   we found a previous submatch.
       if (i == matchCount) {
         matchCount++;
         break;
       }
     }
   }
 }

 return found;

} // watchForRequest

The change was to AltSoftSerial.h to change the YUN?LEONARDO section, which is what I assumed got picked up if you select Pro Micro as the board. Then using Timer3 and pins 0, for GPS Tx, 8 for GPRS Tx and 9 for GPRS Rx. But I also tried those pins under Timer1

// Arduino Leonardo & Yun (from Cristian Maglie)
//
#elif defined(ARDUINO_AVR_YUN) || defined(ARDUINO_AVR_LEONARDO) || defined(__AVR_ATmega32U4__)



  //define ALTSS_USE_TIMER1
  //define INPUT_CAPTURE_PIN   4  // receive
  //#define OUTPUT_COMPARE_A_PIN  9 // transmit
  //#define OUTPUT_COMPARE_B_PIN  10 // unusable PWM
  //#define OUTPUT_COMPARE_C_PIN  11 // unusable PWM

  #define ALTSS_USE_TIMER1
  #define INPUT_CAPTURE_PIN   8 // receive
  #define OUTPUT_COMPARE_A_PIN    9// transmit

I was mistaken about it working, on one test I plugged the GPS output into pin4 when configured as GPRS tx and I saw the NMEA raw data, at least signifying the GPS was outputting something.

As I say there is no question that the hardware is working and working together as it should when running on a Pro Mini, its just I cant get the code quite right to run on the Pro Micro.

Thanks for looking

I'm not sure if you need changes to altsoftserial.

Your GPS is connected to pin 0; on a Leonardo, Micro and ProMicro. That is Serial1 as explained by Robin.

Anything that currently uses Serial for reading needs to change to Serial1. Looking at the code, changing

#define gpsPort Serial  // 0 = RX (to GPS TX),

to

#define gpsPort Serial1  // 0 = RX (to GPS TX),

will probably do the trick to get the GPS part working.

ppuxley:
Code as for Pro Mini and posted above in post 1

here it is again

When you said in Reply #4 "Thanks R, I have now tried all sorts of combinations of this throughout the code but still no luck. " I had assumed you meant that you had tried to implement my suggestion of using Serial1 on the ProMicro.

In the code in the first program in Reply #6 try making the changes as in this code

//  #include <AltSoftSerial.h>   <<----------
// AltSoftSerial GPRS; // 8 = RX (to SIM800 TX), 9 = TX (to SIM800 RX)   <<----------
#define GPRS Serial1   // <<----------

//  #define gpsPort Serial  // 0 = RX (to GPS TX),  <<----------

#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

bool requestReceived = false    ; // SMS track request received?
char expected[]      = "STATE"; // watch for this in the SMS text


void setup()
{
 Serial.begin( 9600 );
 Serial.print("STANDING BY");
 //Serial.print("Hello?");
 Serial.flush();

// gpsPort.begin( 9600 );  <<----------

 GPRS.begin(9600);
 GPRS.println("AT+CMGF=1"); // text mode for SMS
 delay(1000);
 GPRS.println("AT+CNMI=2,2,0,0,0"); // forward SMS to Arduino when received
 delay(1000);
}

I have marked the changed lines with <<----------

…R

PS … following Reply #7 I don’t think gpsPort is actually used anywhere, I think GPRS is the appropriate name

@Robin

It's used in the yield function :wink: I also had to look for its usage; at the end of the code of the opening post.

sterretje:
It's used in the yield function :wink: I also had to look for its usage; at the end of the code of the opening post.

Do you mean this line

 if (gps.available( gpsPort )) {

which I assumed is another error

...R

Thank you for your suggestions I will try them tomorrow. I am surprised AltSoftSerial.h gets commented out when -dev describes its use in the original post#11 where the original code comes from
Post #11

When you describe the gpsPort line being an error, do you mean unnecessary, because that code works fine with the Pro Mini.

The reason I thought the problem was in the Yun/Leonardo section of the AltSoftSerial_Boards.h was because in that section it points to the use of pin 13 which the Pro Micro doesnt have, so some in other posts had attempted to edit that section to point at other pins. But following those ideas didnt work for me.

I will report back, thanks

ppuxley:
When you describe the gpsPort line being an error, do you mean unnecessary, because that code works fine with the Pro Mini.

It looks like an error and / or unnecessary to me, but I am not a C++ expert.

...R