## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0=[[rosserial_arduino/Tutorials/Hello World|Hello World (example Publisher)]] ## descriptive title for the tutorial ## title = Advanced Configuration for NodeHandle and ArduinoHardware. ## multi-line description to be displayed in search ## description = This tutorial shows step by step how to configure NodeHandle and ArduinoHareware to better suit user needs. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= ## next.1.link= ## what level user is this tutorial for ## level= AdvancedCategory ## keywords = #################################### <> The `rosserial_arduino` package is designed to work out-of-box for many users, but users might need to change the `ros.h` and the `ArduinoHardware.h` to better suit their need. In this tutorial, we will be changing both the file to demonstrate some of the advanced settings. == Prerequisite == === Hardware === * [[https://store.arduino.cc/usa/arduino-mega-2560-rev3|Arduino Mega]] * [[https://www.sparkfun.com/products/9716| FTDI Breakout board]] or similar UART to USB bridge * USB cables for both devices * Some jumper wire to connect both devices === Objectives === ==== Publisher/Subscriber Numbers and Input/Output Buffers ==== Arduino Mega has 8 kB of SRAM, much more than most of the other Arduino boards (Uno has 2 kB, Leonardo has 2.5 kB). This enable us to have more Publishers/Subscribers and use bigger messages. While we might never need change those numbers for Arduino Mega as the default value is plenty enough, for smaller board that has limited SRAM, we would need to reduce the memory usage. For the sake for demonstrating how to do it, we will decrease the number of publisher/subscriber from 25/25 to 10/15, and the input/output buffer size for 512/512 bytes to 128/256 bytes. ==== Change the Serial Port ==== Arduino Mega has 4 serial port in total: || '''Object Name''' || '''RX Pin''' || '''TX Pin''' || || Serial || 0 || 1 || || Serial1 || 19 || 18 || || Serial2 || 17 || 16 || || Serial3 || 15 || 14 || Normally, we use `Serial` to communicate with Arduino Mega, as `Serial` is connected to the UART to USB bridge, and shows as the port we see on the computer. But for this tutorial, we will be using the `Serial1`. Because the `Serial1` can not communicate directly with the computer, we use a UART to USB bridge ([[https://www.sparkfun.com/products/9716|FTDI board]]). ==== Change the Baudate ==== By default the rosserial uses `57600` as the [[https://www.mathworks.com/help/matlab/matlab_external/baudrate.html|baudrate]] for communication. This rate is not the maximum that Arduino can achieve, and when there is a lot of information that need to sent back to ROS, the baudrate can become the bottleneck. The Arduino Mega that operate at 16 Mhz can communicate wit baudrate up to 2M bits per seconds (bps) and other boards such as [[https://www.pjrc.com/teensy/td_uart.html|Teensy 3.2]] can go up to 4.6 Mbps. The inefficiency of Arduino Serial library quickly become the bottleneck at high baudrate and we can't really benefit from the increased baudrate. (more information on this [[https://arduino.stackexchange.com/questions/296/how-high-of-a-baud-rate-can-i-go-without-errors|here]]) For this tutorial, we will be changing the baudrate from 57.6 Kbps to 500 Kbps. == The code == We will have 3 source files for this example. The main sketch, the `ros.h` and the `ArduinoHardware.h`. Because many of our changes are under the hood and do not affect how we use rosserial, the hello world sketch is used with minimal modification. The original `ros.h` and `ArduinoHardware.h` can be found either in the `src/ros_lib/` of `rosserial_arduino` package, or in the generated `ros_lib` in your Arduino library. You can modify them directly to achieve the same effect but it is recommended to add them to your sketch folder, to make the change per sketch and persistent over regeneration of `ros_lib`. === Main Sketch === We will first create a new sketch and copy the following code to it: {{{ #!cplusplus block=hello /* * rosserial Publisher Example * Prints "hello world!" */ #include "ros.h" #include ros::NodeHandle nh; std_msgs::String str_msg; ros::Publisher chatter("chatter", &str_msg); char hello[13] = "hello world!"; void setup() { nh.initNode(); nh.advertise(chatter); } void loop() { str_msg.data = hello; chatter.publish( &str_msg ); nh.spinOnce(); delay(1000); } }}} === ros.h === `ros.h` is the `NodeHandle` definition, and we will create a new tab in Arduino by click on the down arrow icon below Serial Monitor, name it `ros.h`, and copy the following content to it: {{{ #!cplusplus block=ros_h #ifndef _ROS_H_ #define _ROS_H_ #include "ros/node_handle.h" #include "ArduinoHardware.h" namespace ros { // default is 25, 25, 512, 512 typedef NodeHandle_ NodeHandle; // This is legal too and will use the default 25, 25, 512, 512 //typedef NodeHandle_ NodeHandle; } #endif }}} === ArduinoHardware.h === `ArduinoHardware.h`, hardware definition for Arduino platform, similarly to `ros.h`, we will create a new tab named `ArduinoHardware.h` and copy the following code to it: {{{ #!cplusplus block=hw_h #ifndef ROS_ARDUINO_HARDWARE_H_ #define ROS_ARDUINO_HARDWARE_H_ #if ARDUINO>=100 #include #else #include #endif #include #define SERIAL_CLASS HardwareSerial class ArduinoHardware { public: ArduinoHardware() { iostream = &Serial1; baud_ = 500000; } 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; iwrite(data[i]); } } unsigned long time() { return millis(); } protected: SERIAL_CLASS* iostream; long baud_; }; #endif }}} == The Code Explained == === The Main Sketch === <> The only difference that we found it the main sketch is how `ros.h` is included, the brackets `` in the original `hello world` are replaced by quotation marks `"ros.h"`. This tells the compiler to look for the file in local path before search it in other libraries. Everything else are the same as the hello world example. === ros.h === <> This set our `NodeHandle` to have 10 Publishers, 15 Subscriber, 128 bytes for input buffer and 256 bytes for output buffer. === ArduinoHardware.h === <> Here we include the header for the serial object we communicate with. The serial object class must have `read()`, `write()` and `begin(baudrate)` member function implemented. `Serial`, and `Serial1` are both `HardwareSerial` objects. <> Here we create the default constructor for `ArduinoHardware` and set the serial port we use to `Serial1` and baudrate to 500 kbps. == Compile and Upload the Code == The code is compile and upload as usual. After compilation, you will be able to see a message of the code like this {{{ Sketch uses 9,552 bytes (3%) of program storage space. Maximum is 253,952 bytes. Global variables use 1,130 bytes (13%) of dynamic memory, leaving 7,062 bytes for local variables. Maximum is 8,192 bytes. }}} By varying the buffer sizes and Publishers/Subscribers numbers, the dynamic memory usage will change as well. == Running the Code == We will be using `Serial1` to communicate with ROS now. Disconnect the USB cable from Arduino, Connect the FTDI breakout board to the Arduino Mega as following: {{{ FTDI Arduino Mega VCC -> 5V TXO -> Pin 19 RXI -> Pin 18 GND -> GND }}} Connect the FTDI breakout board to the computer using USB cable. Now, launch the [[roscore]] in a new terminal window: {{{ roscore }}} Next, run the rosserial client application that forwards your Arduino messages to the rest of ROS. Make sure to use the correct serial port: {{{ rosrun rosserial_python serial_node.py _port:=/dev/ttyUSB0 _baud:=500000 }}} Finally, watch the greetings come in from your Arduino by launching a new terminal window and entering : {{{ rostopic echo chatter }}} == Extras == `ros.h` and `ArduinoHardware.h` license. {{{ #!cplusplus /* * Software License Agreement (BSD License) * * Copyright (c) 2011, Willow Garage, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of Willow Garage, Inc. nor the names of its * contributors may be used to endorse or promote prducts derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ }}} ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE