7 years, 10 months ago.

Saving string from (RX,TX) to an array

Hello! I need help in saving a string data type coming from RS232 (RX,TX) to an array. I have tried the code below, it saves the input but the problem is that when you try to enter the same input again, the end character of your input becomes the first character and it stays that way. Please help me with this. Thank you.

#include "mbed.h"
 
Serial pc(USBTX, USBRX);
 
int main() {
    char command[8]; 
        
    while(1) {
        if (pc.readable()) {
            pc.gets(command, 8);
            for (int i=0; i<8; i++) {
                pc.printf("%x ", command[i]);
            }
            pc.printf("\n");
        }
    }
}

Can you give example inputs and outputs? There can sometimes be issues with gets() detecting the ends of strings.

posted by Andy A 13 May 2016

This is an example output of the code:

Sent: 5/17/2016 1:33:43 PM abcdefg

Received: 5/17/2016 1:33:43 PM 61 62 63 64 65 66 67 0

Sent: 5/17/2016 1:33:44 PM abcdefg

Received: 5/17/2016 1:33:44 PM d 61 62 63 64 65 66 0

Sent: 5/17/2016 1:33:47 PM abcdefg

Received: 5/17/2016 1:33:47 PM 67 61 62 63 64 65 66 0

Sent: 5/17/2016 1:33:50 PM abcdefg

Received: 5/17/2016 1:33:50 PM 67 61 62 63 64 65 66 0

posted by Jas Y 17 May 2016

4 Answers

7 years, 10 months ago.

Hello Jas,
Another alternative is to use scanf function:

#include "mbed.h"
 
 
int main() {Serial pc(USBTX, USBRX);

    volatile char command[8]; 
        
    while(1) {
        pc.scanf("%s", command);
        pc.printf("%s\r\n", command);
    }
}

The scanf function will read (wait for) subsequent characters until a whitespace is found (whitespace characters are considered to be blank, newline and tab). Make sure the length of string passed over the serial connection does not exceed the length of command array.

Hello Jas,
Yes, scanf shall work with any available (valid) Serial device. And I also agree with Oliver that one should prevent exceeding the array by specifying the maximum number of characters to be read in one reading operation.

#include "mbed.h"
 
Serial pc(USBTX, USBRX);
Serial device(PA_9, PA_10);
 
int main() {
    volatile char command[8]; 
        
    while(1) {
        device.scanf("%7s", command);
        pc.printf("%s\r\n", command);
    }
}

Accepted Answer

If I understand correctly you can (and should) qualify %s with a length argument like %7s to prevent exceeding the array.

posted by Oliver Broad 18 May 2016

Will this work if the data is coming from a serial device?

Serial device(PA_9,PA_10);

posted by Jas Y 24 May 2016

Yes, if it is "Serial" it will support scanf.

It should work for any "streams" based input device. For example it works on Serial but not RawSerial.

posted by Oliver Broad 24 May 2016

Do you happen to know how to do a simple serial interrupt? Because I need to activate a sensor when a pin goes high? Thank you.

posted by Jas Y 30 May 2016

Jas do you mean you want the program to continue running while it is receiving serial data?

posted by Oliver Broad 30 May 2016

No. The operation of my program is that it continuously monitors if a pin is set to high, which will then trigger the alarm.

Another is remote configuration where the command is received via serial data.

posted by Jas Y 30 May 2016
7 years, 10 months ago.

...

7 years, 10 months ago.

Try something like that by attach below code as interrupt to USART. It reads incoming bytes until carriage return and works for my communication.

void rf_rx_isr()
{
    node.rf_buffer_char = nodeRF.getc();
    if (node.rf_buffer_char != '\r') {
        node.rfRxBuffer[node.rfRxBufferCounter] = node.rf_buffer_char;
        node.rfRxBufferCounter++;
    } else if (node.rf_buffer_char == '\r') {
        nodeRF.attach(NULL, Serial::RxIrq);
        node.rfRxBufferCounter = 0;
        node.rfInterruptComplete = true;
    }
}

7 years, 10 months ago.

As to the initial question: "gets" with a size parameter is really "fgets", and the reason for the character hanging over is that it is waiting for and returning seven characters. abcdefg fulfils this so the "CR" was queued till the next line. I wondered why I could press Enter seven times and get d d d d d d d 0 but then I realised it is probably waiting for a newline, 0A, and putty sends 0D.

I think you will have to pull characters one by one using "getc" but whether you actually need an ISR is up to you, a "while" loop may do it.