Guten Tag zusammen,
ich heiß Marco und bin noch ziemlich neu was das Arduino Programmieren angeht. Ich hatte zuvor ein bisschen c++ im Studium und habe angefangen mich in der Freizeit nun mit dem Arduino auseinader zusetzen. Bei Problemen hat das Durchforsten des www bisher auch immer etwas gutes herforgebracht. Jedoch stehe ich momentan vor einem Problem und bräuchte eure Hilfe.
Ich kann mir gut vorstellen, dass es eine leichtere Lösung als meine gibt und hoffe, dass ihr mir sie vll zeigen könnt.
zu meinem Programm:
Der Arduino ist mit einem RC Receiver verbunden und ließt die Signale aus. Diese Signal möchte ich gerne alle abspeichern und bei bedarf wieder auslesen.
Die Daten, die an den Receiver ankommen werden vom Arduino empfangen. Diese wollte ich über einen String aneinanderhängen und durch Kommas trennen. Der String selber würde ich dann auf der SD Karte abspeichern und bei Bedarf auslesen und die Werte zwischen den Kommmas an den Motor wieder abgeben.
Genau hier ist mein Problem...den String mit den Kommas bekomme ich noch hin das Abspeichern auf der SD Karte und das darauffolgende auslesen jedoch nicht...ich weiß nicht wie ich das machen kann. Brauch ich die SD Karte überhaupt? Der Mega dürfte doch auch den String speichern können oder? Die Daten Menge in dem String ist jedoch relativ groß. Alle 20ms ein Wert. Würde gerne 10-15min Aufnehmen.
Könnt ihr mir helfen
Mit freundlichen Grüßen
#define CHANNEL_3_IN 0
#define CHANNEL_3_PIN 2
#include <Servo.h>
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
String daten_aufnahme = "";
//micros wenn der pin HIGH wird
volatile unsigned long timer_starten_3;
//die differenze zwischen Timer:start und micros() ist die Länge der Zeit in der der Pin High war
//das ist die PWM Pulslänge
volatile int pulse_laenge_3;
//Zeit bei der das letzte mal ein Interrupt aufgetreten ist
//kann verwendet werden um herrauszufinden ob der Empfänger ein Signal hat oder nicht
volatile int last_interrupt_time_3;
void setup()
{
timer_starten_3 = 0;
attachInterrupt(CHANNEL_3_IN, calcSignal_3, CHANGE);
Serial.begin(115200);
Serial.print("Initialisierung SD Card..");
//Überprüfung ob die Karte vorhanden ist
if (!SD.begin(chipSelect)) {
Serial.println("Fehlgeschlagen, oder Karte ist nicht vorhanden");
// don't do anything more:
return;
}
void loop()
{
int throttle = pulse_laenge_3;
daten_aufnahme =daten_aufnahme + "," + throttle;
}
void calcSignal_3()
{
//nimmt die interrupt zeit auf damit bestimmt werden kann ob an dem Empfänger ein Signal anliegt
last_interrupt_time_3 = micros();
//wenn am pin ein High anliegt soll die Zeit gemessen seitdem der Arduino hochgefahren wurde
if(digitalRead(CHANNEL_3_PIN) == HIGH)
{
timer_starten_3 = micros();
}
//ansonsten liegt ein low signal vor
else
{
//hat der timer bereits gestartet und es liegt nach dem high ein low signal kann über die differenz die Pulslänge errechnet werden.
//der timer ist dabei wieder auf 0 zu sätzen
if(timer_starten_3 > 0)
{
//pulslänge wird berechnet
pulse_laenge_3 = ((volatile int)micros() - timer_starten_3);
//timer wird zurrückgesetzt
timer_starten_3 = 0;
}
}
}
Also nach langem rumprobieren habe ich es geschafft...glaubte ich nun hängt sich jedoch nach langem Datenloggen das Arduino auf. Ich habe in mehreren Foren gelesen das Pin 4 auf Output und high gestellt werden muss. Auch das hat nichts geholfen. Ich kann die Daten aufnehmen und abspielen. Lösche ich diese nun über einen weiteren Steuerbefehl und will wieder neue Datenaufnehmen geht auch das. Spiele ich jedoch nun die Daten ab hängt er sich auf und springt zwischen verschiedenen Modis hin und her. Kann mir jemand einen Tipp geben?
Ich bin mir sicher das es an meinem Setup liegt weil meine Funktionen ja an sich super Funktionieren.
void setup()
{
Timer3.initialize(90000); //inititalisierung des Timer3 welcher benötigt wird um alle 200ms einen Wert einzulesen und auszulesen
timer_starten_3 = 0;
attachInterrupt(CHANNEL_3_IN, calcSignal_3, CHANGE); //Bei einer Änderung an Channel_3_IN soll die Funktion calcSignal_3 aufgerufen werden
timer_starten_5 = 0;
attachInterrupt(CHANNEL_5_IN, calcSignal_5, CHANGE);
timer_starten_6 = 0;
attachInterrupt(CHANNEL_6_IN, calcSignal_6, CHANGE);
timer_starten_7 = 0;
attachInterrupt(CHANNEL_7_IN, calcSignal_7, CHANGE);
Serial.begin(115200); //Einstellung für das Monitoring
Serial.print("Initialisierung SD Card..");
pinMode(4,OUTPUT); //
digitalWrite(4,HIGH); //
pinMode(10, OUTPUT); //Festlegung des Pin10 für die SD Karte
digitalWrite(10, HIGH); //Überschreibung des Wertes an Pin10 auf High wird für Arduino Mega benötigt für UNO wäre dieser Schritt unnötig
if (!SD.begin(4)) { //Überprüfung der SD Karte
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
esc.attach(9); //Initialisierung der Pinbelegung des ESC auf Pin 9
}
Ich benutze ein SD-Karten Modul mit Widerständen wie dieses, das am UNO funktioniert, nicht aber am Mega2560. In diese Richtung ging mein Verdacht. Andere SD-Karten Module wie dieses nutzen ein IC (mit U1 bezeichnet), um die 5V des Arduino an die 3,3V der SD-Karte anzupassen, was verträglicher sein sollte. Wie das bei Deinem Ethernetshield gemacht ist, kann ich nicht erkennen.
@ agmue:
dein SD Shield sollte auch am Mega funktionieren. Mußt nur die andere SPI Pinbelegung beachten.
@ Kalle:
dein Shield hat Ethernet und SD-KArte drauf. Beides läuft über den SPI Bus. Beide benötigen ein Chip-Select Pin. Diese sind beim nicht ansprechen der Device auf High-Pegel zu setzen. Es darf immer nur einer auf LOW Pegel sein.
Das heißt, wenn Pin 4 (CS für die SD-Karte) auf LOW geht, muß Pin 10 (CS für die Ethernet) auf High sein. Sehe ich nicht konfiguriert. Guck Dir mal die Sketch Bsp. von dem Shield an.
Pin 53 immer auf Output setzen, sonst klappt nichts. Deine 4 Pins 50-53 ist die SPI Hardware Schnittstelle vom Mega2560. Die werden von Deinem Shield über die untere 6pol. Buchse kontaktiert.
Wenn das wirklich zum Original kompatibel ist, dann sollte Dir das hier weiter helfen. Arduino Ethernet Shield
Ganz unten sind die Links.
Gehe die Bsp. durch, ich denke das es weiterhilft. Sonst nochmal fragen.
Edit:
in dem Link zum Shield stehen nur Bsp. zum Ethernet. Auf die SD wird nicht eingegangen, weil die zur SD-Lib kompatibel sein soll. Das heißt, gehe die SD-Karten Bsp. durch. Beachte dabei das Du dennoch Pin 10 auf High setzen mußt. Weil die gehen von einem reinen SD Karten Modul aus.
Zuerst einmal VIELEN dank euch beiden! @Doc
Pin 4 und Pin 10 habe ich doch bereits beide auf High gesetzt oder darf auch immer nur eines High sein?
Oder heißt das, dass wenn eines der beiden sein Signaländert muss das andere dem entsprechen auch wechseln damit sie niemals gleich sind?
deine zwei unteren Links gehen bei mir leider nicht und der erste zeigt mir keine Sketchbsp auf nur Informationen bezüglich des Ethernet Shield
hab ich nicht gesehen, dass du Pin 4 und 10 auf High gesetzt hast.
Ja genau, dass ist umgekehrte Logik. Das Device was Du ansprechen möchtest mußt du mit LOW Pegel am CS ansprechen. Alle anderen müssen auf dem SPI Bus ruhig sein (Klappe halten) mit High Pegel an ihren CS Pins.
Wegen SD Bsp. In der IDE sind die SD Bsp. enthalten.
IDE > Datei > Beispiele > SD > ...
Mußt wie gesagt Pin 10 als Output und auf High hinzufügen.
Pin 53 als Output reicht, muß nicht auf High, weil der unbenutzt bleibt.
Falsche Initialisierung für Ethernet-Shield mit SD, wenn nur die SD-Karte genutzt werden soll:
Serial.print("Initialisierung SD Card..");
pinMode(4,OUTPUT); //
digitalWrite(4,HIGH); //
pinMode(10, OUTPUT); //Festlegung des Pin10 für die SD Karte
digitalWrite(10, HIGH); //Überschreibung des Wertes an Pin10 auf High wird für Arduino Mega benötigt für UNO wäre dieser Schritt unnötig
if (!SD.begin(4)) { //Überprüfung der SD Karte
Serial.println("initialization failed!");
return;
}
Korrekte Initialisierung für Ethernet-Shield mit SD, wenn nur die SD-Karte genutzt werden soll:
Serial.print("Initialisierung SD Card..");
pinMode(SS,OUTPUT); // Hardware-SlaveSelect auf OUTPUT/LOW setzen
if (!SD.begin(4)) { // SD-Library mit SlaveSelect-Pin der SD-Karte initialisieren
Serial.println("initialization failed!");
return;
}
(Funktioniert für alle Atmega Arduino-Boards gleichermaßen.)
Hi,
ich habe vielleicht nicht eine direkte schnelle Antwort auf deine Frage. Ich mache Datalogging immer auf SD-Karte im Ehernet shield. Ich schicke dir mal den sketch, wo ich Messdaten von Sensoren neben der Ausgabe ins Internet (z.B. Smartphone) auch auf der Karte ablege. Mit Zeitstempel einer Funkuhr. Datei "log.csv".
Den Code enthält nur die Teile, die du vielleicht meinst. Viel mehr konnte ich nicht posten, wegen der Beschränkung im Forum.
Wichtig ist, das du beachtest, dass beim Mega die PINs alle etwas anders sind. Z.B. SPI 52,50, 51 und
// disable Ethernet chip
pinMode(53, OUTPUT);
digitalWrite(53, HIGH);
in setup.
Gruß. Vielleicht kannst du was brauchen davon.
// Arduino Wetter-Daten und WebCam
//
// - Arduino MEGA
// - Temp/Feuchte: DHT22 Pin1 -> 5V, Pin2 -> 3 , Pin4 -> GRD, 10kOhm zwischen Pin2 und Pin1
// - Druck: BMP085 Verwendung von Serial1, d.h. SDA an 20, SCL an 21
// - Helligkeit: Photowiderstand
// - Kamera adafruit VC0706 RX an 18, TX an 19
// - Ethernet shield 13 an 52, 12 an 50, 11 an 51 (SPI)
// - Funkuhr RTC Data an 2
// ****************************************************************************
*
*
*
Serial.println(F("Ini SD"));
if (!SD.begin(4)) {
Serial.println(F("SD failed!"));
return; // init failed
}
if (SD.exists("log.csv")) //if the datalog file is already on the disk
{
SD.remove("log.csv"); //delete it. This prevents that the data is appended to an already existing file.
}
*
*
// *** Messreihe auf SD-Card schreiben
File dataFile = SD.open("log.csv", FILE_WRITE);
if (dataFile) {
dataFile.print(day());
dataFile.print('/');
dataFile.print(month());
dataFile.print('/');
dataFile.print(year());
dataFile.print(",");
if (hour()<10)
dataFile.print('0');
dataFile.print(hour());
dataFile.print('-');
if (minute()<10)
dataFile.print('0');
dataFile.print(minute());
dataFile.print(",");
dataFile.print(mySensor.getTemperatureC());
dataFile.print(",");
dataFile.print(mySensor.getHumidity());
dataFile.print(",");
dataFile.print(bmp.readPressure()/100);
dataFile.println("");
dataFile.close();
Serial.println("Logfile");
}
else {
Serial.println("Couldn't open log file");
}
Ich habe pinMode(53,OUTPUT); in das setup eingefügt und alles funktioniert!! 1000 Dank an euch für den Fall des es wieder buggen sollte versuche ich die anderen Vorschläge aber bisher funktioniert es perfekt!
Nochmals vielen vielen Dank ihr habt keine Ahnung wie sehr ihr mir damit geholfen habt war echt am verzweifeln
lg
Kalle
@ agmue:
dein SD Shield sollte auch am Mega funktionieren. Mußt nur die andere SPI Pinbelegung beachten.
Die Pinbelegung stimmt, denn mit Spannungsteilern - das wäre mein Hilfestellungsversuch gewesen - funktioniert es mit UNO und Mega2560 einwandfrei.
Aber danke für den Hinweis, beim Mega muß man ja etwas aufpassen