Serial.read() behaviour is different from Arduino when empty

Serial1.read() does not return -1 when empty.

Not sure how to change this in the firmware.

Can someone confirm that serial1.read() (TX/RX) is working? i struggle with it for weeks now and about ten different code samples to get my UARTs running @4800 8 N 1 with no success.

That would explain a lot…

Also, Serial1.peek() does the same thing.

Editing to note that I am actually referring to USART2 i.e. Serial1.

I never receive data also, that may be part of the problem i.e. read not functioning.
I have checked that write works, no issues there. Reading is where my issues begin. I have confirmed that data is being sent to the RX port. However I get no data sent instead of unknown command every time.

Will do a basic loopback test and see if I get the value returned.

EDIT:
Loopback works fine, tested at 2Mbps without any glitches!
It may be part of the implementation where we go wrong. I will check the library I made and write all data out to the serial port and see what it is receiving.

Peek() needs to be implemented…

int USARTSerial::peek(void)
{
return -1;
}

Is how Peek() is currently implemented.

Serial is not 100% implemented yet unfortunately it seems.

@Mike43110: same to me: writing to the UARTS works, but reading NEVER works, to me it seems the buffer is not working, at least every 2nd byte gets lost.

@zach : return -1 , really funny, guys ! Can you confirm that Serial1.read is not working yet ? any plans to fix this ? i’m really frustrated with this. I tested it over and over again with different code, with osci, and my complete home automation plans stuck now for a month. Tell me a date, please, until this bug is fixed for the web IDE, I cannot wait another 4 weeks. and I definitely do not spend another 4 weeks on testing…

I haven’t tested high speed loops yet.

Slow single characters work fine, but I didn’t push it to the limit. Flush() is also not implemented.

Luckily the product only needs send for now and I am on site, but for now I won’t be using the spark for more than personal use until more optimisation has taken place.

I use DFU for flashing, and edited using VS then Eclipse. I had multiple errors involving read…
1stly that it doesn’t return -1 when empty (Haven’t checked what it does return). Then that flush doesn’t work correctly; this made that my commands were only being half sent before the direction pin was returned low. So none of my commands went through properly.

I even started using LEDs to debug by switching them at various places in the code!

It was really difficult seeing that the pin was going low too quickly! The flush code with a //TODO kinda gave it away :smiley:

If I have the time I will try a tight loop echo with a large string and see if they are the same each iteration.

I didn’t try the tight loop yet, I just discovered another potentially annoying thing.

Available returns 1 or 0, so if you are waiting for x number of packets, you have a bit of a problem as it only returns if there is any data currently available.

1 Like

@Mike43110 thanks for the update! I really appreciate your help while @zach isn’t reponding, I’m an absolute beginner to Arduino (did only VBA and other BASIC dialects before, and not able to analye the firmware code that fast). I only want to get 2 UARTs on the breadboard to run (if possible from the web IDE, but I’m ready and willing to go to offline IDE if there’s no other way), I wondering if something can be that difficult in the year 2014…

Hey Guys!

@zach has been traveling so he hasn’t been able to respond, but I can certainly jump in. Serial1 should work, but I know we have a feature request in the backlog for implementing a serial ring buffer so you don’t have to be as diligent about checking during the loop. I’m going to whip up a quick demo with two cores, be back in a few!

Thanks,
David

Hey Guys,

Here’s a basic Serial to Serial example I whipped up for y`all (running same program on both cores, also notice Serial1 is running at 4800 8N1):

byte bufferSize = 64;
byte bufferIndex = 0;
char buffer[65];
char c;

void setup() {
    Serial.begin(9600);
    Serial1.begin(4800);
}

void loop() {
    //reads from USB Serial, pipes to Serial1
    while (Serial.available()) {
        c = Serial.read();
        Serial1.write(c);
    }
    
    //reads from Serial1, pipes to USB Serial
    while (Serial1.available()) {
        c = Serial1.read();
        Serial.write(c);
        bufferIndex++;
        
        if ((bufferIndex >= bufferSize) || (c == (char)'\n')) {
            
            buffer[bufferIndex] = '\0';     //null terminate our string...
            Serial.write(buffer);
            Serial.write("\r\n");
            bufferIndex = 0;
        }
    }
}

Just as a proof of concept, it reads from USB serial, and sends it to hardware serial, where it’s read by the other core and piped to the usb serial output on the other one, here’s a picture of my terminal output (type in one, shows up on the other):

and here is a picture of the wiring on the cores:

1 Like

Can you try that for 1Mbps?

That’s the speed I will be using most probably.
I just am concerned with that code that should be a simple port from Arduino to Spark Core becomes a massive mission as the Core has half implemented functions or different behaviour to Arduino.

while(STATUS_FRAME_BUFFER >= Serial1.available())
where STATUS_FRAME_BUFFER = 5 doesn’t work as available returns 1 or 0.

The issue is that there is no method to return the number of bytes available in the buffer.

There is a link to the gist with the code in at the bottom. This code runs perfectly fine on Arduino but because the functions have been completely differently implemented / not implemented at all it just tells me that no data has been sent.

This is really frustrating as the write commands function correctly, it is just reading the status packets that is not functioning.

I have made the small loop which does work perfectly fine, with and without a level shifter for basic communications that has no reliance on the number of bytes available without an issue.
Reading the status packets however is a big issue. The data is being sent correctly, the function just has to be re-implemented using what is currently available.

Will the serial be changed to fit more with the wiring library in terms of available() giving out the total bytes on the buffer instead of just an HasData() or is it going to remain as is? Read also doesn’t return -1 when empty, unlike the Arduino platform.

It is confusing when the Wiring library functions differently on different platforms. I do hope that it isn’t a hardware limitation.

https://gist.github.com/Mike43110/c7885cdf5335d6573d99

Hi @Mike43110,

Totally, that kind of port shouldn’t be a massive mission. This library is still getting worked on, and it should more closely resemble what you would expect for Arduino libraries in the next sprint or two. If you didn’t want to wait, you could have a small receive buffer in your code and check that, but I realize that’s not ideal.

@Mike43110 @mf2105
At the time of releasing, we implemented an Arduino-like basic implementation of the serial for the :spark: Core. Ideally, we should have a ring buffer and make all the functions available. Like @Dave said, this will be on the task list for next sprint. But in the meantime, you can take a look at Maple’s implementation of Serial on an STM32 for reference: https://github.com/leaflabs/libmaple/blob/master/wirish/HardwareSerial.cpp

1 Like

Thanks!

I can get away with delaying the read functions for awhile. If it is necessary I can make do with something on my own :smiley:

Just was a little worried that it would be a long while before it would be available!

Will look at Maple’s implementation, should be a fun read.

1 Like