Asked — Edited
Resolved Resolved by mtiberia!

Uart Receive Query. Buffer Flush Command?

I am have a little issue with the below code.... I am attempting to read 3 different single byte return sensors on my new Create 2.... Now, it works perfectly if I read only one sensor in the repeatuntil loop. However if I do more than one read (like the code below).... the readings report back false... i.e. the bump sensor will indicate a bump when none occurred or the IR detect will indicate a bump instead of a indicating a close proximity of an object....

So am I daft and my code is wrong or does maybe the UART buffer need to be flushed after each read?

I am stumped....

Thanks guys


REPEATUNTIL(1=2)
  $x=0
  $y=0
  $z=0
  
  uartWrite(0,1,142,45) # Read Roomba IR sensors single byte
  sleep(10)
  
  IF (UARTAvailable(0,1)>0)
    $x=UARTRead(0,1,1)
    $x=GetByte($x)
  ENDIF 
    
    
  sleep(10)
  
  uartWrite(0,1,142,7) #Roomba Bump and wheel drop sensor single byte
  sleep(10)
  
  IF (UARTAvailable(0,1)>0)
    $y=UARTRead(0,1,1)
    $y=GetByte($y)
  ENDIF 
    
  sleep(10)
  
  uartWrite(0,1,142,58) # Stasis (Rommba moving forward) single byte
  sleep(10)
  IF (UARTAvailable(0,1)>0)
    $z=UARTRead(0,1,1)
    $z=GetByte($z)
  ENDIF 
    
  print($x+" IR light object detected")
  print($y+" bump detected")
  print($z+" Is moving forward")
  
  sleep(200)
ENDREPEATUNTIL


ARC Pro

Upgrade to ARC Pro

Take control of your robot's destiny by subscribing to Synthiam ARC Pro, and watch it evolve into a versatile and responsive machine.

#1  

You can try checking to see how many bytes are in the buffer or what I would do do is send the commands to read the sensor one after the other and then read the three bytes received.

$x = UartAvailable(0, 1)

print("Bytes in buffer: " + $x) # checks how many bytes are in the buffer

$RX_DATA = UARTRead(0, 1, $x) # places all the bytes RX into $RX_DATA

read 3 data bytes

$RX_0=GetByteAt($RX_DATA,0)
RX_1=GetByteAt($RX_DATA,1) RX_2=GetByteAt($RX_DATA,2)

#2  

@mtiberia .... Thanks man your code worked with slight modification... Had to put a condition (if statement) to check on the # of bytes in the buffer... If not every 20 or so loops would produce an data out of bounds error... So now, although the bump and IR sensor spit back the correct readings the Stasis (whether the Create is moving forward or not) reports 2 for stopped and 3 for forward movement... According to the Create 2 ROI manual it is supposed to be 0 for not moving and 1 for moving forward... Hmmmm ... Nevertheless it seems to work better with your code....

Edit I am testing this on a Roomba 500 series and not my Create 2 yet.... The Create 2 is a 600 series so that may be the difference in the Stasis reporting different numbers that it is supposed to....

#3  

@mtiberia.... Thanks for your help.... Now if you can only help me read 2 byte data (like Roomba voltage values), that would be awesome... It is returned as a value between 0 65535 mV ... The two bytes are read as high byte and low byte...

#4  

I'm looking at the Create 2 as well, it would make a great mobile platform.

if($rx=2)

$LSB=GetByteAt($rx,0) $MSB=GetByteAt($rx,1)

$voltage=$LSB+(256*$MSB)

#5  

The above formula is if you RX the LSB first and MSB second. Just change positions if its the other way around.

#6  

@mtiberia Thanks I'll give it a try...

By the way my Create 2 came with only the brushes and brush cage retainer missing (in order to make it a full blown Roomba vacuum.... )... For $200 bucks, not bad.... I would buy a second one if it weren't for the fact the Canadian $ is so weak compared to the US dollar....

#7  

@mtiberia ... Here is my code below... It doesn't work... Every loop of the repeatuntil just adds 2 bytes to the buffer (2,4,6,8,10...etc) until it crashes as an out of bounds error.... That's why I was wondering if a flush buffer command was needed... Could be my code still though... High byte is first....


RepeatUntil(1=2)

uartWrite(0,1,142,22) # Volatge check 2 byte receive
sleep(10)
$rx = UartAvailable(0, 1)

print($rx+" bytes in the buffer")
if($rx=2)
$RX_DATA = UARTRead(0, 1, $rx) 
 $MSB=GetByteAt($rx,0)
 $LSB=GetByteAt($rx,1)

 $voltage=$MSB+(256*$LSB)
print($voltage)
endif
sleep(250)
endrepeatuntil

#8  

Ok, it doesn't work at all (thought it did)... although the first read reports 2 bytes in the buffer I get an error at this line (see below)..." Index was outside the bounds of the array" error... Each successive read puts 2 more bytes in the buffer (2,4,6,8,10, etc...)


 $LSB=GetByteAt($rx,1)

#9  

Interesting try placing the initiate UART inside the loop. That should flush the buffer.

#10  

@mtiberia That didn't work either... the first read gives me the out of bounds of the array error.... This is the same problem I had way back when I first tried to do this with my old create 1... I was able to read single byte data but not anything with more than 1 byte.... This works on an Arduino and on my ancient Basic Atom Pro....

Either I am doing something wrong of you are correct the UART port doesn't work correctly on the EZB4

#11  

I just noticed an error in your code, I'm fighting the need for reading glasses, but try changing your code to the following.

if($rx=2) $RX_DATA = UARTRead(0, 1, $rx) $MSB=GetByteAt($RX_DATA,0)
$LSB=GetByteAt($RX_DATA,1)

#12  

That was my bad the above should work for you.

#13  

You're eyes are just fine... good catch dude....Can't believe I missed that as well....

Ok the code below seems to work, however if you don't have the uartinit() in the loop the buffer just continues to grow...


REPEATUNTIL(1=2)
 uartinit(0, 1, 115200) #used to flush the buffer
sleep(20)
   $RX_DATA=0
  uartWrite(0,1,142,22) # Volatge check
  sleep(10)
  $rx = UartAvailable(0, 1)
  
  print($rx+" bytes in the buffer")
  
  IF ($rx=2)
    $RX_DATA = UARTRead(0, 1, $rx)
    $MSB=GetByteAt($RX_DATA,0)
    $LSB=GetByteAt($RX_DATA,1)
    $voltage=$LSB+(256*$MSB)
    print($voltage)
  ENDIF 
  sleep(225)
  
ENDREPEATUNTIL