Having trouble getting #include to work in my code. (Mega 2560)

I’m trying to sort this bit of code, have googled but am struggling to see why it is not working.

I have a sketch that works fine. What I wanted to do is have the set up and part of the code in an #include file. (I'm new to this idea). Right now just working on one function.

Below I have posted the code, mostly stripped down from the original code.

I have created a Cube.h and Cube.cpp. When I call this code from my sketch I get this error.
“expected unqualified-id before '.' token”. I have done a bit of looking and appear that I have syntax error, but can’t fine it.

“expected unqualified-id before -Message found in GCC version 4.5.1 -check your syntax for missing, misplaced, or erroneous characters”

This is why my code is now reduced to just calling the function in Cube.cpp. I can't see it as a syntex error.

The error occurs at line 17 of the sketch. If I remark out line 17 the code complies.

I’ll appreciate any help in understanding what I’m doing wrong.

My Sketch

  //The 8x8x12 RGB LED Cube



#include "Cube.h"

//****setup****
void setup() {

  
}//***end setup***


void loop() { //***start loop***

  Cube.LED(1,1,1,2,2,2)  //This is Line 17, error here.

}//***end loop***

Cube.h

//Updating Code for  8x8x12 layer LED RGB cube, data update and interrupt
 

#ifndef Cube_h
#define Cube_h

#include "Arduino.h"
class Cube {
  public:
    void LED(int Y, int X, int Z, byte red, byte green, byte blue);
    byte red0[96], red1[96], red2[96], red3[96];
    byte blue0[96], blue1[96], blue2[96], blue3[96];
    byte green0[96], green1[96], green2[96], green3[96];
   
};

#endif

Cube.cpp

#include "Arduino.h"
#include "Cube.h"

void Cube::LED(int Y, int X, int Z, byte red, byte green, byte blue) { //****LED Routine


  // First, check and make sure nothing went beyond the limits, just clamp things at either 0 or 15 for location, and 0 or 15 for brightness
  if (Y < 0)     Y= 0;
  if (Y> 11)    Y = 11;
  if (X < 0)   X = 0;
  if (X > 7)    X = 7;
  if (Z < 0)    Z = 0;
  if (Z > 7)    Z = 7;
  if (red < 0)    red = 0;
  if (red > 15)    red = 15;
  if (green < 0)    green = 0;
  if (green > 15)    green = 15;
  if (blue < 0)    blue = 0;
  if (blue > 15)    blue = 15;


  //There are 768 LEDs in the cube, so when we write to level 2, column 5, row 4, that needs to be translated into a number from 0 to 767

  int whichbyte = int(((Y * 64) + (X * 8) + Z) / 8);

  
  // This next variable is the same thing as before, but here we don't divide by 8, so we get the LED number 0-767
  int wholebyte = (Y* 64) + (X* 8) + Z;


  //This is 4 bit color resolution, so each color contains 3 x 96 byte arrays.

  //*** RED ***
  bitWrite(red0[whichbyte], wholebyte - (8 * whichbyte), bitRead(red, 0));
  bitWrite(red1[whichbyte], wholebyte - (8 * whichbyte), bitRead(red, 1));
  bitWrite(red2[whichbyte], wholebyte - (8 * whichbyte), bitRead(red, 2));
  bitWrite(red3[whichbyte], wholebyte - (8 * whichbyte), bitRead(red, 3));


  //*** GREEN ***
  bitWrite(green0[whichbyte], wholebyte - (8 * whichbyte), bitRead(green, 0));
  bitWrite(green1[whichbyte], wholebyte - (8 * whichbyte), bitRead(green, 1));
  bitWrite(green2[whichbyte], wholebyte - (8 * whichbyte), bitRead(green, 2));
  bitWrite(green3[whichbyte], wholebyte - (8 * whichbyte), bitRead(green, 3));


  //*** BLUE ***
  bitWrite(blue0[whichbyte], wholebyte - (8 * whichbyte), bitRead(blue, 0));
  bitWrite(blue1[whichbyte], wholebyte - (8 * whichbyte), bitRead(blue, 1));
  bitWrite(blue2[whichbyte], wholebyte - (8 * whichbyte), bitRead(blue, 2));
  bitWrite(blue3[whichbyte], wholebyte - (8 * whichbyte), bitRead(blue, 3));



}//****LED routine end

You have not created an instance of the Cube class, so Cube in loop() is not of a known type.

PaulS:
You have not created an instance of the Cube class, so Cube in loop() is not of a known type.

Wow, fast reply. I’m not sure how to create the instance?
I thought that Cube.Led() is the instance?

I'm not sure how to create the instance?

Cube blob;

I thought that Cube.Led() is the instance?

No. Calling the LED() method requires an instance of the class:

   blob.LED(1,1,1,2,2,2);

Got it, I see.

Now it works.

Thanks, should have asked earlier.

PaulS:

Cube blob;

No. Calling the LED() method requires an instance of the class:

   blob.LED(1,1,1,2,2,2);

One more Q, will I need to create the instance each time the code is called or only the once, before Void Setup()?

Think of a header file (.h) as an ingredient list in a recipe: It tells you what comprises an object of this class. The code file for the class (.cpp) provides the way the recipe "works"...the directions for making a usable class object. However, until you actually buy the ingredients and follow the directions, you can't really do anything with the class; you don't have an object of the class that you can use (or eat?). A statement like:

Cube myCube;

actually defines a variable named myCube that you can use in your program. In OOP jargon, defining a variable of a class is called instantiating an object of the class. If you instantiate a class object outside of any function, it is "visible and usable" by any part of the code in the file from its point of definition to the end of that file.

Thanks econjack, that make it all a bit clearer. nice post.

I now have everything working as per my OP, and all is working just fine.
Next question.
Now I have two version of the came code.
Version one is a single sketch (all inclusive), when compiled I get this information
“Sketch uses 3,144 bytes (1%) of program storage space. Maximum is 253,952 bytes.
Global variables use 1,170 bytes (14%) of dynamic memory, leaving 7,022 bytes for local variables. Maximum is 8,192 bytes.”

Version two, most of the setup and updating code is now in Cube.h andCube.cpp., when I compile I get this information.
“Sketch uses 5,548 bytes (2%) of program storage space. Maximum is 253,952 bytes.
Global variables use 1,170 bytes (14%) of dynamic memory, leaving 7,022 bytes for local variables. Maximum is 8,192 bytes.”

My question is, I’m using nearly twice the space for the second sketch. Is this inherent with breaking the code up as I have, or is this poor programing?
Would you expect the code to require the extra space in version two?

My question is, I'm using nearly twice the space for the second sketch.

5548 vs 3144 is 1.76 times as much.

We can't see your final code, to see if you did everything right. Creating a class to blink a single LED is going to use more code space. Blinking two LEDs will require almost no extra code space. Blinking 20 will use almost no more code space than blinking 1. I would expect the version with the class to use more code space. Not 75% more, though.

PaulS:
5548 vs 3144 is 1.76 times as much.

Thanks for the reply. Your answer was what I expected.

My code, I know there are lots of improvement required here however it is working.

There are a few test functions for the RGB LED cube at the end of the main sketch, other than that all setup and updating occurs in Cube.cpp.

Main sketch

/*
  The 8x8x12 RGB LED Cube

***** LED Orientation = (Y axis,X axis,Z axis,RED,GREEN,BLUE) *****
                                      0 to 11,0 to 7,0 to 7, 0 to 15

  Latest  Ver 3 21/4/2016 (4096 colour)

  Include Cube.cpp and Cube.H

*/

#include "Cube.h"

unsigned long start;//for a millis timer to cycle through the animations

Cube MyCube; //Creates an Instance of Class Cube

//****setup****
void setup() {
  MyCube.SetupCube(); //Call Cube set up Cube.cpp

}//***end setup***


void loop() { //***start loop***

  // To control an LED, you simply:
  // MyCube.LED(level (Y) you want 0-11, row (X) you want 0-7, column (Z) you want 0-7, red brighness 0-15, green brighness 0-15, blue brighness 0-15);
  // EG - MyCube.LED(1,1,1,15,15,15)


 
  clean();
  cubeTest();
  // OneLED();
  //FullCube();
//  CompareColour();

}//***end loop***

ISR(TIMER1_COMPA_vect) { //***MultiPlex BAM***

  MyCube.UpdateCube();
}

//*+*+*+*+*+*+*+*+*+*+*+*+PUT ANIMATIONS DOWN HERE*+*+*+*+*+*+*+*+*+*+*+*

void clean() { //**************** Clean  *****************
  int ii, jj, kk;
  for (ii = 0; ii < 12; ii++)
    for (jj = 0; jj < 8; jj++)
      for (kk = 0; kk < 8; kk++)
        MyCube.LED(ii, jj, kk, 0, 0, 0);

}
// ******************** END Clean  ******************

//********************* Cube Test  ******************
void cubeTest() {
  int r = 15;
  int g = 15;
  int b = 15;
  for (int xx = 0; xx < 12; xx++) { //Layers
    for (int yy = 0; yy < 8; yy++)  { //Row
      for (int zz = 0; zz < 8; zz++)  {
        MyCube.LED(xx, yy, zz, r, g, b);
        delay (150);
       
      }
    }
  }
}  //**************  END CubeTest ******************

//***************** One LED *******************
void OneLED() {
  int y = 9, x = 7, z = 0;

  MyCube.LED(y, x, z, 0, 0, 15); //LED = (Y axis,X axis,Z axis,RED,GREEN,BLUE)

} // *********  END One LED ****************************

//******************* Full Cube Colour ********************
void FullCube() {
  int ii, jj, kk;
  int Red, Green, Blue;
  Red = 1;
  Green = 1;
  Blue = 1;


  for (ii = 0; ii < 12; ii++)
    for (jj = 0; jj < 8; jj++)
      for (kk = 0; kk < 8; kk++)
        MyCube.LED(ii, jj, kk, Red, Green, Blue);
}
//***************** END Full Cube Colour *******************

void CompareColour() {
  int ii, jj, kk;
  int Red, Green, Blue, Red1, Green1, Blue1;

  //**** Bottom 1/2 *****
  Red = 0;
  Green = 0;
  Blue = 15;

  //*** Top 1/2 ***
  Red1 = 0;
  Green1 = 0;
  Blue1 = 1;


  for (ii = 0; ii < 6; ii++)
    for (jj = 0; jj < 8; jj++)
      for (kk = 0; kk < 8; kk++)
        MyCube.LED(ii, jj, kk, Red, Green, Blue);
  for (ii = 6; ii < 12; ii++)
    for (jj = 0; jj < 8; jj++)
      for (kk = 0; kk < 8; kk++)
        MyCube.LED(ii, jj, kk, Red1, Green1, Blue1);
}
//***************** END Compare Colour *******************

Cube .h

//Updating Code for  8x8x12 layer LED RGB cube, data update and interrupt


#ifndef Cube_h
#define Cube_h
#include "Arduino.h"
// *** these assign layers to their digital pin numbers - all other programming should use these definitions
#define layer1 23 // bottom layer
#define layer2 25
#define layer3 27
#define layer4 29
#define layer5 31
#define layer6 33
#define layer7 35
#define layer8 37
#define layer9 39
#define layer10 41
#define layer11 43
#define layer12 45  // top layer

class Cube {
  public:
    // LED(level(Y) you want 0-7, row (X) you want 0-7, column(Z) you want 0-7, red brighness 0-15, green brighness 0-15, blue brighness 0-15);
    void LED(int CY, int CX, int CZ, byte red, byte green, byte blue);
    
    //This is how the brightness for every LED is stored,
    //Each LED only needs a 'bit' to know if it should be ON or OFF, so 48 Integers (96 Bytes) gives you 768 bits = 768 LEDs
    //Since we are modulating the LEDs, using 4 bit resolution, each colour has 4 arrays containing 64 bits each. One Integer  = 2 bytes/16 bits on the Mega
    byte red0[96], red1[96], red2[96], red3[96];
    byte blue0[96], blue1[96], blue2[96], blue3[96];
    byte green0[96], green1[96], green2[96], green3[96];
         
    void UpdateCube(); //Routine that occurs for each interrupt

    void SetupCube();
  private:
    int level = 0; //keeps track of which level we are shifting data to
    int anodeLevel = 0; //this increments through the anode levels
    int BAM_Bit, BAM_Counter = 0; // Bit Angle Modulation variables to keep track of things
   

};

#endif

Cube.cpp (from above post, exceed max characters)

#include "Arduino.h"
#include "Cube.h"
#include <SPI.h>// SPI Library used to clock data out to the shift registers

#define latch_pin 4// Defines actual BIT or PortH for latch - is Arduino MEGA2560 pin 7
#define blank_pin 3// Defines actual BIT or PortH for latch - is Arduino MEGA2560 pin 6
#define data_pin 51// used by SPI,  MOSI 
#define clock_pin 52// used by SPI,  SCK 
void Cube::SetupCube() {
  SPI.setBitOrder(MSBFIRST);//Most Significant Bit First
  SPI.setDataMode(SPI_MODE0);// Mode 0 Rising edge of data, keep clock low
  SPI.setClockDivider(SPI_CLOCK_DIV2);//Run the data in at 16MHz/2 - 8MHz
  //Serial.begin(115200);// if you need it?
  noInterrupts();// kill interrupts until everybody is set up
  //We use Timer 1 to refresh the cube
  TCCR1A = B00000000;//Register A all 0's since we're not toggling any pins
  TCCR1B = B00001011;//bit 3 set to place in CTC mode, will call an interrupt on a counter match
  //bits 0 and 1 are set to divide the clock by 64, so 16MHz/64=250kHz
  TIMSK1 = B00000010;//bit 1 set to call the interrupt on an OCR1A match
  OCR1A = 35;   //our clock runs at 250kHz, which is 1/250kHz = 4us * (OCR1A +1) = 204us
 
 //finally set up the Outputs
  pinMode (6, OUTPUT); // turn off PWM and set PortH bit 3 as output
  pinMode (7, OUTPUT); // turn off PWM and set PortD bit 4 as output
  pinMode(data_pin, OUTPUT);//MOSI DATA
  pinMode(clock_pin, OUTPUT);//SPI Clock
  pinMode(blank_pin, OUTPUT);//Output Enable  


  //*** Here layer pins are set as outputs

  pinMode(layer1, OUTPUT);
  pinMode(layer2, OUTPUT);
  pinMode(layer3, OUTPUT);
  pinMode(layer4, OUTPUT);
  pinMode(layer5, OUTPUT);
  pinMode(layer6, OUTPUT);
  pinMode(layer7, OUTPUT);
  pinMode(layer8, OUTPUT);
  pinMode(layer9, OUTPUT);
  pinMode(layer10, OUTPUT);
  pinMode(layer11, OUTPUT);
  pinMode(layer12, OUTPUT);

  SPI.begin();//start up the SPI library
  interrupts();//This lets the multiplexing start
}
//****LED ROUTINE BEGIN****
void Cube::LED(int CY, int CX, int CZ, byte red, byte green, byte blue) { //****LED Routine****

  // First, check and make sure nothing went beyond the limits
  if (CY < 0)     CY = 0;
  if (CY > 11)    CY = 11;
  if (CX < 0)   CX = 0;
  if (CX > 7)    CX = 7;
  if (CZ < 0)    CZ = 0;
  if (CZ > 7)    CZ = 7;
  if (red < 0)    red = 0;
  if (red > 15)    red = 15;
  if (green < 0)    green = 0;
  if (green > 15)    green = 15;
  if (blue < 0)    blue = 0;
  if (blue > 15)    blue = 15;

  int whichbyte = int(((CY * 64) + (CX * 8) + CZ) / 8);



  int wholebyte = (CY * 64) + (CX * 8) + CZ;
 

  //*** RED ***
  bitWrite(red0[whichbyte], wholebyte - (8 * whichbyte), bitRead(red, 0));
  bitWrite(red1[whichbyte], wholebyte - (8 * whichbyte), bitRead(red, 1));
  bitWrite(red2[whichbyte], wholebyte - (8 * whichbyte), bitRead(red, 2));
  bitWrite(red3[whichbyte], wholebyte - (8 * whichbyte), bitRead(red, 3));


  //*** GREEN then  Blue etc.

}//****LED ROUTINE END****

//***MultiPlex BAM BEGIN***
void Cube::UpdateCube() { //Routine that occurs for each interrupt

  //Bam counter is the cycle count

  if (BAM_Counter == 12)
    BAM_Bit++;
  else if (BAM_Counter == 36)
    BAM_Bit++;
  else if (BAM_Counter == 84)
    BAM_Bit++;

  BAM_Counter++;//Here is where we increment the BAM counter
  PORTH |= 1 << blank_pin; //The first thing we do is turn all of the LEDs 

  // *** This routine selects levels ***.
   switch (anodeLevel) {
    case 0://Level 1
      PORTL = B00000000;    //Turn off level 12
      PORTA = B00000010;    //Turn on level 1
      break;

    case 1: //Level 2
      PORTA = B00001000;    //Turn on level 2
      break;

    case 2: //Level 3
      PORTA = B00100000;    //Turn on level 3
      break;

    case 3: //Level 4
      PORTA = B10000000;    //Turn on level 4
      break;

    case 4: //Level 5
      PORTA = B00000000;    //Turn off level 4
      PORTC = B01000000;    //Turn on level 5
      break;

    case 5: //Level 6

      PORTC = B00010000;    //Turn on level 6
      break;

    case 6: //Level 7

      PORTC = B00000100;   //Turn on level 7
      break;

    case 7: //Level 8
      PORTC = B00000001;    //Turn on level 8
      break;

    case 8: //Level 9
      PORTC = B00000000;  //Turn off level 8
      PORTG = B00000100;  //Turn on level 9
      break;

    case 9: //Level 10
      PORTG = B00000001; //Turn on level 10

      break;

    case 10: //Level 11
      PORTG = B00000000;  //Turn off level 10
      PORTL = B01000000;  //Turn on level 11
      break;

    case 11: //Level 12
      PORTL = B00010000;  ////Turn on level 12

      break;
  }
  switch (BAM_Bit) { /
    //We shift out Green then Red then Blue / some code removed to fit.
    case 0:
      //Green
      SPI.transfer(green0[level]);
      SPI.transfer(green0[level + 1]);
      SPI.transfer(green0[level + 2]);
      SPI.transfer(green0[level + 3]);
      SPI.transfer(green0[level + 4]);
      SPI.transfer(green0[level + 5]);
      SPI.transfer(green0[level + 6]);
      SPI.transfer(green0[level + 7]);

      //Red
      SPI.transfer(red0[level]);
      SPI.transfer(red0[level + 1]);
      SPI.transfer(red0[level + 2]);
      SPI.transfer(red0[level + 3]);
      SPI.transfer(red0[level + 4]);
      SPI.transfer(red0[level + 5]);
      SPI.transfer(red0[level + 6]);
      SPI.transfer(red0[level + 7]);

      //Blue
      SPI.transfer(blue0[level]);
      SPI.transfer(blue0[level + 1]);
      SPI.transfer(blue0[level + 2]);
      SPI.transfer(blue0[level + 3]);
      SPI.transfer(blue0[level + 4]);
      SPI.transfer(blue0[level + 5]);
      SPI.transfer(blue0[level + 6]);
      SPI.transfer(blue0[level + 7]);



  }//switch_case

  PORTH |= 1 << latch_pin; //Latch pin HIGH
  PORTH &= ~(1 << latch_pin); //Latch pin LOW
  PORTH &= ~(1 << blank_pin); //Blank pin LOW to turn on the LEDs with the new data
  // Blank is the same as the OE or ENABLE pin
  
 

  if (BAM_Counter == 180) {
    BAM_Counter = 0;
    BAM_Bit = 0;
  }
  anodeLevel++;//increment the anode level

  level = level + 8; //increment the level variable 
  if (anodeLevel == 12) { //go back to 0 if max is reached
    anodeLevel = 0;
    //You hit 96 on level, this means you just sent out all 96 bytes

    level = 0;
  }
}//***MultiPlex BAM END***

No idea, anyone?
See code above, why does it require 75% more code space than the original code?

Chrisbee:
Wow, fast reply. I’m not sure how to create the instance?

5 minutes, yes not bad!

Congrats, PaulS!

I have found that this bit of code (Below) is when I get the BIG increase in storage size.

This function is called from the interrupt, if I Remark it out the code size almost halves.
Is this just how the processor works with interrupts?

From the main sketch above

ISR(TIMER1_COMPA_vect) { //MultiPlex BAM

MyCube.UpdateCube(); ---- Function Called each interrupt
}

If you don't call a function anywhere, the compiler omits the code for the function. Thus calling a function (when you previously had not) will make the code size jump. It's not just the call, it's the fact that the compiler now has to include the called code.