Go Down

Topic: Implementing a singleton class. (Read 10 times) previous topic - next topic

Lima7

I'm trying to find out how to implement a singleton class. Here's the background...... I've been playing around with reading and writing to files on an SD card. I've written a very basic 'logger' class to write error messages and other stuff to a log file. So far so good, I can include the class in another class or a sketch and I can log messages to the file without problems.

I now want to include the 'logger' object in all of the classes in my arduino application, but I want all of my classes to write to the same log file on the SD card. My research so far tells me I need to implement this as a 'singleton class' so there will only ever be one copy of my 'logger' object.

At the moment my header file looks like this.....
Code: [Select]

#ifndef Logger_h    
#define Logger_h    

extern "C" {
 #include <string.h>
}

#include <stdlib.h>      
#include "WProgram.h"    
#include "Logger.h" // this file
#include <MikeSDFat.h>
#include <Sd2Card.h>
#include <FatStructs.h>
#include <Sd2PinMap.h>
#include <SdFat.h>
#include <SdFatmainpage.h>
#include <SdFatUtil.h>
#include <SdInfo.h>


class Logger
{
 public:
   Logger();                        // Constructor
   void writeLine(char * line);     // Write a line of data to the log file
   void close();                    // Close the file
 private:
   // Member variables
   MySDFat logFile;                  // needed to allow access to the logger file.
   int state;                           // used to determin the state of the file (open, closed etc)
   int lineCount;

};

How do I convert it to a singleton?

Regards

Mike

robtillaart


As an Arduino (normally) has only one thread, does your class really need to be a singleton? It is no multitasking environment where different objects run in different threads. so ...

wrt the class,
- add the filename to the constructor That enables you to have different loggings (different sketches) on the same SDcard.
- add a flag to writeline indicating type of log; use an enum LEVEL { DEBUG, INFO, WARNING, ERROR, MAYDAY }
- add a timestamp before every string (prefered from a RTC if available)

reader - http://en.wikipedia.org/wiki/Singleton_pattern
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Lima7

Quote
an Arduino (normally) has only one thread
Does this mean an Arduino can be multithreaded? if so how? I thought arduino was single threaded only?

With respect to the original question, firstly, when a class is intrinsically linked to a single physical device it makes sense to have only a single instance of that class. Secondly, I have created multiple instances of my logger object, and although it does compile and run without error, only the first instance created actually manages to write to the file. This code snippet illustrates the problem?.
Code: [Select]
#include <Logger.h>

Logger My1stLogFile;
Logger My2ndLogFile;

void setup()
{
 Serial.begin(9600);
 Serial.println("\n\rStarting......");
 
 My1stLogFile.writeLine("Line one");
 My2ndLogFile.writeLine("Line AAA");
 My1stLogFile.writeLine("Line two");
 My2ndLogFile.writeLine("Line BBB");
 My1stLogFile.writeLine("Line three");
 My2ndLogFile.writeLine("Line CCC");
 My1stLogFile.writeLine("Line four");
 My2ndLogFile.writeLine("Line DDD");
 My1stLogFile.close();
 
}

This runs without error but the resulting log file contains the lines written by the first instance of the object, not the second i.e......
Line one
Line two
Line three
Line four

If I reverse the order of the declarations then the file gets the other set of lines instead.

Basically I have 2 questions....
1) is it possible to implement a singleton class?
2) if the answer is 'yes' how do I do it?

Cheers

PaulS

Quote
Does this mean an Arduino can be multithreaded? if so how? I thought arduino was single threaded only?

No, an Arduino can not be multi-threaded. That requires an operating system to manage which thread is running. The Arduino does not have an operating system.

Quote
Basically I have 2 questions....
1) is it possible to implement a singleton class?
2) if the answer is 'yes' how do I do it?


Typically, a singleton class has a private constructor and a public method to get the existing (static) instance. Your class has a public constructor, no static instance, and no method that returns that static instance.

Si

Don't bother.

Just do everything as static. You will save yourself some typing and make the code that uses the library easier to read.

Its Serial.begin(9600) not Serial.instance.begin()

Keep it simple - thats one of the joys of the Arduino.
--
My New Arduino Book: http://www.arduinobook.com

Go Up