Currently, there are 0 users and 0 guests visiting this topic.
Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #197473
    Johnny T
    Participant
    @johnnyt

    I have an Arduino that is connected to my left/right programmable LEDs.

    I’ve also got an iPac Ultimate and a Sainsmart relay board for some contactors. These work absolutely fine with DOF so I’m assuming everything is set up okay.

    However I can’t get DOF to do anything with my side LEDs.

    I have downloaded the Visual Pinball “DOF Test Table” and have found that when I run the table my system is trying to communicate with my arduino.

    It writes the DirectOutput.log which says:

    2020.08.22 15:48:03.583 Framework initialized.
    2020.08.22 15:48:03.583 Have fun! :)
    2020.08.22 15:48:03.765 EXCEPTION: TeensyStripController LEDStripController updater thread could not connect to the controller. Thread will quit.
    2020.08.22 15:48:03.765 EXCEPTION: Thread: TeensyStripController LEDStripController updater thread
    2020.08.22 15:48:03.765 EXCEPTION: Message: Exception –> Expected 3 bytes containing data on the max number of leds per channel, but the read operation resulted in a exception. Will not send data to the controller
    2020.08.22 15:48:03.767 EXCEPTION: Stacktrace: at DirectOutput.Cab.Out.AdressableLedStrip.TeensyStripController.ConnectToController()
    2020.08.22 15:48:03.767 EXCEPTION: Stacktrace: at DirectOutput.Cab.Out.OutputControllerCompleteBase.UpdaterThreadDoIt()
    2020.08.22 15:48:03.767 EXCEPTION: Targetsite: Void ConnectToController()
    2020.08.22 15:48:03.767 EXCEPTION: InnerException 1: Exception –> A TimeoutException occured while trying to read byte 1 of 3 from Com-Port COM2.
    2020.08.22 15:48:03.767 EXCEPTION: InnerException 2: TimeoutException –> The operation has timed out.
    2020.08.22 15:48:13.730 Finishing framework
    2020.08.22 15:48:13.742 Finishing cabinet

     

    I’ve attached the full DirectOutput.log to this post in case there is other info in there I’ve missed. (** It wouldn’t let me attach my DirectOutput.log for security reasons but if you want it then let me know and I’ll paste it into a reply ***)

    I believe this is the problem:

    Exception –> Expected 3 bytes containing data on the max number of leds per channel, but the read operation resulted in a exception. Will not send data to the controller

    I thought it might be my COM port so I changed to COM port 2 . My settings are (are these correct?):

    comport

    The DOF framework is sending an “M” to the Arduino (I’ve set up my LEDs to display different colours and different LEDs depending on what the DOF sends so I can try and work out what’s happening. My Arduino code is running the SendMaxNumberOfLeds() function back to DOF.

    The function looks like this:

    //Sends the max number of leds per strip
    void SendMaxNumberOfLeds() {
    byte B = MaxLedsPerStrip >> 8;
    Serial.write(B);
    B = MaxLedsPerStrip & 255;
    Serial.write(B);
    Ack();
    }

    //Sends a ack (A)
    void Ack() {
    Serial.write(‘A’);
    }

    So it looks like it’s loading the max number of LEDs (50 is the arbitary number I have in here). It’s shifting value to the right by 8 bits (which, unless I’m mistaken makes ‘B’ equal to zero as it’ll just push the 50 off the byte? It then sends that to DOF.

    Then it ANDs 50 and 255 and sends that to DOF.

    It then sends an “A” letter to DOF.

    However DOF is saying that it expected 3 bytes and didn’t get anything?

    My full arduino code is here (ignore all the references to ledStrip[0].setPixelColor(jtrandled, BLUE); etc.. that’s just so I can test the LEDs).

    /********************************************************************************************************
    ** Arduino Strip Controller
    ** ———————-
    **
    ** This Sketch turns a Arduino into a controller for WS2811/WS2812 based led strips.
    ** This strip controller was originally designed for use with the Direct Output Framework, but since
    ** the communication protocol is simple and communication uses the virtual com port of the Arduino
    ** it should be easy to controll the strips from other applications as well.
    **
    ** Most of the code as been copied from the TeensyStrip Controller, but the OctoWS2811 library
    ** was replaced with the Adafruit_NeoPixel one for compatibility with Arduino
    **
    ** https://github.com/DirectOutput/TeensyStripController
    **
    **
    *********************************************************************************************************/
    /*
    License:
    ——–
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the “Software”), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.

    Required Connections
    ——————–
    pin 2: LED Strip #1 10 possible LED Strips.
    pin 3: LED strip #2
    pin 4: LED strip #3
    pin 5: LED strip #4 A 100 ohm resistor should used
    pin 6: LED strip #5 between each Teensy pin and the
    pin 7: LED strip #6 wire to the LED strip, to minimize
    pin 8: LED strip #7 high frequency ringining & noise.
    pin 9: LED strip #8
    pin 10: LED strip #9
    pin 11: LED strip #10
    pin 12: Test Button. Ground to Test

    */

    #include <elapsedMillis.h>
    #include <Adafruit_NeoPixel.h>

    #define FirmwareVersionMajor 1 // Definiton of Major and Minor part of the firmware version. This value can be received using the V command.
    #define FirmwareVersionMinor 1 // If something is changed in the code the number should be increased.

    #define MaxLedsPerStrip 50 //Defines the max number of leds which is allowed per ledstrip.

    #define LedPin 2 // Defines the Pinnumber to which the built in led is connected.
    #define TestPin 12 // Defines the Pinnumber for the test button which is low when pressed

    elapsedMillis BlinkTimer; // Variable used to control the blinking and flickering of the led of the Teensy
    int BlinkMode;
    elapsedMillis BlinkModeTimeoutTimer;

    const int config = NEO_GRB + NEO_KHZ800; // Config definition for the OctoWS2811 lib. Dont change the color order (even if your strip are GRB). DOF takes care of this issue (see config of ledstrip toy)

    word stripLength=60;
    word numStrips=10;

    Adafruit_NeoPixel ledStrip[] = {
    Adafruit_NeoPixel(stripLength, 2, config),
    Adafruit_NeoPixel(stripLength, 3, config),
    Adafruit_NeoPixel(stripLength, 4, config),
    Adafruit_NeoPixel(stripLength, 5, config),
    Adafruit_NeoPixel(stripLength, 6, config),
    Adafruit_NeoPixel(stripLength, 7, config),
    Adafruit_NeoPixel(stripLength, 8, config),
    Adafruit_NeoPixel(stripLength, 9, config),
    Adafruit_NeoPixel(stripLength, 10, config),
    Adafruit_NeoPixel(stripLength, 11, config)
    };

    //Setup of the system. Is called once on startup.
    void setup() {
    Serial.begin(115200);

    //Initialize the lib for the leds. One instance for each pin, starting pin 2
    for (int i=0; i<numStrips; i++) {
    ledStrip.begin();
    ledStrip.clear();
    }

    pinMode(LedPin,OUTPUT); //Initialize the led pin
    //pinMode(TestPin,INPUT_PULLUP); //Initialize and find value of the test pin

    SetBlinkMode(0);
    }

    //Main loop of the programm gets called again and again.
    void loop() {

    // run test if button is grounded
    if (! digitalRead(TestPin) && false) {
    Test();
    }

    //Check if data is available
    if (Serial.available()) {

    byte receivedByte = Serial.read();

    switch (receivedByte) {
    case ‘L’:
    randomLEDlit(receivedByte);
    //Set length of strips
    SetLedStripLength();
    break;
    case ‘T’:
    randomLEDlit(receivedByte);
    //Test
    Test();
    break;
    case ‘F’:
    randomLEDlit(receivedByte);
    //Fill strip area with color
    Fill();
    break;
    case ‘R’:
    randomLEDlit(receivedByte);
    //receive data for strips
    ReceiveData();
    break;
    case ‘O’:
    randomLEDlit(receivedByte);
    //output data on strip
    OutputData();
    break;
    case ‘C’:
    randomLEDlit(receivedByte);
    //Clears all previously received led data
    ClearAllLedData();
    break;
    case ‘V’:
    randomLEDlit(receivedByte);
    //Send the firmware version
    SendVersion();
    break;
    case ‘M’:
    randomLEDlit(receivedByte);
    //Get max number of leds per strip
    SendMaxNumberOfLeds();
    break;
    default:
    // no unknown commands allowed. Send NACK (N)
    Nack();
    break;
    }
    SetBlinkMode(1);
    }
    Blink();
    }

    void randomLEDlit(byte receivedByte){
    #define RED 0x001600
    #define GREEN 0x160000
    #define BLUE 0x000016
    #define YELLOW 0x141000
    #define PINK 0x001209
    #define ORANGE 0x041000
    #define WHITE 0x101010
    #define BLACK 0x000000
    int a = 20000; //this sets how long the stays one color for
    int ledcolor = random(3); //this randomly selects a number between 0 and 6
    int jtrandled = random(30, 40);
    switch (receivedByte) {
    case ‘L’:
    ledStrip[0].setPixelColor(jtrandled, GREEN);
    ledStrip[0].show();
    delay(a);
    ledStrip[0].setPixelColor(jtrandled, BLACK);
    ledStrip[0].show();
    break;
    case ‘F’:
    ledStrip[0].setPixelColor(jtrandled, RED);
    ledStrip[0].show();
    delay(a);
    ledStrip[0].setPixelColor(jtrandled, BLACK);
    ledStrip[0].show();
    break;
    case ‘R’:
    ledStrip[0].setPixelColor(jtrandled, BLUE);
    ledStrip[0].show();
    delay(a);
    ledStrip[0].setPixelColor(jtrandled, BLACK);
    ledStrip[0].show();
    break;
    case ‘O’:
    ledStrip[0].setPixelColor(jtrandled, GREEN);
    ledStrip[0].setPixelColor(jtrandled+1, GREEN);
    ledStrip[0].show();
    delay(a);
    ledStrip[0].setPixelColor(jtrandled, BLACK);
    ledStrip[0].setPixelColor(jtrandled+1, BLACK);
    ledStrip[0].show();
    break;
    case ‘C’:
    ledStrip[0].setPixelColor(jtrandled, RED);
    ledStrip[0].setPixelColor(jtrandled+1, RED);
    ledStrip[0].show();
    delay(a);
    ledStrip[0].setPixelColor(jtrandled, BLACK);
    ledStrip[0].setPixelColor(jtrandled+1, BLACK);
    ledStrip[0].show();
    break;
    case ‘V’:
    ledStrip[0].setPixelColor(jtrandled, BLUE);
    ledStrip[0].setPixelColor(jtrandled+1, BLUE);
    ledStrip[0].show();
    delay(a);
    ledStrip[0].setPixelColor(jtrandled, BLACK);
    ledStrip[0].setPixelColor(jtrandled+1, BLACK);
    ledStrip[0].show();
    break;
    case ‘M’:
    ledStrip[0].setPixelColor(jtrandled, RED);
    ledStrip[0].setPixelColor(jtrandled+1, BLUE);
    ledStrip[0].setPixelColor(jtrandled+2, GREEN);
    ledStrip[0].show();
    delay(a);
    ledStrip[0].setPixelColor(jtrandled, BLACK);
    ledStrip[0].setPixelColor(jtrandled+1, BLACK);
    ledStrip[0].setPixelColor(jtrandled+2, BLACK);
    ledStrip[0].show();
    break;
    default:
    // no unknown commands allowed. Send NACK (N)
    Nack();
    break;
    }

    }

    //Sets the mode for the blinking of the led
    void SetBlinkMode(int Mode) {
    BlinkMode = Mode;
    BlinkModeTimeoutTimer = 0;
    }

    //Controls the blinking of the led
    void Blink() {
    switch(BlinkMode) {
    case 0:
    //Blinkmode 0 is only active after the start of the Teensy until the first command is received.
    if(BlinkTimer<1500) {
    digitalWrite(LedPin,0);
    } else if(BlinkTimer<1600) {
    digitalWrite(LedPin,1);
    } else {
    BlinkTimer=0;
    digitalWrite(LedPin,0);
    }
    break;
    case 1:
    //Blinkmode 1 is activated when the Teensy receives a command
    //Mode expires 500ms after the last command has been received resp. mode has been set
    if(BlinkTimer>30) {
    BlinkTimer=0;
    digitalWrite(LedPin,!digitalRead(LedPin));
    }
    if(BlinkModeTimeoutTimer>500) {
    SetBlinkMode(2);
    }
    break;
    case 2:
    //Blinkmode 2 is active while the Teensy is waiting for more commands
    if(BlinkTimer<1500) {
    digitalWrite(LedPin,0);
    } else if(BlinkTimer<1600) {
    digitalWrite(LedPin,1);
    } else if(BlinkTimer<1700) {
    digitalWrite(LedPin,0);
    } else if(BlinkTimer<1800) {
    digitalWrite(LedPin,1);
    }else {
    BlinkTimer=0;
    digitalWrite(LedPin,0);
    }
    default:
    //This should never be active
    //The code is only here to make it easier to determine if a wrong Blinkcode has been set
    if(BlinkTimer>2000) {
    BlinkTimer=0;
    digitalWrite(LedPin,!digitalRead(LedPin));
    }
    break;
    }

    }

    //Outputs the data in the ram to the ledstrips
    void OutputData() {
    for (int i=0; i<numStrips; i++) {
    ledStrip.show();
    }
    Ack();
    }

    //Fills the given area of a ledstrip with a color
    void Fill() {
    word firstLed = ReceiveWord();
    word numberOfLeds = ReceiveWord();
    int ColorData = ReceiveColorData();
    if (firstLed <= stripLength * numStrips && numberOfLeds > 0 && firstLed + numberOfLeds – 1 <= stripLength * numStrips) {
    word endLedNr = firstLed + numberOfLeds;
    for(word ledNr = firstLed; ledNr < endLedNr; ledNr++) {
    ledStrip[ledNr / stripLength].setPixelColor(ledNr % stripLength, ColorData);
    }
    OutputData();
    } else {
    //Number of the first led or the number of leds to receive is outside the allowed range
    Nack();
    }
    }

    //Receives data for the ledstrips
    void ReceiveData() {
    word firstLed = ReceiveWord();

    word numberOfLeds=ReceiveWord();

    if( firstLed <= stripLength * numStrips && numberOfLeds > 0 && firstLed + numberOfLeds – 1 <= stripLength * numStrips ) {
    //FirstLedNr and numberOfLeds are valid.
    //Receive and set color data

    word endLedNr = firstLed + numberOfLeds;
    for(word ledNr = firstLed; ledNr < endLedNr; ledNr++) {
    ledStrip[ledNr / stripLength].setPixelColor(ledNr % stripLength, ReceiveColorData());
    }
    OutputData();
    } else {
    Nack(); //Number of the first led or the number of leds to receive is outside the allowed range

    }
    }

    //Sets the length of the longest connected ledstrip. Length is restricted to the max number of allowed leds
    void SetLedStripLength() {
    word newStripLength=ReceiveWord();
    if (newStripLength < 1 || newStripLength > MaxLedsPerStrip) {
    //stripLength is either to small or above the max number of leds allowed
    Nack();
    } else {
    //stripLength is in the valid range
    stripLength = newStripLength;
    for (int i=0; i<numStrips; i++) {
    ledStrip.updateLength(stripLength);
    ledStrip.begin();
    }

    Ack();
    }
    }

    //Clears the data for all configured leds
    void ClearAllLedData() {
    for (word ledNr=0; ledNr < stripLength * numStrips; ledNr++) {
    ledStrip[ledNr / stripLength].setPixelColor(ledNr % stripLength, 0);
    }
    OutputData();
    }

    //Sends the firmware version
    void SendVersion() {
    Serial.write(FirmwareVersionMajor);
    Serial.write(FirmwareVersionMinor);
    Ack();
    }

    //Sends the max number of leds per strip
    void SendMaxNumberOfLeds() {
    byte B = MaxLedsPerStrip >> 8;
    Serial.write(B);
    ledStrip[0].setPixelColor(10, GREEN);
    ledStrip[0].show();
    B = MaxLedsPerStrip & 255;
    Serial.write(B);
    ledStrip[0].setPixelColor(11, GREEN);
    ledStrip[0].show();
    Ack();
    }

    //Sends a ack (A)
    void Ack() {
    ledStrip[0].setPixelColor(12, GREEN);
    ledStrip[0].show();
    Serial.write(‘A’);
    }

    //Sends a NACK (N)
    void Nack() {
    Serial.write(‘N’);
    }

    //Receives 3 bytes of color data.
    int ReceiveColorData() {
    while(!Serial.available()) {};
    int colorValue=Serial.read();
    while(!Serial.available()) {};
    colorValue=(colorValue<<8)|Serial.read();
    while(!Serial.available()) {};
    colorValue=(colorValue<<8)|Serial.read();

    return colorValue;

    }

    //Receives a word value. High byte first, low byte second
    word ReceiveWord() {
    while(!Serial.available()) {};
    word wordValue=Serial.read()<<8;
    while(!Serial.available()) {};
    wordValue=wordValue|Serial.read();

    return wordValue;
    }

    // Colors for testing – assumes WS2812 color order of G, R, B
    /*
    #define RED 0x00FF00
    #define GREEN 0xFF0000
    #define BLUE 0x0000FF
    #define YELLOW 0xFFFF00
    #define PINK 0x10FF88
    #define ORANGE 0x45FF00
    #define WHITE 0xFFFFFF
    #define BLACK 0x000000
    */

    // Less intense colors for testing – assumes WS2812 color order of G, R, B
    #define RED 0x001600
    #define GREEN 0x160000
    #define BLUE 0x000016
    #define YELLOW 0x141000
    #define PINK 0x001209
    #define ORANGE 0x041000
    #define WHITE 0x101010
    #define BLACK 0x000000

    void Test() {
    unsigned int milisecs = 1000; // change them all in 3 seconds
    // randomLEDlit();
    Serial.println(“Testing”);
    // ColorWipe(RED, milisecs);
    // ColorWipe(GREEN, milisecs);
    // ColorWipe(BLUE, milisecs);
    // ColorWipe(YELLOW, milisecs);
    // ColorWipe(PINK, milisecs);
    // ColorWipe(ORANGE, milisecs);
    // ColorWipe(WHITE, milisecs);
    // ColorWipe(BLACK, milisecs);
    }

    void ColorWipe(unsigned long color, unsigned int wait)
    {
    for (int ledNr=0; ledNr < stripLength * numStrips; ledNr++) {
    ledStrip[ledNr / stripLength].setPixelColor(ledNr % stripLength, color);
    }

    digitalWrite(LedPin,1);
    for (int i=0; i<numStrips; i++) {
    ledStrip.show();
    }

    // wait for desginated timeout and then turn off indicator LED
    delay(wait);
    digitalWrite(LedPin,0);
    }

     

    Any help gratefully recieved :-)

     

     

     

    • This topic was modified 2 months ago by Johnny T.
    #197503
    Mike DA Spike
    Participant
    @mikedaspike
    Member

    I’m totally not an expert in this, but your log file shows :

    TeensyStripController LEDStripController updater thread could not connect to the controller. Thread will quit.

    So looks like something not configured correctly, or not setup correctly.

    Is your cabinet.xml setup correctly ? Thats the place where you put the portname in

    Did you flash the correct firmware for Teensy ?

     

    1 user thanked author for this post.
    #197524
    Johnny T
    Participant
    @johnnyt

    I’m totally not an expert in this, but your log file shows :

    TeensyStripController LEDStripController updater thread could not connect to the controller. Thread will quit.

    So looks like something not configured correctly, or not setup correctly.

    Is your cabinet.xml setup correctly ? Thats the place where you put the portname in

    Did you flash the correct firmware for Teensy ?

    Hi Mike

    Thanks for your reply. I’m not using a Teensy controller, I’m using an Arduino. I *think* (I’m hoping) that it’s just saying Teensy as a generic term?

    I got the code off a forum user who kindly shared it on the forum and has used it to get an Arduino working with DOF.

    Fundamentally DOF is working great, I’ve got two contactors working when I press the flippers and I’ve got some button LEDs working from an iPac. So there’s nothing wrong with that side of it. The Programmable LEDs are just set up as a “WS2811” device in the DOF Config Tool.

    I’ve set up “traps” in my code to display LEDs if DOF communicates with it and DOF *is* trying to communicate with it. It sends an “M” to my Arduino. And my Arduino executes the following code to send a reply:

    //Sends the max number of leds per strip
    void SendMaxNumberOfLeds() {
    byte B = MaxLedsPerStrip >> 8;
    Serial.write(B);
    B = MaxLedsPerStrip & 255;
    Serial.write(B);
    Ack();
    }

    //Sends a ack (A)
    void Ack() {
    Serial.write(‘A’);
    }

    I *think* the code to send the reply is correct as I’ve seen that same code in other projects do with with DOF framework on the internet so I’ve no reason to doubt it.

    Hence I wondered if it was my serial port settings which were wrong?

    I’ve currently got it set to:

    comport

    But wasn’t sure if I needed Flow Control turned on (and what it should be set to – xon/xoff or hardware control??)

    Thanks again for your help. I’ll be having another go at it today but I do think I’m exhausting my list of things to try but I really don’t want to admit defeat on this.

     

    #197527
    Mike DA Spike
    Participant
    @mikedaspike
    Member

    Ok. Sorry mate.
    It is so long ago I setup my led strips and matrix, so don’t much about it anymore.
    I have a teensy 3.2 and to get it working I needed the TeensyStripController firmware on it.

    https://github.com/DirectOutput/TeensyStripController

    But that properly something something else than your issue is.
    Still…. If I look at your logs, it looks like  DOF has an issue to initialize the controller itself
    So not sure what you step you missed

    #197534
    Johnny T
    Participant
    @johnnyt

    Ok. Sorry mate.

    It is so long ago I setup my led strips and matrix, so don’t much about it anymore.

    I have a teensy 3.2 and to get it working I needed the TeensyStripController firmware on it.

    https://github.com/DirectOutput/TeensyStripController

    But that properly something something else than your issue is.

    Still…. If I look at your logs, it looks like DOF has an issue to initialize the controller itself

    So not sure what you step you missed

    Hi Mike,

    I’m getting somewhere!!!!!! Oh.. happy day!!!!!

    I downloaded the source code of DOF from the github and looked through it. It seems that it was timing out because the “delay()” command I used in my Arduino code to put the LEDs on isn’t asynchronous. In other words, it puts the LEDs on (to tell me that the program has got to that part of the code) and then it waits for 2 seconds but that is making DOF timeout as the delay() command literally pauses the execution of the software!

    So, I got rid of all the delays and then a few more tweaks later and I’ve just had my first flash of LEDs based on me playing the “DOF Test Table”.

    So, now it seems to be communicating I’ve got to do the rest of the setting up etc but at least it’s communicating so the rest should be software based.

    Many thanks for all your help mate :-)

    #197537
    Mike DA Spike
    Participant
    @mikedaspike
    Member

    I didnt do any help beside mental support.

    Glad you sorted it out!

    1 user thanked author for this post.
    #197539
    Johnny T
    Participant
    @johnnyt

    Mike, sometimes mental support is all someone needs :-) :-) :-)

Viewing 7 posts - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.

©2020 VPinBall.com

Log in with your credentials

or    

Forgot your details?

Create Account

The Vpinball app

FREE
VIEW