PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm säubern mit vielen void()s in eigenen Tabs



jok3r
22.03.2014, 18:40
Mein Programm wird ziemlich umfangreich, jetzt wollte ich für verschiedene Funktionen eigene Tab s erzeugen und dann diese dort ablegen.
Nach dem ich das gemacht habe, gibt es Probleme beim aufrufen der Funktionen. Muss ich diese irgendwie im Hauptprogramm definieren/anmelden das in anderen Tabs void() s sind die gebraucht werden ?

Gruß

Sisor
22.03.2014, 19:29
Wenn du verschiedene .ino Dateien in einem Ordner speicherst, wird der Kompiler diese Dateien automatisch integrieren.
Das sollte kein Problem darstellen.

jok3r
22.03.2014, 19:38
ja das hätte ich auch gemacht , komisch ist das es nur mit den void() s probleme gibt mit dennen das Display angesprochen wird.
Hab die jetzt im Hauptprogramm belassen, so funktionierst wenigstens

Sisor
22.03.2014, 20:07
Das Problem ist, dass du ein Display-Objekt ansprichst, dass der Kompiler anfangs noch nicht kennt.
Wenn du Auslagern willst, könnte das so gehen:

Vorher:


// test.ino
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(32, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);

void setup()
{
...
createCustomChar();
...
}
...
void createCustomChar()
{
uint8_t bell[8] = {0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04};
lcd.createChar(0, bell);
}


Nachher:


// test1.ino
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(32, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);

void setup()
{
...
createCustomChar(lcd);
...
}
...




//test2.ino
#include <LiquidCrystal_I2C.h>

void createCustomChar(LiquidCrystal_I2C lcd)
{
uint8_t bell[8] = {0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04};
lcd.createChar(0, bell);
}

Ich hoffe das Beispiel ist verständlich. Vorher mit integrierter void-Funktion, nachher ausgelagert. Das Display-Objekt (lcd) wird übergeben, damit es dem Kompiler zur Kompilierzeit bekannt ist.

ODER:



// test3.ino

void setup()
{
...
createCustomChar();
...
}
...




//test4.ino
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(32, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);

void createCustomChar()
{
uint8_t bell[8] = {0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04};
lcd.createChar(0, bell);
}
Hierbei ist der Trick, dass die Dateien test3.ino und test4.ino im Ordner test4 liegen. Dadurch erkennt die Arduino-IDE welche Datei als erstes zu interpretieren ist.

ODER:



// test5.ino
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(32, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
void setup()
{
...
createCustomChar();
...
}
...




//test6.ino

void createCustomChar()
{
uint8_t bell[8] = {0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04};
lcd.createChar(0, bell);
}
Hier müssen die Dateien test5.ino und test6.ino im Ordner test5 liegen, damit es funktioniert.

jok3r
22.03.2014, 21:11
Alles klar danke, ich habe es verstanden :) . Gruß

cdk
23.03.2014, 01:31
Ich dachte genau sowas macht man mit #include? Ist das tabu für Code-Teile und wird nur für Header-Dateien verwendet?

Sisor
23.03.2014, 09:37
Obige Beispiele beziehen sich auf .ino Dateien.
Es ist natürlich genauso der C++ Style möglich:


// test7.ino
#include <LiquidCrystal_I2C.h>
#include "LCDHelper.h"
LiquidCrystal_I2C lcd(32, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
void setup()
{
...
createCustomChar(lcd);
...
}
...



// LCDHelper.h

#ifndef _LCDHELPER_
#define _LCDHELPER_

#include <Arduino.h>
#include <LiquidCrystal_I2C.h>

void createCustomChar(LiquidCrystal_I2C);

#endif



// LCDHelper.cpp

#include "LCDHelper.h"

void createCustomChar(LiquidCrystal_I2C lcd)
{
uint8_t bell[8] = {0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04};
lcd.createChar(0, bell);
}

Alle 3 Dateien liegen hier im Ordner test7.

Welche Methode am einfachsten / übersichtlichsten ist, muss jeder für sich entscheiden.

jok3r
23.03.2014, 12:00
Ja danke ich glaub ich habs kapiert :). Eines noch ich hab mit interrupts ein menü gebastelt . Das ganze funktioniert über if Bedienungen mit denen er dann in die verschiedenen case springt.

Wenn ich jetzt mehrere voids im case aufrufe kann ich das display nicht mehr bedienen.


case 1: Teachen_menue();
joystick();
break;
.................................................. .................................................. ...............................

void Teachen_menue() //Menü Teachen, Display Ausgabe
{ lcd.clear();
lcd.setCursor(0,0) ;
lcd.print("---Teaching-Modus---") ;
lcd.setCursor(0,1) ;
lcd.print( "x=") ; lcd.print(x) ;
lcd.setCursor(7,1) ;
lcd.print( "y=") ; lcd.print(y) ;
lcd.setCursor(14,1) ;
lcd.print( "z=") ; lcd.print(z) ;
lcd.setCursor(0,2) ;
lcd.print( "Speed=") ; lcd.print(Speed) ;
lcd.setCursor(10,2);
lcd.print( "Delay=") ; lcd.print(Delay) ;
lcd.setCursor(0,3);
lcd.print( "Tool=") ; lcd.print(Tool) ;
lcd.setCursor(10,3);
lcd.print( "Pos=") ; lcd.print(Pos) ;
delay(500);
}

.................................................. .......................
void Joystick()
{
int analog_in0 = (512 - analogRead(ANALOG_IN0));
int analog_in1 = (512 - analogRead(ANALOG_IN1));
int analog_in2 = (512 - analogRead(ANALOG_IN2));
int analog_in3 = (512 - analogRead(ANALOG_IN3));

int AN0, AN01;
int AN1, AN11;
int AN2, AN21;
int AN3, AN31;

//.......Stepper1..........//
if (analog_in0 >= 35 )
{
AN0 = exp(analog_in0 / 67);
stepper0.setSpeed(AN0) ;
stepper0.runSpeed();
}
else if (analog_in0 <= -35)
{
AN01 = exp(-analog_in0 / 67);
stepper0.setSpeed(-AN01) ;
stepper0.runSpeed();
}

//........Stepper2...........//
else if (analog_in1 >= 35 )
{
AN1 = exp(analog_in1 / 67 );
stepper1.setSpeed(AN1) ;
stepper1.runSpeed();
}
else if (analog_in1 <= -35)
{
AN11 = exp(-analog_in1 / 67 );
stepper1.setSpeed(-AN11) ;
stepper1.runSpeed();
}

//..........Stepper3..........//
else if (analog_in2 >= 35)
{
AN2 = exp (analog_in2 / 67);
stepper2.setSpeed(AN2) ;
stepper2.runSpeed();
}
else if (analog_in2 <= -35)
{
AN21 = exp (-analog_in2 / 67);
stepper2.setSpeed(-AN21) ;
stepper2.runSpeed();
}

//............Stepper4...........//
else if (analog_in3 >= 35 )
{
AN3 = exp (analog_in3 / 67);
stepper3.setSpeed(AN3) ;
stepper3.runSpeed();
}
else if (analog_in3 <= -35)
{
AN31 = exp (-analog_in3 / 67 );
stepper3.setSpeed(-AN31) ;
stepper3.runSpeed();
}


Serial.print( analog_in0 ); Serial.print( ' ' );

Serial.print( analog_in1 ); Serial.print( ' ' );

Serial.print( analog_in2 ); Serial.print( ' ' );

Serial.print( analog_in3 ); Serial.println( "" );
}


case ist für mich wenn ich es richtig verstanden habe, ja nichts anderes als eine schleife die er solange abläuft bis ein break kommt oder ein anderer case gewählt wird ?

Sisor
23.03.2014, 12:16
case macht nur im Zusammenspiel mit switch Sinn. Es ist keine Schleife.
Am besten mal Tante Google fragen!

jok3r
23.03.2014, 12:33
Schon klar , stell mal alles on :)

Final:
#include <LiquidCrystal.h>
#include <AccelStepper.h>
#include <Wire.h>

#define ANALOG_IN0 A0
#define ANALOG_IN1 A1
#define ANALOG_IN2 A2
#define ANALOG_IN3 A3

LiquidCrystal lcd(34, 36, 38, 40, 42, 44, 46, 48, 50, 52);

AccelStepper stepper0(1, 13, 12); //Stepper 1
AccelStepper stepper1(1, 7, 6); //Stepper 2
AccelStepper stepper2(1, 10, 9); //Stepper 3
AccelStepper stepper3(1, 4, 3); //Stepper 4

const int inputPin_0 = 53; // Input Pin 43 Menü Teachen-Modus
const int inputPin_1 = 51; // Input Pin 45 Menü Automatik-Modus
const int inputPin_2 = 49; // Input Pin 47 Menü Justage-Modus


volatile int state=0; // Variablen, die von Interruptroutinen angefasst werden, sollten "volatile" deklariert werden
volatile unsigned long lastTime=0; // Zeitpunkt der letzten steigenden Flanke, nötig zum Entprellen

const int x = 0;
const int y = 0;
const int z = 0;
const int Wahl= 0;
const int Speed= 0;
const int Delay= 0;
const int Tool= 0;
const int Pos = 1;

void setup()
{
Wire.begin();

stepper0.setMaxSpeed(10000);
stepper0.setAcceleration(10000);


stepper1.setMaxSpeed(10000);
stepper1.setAcceleration(10000);


stepper2.setMaxSpeed(10000);
stepper2.setAcceleration(10000);


stepper3.setMaxSpeed(10000);
stepper3.setAcceleration(10000);

pinMode(inputPin_0, INPUT); // Input Deklaration
pinMode(inputPin_1, INPUT); // Input Deklaration
pinMode(inputPin_2, INPUT); // Input Deklaration

attachInterrupt(49, KeyPressed_1, RISING); // 43 ist der Interrupt , bei jeder steigenden Flanke wird keyPressed_0() aufgerufen
attachInterrupt(51, KeyPressed_2, RISING); // 45 ist der Interrupt , bei jeder steigenden Flanke wird keyPressed_1() aufgerufen
attachInterrupt(53, KeyPressed_3, RISING); // 47 ist der Interrupt , bei jeder steigenden Flanke wird keyPressed_2() aufgerufen

lcd.begin(16,4); // 1 ist der Interrupt für Pin 2, bei jeder steigenden Flanke wird keyPressed_1() aufgerufen
}




//.........................Interruput Auswertung mit entprellen........................................ .......................//
void KeyPressed_1(){ // state =0 , falls mindestens 100ms seit der letzten Flanke vergangen sind
unsigned long now = millis();
if (now - lastTime > 100){ // entprellen
state=1 ;

}
lastTime=now;
}

void KeyPressed_2(){ // state =1 , falls mindestens 100ms seit der letzten Flanke vergangen sind
unsigned long now = millis();
if (now - lastTime > 100){ // entprellen
state=2 ;

}
lastTime=now;
}

void KeyPressed_3(){ // state = 2 , falls mindestens 100ms seit der letzten Flanke vergangen sind
unsigned long now = millis();
if (now - lastTime > 100){ // entprellen
state=3 ;

}
lastTime=now;
}







//..................................MENÜ............ .................................................. ......................//
void loop()
{


switch(state)
{
case 0:
{ lcd.clear();

lcd.setCursor(0,0) ;
lcd.print(">>>>>>>Robotik<<<<<<") ;
lcd.setCursor(0,1) ;
lcd.print("Projektarbeit2014 by") ;
lcd.setCursor(0,2) ;
lcd.print("Kevin Krause") ;
lcd.setCursor(0,3) ;
lcd.print("Dominik Loher") ;


delay(10000);
state=1;
}

case 1: Teachen_menue();
Joystick();
break;
case 2: Automatik();
break;
case 3: Justage();
break;

}
}


Display:


void Teachen_menue() //Menü Teachen, Display Ausgabe
{ lcd.clear();
lcd.setCursor(0,0) ;
lcd.print("---Teaching-Modus---") ;
lcd.setCursor(0,1) ;
lcd.print( "x=") ; lcd.print(x) ;
lcd.setCursor(7,1) ;
lcd.print( "y=") ; lcd.print(y) ;
lcd.setCursor(14,1) ;
lcd.print( "z=") ; lcd.print(z) ;
lcd.setCursor(0,2) ;
lcd.print( "Speed=") ; lcd.print(Speed) ;
lcd.setCursor(10,2);
lcd.print( "Delay=") ; lcd.print(Delay) ;
lcd.setCursor(0,3);
lcd.print( "Tool=") ; lcd.print(Tool) ;
lcd.setCursor(10,3);
lcd.print( "Pos=") ; lcd.print(Pos) ;
delay(500);
}


void Automatik() //Menü Automatik, Display Ausgabe
{ lcd.clear();
lcd.setCursor(0,0);
lcd.print("--Automatik-Modus--");
lcd.setCursor(0,1);
lcd.print( "x=") ; lcd.print(x) ;
lcd.setCursor(7,1);
lcd.print( "y=") ; lcd.print(y) ;
lcd.setCursor(14,1);
lcd.print( "z=") ; lcd.print(z) ;
lcd.setCursor(0,2);
lcd.print( "Speed=") ; lcd.print(Speed) ;
lcd.setCursor(10,2);
lcd.print( "Delay=") ; lcd.print(Delay) ;
lcd.setCursor(0,3);
lcd.print( "Tool=") ; lcd.print(Tool) ;
lcd.setCursor(10,3);
lcd.print( "Pos=") ; lcd.print(Pos) ;
delay(500);
}


void Justage() //Menü Justage, Display Ausgabe
{ lcd.clear();
lcd.setCursor(0,0);
lcd.print("---Justage-Modus---");
lcd.setCursor(0,1);
lcd.print( "x=") ; lcd.print(x) ;
lcd.setCursor(7,1);
lcd.print( "y=") ; lcd.print(y) ;
lcd.setCursor(14,1);
lcd.print( "z=") ; lcd.print(z) ;
delay(500);
}


joystick:

void Joystick()
{
int analog_in0 = (512 - analogRead(ANALOG_IN0));
int analog_in1 = (512 - analogRead(ANALOG_IN1));
int analog_in2 = (512 - analogRead(ANALOG_IN2));
int analog_in3 = (512 - analogRead(ANALOG_IN3));

int AN0, AN01;
int AN1, AN11;
int AN2, AN21;
int AN3, AN31;

//.......Stepper1..........//
if (analog_in0 >= 35 )
{
AN0 = exp(analog_in0 / 67);
stepper0.setSpeed(AN0) ;
stepper0.runSpeed();
}
else if (analog_in0 <= -35)
{
AN01 = exp(-analog_in0 / 67);
stepper0.setSpeed(-AN01) ;
stepper0.runSpeed();
}

//........Stepper2...........//
else if (analog_in1 >= 35 )
{
AN1 = exp(analog_in1 / 67 );
stepper1.setSpeed(AN1) ;
stepper1.runSpeed();
}
else if (analog_in1 <= -35)
{
AN11 = exp(-analog_in1 / 67 );
stepper1.setSpeed(-AN11) ;
stepper1.runSpeed();
}

//..........Stepper3..........//
else if (analog_in2 >= 35)
{
AN2 = exp (analog_in2 / 67);
stepper2.setSpeed(AN2) ;
stepper2.runSpeed();
}
else if (analog_in2 <= -35)
{
AN21 = exp (-analog_in2 / 67);
stepper2.setSpeed(-AN21) ;
stepper2.runSpeed();
}

//............Stepper4...........//
else if (analog_in3 >= 35 )
{
AN3 = exp (analog_in3 / 67);
stepper3.setSpeed(AN3) ;
stepper3.runSpeed();
}
else if (analog_in3 <= -35)
{
AN31 = exp (-analog_in3 / 67 );
stepper3.setSpeed(-AN31) ;
stepper3.runSpeed();
}


Serial.print( analog_in0 ); Serial.print( ' ' );

Serial.print( analog_in1 ); Serial.print( ' ' );

Serial.print( analog_in2 ); Serial.print( ' ' );

Serial.print( analog_in3 ); Serial.println( "" );
}

Sisor
23.03.2014, 13:45
Ohne geschweifte Klammern:

void loop()
{
switch(state)
{
case 0:
lcd.clear();
lcd.setCursor(0,0) ;
lcd.print(">>>>>>>Robotik<<<<<<") ;
lcd.setCursor(0,1) ;
lcd.print("Projektarbeit2014 by") ;
lcd.setCursor(0,2) ;
lcd.print("Kevin Krause") ;
lcd.setCursor(0,3) ;
lcd.print("Dominik Loher") ;

delay(10000); // 10 Sekunden? Ernsthaft?
state = 1;
// kein break -> läuft in den case 1!
case 1:
Teachen_menue();
Joystick();
break;

case 2:
Automatik();
break;

case 3:
Justage();
break;
}//END_SWITCH
}//END_LOOP

jok3r
23.03.2014, 13:59
Ohje diese Anfängerfehler ... Aber das Problem besteht weiterhin, das Menü funktioniert nicht mehr wenn
case 1:
Teachen_menue();
Joystick();
break;

lösche ich Joystick() gehts wieder...

Sisor
23.03.2014, 14:47
Klappts denn ohne Auslagern?

Hier eine vereinfachte Version:

void Joystick()
{
int analog_in0 = (512 - analogRead(ANALOG_IN0));
int analog_in1 = (512 - analogRead(ANALOG_IN1));
int analog_in2 = (512 - analogRead(ANALOG_IN2));
int analog_in3 = (512 - analogRead(ANALOG_IN3));

//.......Stepper1..........//
if ( analog_in0 <= -35 || analog_in0 >= 35)
{
stepper0.setSpeed(exp(analog_in0 / 67)) ;
stepper0.runSpeed();
}
//.......Stepper1..........//
if ( analog_in1 <= -35 || analog_in1 >= 35)
{
stepper1.setSpeed(exp(analog_in1 / 67)) ;
stepper1.runSpeed();
}
//.......Stepper2..........//
if ( analog_in2 <= -35 || analog_in2 >= 35)
{
stepper2.setSpeed(exp(analog_in2 / 67)) ;
stepper2.runSpeed();
}
//.......Stepper3..........//
if ( analog_in3 <= -35 || analog_in3 >= 35)
{
stepper3.setSpeed(exp(analog_in3 / 67)) ;
stepper3.runSpeed();
}
// Ausgabe im Serial Monitor
Serial.print( analog_in0 ); Serial.print( ' ' );
Serial.print( analog_in1 ); Serial.print( ' ' );
Serial.print( analog_in2 ); Serial.print( ' ' );
Serial.println( analog_in3 );
}

jok3r
23.03.2014, 15:49
Ne dann klappt es leider auch nicht :/ :confused:

- - - Aktualisiert - - -

Es macht den Anschein als wäre joystick() das Problem ...wenn ich aus case 1 das Teaching_menu() lösche und dafür lcd.clear() einsetze . Hängt das display auch bzw es lässt sich nicht durchwählen. :(

- - - Aktualisiert - - -

Fehler gefunden , bzw es ergibt keinen Sinn ... im case 0 hab ich die delay zeit auf 5 Sekunden gesetzt ....jetzt geht alles wie es soll .Kennt wer die Erklärung dafür ?

Sisor
23.03.2014, 15:54
Ne, aber manchmal ist das halt so. Vermutung: interrupts.

jok3r
23.03.2014, 19:00
Okay ich weiß nicht was ich getan hab , aber der Fehler ist wieder vorhanden ^^.....Mittwoch kommt der Arduino Mega dann tausche ich den Due dagegen aus, vill wirds besser ...

- - - Aktualisiert - - -

So ich hab den Fehler wohl endlich gefunden---> Hinweise

Die Funktion delay() als Funktion innerhalb des Interrupts funktioniert nicht, ebenso wird millis() die zurückgegebenen Werte nicht hochzählen. Serielle Daten, die während der Funktion eintreffen, werden nicht berücksichtigt und gehen verloren. Jede Variable die innerhalb der eingebetteten Funktion verändert wird sollte als volatile deklariert werden


ich hab das entprellen entfernt und schon ging es . :)