Community
cancel
Showing results for 
Search instead for 
Did you mean: 
ABols
New Contributor I
1,909 Views

Multiple 0xFF returned after every transmission

I'm using an Intel Edison for Arduino Board and the code for it is written in C++ using the Intel System Studio IOT Edition.

I use mraa library functions (libmraa) to transmit and to read data to/from a device through the UART.

The issue I'm facing is this: after every transmission through the UART (from Edison to the device), my following attempt to read data from the device results in a certain amount of 0xFF bytes after which I eventually receive the stuff I was expecting.

If I carry out sequential reads one after another, the incoming data is received properly but once I transmit (write) something, a following read will bring me a bunch of these dubious 0xFFs.

The device that I'm communicating with is not responsible for these bytes, it doesn't send them.

So where might they be coming from? And how can I get rid of them?

0 Kudos
25 Replies
idata
Community Manager
421 Views

Hi Cyrillicsoft,

 

 

Thanks for your interest in the Intel® Edison platform.

 

 

It is a strange behavior and we would like to know if you have checked the RX and TX signals using a logic analyzer or oscilloscope in order to know how those signals are behaving while you are writing and reading data from your Edison to your device. Doing that will help us in troubleshooting this issue.

 

 

Regards,

 

-Yermi A.

 

ABols
New Contributor I
421 Views

Hi Yermi!

I do have what you need for the input to Edison (RX) from the device I'm working with.

I have no issues with the transmission itself.

This effect of receiving a sequence of 0xFF for a read, executed after a write, only occurs when I work with a specific device (namely, a Nextion display).

It's important to note that Nextion does not send these strange bytes and they are not on the wire (see diagram).

I should also mention that this device emits a HIGH signal in idle mode.

It might be worth mentioning that when I start a program on Edison, I get a 0xFC byte on the TX of UART0.

Also, upon initializing any GPIO port, I likewise get a 0xFC byte on the TX of UART0. The initialization is done with the mraa_gpio_init() function of the mraa library.

FerryT
Valued Contributor I
421 Views

cyrillicsoft it's coming back to me now. I think we had the problem when we were building with the sdk, which links to mraa 0.7.2. We fixed that by overriding the initialization in main.c by the code in hs_serial.c see https://github.com/htot/hs_uart GitHub - htot/hs_uart .

I think I read that this has been fixed in later versions of mraa. But instead I will be working to remove the dependency on mraa, so that this code will run on vanilla kernels as worked on by Andy Shevshenko https://github.com/andy-shev/linux/tree/eds GitHub - andy-shev/linux at eds

FerryT
Valued Contributor I
421 Views

I think we may have seen something like that too (on the oscilloscope too). Have you tried powering off the edison and then back on (If I remember correct pressing the reset button was not enough).

idata
Community Manager
421 Views

Hi Cyrillicsoft,

Thanks for the information provided. We would like to investigate a little bit more and as soon as we have useful information we'll let you know. We'll appreciate your patience during the meantime.

Additionally, Could you please try FerryT's suggestions and keep us abreast of your results?

Regards,

 

-Yermi A.
ABols
New Contributor I
421 Views

What FerryT has suggested is more or less what the "Using MRAA to Abstract Platform I/O Capabilities" book describes (this is a book by Integrated Computer Solutions, ics.com). I have already tried realizing this but it didn't help.

I found it a bit strange that the book recommended using the C read and write functions while working with the UART and not mraa_uart_read and mraa_uart_write functions...

Nevertheless, I took hs_serial.c and used it to initialize the UART port. But nothing changed.

I should reiterate the strange behavior I have been getting:

If I make sequential reads off RX, then all the data is read correctly.

If I transmit data through TX, then the following read will return a sequence of 0xFF followed by the expected data.

The amount of these 0xFF bytes is always a little larger than the amount of bytes I sent through TX. For example, the write sends 42 bytes and the read immediately after that returns 47 bytes. Moreover, I cannot see any mathematical dependency.

In addition, I find it strange that I would receive a 0xFC on TX after starting a program and after every mraa_gpio_init() call.

FerryT
Valued Contributor I
421 Views

cyrillicsoft It is not that I am recommending to use mraa, in fact I will try to remove mraa dependencies from my code as soon as I can.

We found that when using mraa 0.7.2 we had similar problems to yours: with tx looped back to rx, we were receiving many 0xFF chars, so many in fact that the received buffer overflows and eventually the Edison reboots (we were transmitting 2kB). BTW my colleague remembers it differently, he says the problems was caused *because* we were overflowing the tx buffer. Anyway, the 0xFF chars were actually transmitted and visible on the oscilloscope.

As we did not have that manually initializing the serial port, we fall back to the routine in hs_serial.c (and increased the tx output buffer in the kernel from 2kB to 4 kB).

BTW our https://github.com/htot/hs_uart GitHub - htot/hs_uart transmits data periodically and the period needs to be set longer than the time to actually send the data.

In most other protocols you would only transmit the next message after the receiver confirms reception. Or use XON/XOFF, or HW flow control.

Further:

mraa_uart_read does not do much special.

0xFC is probably generated by toggling the TRI_STATE_ALL signal (is controlled by GPIO 214). This is done when setting up gpio (but also during uart init). Then this triggers a UART start bit causing a spurious char reception. So you need to setup all io's uart etc, open the uart and flush the buffer. But not change pin configuration after that point.

ABols
New Contributor I
421 Views

My case is undoubtedly very similar to yours and I did find a software solution to it as I have done for the 0xFC issue which I handled just as you suggest.

Using XON/XOFF also solves all problems but it does demand that the device support the protocol.

Unfortunately, the Nextion display I'm working with does not have that capability and I really don't want to put it aside as it really simplifies the process of creating GUIs and works on just two wires.

The guys in China have sure made a very ingenious and handy device.

Concerning mraa, I didn't really choose it, it was recommended by Intel and since I've been familiar with it's products since '87, I've grown quite close to it. It would be upsetting if they do indeed disappoint...

I hold that it's easier to simply fix all of the weaknesses and flaws in mraa because there is nothing that you can't improve or correct. I hope Intel think likewise.

I'd also like to wait for Intel's reply on my issue.

FerryT
Valued Contributor I
421 Views

Have you tried upgrading mraa to a more recent version? I think the uart initialization problems have been solved in a later commit.

ABols
New Contributor I
421 Views

My version is 1.5.1. Intel considers this to be the most suitable for Intel System Studio IoT.

idata
Community Manager
421 Views

Hi Cyrillicsoft,

 

 

We would like to let you know that we are still working on it. Thanks for your patience.

 

 

Regards,

 

-Yermi A.

 

idata
Community Manager
421 Views

Hi Cyrillicsoft,

 

 

We did some tests using two Edisons and communicating them through the UART interface, the first Edison sent two messages to the second one and waited for a response, the second one received those messages and then sent the response to the first one. We checked the UART signals using a Logic analyzer and we have received the data successfully, we didn't receive any 0xFFs.

This is the code we used: https://github.com/intel-iot-devkit/mraa/blob/master/examples/python/uart_sender.py uart_sender.py and https://github.com/intel-iot-devkit/mraa/blob/master/examples/python/uart_receiver.py uart_receiver.py, we know that you are using C++ and in this code we are using Python, however, you could use them to test your Edison's UART to discard any issues. Additionally, you can use that code as a reference to write your C++ code.

 

 

Regards,

 

-Yermi A.

 

FerryT
Valued Contributor I
421 Views

You might want to try doing the same with a message length > 2048 bytes (that is in one write).

ABols
New Contributor I
421 Views

Thanks for the time that you have put aside to help me.

Of course, there is no difference whether I use Python or C++ because everything is eventually carried out by the OS.

Your tests were always going to be successful because if they weren't, you'd have been flooded with questions similar to mine from other users about a faulty UART.

My question was about Edison's behavior in a special case i.e. when it communicates with a Nextion display unit. In other words, these 0xFF bytes don't appear in ANY case you can think of, but in my specific setup (and maybe there are other possibilities).

Obviously, you might not be able to check Edison's behavior with this device, I wasn't hoping that you would try to go to such lengths. I thought that just by describing my issue, using your experience, you might be able to advise me on what to do next and where the issue might possibly lie.

If there are no concrete ideas, I'd like to ask this: what signal does Edison expect to receive while in idle mode? HIGH or LOW?

idata
Community Manager
421 Views

Hi Cyrillicsoft,

 

 

The Edison in idle mode is in HIGH and to start the transfer of data, it pulls the transmission line from high to low, also you can take a look at the http://download.intel.com/support/edison/sb/edisonmodule_hg_331189004.pdf Intel® Edison Compute Module Hardware Guide for extra details about the Edison's UART.

 

 

Additionally, I was looking at the https://www.itead.cc/wiki/Nextion_Instruction_Set Nextion Instruction Set, and it mentions that the return data is ended with three bytes of "0xff 0xff 0xff", so I believe that the 0xFF bytes you are receiving are coming from the return data.

 

 

Regards,

 

-Yermi A.

 

ABols
New Contributor I
421 Views

Thanks for your reply.

Concerning the 3 0xff Nextion return bytes, I know all about them but my case has nothing to do with it (moreover, I have purposefully restricted Nextion from sending them, which is something you can do).

Before seeking help on this forum, I had a lengthy discussion with the guys at ITEAD Studio (http://support.iteadstudio.com/support/discussions/topics/11000011825 Multiple 0xFF returned after every transmission : ITEAD Studio ) which ended in them mentioning this:

"Now as seen in the Edison Module electrical characteristics, this is high on idle (TTL) and matches Nextion's TTL high on idle nature. But once again this is for something that is NOT the Arduino board for Edison - which is why I asked if there was any hardware chips identified on the Arduino board as they could indeed interfere with this nature provided by the Edison Module when such hardware exists between the Edison module connector pins and the final pins you are using for your D0/D1."

I'll resume my conversation with them although I doubt I'll be able to get anything helpful now that we've hit a dead end.

Nevertheless if you do come up with any ideas, then I'll be much obliged if you let me know.

Thanks a lot for your kind cooperation!

FerryT
Valued Contributor I
421 Views

I had a look at your logic analyzer diagram. I am noting the following:

- transmitting 20 char takes 1.73ms, so it appears you are transmitting on 115k2, with 8bits, no parity, 1 stop bit

- you are receiving 1.5 stop bit (this is not a problem)

- at t = 1.38645 you are transmitting a glitch

- at t = 1.38663 you are transmitting another glitch

In my experience the edison has strange bugs in some cases, but I have not seen UART transmit glitches before. This might be caused by some reinitialization mid message that you did not intend. However, what is really worrying is that the slave device starts transmitting exactly on this glitch. So the device chokes on the glitch. Or, the glitch is caused by the slave device starting transmit? In this case you might have wiring problems, xtalk or ground bouncing. The logic analyzer is not an oscilloscope, so it might be hiding some analog signal problems from you.

Also, I don't know the protocol, but as I understand you are clearing the device with initially 3 FF's, then sending a command 0x70 followed by some bytes. Then further followed by 3 FF's, I guess the latter are required by the protocol? Then another 3 FF's with the glitch on the first FF and 3rd. Then another 0x70 command.

As i ran through the discussion with Nextion you ref'ed I noted they mention sending 3 FF's only initially to clear their input buffer. I would also flush the Edison's receive buffer at this point. Then send the command string. From then on I would wait after transmission for their reply before transmitting the next command. This will prevent overflowing the slaves input buffer, but also overflowing the Edison's output buffer (this will happen quickly, because the transmit buffer is not very large and the Edison is *really* fast compared to an ordinary MCU). And as I said before, we had strange things happening when overflowing the transmit buffer. Including automatically rebooting :-)

Take into account this: the Edison UART has a FIFO and DMA. This means receiving data goes automatic, without latency. However, these mechanisms are fairly dumb. DMA does not really know when a message terminated. But it needs to know to interrupt the cpu to signal the message is received and to allow the cpu to reprogram the next DMA. So there is a timeout (that we can't control). When you use https://iotdk.intel.com/docs/master/mraa/uart_8h.html# ad2af2d73b6342f9c3e049775bb8e93a1 mraa_uart_data_available and it is true, that means this timeout occurred and all the received bytes are in the receive buffer. (i my code you will see we find out how many bytes are available really and read them all at once in a single read). We have noted that from all the bytes received, the short time out, to https://iotdk.intel.com/docs/master/mraa/uart_8h.html# ad2af2d73b6342f9c3e049775bb8e93a1 mraa_uart_data_available == true can take a few msec. (In my code we are communicating at 2Mb/s, so a few msec. delay is really killing our communication performance, we switched to a preempt_rt kernel do reduce these delays to < 1 msec.)

You might want to share your code so we can have a quick look where the problem might be?

ABols
New Contributor I
421 Views

Hi Ferry!

I'm sorry I missed your answer and have just noticed it.

I did think about grounding problems... I've sent you the schematics of my setup, maybe there's some obvious, common issue that I just don't see.

Concerning the problem itself, I think I didn't give that clear of a description so I'll try to do it again:

I'm using a Nextion display which is connected to Edison for Arduino by the UART. If Nextion is turned on while the program loads onto Edison, then it immediately receives 0xFC before the program even executes and then it receives another 0xFC for every GPIO port I open (I open all of them at the beginning of the program using the https://iotdk.intel.com/docs/master/mraa/uart_8h.html# a680f83b9839d6ab983e8cbe3f706c242 mraa_uart_init function).

These few 0xFC are interpreted as errors by Nextion since it doesn't have commands that match the code. To make it handle these errors, I need to send 3 0xFF bytes, seeing how they are interpreted as an end-of-transmission sequence.

Following this, Nextion is ready to receive and execute new commands.

After this, I get that strange behavior:

If I receive data from Nextion, it is stored with no errors, regardless of the amount of transmissions.

If I transmit something TO Nextion, it receives it with no errors.

Now, if Nextion sends me data after my transmission to it, the received data will be preceded by a random amount of 0xFF bytes (the amount of 0xFF bytes is proportional to the length of my transmission to Nextion).

Following this strange message, Nextion will return to sending normal data until I transmit something to it again.

What you've described above sounds like that behavior must occur constantly and it doesn't quite fit my description where my transmissions and reception function normally and the glitch occurs just once when I receive something immediately after a transmission.

Do you have any ideas on the issue?

FerryT
Valued Contributor I
421 Views

I don't see any connection problem either.

So what you're saying is that:

1) the logic analyzer signal from post # 3 is correct and what you expect

2) the Nextion return the data you expect (0x1A 0xFF 0xFF 0xFF)

3) the Edison is receiving 0xFF .... 0xFF 0x1A 0xFF 0xFF 0xFF

So that might mean the Edison receive buffer already contained bytes before you started transmitting (need to flush the receive before, before you transmit). Or spikes reach the Edison that but are not generated by the Nextion.

Now the suspicious thing is:

1) when you transmit there are 2 negative spikes that I am sure you are not generating on purpose

- at t = 1.38645

- at t = 1.38663

This means the Edison TX is not generating these but they are picked up by the logic analyzer ( so generated between the uart and the edison boards TX header)

2) after you transmit your message you terminate it with 3 0xFF's, but then continue with 3 0xFF and the next message, before even having received the Nextions reply. It looks like you are in a loop that reinitializes the UART and possibly the GPIO, causing the spike on TX and possibly garbage in the RX buffer. Just guessing.

You might want to post the code of your loop?

ABols
New Contributor I
232 Views

Hi Ferry!

Thanks for your reply. Again, apologies for being vague: the logical analyzer diagram has nothing to do with my work and it wasn't me who made it.

It was sent to me by the guys from ITEAD to illustrate how the display works and what I can expect from it. I myself don't have any equipment to measure and record such things, unfortunately.

Nevertheless, there is still no explanation for the OS sending a questionable 0xFC on the UART. It is in no way connected to the display or my program, which has yet to begin executing at that point.

Concerning my exchange with the Nextion display, I have deactivated any sort of protocol that the Nextion guys programmed into the thing: Nextion does NOT send me a 0x1A 0xFF... sequence to notify me of an error.

It ignores any sort of error. Everything that Nextion sends me is either a 4-byte word or sequence of 4-byte words that do not end in 0xFF bytes (this can be done using their 'printh' command).

My program running on the Nextion sends me data only when I expect it to and never otherwise. Any data it receives is aligned by 4 bytes (this is my own exchange protocol with Nextion).

Thus, Nextion must not and does not send me any 0xFF bytes and if I do encounter any, I simply delete them. My 'end-of-transmission flag' is when I receive all of the data that I have been expecting.

So concerning this loop you described, there is definitely no port re-initialization. Initialization occurs once at the beginning of the program's execution. The following transmission can be seen in the code that I've included.

Concerning emptying the read buffer, I can't quite think of a way to do it using the mraa library that I use.

The only thing remotely close to emptying anything that mraa provides is the mraa_uart_flush function which flushes the OUTBOUND buffer...

I'll be much obliged if you find any error in my code!

/*******

Read or Transmit with UART

 

I:

 

numprob - number of sensor in Equipment (0..)

 

com - command

 

= READ (0) - read from RX line

 

= WRITE (1) - write to TX line

 

O:

 

= 0 - OK

 

= 1 - Error in parameters

EQ.probeCB[numprob]->error_code = 0 - OK

 

EQ.probeCB[numprob]->flag_manage - if Error

 

*EQ.probeCB[numprob]->uart_cb->uart_RX_rlen - length of bytes which have been read

 

if = -1 - Error

 

*EQ.probeCB[numprob]->uart_cb->uart_TX_rlen - length of bytes which have been written

 

if = -1 - Error

********/

int sensor_uart (unsigned int numprob, unsigned int com){

 

if (com == READ && (EQ.probeCB[numprob]->uart_cb->uart_RX_adr == 0 || EQ.probeCB[numprob]->uart_cb->uart_RX_len == 0)){return (1);}

 

if (com == WRITE && (EQ.probeCB[numprob]->uart_cb->uart_TX_adr == 0 || EQ.probeCB[numprob]->uart_cb->uart_TX_len == 0)){return (1);}

 

if((EQ.probeCB[numprob<span ...

Reply