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

One last thing - I’m using all this code with Arduino 1.6.5, is it worth updating to 1.6.11 or will that break all the other stuff I’ve added? Most of the files I’m working with were generated via here: http://brightstick.freecade.org/ , which mentions downloading 1.6.5 only.

I just don’t want to give myself more headaches by either using an outdated version of Arduino, or using one that’s too recent that then breaks all the work I’ve done so far.

I updated to 1.6.11 and tried my existing build - got loads of errors which I started to fix, but there were so many I stopped and went back to 1.6.5!

I’m now using your file in kaimana / Kaimana8btn / J2s / tester8btn / tester8btn.ino to copy from and hopefully add tournament mode without any issues. On the old build I was using, I’ve now managed to somehow change the old code so I can’t get it out of Tournament Mode and all my LEDs stay off no matter what I do! Long press on P1 doesn’t work anymore, not sure what I’ve done there, but if I get this new one working I won’t have to figure it out.

I’ll post back with more updates once I’ve got something working.

Thanks again.

Final update I hope! Managed to get the Tournament Mode working with a button/joystick combination for ON and a reversed one for OFF - all working perfectly.

The issue with my animations for EX moves (where 2 buttons are pressed at the same time with a joystick movement) still persists. I’ve tested with Tournament Mode removed from the code and I can get 10 out of 10 animations to work, when it’s on I get 1 or 2 out of 10. Really not sure why this is, looks like it’s affecting the ability to recognise joystick movements ending with more than one button. My throw, V-Reversal and V-Trigger all work as they should (which all involve pressing 2 buttons simultaneously), so it seems to only affect 2 buttons + Joystick movements. Very odd!

I omitted the duplicate combo list in the code (because it made the file too big) and it doesn’t seem to make any difference. I just kept the duplicated code below for button presses and joystick (which I presume you need to keep):



 // 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_P1))
  {
        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);


But again, this is already referenced in the .ino file further up at the start. From what I understand it’s needed when the Tournament Mode is active so that it still recognises which buttons have been pressed etc. - is this correct?

I also tried breatheSine (PURPLE); and breatheSine (PINK); but the effect it gave was very flickery and not really a smooth transition. I don’t think I’ll need it right now anyway, so may go back and have a play in the future.

Other than those minor issues above, it’s all up and running and I can now actually play SFV and get back into ranked matches! The whole process from installing and modding the TE2+ to programming the LEDs was surprisingly intuitive and fairly easy to understand. I had visions of pulling my hair out, but luckily it all just worked! So, if anyone has a TE2+ and needs assistance with installing the LEDs or basic programming, I’m sure I can help.

Thanks to JRDIBBS for all your help and some great code.

Jamie

Just one last thing - when I first plugged this all in after wiring the mini breakout, kaimana khameleon etc. the joystick directions were upside down when moving my character on screen (even though I had double checked the wiring from the TE2+ joystick and it was correct). I solved this quickly by just turning the joystick PCB 180º, but this means the wire connecting to it is a little too short and has a bit of tension on it.

What do I need to change within the ino file (or wherever the joystick functions are) that will enable me to put my joystick PCB back around to where it was originally and give me a bit less stress on the joystick wire, so basically re-assign the pins within the software to the opposite of what they are now. Also if I do this (if it’s possible) will that mean all the moves I’ve input are reversed, or does this only affect how the joystick PCB interacts with the Kaimana and mini breakout? May seem like a bloody obvious question and solution to some, but I just want to double-check first.

Minor issue, but worth changing if possible and good to know for future reference.

Thanks.

I presume the joystick pins are in here (kaimana.h):



// Map function names to arduino leonardo atmega32u4 digital pin numbers
// specific to ParadiseArcadeShop.com Kaimana board (PS360+LED)
#define  PIN_DOWN    11   //PB7
#define  PIN_UP      18   //PF7
#define  PIN_LEFT    19   //PF6
#define  PIN_RIGHT   20   //PF5
#define  PIN_SELECT  9    //PB5
#define  PIN_HOME    8    //PB4
#define  PIN_START   10   //PB6
#define  PIN_P1      3    //PD0
#define  PIN_P2      2    //PD1
#define  PIN_P3      0    //PD2
#define  PIN_P4      1    //PD3
#define  PIN_K1      4    //PD4
#define  PIN_K2      21   //PF4
#define  PIN_K3      12   //PD6
#define  PIN_K4      6    //PD7
//
#define  PIN_LED     23


I’ll have a play and see if I break anything.

When referencing LEDs I see this used which refers to one specific LED:


kaimana.setLED( LED_K4, BLACK );

or this which refers to all LEDs:


kaimana.setALL(BLACK);

But is there a way of referencing a specific group of LEDs?

I’ve tried this:


kaimana.setLED( LED_K1, LED_K2, LED_K3, LED_K4, BLACK);

But it gives me an error. It would be really helpful to only reference P1 to P4 or K1 to K4 without having to put each one in individually. Is there a way to do this?

Reset the position of the pcb and switch the wires in the breakout.

You will have to create a function that will light groups up.

In answer to my own question, with reference this this:



// Map function names to arduino leonardo atmega32u4 digital pin numbers
// specific to ParadiseArcadeShop.com Kaimana board (PS360+LED)
#define  PIN_DOWN    11   <-- changed this to 18 //PB7
#define  PIN_UP      18   <-- changed this to 11  //PF7
#define  PIN_LEFT    19   <-- changed this to 20  //PF6
#define  PIN_RIGHT   20   <-- changed this to 19   //PF5


I made the above changes and I now have my joystick PCB back to where it was originally with less stress on my cable. Simple update.

Think I’ve solved this with my above software amendment, haven’t tried playing a game yet though, so it might still be reversed??? Will post back once updated.

Ah, OK. Might be a bit advanced for me, but I will see if I can work it out. I’ve done it “long-hand” and am just under the max file size. Just thought it would be useful in the animations where you have multiple references to K1, K2, K3, K4 etc. if you could condense it down to just K-ALL or something similar.

Just checked with the PS4 and swapping the pin numbers in the kaimana.h file doesn’t affect the actual joystick movements on screen, only the references to combo animations and joystick movements detected by the Kaimana. So thanks JRDIBBS, yes, had to re-wire, which is really annoying considering they’re all in the right place according to the labelling on the mini breakout and the back of the TE2+ main PCB, instead of 4 wires nicely in a row (as the cable is made), there are now 2 pairs crossed over each other. Nothing too major though.

what’s the advantage of USB switching in the khamelon compared to the standard kaimana? Any benefits other than being able to update with the main USB from your stick as opposed to directly to the led PCB?

I saw Jasen already answered your question here so I wont reiterate.

I presume that there is no way around this, but in programming the animations for SFV, they only show correctly if your character is facing right. There is no way for the Kaimana to know which way you’re facing I guess???

Nope, though you could program both directions since the input only goes one way (eg. a Hadouken is either qcf+p or qcb+p ).

Thanks for the confirmation. I thought that might be the case, it would be OK for Ryu and other characters as their special moves aren’t reversed, but Juri has qcf+k as her specials or charge and qcb+k as her flip kick so you’d have to have the same animation programmed for both. I might see if there’s a compromise. Thought I wouldn’t have to change anything else after spending all weekend programming animations! Fun times.

Also not sure if you’re able to answer the question in the other thread about not having to open up the fighstick to program etc. if you have a Khameleon.

After having seen the install videos on Fundado’s youtube channel I get a sense of it, especially with the breakout board.

If I’m going to make my own stick it will have to be for the Dreamcast. With the breakout board instead of a regular screw terminals going to the buttons.

Very interesting and should work fine, despite not having 4p and 4k. But I’m not sure how it works with the indexed rgbs in sequence. Will it know I don’t have a 4p and know it should go to 1k instead, or do I need to go through the code and remove the 4p and 4k functionality?

I have experience programming so that shouldn’t be an issue.

You basicaly define a new layout ommitting the 4p and 4k and change the LED_COUNT variable in the kaimana_custom file. will look something like this:


#ifdef _LED_ORDER_DEFAULT_
  // Map function names to default LED index numbers
  // specific to ParadiseArcadeShop.com Kaimana board (PS360+LED)
  // change or expand as needed
  //
  //   KAIMANA->LED_JOY->LED_HOME->LED_SELECT->LED_START->LED_P1->LED-P2->LED_P3->LED-P4->LED_K1->LED-K2->LED_K3->LED-K4
  //
  #define  LED_JOY     0
  #define  LED_HOME    1
  #define  LED_GUIDE   1
  #define  LED_SELECT  2
  #define  LED_BACK    2
  #define  LED_START   3
  #define  LED_P1      4
  #define  LED_P2      5
  #define  LED_P3      6
  #define  LED_P4      0xff
  #define  LED_K1      8
  #define  LED_K2      9
  #define  LED_K3      10
  #define  LED_K4      0xff
#endif

Well, after struggling with code for the last few months and realising I setup the whole thing wrong at the beginning, I managed to get two Kaimanas to interrupt each other! There are slight bugs in the timing but at this point I am looking towards rewriting the Kaimana routines from the ground up.

The bad news? I broke both my k-minis usb port from all the finagling. I might just build a development board so I can stop with the connect/disconnect that plagues my setup right now.

I am setting up to continue developing animations and building the Kaimana Wiki, whats your Kaimana project looking like?

Mine is still borked, the buttons are all working fine, but the LED balltop is still broken after the wires over rotated in the hollow shaft and snapped within a week of installing it. Was trying to come up with a way of having a rotating joint in there somewhere.

A place here in the UK sells a setup with an audio-jack connector at the bottom of the joystick shaft, but apparently it won’t fit into a JLF setup - so was looking at seeing if I could replicate that, but ultimately that would be far too complicated for me to do - and I don’t really know anyone who could do it =/

So left with either doing another order from PA, which ends up being crazy expensive because of their international shipping costs, and just ordering a bucket load of balltop LEDs and just changing them whenever they break - or trying to find someone locally who can try and put a 4-pole 2.5mm audio socket into the bottom of a hollow JLF shaft. But considering my facebook friend searches couldn’t even find anyone to do some really basic soldering for me… don’t really see it happening =/

ordering issues
give moledcule a try
hey all, we recently released version 1.0.3 which brings in the balltop fix
you can now order your wiring without writing code

we use a drag and drop for your buttons order

give it a shot
[color=#10cfbd]moledcule.club

or download the chrome app today
[/color]