Class Initializer error in mbed Online Compiler

The online mbed compiler is giving me an error when I try to initialise a class. It gives the following error:

Error: “AgriNet::AgriNet(PinName, PinName)” provides no initializer for in “AgriNet.cpp”, Line: 4, Col: 2

The line of code is is at the top of a .cpp file is:
#include “AgriNet.h”
AgriNet::AgriNet(PinName tx, PinName rx):xbee(tx, rx)
{
}

I have defined the AgriNet class as follows (reduced, but I can provide the full code):

#include “mbed.h”

class AgriNet
{
public:
AgriNet(PinName tx, PinName rx);
private:
Serial xbee;
};

I have spoken to a few people and they have not been able to spot any error in the way this is declared, any help would be appreciated!

Hello @tanmayburde,

There is no Serial class defined in Mbed OS 6. Which Mbed version do you use to build your program?
If you build with Mbed OS 5 or 2 then you can try to inherit from the Serial class rather then to use composition:

class AgriNet : public Serial
{
public:
    AgriNet(PinName tx, PinName rx);
};
#include “AgriNet.h”

AgriNet::AgriNet(PinName tx, PinName rx) : Serial(tx, rx)
{
}

Best regards, Zoltan

Hi @hudakz,

I am creating the programs using mbed LPC1768 platform and the Blinky LED Hello World template, not the mbed OS version. Is there a way to check the mbed build options in the online compiler?
The Serial class and the functions in my program work if I do not try to create a class as described above.

Kind regards,

Tanmay

To check the Mbed version in the online compiler right click on the mbed library in your project and select revisions. The current revision will be highlighted in bold font.

I believe the Revision that I am working on is 172:65be278.

I can give this a try, I named the Serial object xbee, would I need to redeclare these references in the program? Would I replace xbee with Serial or AgriNet?

In that case the AgriNet becomes also a Serial (xbee ). So wherever you called an xbee method just delete xbee. (including the .). For example if you have xbee.readable() then replace it with readable().

Thank you so much for helping Zoltan, I went through the code and made the changes, but unfortunately I am receiving the same error message:

image

Try to include the “Serial.h” or the “mbed.h” header file into the “AgriNet.cpp” file.

I just tried adding both header files to the AgriNet.cpp and the error persisted. Is it possible there is something from elsewhere in the class declaration that is impacting this? I have checked through the curly braces, and I don’t think that I have missed any.

I think the problem is that you are trying to initialize static data members in the constructor.
Initialize them before defining the constructor. Move the whole block before the constructor definition and prepend Agrinet:: like:

...
#include <sstream.h>

#if def SensorNode
 const unsigned char AgriNet::msg_frame[] = { 0x7E, ...

...
AgriNet::AgriNet(PinName tx, PinName rx) : Serial(tx, rx) 
{}
...

Keep only the declaration of these data members in the AgriNet class definition in the header file.

I have tried removing all the declarations within the initializer, but the error has persisted again.

image

Did you remove also the declarations of these members from the AgriNet class difinition in the AgriNet.h header file?

Yes, I just commented them out. Should I not have done that? I figured if this error was resolved then the error would change to being related to the undeclared variables.

Could you please show us the complete AgriNet definition in the AgriNet.h header file?
Put a line with ``` in front and after the code after copying it to your new post. This will assure proper formatting and let others to copy and paste it to for example in an editor. (You can copy& paste the three back-tick characters from this post).

Okay, I have attached the full AgriNet.h file below :slight_smile:
There are #ifdefs but I don’t believe they are the issue

#include "mbed.h"
#include <string.h>
#include <ctype.h>
#include "C12832.h"
#include <string>


//PAN ID: 416772694E6574

// Configuration Section
// ---------------------------------------------------------------------------------
//#define DEBUG

#define BaseStation
//#define SensorNode

#define Display


#define max_msg = 128; //const unsigned int
// ----------------------------------------------------------------------------------


#ifdef SensorNode
#ifdef BaseStation
#undef BaseStation
#endif
#endif

#ifdef DEBUG
Serial usb(USBTX, USBRX);
#endif
#ifdef Display
C12832 lcd(p5, p7, p6, p8, p11);
#endif


class AgriNet : public Serial
{

public:
    AgriNet(PinName tx, PinName rx);
    struct agriProtocol { //Structure for storing AgriNet commands
        uint16_t UUID;
        uint32_t UTCS;
#ifdef BaseStation
        bool LBAT;
        uint8_t PWRS;
        float STMP;
        float ATMP;
        float LIGT;
        float COND;
        float MOIS;
        float HUMD;
        float PHLV;
#endif
#ifdef SensorNode
        bool PDAT;
        bool WAKE;
        bool LPMD;
        bool PALL;
        bool PING;
        bool BTRS;
        bool BRST;
#endif
        //To be added

    };

    enum agriData { //Enumeration of AgriNet Data options
        ERRR,
        UUID,
        UTCS,
#ifdef BaseStation
        LBAT,
        PWRS,
        STMP,
        ATMP,
        MOIS,
        LIGT,
        PHLV,
        COND,
        HUMD,
        GPSC,
#endif
#ifdef SensorNode
        PING,
        BTRS,
        PDAT,
        PALL,
        LPMD,
        WAKE,
        BRST,
#endif
    };

    static agriProtocol data;



    void receive(void);
#ifdef BaseStation
    void transmit(char msg[], int node);
#endif
#ifdef SensorNode
    void transmit(char msg[]);
#endif
    template <typename T>
    void add_msg(char type[], T data, bool end);
    void clear_msg(void);
    agriData resolveString(char *s);
    static unsigned char transmit_msg[];

private:

    /* enum agriData { //Enumeration of AgriNet Data options
         ERRR,
         UUID,
         UTCS,
    #ifdef BaseStation
         LBAT,
         PWRS,
         STMP,
         ATMP,
         MOIS,
         LIGT,
         PHLV,
         COND,
         HUMD,
         GPSC,
    #endif
    #ifdef SensorNode
         PING,
         BTRS,
         PDAT,
         PALL,
         LPMD,
         WAKE,
         BRST,
    #endif
     }; */


    static char *command_ptr,
           *val_ptr;


    void reset(void);
    char *translate(char *p);
    void parse(char *p);
    //agriData resolveString(char *s);
    //Serial xbee;
#ifdef SensorNode
    const unsigned char msg_frame[];
    const unsigned int chksm_1;
#endif
#ifdef BaseStation
    const unsigned char msg_frame[];
    const unsigned char node_1[];
    const unsigned char node_2[];
    const unsigned int chksm_1;
#endif
    unsigned int chksm;

    std::string packet;


};

In case this is useful too I have attached the Agrinet.cpp contents:

#include "AgriNet.h"
#include <string>
#include <sstream>
#include "mbed.h"
#include "Serial.h"

AgriNet::AgriNet(PinName tx, PinName rx):Serial(tx, rx)
{
/*   //Serial xbee(tx, rx)
#ifdef SensorNode
   const unsigned char msg_frame[] = {0x7E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00};
   const unsigned int chksm_1 = 0x20D;
#endif
#ifdef BaseStation
   const unsigned char msg_frame[] = {0x7E, 0x10, 0x00, 0x00, 0x00};
   const unsigned char node_1[] = {0x00, 0x13, 0xA2, 0x00, 0x41, 0xC0, 0x2D, 0x7C, 0x23, 0xFF};
   const unsigned char node_2[] = {0x00, 0x13, 0xA2, 0x00, 0x41, 0xC0, 0x29, 0x31, 0x84, 0x19};
   const unsigned int chksm_1 = 0x10;
#endif
   unsigned int chksm = 0x00;
*/
}

AgriNet::agriData AgriNet::resolveString(char *s)
{

   if(strcmp(s,"UUID") == 0) {
       return UUID;
   }
   if(strcmp(s,"UTCS") == 0) {
       return UTCS;
   }
#ifdef BaseStation
   if(strcmp(s,"PWRS") == 0) {
       return PWRS;
   }
   if(strcmp(s,"LBAT") == 0) {
       return LBAT;
   }
   if(strcmp(s,"STMP") == 0) {
       return STMP;
   }
   if(strcmp(s,"ATMP") == 0) {
       return ATMP;
   }
   if(strcmp(s,"MOIS") == 0) {
       return MOIS;
   }
   if(strcmp(s,"LIGT") == 0) {
       return LIGT;
   }
   if(strcmp(s,"PHLV") == 0) {
       return PHLV;
   }
   if(strcmp(s,"COND") == 0) {
       return COND;
   }
   if(strcmp(s,"HUMD") == 0) {
       return HUMD;
   }
   if(strcmp(s,"GPSC") == 0) {
       return GPSC;
   }
#endif
#ifdef SensorNode
   if(strcmp(s,"PING") == 0) {
       return PING;
   }
   if(strcmp(s,"PDAT") == 0) {
       return PDAT;
   }
   if(strcmp(s,"BTRS") == 0) {
       return BTRS;
   }
   if(strcmp(s,"PALL") == 0) {
       return PALL;
   }
   if(strcmp(s,"LPMD") == 0) {
       return LPMD;
   }
   if(strcmp(s,"WAKE") == 0) {
       return WAKE;
   }
#endif
   //to be added

   return ERRR;
}

void AgriNet::reset(void)
{
   command_ptr = NULL;
   val_ptr = NULL;

#ifdef Display
   lcd.cls();
#endif

}


char *AgriNet::translate(char *p)
{

   static char message[max_msg];
   memset(message, 0, max_msg);
   memcpy(message, (p+16), max_msg); //+
   message[max_msg-1] = '\0';
   return message;


}


void AgriNet::parse(char *p)
{
   char command[5];


#ifdef DEBUG
   usb.printf("Parsing\r\n");
#endif

   reset();

   for(int i=0; i<strlen(p); i++) {
       p[i] = toupper(p[i]); //Make all CAPS for consistency
   }

//First extraction

   command_ptr = strtok(p, " ");
#ifdef Display
   lcd.cls();
   int i = 0;
   int j = 5;
#endif
   while(command_ptr != NULL) {
#ifdef DEBUG
       int pcount = 1;
#endif
       strncpy(command, command_ptr, 4); //extract 4 digit command
       command[4] = '\0'; //append charcter
       switch (resolveString(command)) {

           case UUID:
               val_ptr = command_ptr + 4;
               data.UUID =  atol(val_ptr);
#ifdef DEBUG
               usb.printf("UUID: %u \r\n",data.UUID);
#endif

               break;

           case UTCS:
               val_ptr = command_ptr + 4;
               data.UTCS = atol(val_ptr);
#ifdef DEBUG
               usb.printf("UTCS: %u \r\n",data.UTCS);
#endif
               break;

#ifdef BaseStation
           case STMP:
               val_ptr = command_ptr + 4;
               data.STMP = atof(val_ptr);
#ifdef DEBUG
               usb.printf("SOILTEMP: %4.2f \r\n",data.STMP);
#endif
               break;

           case ATMP:
               val_ptr = command_ptr + 4;
               data.ATMP = atof(val_ptr);
#ifdef DEBUG
               usb.printf("AIRTEMP: %4.2f \r\n",data.ATMP);
#endif
               break;

           case MOIS:
               val_ptr = command_ptr + 4;
               data.MOIS = atof(val_ptr);
#ifdef DEBUG
               usb.printf("SOILMOIS: %4.2f \r\n",data.MOIS);
#endif
               break;

           case LIGT:
               val_ptr = command_ptr + 4;
               data.LIGT = atof(val_ptr);
#ifdef DEBUG
               usb.printf("LIGHT: %4.2f \r\n",data.LIGT);
#endif
               break;

           case COND:
               val_ptr = command_ptr + 4;
               data.COND = atof(val_ptr);
#ifdef DEBUG
               usb.printf("CONDUCTIVITY: %4.2f \r\n",data.COND);
#endif
               break;

           case HUMD:
               val_ptr = command_ptr + 4;
               data.HUMD = atof(val_ptr);
#ifdef DEBUG
               usb.printf("AIR HUMIDITY: %4.2f \r\n",data.HUMD);
#endif
               break;

           case PHLV:
               val_ptr = command_ptr + 4;
               data.PHLV = atof(val_ptr);
#ifdef DEBUG
               usb.printf("PH LEVEL: %4.2f \r\n",data.PHLV);
#endif
               break;

           case LBAT:
               val_ptr = command_ptr + 4;
               data.LBAT = atoi(val_ptr);
#ifdef DEBUG
               usb.printf("LOWBAT: %i \r\n",data.LBAT);
#endif
               break;

#endif
#ifdef SensorNode
           case PDAT:
               val_ptr = command_ptr + 4;
               data.PDAT = atoi(val_ptr);
               break;

           case PING:
               val_ptr = command_ptr + 4;
               data.PING = atoi(val_ptr);
               break;

           case WAKE:
               val_ptr = command_ptr + 4;
               data.WAKE = atoi(val_ptr);
               break;

           case PALL:
               val_ptr = command_ptr + 4;
               data.PALL = atoi(val_ptr);
               break;

           case BTRS:
               val_ptr = command_ptr + 4;
               data.BTRS = atoi(val_ptr);
               break;

           case LPMD:
               val_ptr = command_ptr + 4;
               data.LPMD = atoi(val_ptr);
               break;

           case BRST:
               val_ptr = command_ptr + 4;
               data.BRST = atoi(val_ptr);
               break;

#endif

           default: //ignore unknown data
               memset(command, 0, 5);
               val_ptr = NULL;
               break;
       }

#ifdef Display
       if (i >= 32) {
           i = 0;
           j +=20;
       }
       lcd.locate(j,i);
       lcd.printf("%s:  %s", command, val_ptr);
       i+=8;
#endif

#ifdef DEBUG
       usb.printf("Parsing Pass %i\r\n", pcount);
#endif
//Reset pointers and command bytes
       memset(command, 0, 5);
       val_ptr = NULL;
       command_ptr = strtok(NULL, " ");

   }


#ifdef DEBUG
   usb.printf("Success\r\n");
#endif


}

void AgriNet::receive(void) //recived data from UART
{
   static char input [max_msg]; //Set maximum message size
   static unsigned int input_pos = 0; //reset input positon coutner
#ifdef DEBUG
   char c = usb.getc();
#else
   char c = getc();
#endif
   switch(c) {
       case '\r':   // end of text
#ifdef DEBUG
           usb.printf("\r\n Recv: %s\r\n", input);
#endif
           parse(translate(input)); //Move to translate for API mode
           memset(input, 0, max_msg);
           input_pos = 0;

           break;

       case '\n':   // discard carriage return
           break;

       default:
           if (input_pos < (max_msg)) {
               input [input_pos++] = c;
#ifdef DEBUG
               usb.putc(c);
#endif
               break;
           }
   }

}


#ifdef BaseStation
void AgriNet::transmit(char msg[], int node)
{
   putc(msg_frame[0]);
   putc(0x00);
   putc(14+strlen(msg));
   for (int x=1; x<3 ; x++) {
       putc(msg_frame[x]);
   }
   switch(node) {
       case 1:
           for (int x=0; x<10 ; x++) {
               putc(node_1[x]);
               chksm+= node_1[x];
           }
           break;

       case 2:
           for (int x=0; x<10 ; x++) {
               putc(node_2[x]);
               chksm+= node_2[x];
           }
           break;

       default:

           break;
   }

   for (int x=3; x<5 ; x++) {
       putc(msg_frame[x]);
       chksm+= msg_frame[x];
   }

   printf(msg);

   for (int x=0; x<strlen(msg); x++) {
       chksm += msg[x];
   }
   chksm += chksm_1;
   chksm = 0xFF&chksm;
   chksm = 0xFF - chksm;

   putc(chksm);
   chksm = 0;
}


#endif
#ifdef SensorNode
void AgriNet::transmit(char msg[])
{
   putc(msg_frame[0]);
   putc(0x00);
   putc(14+strlen(msg));
   for (int x=1; x<15 ; x++) {
       putc(msg_frame[x]);
   }

   printf(msg);
   // Calculate checksum for message data
   for (int x=0; x<strlen(msg); x++) {
       chksm += msg[x];
   }
   chksm += chksm_1;
   chksm = 0xFF&chksm;
   chksm = 0xFF - chksm;
   putc(chksm);
   chksm = 0;


}


#endif

template <typename T>
void AgriNet::add_msg(char type[], T data, bool end = false)
{
   std::string tempstr;
   tempstr += transmit_msg ;
   tempstr += type;
   std::stringstream val;
   val << data;
   tempstr += val.str() ;
   tempstr += " " ;
   if (end) {
       tempstr = tempstr + "\r\n";
   }
   std::strcpy (transmit_msg, tempstr.c_str());
}

void AgriNet::clear_msg(void)
{
   memset(transmit_msg,0, strlen(transmit_msg));
   packet.clear();
}

The program below compiles OK with both online and offline compilers:

#include "mbed.h"
#include <string.h>
#include <ctype.h>
//#include "C12832.h"
#include <string>

//PAN ID: 416772694E6574

// Configuration Section
// ---------------------------------------------------------------------------------
//#define DEBUG
#define BaseStation
//#define SensorNode
#define Display

#define max_msg = 128;  //const unsigned int

// ----------------------------------------------------------------------------------
#ifdef SensorNode
#ifdef BaseStation
#undef BaseStation
#endif
#endif
#ifdef DEBUG
Serial  usb(USBTX, USBRX);
#endif
//#ifdef Display
//C12832  lcd(p5, p7, p6, p8, p11);
//#endif
class AgriNet :
    public Serial
{
public:
    AgriNet(PinName tx, PinName rx);
    struct agriProtocol
    {                   //Structure for storing AgriNet commands
        uint16_t    UUID;
        uint32_t    UTCS;
#ifdef BaseStation
        bool        LBAT;
        uint8_t     PWRS;
        float       STMP;
        float       ATMP;
        float       LIGT;
        float       COND;
        float       MOIS;
        float       HUMD;
        float       PHLV;
#endif
#ifdef SensorNode
        bool        PDAT;
        bool        WAKE;
        bool        LPMD;
        bool        PALL;
        bool        PING;
        bool        BTRS;
        bool        BRST;
#endif
        //To be added
    };

    enum agriData
    {                   //Enumeration of AgriNet Data options
        ERRR,
        UUID,
        UTCS,
#ifdef BaseStation
        LBAT,
        PWRS,
        STMP,
        ATMP,
        MOIS,
        LIGT,
        PHLV,
        COND,
        HUMD,
        GPSC,
#endif
#ifdef SensorNode
        PING,
        BTRS,
        PDAT,
        PALL,
        LPMD,
        WAKE,
        BRST,
#endif
    };

    static agriProtocol data;

    void receive(void);
#ifdef BaseStation
    void transmit(char msg[], int node);
#endif
#ifdef SensorNode
    void transmit(char msg[]);
#endif
    template<typename T>
    void add_msg(char type[], T data, bool end);
    void clear_msg(void);
    agriData resolveString(char* s);
    static unsigned char transmit_msg[];
private:
    /* enum agriData { //Enumeration of AgriNet Data options
         ERRR,
         UUID,
         UTCS,
    #ifdef BaseStation
         LBAT,
         PWRS,
         STMP,
         ATMP,
         MOIS,
         LIGT,
         PHLV,
         COND,
         HUMD,
         GPSC,
    #endif
    #ifdef SensorNode
         PING,
         BTRS,
         PDAT,
         PALL,
         LPMD,
         WAKE,
         BRST,
    #endif
     }; */
    static char*        command_ptr, *val_ptr;

    void                reset(void);
    char*               translate(char* p);
    void                parse(char* p);

    //agriData resolveString(char *s);
    //Serial xbee;
#ifdef SensorNode
    const unsigned char msg_frame[];
    const unsigned int  chksm_1;
#endif
//#ifdef BaseStation
//    const unsigned char msg_frame[];
//    const unsigned char node_1[];
//    const unsigned char node_2[];
//    const unsigned int  chksm_1;
//#endif
    unsigned int        chksm;

    std::string         packet;
};

AgriNet::AgriNet(PinName tx, PinName rx) : Serial(tx, rx)
{}

DigitalOut led1(LED1);
AgriNet    agriNet(USBTX, USBRX);

int main()
{
    while (true) {
        led1 = !led1;
        wait_ms(500);
    }
}

Create a new test program in online compiler (using the same template as for your original program), copy&paste the code above and compile.

1 Like

This compiles! What is the change in this class declaration?

I have commented out some lines. You can identify them based on having // at the begin of line.

1 Like