[Solved] Spark keep crashing when sending data through serial port

Hi All!

I am trying to control some function on Spark by sending some commands in C#.

Here is my code:

Spark:

void setup()
{
    pinMode(D7,OUTPUT);         // Turn on the D7 led so we know it's time
    digitalWrite(D7,HIGH);      // to open the Serial Terminal.
    Serial.begin(9600);         // Open serial over USB.
    while(!Serial.available())  // Wait here until the user presses ENTER 
      SPARK_WLAN_Loop();        // in the Serial Terminal. Call the BG Tasks
                                // while we are hanging around doing nothing.
  digitalWrite(D7,LOW); // Turn off the D7 led ... your serial is serializing!
}

void loop() {
    while (Serial.available() > 0) {
        Serial.println("asd");
      }
}

C#:

    private void button1_Click(object sender, EventArgs e)
    {
        dataUpdateTimer = new DispatcherTimer(DispatcherPriority.Normal);
        dataUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
        dataUpdateTimer.Tick += new EventHandler(dataUpdateTimer_Tick);
        dataUpdateTimer.Start();
    }

    private void dataUpdateTimer_Tick(object sender, EventArgs e)
    {
        serialPort.Write("abc");
    }

When button1 is clicked, the dataUpdateTimer will start and C# side will send a string(which is abc) per second.
And Spark side will return a string(which is asd) when received something from serial port.

But something strange happened.The data sent successful at first couple times and then crash
at some random point. Any idea?

Hi @abue172

I don’t see where you pick up the serial data from the host in your Spark code–you must be overflowing the serial buffer quite quickly. What happens if you add a Serial.read() call in your while loop?

You might still have problems if your code sends three characters for every one character it receives, but it shouldn’t overflow buffers quickly.

@bko is correct, you need to flush your read buffer. You could do that and implement an easy command tree like this:

void loop() {
    if (Serial.available()) {
        int c = Serial.read();
        switch (c) {
            case '1': Serial.println("command 1 received"); break;
            case '2': Serial.println("command 2 received"); break;
            default: Serial.println("bad command"); break;
        }
    }
}

Thanks for reply! @bko @BDub

I tried to add Serial.read() in my while loop and still crash.
And i also try to send one character each time and still the same.

Here is my modified code:

Spark:

void setup()
{
    pinMode(D7,OUTPUT);         // Turn on the D7 led so we know it's time
    digitalWrite(D7,HIGH);      // to open the Serial Terminal.
    Serial.begin(9600);         // Open serial over USB.
    while(!Serial.available())  // Wait here until the user presses ENTER 
      SPARK_WLAN_Loop();        // in the Serial Terminal. Call the BG Tasks
                                // while we are hanging around doing nothing.

  digitalWrite(D7,LOW); // Turn off the D7 led ... your serial is serializing!
}

void loop() {
    while (Serial.available() > 0) {
        int inChar = Serial.read();
    
    if (isDigit(inChar)) {
      // convert the incoming byte to a char 
      // and add it to the string:
      inString += (char)inChar; 
    }
    // if you get a newline, print the string,
    // then the string's value:
    if (inChar == '\n') {
      Serial.print("Value:");
      int ledIndexMax = inString.toInt();
      Serial.println(ledIndexMax);
      // clear the string for new input:
      inString = ""; 
    }
  }
}

C#

     //global variable
    int index_tmp = 0;

    private void button1_Click(object sender, EventArgs e)
    {
        dataUpdateTimer = new DispatcherTimer(DispatcherPriority.Normal);
        dataUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, 2000);
        dataUpdateTimer.Tick += new EventHandler(dataUpdateTimer_Tick);
        dataUpdateTimer.Start();
    }

    private void dataUpdateTimer_Tick(object sender, EventArgs e)
    {   
    	string command = pixelIndex.ToString();
        serialPort.WriteLine(command);
        
        pixelIndex++;
    }

The different between the code at first is i will detect the ‘\n’ in Spark and output the value which using
serial.Read().

And i changed the timer interval in C# from 1 sec to 2 sec but still crash.

@abue172 I’m not sure how you are defining inString, but hopefully the same way I did here. I got this working after I changed the \n to \r when using the screen in Mac terminal… when I hit enter it was just sending CR, not a NL. I haven’t seen it crash yet throwing lots of data at it.

#include "application.h"

String inString;

void setup()
{
    pinMode(D7,OUTPUT);         // Turn on the D7 led so we know it's time
    digitalWrite(D7,HIGH);      // to open the Serial Terminal.
    Serial.begin(9600);         // Open serial over USB.
    while(!Serial.available())  // Wait here until the user presses ENTER
      SPARK_WLAN_Loop();        // in the Serial Terminal. Call the BG Tasks
                                // while we are hanging around doing nothing.

  digitalWrite(D7,LOW); // Turn off the D7 led ... your serial is serializing!
}

void loop() {
    while (Serial.available() > 0) {
        int inChar = Serial.read();
        Serial.print("inChar: ");
        Serial.println(inChar);

    if (isDigit(inChar)) {
      // convert the incoming byte to a char
      // and add it to the string:
      inString += (char)inChar;
      Serial.print("inString: ");
      Serial.println(inString);
    }
    // if you get a newline, print the string,
    // then the string's value:
    if (inChar == '\r') {
      Serial.print("Value:");
      int ledIndexMax = inString.toInt();
      Serial.println(ledIndexMax);
      // clear the string for new input:
      inString = "";
    }
  }
}

1 Like

Thanks for reply! @BDub

I tried the code you provided.
In fact i just realized that C# serialPort.WriteLine() method maybe sending \r before \n,
and cause the crash.So i change the code into

//global variable
int pixelIndex= 0;

private void button1_Click(object sender, EventArgs e)
{
    dataUpdateTimer = new DispatcherTimer(DispatcherPriority.Normal);
    dataUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, 2000);
    dataUpdateTimer.Tick += new EventHandler(dataUpdateTimer_Tick);
    dataUpdateTimer.Start();
}

private void dataUpdateTimer_Tick(object sender, EventArgs e)
{   
    serialPort.Write(pixelIndex.ToString()+'\r');

    pixelIndex++;
}

The C# code is just keep sending 0,1,2,3…to Spark.
The Spark work perfectly until 260th , yes, it crashed again.
Then i tried it another time and it crash at 74th…

Is that necessary to clean up some input buffer at Spark?

Updated:
I found that even though i didn’t send command, Spark still crash(reboot) sometimes, So i changed another
micro-USB cable and BINGOOOOO!!! It work perfectly without any crashing or reboot so far!

It seems that maybe the old cable damaged inside which cant tell from outside.

Anyway,thank you for giving advide @bko @BDub!!!

Spark Rock!!!

1 Like