Arduino micro serial probleme

Hallo zusammen,

ich habe ein Digitales dashboard für das Game Project Cars auf dem arduino entwickelt. Es wird immer weiter ausgebaut. Nun habe ich von einem User die Mitteilung bekommen das er mit dem Arduino micro nicht verbinden kann. Das problem ist meine software sendet "VER;" an den controller um die geflashte Version mit dem Programm abzugleichen. Wenn ich jetzt über den serial Monitor prüfe kommt auch die Version zurück "1.2.9;2;". Nur mit dem Programm kommt nichts zurück.

ich habe mich schon auf zisch Seiten rumgetrieben aber ich bin nicht zum erfolg gekommen. Mein Latein ist am ende (schlechte english Kenntnisse). Vielleicht könnt ihr mir ja weiter helfen

Die software und arduino code ist hier zum Download
http://ws-clan.de/pc_dash/

das support Forum

Das Windows Programm habe ich in C++ geschrieben. Getestet habe ich das ganze auf arduino Nano, Uno und Mega und dort funktioniert es Einwand frei, nur halt bis jetzt auf dem micro nicht.

Gruß
saibot852

Hallo saibot852,

das Problem wird an dem Sketch liegen, bzw. an dem falschen Controller! Nano, Uno und Mega nutzen einen externen Chip, um mit dem PC über die Serielle Schnittstelle zu kommunizieren. Uno und Mega über den 8U2/16U2, der Nano über den FTDI.

Problem ist, dass für den Micro die Serielle Schnittstelle falsch konfiguriert ist.

void setup() { 
 //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB
  }
}

Der Micro ist die kleine Version des Leonardo. Da funktioniert Serial anders, da das ein richtiges USB Interface ist

Für dich ist vielleicht das relevant:

ok

wenn ich den anfang jetzt so schreibe

String ver;

void setup() {

  ver = "1.2.9;2;";

  Serial.begin(38400);
  while (!Serial) {
    Serial.println(ver);
    ; // wait for serial port to connect. Needed for native USB
  }

}

und im loop den rest verarbeite disconncted die Software kurz nach dem Versions check

Nein!

while (!Serial) ;

Das ist busy-waiting bis die serielle Schnittstelle bereit ist. Und erst danach kannst du Daten schicken

Du machst jetzt das genaue Gegenteil. Solange Daten schicken wie Serial nicht geht.

ach ja das "!"

aber dennoch kein erfolg

Das kannst du meiner Meinung nach nicht mit einem Nano, Mega oder Uno testen. Die Serielle Schnittstelle steht direkt über den Atmega16U2 zur Verfügung.

Die serielle Schnittstelle an Pin 0 und 1 ist beim Arduino Leonardo / Micro serial1 nicht serial.

also
Serial1.begin(38400);
Serial1.println(ver);
usw

Grüße Uwe

Da sollte er vielleicht mal sagen ob das an der USB Buchse hängt oder direkt an Pin 0/1

Wobei, ernsthaft, ich würde das Programm jetzt nicht für einen umschreiben. Zwischen 16U2 und den Atmega328P/2560 gibt es noch einige Unterschiede, die mehr oder weniger gravierend sein werden.

Der Leonardo verwendet einen 32U4

Das lässt sich aber einfach über Präprozessor Makros lösen:

#if defined (__AVR_ATmega32U4__)
   #define SER Serial1
#else
   #define SER Serial
#endif

Und dann überall SER statt Serial verwenden. Wenn es wirklich daran liegt...

Genauso kann man an anderen Stellen unterscheiden wenn man anderen Code braucht.

Serenifly:
Da sollte er vielleicht mal sagen ob das an der USB Buchse hängt oder direkt an Pin 0/1

USB

Serenifly:
Der Leonardo verwendet einen 32U4

Das lässt sich aber einfach über Präprozessor Makros lösen:

#if defined (__AVR_ATmega32U4__)

#define SER Serial1
#else
  #define SER Serial
#endif




Und dann überall SER statt Serial verwenden. Wenn es wirklich daran liegt...

Genauso kann man an anderen Stellen unterscheiden wenn man anderen Code braucht.

danke für den tipp aber immer noch es kommt nichts zurück

Wenn das Gerät an USB hängt, dann ist Serial korrekt. Serial1 (am Leonardo/Micro) ist Pins 0/1
Deshalb hatte ich gesagt "wenn es wirklich daran liegt"

Komisch dann. Abgesehen davon dass man warten muss bis die serielle Schnittstelle bereit ist, sollte sich ansonsten eigentlich gleich verhalten, auch wenn die Implementierung darunter anders ist.

Vor ein paar Tagen bin ich in einem anderen Thread über eine
ähnliche Kommunikationsverhemmung gestolpert,
vielleicht hängt das ja mit deinem Problem zusammen.

Mit dem Test aus dem obigen Thread konnte ich erfolgreich die Kommunikation
zu einem Leonardo stilllegen, also den Bug bestätigen.

So ich habe es jetzt so geschreiben

String ver;
char incomingByte = 0;
char data[80];
int counter = 0;

void setup() {

  ver = "1.3.0;2;";
  Serial.begin(38400);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB
  }

}
void loop() {

  if (Serial.available() > 0) {
    incomingByte = Serial.read();

    if (incomingByte != ';') {
      data[counter] = incomingByte;
      data[counter + 1] = '\0';
      counter ++;
    } else {
      String stringOne = data;

if (stringOne.substring(0, 3) == "VER") {
        Serial.println(ver);
}

      data[0] = '\0';
      counter = 0;
    }
  }
}

und nichts passiert mit meiner software

aber mit dem seriellen monitor gehts

so sende ich aus meiner software C++

String^ ver_ss = "1.3.0;2;";
Sleep(1000);
serialPort1->ReadTimeout = 3000;
serialPort1->WriteTimeout = 3000;
serialPort1->Write(String::Format(";VER;"));
System::String^ comread = serialPort1->ReadLine();

array<Char>^chars = { ';' };
array<String^>^gesplitted = comread->Split(chars);

if (gesplitted[0] != ver_ss) {
	MessageBox::Show("Your arduino code version: " + gesplitted[0] + " is not compatible.\nPlease update your code.\nYou need Arduino code version " + ver_ss + "!",
	"Connection error", MessageBoxButtons::OK,
	MessageBoxIcon::Warning);
	serialPort1->Close();
	label10->Text = String::Concat("Version check failed.\nYou need Arduino code version " + ver_ss + "!");
	Cursor = System::Windows::Forms::Cursors::Default;
} else if (gesplitted[1] != System::Convert::ToString(o_module)) {
        MessageBox::Show("Your selected TM1638 module: " + o_module + " is not compatible with your arduino code. Please setup for " + gesplitted[1] + " module.",
	"Connection error", MessageBoxButtons::OK,
	MessageBoxIcon::Warning);
	serialPort1->Close();
	Cursor = System::Windows::Forms::Cursors::Default;
	label10->Text = String::Concat("Version check failed.\nPlease setup for " + gesplitted[1] + " module.");
} else {

//connected

}

Am besten du schließt deine Kommandos mit einem CR/LF ab. Da kannst du einfach WriteLine() machen. Und liest dann ein bis ein LF kommt. Format() ist da so oder so überflüssig.

Außerdem kann man auf die String Klasse auf dem Arduino völlig verzichten. Selbst wenn, dann gibt es dafür startsWith() ohne den Umweg über subString()

Dann lass dir auch mal den empfangenen String ausgeben damit du siehst ob du auch wirklich dass empfängst was du denkst.

const char BUFFER_SIZE = 30;
char serial_buffer[BUFFER_SIZE];

void setup()
{
  Serial.begin(38400);
}

void loop()
{
  if (read_serial())
  {
    Serial.println(serial_buffer);

    if (strncmp_P(serial_buffer, PSTR("VER"), 3) == 0)
      Serial.println(F("ok"));
    else
      Serial.println(F("not ok"));
  }
}

bool read_serial()
{
  static byte index;

  while (Serial.available())
  {
    char c = Serial.read();

    if (c >= 32 && index < BUFFER_SIZE - 1)
    {
      serial_buffer[index++] = c;
    }
    else if (c == '\n' && index > 0)
    {
      serial_buffer[index] = '\0';
      index = 0;
      return true;
    }
  }
  return false;
}

Gibt “ok” aus wenn man “VERxxx” eingibt

strncmp() (string n compare) vergleicht die ersten n Zeichen. Hier in der _P Version die für den Vergleichs-String kein RAM belegt

Es gibt auch strcmp() um den kompletten String zu vergleichen

danke erstmal

aber mit deinem example kommt beim verbinden meiner software nichts zurück