Calling function fails

Hi, I have a very strange problem calling a function. For troubleshooting-reasons I created a testfunction.

Callin the function in the setup is no problem, but in the loop it causes trouble.

This one works:

void testfunktion(String test01 = "") {
//  String test02 = "xy";
  Serial.print(test01);
}

This one dont:

void testfunktion(String test01 = "") {
  String test02 = "xy";
  Serial.print(test01);
}

I do not even have an idea where to look.

I am working with arduino Uno, Arduino 0021 and a Motor-Shield. Binary sketch size: 21336 bytes (of a 32256 byte maximum)

Greets, Kevin

What kind of trouble What's the difference between test01 & test02?

With this test-function the program hangs befor loading it.

From the loop:

  Serial.print(".");
  testfunktion(".");
  Serial.print(".");

The first dot shows, but then the program stops.

edit: Now I have a other problem. The program starts with some strange ASCII, goes on normal until the "testfunktion" and repeats this steps in an endless loop.

Wow. Flakey Power problem? Try with external supply??

There is already an external supply on the attached motor shield, but as soon as I find a second I will attach it to the arduino board.

If you separate the shields and load code into a bare arduino, does that help??

no, does not help. same problem.

Could it be, that the program, somehow, is too large?

I started chopping it a little and suddenly it worked... Binary sketch size: 16474 bytes (of a 32256 byte maximum)

I am confused about that.?!

Setting the testfunction back to the original one causes the problems again. Could there be a problem with this function? I call it often and nearly without delay. This is the original one:

/********** Print-Programm **********/
void SPrint(String sp_0="", String sp_1="",String sp_2="",String sp_3="",String sp_4="",String sp_5="",String sp_6="",String sp_7="",String sp_8="",String sp_9="",String sp_10="",String sp_11="",String sp_12="",String sp_13="",String sp_14="",String sp_15="") {

  if (sp_0 != "") {Serial.print(sp_0);};
  if (sp_1 != "") {Serial.print(sp_1);};
  if (sp_2 != "") {Serial.print(sp_2);};
  if (sp_3 != "") {Serial.print(sp_3);};
  if (sp_4 != "") {Serial.print(sp_4);};
  if (sp_5 != "") {Serial.print(sp_5);};
  if (sp_6 != "") {Serial.print(sp_6);};
  if (sp_7 != "") {Serial.print(sp_7);};
  if (sp_8 != "") {Serial.print(sp_8);};
  if (sp_9 != "") {Serial.print(sp_9);};
  if (sp_10 != "") {Serial.print(sp_10);};
  if (sp_11 != "") {Serial.print(sp_11);};
  if (sp_12 != "") {Serial.print(sp_12);};
  if (sp_13 != "") {Serial.print(sp_13);};
  if (sp_14 != "") {Serial.print(sp_14);};
  if (sp_15 != "") {Serial.print(sp_15);};
}

Any suggestions why this could be troublesome? Or any suggestions on how to do this easier?

edit: I figured out, that the setup/ loop-problem was a coincidence. The problem occurres after a several printed characters. Printing longer texts I can force the problem already in the setup function.

More than one type of memory out of sram?

I suspected RAM issues, but I neither know how to check, nor what do do against it.

The problems could be generated with huge Strings. I dont see such Strings in my originally program, but maybe understanding the problems will help me searching my real problem.

Here is the sample-code:

String ln = "\n";

/********** Print-Programm **********/
void test(String sp_0="", String sp_1="",String sp_2="") {

  Serial.print("  -  ");

  if (sp_0 != "") {Serial.print(sp_0);};
  if (sp_1 != "") {Serial.print(sp_1);};
  if (sp_2 != "") {Serial.print(sp_2);};
}

void setup() {
  delay(1000);
  Serial.begin(9600);
  Serial.print("\n\n START \n");
  
  Serial.print("_:abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg \n");
//  test("E:abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg ", ln);
}

void loop() {
  Serial.print("_:hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn \n");
 // test("e:hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn hijklmn",ln);
}

Do you all see the same problems (when deleting the //)?

To save on sram you could store your strings in flash memory see progmem or use the flash library http://arduiniana.org/libraries/flash/

I don't remember how to check how much sram a sketch is using.

also see http://www.arduino.cc/en/Tutorial/Memory the numbers has changed for the 328 but you will get the picture

Could you post the original sketch you had problems with? I am running the one you posted in reply #10 without any problems.

Reading about the SRAM - This explains a lot.
My original code is quite BETA and propably bad structured. Here it is:

// DipCoater 1.0 BETA
 

/*********************** PARAMETER ***********************/

// Anzahl der Dips
const int dips = 20;

// Dipgeschwindigkeit (Millimeter pro Minute)
const int mmpm = 400;

// Hubweg in Millimeter (MAX: 300)
const int hubweg = 50;

// Um Testlauf zu starten auf "true" setzen, für Dipcoaing auf "false"
const boolean testlauf = false;

/********************************************************/
/********************************************************/
/********************************************************/
/********************************************************/
/********************************************************/
/************** Ab hier nichts mehr ändern **************/
/********************************************************/
/********************************************************/
/********************************************************/
/********************************************************/
/********************************************************/

#include <AFMotor.h>


/************* GERÄTEKONSTANTEN *************/
// steps pro Umdrehung
const int spr = 200;
// Millimeter pro Umdrehung (Steigung der Gewindestange)
const int mmpr = 2;
// Hublänge in Millimeter (Schalter zu Schalter)
const int max_hubmm = 300;
// Sicherheitsabstand
const int secmm = 2;
// Maximalgeschwindigkeit (rpm)
const int vmax = 500;

/************** ARDUINO-ANSCHLÜSSE ***************/
// Vom MotorShield ungenutzte Digital-Pins sind Pin2 und Pin13
// Pin11 & Pin3 ist für Stepper1 reserviert
// Pin5 & Pin6 ist für Stepper2 reserviert
// Pin9 & Pin10 ist für einen Servo reserviert

// Nummer des oberen Endschalters
const int topbuttonPin = 2;    
// Nummer des unteren Endschalters
const int bottombuttonPin = 13;    
// Motorport (1 = M1+M2; 2 = M3+M4)
const int mport = 2;

/************* Berechnung *************/
// steps pro Millimeter (abgerundet)
const long spmm = long(spr / mmpr);
// Hublänge in Steps (Schalter zu Schalter)
const long max_hubstep = max_hubmm * spmm;
// Umdrehungen pro minute
int rpm = round(mmpm*spmm/spr);
// Startposition in Millimeter (von oben)
const int pos_start = (max_hubmm - hubweg - secmm);
// Startpos in Steps
const long s_start = round(pos_start * spmm);
// Sicherheits-Steps (Unschärfe)
const int secstep = secmm * spmm;
// Endpos in Steps
long s_end = max_hubstep - secstep;

// Stepper initialisieren
AF_Stepper motor(spr, mport);

// Auslesevariablen der Buttons
int topbutton, bottombutton = 0;
int button = 0;

long pos = 0;
String ln = "\n";

/********** Print-Programm **********/
void SPrint(String sp_0="", String sp_1="",String sp_2="",String sp_3="",String sp_4="",String sp_5="",String sp_6="",String sp_7="",String sp_8="",String sp_9="",String sp_10="",String sp_11="",String sp_12="",String sp_13="",String sp_14="",String sp_15="") {

  Serial.print("-");

  if (sp_0 != "") {Serial.print(sp_0);};
  if (sp_1 != "") {Serial.print(sp_1);};
  if (sp_2 != "") {Serial.print(sp_2);};
  if (sp_3 != "") {Serial.print(sp_3);};
  if (sp_4 != "") {Serial.print(sp_4);};
  if (sp_5 != "") {Serial.print(sp_5);};
  if (sp_6 != "") {Serial.print(sp_6);};
  if (sp_7 != "") {Serial.print(sp_7);};
  if (sp_8 != "") {Serial.print(sp_8);};
  if (sp_9 != "") {Serial.print(sp_9);};
  if (sp_10 != "") {Serial.print(sp_10);};
  if (sp_11 != "") {Serial.print(sp_11);};
  if (sp_12 != "") {Serial.print(sp_12);};
  if (sp_13 != "") {Serial.print(sp_13);};
  if (sp_14 != "") {Serial.print(sp_14);};
  if (sp_15 != "") {Serial.print(sp_15);};
}


void testfunktion(String test01 = "") {
  String test02;
  test02 = "xy";
  Serial.print(test01);
}


/********** Motor-Programm **********/
int move_motor (int m_rpm, String m_direct, long m_pos, long m_steps = -1) {
  // gibt die Endposition zurück
  // m_steps ist optional. Bei keiner Angabe dreht der Motor bis zum Endschalter
  
  long m_return;
  long m_cnt_steps = 0;
  boolean m_runmotor = true;
  boolean m_endschalter = false;

  motor.setSpeed(m_rpm);    
 
  while (m_runmotor == true)
  {    
    // Motor-Bewegung
    if (m_direct == "down") 
    { // RUNTER
      motor.step(1, FORWARD, DOUBLE);
      button = digitalRead(bottombuttonPin);
    } 
    else if (m_direct == "up")
    { // HOCH
      motor.step(1, BACKWARD, DOUBLE);
      button = digitalRead(topbuttonPin);
    }
    m_cnt_steps++;    
    
    // Endbedingungen
    if (button == HIGH) 
    { // Enschalter-Abfrage
      m_runmotor = false;      
      m_endschalter = true;
    } 
    else if ((m_steps > 0) && (m_cnt_steps >= m_steps))
    { // Endpositions-Abfrage, falls eine Stepzahl vorgegeben wurde
      m_runmotor = false;      
    }
  }
  
  // Endpositions-Bestimmung & Auswertung
  if (m_endschalter == true)   
  { // Endschalter gedrückt
    if (m_direct == "down") {m_return = max_hubstep;}
    else if (m_direct == "up") {m_return = 0;}     
  } 
  else 
  { // Endposition erreicht
    if (m_direct == "down") {m_return = m_pos + m_steps;}
    else if (m_direct == "up") {m_return = m_pos - m_steps;}     
  }
  return m_return;
}


/********** Setup-Programm **********/
void setup() {    
  Serial.begin(9600);           // set up Serial library at 9600 bps

  
  // INPUT für Endschalter setzen 
  pinMode(topbuttonPin, INPUT);
  pinMode(bottombuttonPin, INPUT);
  
  SPrint("Dipcoater 0.1", ln, "(c) Christian Schrautzer", ln);
  SPrint("---------------------------------------", ln, ln);

  SPrint("Dips: ", dips, ln);
  SPrint("Geschwindigkeit: ", mmpm, " mm/min", ln);
  SPrint("Hubweg: ", hubweg, " mm", ln);
  SPrint("---------------------------------------", ln);
  
  // Untere Maximalposition festsetzen
  if (s_end > (max_hubstep-secstep)) {s_end = (max_hubstep-secstep);};
  
  // Setzen der Dip-Geschwindigkeit
  if (rpm > vmax) {rpm = vmax;};
 
/* 
 // Timer-Test
 long tmr1 = millis();
 delay(1000);
 long tmr2 = millis();
 SPrint("Timertest", ln, tmr1, ln, tmr2, ln, ln);
 
 */
    
   SPrint("TEST", ln);
   testfunktion("test");
}

/********* Hauptprogramm *********/
void loop() {
  
  Serial.print(".");
  delay(10000);
   testfunktion("-.");
  Serial.print(".");
  
  
if (testlauf == false)
{ // Dip-Coating-Programm beginnt hier

 
   Serial.print("test2");
   
   SPrint("TEST", ln);
  delay(10000);
  
  
  SPrint("Achtung: Hubweg muss komplett frei sein!", ln);
  delay(5000);
  SPrint("Startposition anfahren");
  
  // Halter fährt bis zum oberen Endpunkt
  pos = move_motor(vmax, "up", pos, -1);
  pos = 0;
  
  // Halter fährt in Startposition
  pos = move_motor(vmax, "down", pos, s_start);
  
  SPrint(".", ln, "Start Dipcoating", ln);
  
  // Schätzt die Dauer des Dipcoats in Minuten
  int time = int(2 * dips * hubweg / mmpm);
  int time_h = int(time / 60);
  int time_min = int(time- (time_h * 60));
  SPrint(dips, ln, hubweg, ln, mmpm, ln);
  
  SPrint(time, ln);
  SPrint("Dauer: ", time_h, "h : ", time_min, "min", ln, ".", ln, ln);
  delay(1000);
  
  // Startet den Timer
  long strt_time = millis();
  SPrint("Tmr: ", strt_time, ln);
  
  // Dip-Vorgang
  for (int cnt_dips = 1; cnt_dips <= dips; cnt_dips++)
  {    
    SPrint(cnt_dips);
    pos = move_motor(rpm, "down", pos, hubweg);
    pos = move_motor(rpm, "up", pos, hubweg);
    SPrint("."); 
    
    // Zeilenumbruch alle 20 Dips
    if ((cnt_dips/20)*20 == cnt_dips) {SPrint(ln);};
  }
  SPrint(ln, "Beendet", ln);    

  // Laufzeit in Minuten
  long end_time = millis();
  long run_time = long((end_time - strt_time)/1000/60);
  SPrint("Start: ", strt_time, "s", ln,"End: ", end_time, "s", ln, "Run: ", run_time, "s", ln);
  SPrint("Laufzeit: ", run_time, "min");
} 
else 
{ // Testlauf beginnt hier
  // Dips, Hubweg & mmpm wurden bereits im Setup ausgegeben.
  // NOTHING HERE
} 
  // Endposition oben
  pos = move_motor(vmax, "up", pos);

  // Endlosschleife zum Anhalten des Programms
  while (1) {};
}

This program should drive a stepper to dip a lever down and up again several times. The function causing the problems is “SPrint”.

Thanks

PS: I deleted the else-case wich is not needed, because I just get 9500 characters per post

I complied and ran your sketch the output looks like:

-Dipcoater 0.1
(c) Christian Schrautzer
----------------------------------------

-Dips: 20
-Geschwindigkeit: 400 mm/min
-Hubweg: 50 mm
----------------------------------------
-TEST
test.-.-

then it print out lots and lots of ascii characters mixed with words

Is this what it supposed to do?

No, thats what it should not do. Till then it is all right, but then it should print a counter (line 267 - cnt_dips) followed by a dot like:

1.2.3.4.5.6.7.8.9 and so on.

I read a bit about the memory-thing.

I put in the SPrint-function to save some lines and make the code easier to read. But I think I should stick with the xxx lines of Serial.print as it will save memory. Storing it in the Flash memory wont do as I need to print variables.

What I do not understand is why those strings (sp_1 tp sp_15) would add up over time. I thought they block their memory just until they get a new value.