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