go_away

Author Topic: Simple IO over UART issue using AxonII/webbotlib  (Read 2239 times)

0 Members and 1 Guest are viewing this topic.

Offline GrooveHolmesTopic starter

  • Jr. Member
  • **
  • Posts: 43
  • Helpful? 0
Simple IO over UART issue using AxonII/webbotlib
« on: April 23, 2010, 06:03:04 PM »
Having a strange event I can't seem to understand.

This code:
Code: [Select]
// Place any #define statements here before you include ANY other files

// Now include any other files that are needed here

#include "sys/axon2.h" // I am using an Axon
#include "uart.h"
#include "segled.h"
#include "rprintf.h"

//Globals
int LEDchar = 0;
int LEDdec_status = 0;
int tchar;

void appInitHardware(void){
//code
uartInit(UART1, 115200);
rprintfInit(&uart1SendByte); //output to UART1
}


TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
return 0; // dont pause after
}


TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart){
//TODO
//receive and direct char input from uart

int ch = uartGetByte(UART1);

if(ch != -1) //if character in ch
{
tchar = (char)ch;
rprintf("%c", ch);
rprintfCRLF();
segled_put_char(&led_display, tchar); //send out to onboard LED too
}

uartFlushReceiveBuffer(UART1);
return 200000; // wait for 20ms before calling me again. 1000000 = 1 second
}

... produces an odd behavior.

It's supposed to poll the uart1 for a single char every 20ms and send it to the onboard segmented LED and out the same uart back to the sending PC. This part works fine. It receives the char, and redirects it ducky.

The problem is that after the first char is received and sent back out, the uart keeps outputting what appears to be CRLF commands (empty lines are received on the PC) between the received chars, until I reset (on/off switch) the Axon. After resetting, it stops sending empty lines and again waits for a char to be received. When the character come in, the cycle begins again, outputting results such as:

(just hitting random keys on the PC keyboard)
Code: [Select]
k

d


s
f
d

f


d
s
e
f
f
f
f
s

a


a
...etc.

What's happening here to cause the empty lines? The block calling the rprintfCRLF(); function is inside the if(ch!=-1) block, and since the ch variable is local to the appControl method it should always return -1 if there was no received uart data right (which means, no execution of the if() block)?!

I also find it odd that this cycle doesn't start until the first char is received and is solved by resetting the card.

I even tried making the 'ch' char global and having it manually reset back to -1 at the end of the appControl function, but nay; still sends out empty lines until reset. What's happening here?!

TIA!
The difference between the student and the master, is that the master knows what he does not know.

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #1 on: April 23, 2010, 06:14:54 PM »
I actually saw the same thing recently with my SAGAR robot. I forgot to come tell Webbot about it.

I fixed the issue by using

if (!uartReceiveBufferIsEmpty(uart1))

instead of checking against != -1

Offline GrooveHolmesTopic starter

  • Jr. Member
  • **
  • Posts: 43
  • Helpful? 0
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #2 on: April 23, 2010, 08:47:50 PM »
I actually saw the same thing recently with my SAGAR robot. I forgot to come tell Webbot about it.

I fixed the issue by using

if (!uartReceiveBufferIsEmpty(uart1))

instead of checking against != -1

Thanks mad, I tried your code:
Code: [Select]
if (!uartReceiveBufferIsEmpty(UART1))
... but now it doesn't appear to respond, not sure if it's still receiving it (probably is), but in puTTy, the cursor just sits; no reply to my commands.

But I'll tinker with what you offered. Could be on to something here.
The difference between the student and the master, is that the master knows what he does not know.

Offline dunk

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 1,086
  • Helpful? 21
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #3 on: April 24, 2010, 03:42:38 AM »
are you sure this is an issue with WebbotLib and not a feature of your terminal emulation software?

many terminal emulation programs insert a line break if there is a delay in the received data.
try examining the raw output from the serial port if your software lets you do that and see if you are actually receiving newline chars.
also try switching off any automatic newline options.


dunk.

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #4 on: April 24, 2010, 06:55:39 AM »
I think it may be because you haven't set up any buffers for the UART ie:
# define UART1_RX_BUFFER_SIZE  5
# define UART1_TX_BUFFER_SIZE  5

Hence: 'uartReceiveBufferIsEmpty' always returns true.

EDIT: and 'uartFlushReceiveBuffer' will corrupt some memory around address 0 coz the buffer is null (ie 0) - which I will fix so that the call does nothing if there is no buffer
« Last Edit: April 24, 2010, 07:56:30 AM by Webbot »
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #5 on: April 24, 2010, 08:22:19 AM »
Webbot, in my code the buffer was being written to EEPROM, so no terminal software in the mix. When I would dump EEPROM, I would have all these extra spaces as well.

Code: [Select]
if (!uartReceiveBufferIsEmpty(uart1))
{
temp = uartGetByte(uart1);

if(temp == 'X')
done = TRUE;

// rprintf("%c",temp);

//temps[tempi++] = temp;
eeprom_write_byte((uint8_t*)tempi++,temp);

if (tempi > 2000)
{
rprintf("Download Error");
done = TRUE;
}
// delay_us(100);
}

thats my code, except the if used to be

if(temp = uartgetbyte(uart1), temp != -1)

and this always seemed to return true, after I sent a single character.

And my receive buffer was 500 bytes large. ( I know, large. But I wirelessly transfer large mission text files to be stored in EEPROM.)
« Last Edit: April 24, 2010, 08:25:20 AM by madsci1016 »

Offline GrooveHolmesTopic starter

  • Jr. Member
  • **
  • Posts: 43
  • Helpful? 0
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #6 on: April 24, 2010, 02:04:29 PM »
I think it may be because you haven't set up any buffers for the UART ie:
# define UART1_RX_BUFFER_SIZE  5
# define UART1_TX_BUFFER_SIZE  5

Hence: 'uartReceiveBufferIsEmpty' always returns true.

EDIT: and 'uartFlushReceiveBuffer' will corrupt some memory around address 0 coz the buffer is null (ie 0) - which I will fix so that the call does nothing if there is no buffer

Thanks Webbot, but that creates a whole new error!

Just adding the two define statements now produces this error on compilation:

E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/../dev/ATmega640.h:789: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rx1Buffer'

AVRStudio directs me to this block of code in the atmega640.h when I reference (double click the error) the error;
Code: [Select]
#ifdef UART1_RX_BUFFER_SIZE
  unsigned char rx1Buf[UART1_RX_BUFFER_SIZE];
  cBuffer rx1Buffer = MAKE_BUFFER(rx1Buf);
# define rx1B &rx1Buffer
#else
# define rx1B null
#endif

It halts on the 'cBuffer rx1Buffer....' statement.

Being new to C and webbotlib, I don't understand what it wants!
The difference between the student and the master, is that the master knows what he does not know.

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #7 on: April 24, 2010, 02:07:47 PM »
Are you using the webbotlib project designer?

http://webbot.org.uk/iPoint/37.page

If not, you should try it.

I'm not sur why you are getting that error, that's a webbot question. I woul try using project designer as it takes care of all the #define
for you.
« Last Edit: April 24, 2010, 02:09:39 PM by madsci1016 »

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #8 on: April 24, 2010, 03:43:22 PM »
I think it may be because you haven't set up any buffers for the UART ie:
# define UART1_RX_BUFFER_SIZE  5
# define UART1_TX_BUFFER_SIZE  5

Hence: 'uartReceiveBufferIsEmpty' always returns true.

EDIT: and 'uartFlushReceiveBuffer' will corrupt some memory around address 0 coz the buffer is null (ie 0) - which I will fix so that the call does nothing if there is no buffer

Thanks Webbot, but that creates a whole new error!

Just adding the two define statements now produces this error on compilation:

E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/../dev/ATmega640.h:789: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rx1Buffer'

AVRStudio directs me to this block of code in the atmega640.h when I reference (double click the error) the error;
Code: [Select]
#ifdef UART1_RX_BUFFER_SIZE
  unsigned char rx1Buf[UART1_RX_BUFFER_SIZE];
  cBuffer rx1Buffer = MAKE_BUFFER(rx1Buf);
# define rx1B &rx1Buffer
#else
# define rx1B null
#endif

It halts on the 'cBuffer rx1Buffer....' statement.

Being new to C and webbotlib, I don't understand what it wants!

You need to:
#include "buffer.h"

Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #9 on: April 24, 2010, 03:47:48 PM »
Webbot, in my code the buffer was being written to EEPROM, so no terminal software in the mix. When I would dump EEPROM, I would have all these extra spaces as well.

Code: [Select]
if (!uartReceiveBufferIsEmpty(uart1))
{
temp = uartGetByte(uart1);

if(temp == 'X')
done = TRUE;

// rprintf("%c",temp);

//temps[tempi++] = temp;
eeprom_write_byte((uint8_t*)tempi++,temp);

if (tempi > 2000)
{
rprintf("Download Error");
done = TRUE;
}
// delay_us(100);
}

thats my code, except the if used to be

if(temp = uartgetbyte(uart1), temp != -1)

and this always seemed to return true, after I sent a single character.

And my receive buffer was 500 bytes large. ( I know, large. But I wirelessly transfer large mission text files to be stored in EEPROM.)


Would be interesting to see the declaration of the 'temp' variable
It should be:
int temp;

If its an unsigned data type, or only 8 bits, then it would give the error you are referring to.
ie
uint8_t temp;
would cause un-told problems.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #10 on: April 24, 2010, 06:11:06 PM »
Code: [Select]
char temp = 0;

Your level of expertise astounds me.

I just remember char is unsigned. I'm a fool...  :-(

Offline chelmi

  • Supreme Robot
  • *****
  • Posts: 496
  • Helpful? 15
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #11 on: April 24, 2010, 06:42:39 PM »
Code: [Select]
char temp = 0;

Your level of expertise astounds me.

I just remember char is unsigned. I'm a fool...  :-(

char is signed. Your problem is probably coming from the fact that it's only 8 bits.
You need to declare temp as an int (signed and 16 bits)

Chelmi.

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #12 on: April 24, 2010, 06:53:33 PM »
Code: [Select]
char temp = 0;

Your level of expertise astounds me.

I just remember char is unsigned. I'm a fool...  :-(

char is signed. Your problem is probably coming from the fact that it's only 8 bits.
You need to declare temp as an int (signed and 16 bits)

Chelmi.


I beg to differ. The C standard default has 'char' as signed (dates back to old 7 bit ascii character values) - but most makefiles, etc, use '-funsigned-char' to tell the compiler to treat chars as unsigned.

The '8 bit problem' would only mean that he could not differentiate between receiving a character value of 0xff or 'no data received'
« Last Edit: April 24, 2010, 06:55:32 PM by Webbot »
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #13 on: April 24, 2010, 06:54:14 PM »
Why does it need to be 16 bit? What exactly is it doing?

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #14 on: April 24, 2010, 06:57:05 PM »
Why does it need to be 16 bit? What exactly is it doing?


Here is a summary of theinitial code:
Code: [Select]
char temp=0;
if(temp = uartgetbyte(uart1), temp != -1){

}

Why did the 'if' statement ALWAYS return true?
The call to uartgetbyte is effectively returning 2 values in one 'int'. Either -1 if there is no data, otherwise the data byte.
An 'int' (on AVRs) is a signed two byte integer (like a int16_t).

If the call wants to return a data byte then this is in the low byte and the high byte is 0. If there is no data then it returns 255 in both bytes (which corresponds to -1 for a two byte signed integer).

So lets assume that the call returned -1. This is being stored into a 'char' which a 'unsigned byte'. Semantically: an 'unsigned' variable of any type cannot have a value of -1 as they only store numbers from 0 upwards.
To make things worse it is being stored into a 'char' so the top byte (which indicates whether there is a valid character or not) is thrown away and the actual data byte, or 255 if there wasn't one) is stored into the temp variable.
Come the test against -1 then the char value actually holds '255' not '-1' and so the 'if' statement always returns true.


Here is the 'pattern' you should use:-

int temp;

if( temp =uartgetbyte(uart1), temp!=-1){
    uint8_t ch = temp & 0xff;
    -- or --
   char ch = temp & 0xff;

   

}


« Last Edit: April 24, 2010, 06:59:10 PM by Webbot »
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #15 on: April 24, 2010, 06:57:35 PM »
I beg to differ. The C standard default has 'char' as signed (dates back to old 7 bit ascii character values) - but most makefiles, etc, use '-funsigned-char' to tell the compiler to treat chars as unsigned.

The '8 bit problem' would only mean that he could not differentiate between receiving a character value of 0xff or 'no data received'

Yup, that's in my makefile. So that was my problem.

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #16 on: April 24, 2010, 07:00:22 PM »
I beg to differ. The C standard default has 'char' as signed (dates back to old 7 bit ascii character values) - but most makefiles, etc, use '-funsigned-char' to tell the compiler to treat chars as unsigned.

The '8 bit problem' would only mean that he could not differentiate between receiving a character value of 0xff or 'no data received'

Yup, that's in my makefile. So that was my problem.

But DON'T change it!!!!!!

See the recommended pattern as in my previous post
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #17 on: April 24, 2010, 07:04:00 PM »
Lol, I'm going to leave my code the way it is with the call to uartreceivebufferisempty()

It works fine that way.

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #18 on: April 24, 2010, 07:08:13 PM »
Yep - it will work - just adds the overhead of an extra call to test if the uart receive buffer is empty (as uartgetbyte effectively calls it as well!)

The code pattern I gave you DOES work - its used all over the lib for serial devices eg gps, blackfin camera etc etc.

Its a standard pattern: bit like reading bytes from a file in 'normal C' whereby '-1' indicates the end-of-file
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline GrooveHolmesTopic starter

  • Jr. Member
  • **
  • Posts: 43
  • Helpful? 0
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #19 on: April 24, 2010, 07:20:09 PM »

You need to:
#include "buffer.h"



I added an include statement, and added a header reference to buffer.h in my project; but still get the same compiler error.

here's the main.c
Code: [Select]
// Place any #define statements here before you include ANY other files
#define UART1_RX_BUFFER_SIZE  5
#define UART1_TX_BUFFER_SIZE  5

// Now include any other files that are needed here

#include "sys/axon2.h" // I am using an Axon
#include "uart.h"
#include "segled.h"
#include "rprintf.h"
#include "buffer.h"

//Globals
int LEDchar = 0;
int LEDdec_status = 0;
int tchar;

void appInitHardware(void){
//code
uartInit(UART1, 115200);
rprintfInit(&uart1SendByte); //output to UART1
}


TICK_COUNT appInitSoftware(TICK_COUNT loopStart){
return 0; // dont pause after
}


TICK_COUNT appControl(LOOP_COUNT loopCount, TICK_COUNT loopStart){
//TODO
//receive and direct char input from uart
int ch = -1;

ch = uartGetByte(UART1);

if(ch != -1 ) //if character in ch
{
tchar = (char)ch;
rprintf("%c", ch);
//rprintfCRLF();
segled_put_char(&led_display, tchar); //send out to onboard LED too
} //else?

uartFlushReceiveBuffer(UART1);
return 200000; // wait for 1 second before calling me again. 1000000us = 1 second
}

Compiler error:
Quote
Build started 24.4.2010 at 16:40:39
avr-gcc -I"E:\Robots\LEDNumCounter\..\webbotavrclib\1.17"  -mmcu=atmega640 -Wall -gdwarf-2 -std=gnu99                        -DF_CPU=16000000UL -O0 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT LEDNumCounter.o -MF dep/LEDNumC
ounter.o.d  -c  ../LEDNumCounter.c

In file included from E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/../device.h:47,
                 from E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/axon2.h:252,
                 from ../LEDNumCounter.c:8:
E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/../dev/ATmega640.h:789: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rx1Buffer'
E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/../dev/ATmega640.h:842: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'tx1Buffer'
In file included from E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/../device.h:47,
                 from E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/axon2.h:252,
                 from ../LEDNumCounter.c:8:
E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/../dev/ATmega640.h:897: error: 'rx1Buffer' undeclared here (not in a function)
E:\Robots\LEDNumCounter\..\webbotavrclib\1.17/sys/../dev/ATmega640.h:897: error: 'tx1Buffer' undeclared here (not in a function)
make: *** [LEDNumCounter.o] Error 1
Build failed with 4 errors and 0 warnings...

The difference between the student and the master, is that the master knows what he does not know.

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #20 on: April 24, 2010, 07:23:16 PM »
Put 'buffer.h' before 'sys/axon2.h'
Am looking at fixing this in later releases.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline madsci1016

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,450
  • Helpful? 43
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #21 on: April 24, 2010, 09:17:37 PM »
Yep - it will work - just adds the overhead of an extra call to test if the uart receive buffer is empty (as uartgetbyte effectively calls it as well!)

The code pattern I gave you DOES work - its used all over the lib for serial devices eg gps, blackfin camera etc etc.

Its a standard pattern: bit like reading bytes from a file in 'normal C' whereby '-1' indicates the end-of-file


So wait, which one is more efficient? does getbyte call uartreceivebufferisempty() anyway?

Either way, I am only running at 40-60 % load at 10hz anyway, I can spare it. (I've also got the Axon flash memory half full. Is that a new record? )

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,154
  • Helpful? 110
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #22 on: April 24, 2010, 11:55:42 PM »
The code pattern I gave you is more efficient.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,663
  • Helpful? 169
    • Society of Robots
Re: Simple IO over UART issue using AxonII/webbotlib
« Reply #23 on: April 25, 2010, 08:20:30 PM »
Quote
I've also got the Axon flash memory half full. Is that a new record?

If I remember right, my ERP, with *all* code enabled, comes out to like 54%.

But I believe this is the record:
http://www.societyofrobots.com/robotforum/index.php?topic=10092.0

 


Get Your Ad Here