Moin,
habe mal wieder ein Problem mit einem Arduino Mega...
Der Code, den ich unten eingefügt habe, funktioniert an sich erstmal.
Kurze Erklärung: Ich habe an den Mega zwei Unos angeschlossen die beide einen Wert an den Mega senden. Dieser liest diese und gibt sie an ein Nextion-Display weiter. Funktioniert auch soweit. Nun zum Problem: Wenn ich in dem Code noch irgendetwas ans Display oder an irgendeinen anderen Serial-Port sende, werden mir auf dem Display zwar manchmal die richtigen Werte angezeigt, zwischendurch jedoch, in unregelmäßigen Zeitabständen, werden einfach random irgendwelche Zahlen angezeigt (siehe Video). Liegt es vielleicht daran, dass der eine Uno dauerhaft sendet und der andere nur einmal, wenn die Bedingung einer while-Schleife erfüllt ist?
Hier der funktionierende Code bzw. dessen loop() und die Funktion displayResult():
void loop() {
int num_sats = gps.satellites.value();
char lat = gps.location.lat();
char lng = gps.location.lng();
gps_speed = gps.speed.kmph();
if (serialTask(x)) {
Serial.print("t5.txt=");
Serial.print("\"");
Serial.print(x);
Serial.print("\"");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
var = map(x, 0, 7000, 1, 70);
Serial.print("q0.picc=");
Serial.print(var);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("n1.val=");
Serial.print(gps_speed);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
if(x >= 5750) {
Serial.print("p8.pic=71");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
} else {
Serial.print("p8.pic=79");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
if(x <= 750) {
Serial.print("p4.pic=76");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
} else {
Serial.print("p4.pic=77");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
if(x <= 1400 && x > 750) {
Serial.print("p6.pic=75");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
} else {
Serial.print("p6.pic=79");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
}
displayResult();
digitalWrite(LED_BUILTIN, HIGH);
}
void displayResult() {
int y;
if (serialTask2(y)) {
elapsed = y * 10;
float h, m, s, ms;
unsigned long over;
h = int(y / 360000);
over = y % 36000;
m = int(over / 6000);
over = over % 6000;
s = int(over / 100);
ms = over % 1000;
Serial.print("t0.txt=");
Serial.print("\"");
if(m < 10) Serial.print("0");
Serial.print(m, 0);
Serial.print(":");
if(s < 10) Serial.print("0");
Serial.print(s, 0);
Serial.print(":");
if(ms < 100) Serial.print("0");
if(ms < 10) Serial.print("0");
Serial.print(ms, 0);
Serial.print("\"");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
}
Hier das Video!
Bitte gebt mir, natürlich nur wenn es möglich ist, Beispiele als Code, da ich noch etwas unerfahren bin, was die Sprache angeht und mich einfache Antworten wie mach mal das und das, aus Erfahrung von meinen letzten Beiträgen im Forum nicht weiterbringen. Aber natürlich freue ich mich über jede Antwort.
gerberleon:
Hier der funktionierende Code
Wenn der funktioniert, dann bring doch das, was NICHT funktioniert.
Was soll daraus ersichtlich sein? Das GPS geht oder nicht?
Pinbelegungen? Verwendete lib(s)? Beschaltung?
Oder Klicks bei youtube?
Ich habe doch geschrieben was nicht funktioniert...
Das GPS-Modul an sich geht, wenn ich jedoch etwas an das Nextion-Display (oder auch an einen anderen Serial-Port) senden möchte, dann passiert das, was man in dem Video sieht. An Libraries habe ich nur die für das GPS-Modul... Aber hier nochmal der Setup-Teil mit den Read-Funktionen:
int elapsed;
int rpm, var, gpsspeed;
#define ZEILENTRENNZEICHEN 10
bool led = false;
#include <SoftwareSerial.h>
static const int RXPin = 37, TXPin = 39;
static const uint32_t GPSS = 9600;
SoftwareSerial ss(RXPin, TXPin);
#include <TinyGPS++.h>
TinyGPSPlus gps;
double Lat;
double Long;
int num_sat, gps_speed;
String heading;
int x;
char* receiveBuffer()
{
static char lineBuffer[25];
static byte counter=0;
char c;
if (Serial3.available()==0) return NULL;
if (counter==0) memset(lineBuffer,0,sizeof(lineBuffer));
c=Serial3.read();
if (c==ZEILENTRENNZEICHEN)
{
counter=0;
return lineBuffer;
} else if (c>=32) {
lineBuffer[counter]=c;
if (counter<sizeof(lineBuffer)-2) counter++;
}
return NULL;
}
boolean serialTask(int &rpm) {
char* text = receiveBuffer();
if(text == NULL) return false;
char* rpmrec=strchr(text, 'X');
if(rpmrec == NULL) return false;
rpm = atoi(rpmrec+1);
return true;
}
char* receiveBuffer2()
{
static char lineBuffer2[40];
static byte counter2=0;
char c2;
if (Serial2.available()==0) return NULL;
if (counter2==0) memset(lineBuffer2,0,sizeof(lineBuffer2));
c2=Serial2.read();
if (c2==ZEILENTRENNZEICHEN)
{
counter2=0;
return lineBuffer2;
} else if (c2>=32) {
lineBuffer2[counter2]=c2;
if (counter2<sizeof(lineBuffer2)-2) counter2++;
}
return NULL;
}
boolean serialTask2(int &laptime) {
char* text2 = receiveBuffer2();
if(text2 == NULL) return false;
char* laptimerec=strchr(text2, 'Y');
if(laptimerec == NULL) return false;
laptime = atoi(laptimerec+1);
return true;
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(9600);
Serial.print("baud=115200");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.begin(115200);
Serial3.begin(9600);
Serial2.begin(9600);
Serial1.begin(9600);
Serial.println("Start");
delay(2500);
Serial.print("t2.font=3");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("t0.font=3");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("t2.font=3");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("p7.pic=80");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
delay(200);
Serial.print("p3.pic=79");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("p4.pic=80");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.print("p5.pic=79");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
ss.begin(GPSS);
}
Und bitte entschuldige, falls mein Code "etwas" unordentlich sein sollte...
Warum hängst Du das Nextion an Serial? Das brauchst Du zum Programmieren und für serielle Outputs
Gruß Tommy
Wie soll ich das nextion denn sonst ansteuern? Geht nunmal nur über Serial... Oder weißt du mehr darüber als ich? Oder meinst du an einen anderen port?
gerberleon:
Oder meinst du an einen anderen port?
Ja.
Es würde schon reichen, wenn Du nicht mit Bruchstücken kommen würdest.
Was soll denn der geneigte Leser hier rauslesen?
Serial.begin(9600);
Serial.print("baud=115200");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
Serial.begin(115200);
Serial3.begin(9600);
Serial2.begin(9600);
Serial1.begin(9600);
Du hast den Display an dem seriellen Port, an dem die USB-Schnittstelle dran hängt.
Warum nutzt Du nicht einen der Ports Serial1-3? Was passiert da sonst noch?
Ok, ich habe jetzt Serial.* durch Serial1.* ersetzt. Jetzt geht es gar nicht mehr. Verkabelung stimmt, Baud-Rate stimmt...
Edit: Hier mal mit Fritzing die Verkabelung... Der 4-Pin-Header soll den Anschluss zum Display darstellen. Hatte das Display in Fritzing nicht gefunden. Imgur: The magic of the Internet
Womit versorgst Du das ganze Konstrukt?
Gruß Tommy
Momentan noch über den USB Anschluss, später jedoch über einen 12V Bleiakku.
Du versorgst 3 Arduino per USB und klemmst deren 5V zusammen?
Gruß Tommy
Nein, ich benutze drei Verschiedene USB-Ports meines Computers. Fällt mir auch gerade auf, dass das eigentlich falsch ist auf dem Bild. 
Ok. Wir können nur das beurteilen, was Du uns lieferst.
Zeige uns doch mal wie Dein Sketch jetzt aussieht.
Gruß Tommy
Ok ich poste hier mal den gesamten Sketch:
int best = 999999;
int newbest = 0;
int elapsed;
int selftest = 0;
int st = 0;
int rpm, var, gpsspeed;
#define ZEILENTRENNZEICHEN 10
#include <SoftwareSerial.h>
static const int RXPin = 37, TXPin = 39;
static const uint32_t GPSS = 9600;
SoftwareSerial ss(RXPin, TXPin);
#include <TinyGPS++.h>
TinyGPSPlus gps;
double Lat;
double Long;
int num_sat, gps_speed;
String heading;
int x;
char* receiveBuffer()
{
static char lineBuffer[25];
static byte counter=0;
char c;
if (Serial3.available()==0) return NULL;
if (counter==0) memset(lineBuffer,0,sizeof(lineBuffer));
c=Serial3.read();
if (c==ZEILENTRENNZEICHEN)
{
counter=0;
return lineBuffer;
} else if (c>=32) {
lineBuffer[counter]=c;
if (counter<sizeof(lineBuffer)-2) counter++;
}
return NULL;
}
boolean serialTask(int &rpm) {
char* text = receiveBuffer();
if(text == NULL) return false;
char* rpmrec=strchr(text, 'X');
if(rpmrec == NULL) return false;
rpm = atoi(rpmrec+1);
return true;
}
char* receiveBuffer2()
{
static char lineBuffer2[40];
static byte counter2=0;
char c2;
if (Serial2.available()==0) return NULL;
if (counter2==0) memset(lineBuffer2,0,sizeof(lineBuffer2));
c2=Serial2.read();
if (c2==ZEILENTRENNZEICHEN)
{
counter2=0;
return lineBuffer2;
} else if (c2>=32) {
lineBuffer2[counter2]=c2;
if (counter2<sizeof(lineBuffer2)-2) counter2++;
}
return NULL;
}
boolean serialTask2(int &laptime) {
char* text2 = receiveBuffer2();
if(text2 == NULL) return false;
char* laptimerec=strchr(text2, 'Y');
if(laptimerec == NULL) return false;
laptime = atoi(laptimerec+1);
return true;
}
void setup() {
Serial.begin(9600);
delay(500);
Serial1.begin(9600);
Serial1.print("baud=115200");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.end();
Serial1.begin(115200);
Serial3.begin(9600);
Serial2.begin(9600);
Serial.println("Start");
delay(2500);
Serial1.print("t2.font=3");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.print("t0.font=3");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.print("t2.font=3");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.print("p7.pic=80");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
delay(200);
Serial1.print("p3.pic=79");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.print("p4.pic=80");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.print("p5.pic=79");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
startupTest();
ss.begin(GPSS);
}
void startupTest() {
if(selftest == 0) {
if(st == 0){
delay(10);
rpm = rpm + 100;
Serial1.print("t5.txt=");
Serial1.print("\"");
Serial1.print(rpm);
Serial1.print("\"");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
var++;
Serial1.print("q0.picc=");
Serial1.print(var);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
gpsspeed++;
Serial1.print("n1.val=");
Serial1.print(gpsspeed);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
}
digitalWrite(LED_BUILTIN, LOW);
if(var == 70){
st = 1;
}
if(st == 1) {
delay(10);
rpm = rpm - 100;
Serial1.print("t5.txt=");
Serial1.print("\"");
Serial1.print(rpm);
Serial1.print("\"");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
var = var - 1;
Serial1.print("q0.picc=");
Serial1.print(var);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
gpsspeed--;
Serial1.print("n1.val=");
Serial1.print(gpsspeed);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
if(var == 1){
st = 0;
delay(500);
selftest = 1;
}
}
}
if(selftest == 0) {
startupTest();
}
}
void loop() {
int num_sats = gps.satellites.value();
char lat = gps.location.lat();
char lng = gps.location.lng();
gps_speed = gps.speed.kmph();
if (serialTask(x)) {
Serial1.print("t5.txt=");
Serial1.print("\"");
Serial1.print(x);
Serial1.print("\"");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
var = map(x, 0, 7000, 1, 70);
Serial1.print("q0.picc=");
Serial1.print(var);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.print("n1.val=");
Serial1.print(gps_speed);
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
if(x >= 5750) {
Serial1.print("p8.pic=71");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
} else {
Serial1.print("p8.pic=79");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
}
if(x <= 750) {
Serial1.print("p4.pic=76");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
} else {
Serial1.print("p4.pic=77");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
}
if(x <= 1400 && x > 750) {
Serial1.print("p6.pic=75");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
} else {
Serial1.print("p6.pic=79");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
}
}
displayResult();
digitalWrite(LED_BUILTIN, HIGH);
}
void displayResult() {
int y;
if (serialTask2(y)) {
elapsed = y * 10;
float h, m, s, ms;
unsigned long over;
h = int(y / 360000);
over = y % 36000;
m = int(over / 6000);
over = over % 6000;
s = int(over / 100);
ms = over % 1000;
Serial1.print("t0.txt=");
Serial1.print("\"");
if(m < 10) Serial1.print("0");
Serial1.print(m, 0);
Serial1.print(":");
if(s < 10) Serial1.print("0");
Serial1.print(s, 0);
Serial1.print(":");
if(ms < 100) Serial1.print("0");
if(ms < 10) Serial1.print("0");
Serial1.print(ms, 0);
Serial1.print("\"");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
}
}
static void smartDelay(unsigned long ms){
unsigned long started = millis();
do {
while(ss.available()) gps.encode(ss.read());
} while(millis() - started < ms);
}
void Get_GPS() {
num_sat = gps.satellites.value();
if(gps.location.isValid() == 1) {
Lat = gps.location.lat();
Long = gps.location.lng();
gps_speed = gps.speed.kmph();
heading = gps.cardinal(gps.course.value());
}
smartDelay(0);
}
Der gesamte DCode ohne einen Kommentar, was da passieren soll (inhaltlich), das tut sich keiner an.
Wo liegt denn eigentlich Dein Problem genau?
Dann solltest Du den Sketch erst mal auf dieses Problem reduzieren und das Problem klar benennen. (ich würde beim Nextion in der Erprobungsphase erst mal bei 9600 bleiben).
Gruß Tommy
Also mein eigentliches Problem bestand darin, dass wenn ich in dem Code, so wie ich ihn gerade gepostet habe, nur mit Serial.* anstatt Serial1.*, in den loop() noch irgendetwas einfüge, was mit der seriellen Kommunikation zu tun hat, dass er dann zwar auf dem Display das ausgibt, was er soll, zwischendurch jedoch irgendwelche random Werte. Es ist egal, was ich mit Serial mache, egal ob Serial, 1, 2 oder 3 oder ob Zahl oder ein Wort, egal ob Print oder Write. Sobald da mehr drin steht, als das was jetzt auch drin ist gibt der nicht mehr immer das richtige aus. Ich kann mir das einfach nicht erklären...
Dann gehe zurück und teste erst mal alle Funktionalitäten einzeln.
Wenn die alle funktionieren, dann kombiniere immer 2 und schaue, was passiert.
Auch seriele Ausgaben helfen bei der Fehlersuche, deshalb solltest Du Serial frei haben für Ausgaben.
Danach mehr kombinieren.
Gruß Tommy
Alles klar. Habe das mal getestet.
Der Fehler tritt immer auf, wenn ich mehr über Serial ausgebe, als in dem Code, den ich gepostet habe ausgegeben wird. Ich kann andere Sachen einfach kommentieren und dann geht es. Also wenn ich z. B.
Serial.print("t5.txt=");
Serial.print("\"");
Serial.print(x);
Serial.print("\"");
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
kommentiere, kann ich eine andere Sache wieder an das Display senden, will ich jedoch zwei Werte senden, muss ich noch mehr kommentieren/löschen.
Hat das eventuell etwas mit den Funktionen zu tun, die von den anderen Arduinos lesen?
Serial ist doch nicht mehr die Verbindung zum Nextion. Der gezeigte Code ist Unsinn.
Serial ist Deine Dbugausgabe. Die kannst Du ruhig auf 15200 hoch setzen (den seriellen Monitor auch).
Gruß Tommy
Ich hatte es wieder geändert auf Serial, da es auf Serial1 nach wie vor nicht funktioniert...
Ich gebe es auf. Da sehe ich nicht mehr durch, was Du da treibst.
Evtl. hat jemand anderes da ein besseres Händchen, als ich.
Gruß Tommy