Go Down

Topic: Processingcode resetet ungewollt Arduino (Read 3142 times) previous topic - next topic

KUCKY

Hallo zusammen,
ich versuche mit einem ProcessingProg Daten an Arduino zu senden. Als Empfänger nehme ich den CMDMessenger.

Manuelle Eingabe über Serial-Monitor
z.B.: 5,20,20,20,20;
Die Motoren drehen sich. Alles OK.

Wenn ich aber mit diesem Code das Gleiche versuche....
Code: [Select]

void sendRotorSpeed(){
String s = null;
    portQuad.clear();
   
    s = String.valueOf("5,");
    for(int i = 0; i < 4; i++)
      {
        if(i < 3)
        s = s + Integer.toString(setRotorSpeed[i])+",";
        else
        s = s + Integer.toString(setRotorSpeed[i])+";";   
      }

    s = s + "\r";  Mit und ohne \r versucht
//    s = "5,20,20,20,20;";
    portQuad.write(s);
    portQuad.clear();
    print(s);
}


wir dieser Arduinocode...

Code: [Select]

void rotor_data(){
int seq;
double value;

    cmdMessenger.sendCmd(kACK,"Rotorspeed recieved");
    Serial.println("Rotor Data is here");

    for(seq = 0; cmdMessenger.available(); seq++)
    {
        char buf[100] = { '\0' };
        cmdMessenger.copyString(buf, 100);
        if(buf[0])       
          cmdMessenger.sendCmd(kACK, buf);

        value = atoi(buf);
        msgRotorSpeed[seq] = value;
    }
}


gar nicht erst aufgerufen. Stattdessen wird der Arduino resetet. Dadurch sind natürlich die gesendeten Daten weg.
Ich benutze einen Mega2560. Processing sendet über COM5. Ich kontolliere die Daten im Arduino mit einem BT über COM7 an Serial3.

Was mache ich falsch?

LG
Willi

pylon

Du hast nur Snippets gepostet, da könnte irgend was schiefgehen und wahrscheinlich ist es nicht einmal in diesen Zeilen. Ich tippe auf das Öffnen der seriellen Schnittstelle. Jedes Mal, wenn das geschieht, wird der Arduino geresettet, und das mit Absicht, denn so werden neue Sketches hochgeladen. Wenn Du also in Deiner Processing-App die serielle Schnittstelle am Anfang einmal öffnest, dann wird der Arduino nur beim Start der App resetten, danach kannst Du die Befehle schicken, ohne dass der Sketch gleich wieder von vorne beginnt.

Du kannst den Reset hardwaremässig (mit einem Kondensator) verhindern, aber das Hochladen von Sketches funktioniert dann nicht wie gewohnt.

KUCKY

Hey, Danke für die Antwort.
Das der Arduino beim Öffnen eines COM-Ports resetet wird, weiß ich. Aber wie finde ich in meinem Code die Zeile, an der das geschieht? Ich wollte keinen mit meinem gesamten Code langweilen. Ich versuche mal einen Testcode zu schreiben. Kann aber morgen werden.

Liebe Grüße aus Leverkusen
Willi


KUCKY

Hat mir keine Ruhe gelassen, wenn mir schon jemand helfen möchte.

Leicht angepasster CMDMessenger. Einfügen einer LED als Indikator.

Code: [Select]

#include <CmdMessenger.h>
#include <Base64.h>
#include <Streaming.h>

char field_separator = ',';
char command_separator = ';';

CmdMessenger cmdMessenger = CmdMessenger(Serial, field_separator, command_separator);

int speed[3];

enum
{
  kCOMM_ERROR    = 000, // Lets Arduino report serial port comm error back to the PC (only works for some comm errors)
  kACK           = 001, // Arduino acknowledges cmd was received
  kARDUINO_READY = 002, // After opening the comm port, send this cmd 02 from PC to check arduino is ready
  kERR           = 003, // Arduino reports badly formatted cmd, or cmd not recognised

  kSEND_CMDS_END, // Mustnt delete this line
};

messengerCallbackFunction messengerCallbacks[] =
{
  bens_msg,            // 004 in this example
  jerrys_base64_data,  // 005

  NULL
};

// ------------------ C A L L B A C K  M E T H O D S -------------------------------------------------------

void bens_msg()
{
  cmdMessenger.sendCmd(kACK,"bens cmd recieved");

  digitalWrite(40, HIGH);
  delay(2000);
  digitalWrite(40, LOW);

  while ( cmdMessenger.available() )
  {
    char buf[50] = { '\0' };
    cmdMessenger.copyString(buf, 50);
    if(buf[0])
      cmdMessenger.sendCmd(kACK, buf);
  }
}
//-----------------------------------------------------------------------------------------------------------
void jerrys_base64_data()
{
  char buf[350] = { '\0' };
  boolean data_msg_printed = false;
  cmdMessenger.sendCmd(kACK,"jerrys cmd recieved");

  // base64 decode
  while ( cmdMessenger.available() )
  {
    if(!data_msg_printed)
    {
      cmdMessenger.sendCmd(kACK, "what you send me, decoded base64...");
      data_msg_printed = true;
    }
    char buf[350] = { '\0' };
    cmdMessenger.copyString(buf, 350);
    if(buf[0])
    {
      char decode_buf[350] = { '\0' };
      base64_decode(decode_buf, buf, 350);
      cmdMessenger.sendCmd(kACK, decode_buf);
    }
  }

  // base64 encode
  if(!data_msg_printed)
  {
    cmdMessenger.sendCmd(kACK, "\"the bears are allright\" encoded in base64...");
    char base64_msg[350] = { '\0' };
    base64_encode(base64_msg, "the bears are allright", 22);
    cmdMessenger.sendCmd(kACK, base64_msg);
  }
}

// ------------------ D E F A U L T  C A L L B A C K S -----------------------

void arduino_ready()
{
  // In response to ping. We just send a throw-away Acknowledgement to say "im alive"
  cmdMessenger.sendCmd(kACK,"Arduino ready");
}

void unknownCmd()
{
  // Default response for unknown commands and corrupt messages
  cmdMessenger.sendCmd(kERR,"Unknown command");
}

// ------------------ E N D  C A L L B A C K  M E T H O D S ------------------

// ------------------ S E T U P ----------------------------------------------

void attach_callbacks(messengerCallbackFunction* callbacks)
{
  int i = 0;
  int offset = kSEND_CMDS_END;
  while(callbacks[i])
  {
    cmdMessenger.attach(offset+i, callbacks[i]);
    i++;
  }
}
//---------------------------------------------------------------------------------------------------------------------
void setup()
{
  // Listen on serial connection for messages from the pc
// Serial.begin(57600);  // Arduino Duemilanove, FTDI Serial
    Serial.begin(9600); // Arduino Uno, Mega, with AT8u2 USB

Serial.println("**************************");
Serial.println("*         Quad102        *");
Serial.print  ("*  ");Serial.print(__DATE__);Serial.print(" ");Serial.print(__TIME__);Serial.println("  *");
Serial.println("**************************");

Serial.flush();   

//  cmdMessenger.discard_LF_CR(); // Useful if your terminal appends CR/LF, and you wish to remove them
  cmdMessenger.print_LF_CR();   // Make output more readable whilst debugging in Arduino Serial Monitor
 
  // Attach default / generic callback methods
  cmdMessenger.attach(kARDUINO_READY, arduino_ready);
  cmdMessenger.attach(unknownCmd);

  // Attach my application's user-defined callback methods
  attach_callbacks(messengerCallbacks);

  arduino_ready();

  // blink
  pinMode(13, OUTPUT);
  pinMode(40, OUTPUT);
  digitalWrite(40, LOW);
}


// ------------------ M A I N ( ) --------------------------------------------

// Timeout handling
long timeoutInterval = 2000; // 2 seconds
long previousMillis = 0;
int counter = 0;

void timeout()
{
  // blink
  if (counter % 2)
    digitalWrite(13, HIGH);
  else
    digitalWrite(13, LOW);
  counter ++;


void loop()
{
  // Process incoming serial data, if any
  cmdMessenger.feedinSerialData();

  // handle timeout function, if any
  if (  millis() - previousMillis > timeoutInterval )
  {
    //timeout();
    previousMillis = millis();
  }

  // Loop.
}


Aus Processing kommen diese Versuche:

   s = "4,50,50,50,50;"; 

   portQuad.write(s);
oder
   //portQuad.write(convertStringToByteArray(s));

Keine Reaktion der LED

Bei der Eingabe von 4,50,50,50,50; über den SeriellMonitor alles OK und LED leuchtet 2sec.

Reichen diese Angaben?

LGW

pylon

Quote
Reichen diese Angaben?


Leider nicht, in diesem Fall sollten wir den Processing-Code haben. Wahrscheinlich liegt das Problem dort und nicht im Arduino-Code.

KUCKY

Hallo,
im Anhang findest Du das komplette Projekt. Interessant dürfte aber nur die "Cockpit01" sein. Hier muss, wie Du schon vermutet hast, der Fehler liegen. Ich habe es mit einem kleinen Processingcode versucht, und es funktioniert. Hier werden aber keine Listboxen für COM und Bautertare benutzt.
Bin Dir jetzt schon dankbar für die Hilfe.

LG
Willi

pylon

Code: [Select]
portQuad.write(s);
portQuad.clear();


Hier schreibst Du einen String auf die serielle Schnittstelle und löschst den Puffer danach gleich wieder. Die clear()-Method dürfte in Deinem Programm wenig Sinn machen, da Du ja sicher immer den ganzen String senden und nicht mittendrin abbrechen willst.

Hast Du kontrolliert, wie häufig InitSerial() aufgerufen wird? Bei jedem Aufruf wird der Arduino geresettet.

KUCKY

Guten Morgen,
werde ich heute Abend testen. Vielen Dank schon mal

LGW

TERWI

Ich mache so was (sehr) ähnliches mit dem normalen Messenger.
Der hätte gerne am Ende ein CR, damit er weiß, was Feierabend ist.
Kann sein, dass das an deinem Monitor so eingestellt ist - deine andere Soft müsste dann allerdings noch ein CR anhängen.
To young to die - never to old for rock'n roll

KUCKY

Das CR wird eigentlich automatisch gesendet. Um aber sicher zu sein, habe ich an den String mal ein '\r' angehangen. Auch kein Erfolg.

LGW

KUCKY

Ich traue mich kaum es zu sagen, aber das Problem ist gelöst.
Zuerst habe ich kontolliert, ob InitSerial auch wirklich nur einmal aufgerufen wird. JA.
Dann kam der Hinweis mit dem CR.
Also habe ich mir ein NullModem gebastelt, und ohne Aduino den Processingcode gestartet. Und siehe da, diese Zeile:

public void draw() {
  if ((millis() - interval > 1000) && isConnect)
  {
    portQuad.write("q\r"); <-----
    interval = millis();
  }
....
war der Grund. Auskommentiert, und alles OK.

Vielen Dank für eure Hilfe

LG
Willi

Go Up