8 years, 4 months ago.

Storing SoftSerial to array

Thank you in advance.

Kindly advice on how to store GSM.getc() to an array or string during callback() to be used in the main() function.

######

  1. include "mbed.h"
  2. include "SoftSerial.h"

Serial pc(USBTX, USBRX); tx, rx SoftSerial GSM(D10,D9);

void callback() {

pc.putc(GSM.getc());

}

int main() {

GSM.attach(&callback,SoftSerial::RxIrq); pc.printf("Hello World!\n");

while(1) {

} }

1 Answer

8 years, 4 months ago.

You probably want something like this:

#define maxStringLength 32;
volatile bool stringReady = false;
char stringBuffer[maxStringLength+1];
volatile int stringLength = 0;


void callback() {
  char letterIn = GSM.getc();   // read the letter
  if (!stringReady) {                   // if there isn't already a string waiting for the main program
    stringBuffer[stringLength++] = letterIn                                       // add the letter to the string
    if ((stringLength == maxStringLength) || (letterIn == '\n'))        // if it was a new line or we ran out of space
      stringBuffer[stringLength++] = 0;                                              // add a null (standard c string termination marker)
      stringReady = true;                                                                    // indicate that a string is ready.
    }
  }
}

main () {

  GSM.attach(&callback,SoftSerial::RxIrq); pc.printf("Hello World!\n");

  char localString[maxStringLength+1];       // a local buffer for the string.

  while(1) {
    if (stringReady) {                               // if there is a string waiting
     __disable_irq()                                 // disable interrupts (means data isn't lost if a byte arrives while copying the data)
      for (int i = 0; i<stringLength; i++)   // copy the string from the interrupts buffer to the main loops buffer (could use strcpy() instead)
        localString[i] == stringBuffer[i];
      stringLength = 0;                            // reset the interrupts counter
      stringReady = false;                       // indicate that the interrupt can start collecting the next string
     __enable_irq()                                 // re-enable interrupts
    }
    // do whatever you want with the string in localString.
  } 
}

You could do things a little bit more efficiently by switching buffers rather than copying the string but that makes the code harder to follow. The basic idea remains the same, the interrupt sores the data into an string (in c a string is just a char array that ends with a 0) and then indicates to the main loop when there is a complete string.

Hi Andy,

Thank you for the example. However, got some errors during compiling. Hope you can just touch up the program to clear the errors.

Regards,

posted by Jason Choong 28 Nov 2015
  1. include "mbed.h" Serial pc(USBTX, USBRX); Serial GSM(USBTX, USBRX); It was a; where it shouldn't have been, a couple of missing ;'s and a missing {

#define maxStringLength 32
volatile bool stringReady = false;
char stringBuffer[maxStringLength+1];
volatile int stringLength = 0;


void callback()
{
    char letterIn = GSM.getc();   // read the letter
    if (!stringReady) {           // if there isn't already a string waiting for the main program
        stringBuffer[stringLength++] = letterIn;                           // add the letter to the string
        if ((stringLength == maxStringLength) || (letterIn == '\n')) {     // if it was a new line or we ran out of space
            stringBuffer[stringLength++] = 0;                              // add a null (standard c string termination marker)
            stringReady = true;                                            // indicate that a string is ready.
        }                                                             
    }
}


main ()
{

    GSM.attach(&callback);
    pc.printf("Hello World!\n");

    char localString[maxStringLength+1];       // a local buffer for the string.

    while(1) {
        if (stringReady) {                               // if there is a string waiting
            __disable_irq();                                 // disable interrupts (means data isn't lost if a byte arrives while copying the data)
            for (int i = 0; i<stringLength; i++)   // copy the string from the interrupts buffer to the main loops buffer (could use strcpy() instead)
                localString[i] = stringBuffer[i];
            stringLength = 0;                            // reset the interrupts counter
            stringReady = false;                       // indicate that the interrupt can start collecting the next string
            __enable_irq();                                 // re-enable interrupts
        }
        // do whatever you want with the string in localString.
    }
}
posted by Andy A 30 Nov 2015