Errors when creating library

Hi.
I've just started trying to make my code into a library instead, as that would be easier.
The only problem is, that the code uses the NewSoftSerial library, and I don't know if it's possible for a library to include and use another library!
But anyways, I'm getting alot of errors when i start Arduino (it compiles the new library)

So here is my GPU.h file:

/*
  GPU.h - Library for Serial GPU.
  Created by Thomas Jespersen, May 8, 2009.
  Released into the public domain.
*/
#ifndef GPU_h
#define GPU_h

#include "WConstants.h"

class GPU
{
  public:
    GPU(int ser1, int ser2, int ledPin);
    void Transmit(byte msg);
    void ClearTV();
    void ChangeType(char type);
    void WriteChar(char x, char y, char chr);
    void WriteText(char x, char y, char str[])
    void Pixel(char x, char y)
  private:
    int _ledPin;
};

#endif

And here is my GPU.cpp file:

/*
  GPU.h - Library for Serial GPU.
  Created by Thomas Jespersen, May 8, 2009.
  Released into the public domain.
*/

#include "WProgram.h"
#include "GPU.h"
#include <NewSoftSerial.h>

GPU::GPU(int ser1, int ser2, int ledPin)
{
  NewSoftSerial GPU(ser1,ser2);
  GPU.begin(9600);
  pinMode(ledPin, OUTPUT);
  _ledPin = ledPin;
}

void GPU::Transmit(byte msg)
{
  byte cnt = 0;
  GPU.print(msg, BYTE);
  
  while (true) {
    if (GPU.available() > 0) {
      incoming = GPU.read();
    
      if (incoming == msg) {

        break;
      }
    }
    cnt++;
    if (cnt >= 10) {
      GPU.print(msg, BYTE);
      cnt = 0;
    }
    delay(1);  //Delay to wait for response
  } 
}

void GPU::ClearTV()
{
  //Send "Clear Screen" command
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(255);
  digitalWrite(_ledPin, LOW);   // sets the LED on
  
  while (true) {
    if (GPU.available() > 0) {
      incoming = GPU.read();
      
      if (incoming == 11) {
        break;
      }
    }
  }
}

void GPU::ChangeType(char type) 
{
  //Send "Clear Screen" command
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(254);
  digitalWrite(_ledPin, LOW);   // sets the LED on
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(type);
  digitalWrite(_ledPin, LOW);   // sets the LED on
  
  while (true) {
    if (GPU.available() > 0) {
      incoming = GPU.read();
      
      if (incoming == 11) {
        break;
      }
    }
  }
}

void GPU::WriteChar(char x, char y, char chr)
{  
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(x); // X
  digitalWrite(_ledPin, LOW);   // sets the LED on  
  digitalWrite(_ledPin, HIGH);   // sets the LED on  
  Transmit(y); // Y
  digitalWrite(_ledPin, LOW);   // sets the LED on  
  digitalWrite(_ledPin, HIGH);   // sets the LED on  
  Transmit(chr);
  digitalWrite(_ledPin, LOW);   // sets the LED on  
  digitalWrite(_ledPin, HIGH);   // sets the LED on  
  Transmit(13);
  digitalWrite(_ledPin, LOW);   // sets the LED on  

  while (true) {
    if (GPU.available() > 0) {
      incoming = GPU.read();
      
      if (incoming == 11) {
        break;
      }
    }
  }
}

void GPU::WriteText(char x, char y, char str[])
{
  int i;  
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(x); // X
  digitalWrite(_ledPin, LOW);   // sets the LED on  
  digitalWrite(_ledPin, HIGH);   // sets the LED on  
  Transmit(y); // Y
  digitalWrite(_ledPin, LOW);   // sets the LED on  
  
  for (i = 0; i <= strlen(str); i++) {
    digitalWrite(_ledPin, HIGH);   // sets the LED on  
    Transmit(str[i]);
    digitalWrite(_ledPin, LOW);   // sets the LED on  
  }

  digitalWrite(_ledPin, HIGH);   // sets the LED on  
  Transmit(13);
  digitalWrite(_ledPin, LOW);   // sets the LED on  

  while (true) {
    if (GPU.available() > 0) {
      incoming = GPU.read();
      
      if (incoming == 11) {
        break;
      }
    }
  }
}

void GPU::Pixel(char x, char y)
{
  int i;
  
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(x); // X
  digitalWrite(_ledPin, LOW);   // sets the LED on  
  digitalWrite(_ledPin, HIGH);   // sets the LED on  
  Transmit(y); // Y
  digitalWrite(_ledPin, LOW);   // sets the LED on  
  digitalWrite(_ledPin, HIGH);   // sets the LED on  
  Transmit(13);
  digitalWrite(_ledPin, LOW);   // sets the LED on  

  while (true) {
    if (GPU.available() > 0) {
      incoming = GPU.read();
      
      if (incoming == 11) {
        break;
      }
    }
  }
}

Try: #include "WProgram.h"

See this: Arduino Playground - Library Tutorial :slight_smile:

[edit]And if I may be so bold, this: Arduino Playground - Library Tutorial

About the include WProgram.h, should that be included in both the header and cpp file?
Also, does it matter if it's <WProgram.h> or "WProgram.h"?
But I've followed this tutorial: http://www.arduino.cc/en/Hacking/LibraryTutorial and it didn't say anything about that the WProgram.h was needed in the header!

Edit:
But I still get errors...

This is the errors I get:

In file included from GPU.cpp:8:
/GPU.h:21: error: expected ';' before 'void'
GPU.cpp: In constructor 'GPU::GPU(int, int, int)':
GPU.cpp:16: error: '_ledPin' was not declared in this scope
GPU.cpp: In member function 'void GPU::Transmit(byte)':
GPU.cpp:22: error: expected unqualified-id before '.' token
GPU.cpp:25: error: expected primary-expression before '.' token
GPU.cpp:26: error: 'incoming' was not declared in this scope
GPU.cpp:26: error: expected primary-expression before '.' token
GPU.cpp:35: error: expected unqualified-id before '.' token
GPU.cpp: In member function 'void GPU::ClearTV()':
GPU.cpp:45: error: '_ledPin' was not declared in this scope
GPU.cpp:50: error: expected primary-expression before '.' token
GPU.cpp:51: error: 'incoming' was not declared in this scope
GPU.cpp:51: error: expected primary-expression before '.' token
GPU.cpp: In member function 'void GPU::ChangeType(char)':
GPU.cpp:63: error: '_ledPin' was not declared in this scope
GPU.cpp:71: error: expected primary-expression before '.' token
GPU.cpp:72: error: 'incoming' was not declared in this scope
GPU.cpp:72: error: expected primary-expression before '.' token
GPU.cpp: In member function 'void GPU::WriteChar(char, char, char)':
GPU.cpp:83: error: '_ledPin' was not declared in this scope
GPU.cpp:97: error: expected primary-expression before '.' token
GPU.cpp:98: error: 'incoming' was not declared in this scope
GPU.cpp:98: error: expected primary-expression before '.' token
GPU.cpp: At global scope:
GPU.cpp:107: error: no 'void GPU::WriteText(char, char, char*)' member function declared in class 'GPU'
GPU.cpp:138: error: no 'void GPU::Pixel(char, char)' member function declared in class 'GPU'

void WriteText(char x, char y, char str[])
void Pixel(char x, char y)

Does 2 lines in the h file need to end with a semicolon**;**

:wink:

Woops, missed that :stuck_out_tongue:
But I still get errors!

GPU.cpp: In member function 'void GPU::Transmit(byte)':
GPU.cpp:22: error: expected unqualified-id before '.' token
GPU.cpp:25: error: expected primary-expression before '.' token
GPU.cpp:26: error: 'incoming' was not declared in this scope
GPU.cpp:26: error: expected primary-expression before '.' token
GPU.cpp:35: error: expected unqualified-id before '.' token
GPU.cpp: In member function 'void GPU::ClearTV()':
GPU.cpp:50: error: expected primary-expression before '.' token
GPU.cpp:51: error: 'incoming' was not declared in this scope
GPU.cpp:51: error: expected primary-expression before '.' token
GPU.cpp: In member function 'void GPU::ChangeType(char)':
GPU.cpp:71: error: expected primary-expression before '.' token
GPU.cpp:72: error: 'incoming' was not declared in this scope
GPU.cpp:72: error: expected primary-expression before '.' token
GPU.cpp: In member function 'void GPU::WriteChar(char, char, char)':
GPU.cpp:97: error: expected primary-expression before '.' token
GPU.cpp:98: error: 'incoming' was not declared in this scope
GPU.cpp:98: error: expected primary-expression before '.' token
GPU.cpp: In member function 'void GPU::WriteText(char, char, char*)':
GPU.cpp:117: warning: comparison between signed and unsigned integer expressions
GPU.cpp:128: error: expected primary-expression before '.' token
GPU.cpp:129: error: 'incoming' was not declared in this scope
GPU.cpp:129: error: expected primary-expression before '.' token
GPU.cpp: In member function 'void GPU::Pixel(char, char)':
GPU.cpp:153: error: expected primary-expression before '.' token
GPU.cpp:154: error: 'incoming' was not declared in this scope
GPU.cpp:154: error: expected primary-expression before '.' token
GPU.cpp:140: warning: unused variable 'i'

NewSoftSerial GPU(ser1,ser2);

Will cause a naming conflict. You should either have a private variable that are a NSS or you should inherit from it.

Either of the solutions will resolve your errors.

Private variable that are a NSS or you should inherit from it

Huh??

Sorry. Just me being lazy :frowning:

NSS = NesSoftSerial

I mean something like this:

private:
  NewSoftSerial serial;

Inside your class.

[edit]Include what needs to be included in the .h file.

There are some times this is not true, but for most classes, the .h is where you #include.

Use <> on system files, and "" on project dependant files.
Such as:

#include <WProgram.h>
#include "config.h"

[/edit]

So you are saying that my .h file should be:

/*
  GPU.h - Library for Serial GPU.
  Created by Thomas Jespersen, May 8, 2009.
  Released into the public domain.
*/
#ifndef GPU_h
#define GPU_h

#include <WConstants.h>
#include <WProgram.h>
#include "NewSoftSerial.h"

class GPU
{
  public:
    GPU(int ser1, int ser2, int ledPin);
    void Transmit(byte msg);
    void ClearTV();
    void ChangeType(char type);
    void WriteChar(char x, char y, char chr);
    void WriteText(char x, char y, char str[]);
    void Pixel(char x, char y);
  private:
    int _ledPin;
    NewSoftSerial serial(2,3); 
};

#endif

But that still doesn't fix the problem, as it gives me the:
error: '((GPU*)this)->GPU::serial' does not have class type

Actually, maybe something like this:

/*
  GPU.h - Library for Serial GPU.
  Created by Thomas Jespersen, May 8, 2009.
  Released into the public domain.
*/
#ifndef GPU_h
#define GPU_h

#include <WProgram.h>
#include "../NewSoftSerial/NewSoftSerial.h"

class GPU
{
  public:
    GPU(int ser1, int ser2, int ledPin);
    void Transmit(byte msg);
    void ClearTV();
    void ChangeType(char type);
    void WriteChar(char x, char y, char chr);
    void WriteText(char x, char y, char str[]);
    void Pixel(char x, char y);
  private:
    int _ledPin;
    NewSoftSerial _serial;
      
};

#endif
/*
  GPU.h - Library for Serial GPU.
  Created by Thomas Jespersen, May 8, 2009.
  Released into the public domain.
*/

#include "GPU.h"

GPU::GPU(int ser1, int ser2, int ledPin) : _serial(ser1,ser2)
{
  _serial.begin(9600);
  _ledPin = ledPin;
  pinMode(_ledPin, OUTPUT);
}

void GPU::Transmit(byte msg)
{
  byte incoming = 0;
  byte cnt = 0;
  _serial.print(msg, BYTE);

  while (true) {
    if (_serial.available() > 0) {
      incoming = _serial.read();

        if (incoming == msg) {

          break;
        }
    }
    cnt++;
    if (cnt >= 10) {
        _serial.print(msg, BYTE);
        cnt = 0;
    }
    delay(1);  //Delay to wait for response
  }
}

void GPU::ClearTV()
{
  //Send "Clear Screen" command
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(255);
  digitalWrite(_ledPin, LOW);   // sets the LED on

  while (_serial.read() != 11) {/*do nothing*/}
}

void GPU::ChangeType(char type)
{
  //Send "Clear Screen" command
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(254);
  digitalWrite(_ledPin, LOW);   // sets the LED on
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(type);
  digitalWrite(_ledPin, LOW);   // sets the LED on

  while (_serial.read() != 11) {/*do nothing*/}
}

void GPU::WriteChar(char x, char y, char chr)
{
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(x); // X
  digitalWrite(_ledPin, LOW);   // sets the LED on
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(y); // Y
  digitalWrite(_ledPin, LOW);   // sets the LED on
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(chr);
  digitalWrite(_ledPin, LOW);   // sets the LED on
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(13);
  digitalWrite(_ledPin, LOW);   // sets the LED on

  while (_serial.read() != 11) {/*do nothing*/}
}

void GPU::WriteText(char x, char y, char str[])
{
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(x); // X
  digitalWrite(_ledPin, LOW);   // sets the LED on
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(y); // Y
  digitalWrite(_ledPin, LOW);   // sets the LED on

  for (unsigned int i = 0; i <= strlen(str); i++) {
    digitalWrite(_ledPin, HIGH);   // sets the LED on
    Transmit(str[i]);
    digitalWrite(_ledPin, LOW);   // sets the LED on
  }

  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(13);
  digitalWrite(_ledPin, LOW);   // sets the LED on

  while (_serial.read() != 11) {/*do nothing*/}
}

void GPU::Pixel(char x, char y)
{
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(x); // X
  digitalWrite(_ledPin, LOW);   // sets the LED on
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(y); // Y
  digitalWrite(_ledPin, LOW);   // sets the LED on
  digitalWrite(_ledPin, HIGH);   // sets the LED on
  Transmit(13);
  digitalWrite(_ledPin, LOW);   // sets the LED on

  while (_serial.read() != 11) {/*do nothing*/}
}

It compiles here using:

#include <NewSoftSerial.h>
#include <GPU.h>

GPU test = GPU(3,4,13);

:slight_smile:

Thanks for your help...
I can see that you've optimized my code at the serial part, waiting for the byte 11! Thanks again.

Edit:
It is working by starting it this way:
#include <GPU.h>
GPU gpu(2,3,13);

But please tell me, so I know it, why you have the _serial thing after the colon - what does the colon mean?

GPU::GPU(int ser1, int ser2, int ledPin) : _serial(ser1,ser2)

It's a common way to call an inherited constructor or initialize a data member.

It's not much different than this...

GPU::GPU(int ser1, int ser2, int ledPin)
{
  _serial(ser1,ser2);
}

There are times when the initialization must be done the way AlphaBeta did it. The compiler will complain if you must do it the AlphaBeta way. :wink:

  • Brian

Ok, but I can only get it working, with AlphaBeta's way
But then it's working fine :slight_smile:

The difference is when the construction happens (aka when the constructor gets called).

The 'AlphaBeta way' :wink: will make sure that the _serial has been initialized in memory before the GPU class is allowed to use the _serial for anything.

Oh, now I get it :stuck_out_tongue:
Thank you very much for your help, both of you :smiley: