Closed devinejohnny closed 11 years ago
Hmm well PixelController already works with the Rainbowduino v3. However it looks like your Rainbowduino board is crashing.
Can you replace the board to make sure its not a HW issue?
While you was editing the wire and twi files, you Arduino IDE was closed?
What Arduino version do you use?
Try to replace the USB cable (maybe with a shorter one)
What happens if you don't power up your DIY LED Matrix (only the Rainbowduino board)?
Thanks for the response and suggestions.
I have another v3.0b board, so I swapped it out and tried again. The result was the same.
When I edited the .h files Arduino IDE was closed. I just checked both files to make sure the changes were in place, then relaunched the IDE, uploaded the firmware, and opened PixelController. The issue is still present.
I'm using Arduino 1.0.5 on both my Mac and PC.
I unplugged my matrix from the Rainbowduino and launched PixelController. The issue is still present (both the TX and RX lights on the Rainbowduino will flash for a couple seconds, then the TX turns off, but the RX continues to blink).
The last thing for me to try is the new cable. I'm using a 3 foot cable right now, but I'll go buy some other options and report back.
Thanks for the help so far!
I've tried two new cables (thicker 6 foot cable and a different 3 foot cable) on both Rainbowduinos with the same result.
I uninstalled my Arduino IDE and re-downloaded it. I made the changes to wire.h and twi.h files before launching it. I reloaded the firmware on my Rainbowduino, but am still getting the crash.
Am I using the correct firmware:
/* Rainbowduino V3 firmware capable of streaming 24bit RGB frames with up to 35fps via the USB connector of the Rainbowduino V3 controller.
Author: Markus Lang (m@rkus-lang.de) Websites: http://programmers-pain.de/ https://code.google.com/p/rainbowduino-v3-streaming-firmware/
This firmware is based on several Rainbowduino related firmwares like: neorainbowduino: http://code.google.com/p/neorainbowduino/ rainbowdash: http://code.google.com/p/rainbowdash/ seeedstudio.com: http://www.seeedstudio.com/wiki/Rainbowduino_v3.0
The Java part splits a full 8x8 RGB frame (3 colors * 64 LEDs = 192byte) into four frame fragments (each 48byte) to get around the 64byte default buffer size of the Arduino hardware serial implementation. Each fragment will be extended with the HEADER bits and a frame fragment index to be able to reconstruct the full frame in the correct order inside this firmware.
Splitting up the frame into fragments avoids running into data corruption / data loss if the Java part sends more bytes than the Arduino controller can buffer. For every frame fragment the controller will send an ACK REPLY message to the Java code so that the next fragment will be send.
The firmware is able to handle incomplete frames as well as CRC checksum errors of the transferred LED color data so that it's able to signal those error conditions to the Java API.
The LED update routine of this firmware is just a rewrite of the original seeedstudio.com firmware (http://www.seeedstudio.com/wiki/Rainbowduino_v3.0) including some changes regarding the interrupt handling to allow the controller to update the LEDs and receiving incoming serial data at the same time. */
// ports and bit values needed by the LED update routine
// general const variables const unsigned char RAINBOWDUINO_LEDS = 64; const unsigned char NUMBER_OF_COLORS = 3; const unsigned char RED = 0; const unsigned char GREEN = 1; const unsigned char BLUE = 2; const unsigned char NUMBER_OF_FRAME_FRAGMENTS = 4; const int FRAME_FRAGMENT_LENGTH = ((RAINBOWDUINO_LEDS / NUMBER_OF_FRAME_FRAGMENTS) * NUMBER_OF_COLORS);
// serial protocol related const variables const long BAUD_RATE = 115200; const unsigned char HEADER_LENGTH = 3; const unsigned char ACK_REPLY_LENGTH = 4; const byte HEADER = 0x10; const byte FRAME_FRAGMENTS[NUMBER_OF_FRAME_FRAGMENTS] = {0x20, 0x21, 0x22, 0x23}; // serial protocol state codes const byte STATE_ACK = 0x30; const byte STATE_FRAME_FRAGMENT_INDEX = 0x31; const byte STATE_INCOMPLETE_FRAME = 0x32;
// byte array used to send back ack replies // (HEAHDER, 2 bytes for returned value, ERROR CODE) byte ackReply[ACK_REPLY_LENGTH] = {HEADER, 0, 0, 0};
// byte array used as frame buffers for the currently received and displayed frame // (2 buffers, RGB colors, 8 rows, 8 columns) unsigned char frameBuffers[2][NUMBER_OF_COLORS][8][8]; // the currently used frame buffer by the LED update routine volatile unsigned char currentFrameBuffer; // the current line the LED update routine will push color data for volatile unsigned char currentLine;
// global variables used to parse the incoming serial data byte serialData; // stores the currently parsed byte unsigned char headerCounter; // counts the number of found HEADER bytes int frameFragmentPos; // the relative position in the currently parsed frame fragment int frameFragmentPosOffset; // the offset to the relative position of the currently parsed frame fragment int frameFragmentIndex; // the index of the currently parsed frame fragment int crc; // used to calculate the frame fragment crc value unsigned char currentColor; // used to store the current color index unsigned char currentRow; // used to store the current row index unsigned char currentColumn; // used to store the current column index
void setup() { // initialize global variables used to update the LEDs currentFrameBuffer = 0; currentLine = 0; // initialize global variables used to parse the incoming serial data headerCounter = 0; frameFragmentPos = -1; frameFragmentPosOffset = -1; frameFragmentIndex = -1; crc = 0; currentColor = 0; currentRow = 0; currentColumn = 0; // setup serial communication Serial.begin(BAUD_RATE); // initialize frame buffers array for (unsigned char buffer = 0; buffer < 2; buffer++) { for (unsigned char color = 0; color < NUMBER_OF_COLORS; color++) { for (unsigned char row = 0; row < 8; row++) { for (unsigned char column = 0; column < 8; column++) { frameBuffers[buffer][color][row][column] = 0; } } } } // disable all internal interrupts cli(); // initialize LED update routine and MY9221 state DDR_LINES |= BIT_LINES; PORT_LINES &= ~BIT_LINES; DDRD |= 0x04; DDR_DATA |= BIT_DATA; DDR_CLK |= BIT_CLK; PORT_DATA &= ~BIT_DATA; PORT_CLK &= ~BIT_CLK; DDRB |= 0x20; // clear the display to get a clean state clearDisplay(); // init TIMER 1 (trigger every ~1250us) TCCR1A = 0; TCCR1B = _BV(WGM13); ICR1 = 10000; TIMSK1 = _BV(TOIE1); TCNT1 = 0; TCCR1B |= _BV(CS10); // re-enable all internal interrupts sei(); }
void loop() { // check for available serial data and start parsing after the HEADER bytes have been found while (Serial.available() > 0) { serialData = Serial.read(); // count the number of header bytes if we're not parsing a frame fragment right now if (frameFragmentPos == -1) { if (serialData == HEADER) { headerCounter++; // check if we've counted two HEADER bytes if (headerCounter == 2) { // set the frame fragment position and start the parsing frameFragmentPos = 0; headerCounter = 0; } } else { headerCounter = 0; } continue; }
// check if we need to resolve the frame fragment index
if (frameFragmentPos == 0 && frameFragmentIndex == -1) {
for (unsigned char i = 0; i < NUMBER_OF_FRAME_FRAGMENTS; i++) {
if (serialData == FRAME_FRAGMENTS[i]) {
frameFragmentIndex = i;
frameFragmentPosOffset = frameFragmentIndex * FRAME_FRAGMENT_LENGTH;
break;
}
}
// throw an error in case we couldn't parse the frame fragment index
if (frameFragmentIndex == -1) {
sendAckReply(STATE_FRAME_FRAGMENT_INDEX, serialData);
}
// throw an error in case the frame fragment index doesn't match the
// currentRow counter which indicates that we haven't received the
// frame fragments in the correct order. that can happen if you reset
// the controller manually or if a frame fragment was lost during
// transfer. therefore we'll skip the just received frame index incl.
// it's frame data.
if (frameFragmentIndex * 2 != currentRow) {
sendAckReply(STATE_INCOMPLETE_FRAME, frameFragmentIndex);
}
continue;
}
// store the received byte in the frame buffer and calculate the crc value
if (frameFragmentPos != -1 && frameFragmentPos < FRAME_FRAGMENT_LENGTH) {
// store received color value in the currently used framebuffer
int framePos = frameFragmentPosOffset + frameFragmentPos;
int frameBufferPos = framePos / NUMBER_OF_COLORS;
frameBuffers[currentFrameBuffer][currentColor][currentRow][currentColumn] = serialData;
// reset currentColor pointer if a complete color cycle is done
currentColor++;
if (currentColor == NUMBER_OF_COLORS) {
currentColor = 0;
currentColumn++;
// reset currentColumn pointer if a complete row is done
if (currentColumn == 8) {
currentColumn = 0;
currentRow++;
// reset currentRow pointer if a complete row cycle is done
if (currentRow == 8) {
currentRow = 0;
}
}
}
// calculate crc value for the currently parsed frame fragment
crc = crc + serialData;
// increment the frame fragment position
frameFragmentPos++;
}
// check if we've parsed all bytes of the current frame fragment
if (frameFragmentPos == FRAME_FRAGMENT_LENGTH) {
// switch the currently used frame buffer if we've received the last frame fragment
if (frameFragmentIndex == NUMBER_OF_FRAME_FRAGMENTS) {
currentFrameBuffer = !currentFrameBuffer;
// reset global variables that have been in use to parse the whole frame
currentRow = 0;
currentColumn = 0;
}
// let the java code know that we've parse an entire frame fragment
sendAckReply(STATE_ACK, crc);
}
} }
// send the ack reply message to the serial interface and reset the global parsing variables void sendAckReply(byte stateCode, int value) { // update ack reply array ackReply[1] = value >> 8; ackReply[2] = value; ackReply[3] = stateCode; // send ack reply message Serial.write(ackReply, ACK_REPLY_LENGTH); Serial.flush(); // reset global variables that have been in use to parse the frame fragment frameFragmentPos = -1; frameFragmentPosOffset = -1; frameFragmentIndex = -1; currentColor = 0; crc = 0; }
void send16BitData(unsigned int data) { for (unsigned char i = 0; i < 16; i++) { if (data & 0x8000) { PORT_DATA |= BIT_DATA; } else { PORT_DATA &= ~BIT_DATA; } PORT_CLK ^= BIT_CLK; data <<= 1; } }
void latchData() { PORT_DATA &= ~BIT_DATA; delayMicroseconds(10); PORT_LINES &= ~0x80; for (unsigned char i = 0; i < 8; i++) { PORT_DATA ^= BIT_DATA; } }
void switchOnDrive(unsigned char line) { PORT_LINES &= ~BIT_LINES; PORT_LINES |= (line << 4); PORT_LINES |= 0x80; }
void clearData() { PORT_DATA &= ~BIT_DATA; for (unsigned char i = 0; i < 192; i++) { PORT_CLK ^= BIT_CLK; } }
void clearDisplay() { send16BitData(0); clearData(); send16BitData(0); clearData(); latchData(); }
ISR(TIMER1_OVF_vect) { // re-enable global interrupts, this needs some explanation: // --------------------------------------------------------- // to allow the internal interrupt of the Arduino framework to handle // incoming serial data we need to re-enable the global interrupts // inside this interrupt call of the LED update routine. // usually that's an stupid idea since the LED update rountine interrupt // could also be called a second time while this interrupt call is still // running - this would result in a hanging controller. // since we know that the interrupt is called in a 1250us interval and // the code in this method takes around ~650us to finish we still have // enough buffer to allow the internal interrupt to handle incoming serial // data without risking to block the controller. the time between the next // LED update rountine call is also sufficient to give the controller // enough time to parse the incoming serial data. // this setup was the easiest way out of the problem that the internal // interrupt and the interrupt of the LED update routine do otherwise // result in major data loss and data corruption if we wouldn't re-enable // the global interrupts here. sei(); // determine the frame buffer row to be used for this interrupt call unsigned char row = 7 - currentLine; // clear the data of the former interrupt call to avoid flickering clearDisplay(); // push data to the MY9221 ICs send16BitData(0); // push the blue color value of the current row for (char column = 0; column < 8; column++) { send16BitData(frameBuffers[currentFrameBuffer][BLUE][row][column]); } // push the green color value of the current row for (char column = 0; column < 4; column++) { send16BitData(frameBuffers[currentFrameBuffer][GREEN][row][column]); } send16BitData(0); for (char column = 4; column < 8; column++) { send16BitData(frameBuffers[currentFrameBuffer][GREEN][row][column]); } // push the red color value of the current row for (char column = 0; column < 8; column++) { send16BitData(frameBuffers[currentFrameBuffer][RED][row][column]); } // since the following code is timing-sensitive we have to disable // the global interrupts again to avoid ghosting / flickering of // the other lines that shouldn't be active at all. cli(); latchData(); // activate current line switchOnDrive(currentLine); PORTD &= ~0x04; // increment current led row counter for the next interrupt call currentLine++; if (currentLine == 8) { currentLine = 0; } }
I don't think there is a hardware issue. I bought the boards from different outlets (one from California, the other from Hong Kong) and they are both able to run my DIY LED matrix using the RainbowStudio and the example sketches from SeeedStudio.
Does my config file look ok?
#
#
#
#
#
#
initial.image.simple=logo.gif initial.blinken=torus.bml initial.text=PIXELINVADERS
font.filename=04B_03__.TTF font.size=82
screen.capture.offset=100 screen.capture.window.size.x=0
screen.capture.window.size.y=300
net.listening.port=3448 net.listening.addr=127.0.0.1 net.send.port=3449
osc.listening.port=9876
fps=25
show.debug.window=true maximal.debug.window.xsize=600
additional.visual.screens=0
led.pixel.size=20
startup.in.randommode=false
update.generators.by.sound=true
#
panel.gamma.tab=GAMMA_25
layout.row1.serial.devices=/dev/tty.usbserial-A901LS8Z
Ok! Sorry about that blast of info. I think I have it working stably now.
In the firmware I changed this line: const unsigned char ACK_REPLY_LENGTH = 10;
The variable was set to 4 and I increased it to 6. That allowed it to work a little longer before crashing, but now that I've put it up to 10, my Rainbowduino seems to be running just fine.
Awesome! Thanks again for this great piece of software and extra thanks for sharing it with the world.
ok glad it works. Hint: you may increase that value to 60, as thats the usb buffer size.
First, awesome work. I love what your doing with light and sound and I love even more that you are putting it out here for the public to enjoy.
I see in the other issues here that you are working on getting the v3.0b Rainbowduino to jive with the Pixelcontroller, so this may be what you are currently working on, but I thought I'd throw it out any way.
I've been able to use Pixelcontroller to light up my homemade LED matrix (64 RGB LEDs) via the Rainbowduino v3.0b for about 5 to 10 seconds, at which point it freezes. The RX light on the board continues to flash red, but the image on the matrix does not change.
I've had the same results when I run the program from my Mac and from my PC.
I made the changes to the wire.h and twi.h files (increased frequency to 400 kHz, and buffer size to 98).
Again, if this is the same issue you are already working on with the RainbowduinoV3, feel free to ignore this post, but if you see something simple that I'm doing, I'd love to hear what it is! I feel like I'm so close to having this awesomness up and running!
Here is the log from the last time I ran Pixelcontroller:
Aug 9, 2013 6:23:54 PM com.neophob.PixelController setup INFO: Aug 9, 2013 6:23:54 PM com.neophob.sematrix.setup.InitApplication loadConfiguration INFO: Config loaded, 21 entries Aug 9, 2013 6:23:54 PM com.neophob.sematrix.properties.ApplicationConfigurationHelper
INFO: found RainbowduinoV3 device: 1
Aug 9, 2013 6:23:54 PM com.neophob.sematrix.setup.InitApplication getColorPalettes
INFO: ColorSets loaded, 35 entries
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.input.SoundMinim run
INFO: Sound thread started...
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.glue.MatrixData
INFO: screenSize: 64 (8 * 8),
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.PixelControllerGenerator initAll
INFO: Start init
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: BLINKENLIGHTS
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Blinkenlights
INFO: Blinkenlights, found 20 movie files
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.blinken.BlinkenLibrary loadFile
INFO: Loaded file blinken/torus.bml / 250 frames in 209ms
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: IMAGE
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Image loadFile
INFO: resize to img logo.gif 64, 64
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Image
INFO: Image, found 46 image files
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: PLASMA
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: PLASMA_ADVANCED
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: FIRE
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: PASSTHRU
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: METABALLS
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: PIXELIMAGE
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: TEXTWRITER
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Textwriter
INFO: Loaded font 04B_03__.TTF, size: 82
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: CELL
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: FFT
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: DROPS
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: COLOR_SCROLL
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: COLOR_FADE
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: OSC_GEN1
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: OSC_GEN2
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.Generator
INFO: Generator: internalBufferSize: 4,096 name: VISUAL_ZERO
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.generator.PixelControllerGenerator initAll
INFO: Init finished
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.properties.ApplicationConfigurationHelper loadPresents
INFO: Loaded 101 presents from file data/presents.led
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.jmx.PixelControllerStatus
INFO: Initialize the PixelControllerStatus JMX Bean
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.listener.TcpServer
INFO: Server started at port 3,448
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.listener.TcpServer run
INFO: Ready receiving messages...
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.listener.TcpServer connectToClient
INFO: Pure Data Client not found at 127.0.0.1:3449
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.listener.TcpServer
INFO: Pure Data Client not available yet!
Aug 9, 2013 6:23:55 PM com.neophob.sematrix.listener.OscServer
INFO: Start OSC Server at port 9,876
Aug 9, 2013 6:23:56 PM com.neophob.sematrix.layout.Layout
INFO: Layout created: HORIZONTAL, size row 1: 1, row 2: 0
Aug 9, 2013 6:23:56 PM com.neophob.sematrix.layout.HorizontalLayout
INFO: HorizontalLayout created, size row1: 1, row2:0
Aug 9, 2013 6:23:56 PM com.neophob.sematrix.output.Output
INFO: Output created: RAINBOWDUINO_V3, Layout: HORIZONTAL, BPP: 8, Gamma Correction: GAMMA_25
Aug 9, 2013 6:23:56 PM com.neophob.sematrix.output.RainbowduinoV3Device
INFO: Try to open serial port /dev/tty.usbserial-A901LS8Z
Aug 9, 2013 6:23:57 PM de.programmerspain.rv3sf.api.RainbowduinoV3
INFO: Created RainbowduinoV3 instance using serial port: '/dev/tty.usbserial-A901LS8Z'
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.output.RainbowduinoV3Device
INFO: Rainbowduino output initialized sucessfully
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.layout.Layout
INFO: Layout created: HORIZONTAL, size row 1: 1, row 2: 0
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.layout.HorizontalLayout
INFO: HorizontalLayout created, size row1: 1, row2:0
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.output.gui.GeneratorGuiCreator
INFO: create GUI, nr of screens: 2
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.output.gui.GeneratorGuiCreator
INFO: create frame with size 820/650, aspect: 1.0
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.output.gui.GeneratorGui setup
INFO: Create GUI Window with size 820/650
Aug 9, 2013 6:23:57 PM com.neophob.PixelController asyncInitApplication
INFO: --- PixelController Setup END ---
Aug 9, 2013 6:23:57 PM com.neophob.PixelController asyncInitApplication
INFO: ---------------------------------
Aug 9, 2013 6:23:57 PM com.neophob.PixelController asyncInitApplication
INFO:
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.output.gui.GeneratorGui setup
INFO: GUI logo loaded
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.output.gui.P5EventListener controlEvent
INFO: CURRENT_VISUAL Value: 0.0
Aug 9, 2013 6:23:57 PM com.neophob.sematrix.output.gui.P5EventListener controlEvent
INFO: CURRENT_OUTPUT: 0.0
Aug 9, 2013 6:23:57 PM de.programmerspain.rv3sf.api.RainbowduinoV3 waitForACK
WARNING: No serial ACK reply received for frame fragment 0 after waiting for 50ms. Serial port has only 0 bytes available.
Aug 9, 2013 6:23:57 PM de.programmerspain.rv3sf.api.RainbowduinoV3 waitForACK
WARNING: Controller has returned error code: 'STATE_INCOMPLETE_FRAME', error value: '1'
Aug 9, 2013 6:23:57 PM de.programmerspain.rv3sf.api.RainbowduinoV3 waitForACK
WARNING: Controller has returned error code: 'STATE_INCOMPLETE_FRAME', error value: '2'
Aug 9, 2013 6:23:57 PM de.programmerspain.rv3sf.api.RainbowduinoV3 waitForACK
WARNING: Controller has returned error code: 'STATE_INCOMPLETE_FRAME', error value: '3'
Aug 9, 2013 6:23:59 PM de.programmerspain.rv3sf.api.RainbowduinoV3 waitForACK
WARNING: No serial ACK reply received for frame fragment 3 after waiting for 50ms. Serial port has only 0 bytes available.
Aug 9, 2013 6:23:59 PM de.programmerspain.rv3sf.api.RainbowduinoV3 waitForACK
WARNING: No serial ACK reply received for frame fragment 0 after waiting for 50ms. Serial port has only 0 bytes available.
Aug 9, 2013 6:23:59 PM de.programmerspain.rv3sf.api.RainbowduinoV3 waitForACK
WARNING: No serial ACK reply received for frame fragment 1 after waiting for 50ms. Serial port has only 0 bytes available.