Kaimana RGB LED Board thread, RGB animations and more! SRK Tech Talk 2013 Product of the Year!


#1350

Hi there I’m a noob,
I’m having trouble making tournament mode working the way I want. Code 1 had the colors that are grabbed from the kaimana_Custom.h files,
Code 2 is my tournament mode but now When a turn tournament mode my punch and kikc buttons stay the normal color without the active colour change the normal mode has. (Basically I want them to be BLACK)

Sorry I’m very new to this, so I have posted my codes with hope that someone can see where my mistake is made. Appreciate the help

P.S Sometimes my lights freeze at a certain color during the standby animation when i hit a button, also sometimes the lights dont all light up in the chain depending what it is plugged into. Unplugging and pkugging can fix it usually. Is this a normal glitch?

Before Tournament mode (These settings worked in regards to colors activating and not activating)

//  example.ino
//
//  Copyright 2013 Paradise Arcade Shop, ParadiseArcadeShop.com  
//  All rights reserved.  Use is subject to license terms.
//
//  Code is provided for entertainment purposes and use with the Kaimana controller.
//  Code may be copied, modified, resused with this Copyright notice.
//  No commercial use without written permission from Paradise Arcade Shop.
//
//  Paradise Arcade Shop Kaimana LED Driver Board
//  Initial Release October 15, 2013
//
//  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.
//
//  Kaimana example based on original source released by ParadiseArcadeShop.com October 15, 2013
//
//  Created:  October 24, 2013    zonbipanda // gmail.com  -- Arduino 1.0.5 Support
//  Revised:  October 29, 2013    zonbipanda // gmail.com
//  Revised:  April   11, 2015    zonbipanda // gmail.com  -- Arduino 1.6.3 Support
//


#define __PROG_TYPES_COMPAT__
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "kaimana.h"
#include "kaimana_custom.h"
#include "animations.h"


// local function declarations
int  pollSwitches(void);
void showStartup(void);
void setLEDRandomColor(int index);


// ParadiseArcadeShop.com Kaimana features initialzied when Kaimana class instantiated
Kaimana kaimana;


// the setup routine runs first and once each time power is applied to the Kaimana board
void setup() 
{                
  // light up all leds at boot to demonstrate everything is functional
  showStartup();
}


// the loop routine repeats indefinitely and executes immediately following the setup() function
void loop() 
{
  unsigned long  ulTimeout;
  uint8_t i;

  // initialize timeout value to now + some seconds
  ulTimeout = millis() + ( (unsigned long)IDLE_TIMEOUT_SECONDS * 1000 );


  // infinite loop of read switches, update LEDs and idle animation when necessary
  while(true)
  {
    // active -- poll switches and update leds
    if( pollSwitches() != 0 )
    {
        // some switches were active so reset idle timeout to now + some seconds
        ulTimeout = millis() + ( (unsigned long)IDLE_TIMEOUT_SECONDS * 1000 );
    }
    else
    {
        // no switches active so test for start of idle timeout  
        if( millis() > ulTimeout )
        {
          animation_idle();
        }  
    }
    
    // delay a little to avoid flickering (yea, updates happens really, really fast!)
    delay( MAIN_LOOP_DELAY );
  } 
}


// ==============================================================
//
//  local functions start here
//
// ==============================================================


// light up all leds at boot to demonstrate everything is functional
//
void showStartup(void)
{
  kaimana.setALL( BLACK );
  delay( BOOT_COLOR_DELAY );
  kaimana.setALL( RED );
  delay( BOOT_COLOR_DELAY );
  kaimana.setALL( GREEN );
  delay( BOOT_COLOR_DELAY );
  kaimana.setALL( BLUE );
  delay( BOOT_COLOR_DELAY );

  kaimana.setALL( BLACK );
  delay( BOOT_COMPLETE_DELAY );
} 


// set LED to one of 8 predefined colors selected at random
//
void setLEDRandomColor(int index)
{
  switch(random(1,8))    // pick a random color between 1 and 8
  {
    case 1:
      kaimana.setLED(index, COLOR_RANDOM_1);
      break;
    case 2:
      kaimana.setLED(index, COLOR_RANDOM_2);
      break;
    case 3:
      kaimana.setLED(index, COLOR_RANDOM_3);
      break;
    case 4:
      kaimana.setLED(index, COLOR_RANDOM_4);
      break;
    case 5:
      kaimana.setLED(index, COLOR_RANDOM_5);
      break;
    case 6:
      kaimana.setLED(index, COLOR_RANDOM_6);
      break;
    case 7:
      kaimana.setLED(index, COLOR_RANDOM_7);
      break;
    case 8:
      kaimana.setLED(index, COLOR_RANDOM_8);
      break;
    default:   // any undefined value so discard data and set led to BLACK
      kaimana.setLED(index, BLACK);    
      break;
  }  
}



int pollSwitches(void)
{
  static int  iLED[LED_COUNT];
  static int  iActiveSwitchCount;
  static int  i;  
  static int  j;  
  static int  firsttime;
  static uint16_t  joystickDirection;
  static uint16_t  switchActivity;

  // reset LED status
  if (firsttime == 1)
  {
    for(i=0;i<LED_COUNT;++i)
    {
      iLED[i] = false;
      firsttime = 0;
    }
  }

  // read arduino pins and save results in the mapped LED if button is pressed (pin grounded)

  // complex special case for joystick but it's worth the effort
  joystickDirection = ATTACK_NONE;

  if(!digitalRead(PIN_RIGHT))    
    joystickDirection |= ATTACK_RIGHT;
  if(!digitalRead(PIN_LEFT))
    joystickDirection |= ATTACK_LEFT;
  if(!digitalRead(PIN_DOWN))
    joystickDirection |= ATTACK_DOWN;
  if(!digitalRead(PIN_UP))
    joystickDirection |= ATTACK_UP;

  switch(joystickDirection)
  {
    case ATTACK_RIGHT:    // right
      #ifdef RANDOM_COLOR_JOY_ON
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
      #endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_LEFT:    // left
      #ifdef RANDOM_COLOR_JOY_ON
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
      #endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN:    // down
      #ifdef RANDOM_COLOR_JOY_ON
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
      #endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN + ATTACK_RIGHT:    // down + right
      #ifdef RANDOM_COLOR_JOY_ON
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
      #endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN + ATTACK_LEFT:    // down + left
      #ifdef RANDOM_COLOR_JOY_ON
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
      #endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP:    // up
      #ifdef RANDOM_COLOR_JOY_ON
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
      #endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP + ATTACK_RIGHT:    // up + right
      #ifdef RANDOM_COLOR_JOY_ON
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
      #endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP + ATTACK_LEFT:   // up + left
      #ifdef RANDOM_COLOR_JOY_ON
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
      #endif
      iLED[LED_JOY] = true;
      break;
    default:   // zero or any undefined value on an 8 way stick like UP+DOWN which is not happening on my watch
      #ifdef RANDOM_COLOR_JOY_OFF
        setLEDRandomColor(LED_JOY);
      #else
        kaimana.setLED(LED_JOY, LED_JOY_COLOR_OFF);
      #endif    
      iLED[LED_JOY] = false;
      break;
  }  
  
  

  // clear results for switch activity
  switchActivity = ATTACK_NONE;
  
  // test switch and set LED based on result       // HOME = GUIDE
  if(!digitalRead(PIN_HOME))
  {
    // switch is active
    if(iLED[LED_HOME] == true)
    {
      //maintain color while switch is active
      iLED[LED_HOME] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_HOME_ON      
        setLEDRandomColor(LED_HOME);  
      #else
         kaimana.setLED(LED_HOME, LED_HOME_COLOR_ON);
      #endif
      iLED[LED_HOME] = true;
    }
  }
  else
  {
      // switch is inactive
      #ifdef RANDOM_COLOR_HOME_OFF
        setLEDRandomColor(LED_HOME);
      #else
        kaimana.setLED(LED_HOME, LED_HOME_COLOR_OFF);
      #endif    
      iLED[LED_HOME] = false;
  }


  // test switch and set LED based on result    // SELECT = BACK 
  if(!digitalRead(PIN_SELECT))
  {
    // switch is active
    if(iLED[LED_SELECT] == true)
    {
      //maintain color while switch is active
      iLED[LED_SELECT] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_SELECT_ON        //mwolak 11-01-2015 switch between random or solid colors
        setLEDRandomColor(LED_SELECT);  //mappings in kaimana_custom.h
      #else
         kaimana.setLED(LED_SELECT, LED_SELECT_COLOR_ON);
      #endif
      iLED[LED_SELECT] = true;
    }
  }
  else
  {
      // switch is inactive
      #ifdef RANDOM_COLOR_SELECT_OFF
        setLEDRandomColor(LED_SELECT);
      #else
        kaimana.setLED(LED_SELECT, LED_SELECT_COLOR_OFF);
      #endif       
      iLED[LED_SELECT] = false;
  }


  // test switch and set LED based on result
  if(!digitalRead(PIN_START))
  {
    // switch is active
    if(iLED[LED_START] == true)
    {
      //maintain color while switch is active
      iLED[LED_START] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_START_ON        //mwolak 11-01-2015 switch between random or solid colors
        setLEDRandomColor(LED_START);  //mappings in kaimana_custom.h
      #else
         kaimana.setLED(LED_START, LED_START_COLOR_ON);
      #endif
      iLED[LED_START] = true;
    }
  }
  else
  {
      // switch is inactive
      // switch is inactive
      #ifdef RANDOM_COLOR_START_OFF
        setLEDRandomColor(LED_START);
      #else
        kaimana.setLED(LED_START, LED_START_COLOR_OFF);
      #endif      
      iLED[LED_START] = false;
  }


  // test switch and set LED based on result
  if(!digitalRead(PIN_P1))
  {
    switchActivity |= ATTACK_P1;
    // switch is active
    if(iLED[LED_P1] == true)
    {
      //maintain color while switch is active
      iLED[LED_P1] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_P1_ON
        setLEDRandomColor(LED_P1);
      #else
         kaimana.setLED(LED_P1, LED_P1_COLOR_ON);
      #endif
      iLED[LED_P1] = true;
    }
  }
  else
  {
      // switch is inactive
      #ifdef RANDOM_COLOR_P1_OFF
        setLEDRandomColor(LED_P1);
      #else
        kaimana.setLED(LED_P1, LED_P1_COLOR_OFF);
      #endif     
      iLED[LED_P1] = false;
  }


  // test switch and set LED based on result
  if(!digitalRead(PIN_P2))
  {
    switchActivity |= ATTACK_P2;
    
    // switch is active
    if(iLED[LED_P2] == true)
    {
      //maintain color while switch is active
      iLED[LED_P2] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_P2_ON
        setLEDRandomColor(LED_P2);
      #else
         kaimana.setLED(LED_P2, LED_P2_COLOR_ON);
      #endif
      iLED[LED_P2] = true;
    }
  }
  else
  {
      // switch is inactive
      #ifdef RANDOM_COLOR_P2_OFF
        setLEDRandomColor(LED_P2);
      #else
        kaimana.setLED(LED_P2, LED_P2_COLOR_OFF);
      #endif    
      iLED[LED_P2] = false;
  }


  // test switch and set LED based on result
  if(!digitalRead(PIN_P3))
  {
    switchActivity |= ATTACK_P3;
    
    // switch is active
    if(iLED[LED_P3] == true)
    {
      //maintain color while switch is active
      iLED[LED_P3] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_P3_ON
        setLEDRandomColor(LED_P3);
      #else
         kaimana.setLED(LED_P3, LED_P3_COLOR_ON);
      #endif
      iLED[LED_P3] = true;
    }
  }
  else
  {
      // switch is inactive
      // switch is inactive
      #ifdef RANDOM_COLOR_P3_OFF
        setLEDRandomColor(LED_P3);
      #else
        kaimana.setLED(LED_P3, LED_P3_COLOR_OFF);
      #endif   
      iLED[LED_P3] = false;
  }
  

  // test switch and set LED based on result
  if(!digitalRead(PIN_P4))
  {
    switchActivity |= ATTACK_P4;
    
    // switch is active
    if(iLED[LED_P4] == true)
    {
      //maintain color while switch is active
      iLED[LED_P4] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_P4_ON
        setLEDRandomColor(LED_P4);
      #else
         kaimana.setLED(LED_P4, LED_P4_COLOR_ON);
      #endif
      iLED[LED_P4] = true;
    }
  }
  else
  {
      // switch is inactive
      #ifdef RANDOM_COLOR_P4_OFF
        setLEDRandomColor(LED_P4);
      #else
        kaimana.setLED(LED_P4, LED_P4_COLOR_OFF);
      #endif 
      iLED[LED_P4] = false;
  }


  // test switch and set LED based on result
  if(!digitalRead(PIN_K1))
  {
    switchActivity |= ATTACK_K1;
    
    // switch is active
    if(iLED[LED_K1] == true)
    {
      //maintain color while switch is active
      iLED[LED_K1] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_K1_ON
        setLEDRandomColor(LED_K1);
      #else
         kaimana.setLED(LED_K1, LED_K1_COLOR_ON);
      #endif
      iLED[LED_K1] = true;
    }
  }
  else
  {
      // switch is inactive
      #ifdef RANDOM_COLOR_K1_OFF
        setLEDRandomColor(LED_K1);
      #else
        kaimana.setLED(LED_K1, LED_K1_COLOR_OFF);
      #endif    
      iLED[LED_K1] = false;
  }


  // test switch and set LED based on result
  if(!digitalRead(PIN_K2))
  {
    switchActivity |= ATTACK_K2;
    
    // switch is active
    if(iLED[LED_K2] == true)
    {
      //maintain color while switch is active
      iLED[LED_K2] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_K2_ON
        setLEDRandomColor(LED_K2);
      #else
         kaimana.setLED(LED_K2, LED_K2_COLOR_ON);
      #endif
      iLED[LED_K2] = true;
    }
  }
  else
  {
      // switch is inactive
      // switch is inactive
      #ifdef RANDOM_COLOR_K2_OFF
        setLEDRandomColor(LED_K2);
      #else
        kaimana.setLED(LED_K2, LED_K2_COLOR_OFF);
      #endif      
      iLED[LED_K2] = false;
  }


  // test switch and set LED based on result
  if(!digitalRead(PIN_K3))
  {
    switchActivity |= ATTACK_K3;
    
    // switch is active
    if(iLED[LED_K3] == true)
    {
      //maintain color while switch is active
      iLED[LED_K3] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_K3_ON
        setLEDRandomColor(LED_K3);
      #else
         kaimana.setLED(LED_K3, LED_K3_COLOR_ON);
      #endif
      iLED[LED_K3] = true;
    }
  }
  else
  {
      // switch is inactive
      // switch is inactive
      #ifdef RANDOM_COLOR_K3_OFF
        setLEDRandomColor(LED_K3);
      #else
        kaimana.setLED(LED_K3, LED_K3_COLOR_OFF);
      #endif    
      iLED[LED_K3] = false;
  }


  // test switch and set LED based on result
  if(!digitalRead(PIN_K4))
  {
    switchActivity |= ATTACK_K4;
    
    // switch is active
    if(iLED[LED_K4] == true)
    {
      //maintain color while switch is active
      iLED[LED_K4] = true;
    }
    else
    {
      // select new color when switch is first activated
      #ifdef RANDOM_COLOR_K4_ON
        setLEDRandomColor(LED_K4);
      #else
         kaimana.setLED(LED_K4, LED_K4_COLOR_ON);
      #endif
      iLED[LED_K4] = true;
    }
  }
  else
  {
      // switch is inactive
      // switch is inactive
      #ifdef RANDOM_COLOR_K4_OFF
        setLEDRandomColor(LED_K4);
      #else
        kaimana.setLED(LED_K4, LED_K4_COLOR_OFF);
      #endif       
      iLED[LED_K4] = false;
  }



  // convert joystick, P1-P4, K1-K4 into a single unsigned int
  switchActivity = joystickDirection + switchActivity;
  kaimana.switchHistorySet(switchActivity);
  

  // test for combinations from most complext to least complex
  // test for switches in reverse order (newest to oldest)


  // combo #6
  // test for: Ultra 2 (Metsu Shoryuken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, DOWN, DOWN+RIGHT, RIGHT, RIGHT+K3
  if( kaimana.switchHistoryTest( COMBO_PATTERN_6A ) )
      animation_combo_6();

  // combo #5
  // test for: Ultra 1 (Metsu Hadouken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, <NONE>, DOWN, DOWN+RIGHT, RIGHT, RIGHT+P3
  if( kaimana.switchHistoryTest( COMBO_PATTERN_5A ) )
      animation_combo_5();

  // combo #4
  // test for: Super (Shinkuu Hadouken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, <NONE>, DOWN, DOWN+RIGHT, RIGHT, RIGHT+P1
  if( kaimana.switchHistoryTest( COMBO_PATTERN_4A ) )
      animation_combo_4();

  // combo #3
  // test for: Tatsumaki Senpukyaku (Hurricane Kick)
  // combo is: DOWN, DOWN+LEFT, LEFT, LEFT+K1 or LEFT+K2
  if( kaimana.switchHistoryTest( COMBO_PATTERN_3A ) )
      animation_combo_3();
  if( kaimana.switchHistoryTest( COMBO_PATTERN_3B ) )
      animation_combo_3();

  // combo #2
  // test for: Ryu Shoryuken (Dragon Punch)
  // combo is: RIGHT, <NONE>, DOWN, DOWN+RIGHT, DOWN+RIGHT+P1 or DOWN+RIGHT+P2
  if( kaimana.switchHistoryTest( COMBO_PATTERN_2A ) )
      animation_combo_2();
  if( kaimana.switchHistoryTest( COMBO_PATTERN_2B ) )
      animation_combo_2();

  // combo #1
  // test for: Ryu Hadouken (Fireball) 
  // combo is: DOWN, DOWN+RIGHT, RIGHT, RIGHT+P1 or RIGHT+P2  
  if( kaimana.switchHistoryTest( COMBO_PATTERN_1A ) )
      animation_combo_1();
  if( kaimana.switchHistoryTest( COMBO_PATTERN_1B ) )
      animation_combo_1();


  // zero active switch counter (note: 4 way joystick counts as 1)
  iActiveSwitchCount = 0;
  
  // set LED color based on switch
  for(i=0;i<LED_COUNT;++i)
  {
    if(iLED[i] == true)
      ++iActiveSwitchCount;
  }  

  // update the leds with new/current colors in the array
  kaimana.updateALL();
  
  // return number of active switches
  return(iActiveSwitchCount);
}  



 

After Implimentingtorunament mode

//  panzer2kaimana.ino
//
//  Copyright 2013 Paradise Arcade Shop, ParadiseArcadeShop.com
//  All rights reserved.  Use is subject to license terms.
//
//  Code is provided for entertainment purposes and use with the Kaimana controller.
//  Code may be copied, modified, resused with this Copyright notice.
//  No commercial use without written permission from Paradise Arcade Shop.
//
//  Paradise Arcade Shop Kaimana LED Driver Board
//  Initial Release October 15, 2013
//
//  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.
//
//  Kaimana example based on original source released by ParadiseArcadeShop.com October 15, 2013
//
//  Created:  October 24, 2013    zonbipanda // gmail.com  -- Arduino 1.0.5 Support
//  Revised:  October 29, 2013    zonbipanda // gmail.com
//  Revised:  April   11, 2015    zonbipanda // gmail.com  -- Arduino 1.6.3 Support
//  Revised:  March    7, 2016    info // mightyjrmods.com -- Added startup animations

#define __PROG_TYPES_COMPAT__
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "kaimana.h"
#include "kaimana_custom.h"
#include "animations.h"


// local function declarations
int  pollSwitches(void);
void showStartup(void);
void setLEDRandomColor(int index);
boolean tournamentMode = false;
int holdTimeout = 0;

// ParadiseArcadeShop.com Kaimana features initialzied when Kaimana class instantiated
Kaimana kaimana;


// the setup routine runs first and once each time power is applied to the Kaimana board
void setup()
{
  // light up all leds at boot to demonstrate everything is functional
  showStartup();
}


// the loop routine repeats indefinitely and executes immediately following the setup() function
void loop()
{
  unsigned long  ulTimeout;
  uint8_t i;

  // initialize timeout value to now + some seconds
  ulTimeout = millis() + ( (unsigned long)IDLE_TIMEOUT_SECONDS * 1000 );

  // infinite loop of read switches, update LEDs and idle animation when necessary
  while ( true)
  {
    // active -- poll switches and update leds

    if (tournamentMode != true)
    {
      if ( pollSwitches() != 0 )
      
      {
        // some switches were active so reset idle timeout to now + some seconds
        ulTimeout = millis() + ( (unsigned long)IDLE_TIMEOUT_SECONDS * 1000 );
      }
      else
      {
        // no switches active so test for start of idle timeout
        if ( millis() > ulTimeout )
        {
          animation_idle();
        }
      }
    }
    else
    {
      if ( tourneypollSwitches() != 0 )
      {
        // some switches were active so reset idle timeout to now + some seconds
        ulTimeout = millis() + ( (unsigned long)IDLE_TIMEOUT_SECONDS * 1000 );
      }

    }
  }
  // delay a little to avoid flickering (yea, updates happens really, really fast!)
  delay( MAIN_LOOP_DELAY );

}


// ==============================================================
//
//  local functions start here
//
// ==============================================================


// light up all leds at boot to demonstrate everything is functional
//
void showStartup(void)
{
  kaimana.setALL( BLACK );
  delay( BOOT_COLOR_DELAY );
  kaimana.setALL( RED );
  delay( BOOT_COLOR_DELAY );
  kaimana.setALL( GREEN );
  delay( BOOT_COLOR_DELAY );
  kaimana.setALL( BLUE );
  delay( BOOT_COLOR_DELAY );

  kaimana.setALL( BLACK );
  delay( BOOT_COMPLETE_DELAY );
}

// set LED to one of 8 predefined colors selected at random
//
void setLEDRandomColor(int index)
{
  switch (random(1, 8))  // pick a random color between 1 and 8
  {
    case 1:
      kaimana.setLED(index, COLOR_RANDOM_1);
      break;
    case 2:
      kaimana.setLED(index, COLOR_RANDOM_2);
      break;
    case 3:
      kaimana.setLED(index, COLOR_RANDOM_3);
      break;
    case 4:
      kaimana.setLED(index, COLOR_RANDOM_4);
      break;
    case 5:
      kaimana.setLED(index, COLOR_RANDOM_5);
      break;
    case 6:
      kaimana.setLED(index, COLOR_RANDOM_6);
      break;
    case 7:
      kaimana.setLED(index, COLOR_RANDOM_7);
      break;
    case 8:
      kaimana.setLED(index, COLOR_RANDOM_8);
      break;
    default:   // any undefined value so discard data and set led to BLACK
      kaimana.setLED(index, BLACK);
      break;
  }
}



int pollSwitches(void)
{
  static int  iLED[LED_COUNT];
  static int  iActiveSwitchCount;
  static int  i;
  static int  j;
  static int  firsttime;
  static uint16_t  joystickDirection;
  static uint16_t  switchActivity;

  // reset LED status
  if (firsttime == 1)
  {
    for (i = 0; i < LED_COUNT; ++i)
    {
      iLED[i] = false;
      firsttime = 0;
    }
  }

  // read arduino pins and save results in the mapped LED if button is pressed (pin grounded)

  // complex special case for joystick but it's worth the effort
  joystickDirection = ATTACK_NONE;

  if (!digitalRead(PIN_RIGHT))
    joystickDirection |= ATTACK_RIGHT;
  if (!digitalRead(PIN_LEFT))
    joystickDirection |= ATTACK_LEFT;
  if (!digitalRead(PIN_DOWN))
    joystickDirection |= ATTACK_DOWN;
  if (!digitalRead(PIN_UP))
    joystickDirection |= ATTACK_UP;

  switch (joystickDirection)
  {
    case ATTACK_RIGHT:    // right
#ifdef RANDOM_COLOR_JOY_ON
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
#endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_LEFT:    // left
#ifdef RANDOM_COLOR_JOY_ON
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
#endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN:    // down
#ifdef RANDOM_COLOR_JOY_ON
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
#endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN + ATTACK_RIGHT:    // down + right
#ifdef RANDOM_COLOR_JOY_ON
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
#endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN + ATTACK_LEFT:    // down + left
#ifdef RANDOM_COLOR_JOY_ON
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
#endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP:    // up
#ifdef RANDOM_COLOR_JOY_ON
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
#endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP + ATTACK_RIGHT:    // up + right
#ifdef RANDOM_COLOR_JOY_ON
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
#endif
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP + ATTACK_LEFT:   // up + left
#ifdef RANDOM_COLOR_JOY_ON
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_ON);
#endif
      iLED[LED_JOY] = true;
      break;
    default:   // zero or any undefined value on an 8 way stick like UP+DOWN which is not happening on my watch
#ifdef RANDOM_COLOR_JOY_OFF
      setLEDRandomColor(LED_JOY);
#else
      kaimana.setLED(LED_JOY, LED_JOY_COLOR_OFF);
#endif
      iLED[LED_JOY] = false;
      break;
  }



  // clear results for switch activity
  switchActivity = ATTACK_NONE;

  // test switch and set LED based on result       // HOME = GUIDE
  if (!digitalRead(PIN_HOME))
  {
    // switch is active
    if (iLED[LED_HOME] == true)
    {
      //maintain color while switch is active
      iLED[LED_HOME] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_HOME_ON
      setLEDRandomColor(LED_HOME);
#else
      kaimana.setLED(LED_HOME, LED_HOME_COLOR_ON);
#endif
      iLED[LED_HOME] = true;
    }
  }
  else
  {
    // switch is inactive
#ifdef RANDOM_COLOR_HOME_OFF
    setLEDRandomColor(LED_HOME);
#else
    kaimana.setLED(LED_HOME, LED_HOME_COLOR_OFF);
#endif
    iLED[LED_HOME] = false;
  }


  // test switch and set LED based on result    // SELECT = BACK
  if (!digitalRead(PIN_SELECT))
  {
    // switch is active
    if (iLED[LED_SELECT] == true)
    {
      //maintain color while switch is active
      iLED[LED_SELECT] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_SELECT_ON        //mwolak 11-01-2015 switch between random or solid colors
      setLEDRandomColor(LED_SELECT);  //mappings in kaimana_custom.h
#else
      kaimana.setLED(LED_SELECT, LED_SELECT_COLOR_ON);
#endif
      iLED[LED_SELECT] = false;
    }
  }
  else
  {
    // switch is inactive
#ifdef RANDOM_COLOR_SELECT_OFF
    setLEDRandomColor(LED_SELECT);
#else
    kaimana.setLED(LED_SELECT, LED_SELECT_COLOR_OFF);
#endif
    iLED[LED_SELECT] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_START))
  {
    //Button hold to start tourneymode
    holdTimeout += 1;
    if (holdTimeout == 3000)
    {
      tournamentMode = true;
      tourneyModeActivate();
    }
    // switch is active
    if (iLED[LED_START] == true)
    {
      //maintain color while switch is active
      iLED[LED_START] = true;

    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_START_ON        //mwolak 11-01-2015 switch between random or solid colors
      setLEDRandomColor(LED_START);  //mappings in kaimana_custom.h
#else
      kaimana.setLED(LED_START, LED_START_COLOR_ON);
#endif
      iLED[LED_START] = false;
    }
  }
  else
  {
    // switch is inactive
    // switch is inactive
#ifdef RANDOM_COLOR_START_OFF
    setLEDRandomColor(LED_START);
#else
    kaimana.setLED(LED_START, LED_START_COLOR_OFF);
#endif
    iLED[LED_START] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_P1))
  {
    switchActivity |= ATTACK_P1;
    // switch is active
    if (iLED[LED_P1] == true)
    {
      //maintain color while switch is active
      iLED[LED_P1] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_P1_ON
      setLEDRandomColor(LED_P1);
#else
      kaimana.setLED(LED_P1, LED_P1_COLOR_ON);
#endif
      iLED[LED_P1] = true;
    }
  }
  else
  {
    // switch is inactive
#ifdef RANDOM_COLOR_P1_OFF
    setLEDRandomColor(LED_P1);
#else
    kaimana.setLED(LED_P1, LED_P1_COLOR_OFF);
#endif
    iLED[LED_P1] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_P2))
  {
    switchActivity |= ATTACK_P2;

    // switch is active
    if (iLED[LED_P2] == true)
    {
      //maintain color while switch is active
      iLED[LED_P2] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_P2_ON
      setLEDRandomColor(LED_P2);
#else
      kaimana.setLED(LED_P2, LED_P2_COLOR_ON);
#endif
      iLED[LED_P2] = true;
    }
  }
  else
  {
    // switch is inactive
#ifdef RANDOM_COLOR_P2_OFF
    setLEDRandomColor(LED_P2);
#else
    kaimana.setLED(LED_P2, LED_P2_COLOR_OFF);
#endif
    iLED[LED_P2] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_P3))
  {
    switchActivity |= ATTACK_P3;

    // switch is active
    if (iLED[LED_P3] == true)
    {
      //maintain color while switch is active
      iLED[LED_P3] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_P3_ON
      setLEDRandomColor(LED_P3);
#else
      kaimana.setLED(LED_P3, LED_P3_COLOR_ON);
#endif
      iLED[LED_P3] = true;
    }
  }
  else
  {
    // switch is inactive
    // switch is inactive
#ifdef RANDOM_COLOR_P3_OFF
    setLEDRandomColor(LED_P3);
#else
    kaimana.setLED(LED_P3, LED_P3_COLOR_OFF);
#endif
    iLED[LED_P3] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_P4))
  {
    switchActivity |= ATTACK_P4;

    // switch is active
    if (iLED[LED_P4] == true)
    {
      //maintain color while switch is active
      iLED[LED_P4] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_P4_ON
      setLEDRandomColor(LED_P4);
#else
      kaimana.setLED(LED_P4, LED_P4_COLOR_ON);
#endif
      iLED[LED_P4] = true;
    }
  }
  else
  {
    // switch is inactive
#ifdef RANDOM_COLOR_P4_OFF
    setLEDRandomColor(LED_P4);
#else
    kaimana.setLED(LED_P4, LED_P4_COLOR_OFF);
#endif
    iLED[LED_P4] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_K1))
  {
    switchActivity |= ATTACK_K1;

    // switch is active
    if (iLED[LED_K1] == true)
    {
      //maintain color while switch is active
      iLED[LED_K1] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_K1_ON
      setLEDRandomColor(LED_K1);
#else
      kaimana.setLED(LED_K1, LED_K1_COLOR_ON);
#endif
      iLED[LED_K1] = true;
    }
  }
  else
  {
    // switch is inactive
#ifdef RANDOM_COLOR_K1_OFF
    setLEDRandomColor(LED_K1);
#else
    kaimana.setLED(LED_K1, LED_K1_COLOR_OFF);
#endif
    iLED[LED_K1] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_K2))
  {
    switchActivity |= ATTACK_K2;

    // switch is active
    if (iLED[LED_K2] == true)
    {
      //maintain color while switch is active
      iLED[LED_K2] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_K2_ON
      setLEDRandomColor(LED_K2);
#else
      kaimana.setLED(LED_K2, LED_K2_COLOR_ON);
#endif
      iLED[LED_K2] = true;
    }
  }
  else
  {
    // switch is inactive
    // switch is inactive
#ifdef RANDOM_COLOR_K2_OFF
    setLEDRandomColor(LED_K2);
#else
    kaimana.setLED(LED_K2, LED_K2_COLOR_OFF);
#endif
    iLED[LED_K2] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_K3))
  {
    switchActivity |= ATTACK_K3;

    // switch is active
    if (iLED[LED_K3] == true)
    {
      //maintain color while switch is active
      iLED[LED_K3] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_K3_ON
      setLEDRandomColor(LED_K3);
#else
      kaimana.setLED(LED_K3, LED_K3_COLOR_ON);
#endif
      iLED[LED_K3] = true;
    }
  }
  else
  {
    // switch is inactive
    // switch is inactive
#ifdef RANDOM_COLOR_K3_OFF
    setLEDRandomColor(LED_K3);
#else
    kaimana.setLED(LED_K3, LED_K3_COLOR_OFF);
#endif
    iLED[LED_K3] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_K4))
  {
    switchActivity |= ATTACK_K4;

    // switch is active
    if (iLED[LED_K4] == true)
    {
      //maintain color while switch is active
      iLED[LED_K4] = true;
    }
    else
    {
      // select new color when switch is first activated
#ifdef RANDOM_COLOR_K4_ON
      setLEDRandomColor(LED_K4);
#else
      kaimana.setLED(LED_K4, LED_K4_COLOR_ON);
#endif
      iLED[LED_K4] = true;
    }
  }
  else
  {
    // switch is inactive
    // switch is inactive
#ifdef RANDOM_COLOR_K4_OFF
    setLEDRandomColor(LED_K4);
#else
    kaimana.setLED(LED_K4, LED_K4_COLOR_OFF);
#endif
    iLED[LED_K4] = false;
  }



  // convert joystick, P1-P4, K1-K4 into a single unsigned int
  switchActivity = joystickDirection + switchActivity;
  kaimana.switchHistorySet(switchActivity);


  // test for combinations from most complext to least complex
  // test for switches in reverse order (newest to oldest)


  // combo #6
  // test for: Ultra 2 (Metsu Shoryuken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, DOWN, DOWN+RIGHT, RIGHT, RIGHT+K3
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_6A ) )
    animation_combo_6();

  // combo #5
  // test for: Ultra 1 (Metsu Hadouken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, <NONE>, DOWN, DOWN+RIGHT, RIGHT, RIGHT+P3
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_5A ) )
    animation_combo_5();

  // combo #4
  // test for: Super (Shinkuu Hadouken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, <NONE>, DOWN, DOWN+RIGHT, RIGHT, RIGHT+P1
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_4A ) )
    animation_combo_4();

  // combo #3
  // test for: Tatsumaki Senpukyaku (Hurricane Kick)
  // combo is: DOWN, DOWN+LEFT, LEFT, LEFT+K1 or LEFT+K2
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_3A ) )
    animation_combo_3();
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_3B ) )
    animation_combo_3();

  // combo #2
  // test for: Ryu Shoryuken (Dragon Punch)
  // combo is: RIGHT, <NONE>, DOWN, DOWN+RIGHT, DOWN+RIGHT+P1 or DOWN+RIGHT+P2
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_2A ) )
    animation_combo_2();
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_2B ) )
    animation_combo_2();

  // combo #1
  // test for: Ryu Hadouken (Fireball)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, RIGHT+P1 or RIGHT+P2
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_1A ) )
    animation_combo_1();
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_1B ) )
    animation_combo_1();

  //Tournament mode
  /*   if( kaimana.switchHistoryTest( TOURNAMENT_MODE ) )
    {
      if (tournamentMode != true)
      {
        tournamentMode = true;
        tourneyMode
      }
      else
      {

        tournamentMode = false;
      }
    } */


  // zero active switch counter (note: 4 way joystick counts as 1)
  iActiveSwitchCount = 0;

  // set LED color based on switch
  for (i = 0; i < LED_COUNT; ++i)
  {
    if (iLED[i] == true)
      ++iActiveSwitchCount;
  }

  // update the leds with new/current colors in the array
  kaimana.updateALL();

  // return number of active switches
  return (iActiveSwitchCount);
}

int tourneypollSwitches(void)
{
  static int  iLED[LED_COUNT];
  static int  iActiveSwitchCount;
  static int  i;
  static int  j;
  static int  firsttime;
  static uint16_t  joystickDirection;
  static uint16_t  switchActivity;

  // reset LED status
  if (firsttime == 1)
  {
    for (i = 0; i < LED_COUNT; ++i)
    {
      iLED[i] = false;
      firsttime = 0;
    }
  }

  // read arduino pins and save results in the mapped LED if button is pressed (pin grounded)

  // complex special case for joystick but it's worth the effort
  joystickDirection = ATTACK_NONE;

  if (!digitalRead(PIN_RIGHT))
    joystickDirection |= ATTACK_RIGHT;
  if (!digitalRead(PIN_LEFT))
    joystickDirection |= ATTACK_LEFT;
  if (!digitalRead(PIN_DOWN))
    joystickDirection |= ATTACK_DOWN;
  if (!digitalRead(PIN_UP))
    joystickDirection |= ATTACK_UP;

  switch (joystickDirection)
  {
    case ATTACK_RIGHT:    // right
      iLED[LED_JOY] = true;
      break;
    case ATTACK_LEFT:    // left
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN:    // down
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN + ATTACK_RIGHT:    // down + right
      iLED[LED_JOY] = true;
      break;
    case ATTACK_DOWN + ATTACK_LEFT:    // down + left
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP:    // up
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP + ATTACK_RIGHT:    // up + right
      iLED[LED_JOY] = true;
      break;
    case ATTACK_UP + ATTACK_LEFT:   // up + left
      iLED[LED_JOY] = true;
      break;
    default:   // zero or any undefined value on an 8 way stick like UP+DOWN which is not happening on my watch
      iLED[LED_JOY] = false;
      break;
  }



  // clear results for switch activity
  switchActivity = ATTACK_NONE;

  // test switch and set LED based on result       // HOME = GUIDE
  if (!digitalRead(PIN_HOME))
  {
    // switch is active
    if (iLED[LED_HOME] == true)
    {
      //maintain color while switch is active
      iLED[LED_HOME] = true;
    }
    else
    {
      // select new color when switch is first activated
      iLED[LED_HOME] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_HOME] = false;
  }


  // test switch and set LED based on result    // SELECT = BACK
  if (!digitalRead(PIN_SELECT))
  {
    // switch is active
    if (iLED[LED_SELECT] == true)
    {
      //maintain color while switch is active
      iLED[LED_SELECT] = true;
    }
    else
    {
      // select new color when switch is first activated
      iLED[LED_SELECT] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_SELECT] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_START))
  {

    // switch is active
    //Button hold to stop tourneymode
    holdTimeout += 1;
    if (holdTimeout == 2000)
    {
      tournamentMode = false;
      tourneyModeDeactivate();
    }
    if (iLED[LED_START] == true)
    {
      //maintain color while switch is active
      iLED[LED_START] = true;
    }
    else
    {
      // select new color when switch is first activated
      holdTimeout = 0;
      iLED[LED_START] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_START] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_P1))
  {
    switchActivity |= ATTACK_P1;

    // switch is active
    if (iLED[LED_P1] == true)
    {

      iLED[LED_P1] = true;
    }
    else
    {
      iLED[LED_P1] = true;

    }
  }
  else
  {
    // switch is inactive
    iLED[LED_P1] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_P2))
  {
    switchActivity |= ATTACK_P2;

    // switch is active
    if (iLED[LED_P2] == true)
    {
      //maintain color while switch is active
      iLED[LED_P2] = true;
    }
    else
    {
      // select new color when switch is first activated
      iLED[LED_P2] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_P2] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_P3))
  {
    switchActivity |= ATTACK_P3;

    // switch is active
    if (iLED[LED_P3] == true)
    {
      //maintain color while switch is active
      iLED[LED_P3] = true;
    }
    else
    {
      // select new color when switch is first activated
      iLED[LED_P3] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_P3] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_P4))
  {
    switchActivity |= ATTACK_P4;

    // switch is active
    if (iLED[LED_P4] == true)
    {
      //maintain color while switch is active
      iLED[LED_P4] = true;
    }
    else
    {
      // select new color when switch is first activated

      iLED[LED_P4] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_P4] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_K1))
  {
    switchActivity |= ATTACK_K1;

    // switch is active
    if (iLED[LED_K1] == true)
    {
      //maintain color while switch is active
      iLED[LED_K1] = true;
    }
    else
    {
      // select new color when switch is first activated
      iLED[LED_K1] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_K1] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_K2))
  {
    switchActivity |= ATTACK_K2;

    // switch is active
    if (iLED[LED_K2] == true)
    {
      //maintain color while switch is active
      iLED[LED_K2] = true;
    }
    else
    {
      // select new color when switch is first activated
      iLED[LED_K2] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_K2] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_K3))
  {
    switchActivity |= ATTACK_K3;

    // switch is active
    if (iLED[LED_K3] == true)
    {
      //maintain color while switch is active
      iLED[LED_K3] = true;
    }
    else
    {
      // select new color when switch is first activated
      iLED[LED_K3] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_K3] = false;
  }


  // test switch and set LED based on result
  if (!digitalRead(PIN_K4))
  {
    switchActivity |= ATTACK_K4;

    // switch is active
    if (iLED[LED_K4] == true)
    {
      //maintain color while switch is active
      iLED[LED_K4] = true;
    }
    else
    {
      // select new color when switch is first activated
      iLED[LED_K4] = true;
    }
  }
  else
  {
    // switch is inactive
    iLED[LED_K4] = false;
  }



  // convert joystick, P1-P4, K1-K4 into a single unsigned int
  switchActivity = joystickDirection + switchActivity;
  kaimana.switchHistorySet(switchActivity);


  // test for combinations from most complext to least complex
  // test for switches in reverse order (newest to oldest)


  // combo #6
  // test for: Ultra 2 (Metsu Shoryuken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, DOWN, DOWN+RIGHT, RIGHT, RIGHT+K3
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_6A ) )
    animation_combo_6();

  // combo #5
  // test for: Ultra 1 (Metsu Hadouken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, <NONE>, DOWN, DOWN+RIGHT, RIGHT, RIGHT+P3
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_5A ) )
    animation_combo_5();

  // combo #4
  // test for: Super (Shinkuu Hadouken)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, <NONE>, DOWN, DOWN+RIGHT, RIGHT, RIGHT+P1
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_4A ) )
    animation_combo_4();

  // combo #3
  // test for: Tatsumaki Senpukyaku (Hurricane Kick)
  // combo is: DOWN, DOWN+LEFT, LEFT, LEFT+K1 or LEFT+K2
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_3A ) )
    animation_combo_3();
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_3B ) )
    animation_combo_3();

  // combo #2
  // test for: Ryu Shoryuken (Dragon Punch)
  // combo is: RIGHT, <NONE>, DOWN, DOWN+RIGHT, DOWN+RIGHT+P1 or DOWN+RIGHT+P2
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_2A ) )
    animation_combo_2();
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_2B ) )
    animation_combo_2();

  // combo #1
  // test for: Ryu Hadouken (Fireball)
  // combo is: DOWN, DOWN+RIGHT, RIGHT, RIGHT+P1 or RIGHT+P2
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_1A ) )
    animation_combo_1();
  if ( kaimana.switchHistoryTest( COMBO_PATTERN_1B ) )
    animation_combo_1();

  //Tournament mode
  // Adding a custom animation when pressing buttons


  // zero active switch counter (note: 4 way joystick counts as 1)
  iActiveSwitchCount = 0;

  // set LED color based on switch
  for (i = 0; i < LED_COUNT; ++i)
  {
    if (iLED[i] == true)
      ++iActiveSwitchCount;
  }

  // update the leds with new/current colors in the array
  kaimana.updateALL();

  // return number of active switches
  return (iActiveSwitchCount);
}

#1351

You want to set all the buttons to black when you activate tournament mode.
kaimana.setALL( BLACK )

Try calling this method either during activation here

//Button hold to start tourneymode
holdTimeout += 1;
if (holdTimeout == 3000)
{
  tournamentMode = true;
  tourneyModeActivate();
  kaimana.setALL( BLACK );
}
// switch is active
if (iLED[LED_START] == true)
{
  //maintain color while switch is active
  iLED[LED_START] = true;

}
else
{

or within int tourneypollSwitches(void) before kaimana.updateALL(); all the way at the bottom.

// update the leds with new/current colors in the array
kaimana.setALL( BLACK );
kaimana.updateALL();

EDIT: I feel like I should give an explanation. It looks like when this code is in “tournment mode” it stops passing anything to the change the LEDs. All LED output is passed through the kaimana.setLED method and iirc kaimana.setALL calls the previous method (i could be wrong)

take a look at the normal mode K1 button:

  // test switch and set LED based on result

if (!digitalRead(PIN_K1))
{
switchActivity |= ATTACK_K1;

// switch is active
if (iLED[LED_K1] == true)
{
  //maintain color while switch is active
  iLED[LED_K1] = true;
}
else
{
  // select new color when switch is first activated

#ifdef RANDOM_COLOR_K1_ON
setLEDRandomColor(LED_K1);
#else
kaimana.setLED(LED_K1, LED_K1_COLOR_ON);
#endif
iLED[LED_K1] = true;
}
}
else
{
// switch is inactive
#ifdef RANDOM_COLOR_K1_OFF
setLEDRandomColor(LED_K1);
#else
kaimana.setLED(LED_K1, LED_K1_COLOR_OFF);
#endif
iLED[LED_K1] = false;
}

Notice how it’s calling kaimana.setLED whether it is active or not and passing LED_K1_COLOR_ON or LED_K1_COLOR_OFF respectively. That is why when you are in “tournament mode” with your current code, the inactive color stays the same and nothing changes when you press a button.


#1352

The site’s notifications keep being sent to my gmails junk folder. Reading these today and providing updates tonight.


#1353

@Finest_KO this is actually a feature of the connectors, they had to tiny tabs that fit into two slots inside the connector, use a small flathead screwdriver inside those slots to loosen up the tabs. what code are you using?

@ErybodyDyin awesome that you got the code working! see below for tourney.

@Robmo The way ive implemented tournament mode is to have a separate function that only waits for the button that disabled the tournament mode. Like below

int tourneypollSwitches(void)
{
static int iLED[LED_COUNT];
static int iActiveSwitchCount = 0;
static int i;
static int j;
static int firsttime;
static uint16_t joystickDirection;
static uint16_t switchActivity;

// test switch and set LED based on result // HOME = GUIDE
if(!digitalRead(PIN_START))
{
//Button hold to change idle animation
holdTimeout += 1;
//Button hold to start tourneymode
if(holdTimeout == 200)
{
tournamentMode = false;
tourneyModeDeactivate();
}
++iActiveSwitchCount;
delay(10);
}
else
{
holdTimeout=0;
}
return(iActiveSwitchCount);
}


#1354

Really new to this so sorry if this has been discussed before but I was using the hitbox code and I was trying to change the idle animation in the settings to the breathe animation and I get this error anyone know how to fix this?

Arduino: 1.6.5 (Windows 8.1), Board: “Arduino Leonardo”

animations.cpp.o: In function breatheSine(int, int, int)': C:\Users\Danny\AppData\Local\Temp\build489415380580964501.tmp/animations.cpp:176: undefined reference toKaimana::setLEDBrightness(int, int, int, int, float)’
collect2.exe: error: ld returned 1 exit status
Error compiling.


#1355

Hey @CptCommando,

Can you walk me through what you did to the code?

Cheers


#1356

I tried changing _IDLE_DEFAULT to _IDLE_BREATHE_ANIMATION in the settings and thats the error I get when I try to compile


#1357

I pushed a ffix to the repo, the function didnt exist in the hitbox version of the code. My bad!


#1358

does anyone still have the code to do this or know how it was done?


#1359

Which part?

I have an idea for the storing of profiles between power cycles but need to test it with my own setup, there is a small segment of memory in the arduino that is powercycle persistent but its very fragile, its documented to fail after 100K operations on it so it doesnt last forever.


#1360

The profile part is the one I’m most interested in although how he did his marvel 3 loadout was pretty cool too and wouldn’t mind learning or having the code for that too. Also, thanks for writing a lot of the code on your Github, I’m just now starting to learn how to code haha and your code has made my life a lot easier.


#1361

I’m thinking of getting a Kaimana, I’m just wondering how many extra J2 LED modules the Kaimana can handle over the standard 8 in the kit? I’m going to be building a stick with the Brook UFB, and I’d like to light the six extra service buttons on the edge of the stick body, along with the usual 8 action buttons.


#1362

I wouldnt go above 30~35 (15 J2s) without an external power supply.


#1363

Finally getting my kaimana kit tomorrow, I’m so excited!! :smiley:

I have another noob question, due to my wiring and laziness to rewire my hitbox, I’m curious if it’s safe to keep the micro usb plugged into the kaimana indefinitely, I have a plexicase and I do intend taping the cable down so it doesn’t move.

I’m wondering because it would be very difficult to access the kaimana after wiring everything up and I do want to mess around with the code for quite awhile and it would be a hassle to do it that way etc basically just trying to see if I should rewire my hitbox to make it easier to access or not.


#1364

While it is technically safe to keep the microUSB plugged into the Kaimana, remember that it will not enable the Controller pcb to communicate with the console so you will have to have 2 usb cables dangling from the stick. Connecting those two usb plugs by mistake at the same time will be a bad day for everyone so I wouldnt run the risk.

Thats the ugly fast solution, the correct solution is to wire up a dpdt switch to the data lines on the Controller pcd and the Kaimana, like they do with the old school dual mods.


#1365

Thanks man :smiley: I just rewired it for easy access instead, I appreciate the advice and it seems I need a little more I got this error while compiling your hitbox code from github,

"Arduino: 1.6.11 (Windows 10), Board: “Arduino Leonardo”

Sketch uses 12,436 bytes (43%) of program storage space. Maximum is 28,672 bytes.
Global variables use 437 bytes (17%) of dynamic memory, leaving 2,123 bytes for local variables. Maximum is 2,560 bytes.
An error occurred while uploading the sketch

This report would have more information with
“Show verbose output during compilation”
option enabled in File -> Preferences. "

Anyway, I googled it and the person said he uploaded as soon as plugging the micro usb in, couldn’t get that method to work, any ideas? :slight_smile: Thanks again man, you are a hero for helping everyone out, much appreciated


#1366

In the top menu go to File-Preferences and select Show verbose output during compilation, then build it again so that the real error comes out


#1368

Hiya!

I think that if you wire the VCC to the TEs pcb you will be good .


#1369

Hi, everyone! I’m new here, just installed a kaimana mini to my hitbox and I was wondering if any of the vets here could help me implement a tournament mode so that I don’t distract my friends at casuals. I’m using a generated sketch from the brightstick.freecade site. I seen someone had posted near the beginning of this thread a video of their setup, with a menu mode to select different profiles, it would be cool if I could do that.

I work 3rd shift and live in the midwest, so I will check back tomorrow.

EDIT: I just seen the October 18 post for tournament mode, I will give that a try.


#1370

Hi all, I have a kaimana mini and an old SE stick. I want to make a fun light up joystick toy for my 1 year old son. I don’t need the SE to control anything. I don’t have a Brook fighting board.

Is there a pinout available for the kaimana mini? I’m hoping to just power the kaimana mini using the stock SE pcb’s VCC.

Thanks!