Sending from Serial1 to Serial [SOLVED]

Hi

I need help because I think there is something I am missing.

I am trying to connect Spark Core to a Cycle Analyst which every second at 9600 baud rate sends a tab deliminated ASCII text like: 3.296 47.62 10.04 15.32 8.9132

So I use Shield Shield for logic level conversion 5 V to 3,3 and connected Cycle Analyst to D0 and D1 on Shield Shield (Serial 1) and send result to Serial for debug.

But I can not get a values like above. When I use Serial.write() I get some strange letters and if I use Serial.print() I receive a lot of numbers like: 254004800254001280019200025219200000192

Is it someone who can help with my code?

// EXAMPLE USAGE
void setup()
{
  Serial.begin(57600);   // open serial over USB
  // On Windows it will be necessary to implement the following line:
  // Make sure your Serial Terminal app is closed before powering your Core
  // Now open your Serial Terminal, and hit any key to continue!
  while(!Serial.available()) SPARK_WLAN_Loop();
  Serial1.begin(9600);  // open serial over TX and RX pins
}

void loop()
{
  // read from port 1, send to port 0:
  if (Serial1.available())
  {
      Serial.print(Serial1.read());
  }
}

Hi @zerous

The Serial1 serial port on Spark is on the dedicated TX/RX pins, not on D0, D1 (that’s Serial2) so either your wiring or your code needs to change depending on which way you want to go.

http://docs.spark.io/firmware/#communication-serial

Yes, but I am using Shied Shield. As I understand it Serial1 is D0 and D1 on the shield according to Pin mapping

Arduino pin Spark Core pin
D0 RX
D1 TX

It is two top right pins on the picture marked with TX and RX.

That is a bit confusing. On the Core pins D0/D1 are as @bko said not the RX/TX pins for Serial1, but the Shield shield has got the Arduion pin names 0/1 (no D there) and they are in fact connected to RX/TX.

But that does not seem to be the problem.
Have you tested if you do get the correct string on you PC when you only do Serial.println("This will test the functionality of Serial"); after your while() in setup()?
Next thing to test might be, if the port settins for Serial1 actually fit your data source (parity, start/stop bits - double check baud rate).

I guess you have double/tripple/… checked your wiring :wink:

Hi

Serial.println("This will test the functionality of Serial");
float a = 1.33;
float b = 0.0001;
Serial.println(a);
Serial.println(b);
 
String str = "3.81\t2.65\t0.0\n";
Serial.println(str);

seems to work well...

This will test the functionality of Serial
1.33
0.00
3.81 2.65 0.0

Serial.read returns a int, can it be something with how it read Serial1? I tryed with

Serial.print((char)Serial1.read());

and get a lot of letters and spaces like "Á" (ASCII 193).

Serial checked OK, so one variable is out of the equation (question).

I think the way how you read Serial1 is fine, but you might want to read more bytes at a time

  while(Serial1.available())
    Serial.write((char)Serial1.read());  // write does no fancy stuff like print might
  Serial.println();                      // to 'see' how many bytes we get at a time 

You could also check if your way of reading works, by sending some defined string into Serial1 from Serial2 :wink:
Connect the Core D1 to the Core TX and the Core D0 to Core RX.

This way you can keep the “unkown” behaviour of your other hardware out of the picture, too.

Try this one out.. it works for my fingerprint reader.. it took some mucking around to find code that worked.. Black Magic trial and error stuff

1 Like

So, now i have tested to connect Serial2 to Serial1 and to read Serial1 to Serial.

USARTSerial Serial2(&USART_MAP[USART_D1_D0]);
   String str = "3.81\t2.65\t0.0\n";

void setup()
{
  Serial.begin(57600);   // open serial over USB

  while(!Serial.available()) SPARK_WLAN_Loop();

  Serial1.begin(9600);  // open serial over TX and RX pins
  Serial2.begin(9600);

}

void loop()
{
    Serial2.print(str);
    // read from Serial1, send to Serial
    if (Serial1.available())
    {
        Serial.write(Serial1.read());
    }
}

And i get following in Putty

3.81 2.65 0.0
3.81 2.65 0.0
3.81 2.65 0.0
3.81 2.65 0.0
3.81 2.65 0 .0
322222222222222222222222222222222222222222222222222222222222222222222222222222

I seems thar Serial1.read do not remove read byte from buffer, after a while it gets full and i get same number 2 all the time.

Any solutions for that?

Looking at the source of USARTSerial::read it seems that the circular buffer position _rx_buffer.tail is correctly moved forward on each read. Could you check the exact amount of bytes that you receive before it repeats and if the behaviour is reproducible every time after the same amount of bytes got read? Maybe(!) an issue in the interrupt handler that fills the buffer and increments the buffer position?

As said before, it might be better to read all available data each time round in loop().

In your example you stuff 14 byte into the 64 byte buffer, but only pull one out at a time. This must end up in a buffer overflow.

2 Likes

Hum.. his 14 bytes arrive every 1000ms, the loop will run 'a bit' more often in the meanwhile. Though IMHO pulling them all out of the buffer at once is a good coding pattern.

Actually when looking at the store_char function which get inlined into the interrupt handler USART_Interrupt_Handler, a buffer overrun can't happen. If the _rx_buffer's new circular storage pointer would point to the current reading pointer (-> buffer is "full"), the incoming byte would just be discarded.

arrr, looked at the original example - @ScruffR, you were totally right with the reading<>writing imbalance :blush:

I think @ScruffR 's point is that every time around loop(), we are writing 14 chars to Serial2 and reading 1 char from Serial1 at the same baud rate, so buffer overflow is inevitable. If you change the

if (Serial1.available())

to

while (Serial1.available())

it will work a lot better.

1 Like

@rastapasta, I've seen that you noticed the difference with the Serial2-Serial1 test, but even with the original 1000ms cycle, you might run into troubles, because the loop() is not executed as often/rapidly on a Core as it would be on an Arduino, since the Spark cloud management does take its time.

I think to recall that at one time the average execution periode for loop was 5ms (200Hz).

So for a 1000ms cycle and 30byte (in original post), this would work, but with, lets say 250ms and 50byte (not too much of a difference), you might run into problems - and this would be hell of a problem to pin down.
Sometimes it works, sometimes not - depending on the cloud, WiFi, slightly varying string length (one byte more :frowning: one byte less :smiley:), ...

Best to get it all read at once, rather than hoping it'll do :wink:

2 Likes

That's sooo good to know, big thanks(!) for the info! Didn't expect the huge difference to the Arduino and just recently switched and started Spark'ing without a scenario yet where the frequency would have mattered.

Searched a bit and found the thread about the topic, in case other newcomers are interested as well :wink:

love + light :sunny:

1 Like

In connection with this, you’d also like to see this
http://community.spark.io/t/new-feature-control-your-connection/6282

This new feature gives you more control over the cloud, during time critical sections of your project.


But I think this has little to do with @zerous original problem - didn’t want to hijack :blush:

1 Like

Thank you.

Change from If to while solved my problem. Now everything is working well and I receive right string

3 Likes

Good to hear!

@zerous, could you please alter the title to “Sending from Serial1 to Serial [SOLVED]”?

1 Like