Salut tous !
Un petit trailer de mon petit wip :
[youtube=600,360]8hIy-T9cdcQ[/youtube]
Au départ du projet, nous nous sommes fixés comme objectif de faire un siège dynamique.
Mais rapidement on trouvait dommage de limiter les mouvements dynamiques uniquement au siège - quoi de plus irréaliste que d'avoir le siège qui se rapproche des pédales et du volant !
Donc ce n'est pas un simple 2Dof que nous voulions monter mais bel et bien un simulateur complet et dédié.
Ce simulateur reprend donc le fonctionnement d'un siège dynamique légèrement plus "vitaminé". Il s'agit du premier prototype. Le second est quasi fini avec un système de motorisation privilégiant le roll latéral : les moteurs se trouvent alors à l'avant et les moyeux font face à la plateforme.
Pour des raisons pratique j'ai posé le simu sur de vieux caissons d'une ancienne réalisation - ça évite de se casser le dos pour monter dedans et de s'appuyer trop sur les supports - je referai un grand caisson ventilé et plus haut, lequel abritera dans des tiroirs l'ensemble de l'électronique et informatique.
Tout doit rester accessible, cela reste une machine qui a besoin de pas mal d'entretien (au stade actuel)
Prochainement je vais aussi mettre une rampe/accoudoir pour monter sans s'agripper au volant.
- Dimensions du châssis :
A renseigner
000 x 000 x 000
profil en L galva de récupération de 40mm
Moteur D&G
Alimentation
Poids estimé = 40 kg
A ce niveau le poids ne nous inquiète pas. - Dimensions de la plateforme :
A renseigner
000 x 000 x 000
Poids estimé = 36 kg ... plus le pilote !
1 baquet = 9kg
1 set g25 = 7 kg
profil en L acier de récupération de 40mm
Profil carré de recup (support volant / boite)
- Hauteur du dossier
profil en L acier de récupération de 40mm
90 cm de haut
Le châssis doit être ultra rigide. Il sert d'assise à la plateforme, également à isoler le sol des vibrations. Sur un support transversal est soudé un gros cardan de camion.
La plateforme est mobile grâce à ce cardan.
Attention : il est important que l'ensemble de la plateforme soit suffisamment flexible pour encaisser des contraintes importantes.
Les deux moteurs sont mus par un bloc d'alimentation DC 12V de 30 A piloté par l'interface arduino.
La puissance exigée par les moteurs est importante, le module de puissance Arduino doit impérativement être refroidi via dissipateur actif.Ce sera possible avec un radiateur de chipset graphique ou une découpe dans les ailettes alu d'un vieux cpu.
Au besoin pour les tests, vous pouvez commencer par alimenter le montage avec une batterie de voiture - laquelle sera branchée sur un chargeur.
les deux circuits, 12V 30A et 5V USB, sont indépendants.
A ce moment avant de brancher quoi que ce soit assurez vous que la masse de vos moteurs est bien isolée.
Si vous notez une continuité sur l'ensemble du châssis avec la borne negative de votre alimentation, vos moteurs d’essuie-glace ont la masse reliée à la carcasse. Cela peut provoquer des interférence très importantes avec le matériel usb, le g25 notamment lorsque le pédalier est fixé au châssis en acier - la vis met les pédales en metal à la terre... et ça c'est pas pas bon.
Si vous rencontre ce problème, il va falloir ouvrir les moteurs pour ponter la piste qui va à la masse et la rediriger dans le circuit pour la redistribuer. J'ai dû le faire sur une première version du cab équipée de valeo de golf3...
NB : Les moteurs smolka n'ont pas ce souci.
La position des moteurs est connue par le biais de la lecture de potentiomètres 10k dédiés sur l'axe du moteur - la lecture permet aussi à l'arduino de détecter les mouvements/positions hors champs d'application qui a comme effet de couper purement et simplement l'alimentation des moteurs.
Dans le cas de ma machine, les potards sont disposés à l'opposé de l'axe du moteur et maintenus en position par une vis dans le cylindre percé , ce cylindre serre la pièce qui actionne la tige de rotule et le coince sur le moyeu du moteur.
Fichier pdf :
http://dl.free.fr/vhy9wLfXcLors du montage bien s'assurer que l'axe et les boulons de la rotule ne s'accrochent pas dans les vis du moteur...
Il est possible de tarauder l'intérieur du moyeu de l'autre coté du moteur - solution adoptée sur le 2ème proto.
photo à venirXsim3 via le plugin dédié se charge d'extraire les informations de télémétries du jeu pour les confier au converter série qui transmet les informations au arduino via usb.
Ce dernier se charge de piloter les moteurs et limiter l'amplitude des mouvements (entre autre)
Le jeu qui est actuellement privilégié est Rfactor, compatible avec un plugin
Xsim3, pour son excellent moteur physique et ses nombreux mods.
L'écran est déporté sur l'extérieur de châssis afin de limiter le poids en effet de levier et éviter trop de vibrations. J'ai utilisé un cadre de lit 2 personnes pour faire l'armature.
Ce simulateur privilégie les effets d’accélération, le roll latéral est à mon sens suffisant.
Vous avez besoin pour ce montage :
- Coté structure :
- structure de la plateforme et du châssis : ce que vous voulez tant que ça reste résistant et souple.
vous pouvez utiliser de l’auto foreuse ou de la tige filetée pour monter le châssis pas forcément besoin de souder. Par contre il faut soigner les points de force tout en les laissant relativement souples.
- 1 cardan
- 2 rotules de voiture
- 2 tiges filetées de 12mm (à vérifier) + 8 boulons de 12
- de la plaque ferraille / grille / bois ... pour le plancher du simu (idéalement de l'alu strié)
- cylindre plein dans la masse / alu / acier mini XX mm de diamètre (à renseigner)
- Coté électrique :
- 1 arduino uno
- 1 monster motor shield (attention c'est le truc qui douille : 70€)
- 1 radiateur + ventilateur (cpu pc)
- 2 moteurs de camion ou voiture en 12v
- 2 condensateurs potards linéaires 10k
- 1 batterie de voiture ou 1 alimentation 12v très pêchue (une alim pc de très bonne qualité peut aussi faire l'affaire)
- 1 coupe circuit 12v / interrupteur
- 1 fusible de 30A (maximum)
- quelques mètres de câble 1.5 souple (alimentation des moteurs)
- quelques mètres de câble électrique souple (type alim atx par ex - potards)
- une trentaine de sucres (ou dominos) adaptés pour du 1.5
- 8 prises à sertir type voiture et la pince qui va avec
- accessoires :
- 1 siège baquet (le plus léger est le mieux)
- 1 set volant pédale (ffb of course!)
- 1 écran
- 1 pc de 3-4 ans mini
- 1 cable usb (type imprimante)
- le soft :
- Un windaube...
- Xsim 2 ou 3 (le 3 nécessite le net pour les paramètres en cloud)
- Un jeu supporté par xsim (le plugin est dans le setup de xsim):
Racing Games
* Codemasters F1 2010
* RFactor
* ARCA
* Live for Speed
* GTR
* GTR 2
* Race
* Race 07
* GT Legends
* GTR Evolution
* Nascar Racing 2003
* Nascar Racing 2005
* Collin McRay Dirt
* Dirt 2
* Racedriver Grid
* Racer (Freeware)
* Grandprix 3+4
* SBK (motorbike sim)
* IRacing
* Cruden Racer
Flight Simulations
* X-Plane
* IL2
* MS Flight Simulator 98-X
* MS Combat
* Falcon
* Condor soaring
* Lockon
- arduono setup & drivers
- programmation arduono
- Outils :
perceuse (idéalement à colonne)
poste à souder
foret à métaux de 12 - taraud m10 ( à vérifier)
foret à métaux de 5 et taraud m4 ou vis de 6 (pour coincer le potard en rotation)
Un outil pour scier l'acier (scie à main / onglet)
Un fer à souder
- en option à venir le tachometer LKM1638
- câble port com
- régulateur 78L05
- module ULN2804
Un peu de temps !
Quelques liens :
Arduino uno
http://www.dealextreme.com/p/arduino-uno-rev3-development-board-120464?item=4Module de puissance pour arduino
http://www.lextronic.fr/P22600-platine-de-commande-de-moteur-dc-monster-moto-shield.htmlSWF VALEO NIDEC ITT 404.458 motoréducteur 24V DC
http://www.smolka-berlin.de/onlineshop/fr/artikel/SWF_VALEO_NIDEC_ITT_404.458_motor%E9ducteur_24V_DC__Offre_sp%E9ciale%21%21%21_/4398(Ils sont en destockage à 35 € ... alors qu'ils coutent x10 plus cher en temps normal...)
Vous pouvez utiliser des moteurs d'essuiglace de voiture - j'en ai quelques dispos au besoin pour test.
Ça peut très bien convenir pour un modèle playseat uniquement.
voici les caractéristiques des moteurs smolka (made in germany) qui nous intéressent :
Ils ont la capacité de se bloquer en position lorsqu'ils ne sont plus alimentés - très intéressant pour monter dans le simu sans ce soucier de faire bouger les moteurs ou de les mettre en butée=défaut.Engrenage: à droite, cercle de perçage 72 mm, écartement des trous 62 mm
Diamètre de l'arbre: 12 mm
Longueur de l'arbre: 21 mm + filetage M10, 12 mm
Arbre avec cône moleté (ou vient se caler le doigt qui actionne les tiges des rotules)
Wiring diagram completFichier PDF
http://dl.free.fr/rZnfpbuQI
Le programme du arduino
/*
Opensource code for xsimulator by Jean David SEDRUE
Version betatest26 - 24042012
test21 with Tacho
test22 less tache to continue biMotor test
*/
#define BRAKEVCC 0
#define RV 2 //according to cable at 24/11/2011
#define FW 1 //according to cable at 24/11/2011
#define STOP 0
#define BRAKEGND 3
#define CS_THRESHOLD 253 //not use :(
////////////////////////////////////////////////////////////////////////////////
#define pwmMin 128;
#define pwmMax 250;
#define motLeft 0
#define motRigth 1
#define speedPin 10
#define potL A4
#define potR A5
////////////////////////////////////////////////////////////////////////////////
// DECLARATIONS
////////////////////////////////////////////////////////////////////////////////
/* VNH2SP30 pin definitions*/
int inApin[2] = {
7, 4}; // INA: Clockwise input
int inBpin[2] = {
8, 9}; // INB: Counter-clockwise input
int pwmpin[2] = {
5, 6}; // PWM input
int cspin[2] = {
2, 3}; // CS: Current sense ANALOG input
int enpin[2] = {
0, 1}; // EN: Status of switches output (Analog pin)
int statpin = 13;
/* init position value*/
int DataValueL=125; //middle position
int DataValueR=125; //middle position
////////////////////////////////////////////////////////////////////////////////
// INITIALIZATION
////////////////////////////////////////////////////////////////////////////////
void setup()
{
/* serial initialization */
Serial.begin(115200);
/* motor initialization */
pinMode(statpin, OUTPUT);
for (int i=0; i<2; i++)
{
pinMode(inApin[i], OUTPUT);
pinMode(inBpin[i], OUTPUT);
pinMode(pwmpin[i], OUTPUT);
}
// Initialize braked for motor
for (int i=0; i<2; i++)
{
digitalWrite(inApin[i], LOW);
digitalWrite(inBpin[i], LOW);
}
}
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Main Loop ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void loop()
{
int sensorL,sensorR;
serialData();
sensorR = analogRead(A4)/4;
sensorL = analogRead(A5)/4; // echelle 0-1000
/* Serial.print(sensorL);
Serial.print(" ; ");
Serial.println(sensorR);
motorGo(motRigth, FW, 255);
delay(100);
motorOff(motRigth);
delay(1000);
*/
motorMotion(motRigth,sensorR,DataValueR);
motorMotion(motLeft,sensorL,DataValueL);
}
////////////////////////////////////////////////////////////////////////////////
// Procedure: wait for complete trame
////////////////////////////////////////////////////////////////////////////////
void serialData()
{
byte Data[3]={
'0','0','0' };
// il faut limmitter le temps pour garder le contrôle des moteurs
if (Serial.available()>2){ //wait a packets of 6
//test if order R or L data type
Data[0]=Serial.read();
if (Data[0]=='R'){ // ordre connue ?, si non je verrais au prochain tour !
Data[1]=Serial.read();
Data[2]=Serial.read();
DataValueR=NormalizeData(Data);
}
if (Data[0]=='L'){ // ordre connue ?, si non je verrais au prochain tour !
Data[1]=Serial.read();
Data[2]=Serial.read();
DataValueL=NormalizeData(Data);
}
}
if (Serial.available()>16) Serial.flush();
}
////////////////////////////////////////////////////////
void motorMotion(int numMot,int actualPos,int targetPos)
////////////////////////////////////////////////////////
{
// int potPinL=A4; //to include in header procedure
// int potPinR=A5; //to include in header procedure
int Tol=4;
int difference;
int pwm;
int securityLow=20;
int securityHigh=200;
int brakeDistance=16;
boolean move=true;
// encadrements des valeurs
if (targetPos<securityLow+brakeDistance) targetPos=(securityLow+brakeDistance); //software limits, but consideration speed brake.
if (targetPos>securityHigh-brakeDistance) targetPos=(securityHigh-brakeDistance); //software limits, but consideration speed brake.
// calculate speed about distance
difference=abs(targetPos-actualPos);
if (difference<=Tol) pwm=0; // to near to mov
if (difference>Tol) pwm=168;
if (difference>50) pwm=200;
if (difference>75) pwm=225;
if (difference>100) pwm=255;
// pay attention for security for Right motor!!
if (actualPos>securityHigh || actualPos<securityLow) move=false; //mechanicals limits
//to near to move
if (difference<= Tol) move=false; //to near to move
// en avant (haut)
if (actualPos<targetPos && move) {
pwm=255; //need power to go up !
motorGo(numMot, FW, pwm);
}
pwm=255; //test !
// en arriere (bas)
if (actualPos>targetPos && move) motorGo(numMot, RV, pwm);
// ne pas bouger !
if (move==false) motorOff(numMot);// STOP
}
////////////////////////////////////////////////////////////////////////////////
void motorOff(int motor){
////////////////////////////////////////////////////////////////////////////////
digitalWrite(inApin[motor], LOW);
digitalWrite(inBpin[motor], LOW);
analogWrite(pwmpin[motor], 0);
}
////////////////////////////////////////////////////////////////////////////////
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
////////////////////////////////////////////////////////////////////////////////
{
if (motor <= 1)
{
if (direct <=4)
{
// Set inA[motor]
if (direct <=1)
digitalWrite(inApin[motor], HIGH);
else
digitalWrite(inApin[motor], LOW);
// Set inB[motor]
if ((direct==0)||(direct==2))
digitalWrite(inBpin[motor], HIGH);
else
digitalWrite(inBpin[motor], LOW);
analogWrite(pwmpin[motor], pwm);
}
}
}
////////////////////////////////////////////////////////////////////////////////
// testPot
////////////////////////////////////////////////////////////////////////////////
void testPot(){
Serial.print(analogRead(A4));
Serial.print(";");
Serial.println(analogRead(A5));
delay(250);
}
////////////////////////////////////////////////////////////////////////////////
void testpulse(){
int pw=120;
while (true){
motorGo(motLeft, FW, pw);
delay(250);
motorOff(motLeft);
delay(250);
motorGo(motLeft, RV, pw);
delay(250);
motorOff(motLeft);
delay(500);
motorGo(motRigth, FW, pw);
delay(250);
motorOff(motRigth);
delay(250);
motorGo(motRigth, RV, pw);
delay(250);
motorOff(motRigth);
Serial.println("testpulse pwm:80");
delay(500);
}
}
////////////////////////////////////////////////////////////////////////////////
// Function: convert Hex to Dec
////////////////////////////////////////////////////////////////////////////////
int NormalizeData(byte x[3])
////////////////////////////////////////////////////////////////////////////////
{
int result;
if (x[2]==13) //only a LSB and Carrier Return
{
x[2]=x[1]; //move MSB to LSB
x[1]='0'; //clear MSB
}
for (int i=1; i<3; i++)
{
if (x[i]>47 && x[i]<58 ){//for xA to xF
x[i]=x[i]-48;
}
if ( x[i]>64 && x[i]<71 ){//for x0 to x9
x[i]=x[i]-55;
}
}
result=(x[1]*16+x[2]);
return result;
}
Fichier zippé
http://dl.free.fr/nR7jK0tu5version betatest26
A copier/coller dans un fichier *.ino et upper dans l'arduino
Bien sûr je vous recommande la plus grande prudence lorsque vous testez vos machines, n'oubliez jamais de protéger l'installation électrique (surtout sur batterie) - Ne laissez pas le simulateur sous tension en mode wip ! Nous ne pourrons pas être tenus responsables des dégats survenus suite à la lecture de ce topic... (même au niveau du waf!)Lors d'une séance de roulage virtuel alors qu'on effectuait des réglages de xsim sur le proto2, sur un test de roll, le rendu des paramètres a arraché les soudures du siège... la sanction peut donc être physique.
Je posterai prochainement un mini tuto pour débuter facilement avec xsim.
Je crois que vous savez tout !
Bon bricolage !