Simple serial echo program help

25 Apr 2011

Hey everyone. I am in the process of making a little echo program to echo back whatever ir receives over serial connection. I have another microcontroller hooked up to an LCD and printing whatever it receives to LCD. So far I have sent "Hello world to this other microcontroller and had it printed to the LCD. I am now trying to send "Hello to you" to the mbed, have it wait a second, then send back the message to be displayed on the LCD. Any ideas whats going wrong with my code?

#include "mbed.h"

DigitalOut sendled(LED1);
DigitalOut recieveled(LED2);
DigitalIn button(p8);
Serial device(p9, p10);  // tx, rx
const char message[]="";


int main() {

    device.baud(19200);

    while (1) {

        if (device.readable()) {
        
            device.scanf("%s",&message);
            wait(1);
            device.printf("%s", &message);
        }

        if (button==1) {
            device.printf("Hello World");
            wait(2);
        }

    }

}
25 Apr 2011

A few errors in this that I can notice.

1) Your array message is being declared with length 0. It is being statically sized so it cannot allocate more memory if necessary.
2) When using scanf() for a string, you only need to supply the name of the array, as the name itself is a pointer to the first element.
3) When printing a char array, again you only need to supply the name of the array.

The code should look something like this

#include "mbed.h"

DigitalOut sendled(LED1);
DigitalOut recieveled(LED2);
DigitalIn button(p8);
Serial device(p9, p10);  // tx, rx
const char message[10];                        //10 represents the maximum amount of chars including a null character which can be in the array, adjust to suit the input


int main() {

    device.baud(19200);

    while (1) {

        if (device.readable()) {
        
            device.scanf("%s",message);
            wait(1);
            device.printf("%s", message);
        }

        if (button==1) {
            device.printf("Hello World");
            wait(2);
        }

    }

}

Hope that helps!
Rob

25 Apr 2011

I thought that I was supposed to be able to do it like that. The thing is I've tried to do exactly that and allocate memory when I declare the variable because I was sure that it was what needed to be done. The problem with this is when I try to compile it says that it requires an initializer... not sure what it wants from me lol

25 Apr 2011

Try looking at MODSERIAL. It extends the Serial object and has a more useful API for handling messages. See also the MODSERIAL cookbook page. The end of that cookbook page has a section called "Delineating 'packets'" which in your case could also be "messages" rather than packets.

25 Apr 2011

I don't think you should declare the array message[10] as a const given that scanf() will write to it.

On seeing the const keyword the compiler could locate the array in the code area (i.e. Flash) instead of the data area (i.e. RAM).

25 Apr 2011

Hey again,

Paul you were definatly right about the const getting in the way. I am used to writing web languages and wiring so declaring types of values is something still a little foreign to me. Thank you for the explanation. I did seem to get it working however I took a look at MODSERIAL like Andy suggested and it seems to be a really nice extension.... the "Delineating 'packets'" function is defiantly something I could use as I am merely trying to make the mbed a sort of master controller for several AVR µC's to be able to request that they check their sensors, gather the information to the mBed, and send off what needs to be displayed to another AVR that displays all the info nicely.

Now it's time to get to work trying to make this all fit together.

25 Apr 2011

Oops, didn't notice that "const", thanks for that Paul

25 Apr 2011

Andy K wrote:

Try looking at MODSERIAL. It extends the Serial object and has a more useful API for handling messages. See also the MODSERIAL cookbook page. The end of that cookbook page has a section called "Delineating 'packets'" which in your case could also be "messages" rather than packets.

Hey Andy! thanks for the suggestion. I do however have another question for you. So I have tried to implement your library as it is exactly what I'm looking for. my problem now is trying to access the rx buffer once the \n has been reached.

this is what I have:

#include "mbed.h"
#include "MODSERIAL.h"

DigitalOut sendled(LED1);
DigitalOut recieveled(LED2);
DigitalOut availa(LED4);
DigitalIn button(p8);
MODSERIAL arduino(p9, p10);

bool newline_detected = false;
// Called everytime a new character goes into
// the RX buffer. Test that character for \n
// Note, rxGetLastChar() gets the last char that
// we received but it does NOT remove it from
// the RX buffer.
void rxCallback(MODSERIAL_IRQ_INFO *q) {
    MODSERIAL *serial = q->serial;
    if ( serial->rxGetLastChar() == '\n') {
        newline_detected = true;
    }
}


int main() {

    arduino.baud(9600);
    arduino.attach(&rxCallback, MODSERIAL::RxIrq);

    // Wait here until we detect the \n going into the buffer.
    while (! newline_detected );  
    recieveled=1;
    // When we get here the RX buffer now contains a NMEA sentence.
    // ...
                arduino.printf("%s", MODSERIAL::RxIrq);


        if (button==1) {
            arduino.printf("From mBed");
            wait(2);
        }

    

}

and my arduino (which is what I'm using for now) I have a simple code to start serial at 9600 and a quick Serial.write("123456789 \n"); in the setup stage. My terminal shows that the message is being sent and I put in a sort of tracker in the code that after it detects the newline it lights up an led.... unfortunately the LED does not light up. I'm not sure if I am interpreting the concept improperly or not and I'm not so sure that my printf is going to send whats in the rx buffer as I cant see if that is the correct way to call up what is in the buffer.

Any insights would be appreciated.

25 Apr 2011

Not quite right. Once you get the \n you need to read the buffer. for example

#include "mbed.h"
#include "MODSERIAL.h"

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

MODSERIAL arduino(p9, p10);

bool newline_detected = false;

void rxCallback(MODSERIAL_IRQ_INFO *q) {
    MODSERIAL *serial = q->serial;
    if ( serial->rxGetLastChar() == '\n') {
        newline_detected = true;
    }
}


int main() {

    arduino.baud(9600);
    arduino.attach(&rxCallback, MODSERIAL::RxIrq);

    while(1) {
  
        if (newline_detected) {
            newline_detected = false;
            char c = arduino.getc();
            switch (c) {
                case '1': led1 = !led1; break; // Toggle LED1
                case '2': led2 = !led2; break; // Toggle LED2
                case '3': led3 = !led3; break; // Toggle LED3
                case '4': led4 = !led4; break; // Toggle LED4
            }
        }

        if (button == 1) {
            arduino.printf("From mBed\n");
        }
    }
}

In the above example if the arduino sends "1\n" then the Mbed will toggle LED1, "2\n" will toggle LED2, etc.

You still need to read the RX buffer with getc() and actually get the characters in the buffer and do something with them.

If you just wanted to echo what the arduino sends then you need something like this:-

        if (newline_detected) {
            newline_detected = false;
            char c;
            while((c = arduino.getc()) != '\n') {
                arduino.putc(c);
            }
        }
25 Apr 2011

Hi John,

Take a look at my recent program Canonical Input Processing. I am using the RX callback feature of Andy's MODSERIAL library to buffer an incoming command line, echo characters back to the terminal and do simple editing, like erase the last character. It's similar to what you want to do and may help you get to grips with MODSERIAL.

Paul

26 Apr 2011

Ok I think I am understanding a bit more. When you are receiving a "packet" its just sending one byte at a time and putting it into an array, or in this case the rx buffer. Once it reaches \n it stops looking for new data and you then have an array like this

buffer{H,e,l,l,o, ,W,o,r,l,d]

correct?

I really appreciate all the help in getting my head wrapped around this. Serial communication is completely new to me as all I've used it for is sending back debugging messages to a terminal.