Before logging an issue, please update to the latest release of Visual Micro from the Downloads Page.

When Logging a Support Issue in the Forum, please ensure you have also:-

  • Enabled vMicro > Compiler > Show Build Properties
  • Re-Compile your program with these settings enabled
 
Save the new Output to a Text File and....
  • Click the Reply button and attach as .txt file OR
  • Click here to Email us with the file attached, and a link to your post
Support requests without the output above may be impossible to answer, so please help us to help you
 
Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic VS2017 Arduino Plugin Problem with enumerations (Read 2134 times)
Gerhard Biebl
Newbies
*
Offline


Posts: 2
Joined: Jan 3rd, 2019
VS2017 Arduino Plugin Problem with enumerations
Jan 4th, 2019 at 5:20am
Print Post  
Other than in the Original Arduino IDE, enumerations seem to not be recognized/ handled correctly in Arduino Plugin for VS 2017, Community Edition. The same code that compiles well with Arduino IDE does produce strange errors in Arduino Plugin.
There is no difference if you use the new enum class statement or just enum.
Error Messages are:

Compiling 'NEMA17' for 'Arduino Leonardo'
 
Error compiling project sources
NEMA17.ino: 3:29: error: variable or field 'CalculateNumberOfSteps' declared void
Build failed for project 'NEMA17'
   dirPin=5
 
NEMA17.ino: 3:29: error: 'Resolutions' was not declared in this scope
 
NEMA17.ino: 4:20: error: variable or field 'SetResolution' declared void
   stepPin
 
NEMA17.ino: 4:20: error: 'Resolutions' was not declared in this scope

As i said, the same code compiles and runs well using Arduino IDE. This is very annoing because i prefer to work with VS which definitely is the best IDE of all.
  

Please Register or Login to the Forum to see File Attachments
Back to top
 
IP Logged
 
Tim@Visual Micro
Administrator
*****
Offline


Posts: 12186
Location: United Kingdom
Joined: Apr 10th, 2010
Re: VS2017 Arduino Plugin Problem with enumerations
Reply #1 - Jan 4th, 2019 at 2:59pm
Print Post  
Hi,

There is one difference with visual micro. It does not use a new system to establish where to inject c++ prototypes. Visual Micro will attempt to inject them before your user types have been created but you can override this behaviour and add them yourself.

Prototypes have the exact same signature as the methods they relate too along with a semi colon on the end. 

Adding prototypes has the benefit that you can move your code to ccp/h file more easily and also decide for yourself the right time to declare the prototype for a method.


In this example the prototypes have been added together before the code. The comments have been added for information only.

Code (C++)
Select All
// Connections to A4988
enum class Pins {
					dirPin=5,
					stepPin,
					SleepPin,
					ResetPin,
					MS3,
					MS2,
					MS1,
					EnablePin
                };

// Motor steps per rotation
enum class Constants {	STEPS_PER_REV = 200 };

enum class Resolutions	{	FullStep = 1,
							HalfStep = 2,
							QuarterStep = 4,
							EigthStep = 8,
							SixteenthStep = 16
						};

unsigned int NumberOfSteps = 0;



/* PROTOTYPES */

void CalculateNumberOfSteps(Resolutions DesiredResolution);
void SetResolution(Resolutions DesiredResolution);



/* CODE */

void CalculateNumberOfSteps(Resolutions DesiredResolution)
{
	NumberOfSteps = (unsigned int) Constants::STEPS_PER_REV * (unsigned int) DesiredResolution;
}

void SetResolution(Resolutions DesiredResolution)
{
	// Set Steprate to Resolution
	switch (DesiredResolution)
	{
		case Resolutions::FullStep:
		{
			digitalWrite((unsigned int)Pins::MS1, LOW);
			digitalWrite((unsigned int)Pins::MS2, LOW);
			digitalWrite((unsigned int)Pins::MS3, LOW);
			break;
		}
		case Resolutions::HalfStep:
		{
			digitalWrite((unsigned int)Pins::MS1, HIGH);
			digitalWrite((unsigned int)Pins::MS2, LOW);
			digitalWrite((unsigned int)Pins::MS3, LOW);
			break;
		}
		case Resolutions::QuarterStep:
		{
			digitalWrite((unsigned int)Pins::MS1, LOW);
			digitalWrite((unsigned int)Pins::MS2, HIGH);
			digitalWrite((unsigned int)Pins::MS3, LOW);
			break;
		}
		case Resolutions::EigthStep:
		{
			digitalWrite((unsigned int)Pins::MS1, HIGH);
			digitalWrite((unsigned int)Pins::MS2, HIGH);
			digitalWrite((unsigned int)Pins::MS3, LOW);
			break;
		}
		case Resolutions::SixteenthStep:
		{
			digitalWrite((unsigned int)Pins::MS1, HIGH);
			digitalWrite((unsigned int)Pins::MS2, HIGH);
			digitalWrite((unsigned int)Pins::MS3, HIGH);
			break;
		}
		default:
		{
			digitalWrite((unsigned int)Pins::MS1, LOW);
			digitalWrite((unsigned int)Pins::MS2, LOW);
			digitalWrite((unsigned int)Pins::MS3, LOW);
			break;
		}
	}

	CalculateNumberOfSteps(DesiredResolution);
}

void setup()
{

  // Setup the pins as Outputs
  pinMode((unsigned int) Pins::stepPin,OUTPUT);
  pinMode((unsigned int) Pins::dirPin,OUTPUT);
  pinMode((unsigned int) Pins::SleepPin,OUTPUT);
  pinMode((unsigned int) Pins::ResetPin,OUTPUT);
  pinMode((unsigned int) Pins::MS3,OUTPUT);
  pinMode((unsigned int) Pins::MS2,OUTPUT);
  pinMode((unsigned int) Pins::MS1,OUTPUT);
  pinMode((unsigned int) Pins::EnablePin,OUTPUT);

  // Set Status Pins
  digitalWrite((unsigned int) Pins::EnablePin, LOW);
  digitalWrite((unsigned int) Pins::ResetPin, HIGH);
  digitalWrite((unsigned int) Pins::SleepPin, HIGH);

  Serial.begin(9600);
}

void loop()
{

  // Experiment with dynamically changing Step Resolutions
  // and Accelleration / Decelleration, simulationg 3D Print Movements
  // First, do a quarter spin with lowest Resolution and high Speed movement to position
  Serial.print("CW\n");
  digitalWrite((unsigned int)Pins::dirPin, HIGH);
  SetResolution(Resolutions::FullStep);
  Serial.print("FullStep\n");
  Serial.print("NumberOfSteps: ");
  Serial.print(NumberOfSteps);
  Serial.print("\n");
  for(unsigned int x = 0; x < NumberOfSteps / 4; x++)
  {
    digitalWrite((unsigned int) Pins::stepPin, HIGH);
    delayMicroseconds(500);
    digitalWrite((unsigned int) Pins::stepPin, LOW);
    delayMicroseconds(500);
  }

  delay(1000);

  // Second, do a half spin with finest resolution and slow movement
  SetResolution(Resolutions::SixteenthStep);
  Serial.print("CW\n");
  Serial.print("MicroStep \n");
  Serial.print("NumberOfSteps: ");
  Serial.print(NumberOfSteps);
  Serial.print("\n");
  for(unsigned int x = 0; x < NumberOfSteps / 2; x++)
  {
    digitalWrite((unsigned int) Pins::stepPin, HIGH);
    delayMicroseconds(2000);
    digitalWrite((unsigned int) Pins::stepPin, LOW);
    delayMicroseconds(2000);
  }

  delay(1000);

  // Third, go back to start position on high Speed
  Serial.print("CCW\n");
  digitalWrite((unsigned int) Pins::dirPin, LOW);
  SetResolution(Resolutions::FullStep);
  Serial.print("FullStep \n");
  Serial.print("NumberOfSteps: ");
  Serial.print(NumberOfSteps);
  Serial.print("\n");
  for(unsigned int x = 0; x < NumberOfSteps * 3 / 4; x++)
  {
    digitalWrite((unsigned int) Pins::stepPin, HIGH);
    delayMicroseconds(500);
    digitalWrite((unsigned int) Pins::stepPin, LOW);
    delayMicroseconds(500);
  }

  // Fourth, repeat slow movement, this time with medium Resolution
  // Reset Motor Driver - Test
  //Serial.print("Reset \n");
  //digitalWrite((unsigned int) Pins::ResetPin, LOW);
  // shut off motor  Serial.print("MicroStep \n");
  //Serial.print("Disable \n");
  //digitalWrite((unsigned int) Pins::EnablePin, LOW);

  delay(2000);

  // switch Motor on again
  //Serial.print("Enable \n");
  //digitalWrite((unsigned int) Pins::EnablePin, HIGH);

  //delay(1000);

  //Serial.print("Un-Reset \n");
  //digitalWrite((unsigned int) Pins::ResetPin, HIGH);
}
 

  
Back to top
IP Logged
 
Gerhard Biebl
Newbies
*
Offline


Posts: 2
Joined: Jan 3rd, 2019
Re: VS2017 Arduino Plugin Problem with enumerations
Reply #2 - Jan 4th, 2019 at 3:31pm
Print Post  
Thank you for your kind reply. I will try as soon as i can.

Normally, C++ does not need function prototypes if the functions are implemented before the place where they are called (foreward-declaration), because the C++ Compiler scans the code sequentially from Top to Bottom and finds the function implementation before he sees the call.
The prototype enables the compiler to identify the function plus return type and parameters before he even sees the implementation. This is only needed if you implement the function after the place where it is called.

I don't know it this has something to do with the enum Declarations in front of the function implementation or not, but i have never seen such a behaviour before.

It is a little disturbing that this behaviour differs from original Arduino IDE/Compiler combo.

I will have a try and also look at the resulting assembler/machine code the compiler generates.
  
Back to top
 
IP Logged
 
Tim@Visual Micro
Administrator
*****
Offline


Posts: 12186
Location: United Kingdom
Joined: Apr 10th, 2010
Re: VS2017 Arduino Plugin Problem with enumerations
Reply #3 - Jan 4th, 2019 at 3:36pm
Print Post  
I agree but the arduino ide worked the same way until the last year or so. The new method used by the arduino ide to extract the prototypes is not perfect so has not been worth the time investment with so many other priorities. I believe an updated system is being created and we will move to that if it is 100% accurate.

As for how prototypes work. Yes you are correct and that is why I have added your prototypes to your code with the user defined types.

If you create a new arduino project with visual micro you should see comment in the new .ino code file that explains this issue. It's not highest priority because it is easily worked around. I think adding your user types to a .h file and #including that also works around the issue and keeps code organised at the same time.

« Last Edit: Jan 4th, 2019 at 3:43pm by Tim@Visual Micro »  
Back to top
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint