Usb woes

After all of the work put in to understanding hid usb and creating my pinball controller, I sat down today and created a simple pinball game in unity.  

I used my controller in windows the entire time.  I had to program it a bit more simplistic for now to get the physics worked out in game, but all in all I was having a great experience.  

I built the game for android and then installed it on my phone.  Plugged in the controller using an otg cable and then loaded the game. No input.  This must be an error.  Tried again.  No input. Ahhhhhh!

For some unknown reason,  I can't get unity on android to recognize my device properly.  Android itself randomly selects things when buttons are pushed, so something is happening.  

I then loaded up the bt joystick mapping app I purchased a while back to map a joystick for a vr flight sim on android and it found it right away. but when trying to assign bits to the buttons,  nothing would activate when buttons were pushed. a prompt at the top of the app made it clear that it was receiving something. But I have not had any luck with it actually allowing input. 

I did see that there is now an upgraded nicohood library to use, so I will treat that and see if there are any differences.  But with the comments from a couple people stating similar problems with Linux and android, I'm pretty sure that I'm out of luck.  

Nicohood built his library based on the same thing I built mine.  I understand his is very nice, but he doesn't have the time to look in to the android problem.  There is another user who is though. 

For now, my dreams of custom hardware and software controllers for mobile vr are dying on the vine.  I'll just tear apart an old moga bluetooth controller to make this build. I found several for 5 bucks each a year ago and haven't used them.  

At least all is not lost, I can always build custom controllers for desktop based vr.  And maybe this person working on his own controller for android will figure this out for me.  Or, once I regain my resolve, I'll do it myself. But now it's time to focus on game development. 

Revised Pinball Controller Code

So with my last attempt, I was using a SPST switch and attempting to use a spring to release the button. After several failed linear pots and a half working sketch, I tried something else.

This time I am using a endstop type switch that is SPDT and I wired the Norm off position to the button 3 input and the Norm on position to the button 4 input. I tried to do the same sketch with the SPST using the ON position to start the readPull() function, and it just plain will not work. This solutino takes another input to resolve the issue, but it seems to work cleanly.

The only thing is, because the function is outside the loop, the buttons wont work while pulling back. But, I do not think that people usually push the buttons while pulling the shooter. And now that I write this, I could just put the other buttons in to the function and in the off chance that you would push them, it would still work.

Anyhow, this is the updated code. I will post the schematics another time. I need to move on to the actual game. I wasted enough time trying to figure out the pull shooter code.


/*
All around joystick to easily create custom layouts 


// this is the address of each button in the 4 bytes 
definitions :
#define BUTTON_1 0x01
#define BUTTON_2 0x02
#define BUTTON_3 0x03
#define BUTTON_4 0x04
#define BUTTON_5 0x05
#define BUTTON_6 0x06
#define BUTTON_7 0x07
#define BUTTON_8 0x08
#define BUTTON_9 0x09
#define BUTTON_10 0x0A
#define BUTTON_11 0x0B
#define BUTTON_12 0x0C
#define BUTTON_13 0x0D
#define BUTTON_14 0x0E
#define BUTTON_15 0x0F
#define BUTTON_16 0x10
#define BUTTON_17 0x11
#define BUTTON_18 0x12
#define BUTTON_19 0x13
#define BUTTON_20 0x14
#define BUTTON_21 0x15
#define BUTTON_22 0x16
#define BUTTON_23 0x17
#define BUTTON_24 0x18
#define BUTTON_25 0x19
#define BUTTON_26 0x1A
#define BUTTON_27 0x1B
#define BUTTON_28 0x1C
#define BUTTON_29 0x1D
#define BUTTON_30 0x1E
#define BUTTON_31 0x1F
#define BUTTON_32 0x20

*/

    #include <Bounce2.h>
    JoyState_t joySt; // joystick HID descriptor
    
    
    const bool DEBUG = false;  // set to true to debug the raw values
    int BUTTON_1 = 11;// LEFT TRIGGER ON PINBALL
    int BUTTON_2 = 10;//RIGHT TRIGGER ON PINBALL
    int BUTTON_3 = 9; //Used to trigger the value of the pinball shooter at its apex
    int BUTTON_4 = 8; //
    int throttlePin = A5; //One Axes for pinball shooter
    int xPin = A2;
    int yPin = A3;
    int xZero, yZero;
    int xValue, yValue;
    int deadzone = 5;  // smaller values will be set to 0
    int throttleValue;// CURRENTLY SET TO PINBALL LAUNCHER
    unsigned int maxRead ; //SET MAXREAD AS THE MAX INPUT FOR THE BALL
    unsigned int lastRead; // last stored reading greater than previous
    unsigned int pushed; //was the button pushed last time?
    int count = 0;
    int maxCount = 100; // number of loops to allow the axis to be sent to the computer. The lower the number the less accurate the input. I will figure this out later.



/**************************************************************************************/
    void setup()
    {

    if(DEBUG) {
        Serial.begin(9600);
               }
    

        maxRead = 0;  //zero the value before loop
        lastRead = 0; // zero the value before loop
        pushed = false;
     
    // Setup the button with an internal pull-up :
  
  
        pinMode(BUTTON_1,INPUT_PULLUP); 
        pinMode(BUTTON_2,INPUT_PULLUP);
        pinMode(throttlePin, INPUT);
        pinMode(xPin, INPUT);
        pinMode(yPin, INPUT);
        pinMode(BUTTON_3,INPUT_PULLUP); 
        pinMode(BUTTON_4,INPUT_PULLUP);     
        xZero = analogRead(xPin);
        yZero = analogRead(yPin);
       
    

    // zero out all axis and button variables 
    joySt.xAxis = 0;
    joySt.yAxis = 0;
    joySt.zAxis = 0;
    joySt.xRotAxis = 0;
    joySt.yRotAxis = 0;
    joySt.zRotAxis = 0;
    joySt.throttle = 0;
    joySt.rudder = 0;
    joySt.hatSw1 = 0;
    joySt.hatSw2 = 0;
    joySt.buttons = 0;

       }


  void loop() {
          
    while(digitalRead(BUTTON_4) == HIGH){
      pushed = false;
      count = 0;   
      readPull();
    }
        
        
        if ((pushed == true) && (count <= maxCount)) { // if the button was pressed and the max count has not been reached
        joySt.zAxis = map(maxRead,0,1023,0,255); // map the output to the axis
        count++; // add one to the count
          }
         else if (count = maxCount){
           pushed = false;
           count = 0;
           joySt.zAxis = 0;
         }       


        joySt.buttons = 0x00; // off state
        
        
        if (digitalRead(BUTTON_1) == LOW){
        joySt.buttons += 0x01;
        
        }
        
        if (digitalRead(BUTTON_2) == LOW){
        joySt.buttons += 0x02; //adds the two inputs together
       
        }
        


        xValue = analogRead(xPin) - xZero;
    yValue = analogRead(yPin) - yZero;

    if(abs(xValue) < deadzone) {
        xValue = 0;
    }
    if(abs(yValue) < deadzone) {
        yValue = 0;
    }

    

    joySt.xAxis = map(xValue, 450, -450, 0, 255);  // here the axis is inverted
    joySt.yAxis = map(yValue, -400, 400, 0, 255);

        
        
    if(DEBUG) {
        Serial.print("X: ");
        Serial.println(xValue);
        Serial.print("Y: ");
        Serial.println(yValue);
                Serial.print("Throttle value");
                Serial.println(throttleValue);
                Serial.print("maxread");
                Serial.println(maxRead);
                Serial.print("lastRead");
                Serial.println(lastRead);
                
    }




    // Call Joystick.move
    Joystick.setState(&joySt);

     }
                /**************************************************/
   void readPull() {
     
         throttleValue = analogRead(throttlePin);  //(throttlePin) - throttleZero;
         joySt.throttle = map(throttleValue,0,1023,0,255); // scaling the throttle value      
  
         if (digitalRead(BUTTON_3) == HIGH){ //if the button is pushed set pushed to true and lastread to 0 and set the axis value to the max read. lastread will read on the next loop
           pushed = true;  
           lastRead = 0;
         }
           
           // THIS SECTION WILL DETERMINE THE LAST HIGHEST READING AND APPLY THAT TO THE BUTTON 
        
        if (throttleValue > lastRead) {
                 lastRead = throttleValue; // store the current throttle value in last read
        }
          else if (throttleValue <= lastRead) { //throttle is changing direction so record th elast value that was the highes t and store it 
                 maxRead = lastRead;  // store the max value in last read
              
        }
        
            // Call Joystick.move
    Joystick.setState(&joySt); // apparently this has to be called every time to update the position of an axis or joystick button. 
         }

   
                /**************************************************/

Until next time.....

FINALLY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! figured it out

And now that I have it figured out, I feel stupid. I guess sleeping on it works.

While trying to get the variable to reset after the button was pushed, i was clearing all of the variables that were sent to the button push. But not the variable that creates the data for the other variables. I just figured that since the value would shift so much all of the time, it would not matter if I did clear it.

But, I cant process information in the linear fashion that this code does, so my brain broke when I tried to reason with it. I am so glad I didn't post this question on Stack Exchange. That would be an invitation for trolling, for sure.

But here is my code as of now.

 


/*
All around joystick to easily create custom layouts 


// this is the address of each button in the 4 bytes 
definitions :
#define BUTTON_1 0x01
#define BUTTON_2 0x02
#define BUTTON_3 0x03
#define BUTTON_4 0x04
#define BUTTON_5 0x05
#define BUTTON_6 0x06
#define BUTTON_7 0x07
#define BUTTON_8 0x08
#define BUTTON_9 0x09
#define BUTTON_10 0x0A
#define BUTTON_11 0x0B
#define BUTTON_12 0x0C
#define BUTTON_13 0x0D
#define BUTTON_14 0x0E
#define BUTTON_15 0x0F
#define BUTTON_16 0x10
#define BUTTON_17 0x11
#define BUTTON_18 0x12
#define BUTTON_19 0x13
#define BUTTON_20 0x14
#define BUTTON_21 0x15
#define BUTTON_22 0x16
#define BUTTON_23 0x17
#define BUTTON_24 0x18
#define BUTTON_25 0x19
#define BUTTON_26 0x1A
#define BUTTON_27 0x1B
#define BUTTON_28 0x1C
#define BUTTON_29 0x1D
#define BUTTON_30 0x1E
#define BUTTON_31 0x1F
#define BUTTON_32 0x20

*/

    #include <Bounce2.h>
    JoyState_t joySt; // joystick HID descriptor
    
    
    const bool DEBUG = false;  // set to true to debug the raw values
    int BUTTON_1 = 11;// LEFT TRIGGER ON PINBALL
    int BUTTON_2 = 10;//RIGHT TRIGGER ON PINBALL
    int BUTTON_3 = 9; //Used to trigger the value of the pinball shooter at its apex
    int throttlePin = A5; //One Axes for pinball shooter
    int xPin = A2;
    int yPin = A3;
    int xZero, yZero;
    int xValue, yValue;
    int deadzone = 5;  // smaller values will be set to 0
    int throttleValue;// CURRENTLY SET TO PINBALL LAUNCHER
    unsigned int maxRead ; //SET MAXREAD AS THE MAX INPUT FOR THE BALL
    unsigned int lastRead; // last stored reading greater than previous
    unsigned int pushed; //was the button pushed last time?



/**************************************************************************************/
    void setup()
    {

    if(DEBUG) {
        Serial.begin(9600);
               }
    

        maxRead = 0;  //zero the value before loop
        lastRead = 0; // zero the value before loop
        pushed = false;
     
    // Setup the button with an internal pull-up :
  
  
        pinMode(BUTTON_1,INPUT_PULLUP); 
        pinMode(BUTTON_2,INPUT_PULLUP);
        pinMode(throttlePin, INPUT);
        pinMode(xPin, INPUT);
        pinMode(yPin, INPUT);
        pinMode(BUTTON_3,INPUT_PULLUP);      
        xZero = analogRead(xPin);
    yZero = analogRead(yPin);
       
    

    // zero out all axis and button variables 
    joySt.xAxis = 0;
    joySt.yAxis = 0;
    joySt.zAxis = 0;
    joySt.xRotAxis = 0;
    joySt.yRotAxis = 0;
    joySt.zRotAxis = 0;
    joySt.throttle = 0;
    joySt.rudder = 0;
    joySt.hatSw1 = 0;
    joySt.hatSw2 = 0;
    joySt.buttons = 0;

       }


  void loop()
        {
        joySt.buttons = 0x00; // off state
        
   
        if (digitalRead(BUTTON_1) == LOW){
        joySt.buttons += 0x01;
        
        }
        
        if (digitalRead(BUTTON_2) == LOW){
        joySt.buttons += 0x02; //adds the two inputs together
       
        }
        
        if (digitalRead(BUTTON_3) == LOW){ //if the button is pushed set pushed to true and lastread to 0 and set the axis value to the max read. lastread will read on the next loop
           joySt.zAxis = map(maxRead,0,1023,0,255);
           pushed = true;
           delay(1);
           lastRead = 0;
           
        }        
       
        xValue = analogRead(xPin) - xZero;
    yValue = analogRead(yPin) - yZero;

    if(abs(xValue) < deadzone) {
        xValue = 0;
    }
    if(abs(yValue) < deadzone) {
        yValue = 0;
    }

    throttleValue = analogRead(throttlePin);  //(throttlePin) - throttleZero;
    
    
        // THIS SECTION WILL DETERMINE THE LAST HIGHEST READING AND APPLY THAT TO THE BUTTON 
        
        if (throttleValue > lastRead) {
                 lastRead = throttleValue; // store the current throttle value in last read
        }
          else if (throttleValue <= lastRead) { //throttle is changing direction so record th elast value that was the highes t and store it 
                 maxRead = lastRead;  // store the max value in last read
              
        }

        if (digitalRead(BUTTON_3) == HIGH && (pushed = true)){ // if the button is pressed and let go, set the axis back to 0
           joySt.zAxis = 0;
           pushed = false;
          }
          



    joySt.xAxis = map(xValue, 450, -450, 0, 255);  // here the axis is inverted
    joySt.yAxis = map(yValue, -400, 400, 0, 255);
        joySt.throttle = map(throttleValue,0,1023,0,255); // scaling the throttle value
        
        
    if(DEBUG) {
        Serial.print("X: ");
        Serial.println(xValue);
        Serial.print("Y: ");
        Serial.println(yValue);
                Serial.print("Throttle value");
                Serial.println(throttleValue);
                Serial.print("maxread");
                Serial.println(maxRead);
                Serial.print("lastRead");
                Serial.println(lastRead);
                
    }

//  joySt.xAxis = random(255);
//  joySt.yAxis = random(255);
//  joySt.zAxis = random(255);
//  joySt.xRotAxis = random(255);
//  joySt.yRotAxis = random(255);
//  joySt.zRotAxis = random(255);
//  joySt.throttle = random(255);
//  joySt.rudder = random(255);
//
//  joySt.throttle++;
//
//
//  joySt.buttons <<= 1;
//  if (joySt.buttons == 0)
//      joySt.buttons = 1;
//
//  joySt.hatSw1++;
//  joySt.hatSw2--;
//
//  if (joySt.hatSw1 > 8)
//      joySt.hatSw1 = 0;
//  if (joySt.hatSw2 > 8)
//      joySt.hatSw2 = 8;
//
//  delay(100);
//
//  if (joySt.throttle > 127)
//      digitalWrite(13, HIGH);
//  else
//      digitalWrite(13, LOW);


    // Call Joystick.move
    Joystick.setState(&joySt);

    }

These two files enable you to replace the default HID descriptors in the arduino IDE. To use them in your projects, with an arduino leonardo or an arduino pro micro, rename your original files and place them in a folder within the directory. Use the .BAK file extension to remind you that it is a backup. The directory is in C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino and the files to replace are HID.cpp and USBAPI.h.

The files are below for use. I originaly saw this when first researching @ http://www.instructables.com/id/Add-a-little-two-analog-axis-thumb-joystick-to-you/?ALLSTEPS

Then that pointed towards http://www.imaginaryindustries.com/blog/?p=80

Which gave me insight in to the working of HID. it is confusing at first, but once you stare at the HID descriptors and play with the descriptor tool from the USB site and some other sites that have java versions of the descriptor tool.

And this is the list of sites I read through to understand this stuff more. It should be comprehensive if you are willing to look through them. I pretty much did all of the googling for you.

http://share.xmarks.com/folder/bookmarks/nOiUcxaHt6

This is using xmarks so its web based.



Pinball Controller HID code

So, i worked on my controller for  a while last night. I have it working, but I need to refine the program a bit. 

So far I have the left and right buttons, the trigger button and the shooter. The left and right buttons are digital. The shooter is a linear potentiometer, and the trigger button is digital but just sends the highest value from the potentiometer before the button was pressed.

The thing is, I can't quite figure out what I am doing wrong with the code. I know it has to clear the variable, but I began to get stuck in a loop last night, so I gave up until I could think clearly again.

This is the code currently, it is adapted from this project here:  http://www.imaginaryindustries.com/blog/?p=80 

 

/*

 

// this is the address of each button in the 4 bytes 
definitions :
#define BUTTON_1 0x01
#define BUTTON_2 0x02
#define BUTTON_3 0x03
#define BUTTON_4 0x04
#define BUTTON_5 0x05
#define BUTTON_6 0x06
#define BUTTON_7 0x07
#define BUTTON_8 0x08
#define BUTTON_9 0x09
#define BUTTON_10 0x0A
#define BUTTON_11 0x0B
#define BUTTON_12 0x0C
#define BUTTON_13 0x0D
#define BUTTON_14 0x0E
#define BUTTON_15 0x0F
#define BUTTON_16 0x10
#define BUTTON_17 0x11
#define BUTTON_18 0x12
#define BUTTON_19 0x13
#define BUTTON_20 0x14
#define BUTTON_21 0x15
#define BUTTON_22 0x16
#define BUTTON_23 0x17
#define BUTTON_24 0x18
#define BUTTON_25 0x19
#define BUTTON_26 0x1A
#define BUTTON_27 0x1B
#define BUTTON_28 0x1C
#define BUTTON_29 0x1D
#define BUTTON_30 0x1E
#define BUTTON_31 0x1F
#define BUTTON_32 0x20

*/

#include <Bounce2.h>
JoyState_t joySt; // joystick HID descriptor


const bool DEBUG = false;  // set to true to debug the raw values
int BUTTON_1 = 11;// LEFT TRIGGER ON PINBALL
int BUTTON_2 = 10;//RIGHT TRIGGER ON PINBALL
int BUTTON_3 = 9; //Used to trigger the value of the pinball shooter at its apex
int throttlePin = A5; //One Axes for pinball shooter
int xPin = A2;
int yPin = A3;
int xZero, yZero;
int xValue, yValue;
int deadzone = 5;  // smaller values will be set to 0
int throttleValue;// CURRENTLY SET TO PINBALL LAUNCHER
unsigned int maxRead ; //SET MAXREAD AS THE MAX INPUT FOR THE BALL
unsigned int lastRead; // last stored reading greater than previous
unsigned int count;
unsigned int count1;
void setup()
{

//     if(DEBUG) {
         Serial.begin(57600);
     

        maxRead = 0;  //zero the value before loop
        lastRead = 0; // zero the value before loop
        count = 0;
        count1 = 0;
    // Setup the button with an internal pull-up :
  
  
        pinMode(BUTTON_1,INPUT_PULLUP); 
        pinMode(BUTTON_2,INPUT_PULLUP);
        pinMode(throttlePin, INPUT);
        pinMode(xPin, INPUT);
        pinMode(yPin, INPUT);
        pinMode(BUTTON_3,INPUT_PULLUP);      
        xZero = analogRead(xPin);
    yZero = analogRead(yPin);
       
    

    // guessing that these values are zeroed at the beginning of the sketch
    joySt.xAxis = 0;
    joySt.yAxis = 0;
    joySt.zAxis = 0;
    joySt.xRotAxis = 0;
    joySt.yRotAxis = 0;
    joySt.zRotAxis = 0;
    joySt.throttle = 0;
    joySt.rudder = 0;
    joySt.hatSw1 = 0;
    joySt.hatSw2 = 0;
    joySt.buttons = 0;

}


void loop()
{
        joySt.buttons = 0x00; // off state
        
//        if (count = 1) {
        if (digitalRead(BUTTON_3) == HIGH){
        joySt.zAxis = 0;
//        count = 0;
        }
        

        
        if (digitalRead(BUTTON_1) == LOW){
        joySt.buttons += 0x01;
        
        }
        
        if (digitalRead(BUTTON_2) == LOW){
        joySt.buttons += 0x02; //adds the two inputs together
       
        }
        
        
        if (digitalRead(BUTTON_3) == LOW){
           joySt.zAxis = map(maxRead,0,1023,0,255);
//           count = 1;   
           
        }
        
        xValue = analogRead(xPin) - xZero;
    yValue = analogRead(yPin) - yZero;

    if(abs(xValue) < deadzone) {
        xValue = 0;
    }
    if(abs(yValue) < deadzone) {
        yValue = 0;
    }

     throttleValue = analogRead(throttlePin);  //(throttlePin) - throttleZero;
    
    
        // THIS SECTION WILL DETERMINE THE LAST HIGHEST READING AND APPLY THAT TO THE BUTTON 
        
        if (throttleValue > lastRead) {
                 lastRead = throttleValue; // store the current throttle value in last read
        }
          else if (throttleValue < lastRead) {
                 maxRead = lastRead;  // store the max value in last read
          }
          
    
          

 

    joySt.xAxis = map(xValue, 450, -450, 0, 255);  // here the axis is inverted
    joySt.yAxis = map(yValue, -400, 400, 0, 255);
        joySt.throttle = map(throttleValue,0,1023,0,255); // scaling the throttle value
        
        
//     if(DEBUG) {
//         Serial.print("X: ");
//        Serial.println(xValue);
//         Serial.print("Y: ");
//        Serial.println(yValue);
//                Serial.print("Throttle value");
//                Serial.println(throttleValue);
//    }

//    joySt.xAxis = random(255);
//    joySt.yAxis = random(255);
//    joySt.zAxis = random(255);
//    joySt.xRotAxis = random(255);
//    joySt.yRotAxis = random(255);
//    joySt.zRotAxis = random(255);
//    joySt.throttle = random(255);
//    joySt.rudder = random(255);
//
//    joySt.throttle++;
//
//
//    joySt.buttons <<= 1;
//    if (joySt.buttons == 0)
//        joySt.buttons = 1;
//
//    joySt.hatSw1++;
//    joySt.hatSw2--;
//
//    if (joySt.hatSw1 > 8)
//        joySt.hatSw1 = 0;
//    if (joySt.hatSw2 > 8)
//        joySt.hatSw2 = 8;
//
//    delay(100);
//
//    if (joySt.throttle > 127)
//        digitalWrite(13, HIGH);
//    else
//        digitalWrite(13, LOW);


    // Call Joystick.move
    Joystick.setState(&joySt);

}

 

I need to figure out how to make a timer that actually counts well. I think. But, it is thanksgiving today, and I have two sick kids. I will have to return to this tomorrow. For now I will just think about it.

USB HID Pinball Controller

another project that I've started is a pinball virtual reality game for Android. So to make this game feel more realistic and give you a sense of presence I am creat It took me a few days but I figured out how to make the pull for the ball shooter, and it works, but not a amazingly. I may actually end up ordering a real pull shooter but I'm going to wait on that for a minute until I finish the code.

I'm using a full-size Arduino Leonardo for the HID input. Hopefully I'll have time this week code it and test. Then on to asset creation in 3ds max and then to unity for game development.

i wanted to use debouncing for my input buttons, but then after researching, i found that there are a crazy amount of ways to do it. Note i have to find the best for this project.  

upload.jpeg
upload.jpeg

3d scanner

I am working on a 3d scanner for a full body.I have a few things complete, but I still have a lot of work to do. My 3d printer is down at the moment and waiting for some parts to be machined for me. I have a working turntable but I'm waiting on the motor to come in. I tried to use another motor from a wheelchair for the seat raising portion, but the speed on it is way too fast and when I use a PWM controller to then control the speed the torque is not high enough. I ended up ordering a cheap one with 4.5 rotations per minute motor off of Amazon and it should be here in a couple of days. 

I have several projects that I am working on at the moment so I'm going to post pictures and instructions at some point but as of now I'm just going to go over what I have actually done so far. 

upload.jpeg

Here is the working spinning lazy Susan without any motor. I made it with scrap plywood I had around.

Updates to come... 

Electronic controller case

I have the electronics case printed and sanded. I have filled most of the divots with Tamiya putty.
I'll have this ready by the end of the week.
Then I'm moving on to the molding. I will most likely make a mother mold for this piece. It's fairly complicated and I want to use as little silicone as I can. Especially with the issue I ran in to the last time I tried to mold a part of this project.

just after printing
just after printing
after the first sanding and vapor chamber
after the first sanding and vapor chamber
here are the other parts of the project. almost fondue with the master models
here are the other parts of the project. almost fondue with the master models

Platinum Cure Silicone Inhibition Test

I recently purchased Smooth-On's sortaclear 40 for a project i have been working on. I spent at least a week getting my model ready. Starting with a 3d print of the object, i then sanded and smoothed the abs and filled, primed, and painted the object. I was finally ready to make my mold and spent another day figuring out the best possible way to set up the sprues and vents. Then it came down to pouring my silicone. I degassed the mixture and poured it perfectly, no air entrapment. It was beautiful. I then used my pressure chamber to cure the mold.

After 20 hours of curing, I found that it set up great, But i could see a gap between the model and the silicone. I opened it up to see if anything touching the model surface did not cure. After all my forethought and planning, I didn't even question whether or not my surface would inhibit the silicone.

20140131_162754.jpg

After reading the information for the silicone. I saw that they recommend sealing your model with an acrylic lacquer. I searched at every store I could think of to find a matte finish clear acrylic lacquer, and could only find a gloss clear lacquer.

You can purchase acrylic lacquer at most auto supply stores. I also found one product at hobby lobby that is a matte acrylic, but not a lacquer. Rustoleum sells acrylic lacquer at auto zone and probably other auto supply stores. I have also found that duplicolor has an entire line of acrylic paints, but I couldnt find exactly what I needed for this project. 

Because I want to make sure that this works before I waste another pound or so of silicone, I am going to do a test on all of the products that I have used so far in my model as well as adding the two other products I have purchased.

Here are the products used in this test:

The test is laid out from left to right and then one object on the bottom of the page.

1. Plain abs

2. Rustoleum flat gray primer

3. Duplicolor filler primer. High build formula

4. Rustoleum smooth protective enamel

5. Rustoleum acrylic lacquer. Crystal clear gloss

6. Tree House Studio clear acrylic matte coating 

7. Rustoleum acrylic lacquer. Crystal clear gloss on the first coat and Tree House Studio clear acrylic matte coating on top. I want a matte finish, so maybe if I seal with the gloss acrylic lacquer and then coat with the matte acrylic, it will not react. But just in case I need to test this before wasting mass material.

20140201_104045.jpg

Here are the pieces, covered with the silicone rubber, before curing.

 

20140201_111512.jpg

And finally, the pieces after curing.

   

 

 

As you may be able to tell from the photo, the only one to inhibit the curing of Smooth-On sorta clear 40 was the Rustoleum smooth protective enamel.

I do not know if this contains any sulfur, but I know that it should not be used with your silicone molds. 

The ones that did work

1. Rustoleum flat gray primer

2. Duplicolor filler primer. High build formula

3. Rustoleum acrylic lacquer. Crystal clear gloss

4. Tree House Studio clear acrylic matte coating 

The combination of the clear and the matte also cured fine. The abs worked as well. But I did that as a control, just in case. 

(UPDATE) just a note to people who would like to be able to clean their master model. Use rubbing alcohol. It may eat away at some of the paint, but you're going to have to remove that anyway.