Professional Documents
Culture Documents
Digitalduino - DIY Arduino Racing Wheel! (With Direct Port Manipulation) PDF
Digitalduino - DIY Arduino Racing Wheel! (With Direct Port Manipulation) PDF
Digitalduino - DIY Arduino Racing Wheel! (With Direct Port Manipulation) PDF
Since that i am now using multiple encoders and interrupts, i am now using direct port manipulation to
read the pin states as it is many times faster than regular digitalReads.
I found a way better way to write the Arduino values to the virtual joystick; PPJoyCom. It is a add-on
type program for the PPJoy virtual joystick driver. PPJoyCom waits for a initialization byte over the
serial port from the Arduino(print a byte value 240+number of channels). then the encoder values
range from 0 to 255(max value of a byte) and are sent to PPJoyCom and written to the joystick. way
easier than a C# app. :) basic sample PPJoyCom arduino sketch below, along with encoder code.
basic flow:
1. arduino reads HDD encoders for position, button states etc. sends the data to the PPJoyCom
program.
3. PPJoyCom program "writes" the values from the Arduino to the virtual joystick.
3. racing game reads the virtual joystick; X axis is turning, Y is throttle, Z is brake, buttons for shifting,
menu keys...
#define Xpin 2
#define Ypin 3
#define Btn1Pin 11
#define Btn2Pin 12
byte Xaxis;
byte Yaxis;
byte Btn1 = 0;
byte Btn2 = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Btn1 = digitalRead(Btn1Pin);
Btn2 = digitalRead(Btn2Pin);
Xaxis = analogRead(Xpin) / 4;
Yaxis = analogRead(Ypin) / 4;
#include <PinChangeInt.h>
#include <PinChangeIntConfig.h>
#define WheelPinA 2
#define WheelPinB 3
#define GasPinA 4
#define GasPinB 5
#define BrakePinA 6
#define BrakePinB 7
#define ClutchPinA 8
#define ClutchPinB 9
#define Gear1pin 10
#define Gear2pin 11
#define Gear3pin 12
#define Gear4pin 13
#define Gear5pin 14 //A0
#define Gear6pin 15 //A1
void setup()
{
// 76543210
//(PIND & B00001000) check only the pin '1' (in this case digital 3) in this line for low or high, & means
dont check any others
//would be the same as: PIND & (1 << 3);
// ..13...8
DDRB &= B11000000; //sets through 13 as inputs excpet for crytsl pins
PORTB &= B00111111; //enable pullups on all but crystal pins
// ..543210
DDRC = B00000000; //sets analog 0 through 5 as inputs
PORTC &= B00111111; //enable pullups on all but analog 6 an 7 (6 and 7 arent avaliable on atmega
328)
void loop()
{
for(int x=0; x<4; x++)
{
Serial.print(Encoders[x]);
Serial.print(","); //delimiter
}
for(int x=0; x<4; x++)
{
Serial.print(ButtonStates[x]);
Serial.print(","); //delimiter
}
Serial.println();
}
void GearItrig()
{
ButtonStates[0]=1;
}
void GearIItrig()
{
ButtonStates[0]=2;
}
void GearIIItrig()
{
ButtonStates[0]=3;
}
void GearIVtrig()
{
ButtonStates[0]=4;
}
void GearVtrig()
{
ButtonStates[0]=5;
}
void GearVItrig()
{
ButtonStates[0]=6;
}
void ShiftTrig()
{
ButtonStates[1]=~ButtonStates[1];
}
void AuxItrig()
{
ButtonStates[2]=1;
}
void AuxIItrig()
{
ButtonStates[2]=2;
}
void AuxIIItrig()
{
ButtonStates[3]=3;
}
void WheelTrigA()
{
// look for a low-to-high on pin A
if ((PIND & B00000100) == 4)
{
// check pin B to see which way encoder is turning
if ((PIND & B00001000) == 0)
{
Encoders[0] -= 1; // CW
}
else
{
Encoders[0] += 1; // CCW
}
}
else // must be a high-to-low edge on pin A
{
// check pin B to see which way encoder is turning
if ((PIND & B00001000) == 8)
{
Encoders[0] -= 1; // CW
}
else
{
Encoders[0] += 1; // CCW
}
}
//Serial.println (Encoders[0], DEC);
// use for debugging - remember to comment out
}
void WheelTrigB()
{
// look for a low-to-high on pin B
if ((PIND & B00001000) == 8)
{
// check pin A to see which way encoder is turning
if ((PIND & B00000100) == 4)
{
Encoders[0] -= 1; // CW
}
else
{
Encoders[0] += 1; // CCW
}
}
// Look for a high-to-low on pin B
else
{
// check pin B to see which way encoder is turning
if ((PIND & B00000100) == 0)
{
Encoders[0] -= 1; // CW
}
else
{
Encoders[0] += 1; // CCW
}
}
}
void GasTrigA()
{
// look for a low-to-high on pin A
if ((PIND & B00010000) == 16)
{
// check pin B to see which way encoder is turning
if ((PIND & B00100000) == 0)
{
Encoders[1] -= 1; // CW
}
else
{
Encoders[1] += 1; // CCW
}
}
else // must be a high-to-low edge on pin A
{
// check pin B to see which way encoder is turning
if ((PIND & B00100000) == 32)
{
Encoders[1] -= 1; // CW
}
else
{
Encoders[1] += 1; // CCW
}
}
//Serial.println (Encoders[1], DEC);
// use for debugging - remember to comment out
}
void GasTrigB()
{
// look for a low-to-high on pin B
if ((PIND & B00100000) == 32)
{
// check pin A to see which way encoder is turning
if ((PIND & B00010000) == 16)
{
Encoders[1] -= 1; // CW
}
else
{
Encoders[1] += 1; // CCW
}
}
// Look for a high-to-low on pin B
else
{
// check pin B to see which way encoder is turning
if ((PIND & B00010000) == 0)
{
Encoders[1] -= 1; // CW
}
else
{
Encoders[1] += 1; // CCW
}
}
}
void BrakeTrigA()
{
// look for a low-to-high on pin A
if ((PIND & B01000000) == 64)
{
// check pin B to see which way encoder is turning
if ((PIND & B10000000) == 0)
{
Encoders[2] -= 1; // CW
}
else
{
Encoders[2] += 1; // CCW
}
}
else // must be a high-to-low edge on pin A
{
// check pin B to see which way encoder is turning
if ((PIND & B10000000) == 128)
{
Encoders[2] -= 1; // CW
}
else
{
Encoders[2] += 1; // CCW
}
}
//Serial.println (Encoders[2], DEC);
// use for debugging - remember to comment out
}
void BrakeTrigB()
{
// look for a low-to-high on pin B
if ((PIND & B10000000) == 128)
{
// check pin A to see which way encoder is turning
if ((PIND & B01000000) == 64)
{
Encoders[2] -= 1; // CW
}
else
{
Encoders[2] += 1; // CCW
}
}
// Look for a high-to-low on pin B
else
{
// check pin B to see which way encoder is turning
if ((PIND & B01000000) == 0)
{
Encoders[2] -= 1; // CW
}
else
{
Encoders[2] += 1; // CCW
}
}
}
void ClutchTrigA()
{
// look for a low-to-high on pin A
if ((PINB & B00000001) == 1)
{
// check pin B to see which way encoder is turning
if ((PINB & B00000010) == 0)
{
Encoders[3] -= 1; // CW
}
else
{
Encoders[3] += 1; // CCW
}
}
else // must be a high-to-low edge on pin A
{
// check pin B to see which way encoder is turning
if ((PINB & B00000010) == 2)
{
Encoders[3] -= 1; // CW
}
else
{
Encoders[3] += 1; // CCW
}
}
//Serial.println (Encoders[3], DEC);
// use for debugging - remember to comment out
}
void ClutchTrigB()
{
// look for a low-to-high on pin B
if ((PINB & B00000010) == 2)
{
// check pin A to see which way encoder is turning
if ((PINB & B00000001) == 1)
{
Encoders[3] -= 1; // CW
}
else
{
Encoders[3] += 1; // CCW
}
}
// Look for a high-to-low on pin B
else
{
// check pin B to see which way encoder is turning
if ((PINB & B00000001) == 0)
{
Encoders[3] -= 1; // CW
}
else
{
Encoders[3] += 1; // CCW
}
}
}
Jordan at 12:38 PM
Share
20 comments:
[code]
#define Xpin 0
byte Xaxis;
void setup(){
Serial.begin(9600);
}
void loop()
{
Xaxis = analogRead(Xpin) / 4;
Serial.write(241); // 240 + # of channels, 2 Buttons and 2 axis
Serial.write(Xaxis);
delay(25);
}
[/code]
Reply
Serial.write(241);
Serial.write(Xaxis);
then a analog input would need to be set as the first input in PPjoy, not a digital.
http://www.etheli.com/simulator/simulator.html look at first pic here.
Reply
Replies
Been searching for long time for a tutorial for PPjoy with Ardiuno.
Reply
Replies
Reply
[code]
#define B4Pin 10
#define B3Pin 11
#define B2Pin 12
#define B1Pin 13
#define Xpin A5
#define acelPin A0
#define frenoPin A2
byte Xaxis;
byte acel;
byte freno;
byte Bot1;
byte Bot2;
byte Bot3;
byte Bot4;
void setup()
{
Serial.begin(9600);
pinMode(B4Pin,INPUT_PULLUP);
pinMode(B3Pin,INPUT_PULLUP);
pinMode(B2Pin,INPUT_PULLUP);
pinMode(B1Pin,INPUT_PULLUP);
}
void loop()
{
Xaxis = analogRead(Xpin)/8;
acel= analogRead(acelPin)/4;
freno= analogRead(frenoPin)/4;
Bot4=digitalRead(B4Pin);
Bot3= digitalRead(B3Pin);
Bot2= digitalRead(B2Pin);
Bot1=digitalRead(B1Pin);
delay(25);
}
[/code]
Reply
Replies
Serial.write(Ib1);
Serial.write(Ib2);
//Serial.write(Ib3);
//Serial.write(Ib4);
//Serial.write(Xaxis);
Serial.write(acel);
Serial.write(freno);
Reply
Gastón Sebastián Marengo September 16, 2013 at 8:31 PM
Just send a Serial.write(0); after the initialization byte (240 + # of channels). It is needed (but not
documented). After that all my axis and buttons worked.
Serial.write(244);
Serial.write(0);
Serial.write(Ib1);
Serial.write(Ib2);
//Serial.write(Ib3);
//Serial.write(Ib4);
//Serial.write(Xaxis);
Serial.write(acel);
Serial.write(freno);
Reply
Replies
Reply
Serial.write(byte(243));
Serial.write(byte(0));
Serial.write(byte(Xaxis));
Serial.write(byte(Btn1));
Serial.write(byte(Btn2));
delay(25);
}
This code is not recognizing the two buttons, i have changed it a lot of times, but still id doesent work,
any help please?
Reply
‹ Home ›
View web version
About Me
Jordan
View my complete profile
Powered by Blogger.