Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Troubleshooting / Re: Problem with Receiving data at 1MBps ( 1000000bps) on: April 06, 2010, 02:26:56 am
I tried the unmodified embedded c code in arduino but i had to remove/hash the following code from HardwareSerial.cpp ( Arduino core file ) as it was conflicting with the same RX interrupt on UART0 in the embedded c code.

Code:
/*
SIGNAL(SIG_USART0_RECV)
{
  unsigned char c = UDR0;
  store_char(c, &rx_buffer);
}
*/


and now it works perfectly , that means definitely there is a lag in the method that Arduino RX interrupt uses to store data.

Am i right?


If true, is some one working to fix this in future builds of Arduino IDE ?
2  Forum 2005-2010 (read only) / Troubleshooting / Re: Problem with Receiving data at 1MBps ( 1000000bps) on: April 06, 2010, 01:53:19 am
Sorry Character limit! smiley-grin

Here is my code :
Code:
#include <stdio.h>
#include "H.h"
#include "WProgram.h"
#include <avr/interrupt.h>
#include <util/delay.h>



//#define MAXNUM_DXLBUFF      256
// Porting

//volatile unsigned char gbDxlBuffer[MAXNUM_DXLBUFF] = {0};
//volatile unsigned char gbDxlBufferHead = 0;
//volatile unsigned char gbDxlBufferTail = 0;
volatile double gfByteTransTime_us;
volatile unsigned int gwCountNum;
volatile unsigned int gwTimeoutCountNum;
volatile unsigned int gwReturnDelayCountNum;


//Set to transmite mode ( MAX485 Chip & TTL CHIP)
void DIR_TXD(void)
{


PORTE &= ~0x08;
PORTE |= 0x04;
}


//set to recieve mode ( MAX485 Chip & TTL CHIP)
void DIR_RXD(void)
{

PORTE &= ~0x04;
PORTE |= 0x08;
}

int dxl_hal_open(int devIndex, float baudrate)
{
/*
      // Opening device
      // devIndex: Device index
      // baudrate: Real baudrate (ex> 115200, 57600, 38400...)
      // Return: 0(Failed), 1(Succeed)
      
      unsigned short Divisor;

      // dynamixel communication using UART0
      
      // set UART register A
      //Bit 7: USART Receive Complete
      //Bit 6: USART Transmit Complete
      //Bit 5: USART Data Resigter Empty
      //Bit 4: Frame Error
      //Bit 3: Data OverRun
      //Bit 2: Parity Error
      //Bit 1: Double The USART Transmission Speed
      //Bit 0: Multi-Processor Communication Mode
      UCSR0A = 0b01000010;
      
      // set UART register B
      // bit7: enable rx interrupt
    // bit6: enable tx interrupt
    // bit4: enable rx
    // bit3: enable tx
    // bit2: set sendding size(0 = 8bit)
      UCSR0B = 0b10011000;
      
      // set UART register C
      // bit6: communication mode (1 = synchronize, 0 = asynchronize)
    // bit5,bit4: parity bit(00 = no parity)
    // bit3: stop bit(0 = stop bit 1, 1 = stop bit 2)
    // bit2,bit1: data size(11 = 8bit)
      UCSR0C = 0b00000110;
      
      // Set baudrate
      Divisor = (unsigned short)(2000000.0 / baudrate) - 1;
      UBRR0H = (unsigned char)((Divisor & 0xFF00) >> 8);
      UBRR0L = (unsigned char)(Divisor & 0x00FF);
*/
      //open & set baud rate
      Serial.begin(baudrate);
      
      //Define the RX & TX Pins as Output pins
       DDRE |=0x04;
       DDRE |=0x08;
      
      //calculate byte transmitting time
      gfByteTransTime_us = 1000000.0 / (double)baudrate * 12.0;
      gwReturnDelayCountNum = (unsigned int)(250.0 / gfByteTransTime_us);
      
      // initialize
      DIR_RXD();
      //UDR0 = 0xFF;  // i think it is to initialize the UART register which Arduino already does.
      //gbDxlBufferHead = 0;
      //gbDxlBufferTail = 0;
      return 1;
}

void dxl_hal_close(void)
{
      Serial.end();
      // Closing device
}

void dxl_hal_clear(void)
{
      // Clear communication buffer
      Serial.flush();
      //gbDxlBufferHead = gbDxlBufferTail;
}

int dxl_hal_tx( unsigned char *pPacket, int numPacket )
{
      // Transmiting date
      // *pPacket: data array pointer
      // numPacket: number of data array
      // Return: number of data transmitted. -1 is error.      
      int count;
      
      noInterrupts();
      DIR_TXD();
      for( count=0; count<numPacket; count++ )
      {
            

      while(!bit_is_set(UCSR0A,5));
            
            //Serial.print(pPacket[count],BYTE); getting wrong checksum at 1MBPS so transmitting directly
            UCSR0A |= 0x40;
            UDR0 = pPacket[count];
      
      }
      
      while( !bit_is_set(UCSR0A,6) );
      DIR_RXD();
      interrupts();;
      return count;
}

int dxl_hal_rx( unsigned char *pPacket, int numPacket )
{
      // Recieving date
      // *pPacket: data array pointer
      // numPacket: number of data array
      // Return: number of data recieved. -1 is error.
      int count, numgetbyte;
      
      if( Serial.available()==0 )
      {
      //Serial1.println("Serial data not available");
            return 0;
      }
      //if( gbDxlBufferHead == gbDxlBufferTail )
            //return 0;
      
      numgetbyte = Serial.available();
      //numgetbyte = dxl_hal_get_qstate();
      //Serial1.print("Num get byte : ");
      //Serial1.println(numgetbyte);
      if( numgetbyte > numPacket )
            numgetbyte = numPacket;
      
      for( count=0; count<numgetbyte; count++ )
      {
      //delayMicroseconds(gfByteTransTime_us);
      pPacket[count] = (unsigned char) Serial.read();
      
      //Serial1.println(pPacket[count],DEC);
      }
      //pPacket[count] = dxl_hal_get_queue();
      // or can directly get Serial.read();
      return numgetbyte;
}

void dxl_hal_set_timeout( int NumRcvByte )
{
      // Start stop watch
      // NumRcvByte: number of recieving data(to calculate maximum waiting time)
      gwCountNum = 0;      
      gwTimeoutCountNum = (NumRcvByte + 10) + gwReturnDelayCountNum;
}

int dxl_hal_timeout(void)
{
      // Check timeout
      // Return: 0 is false, 1 is true(timeout occurred)
      gwCountNum++;
            
      if( gwCountNum > gwTimeoutCountNum )
      {
            return 1;
      }
      
      //_delay_us(gfByteTransTime_us);
      delayMicroseconds(gfByteTransTime_us);
      return 0;
}

Its actually not important for you to go through my code , in case the arduino library does not work properly at 1MBps. Then the problem is there and not in my code  smiley .

THanks for helping out. smiley-wink
3  Forum 2005-2010 (read only) / Troubleshooting / Problem with Receiving data at 1MBps ( 1000000bps) on: April 06, 2010, 01:50:50 am
Hi ,

I am basically trying to interface a ROBOTIS Dynamixel Motor with an Arduino Mega Shield.

The motor has an inbuilt ATMega8 which controls the motor driver,feedback ( potentiometer ) etc. It has a good communication protocol which works with its controllers & embedded C examples codes at 1mbps

The problem is that am trying to modify the embedded c library files file to an arduino library.

Since both are written in c , i am just trying to shift the serial data handling from this library to use the Arduino Hardware serial library.

Everything works at baudrates lower than 1 mbps but at 1 mbps the serial buffer starts skipping some recieved bytes.

for my test i am just receiving 7 - 10 bytes every sec at 1 MBPS( Much lower than the max buffer ). The buffer eats up 1 byte on an average.

I am able to transmit data without any problems but have a problem in receiving.

A friend of mine told me that the Arduino's RX Ring buffer is not able to receive data at 1MBps. is this true ?

The following is the unmodified embedded C code for sending & receiving data. this works flawlessly!
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "dxl_hal.h"

#define MAXNUM_DXLBUFF      256
// Porting
#define DIR_TXD       PORTE &= ~0x08, PORTE |= 0x04
#define DIR_RXD       PORTE &= ~0x04, PORTE |= 0x08


volatile unsigned char gbDxlBuffer[MAXNUM_DXLBUFF] = {0};
volatile unsigned char gbDxlBufferHead = 0;
volatile unsigned char gbDxlBufferTail = 0;
volatile double gfByteTransTime_us;
volatile unsigned int gwCountNum;
volatile unsigned int gwTimeoutCountNum;
volatile unsigned int gwReturnDelayCountNum;

int dxl_hal_get_qstate(void);
void dxl_hal_put_queue( unsigned char data );
unsigned char dxl_hal_get_queue(void);


int dxl_hal_open(int devIndex, float baudrate)
{
      // Opening device
      // devIndex: Device index
      // baudrate: Real baudrate (ex> 115200, 57600, 38400...)
      // Return: 0(Failed), 1(Succeed)
      
      unsigned short Divisor;

      // dynamixel communication using UART0
      
      // set UART register A
      //Bit 7: USART Receive Complete
      //Bit 6: USART Transmit Complete
      //Bit 5: USART Data Resigter Empty
      //Bit 4: Frame Error
      //Bit 3: Data OverRun
      //Bit 2: Parity Error
      //Bit 1: Double The USART Transmission Speed
      //Bit 0: Multi-Processor Communication Mode
      UCSR0A = 0b01000010;
      
      // set UART register B
      // bit7: enable rx interrupt
    // bit6: enable tx interrupt
    // bit4: enable rx
    // bit3: enable tx
    // bit2: set sendding size(0 = 8bit)
      UCSR0B = 0b10011000;
      
      // set UART register C
      // bit6: communication mode (1 = synchronize, 0 = asynchronize)
    // bit5,bit4: parity bit(00 = no parity)
    // bit3: stop bit(0 = stop bit 1, 1 = stop bit 2)
    // bit2,bit1: data size(11 = 8bit)
      UCSR0C = 0b00000110;
      
      // Set baudrate
      Divisor = (unsigned short)(2000000.0 / baudrate) - 1;
      UBRR0H = (unsigned char)((Divisor & 0xFF00) >> 8);
      UBRR0L = (unsigned char)(Divisor & 0x00FF);

      gfByteTransTime_us = 1000000.0 / (double)baudrate * 12.0;
      gwReturnDelayCountNum = (unsigned int)(250.0 / gfByteTransTime_us);
      
      // initialize
      DIR_RXD;
      UDR0 = 0xFF;
      gbDxlBufferHead = 0;
      gbDxlBufferTail = 0;
      return 1;
}

void dxl_hal_close(void)
{
      // Closing device
}

void dxl_hal_clear(void)
{
      // Clear communication buffer
      gbDxlBufferHead = gbDxlBufferTail;
}

int dxl_hal_tx( unsigned char *pPacket, int numPacket )
{
      // Transmiting date
      // *pPacket: data array pointer
      // numPacket: number of data array
      // Return: number of data transmitted. -1 is error.      
      int count;
      
      cli();
      DIR_TXD;
      for( count=0; count<numPacket; count++ )
      {
            while(!bit_is_set(UCSR0A,5));
            
            UCSR0A |= 0x40;
            UDR0 = pPacket[count];
      }
      while( !bit_is_set(UCSR0A,6) );
      DIR_RXD;
      sei();
      return count;
}

int dxl_hal_rx( unsigned char *pPacket, int numPacket )
{
      // Recieving date
      // *pPacket: data array pointer
      // numPacket: number of data array
      // Return: number of data recieved. -1 is error.
      int count, numgetbyte;
      
      if( gbDxlBufferHead == gbDxlBufferTail )
            return 0;
      
      numgetbyte = dxl_hal_get_qstate();
      if( numgetbyte > numPacket )
            numgetbyte = numPacket;
      
      for( count=0; count<numgetbyte; count++ )
            pPacket[count] = dxl_hal_get_queue();
      
      return numgetbyte;
}

void dxl_hal_set_timeout( int NumRcvByte )
{
      // Start stop watch
      // NumRcvByte: number of recieving data(to calculate maximum waiting time)
      gwCountNum = 0;      
      gwTimeoutCountNum = (NumRcvByte + 10) + gwReturnDelayCountNum;
}

int dxl_hal_timeout(void)
{
      // Check timeout
      // Return: 0 is false, 1 is true(timeout occurred)
      gwCountNum++;
            
      if( gwCountNum > gwTimeoutCountNum )
      {
            return 1;
      }
      
      _delay_us(gfByteTransTime_us);
      return 0;
}

int dxl_hal_get_qstate(void)
{
      short NumByte;
      
      if( gbDxlBufferHead == gbDxlBufferTail )
            NumByte = 0;
      else if( gbDxlBufferHead < gbDxlBufferTail )
            NumByte = gbDxlBufferTail - gbDxlBufferHead;
      else
            NumByte = MAXNUM_DXLBUFF - (gbDxlBufferHead - gbDxlBufferTail);
      
      return (int)NumByte;
}

void dxl_hal_put_queue( unsigned char data )
{
      if( dxl_hal_get_qstate() == (MAXNUM_DXLBUFF-1) )
            return;
            
      gbDxlBuffer[gbDxlBufferTail] = data;

      if( gbDxlBufferTail == (MAXNUM_DXLBUFF-1) )
            gbDxlBufferTail = 0;
      else
            gbDxlBufferTail++;
}

unsigned char dxl_hal_get_queue(void)
{
      unsigned char data;
      
      if( gbDxlBufferHead == gbDxlBufferTail )
            return 0xff;
            
      data = gbDxlBuffer[gbDxlBufferHead];
            
      if( gbDxlBufferHead == (MAXNUM_DXLBUFF-1) )
            gbDxlBufferHead = 0;
      else
            gbDxlBufferHead++;
            
      return data;
}

SIGNAL(USART0_RX_vect)
{
      dxl_hal_put_queue( UDR0 );
}

The following is my modified code which transmits perfectly at all baud rates but is not able to receive data at 1 MBPS ( receives data perfectly at 57600bps)

4  Forum 2005-2010 (read only) / Syntax & Programs / Re: Recieve data from Serial when loop() busy on: April 06, 2010, 03:31:14 am
You can directly use the ROBOTIS supplied embedded C Lib with Arduino. Arduino's Serial is interrupt driven already but does not work properly at 1MBps.

Check out http://support.robotis.com

BTW .
Robotis embedded c lib uses

Serial line ( i.e pin 0 & 1 ) for TTL /RS485 communication.
5  Forum 2005-2010 (read only) / Troubleshooting / Re:  Bugs in Serial.read()??[NEW] on: April 06, 2010, 03:27:12 am
Hi.

According to me the problem is with using the Serial.Read at 1 mbps.

U can fix the problem by either of the following two ways.

1. Lower the baud rate . i know BAUD 34 i.e 57600 works fine with the arduino serial library.

2. I personally did the following.

Disabled the RX interrupt in the main serial library in arduino and used the Robotis embedded C lib that is available at support.robotis.com. It works perfectly at 1 MBps.

Let me know if you need more details .
6  Forum 2005-2010 (read only) / Interfacing / Re: Arduino and robotis dynamixel servo on: April 06, 2010, 09:18:57 am
Would love to.

So what is your setup ?

Which arduino board ? AX or RX type motors ?

Do you have the TTL or RS485 circuit ready & running ?

Where exactly are you stuck ? Hardware or software ?
7  Forum 2005-2010 (read only) / Interfacing / Re: Arduino and robotis dynamixel servo on: April 06, 2010, 03:17:18 am
Are you still stuck ? need help ?
8  Forum 2005-2010 (read only) / Interfacing / Re: Dynamixel ax-12 and Arduino on: April 06, 2010, 03:08:42 am
Sorry for the late reply. But it can definitely be done.

We have been using both the Dynamixel AX & RX series with our Arduino.

Are you still on the project or figured out a way?
9  Forum 2005-2010 (read only) / Exhibition / Re: Self Balancing Robot on: April 06, 2010, 03:13:35 am
Did you ever go the AX-12 route ?
Pages: [1]