Go Down

Topic: Serial.print crashes when printing int (Read 1 time) previous topic - next topic

elf

This has really got me stumped.  When I comment out the Serial.println statements that are printing an int (or in this version using the FloatToString method) the program runs to completion. If they're not commented out, the program crashes and restarts. See inline comments for the spot where crash occurs.  Compiled size is approx 7500 bytes.

Code: [Select]
// Global variables
int dirpin = 3;
int steppin = 12;
int ledPinBlue = 9;
int ledPinGreen = 10;
int leadScrewPitch = 1; //.8; // Pitch of leadscrew in millimeters
int gearRatio = 2; // Drive gear ratio
float coc = .088; // Circle of confusion
float focalLength = 52.10; // Actual focal length of lens
float fStop = 5.60; // fStop of lens
float exposureTimeout = 3500; // Time allowed to complete exposure
float extensionOffset = 40; // Combination of scale reading position and exit pupil distance.
char strFloat[16];

 
void setup()
{
 Serial.begin(9600);
 Serial.println ("Start Program");
 
 float beginPoint = 192.67;// Begin point in mm
 float endPoint = 170.58; // End point in mm
 float backlash = 500; // Amount of backlash in stepper motor steps


 float imageCount = 3; // Number of images
 float currentPoint;
 float dofStored;
 float objectDistanceStored;
 float extensionStored;
 float leadScrewPositionCurrent;
 float dof; //2*COC*Fstop*((magnification+1)/(magnification*magnification))
 float objectDistance; // Distance from entrance pupil to subject: focalLength+((focalLength*focalLength)/(extension))
 float magnification; // -(focalLength/(focalLength-objectDistance))
 float magnificationStored;
 float extension; // 1/((1/FocalLength)-(1/objectDistance))
 float extensionChange;
 float focusStepDistanceMM; // Distance of individual focus step in millimeters
 
 // Set pin assignments
 pinMode(dirpin, OUTPUT);
 pinMode(steppin, OUTPUT);
 pinMode(ledPinBlue, OUTPUT);
 pinMode(ledPinGreen, OUTPUT);

 // Print beginPoint
 Serial.print("beginPoint: ");
 Serial.println(floatToString(strFloat, beginPoint, 4, 0));

 // Set initial extension
 extension = beginPoint - extensionOffset;
 Serial.print("extensionOffset: ");
 Serial.println(floatToString(strFloat, extensionOffset, 4, 0));

 extensionStored = extension;
 Serial.print("extension: ");
 Serial.println(floatToString(strFloat, extension, 4, 0));  

 objectDistance = GetInitialObjectDistance(extension);
 objectDistanceStored = objectDistance;
 Serial.print("Initial objectDistance: ");
 Serial.println(floatToString(strFloat, objectDistanceStored, 4, 0));  

 magnification = GetMagnification(objectDistance, focalLength);
 Serial.print("magnification is ");
 Serial.println(floatToString(strFloat, magnification, 4, 0));  
 
 dof = GetDOF( magnification, coc, fStop);
 dofStored = dof;
 Serial.print("dof: ");
 Serial.println(floatToString(strFloat, magnification, 4, 0));
 int totalSteps;
 digitalWrite(dirpin, HIGH); // Set Clockwise direction.
 digitalWrite(ledPinGreen, HIGH);   // sets the LED on  
 digitalWrite(ledPinBlue, LOW);   // sets the LED off
 Serial.println("dirpin HIGH");  
 DoStep(400); // Move the camera to verify direction
 Serial.println("TODO:=====");
 Serial.println("Click first image");
 Serial.println("=======");

 // TODO:Change to while loop
 int i;
 for (i = 1; i <= imageCount; i++)
 {
   Serial.print(">>>>>>>>>  ");
//*****************************
// Uncommenting the following line will cause the program to crash and restart at the beginning
// Uncommenting any other println below this will cause the same behaviour.
// Program runs to completion when these lines are commented out, but of course I can see what values are being used.
   ////Serial.print(i);
   Serial.println("  <<<<<<<<<");
   if (beginPoint >= endPoint) // Move from higher magnification to lower
   {
     digitalWrite(dirpin, HIGH); // Set Clockwise direction.
     digitalWrite(ledPinGreen, HIGH);   // sets the LED on  
     digitalWrite(ledPinBlue, LOW);   // sets the LED off
     Serial.println("dirpin: HIGH");  
   }
   else //Move from lower magnification to higher
   {
     digitalWrite(dirpin, LOW); // Set Clockwise direction.
     digitalWrite(ledPinGreen, LOW);   // sets the LED off  
     digitalWrite(ledPinBlue, HIGH);   // sets the LED on
     Serial.println("dirpin: LOW");  
   }

   delay(200); // Pause
   Serial.print("objectDistanceStored: ");
   ////Serial.println(floatToString(strFloat, objectDistanceStored, 4, 0));
   Serial.print("dofStored: ");
   ////Serial.println(floatToString(strFloat, dofStored, 4, 0));  

   // Get new objectDistance
   if (beginPoint >= endPoint) // Move from higher magnification to lower
   {
     objectDistance = objectDistanceStored + dofStored;
   }
   else
   {
     objectDistance = objectDistanceStored - dofStored;
   }

   objectDistanceStored = objectDistance;
   Serial.print("objectDistance: ");
   ////Serial.println(floatToString(strFloat, objectDistance, 4, 0));

   // Get new magnification
   float magnification = GetMagnification(objectDistance, focalLength);
   Serial.print("magnification: ");
   ////Serial.println(floatToString(strFloat, magnification, 4, 0));

   // Get new DOF
   float dof = GetDOF(magnification, coc, fStop);
   dofStored = dof;
   Serial.print("dof is ");
   ////Serial.println(floatToString(strFloat, dof, 4, 0));  

   // Get new extension
   extensionStored = extension;
   Serial.print("extensionStored: ");
   ////Serial.println(floatToString(strFloat, extensionStored, 4, 0));
   extension = GetExtension(focalLength, objectDistanceStored - dof);
   Serial.print("extension: ");
   ////Serial.println(floatToString(strFloat, extension, 4, 0));

   // Get extension change
   if (beginPoint >= endPoint) // Move from higher magnification to lower
   {
     extensionChange = extensionStored - extension;
   }
   else
   {
     extensionChange = extensionStored + extension;
   }
   Serial.print("extensionChange: ");
   ////Serial.println(floatToString(strFloat, extensionChange, 4, 0));
 
   // Store the current scale setting
   leadScrewPositionCurrent = leadScrewPositionCurrent + extensionChange;
   Serial.print("leadScrewPositionCurrent: ");
   ////Serial.println(floatToString(strFloat, leadScrewPositionCurrent, 4, 0));
   
   int steps = (leadScrewPitch / (3200 * gearRatio)) * extensionChange;
   Serial.println("StepCalc parameters");
   Serial.print("leadScrewPitch: ");
   ////Serial.println(floatToString(strFloat, leadScrewPitch, 4, 0));
   Serial.print("gearRatio: ");
   ////Serial.println(floatToString(strFloat, gearRatio, 4, 0));

   Serial.print("steps to move: ");
   Serial.println(floatToString(strFloat, steps, 4, 0));

   DoStep(steps); // Move the camera
   totalSteps = totalSteps + steps;
   Serial.print("totalSteps");
   ////Serial.println(floatToString(strFloat, totalSteps, 4, 0));
   
   Serial.println("TODO:===============================================================");
   Serial.println("Click shutter here");
   delay(exposureTimeout); // Take the image
   Serial.println("===============================================================");
 }

 // Return to start position
 if (beginPoint >= endPoint) // Return from lower magnification to lower
 {
   digitalWrite(dirpin, LOW); // Set Clockwise direction.
   digitalWrite(ledPinGreen, LOW);   // sets the LED off  
   digitalWrite(ledPinBlue, HIGH);   // sets the LED on
   Serial.println("Return dirpin LOW");  
 }
 else //Return from higher magnification to higher
 {
   digitalWrite(dirpin, HIGH); // Set Clockwise direction.
   digitalWrite(ledPinGreen, HIGH);   // sets the LED on  
   digitalWrite(ledPinBlue, LOW);   // sets the LED off
   Serial.println("Return dirpin HIGH");  
 }

 delay(200); // Pause
 DoStep(totalSteps); // Move the camera

 Serial.println("");
 Serial.println("The End");
}

void loop()
{

}

void DoStep(int stepCount)
{
 int step;
 Serial.println("DoStep:");  
 for (step = 1; step <= stepCount; step++)
 {
   digitalWrite(steppin,HIGH); // This LOW to HIGH change is what creates the "Rising Edge" so the easydriver knows when to step.
   delayMicroseconds(2000); // Delay time (200) is close to top speed for this particular motor. Any faster (without ramping) the motor stalls.
   digitalWrite(steppin,LOW);
 }
}


This is a small section of the serial output.  It appears to be crashing and restarting just before the "Start Program" output.
Code: [Select]
>>>>>>>>>  Start Program

beginPoint: 1926700

extensionOffset: 400

extension: 1526700



Initial objectDistance: 79903

GetMagnification calc-------------------

Magnification * 1000: End GetMagnification calc----------------

magnification is 19303

GetDOF calc-------------------

End GetDOF ----------------

dof: 19303

dirpin HIGH

DoStep:

TODO:=====

Click first image

=======

>>>>>>>>>  Start Program

beginPoint: 1926700

extensionOffset: 400

mem

#1
Sep 26, 2009, 09:14 am Last Edit: Sep 26, 2009, 09:16 am by mem Reason: 1
You are probably running out of RAM. You could try making your strings shorter or putting them in progmem

Try commenting out things like:
Serial.println("TODO:===============================================================");


elf

Thanks, that appears to cure the problem.  Will using shorter variable names affect RAM usage?

mem

#3
Sep 26, 2009, 09:52 am Last Edit: Sep 26, 2009, 09:54 am by mem Reason: 1
Length of variable names make no difference at all. But you can save 150 bytes of ram if you print those strings of equals signs using a for loop:
[font=Courier New]    for(int i=0; i < 75; i++)
     Serial.print("=");[/font]

Professor Chaos

Mikal Hart's Flash library makes storing strings in flash very easy;  combine it with Streaming and you can simply write something like:
Code: [Select]
Serial << F("=====================") << endl;
and not worry about RAM.

Check out http://arduiniana.org/

ReCreate

That means that our strings can't be longer than 2KB? O_O

mem

Quote
That means that our strings can't be longer than 2KB?

no, it means that you should consider using progmem to store your strings in flash. Mikal's library provides an easy way to do this.

elf

The Flash library looks to be quite useful.  The long Serial.print strings in my current app are mostly for debugging purposes and will disappear shortly.  I'm used to programing in C# on computers with lots of ram, so still need to learn how to think small :)

Professor Chaos

Quote
I'm used to programing in C# on computers with lots of ram, so still need to learn how to think small


Heh.  I started with a Basic Stamp 2.  You want small?  Try 2k of program space and 32 - yes, 32 - bytes of RAM.  6 of which were dedicated to I/O.   Arduino seems like tons of memory to me. :D

Go Up