ros-drivers / rosserial

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

ROS subscriber seems to block Adafruit NeoMatrix library #332

Closed 4al closed 6 years ago

4al commented 6 years ago

I'm using the following setup:

If I try only a rosserial example (Blink) or only a NeoMatrix example (matrixtest) I get perfect results. But when I combine both libraries into one sketch, the ROS subscriber seems to block the functions of the Adafruit NeoMatrix library.

Space should be sufficient:

Sketch uses 15350 bytes (47%) of program storage space. Maximum is 32256 bytes. Global variables use 1101 bytes (53%) of dynamic memory, leaving 947 bytes for local variables. Maximum is 2048 bytes.

This is a minmal working example

include "ros.h"

include "std_msgs/Float32.h"

include "Adafruit_NeoMatrix.h"

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, 6, NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG, NEO_GRB + NEO_KHZ800);

void CallbackFunction( const std_msgs::Float32& msg) { // LED does blink digitalWrite(13, HIGH-digitalRead(13));

// LED matrix doesn't change output matrix.fillScreen(0); matrix.setCursor(0, 0); matrix.print(F("Callback")); matrix.show(); }

ros::NodeHandle_<ArduinoHardware, 10, 10, 150, 150> nodeHandle;

// This has to be commented out for the LED matrix to work //ros::Subscriber subscriber("led", &CallbackFunction);

void setup() { pinMode(13, OUTPUT);

matrix.begin(); matrix.setTextWrap(false); matrix.setBrightness(25); matrix.setTextColor(matrix.Color(0, 255, 0));

nodeHandle.initNode();

// This has to be commented out for the LED matrix to work //nodeHandle.subscribe(subscriber); }

void loop() { // This has to be commented out for the LED matrix to work //nodeHandle.spinOnce();
//delay(1);

// LED matrix doesn't change output when nodeHandle.spinOnce() is included matrix.fillScreen(0); matrix.setCursor(0, 0); matrix.print(F("Text")); matrix.show();

delay(100); }

Does rosserial change the configuration of the GPIO pins? I'm using pin number 6 on the Arduino Uno as DATA in.

romainreignier commented 6 years ago

I may be mistaken but I think that the Neopixel Library from Adafruit is blocking it may be possible that the show() method block for too long the program and cause some timeouts for example.

Note that there was an error on the timeout computation that was fixed last month by this commit but that is not yet in the version in Kinetic repos.

So maybe you could try with the latest git version of rosserial.

4al commented 6 years ago

Thanks for the quick reply. I've just tried the latest git version of rosserial, but experienced the same behaviour.

I've replaced the Adafruit NeoPixel library for test purposes with a different one (FastLED) and it worked together with rosserial, however the dynamic memory increased to about 94%.

So I guess the Adafruit library seems to interfere with rosserial somehow.

romainreignier commented 6 years ago

Yes, the NeoPixel library from Adafruit (on which is based NeoMatrix library) is very low-level and block the processor with assembly instructions see here to update every LEDs.

If you want to do other things on your microcontroller, I would advise you to try a Teensy 3.2 board with a non-blocking library for WS2812 LEDs. The Teensy is cheaper than an official Arduino UNO board, but much more powerful and also supported by this same rosserial_arduino library.

Edit: Actually, the Teensy LC is even cheaper and more suitable to drive 5V Led ribbon with a trick explained in the README of the library.

4al commented 6 years ago

Thanks for the investigation! I'll have a closer look at the Teensy boards.