ros-drivers / rosserial

A ROS client library for small, embedded devices, such as Arduino. See: http://wiki.ros.org/rosserial
508 stars 527 forks source link

rosserial with the ti tm4c123 launchpad. It won't connect #100

Open blueminerals opened 10 years ago

blueminerals commented 10 years ago

I am trying to use rosserial with the ti tm4c123 launchpad. It won't connect when I do a rosrun rosserial_python serial_node.py /dev/ttyACM0

my ardunio_hardware.h is below

ifndef ROS_ARDUINO_HARDWAREH

define ROS_ARDUINO_HARDWAREH

include //

include

class ArduinoHardware { public: ArduinoHardware(HardwareSerial* io , long baud= 57600){ iostream = io; baud = baud; } ArduinoHardware() { iostream = &Serial; baud = 57600; } ArduinoHardware(ArduinoHardware& h){ this->iostream = iostream; this->baud = h.baud; }

void setBaud(long baud){
  this->baud_= baud;
}  
int getBaud(){return baud_;}

void init(){
  iostream->begin(baud_);
}
int read(){return iostream->read();};
void write(uint8_t* data, int length){
  for(int i=0; i<length; i++)
    iostream->write(data[i]);
}
unsigned long time(){return millis();}

protected: HardwareSerial* iostream; long baud_; };

endif

mikeferguson commented 10 years ago

Does it actually compile? Where is your HardwareSerial defined, what set of underlying libraries are you using? There really isn't enough here to start debugging.

blueminerals commented 10 years ago

I am using energia at http://energia.nu/download/. Enclosed is the HardwareSerial files from the energia download. Energia is sort of a clone of the Ardunio IDE for the Ti products. Using the Energia IDE, it does compile. I am not compiling in any other way. If I should , please let me know. I have put ros_lib in the libraries folder under where the sketches are. Thanks for your help.

/*

*/

I am trying to run this program and it compiles in the Energia IDE

//sketch_blink

include

include <std_msgs/Empty.h>

ros::NodeHandle nh;

void messageCb( const std_msgs::Empty& toggle_msg){

digitalWrite(RED_LED, HIGH); // blink the led

delay(1000);

digitalWrite(RED_LED, LOW);

delay(1000);

}

ros::Subscriber sub("toggle_led", &messageCb );

void setup()

{

pinMode(RED_LED, OUTPUT);

nh.initNode();

nh.subscribe(sub);

}

void loop()

{

nh.spinOnce();

delay(1);

}

Then I run this:

qmi@ubuntu:/dev$ rosrun rosserial_python serial_node.py /dev/ttyACM0

[INFO] [WallTime: 1392985717.959284] ROS Serial Python Node

[INFO] [WallTime: 1392985717.985203] Connecting to /dev/ttyACM0 at 9600 baud

[ERROR] [WallTime: 1392985735.116228] Unable to sync with device; possible link problem or link software version mismatch such as hydro rosserial_python with groovy Arduino

[ERROR] [WallTime: 1392986335.570003] Unable to sync with device; possible link problem or link software version mismatch such as hydro rosserial_python with groovy Arduino

I controlled-C at this point

Traceback (most recent call last):

File "/opt/ros/hydro/lib/rosserial_python/serial_node.py", line 82, in

client.run()

File "/opt/ros/hydro/lib/python2.7/dist-packages/rosserial_python/SerialClient.py", line 387, in run

flag[0]  = self.port.read(1)

File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 456, in read

raise SerialException('device reports readiness to read but returned no data (device disconnected?)')

serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected?)

From: Michael Ferguson [mailto:notifications@github.com] Sent: Saturday, February 22, 2014 3:50 PM To: ros-drivers/rosserial Cc: blueminerals Subject: Re: [rosserial] rosserial with the ti tm4c123 launchpad. It won't connect (#100)

Does it actually compile? Where is your HardwareSerial defined, what set of underlying libraries are you using? There really isn't enough here to start debugging.

— Reply to this email directly or view it on GitHub https://github.com/ros-drivers/rosserial/issues/100#issuecomment-35814241 . https://github.com/notifications/beacon/6001430__eyJzY29wZSI6Ik5ld3NpZXM6QmVhY29uIiwiZXhwaXJlcyI6MTcwODYzNTAwNywiZGF0YSI6eyJpZCI6MjYyMzc3OTd9fQ==--b91ce6a74c207f07d3cc2191dc6304d4b19978e7.gif /*


include

include

include

include

include "wiring_private.h"

include "inc/hw_memmap.h"

include "inc/hw_types.h"

include "inc/hw_ints.h"

include "inc/hw_uart.h"

include "driverlib/gpio.h"

include "driverlib/debug.h"

include "driverlib/interrupt.h"

include "driverlib/rom.h"

include "driverlib/rom_map.h"

include "driverlib/pin_map.h"

include "driverlib/sysctl.h"

include "driverlib/uart.h"

include "HardwareSerial.h"

define TX_BUFFER_EMPTY (txReadIndex == txWriteIndex)

define TX_BUFFER_FULL (((txWriteIndex + 1) % txBufferSize) == txReadIndex)

define RX_BUFFER_EMPTY (rxReadIndex == rxWriteIndex)

define RX_BUFFER_FULL (((rxWriteIndex + 1) % rxBufferSize) == rxReadIndex)

define UART_BASE g_ulUARTBase[uartModule]

static const unsigned long g_ulUARTBase[8] = { UART0_BASE, UART1_BASE, UART2_BASE, UART3_BASE, UART4_BASE, UART5_BASE, UART6_BASE, UART7_BASE };

// // // The list of possible interrupts for the console UART. // // static const unsigned long g_ulUARTInt[8] = { INT_UART0, INT_UART1, INT_UART2, INT_UART3, INT_UART4, INT_UART5, INT_UART6, INT_UART7 };

// // // The list of UART peripherals. // // static const unsigned long g_ulUARTPeriph[8] = { SYSCTL_PERIPH_UART0, SYSCTL_PERIPH_UART1, SYSCTL_PERIPH_UART2, SYSCTL_PERIPH_UART3, SYSCTL_PERIPH_UART4, SYSCTL_PERIPH_UART5, SYSCTL_PERIPH_UART6, SYSCTL_PERIPH_UART7 }; // // // The list of UART GPIO configurations. // // static const unsigned long g_ulUARTConfig[8][2] = { {GPIO_PA0_U0RX, GPIO_PA1_U0TX}, {GPIO_PC4_U1RX, GPIO_PC5_U1TX}, {GPIO_PD6_U2RX, GPIO_PD7_U2TX}, {GPIO_PC6_U3RX, GPIO_PC7_U3TX}, {GPIO_PC4_U4RX, GPIO_PC5_U4TX}, {GPIO_PE4_U5RX, GPIO_PE5_U5TX}, {GPIO_PD4_U6RX, GPIO_PD5_U6TX}, {GPIO_PE0_U7RX, GPIO_PE1_U7TX} };

static const unsigned long g_ulUARTPort[8] = { GPIO_PORTA_BASE, GPIO_PORTC_BASE, GPIO_PORTD_BASE, GPIO_PORTC_BASE, GPIO_PORTC_BASE, GPIO_PORTE_BASE, GPIO_PORTD_BASE, GPIO_PORTE_BASE };

static const unsigned long g_ulUARTPins[8] = { GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_6 | GPIO_PIN_7, GPIO_PIN_6 | GPIO_PIN_7, GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_0 | GPIO_PIN_1 };

// Constructors //////////////////////////////////////////////////////////////// HardwareSerial::HardwareSerial(void) { txWriteIndex = 0; txReadIndex = 0; rxWriteIndex = 0; rxReadIndex = 0; uartModule = 0;

txBuffer = (unsigned char *) 0xFFFFFFFF;
rxBuffer = (unsigned char *) 0xFFFFFFFF;
txBufferSize = SERIAL_BUFFER_SIZE;
rxBufferSize = SERIAL_BUFFER_SIZE;

}

HardwareSerial::HardwareSerial(unsigned long module) { txWriteIndex = 0; txReadIndex = 0; rxWriteIndex = 0; rxReadIndex = 0; uartModule = module;

txBuffer = (unsigned char *) 0xFFFFFFFF;
rxBuffer = (unsigned char *) 0xFFFFFFFF;
txBufferSize = SERIAL_BUFFER_SIZE;
rxBufferSize = SERIAL_BUFFER_SIZE;

} // Private Methods ////////////////////////////////////////////////////////////// void HardwareSerial::flushAll(void) { // wait for transmission of outgoing data while(!TX_BUFFER_EMPTY) { } txReadIndex = 0; txWriteIndex = 0;

//
// Flush the receive buffer.
//
rxReadIndex = 0;
rxWriteIndex = 0;

}

void HardwareSerial::primeTransmit(unsigned long ulBase) { // // Do we have any data to transmit? // if(!TX_BUFFER_EMPTY) { // // Disable the UART interrupt. If we don't do this there is a race // condition which can cause the read index to be corrupted. // ROM_IntDisable(g_ulUARTInt[uartModule]); // // Yes - take some characters out of the transmit buffer and feed // them to the UART transmit FIFO. // while(!TX_BUFFER_EMPTY) { while(ROM_UARTSpaceAvail(ulBase) && !TX_BUFFER_EMPTY){ ROM_UARTCharPutNonBlocking(ulBase, txBuffer[txReadIndex]);

            txReadIndex = (txReadIndex + 1) % txBufferSize;
        }
    }

    //
    // Reenable the UART interrupt.
    //
    ROM_IntEnable(g_ulUARTInt[uartModule]);
}

}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(unsigned long baud) { baudRate = baud; // // Initialize the UART. // ROM_SysCtlPeripheralEnable(g_ulUARTPeriph[uartModule]);

//TODO:Add functionality for PinConfigure with variable uartModule
ROM_GPIOPinConfigure(g_ulUARTConfig[uartModule][0]);
ROM_GPIOPinConfigure(g_ulUARTConfig[uartModule][1]);

ROM_GPIOPinTypeUART(g_ulUARTPort[uartModule], g_ulUARTPins[uartModule]);

ROM_UARTConfigSetExpClk(UART_BASE, ROM_SysCtlClockGet(), baudRate,
                        (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |
                         UART_CONFIG_WLEN_8));
//
// Set the UART to interrupt whenever the TX FIFO is almost empty or
// when any character is received.
//
ROM_UARTFIFOLevelSet(UART_BASE, UART_FIFO_TX1_8, UART_FIFO_RX1_8);
flushAll();
ROM_UARTIntDisable(UART_BASE, 0xFFFFFFFF);
ROM_UARTIntEnable(UART_BASE, UART_INT_RX | UART_INT_RT);
ROM_IntEnable(g_ulUARTInt[uartModule]);

//
// Enable the UART operation.
//
ROM_UARTEnable(UART_BASE);

// Allocate TX & RX buffers
if (txBuffer != (unsigned char *)0xFFFFFFFF)  // Catch attempts to re-init this Serial instance by freeing old buffer first
    free(txBuffer);
if (rxBuffer != (unsigned char *)0xFFFFFFFF)  // Catch attempts to re-init this Serial instance by freeing old buffer first
    free(rxBuffer);
txBuffer = (unsigned char *) malloc(txBufferSize);
rxBuffer = (unsigned char *) malloc(rxBufferSize);

SysCtlDelay(100);

}

void HardwareSerial::setBufferSize(unsigned long txsize, unsigned long rxsize) { if (txsize > 0) txBufferSize = txsize; if (rxsize > 0) rxBufferSize = rxsize; }

void HardwareSerial::setModule(unsigned long module) { ROM_UARTIntDisable(UART_BASE, UART_INT_RX | UART_INT_RT); ROM_IntDisable(g_ulUARTInt[uartModule]); uartModule = module; begin(baudRate);

} void HardwareSerial::setPins(unsigned long pins) { if(pins == UART1_PORTB) { ROM_GPIOPinConfigure(GPIO_PB0_U1RX); ROM_GPIOPinConfigure(GPIO_PB1_U1TX); ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); } else { //Default UART1 Pin Muxing ROM_GPIOPinConfigure(g_ulUARTConfig[1][0]); ROM_GPIOPinConfigure(g_ulUARTConfig[1][1]); ROM_GPIOPinTypeUART(g_ulUARTPort[1], g_ulUARTPins[1]); } }

void HardwareSerial::end() { unsigned long ulInt = ROM_IntMasterDisable();

flushAll();

//
// If interrupts were enabled when we turned them off, turn them
// back on again.
//
if(!ulInt)
{
    ROM_IntMasterEnable();
}

ROM_IntDisable(g_ulUARTInt[uartModule]);
ROM_UARTIntDisable(UART_BASE, UART_INT_RX | UART_INT_RT);

}

int HardwareSerial::available(void) { return((rxWriteIndex >= rxReadIndex) ? (rxWriteIndex - rxReadIndex) : SERIAL_BUFFER_SIZE - (rxReadIndex - rxWriteIndex)); }

int HardwareSerial::peek(void) { unsigned char cChar = 0;

//
// Wait for a character to be received.
//
while(RX_BUFFER_EMPTY)
{
    //
    // Block waiting for a character to be received (if the buffer is
    // currently empty).
    //
}

//
// Read a character from the buffer.
//
cChar = rxBuffer[rxReadIndex];
//
// Return the character to the caller.
//
return(cChar);

}

int HardwareSerial::read(void) { unsigned char cChar = peek(); rxReadIndex = ((rxReadIndex) + 1) % SERIAL_BUFFER_SIZE; return(cChar); }

void HardwareSerial::flush() { while(!TX_BUFFER_EMPTY); }

size_t HardwareSerial::write(uint8_t c) {

unsigned int numTransmit = 0;
//
// Check for valid arguments.
//
ASSERT(c != 0);

/* //this is not necessary: https://github.com/energia/Energia/issues/225 // // If the character to the UART is \n, then add a \r before it so that // \n is translated to \n\r in the output. //

// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit

if(c == '\n')
{
    while (TX_BUFFER_FULL);
    txBuffer[txWriteIndex] = '\r';
    txWriteIndex = (txWriteIndex + 1) % SERIAL_BUFFER_SIZE;
    numTransmit ++;
}

*/ // // Send the character to the UART output. // while (TX_BUFFER_FULL); txBuffer[txWriteIndex] = c; txWriteIndex = (txWriteIndex + 1) % SERIAL_BUFFER_SIZE; numTransmit ++;

//
// If we have anything in the buffer, make sure that the UART is set
// up to transmit it.
//
if(!TX_BUFFER_EMPTY)
{
    primeTransmit(UART_BASE);
    ROM_UARTIntEnable(UART_BASE, UART_INT_TX);
}

//
// Return the number of characters written.
//
return(numTransmit);

}

void HardwareSerial::UARTIntHandler(void){ unsigned long ulInts; long lChar; // Get and clear the current interrupt source(s) // ulInts = ROM_UARTIntStatus(UART_BASE, true); ROM_UARTIntClear(UART_BASE, ulInts);

// Are we being interrupted because the TX FIFO has space available?
//
if(ulInts & UART_INT_TX)
{
    //
    // Move as many bytes as we can into the transmit FIFO.
    //
    primeTransmit(UART_BASE);

    //
    // If the output buffer is empty, turn off the transmit interrupt.
    //
    if(TX_BUFFER_EMPTY)
    {
        ROM_UARTIntDisable(UART_BASE, UART_INT_TX);
    }
}
if(ulInts & (UART_INT_RX | UART_INT_RT))
{
    while(ROM_UARTCharsAvail(UART_BASE))
        {

        //
        // Read a character
        //
        lChar = ROM_UARTCharGetNonBlocking(UART_BASE);
        //
        // If there is space in the receive buffer, put the character
        // there, otherwise throw it away.
        //
        uint8_t volatile full = RX_BUFFER_FULL;
        if(full) break;

        rxBuffer[rxWriteIndex] =
            (unsigned char)(lChar & 0xFF);
        rxWriteIndex = ((rxWriteIndex) + 1) % SERIAL_BUFFER_SIZE;

        //
        // If we wrote anything to the transmit buffer, make sure it actually
        // gets transmitted.
        //
    }
    primeTransmit(UART_BASE);
    ROM_UARTIntEnable(UART_BASE, UART_INT_TX);
}

}

void UARTIntHandler(void) { Serial.UARTIntHandler(); }

void UARTIntHandler1(void) { Serial1.UARTIntHandler(); }

void UARTIntHandler2(void) { Serial2.UARTIntHandler(); }

void UARTIntHandler3(void) { Serial3.UARTIntHandler(); }

void UARTIntHandler4(void) { Serial4.UARTIntHandler(); }

void UARTIntHandler5(void) { Serial5.UARTIntHandler(); }

void UARTIntHandler6(void) { Serial6.UARTIntHandler(); }

void UARTIntHandler7(void) { Serial7.UARTIntHandler(); }

void serialEvent() attribute((weak)); void serialEvent() {} void serialEvent1() attribute((weak)); void serialEvent1() {} void serialEvent2() attribute((weak)); void serialEvent2() {} void serialEvent3() attribute((weak)); void serialEvent3() {} void serialEvent4() attribute((weak)); void serialEvent4() {} void serialEvent5() attribute((weak)); void serialEvent5() {} void serialEvent6() attribute((weak)); void serialEvent6() {} void serialEvent7() attribute((weak)); void serialEvent7() {}

void serialEventRun(void) { if (Serial.available()) serialEvent(); if (Serial1.available()) serialEvent1(); if (Serial2.available()) serialEvent2(); if (Serial3.available()) serialEvent3(); if (Serial4.available()) serialEvent4(); if (Serial5.available()) serialEvent5(); if (Serial6.available()) serialEvent6(); if (Serial7.available()) serialEvent7(); }

HardwareSerial Serial; HardwareSerial Serial1(1); HardwareSerial Serial2(2); HardwareSerial Serial3(3); HardwareSerial Serial4(4); HardwareSerial Serial5(5); HardwareSerial Serial6(6); HardwareSerial Serial7(7); /*


ifndef HardwareSerial_h

define HardwareSerial_h

include

include "Stream.h"

define SERIAL_BUFFER_SIZE 64

define UART1_PORTB 0

define UART1_PORTC 1

class HardwareSerial : public Stream {

private:
    unsigned char *txBuffer;
    unsigned long txBufferSize;
    unsigned long txWriteIndex;
    unsigned long txReadIndex;
    unsigned char *rxBuffer;
    unsigned long rxBufferSize;
    unsigned long rxWriteIndex;
    unsigned long rxReadIndex;
    unsigned long uartModule;
    unsigned long baudRate;
    void flushAll(void);
    void primeTransmit(unsigned long ulBase);

public:
    HardwareSerial(void);
    HardwareSerial(unsigned long);
    void begin(unsigned long);
    void setBufferSize(unsigned long, unsigned long);
    void setModule(unsigned long);
    void setPins(unsigned long);
    void end(void);
    virtual int available(void);
    virtual int peek(void);
    virtual int read(void);
    virtual void flush(void);
    void UARTIntHandler(void);
    virtual size_t write(uint8_t c);
    using Print::write; // pull in write(str) and write(buf, size) from Print

};

extern HardwareSerial Serial; extern HardwareSerial Serial1; extern HardwareSerial Serial2; extern HardwareSerial Serial3; extern HardwareSerial Serial4; extern HardwareSerial Serial5; extern HardwareSerial Serial6; extern HardwareSerial Serial7;

extern "C" void UARTIntHandler(void); extern "C" void UARTIntHandler1(void); extern "C" void UARTIntHandler2(void); extern "C" void UARTIntHandler3(void); extern "C" void UARTIntHandler4(void); extern "C" void UARTIntHandler5(void); extern "C" void UARTIntHandler6(void); extern "C" void UARTIntHandler7(void);

extern void serialEventRun(void) attribute((weak));

endif

bmagyar commented 9 years ago

Hey @blueminerals ,

How urgent is this for you?

I have a fully working implementation of rosserial on the Tiva both using Energia and the advanced way using Code Composer Studio with only the TivaWare libraries. Be warned! These videos may be less professional than what you expect ;) https://www.youtube.com/watch?v=I4dPV7aJafk https://www.youtube.com/watch?v=--hj8MRKHUM

I am planning to release the package soon, since I see great potential in this board. Any ideas where it should go? Here, along with the rest of the rosserial stuff, or should I release it from me own repo?

PaulBouchier commented 9 years ago

Just a quick observation: your arduino_hardware.h has baud rate set to default to 57600, which is the default, but your rosserial_python prints that it's connecting at 9600. Check the baud rates on the wire. It looks like it just can't start talking.

blueminerals commented 9 years ago

It is not urgent at all, because we couldn’t get it to work, we went to a different approach. I would suggest github for the repo. Thanks for your work. The Launchpads are cheap and have quadrature decoders. They have come out with the 129 with is 120 mhz and has Ethernet.

From: Bence Magyar [mailto:notifications@github.com] Sent: Thursday, March 19, 2015 6:23 PM To: ros-drivers/rosserial Cc: blueminerals Subject: Re: [rosserial] rosserial with the ti tm4c123 launchpad. It won't connect (#100)

Hey @blueminerals https://github.com/blueminerals ,

How urgent is this for you?

I have a fully working implementation of rosserial on the Tiva both using Energia and the advanced way using Code Composer Studio with only the TivaWare libraries. Be warned! These videos may be less professional than what you expect ;) https://www.youtube.com/watch?v=I4dPV7aJafk https://www.youtube.com/watch?v=--hj8MRKHUM

I am planning to release the package soon, since I see great potential in this board. Any ideas where it should go? Here, along with the rest of the rosserial stuff, or should I release it from me own repo?

— Reply to this email directly or view it on GitHub https://github.com/ros-drivers/rosserial/issues/100#issuecomment-83785178 .Image removed by sender. Web Bug from https://github.com/notifications/beacon/AFuTFoGzPd4ZfszUes1Zu4vR6CheGLfZks5n20PGgaJpZM4BkFtl.gif