neophob / PixelController

(LED) Matrix Control Software, supports various Hardware, Keywords: LED Matrix, OSC, Realtime, VJ, Arduino, Teensy, RPI
www.pixelinvaders.ch
GNU General Public License v3.0
286 stars 103 forks source link

Rainbowduino v3.0b freezes after a few seconds #36

Closed devinejohnny closed 11 years ago

devinejohnny commented 11 years ago

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.

neophob commented 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)?

devinejohnny commented 11 years ago

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!

devinejohnny commented 11 years ago

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

define DDR_DATA DDRB

define DDR_CLK DDRB

define DDR_LINES DDRD

define PORT_DATA PORTB

define PORT_CLK PORTB

define PORT_LINES PORTD

define BIT_DATA 0x01

define BIT_CLK 0x02

define BIT_LINES 0xF0

// 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; } }

devinejohnny commented 11 years ago

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.

devinejohnny commented 11 years ago

Does my config file look ok?

#

Copyright (C) 2011-2013 Michael Vogt michu@neophob.com

#

This file is part of PixelController.

#

PixelController is free software: you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation, either version 3 of the License, or

(at your option) any later version.

#

PixelController is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

#

You should have received a copy of the GNU General Public License

along with PixelController. If not, see http://www.gnu.org/licenses/.

#

=========================

default values for generators

=========================

initial.image.simple=logo.gif initial.blinken=torus.bml initial.text=PIXELINVADERS

font.filename=04B_03__.TTF font.size=82

x/y offset for screen capturing generator

if you define screen.capture.window.size.x as 0, the screen capture generator will be disabled

screen.capture.offset=100 screen.capture.window.size.x=0

screen.capture.window.size.x=500

screen.capture.window.size.y=300

=========================

network port config

=========================

fudi protocol config, used to communicate with pure data sketch

net.listening.port=3448 net.listening.addr=127.0.0.1 net.send.port=3449

osc protocol config

osc.listening.port=9876

=========================

frames per second

=========================

fps=25

=========================

display internal gui window and debug buffer?

=========================

show.debug.window=true maximal.debug.window.xsize=600

=========================

per default you get # of output windows + 1 visuals

maybe you need more, so add them here if you want...

=========================

additional.visual.screens=0

=========================

the size of the software output matrix

=========================

led.pixel.size=20

=========================

start in random mode?

=========================

startup.in.randommode=false

=========================

load a preset if PixelController starts?

Warning, this will overwrite your settings configured above (initial generator values)!

=========================

startup.load.preset.nr=1

=========================

use audio as input setting (true)

or just regular fps (false)

=========================

update.generators.by.sound=true

OUTPUT SETTINGS

enable only ONE output device (PixelInvaders, RainbowduinoV2, RainbowduinoV3, Art-Net, TPM2, UDP, Adafruit or Minidmx)

=========================

optional, defines the color order of the output device

this option is used for ALL output devices, if you have multiple panels you must define

multiple entries, for example if you have 3 panels you need to define "BRG,BRG,BRG"

#

if this setting is commented out, RGB color order is assumed for all panels

=========================

panel.color.order=RGB

=========================

Apply gamma correction for output panels

Valid options

- NONE

- GAMMA_20: apply gamma 2.0 correction

- GAMMA_25: apply gamma 2.5 correction

- SPECIAL1: apply special gamma correction

=========================

panel.gamma.tab=GAMMA_25

=========================

Settings for PixelInvaders panels, valid options:

=========================

NO_ROTATE,

ROTATE_90,

ROTATE_90_FLIPPEDY,

ROTATE_180,

ROTATE_180_FLIPPEDY,

ROTATE_270,

=========================

HINT: you define how many PixelInvaders panels are in use, in this example we use four panels.

pixelinvaders.layout.row1=NO_ROTATE,NO_ROTATE

pixelinvaders.layout.row2=NO_ROTATE,NO_ROTATE

do not try this device for autodetection

pixelinvaders.blacklist.devices=/dev/ttyUSB000

if you have multiple pixelinvaders panels wired up special, you can define this here.

if you don't define this setting, the "default wiring" is expected

example (the number define the wiring direction):

+---+---+---+

| 0 | 3 | 4 |

+---+---+---+

| 1 | 2 | 5 |

+---+---+---+

HINT: the first panel is 0!

pixelinvaders.panel.order=0,3,4,1,2,5

pixelinvaders.panel.ip=192.168.111.22

pixelinvaders.panel.port=5333

=========================

settings for null output

=========================

nulloutput.devices.row1=2

nulloutput.devices.row2=0

=========================

settings for rainbowduinoV2

=========================

i2c destination address + layout definition

layout.row1.i2c.addr=5,6

layout.row2.i2c.addr=8,9

=========================

settings for rainbowduinoV3

=========================

serial device names + layout definition

on Linux/OSX use names like "/dev/ttyUSB1"

on Windows use names like "COM1"

This is for one of my boards:

layout.row1.serial.devices=/dev/tty.usbserial-AD01W4YR

This is for my other board:

layout.row1.serial.devices=/dev/tty.usbserial-A901LS8Z

layout.row2.serial.devices=/dev/ttyUSB2,/dev/ttyUSB3

=========================

settings for stealth panel

=========================

stealth.layout.row1=NO_ROTATE

=========================

settings for Art-Net, Null output, Minidmx, UDP, TPM2 and Adavision

=========================

output.resolution.x=8

output.resolution.y=8

flip each second scanline

output.snake.cabling=true

OR use manual image mapping, instead of the snake cabling setting.

the output mapping table should contain output.resolution.x * output.resolution.y entries

REMEMBER: the first outputs starts at 0 NOT 1!

output.mapping=0,1,4,5,2,3...

optional rotate image, valid options:

NO_ROTATE (default),

ROTATE_90,

ROTATE_90_FLIPPEDY,

ROTATE_180,

ROTATE_180_FLIPPEDY,

ROTATE_270

output.layout=NO_ROTATE

=========================

settings for Art-Net

Info: PixelController supports more than 1 universe

do NOT FORGET to define the output resolution above!

=========================

artnet.ip=192.168.1.2

define how many rgb pixels are used on a universe, maximal 170 (=510 Channels)

artnet.pixels.per.universe=170

define the first universe id

artnet.first.universe.id=1

=========================

settings for udp "device"

do NOT FORGET to define the output resolution above!

=========================

send to this address

udp.ip=192.168.111.25

udp.port=6803

=========================

settings for tpm2 device

do NOT FORGET to define the output resolution above!

=========================

Where is the TPM2 device connected?

on Linux/OSX use names like "/dev/ttyUSB1"

on Windows use names like "COM1"

tpm2.device=/whatever/youwant

tpm2.baudrate=115200

=========================

settings for tpm2.net device

do NOT FORGET to define the output resolution above!

=========================

tpm2net.ip=192.168.111.25

define layout, valid options:

NO_ROTATE (default),

ROTATE_90,

ROTATE_90_FLIPPEDY,

ROTATE_180,

ROTATE_180_FLIPPEDY,

ROTATE_270

HINT: you define how many Tpm2Net panels are in use, in this example we use four panels.

tpm2net.layout.row1=NO_ROTATE,NO_ROTATE

tpm2net.layout.row2=NO_ROTATE,NO_ROTATE

=========================

settings for miniDmx (like the SEDU board)

do NOT FORGET to define the output resolution above!

=========================

minidmx.baudrate=115200

=========================

settings for adavision

do NOT FORGET to define the output resolution above!

=========================

define serial port

on Linux/OSX use names like "/dev/ttyUSB1"

on Windows use names like "COM1"

adavision.serial.port=/dev/tty.Whatever

optional: define serial speed

adavision.baudrate=115200

EOF

devinejohnny commented 11 years ago

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.

neophob commented 11 years ago

ok glad it works. Hint: you may increase that value to 60, as thats the usb buffer size.