contact us

Use the form on the right to contact us.

You can edit the text in this area, and change where the contact form on the right submits to, by entering edit mode using the modes on the bottom right.


123 Street Avenue, City Town, 99999

(123) 555-6789


You can set your address, phone number, email and site description in the settings tab.
Link to read me page with more information.


Pinball Controller HID code

michael woodrum

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: 




// 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_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
unsigned int lastRead; // last stored reading greater than previous
unsigned int count;
unsigned int count1;
void setup()

//     if(DEBUG) {

        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(throttlePin, INPUT);
        pinMode(xPin, INPUT);
        pinMode(yPin, INPUT);
        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;
        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



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

michael woodrum

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.  


3d scanner

michael woodrum

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. 


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

michael woodrum

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

michael woodrum

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.


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.


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



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.