Hallo Forum, ich habe mal eine Frage zu Ports vom Mega 2560. Ich habe einen GPS Sensor an das Mega 2560 an die Ports 52, 53, 5V, Ground angeschlossen. Der GPS-Sensor (NL-552ETTL) funktioniert wunderbar. Nun wollte ich die Daten auf eine SD Karte schreiben, live übertragen. Dazu benutzte ich ein Catalex 0.9b Micro(TF) SD Adapter. Laut Anleitung werden die Ports 50-53 und Spannungsversorgung 5V/Ground verwendet. Im Beispielsketch soll PinMode(53, Output); verwendet werden. Gibt es eine Alternative wie ich den GPS-Sensor oder die SD- Karte anders anschliessen kann? Danke im Voraus.
Steffen Priem schrieb: > Laut Anleitung werden die Ports 50-53 und Spannungsversorgung 5V/Ground > verwendet. Die Pins 50 bis 53 sind beim Arduino MEGA der "SPI-Bus". SD-Karten kannst Du nur am SPI-Bus betreiben. > Gibt es eine Alternative wie ich den GPS-Sensor oder die SD- Karte > anders anschliessen kann? GPS-Module geben ihre Daten meistens über eine serielle Schnittstelle aus. Der MEGA2560 hat vier serielle Schnittstellen, wovon die erste an Pin-0/1 über USB mit dem PC verbunden werden kann. Die übrigen drei seriellen Schnittstellen (Serial1, Serial2, Serial3) kannst Du daher problemlos zusammen mit GPS-Modulen verwenden. Auf dem Arduino MEGA Board sind die Pins für Serial1 mit RX1/TX1 gekennzeichnet, Serial2 mit RX2/TX2 und Serial3 mit RX3/TX3.
Das liegt daran, weil pin50 bis 53 der SPI-Port sind. SPI slaves haben normalerweie auch noch einen SlaveSelect mit dem mehrere am SPI-Bus betrieben werden könnten.
Hi >Die Pins 50 bis 53 sind beim Arduino MEGA der "SPI-Bus". >SD-Karten kannst Du nur am SPI-Bus betreiben. >Der MEGA2560 hat vier serielle Schnittstellen, Und jede der vier serielle Schnittstellen kann auch SPI. MfG Spess
Danke für die Antworten! Ich habe im Programm die neuen pins gesetzt trotzdem bekomme ich keine GPS-Daten mehr. Das funktioniert nur einwandfrei wenn ich Pin 52,53 nehme. Was muss ich am Programm ändern damit ich fortlaufend Daten bekomme? #include "Arduino.h" #include "SoftwareSerial.h" #include <LiquidCrystal.h> SoftwareSerial mySerial = SoftwareSerial(18, 19); #define powerpin 7 #define BUFFSIZ 64 LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7); int backLight=10; char buffer[BUFFSIZ]; // Stringlänge char *parseptr; char buffidx; int h; // Daten- GPS uint8_t hour, minute, second, year, month, date; uint32_t latitude, longitude; uint8_t groundspeed, trackangle; char latdir, longdir; char status; void setup() { pinMode(backLight, OUTPUT); digitalWrite(backLight, HIGH); //LCD-Display einschalten // Spalten und Zeilen des LCDs einstellen und lcd.begin(16, 2); // Eine Meldung auf dem LCD ausgeben. lcd.clear (); digitalWrite(backLight, LOW); //LCD-Display ausschalten if (powerpin) { pinMode(powerpin, OUTPUT); } pinMode(7, OUTPUT); // Verbindung mit seriellen Monitor Serial.begin(38400); // Verbindung mit GPS-Empfänger mySerial.begin(38400); digitalWrite(powerpin, LOW); Serial.println("LABEL, Format, Zeit UTC, Status A=OK, Lat (dd.mm.mmm), N/S, Long (dd.mm.mmm), E/W, Speed (Knoten), Curse, Datum, "); } uint32_t parsedecimal(char *str) { uint32_t d = 0; while (str[0] != 0) { if ((str[0] > '9') || (str[0] < '0')) return d; d *= 10; d += str[0] - '0'; str++; } return d; } void readline(void) { char c; buffidx = 0; while (1) { c=mySerial.read(); if (c == -1) continue; Serial.print(c); if (c == '\n') continue; if ((buffidx == BUFFSIZ-1))// || (c == '\r')) { buffer[buffidx] = 0; return; } buffer[buffidx++]= c; } } void loop() { Serial.print("DATA,"); uint32_t tmp; readline(); //Ausgabe des GPS-Empfängers //Serial.print(","); Serial.println(); if (strncmp(buffer, "$GPRMC",6) == 0) { // hhmmss time data parseptr = buffer+7; tmp = parsedecimal(parseptr); hour = tmp / 10000; minute = (tmp / 100) % 100; second = tmp % 100; parseptr = strchr(parseptr, ',') + 1; status = parseptr[0]; parseptr += 2; // Daten: latitude latitude = parsedecimal(parseptr); if (latitude != 0) { latitude *= 10000; parseptr = strchr(parseptr, '.')+1; latitude += parsedecimal(parseptr); } parseptr = strchr(parseptr, ',') + 1; // N/S if (parseptr[0] != ',') { latdir = parseptr[0]; } //Serial.print(latdir); // Daten: longitude parseptr = strchr(parseptr, ',')+1; longitude = parsedecimal(parseptr); if (longitude != 0) { longitude *= 10000; parseptr = strchr(parseptr, '.')+1; longitude += parsedecimal(parseptr); } parseptr = strchr(parseptr, ',')+1; // E/W if (parseptr[0] != ',') { longdir = parseptr[0]; //Serial.print(longdir); } // Speed parseptr = strchr(parseptr, ',')+1; groundspeed = parsedecimal(parseptr); // track angle parseptr = strchr(parseptr, ',')+1; trackangle = parsedecimal(parseptr); // date parseptr = strchr(parseptr, ',')+1; tmp = parsedecimal(parseptr); date = tmp / 10000; month = (tmp / 100) % 100; year = tmp % 100; delay (250); } //Serial.println(buffer); }
Steffen Priem schrieb: > Ich habe im Programm die neuen pins gesetzt trotzdem bekomme ich keine > GPS-Daten mehr. > Das funktioniert nur einwandfrei wenn ich Pin 52,53 nehme. > > ... > SoftwareSerial mySerial = SoftwareSerial(18, 19); Oh, oh, oh. Die Pins 18 und 19 SIND eine Hardware-Serial Schnittstelle, und zwar "Serial1". An den Pins wird daher natürlich keine serielle Schnittstelle per Software emuliert, sondern die vorhandene Serielle Schnittstelle wird einfach benutzt. Du deklarierst daher keine "SoftwareSerial" als "mySerial", sondern verwendest stattdessen "Serial1" überall dort, wo bisher "mySerail" stand. Also lösche als erstes die include-Zeile:
1 | #include "SoftwareSerial.h" |
Dann löschst Du die Deklaration der SoftwareSerial-Schnittstelle:
1 | SoftwareSerial mySerial = SoftwareSerial(18, 19); |
Und lasse dann "Suchen und Ersetzen" laufen und ersetze alle Vorkommen von "mySerial" durch "Serial1" im gesamten Sketch! Außerdem beachten: Pin-19 ist der RX1-Pin und Pin-18 der TX1-Pin!
Hallo Leute, ich kann doch die digitalen Ports, z.B. 30-33 als SPI nutzen. Die Frage ist, wo ich deklariere, dass die Ports 30-33 aber auch die Ports 50-53 SPI sind und darüber jeweils ein Gerät läuft. Ich habe folgendes probiert zu ergänzen(in pins_Arduino.h): #ifndef Pins_Arduino_h #define Pins_Arduino_h #include <avr/pgmspace.h> #define NUM_DIGITAL_PINS 70 #define NUM_ANALOG_INPUTS 16 #define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1) #define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46)) static const uint8_t SS = 53 && 33; static const uint8_t MOSI = 51 && 31; static const uint8_t MISO = 50 && 30; static const uint8_t SCK = 52 && 32; static const uint8_t SDA = 20; static const uint8_t SCL = 21; static const uint8_t LED_BUILTIN = 13; static const uint8_t A0 = 54; static const uint8_t A1 = 55; static const uint8_t A2 = 56; static const uint8_t A3 = 57; static const uint8_t A4 = 58; static const uint8_t A5 = 59; static const uint8_t A6 = 60; static const uint8_t A7 = 61; static const uint8_t A8 = 62; static const uint8_t A9 = 63; static const uint8_t A10 = 64; static const uint8_t A11 = 65; static const uint8_t A12 = 66; static const uint8_t A13 = 67; static const uint8_t A14 = 68; static const uint8_t A15 = 69; // A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) // Only pins available for RECEIVE (TRANSMIT can be on any pin): // (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me) // Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 #define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \ (((p) >= 50) && ((p) <= 53)) || \ (((p) >= 30) && ((p) <= 33)) || \ (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) )//davor die Zeile neu #define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53))|| (((p) >= 30) && ((p) <= 33)) ? 0 : \ ( (((p) >= 62) && ((p) <= 69)) ? 2 : \ 0 ) )//Abschnitt mit 30-33 ist neu #define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53))|| (((p) >= 30) && ((p) <= 33)) ? (&PCMSK0) : \ ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \ ((uint8_t *)0) ) )//Abschnitt mit 30-33 ist neu #define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \ ( ((p) == 50 || 30) ? 3 : \ ( ((p) == 51 || 31) ? 2 : \ ( ((p) == 52 || 32) ? 1 : \ ( ((p) == 53 || 33) ? 0 : \ ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \ 0 ) ) ) ) ) )//davor die Zeilen sind neu #ifdef ARDUINO_MAIN
Steffen Priem schrieb: > ich kann doch die digitalen Ports, z.B. 30-33 als SPI nutzen. Die Frage > ist, wo ich deklariere, dass die Ports 30-33 aber auch die Ports 50-53 > SPI sind und darüber jeweils ein Gerät läuft. Hardware-SPI liegt bei den Arduino MEGA Boards auf den Pins 50 bis 53. An anderen Pins als diesen gibt es keine Hardware SPI-Unterstützung vom Controller. Lediglich eine "Software SPI" Emulation kannst Du auf anderen Pins laufen lassen. Irgendwie hast Du es damit, Hardware in Software emulieren zu wollen? Schon eine zusätzliche serielle Schnittstelle wolltest Du weiter oben in Software emulieren, obwohl ein Atmega2560 bereits vier in Hardware verfügbare serielle Schnittstellen mitbringt. Nun möchtest Du eine SPI-Schnittstelle auf anderen Pins per Software emulieren, obwohl es eine SPI-Schnittstelle als Hardware auf dem Atmega2560 gibt. Es ist mir alles unbegreiflich, was Du da machen möchtest.
Ich versuche über SPI(Ports50-53) TF Card Adapter anzuschließen,funktioniert auch. GPS Modul war vorher an den Pins 52 und 53. Nun musste ich halt für GPS andere Ports suchen. Die Ports 18 und 19 können zwar genutzt werden,aber GPS schickt nun Teile von Zeichenketten, die völlig unverständlich sind. Die Vermutung liegt darin,dass der Speicher so ausgelesen wird,dass alte Daten noch nicht weg sind, jedoch bereits mit neuen überschrieben werden. Da ich nicht am Speicher fummeln wollte, dachte ich, dass es einfacher wäre, einen zweiten SPI zu emulieren. Ich habe auch etwas vom UART Buffer gelesen, habe aber leider nicht so viel Ahnung davon. Daher bitte um Hilfe
Steffen Priem schrieb: > Die Ports 18 und 19 > können zwar genutzt werden,aber GPS schickt nun Teile von Zeichenketten, > die völlig unverständlich sind. Die Vermutung liegt darin,dass der > Speicher so ausgelesen wird,dass alte Daten noch nicht weg sind, jedoch > bereits mit neuen überschrieben werden. Da ich nicht am Speicher fummeln > wollte, dachte ich, dass es einfacher wäre, einen zweiten SPI zu > emulieren. Hast Du die von mir in Posting Beitrag "Re: Arduino Mega 2560 + GPS + auf SD schreiben" vorgeschlagenen Änderungen gemacht und verwendest Serial1 als HardwareSerial? Wenn nein, und wenn Du immer noch SoftwareSerial verwendest, dann kann der eintrudelnde Datenmatsch auch an SoftwareSerial liegen. Wenn Du HardwareSerial nutzt und trotzdem Datenmüll reinbekommst, dann liest Du die Schnittstelle tatsächlich zu langsam aus. Bei 38400 Baud empfängst Du bis zu 3840 Zeichen pro Sekunde. Der serielle Eingangspuffer kann 63 Zeichen zwischenpuffern, also mußt Du den Eingangspuffer SPÄTESTENS alle 63/3840s = 0,0164s = 16,4 ms auslesen. Falls Dir der serielle Eingangspuffer bei längerdauernden Aktionen überläuft, z.B. weil die Speicheraktion auf SD-Karte mal wieder 60 Millisekunden dauert, dann mußt Du im Prinzip den kompletten Eingangspuffer leerlesen und verwerfen und neu auf einen Zeilenanfang synchronisieren.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.