0

Context

I first ran a sketch (on Arduino Uno) without any custom data structure and list, so I was using a bunch of arrays, methods and other primitive variables. And it worked perfectly.

My program acts like a menu which takes serial user input to perform actions. So you could have serial input "man r+(100,0,345)". Or just "man" to set this mode active, and later "r+(100,0,345)" to actualize the data in the "r" field in the "man" instance. I use a custom data structure to manage the input (class called Mode), and a linked list (class called ModeList).

Problem

I implemented some data structures (an object and a list) to manage incoming serial data, without modifying the rest of the program. But now, serial communication is not working properly: If I add Serial.print("Allo") anywhere in the sketch, it will print spaces for a while and stop, before I send any serial data. If it is in the setup() function, it prints spaces continuously with some characters from "Allo" from time to time. There's always a different problem along those lines, depending on where I put that simple print statement.

Here follows the sketch, the header files of the Mode and ModeList classes... By the way, I suspect a memory management problem.

The sketch

#include "Mode.h"
#include "ModeList.h"

const int inputSize=12;
const int nbModes=4;
int input;
int toSet[inputSize];
int i;

char manName[3]={'m','a','n'};
char cutName[3]={'c','u','t'};
char levName[3]={'l','e','v'};
char autName[3]={'a','u','t'};

Mode m=Mode(0,manName);
Mode c=Mode(1,cutName);
Mode l=Mode(2,levName);
Mode a=Mode(3,autName);
Mode* man=&m;
Mode* cut=&c;
Mode* lev=&l;
Mode* aut=&a;
ModeList modeList=ModeList();

void setup() {
  Serial.begin(115200);
  Serial.print("Allo");
  modeList.add(man);
  modeList.add(cut);
  modeList.add(lev);
  modeList.add(aut);
  }

void loop() {
  for(int j=0;j<inputSize;j++)
  {
    toSet[j]=NULL;
  }
  i=0;
  if(Serial.available()>0)
  {
    while(Serial.available())
    {
      if(i<inputSize)
      {
        input=Serial.read();
        if(input!=' ' && input!='(' && input !=')' && input!=',' && input!='\n')
        {
          toSet[i]=input;
          i++;
        }
      }
    }
  }

  if(serialMode(man)||man->getStatus())
  {
    //Set man on
    modeList.setMode(man);

    if(toSet[3]=='r')
    {
      if(toSet[4]=='+')
      {
        //Set ypr rate
        Serial.println("Set ypr rate +");
      }
      else if(toSet[4]=='-')
      {
        //Set ypr rate
        Serial.println("Set ypr rate -");
      }
      else
      {
        //Set ypr rate
        Serial.println("Set ypr rate");
      }
    }
    else if(toSet[3]=='a')
    {
      if(toSet[4]=='+')
      {
        //Set ypr angle
        Serial.println("Set ypr angle +");
      }
      else if(toSet[4]=='-')
      {
        //Set ypr angle
        Serial.println("Set ypr angle -");
      }
      else
      {
        //Set ypr angle
        Serial.println("Set ypr angle");
      }
    }
    else if(toSet[3]=='t')
    {
      if(toSet[4]=='+')
      {
        //Set thrust
        Serial.println("Set thrust +");
      }
      else if(toSet[4]=='-')
      {
        //Set thrust
        Serial.println("Set thrust -");
      }
      else
      {
        //Set thrust
        Serial.println("Set thrust");
      }
    }
  }
  if(serialMode(cut)||cut->getStatus())
  {
    //Cut engines
    modeList.setMode(cut);
    if(serialMode(cut))
      Serial.println("Cut");
  }
  if(serialMode(lev)||lev->getStatus())
  {
    //Stabilize axes
    modeList.setMode(lev);
    if(serialMode(lev))
      Serial.println("Level");
  }
  if(serialMode(aut)||aut->getStatus())
  {
    //Set aut on
    modeList.setMode(aut);
    if(serialMode(aut))
      Serial.println("Set aut on");
    if(toSet[3]=='s')
    {
      if(toSet[4]=='+')
      {
        //Set ypr angle
        Serial.println("Set ypr angle +");
      }
      else if(toSet[4]=='-')
      {
        //Set ypr angle
        Serial.println("Set ypr angle -");
      }
      else
      {
        //Set ypr angle
        Serial.println("Set ypr angle");
      }
    }
    else if(toSet[3]=='A')
    {
      if(toSet[4]=='+')
      {
        //Set altitude
        Serial.println("Set altitude +");
      }
      else if(toSet[4]=='-')
      {
        //Set altitude
        Serial.println("Set altitude -");
      }
      else
      {
        //Set altitude
        Serial.println("Set altitude");
      }
    }
  }
  delay(10);
}

bool serialMode(Mode* inputMode)
{
  char* modeName;
  modeName=inputMode->getName();
  Serial.print("ALLO");
  if(toSet[0]==*modeName&&toSet[1]==*(modeName+1)&&toSet[2]==*(modeName+2))
  {
    Serial.print("Set ");
    for(int i=0;i<3;i++)
    {
      Serial.print(*(modeName+i));
    }
    Serial.println(" on");
    return true;
  }
  else
    return false;
}

The Mode class header

#include "Arduino.h"

class Mode
{
    public:
        Mode(int id, char* name);
        int getId();
        Mode* getNext();
        void setNext(Mode m);
        void setStatus(bool status);
        bool getStatus();
        char* getName();
    private:
        char *_name;
        int _id;
        Mode* _next;
        bool _status;
};

The ModeList class header

class ModeList
{
    public:
        void add(Mode* input);
        int get(int pos);
        ModeList();
        void setMode(Mode* inputMode);
    private:
        Mode* start;
        Mode* end;
};
1

If I add Serial.print("Allo") anywhere in the sketch, it will print spaces for a while and stop, before I send any serial data.

Classic symptoms of using up all available RAM.

As a workaround I would use the F() macro.

eg.

    Serial.println(F("Set ypr rate +"));

Do that in all places where you are printing string literals. That would save you a couple of hundred bytes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.