Society of Robots - Robot Forum

Software => Software => Topic started by: CalamariDudeMan on March 30, 2011, 09:26:17 PM

Title: Simple Serial Dialog Not Working [Solved]
Post by: CalamariDudeMan on March 30, 2011, 09:26:17 PM
Hi all,

I'm just trying to get some very simple serial communication between the Serial module of Roborealm and my Axon II.  The Axon is sending bytes fine, but every time I attempt to send it a "!" whose decimal equivalent is 33, the program reports a receive buffer overflow through the built-in error messaging from WebbotLib (11 blinks).  As the code will attest, I have defined a 60 byte (excessive) receive buffer, but to no avail.  Why am I getting this error?  Please excuse my dirty formatting, I'm trying to use comments and clean things up, but this is mostly a late night project for the inexperienced mind.

Thanks

Code: [Select]
#define UART1_TX_BUFFER_SIZE 10
#define UART1_RX_BUFFER_SIZE 60

unsigned char command;
char rxBufferUsed = 0;
int const checkByte = 33;
char const confirmationGood = 101;
char const confirmationBad = 99;
int i;

#include "hardware.h"

// Initialise the hardware
void appInitHardware(void) {
initHardware();


}
// Initialise the software
TICK_COUNT appInitSoftware(TICK_COUNT loopStart){



//start uart comm
uartSetBaudRate(uart1, (BAUD_RATE)115200);
rprintfInit(&uart1SendByte);
rprintfChar('A');
uartFlushReceiveBuffer(UART1);
return 30;
}
// This is the main loop
TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart) {


//Check if there's new data
if (uartReceiveBufferIsEmpty(UART1) && rxBufferUsed == 0){   //if theres nothing in the buffer and there never was

i++; //tack one up on the run counter


if (i==16000){
rprintfChar('x'); //let me know nothing was received every few seconds to make sure
i=0;                //everything's still running, then reset the counter
}


}else{                         //if something is in the buffer or has been
rprintfChar('d');                     //tell me!
rxBufferUsed=1;            //
if (uartGetByte(UART1) == checkByte){    //check if its the right stuff just to keep commands in order
command = uartGetByte(UART1);             // if it is, print the command recieved
                                                         // on the segled

// -------- Start Marquee-------

Writer old = rprintfInit(marqueeGetWriter(&marquee));

marqueeSetEndDelay(&marquee,0);    
if(marqueeIsActive(&marquee)==FALSE){
    rprintf("Action %s\n",command);        //let me know what command was received
  }

rprintfInit(old);
// -------- End   Marquee-------

rprintfChar(confirmationGood);  //then tell the computer it got the command successfully
i=0;                                     //reset counter
}else{               //if the received first byte was not the correct verification byte

rprintfChar(confirmationBad);
i=0;
}

}

return 30;
}
Title: Re: Simple Serial Dialog Not Working
Post by: mstacho on April 02, 2011, 10:50:55 AM
What happens if you try to send anything but 33?  Try to send 65, or 'A'.  I doubt this is the problem, but just in case, you may be sending special characters that the uC interprets wrong.

MIKE
Title: Re: Simple Serial Dialog Not Working
Post by: MikeK on April 02, 2011, 12:30:26 PM
I always tell people to simply the problem first.  If you've got 20 things going on and it's not working then you're going to have difficulty debugging.

So start with a simple program:
1. Receive byte.
2. Print byte.
3. Repeat.

...To check that the "!" is getting through.  (I'm sure it is.)
Title: Re: Simple Serial Dialog Not Working
Post by: MikeK on April 02, 2011, 12:36:37 PM
Looking over your program briefly it does look like you're going to generate an overflow condition.  Look at your main ELSE block.  At this point you know that you have a byte to receive, and you receive it.  But you then assume there is another byte right after it.
Title: Re: Simple Serial Dialog Not Working
Post by: CalamariDudeMan on April 02, 2011, 04:44:26 PM
Thank for the replies!

I will go back and try a different character, as well as comment out everything I can to simplify as much as possible.  One thing I'm wondering is if I have set up the serial comm correctly in Roborealm, since I have no idea what a stop bit does or some of the other fine tuning options (8 bits and 115200 baud are the only things I know to check).  Also, does Roborealm send any additional data when you ask it to send a single ASCII character through the serial terminal?

The reason for getByte-ing again is that the first byte notifies of incoming data, and makes sure it is received properly.  However, I'm sure that my serial communication setup will be reliable, so I can probably get rid of that step entirely since corruption is unlikely.
Also, since I've been dealing with this error I was thinking an interrupt might be more helpful in my situation.  I'll sort out this issue first though.
Title: Re: Simple Serial Dialog Not Working
Post by: mstacho on April 03, 2011, 12:34:52 PM
A stop bit is exactly what it sounds like: a bit that tells your uC that the message has ended.  The reason it's used is because unless you're using two voltage levels, both of which are nonzero, to represent 1 and 0, it is hard (read: impossible) to tell the difference between a very long string of 0's (or 1's if the logic levels are reversed) and a line that is "off".

It's REALLY important when dealing with UART/serial communications that both ends are set up exactly the same.  So your uC and the whatever it's communicating with have to have the same options, or else you'll only end up with gibberish.

This also goes for "parity", which is one (or more) bits used to determine if any error has occurred during transmission.  Again, it doesn't matter what the settings are, but it does matter that the settings are all the same!

MIKE
Title: Re: Simple Serial Dialog Not Working
Post by: CalamariDudeMan on April 17, 2011, 10:26:27 PM
I've slowed down the baud rate and trimmed out everything that is not absolutely necessary.  Also, I made sure that the Axon was on, then started serial comm in Roborealm.  What do you know!  It works!  Thanks for the suggestions!  I know that probably everyone knows how to do this, but just for the kids in the back row I'll post my code:

Code: [Select]
#define UART1_RX_BUFFER_SIZE 80
#define UART1_TX_BUFFER_SIZE 80

#include "hardware.h"

char rxYes = 0;
char rxChar;

void appInitHardware(void) {
initHardware();
}

TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
uartInit(UART1, 9600);
return 0;
}

TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart) {

Writer old = rprintfInit(marqueeGetWriter(&marquee));
marqueeSetEndDelay(&marquee,0);

    if(!uartReceiveBufferIsEmpty(UART1)){
        rxYes=1;
        rxChar = uart1GetByte();
        uartFlushReceiveBuffer(UART1);
txChar = rxChar + 1;
        uart1SendByte(txChar);
    }

if(marqueeIsActive(&marquee)==FALSE){
    if(rxYes == 1){
    rprintf("%c\n", rxChar);
rxYes = 0;
}
}

rprintfInit(old);

return 0;
}

This code takes a character via serial (UART) connection and displays it once on the segled, as well as bumps it down to the next letter and sends that back over serial.