[SOLVED] creating instance of class outside of setup disables serial interface

Following the guidelines laid out in the LibraryTutorial, I wrote my own library for a stepper motor.

The sketch I wrote that uses it, cannot be uploaded correctly it seems (or the Arduino Micro just halts after the bootloader phase, in any case the serial interface does not come up anymore in the list of Windows devices after uploading) when an instance of the class is created outside of the setup(), so in the global scope.

Everything compiles well for the Arduino Micro I have here, if the instance gets defined in the setup, as below:

void setup()
{
    OrielRotationStage stage0(0);
    OrielRotationStage stage1(1);
    int baud = 9600;
    Serial.begin(baud);
    while (!Serial) ; // wait for serial port to connect. Needed for Leonardo only
    Serial.setTimeout(5000);
    stage0.rotateSteps(4500);
    stage1.setSpeed(255);
    stage1.rotateSteps(4500);
}

Even the actions these 2 stepper motors are supposed to perform are actually working then. But if I define the instance in setup(), I can’t access it in the loop, which is what I need.

I’ve attached the header, cpp and sketch and was hoping that someone could explain to me why this fails.

Edit: changed pre-tag to code. Missed it :blush:

RotationStage.h (804 Bytes)

RotationStage.cpp (3.6 KB)

rotation_stage.ino (942 Bytes)

But if I define the instance in setup(), I can't access it in the loop, which is what I need.

No, it most certainly isn't. Why do you think you need to create an instance in one function and use it in another?

I'm guessing there's been a misunderstanding.

What I need is this:

#include "RotationStage.h"

OrielRotationStage stage0(0);
OrielRotationStage stage1(1);

void setup()
{
    // some magic unrelated to the 2 instances defined globally, i.e. stage0 and stage1
}
void loop()
{
     // perform operations on stage0 and stage1
}

Similar to the library tutorial.

But for some reason that doesn't work for me. The only way I can get the Arduino Micro to do anything is to define and initialize stage0 and stage1 within setup() and perform the actions there. But then I can't use it anymore in the loop() and I want to be able to use these instances inside the loop, so I know I have to define them in the global scope (i.e. outside of setup() and loop()). The problem is just that that fails for my code.

You need to post your real code that creates global instances (the only way that can work), and explain what "it doesn't work" means.

Meanwhile, how you confirmed that you have enough memory?
http://playground.arduino.cc/Code/AvailableMemory

As requested, I’ll post the contents of the file I’m trying to get to work. I’ll even show you the output from a diff command to show you that I’m not changing anything else:
left = code that doesn’t work, right = code that works

#include "RotationStage.h"					#include "RotationStage.h"

// (un)comment to debug						// (un)comment to debug
							      |	/*
OrielRotationStage stage0(0);					OrielRotationStage stage0(0);
OrielRotationStage stage1(1);					OrielRotationStage stage1(1);
							      |	*/
void setup()							void setup()
{								{
    // (un)comment the following 2 lines to debug		    // (un)comment the following 2 lines to debug
    /*OrielRotationStage stage0(0);			      |	    OrielRotationStage stage0(0);
    OrielRotationStage stage1(1);*/			      |	    OrielRotationStage stage1(1);

    int baud = 9600;						    int baud = 9600;
    Serial.begin(baud);						    Serial.begin(baud);
    while (!Serial) ; // wait for serial port to connect. Nee	    while (!Serial) ; // wait for serial port to connect. Nee
    Serial.setTimeout(5000);					    Serial.setTimeout(5000);

    // (un)comment the following 3 to debug			    // (un)comment the following 3 to debug
   /* stage0.rotateSteps(4500);				      |	    stage0.rotateSteps(4500);
    stage1.setSpeed(255);					    stage1.setSpeed(255);
    stage1.rotateSteps(4500);*/				      |	    stage1.rotateSteps(4500);
}								}

void loop()							void loop()
{								{

    Serial.print('1');						    Serial.print('1');
    stage0.rotateSteps(4500);				      |	    /*stage0.rotateSteps(4500);
    stage1.rotateSteps(9000); 				      |	    stage1.rotateSteps(9000); */
    delay(3000);						    delay(3000);
    Serial.println('2');					    Serial.println('2');
}								}

By the way, this sketch was also in the attachments to my first post.
What I mean by “it doesn’t work”: after uploading the code to the left, my actuators don’t move although they should. When I then open the serial monitor to see the strings of “12” sequences, I get the error message saying that the serial port COM7 could not be found:

<snip>
# | 100% 0.11s

avrdude: verifying ...
avrdude: 5694 bytes of flash verified
avrdude: Send: L [4c] 
avrdude: Recv: . [0d] 
avrdude: Send: E [45] 
avrdude: Recv: . [0d] 

avrdude done.  Thank you.

<opening the serial monitor from the IDE here >
processing.app.SerialNotFoundException: Seri?le poort 'COM7' niet gevonden. <snip>

When I check the list of Windows devices, the Arduino Micro is no longer listed (its serial interface appeared before the upload under COM7 and had a working program on it before the upload though).

I haven’t checked the available memory yet. The IDE tells me the program’s about 5kB, which is less than the 32 kB it’s listed to have.

By the way, this sketch was also in the attachments to my first post.

The code in your first post does NOT create global instances.

By creating the instances in setup(), you assure that the constructors are called after init() is called. When creating global instances, the are created before init() is called.

You should NOT rely on whether the constructor is called before or after init(). This means that the constructor should NOT be diddling with the hardware - no calls to pinMode() in the constructor.

You need a begin() method, called in setup(), that does the hardware diddling.

    _electroMagnet1 = 2 + pinshift, _electroMagnet2 = 3 + pinshift, _electroMagnet3 = 4 + pinshift, _electroMagnet4 = 5 + pinshift;

What is this nonsense? The comma operator should not be being abused this way.

By creating the instances in setup(), you assure that the constructors are called after init() is called. When creating global instances, the are created before init() is called.

You should NOT rely on whether the constructor is called before or after init(). This means that the constructor should NOT be diddling with the hardware - no calls to pinMode() in the constructor.

You need a begin() method, called in setup(), that does the hardware diddling.

Thank you for this note, which pushes me in the right direction and explains something I didn't know yet. I also want to thank you for taking the time to reply to this question, although the tone could've been more friendly.

I'll update the thread title as soon as I've been able to test the new solution.

although the tone could've been more friendly.

If you'll explain exactly what you didn't like, I'll try to do better.