Sunteți pe pagina 1din 67

Mcatronique

Application avec le lego Mindstorm EV3

Image Source: [techcamp]


Mcatronique :
lintgration en synergie de la mcanique, llectronique,
lautomatique et linformatique dans la conception dun systme en
vue doptimiser sa fonctionnalit (Norme NF E 01-010)

Image Source: [Helix84]


Exemple autour du lego Mindstorm
Sommaire
1. Lego EV3 Hardware
1) La brique EV3
2) Les moteurs et capteurs

1bis. Robotique mobile et le tribot (notre sujet de TP)

2. Lego EV3 Programming


1) Lenvironnement RobotC
2) Le langage RobotC
3) LAPI (les fonctions disponibles)
1. EV3 Hardware
EV3 Hardware (overview)
Moteurs: Capteurs/Entres
-commande en vitesse Actionneurs/Sorties
-codeur incrmental de position
(rsolution: 1)

Capteur ultrason:
-distance obstacle (cm)

Brique EV3 LED + photodiode:


(CPU + batterie): -couleur
-Ecran LCD -lumire rflchie (%)
-LED
-Haut parleur
-Boutons Capteur gyroscopique 1axe:
-vitesse angulaire (/s)
-angle (par intgration )

Capteur contact:
-press (1), relch(0)
La brique EV3
Nom de la brique USB :
si connexion tablie
Etat connexion avec un priphrique
bluetooth
Charge de la batterie

1 Bouton Retour :
-Annuler
Spc. techniques : -Stopper un programme
-Eteindre la brique
- Processeur 300MHz
- Ecran 178x128 pixels
- Noyau Linux 2 Bouton Central :
- 16 Mo FLASH -Valider
- 64 Mo RAM -Allumer la brique

3 Bouton gauche,droite,
haut,bas :
-Naviguer dans les menus
La brique EV3
Code couleur (par dfaut) des leds :

Rouge : -dmarrage Orange : - alerte Vert : - prt


- arrt du systme - prt

Rouge clignotant: Orange clignotant: Vert clignotant :


- occup - alerte - programme en cours
- programme en cours
La brique EV3 Port USB connexion avec le PC

Port pour les capteurs: Port pour les moteurs:


S1, S2, S3, S4 A,B,C D

Prise chargeur
de la batterie

Vue de dessous Vue de dessus

Vue de droite Vue de gauche

Port USB Port dextension


Batterie Haut-parleur pour priphrique de mmoire : Carte SD
Menus Menu Utilitaires:
- Port view :
test capteur, position moteur
Menu Fichiers:
-explorateur de fichiers - Motor control :
-lancer tout programme test des moteurs
-effacer le contenu dun rpertoire

Menu Rcent: Menu Rglage:


- liste des derniers - volume
programmes excuts - mise en veille
- permet de les relancer - bluetooth/wifi
- info brique
Utilitaire Port view
Menu Utilitaire
Affiche la valeur mesure par les capteurs, dont les codeurs de position

Valeurs courantes
des codeurs,
ports A, B, C, D.
Valeurs courantes
des capteurs,
ports S1, S2, S3, S4.
Les moteurs

Moteurs courant continu


- avec balai (brushed DC motor)
+ train dengrenage pour augmenter le couple

- couple moteur , cr par force de Laplace sur le fil : dF = i dl B


= K i , avec i le courant du rotor

Images source: [dcmotor]


Les moteurs
Modle lectrique et mcanique du moteur DC

Images source: [dcmodel]


! di
# U = L + Ri +Uemf
" dt
# Uemf = K
$

"$ J! = b
# Fonction de transfert :
$% = Ki
K
(s) =
U (Ls + R)(Js + b) + K 2

En rgime permanent et pour un charge constante sur le moteur :


La vitesse du moteur est proportionnelle U.
Les moteurs

Moteur command en tension :


- par modification du rapport cyclique en % dun signal PWM 8 kHz
- si non rgul (boucle ouverte):
si charge mcanique , vitesse pour un mme U

9V

90% duty cycle 90% : Umoy= 8.1V


OV

9V
10% duty cycle
10% : Umoy=0.9V
OV

La commande du moteur est exprim en % de la tension de la batterie


Les moteurs
Pont H (H-bridge):
- pilote le sens de rotation et freinage dynamique (electronic braking)
- constitu de 4 interrupteurs commands (transistors Q1, Q2, Q3, Q4)

Q1

Image source: [hbridge]


Q4
+Ve
Q2 -Ve
M-
M+
Q3

Tous interrupteurs ouverts : moteur non aliment (float)


Les moteurs

+ - - +

Q1 et Q4 haut : moteur avance Q2 et Q3 haut : moteur recule

U=0 et moteur en rotation > 0 ,


moteur en mode gnrateur court-circuit :

! 0 = Ri +U " U
# emf $ i = emf < 0
" # R
#$ Uemf = K > 0 $ = Ki<0
%

Q3 et Q4 haut : freinage electronic Le courant induit par la rotation cre ici un


braking (si moteur en rotation) couple oppos au mouvement.
Les moteurs : capteur de position

Image source: [Philo]


Image source: [encoder]
Codeur incrmental optique :
- disque ajour de fentes
- passage des fentes dtect par 2 photodiodes
- sens rotation donn par la voie en avance de phase sur lautre
Le capteur de couleur
LED rouge
3 modes de fonctionnement:
Couleur
( 7 couleurs codes ou composantes RGB )

Lumire rflchie Cellule


LED active (en % dintensit lumineuse) photosensible
0%= sombre, 100%=clair

Lumire ambiante
LED inactive (en % dintensit lumineuse)

Mode couleur Mesure lumire rflchie (en %)


Les capteurs

Capteur de contact:
- analogique Gyroscope, vitesse angulaire et angle 1 axe:
- ferme un interrupteur - angle par intgration de la vitesse
- 2 tats (drive au cours du temps !)
- vitesse maximale mesure: 440/s

Micro Electo-Mecanical System (MEMS)


1 =Press
-mesure force Coriolis
sur structure vibrante

2 =Relch

Image source: [electroiq]


Les capteurs
Le capteur ultrason:
-mesure de distance via un temps de parcours

Limitations :

a. distance max mesure: 25cm


b. angle entre obstacle plan et capteur < 45
d.
c. objet petit ou absorbant = invisible
d. interfrence entre 2 capteurs
?

Images source: [escplanta]


1bis. Robotique mobile
et le robot tribot

Le robot tribot est le sujet dtude des TPs


2. EV3 Programming
2. EV3 Programming
Logiciel RobotC : -un diteur de cource
-un compilateur
-un tlchargeur via usb

sourceFile1
(excutable)

librobotc.so
(bibliothque
dynamique robotC)
3. Tlchargement sourceFile1.c 1. Edition du source
(via usb)
2. Compilation

4. Excution sourceFile1 (excutable)


2.1 RobotC, lenvironnement
Installer la bibliothque
Crer, ouvrir, sauver RobotC sur lEV3 Compiler et
un fichier source (uniquement la premire fois) tlcharger
Rglage moteurs
et capteurs Compiler

1 Liste des fonctions (avec glisser-dposer dans le source et aide contextuelle disponibles)
2 Editeur de source 3 Erreur compilation, dbogage
Configuration de RobotC
1. Menu Robot :
-la cible de compilation est le robot physique
-la plateforme est le Lego EV3
sans le natural language

2. Menu Windows -> Menu level :


-dfinie le nombre de fonctions affiches
dans la fentre liste des fonctions

-Expert est recommand


(Basic cache les fonctions pour lcran LCD)
Start et dbogage
Le bouton tlcharger sur le robot ouvre le mode dbogage:
-dmarrer, excuter instruction par instruction, arrter le programme
-visualiser ltat courant des variables, capteurs et moteurs (monitoring via lUSB)

Start/stop programme

Quitter le dbogage

Pause/Resume :
-pauser ou reprendre
lexcution normale

Step Into :
-dmarre et avancer en
mode une instruction par clic
Etat courant des variables locales

Note : pour afficher aussi les capteurs (menu Robot debugger windows -> sensors)
Start et dbogage

Pour dmarrer le programme partir de la brique EV3 (sans connexion au PC)

slectionner votre programme dans le Menu files de lEV3, rpertoire RC


2.2 Le langage RobotC
Langage C avec des exceptions simplificatrices:

Pas de fonction main() mais une task main()


une programmation multi-tche simplifie

Des nouveaux types : string pour les chaines de caractres


char msg[6]="allo!"; string msg="allo!";

Pas dallocation dynamique


uniquement des tableaux statiques int tab[5];

Un prototype doit obligatoirement inclure le nom des paramtres effectifs


+ utiliser la notation func(int tab*) et non func(int tab[])
Les commentaires

/* Ceci est un commentaire (ansi C style)*/


ou
/* Ceci est un commentaire
(ansi C style)*/

// Ceci est un commentaire (C++ style)


ou
// Ceci est un commentaire
// (C++ style)
Les types
type Plage de valeurs Taille mmoire
int -32768 +32767 2 octets
long -2147483648 +2147483647 4 octets
float xxx 10xx 4 octets
char 0 255 1 octet
string chane de 20 char 20 octets (20 char)

pas de double, nombre virgule en double prcision


des types supplmentaires existent (sans utilit): byte, ubyte, bool

Le type string remplace les chaines de caractre char[]


limit 20 caractres = nombre de caractres qui tiennent sur la largeur de lcran
Le type string
Introduit (du C++) pour faciliter la manipulation des chanes

Affectation
Equivalant en C-ansi:
string a="allo!"; Char a[20]="allo!";
string b; Char b[20];

a ="a lhuile"; strcpy(a,"a lhuile");


b=a; strcpy(b,a);

Concatenation
string c="tic-"; char c[20]="tic-";
c=a + "tac"; strcat(c,"tac");
/*c vaut "tic-tact"*/
Le type string
Test Equivalant en C-ansi:
string a="allo!"; Char a[20]="allo!";
string b; Char b[20];

if (a==b) if (!strcmp(a,b))
{/* a et b identique*/} {/*a et b idetique*/}

Passage implicite par adresse Seul passage par adresse.


{
display(ma);
}

void display(string c)
{c="toto"; /*modifier c, modifie aussi la variable ma */
}
Le type string
Quelques fonctions :
strcat, strcmp, strlen strcpy sont dfinis pour les strings

string msg="un test";


int length= strlen(msg);

sprintf(string, "format", var1,var2,)


crit dans le string le message correspondant au format prcis

string mesg;
int a=-1;
sprintf(mesg,"i: %d",a); mesg="i: -1";
Les fonctions math
Voir liste des fonctions disponibles.
On note cependant :

float cos(float fRadians)


float sin(float fRadians)
retournent le cosinus/sinus dun angle en radians.

const float PI
une constante valant .
Exemple : float oneTurn =2*PI;
Structure de contrles
Identiques au C:

if (condition)
if (condition) else

for ( ; ; )
while(condition)
do while (condition);

Attention: robotC autorise


labsence de cette virgule.
Le multitche
Chaque programme contient au moins une tche initiale:
task main() fonction main() du C-ANSI

La tche prend fin la fin de ses instructions.


Lorsque toutes les tches sont finies, le programme sarrte.

source.c

task main()
{
int speed=30;

setMotorSpeed(motorB, speed);

}
Le multitche
On peut crer une tche infinie
(tant que lon nappuie pas sur le bouton darrt):

source.c

task main()
{
int speed=30;

setMotorSpeed(motorB, speed);
Moteurs B et C 30%
setMotorSpeed(motorC, 30);
de leur vitesse.
while (1);

Les moteurs tournent indfiniment.


Le multitche
On peut crer une tche priodique:
source.c

task main()
{
int speed=30;
Joue un note 400Hz
while(1) pendant 20x10ms
{
playTone(400,20);
sleep(2000); Attente/stoppe lexcution
pendant 2000 ms
}
}

Usage du CPU par tche main


playTone() playTone() playTone() playTone()
2000 ms
temps
Le multitche
Multitche : plusieurs tches peuvent tourner en parallle

void startTask( task_name)


permet une tche de dmarrer en parallle la tche de nom
task_name

void stopTask( task_name)


permet une tche de stopper la tche de nom task_name

void stopAllTasks()
stoppe toutes les tches dont la tche principale
Stoppe le programme.
Le multitche
task beep(); /*prototype*/
les moteurs reoivent en boucle
une commande de vitesse pendant 3s,
task main()
{ startTask(beep); pendant que lautre tche met un bip
toutes les 2s.
while(time1(T1)<3000)
{ setMotorSpeed(MotorB,30);
setMotorSpeed(MotorB,30);
} Usage du CPU:
stopTask(beep);
} task main
task beep
setMotorSpeed
task beep() setMotorSpeed
{ while(1) playTone() setMotorSpeed
{ playTone(400,20); .
sleep(2000);
} }
2000 ms temps
Le multitche
Pas ncessaire de renvoyer la commande
task beep(); /*prototype*/ moteur sans rpit (et saturer le CPU):
la vitesse est maintenue tant
task main() quil ny a pas de nouvelle commande.
{ startTask(beep); un sleep() une bonne ide !

while(time1(T1)<3000)
{ setMotorSpeed(MotorB,30);
setMotorSpeed(MotorB,30); Ncessaire pour que
sleep(400); le programme se finisse
}
stopTask(beep);
} Usage du CPU:

task beep() task main


{ while(1) task beep
setMotorSpeed
{ playTone(400,20);
setMotorSpeed
sleep(2000); playTone()
} }

2000 ms temps
Le multitche
Communication entre plusieurs tches :

Utiliser des variables globales.


Toute tche ou fonction peut accder ces variables.
Prototypes et fonctions
Particularits RobotC pour les fonctions :
le prototype doit inclure les noms des arguments tels qu la dfinition
la notation func(int tab[]) nest pas tolre
utiliser la notation func(int tab*)

int somme(int *tab); /*int somme(int*) rejet*/

task main()
{
int tab[2]={1,2};
int a;

a=somme(tab);
}

int somme(int*tab)
{ return tab[1]+tab[2] ;}
2.3 Linterface de programmation

API (Application Programming Interface )


dont liste des fonctions disponibles
Lcran LCD 178 pixels (29 caractres)

16 lignes daffichage, n 0 15
128 pixels
un caractre : 6x8 pixels ( 16 lignes [015]
un Big caractre : 12x16 pixel daffichage)
Un Big caractre occupe 2 lignes

task main()
{
string msg="Bonjour!";
float f=1; Bonjour! - 1.000

displayBigTextLine(0, allo!
"%s - %f",msg, f);
displayCenteredTextLine(8,"allo!");
}
Lcran LCD
void eraseDisplay()
efface compltement lcran

void displayTextLine(int Line, string Format, ..)


affiche sur la ligne de numro Line la chane correspondant au Format
le reste de la ligne est rempli de blancs

void displayCenteredTextLine(int Line, string Format,..)


idem displayTextLine mais le texte est centr au milieu de lcran

Les mme fonctions mais pour des gros caractres:


void displayBigTextLine(int Line, string Format,...)
void displayCenteredBigTextLine(int Line, string Format,
Le temps
void sleep(long ms)
void delay(long ms)
linstruction bloque pendant ms millisecondes
i.e. on passe linstruction suivante aprs ms millisecondes

La mesure du temps coul:


-un timer compte le nombre de millisecondes coules
-4 timers sont disponibles dID: T1,T2,T3 et T4

clearTimer(timerID)
remet 0 le timer en argument
long time1(timerID)
-retourne le temps coul depuis le reset en millisecondes
Le temps
task main()
{
long temps;

clearTimer(T1);
sleep(1654);
sleep(1000);
temps=time1(T1);

displayTextLine(8,"elapsed time: %i,temps);


}

Laffichage lexcution est : elapsed time: 2601


Le son

void setSoundVolume(int Volume)


rgle le volume sonore de la brique (0 (off) -100 (max))

void playTone(int frequency, int 10MsecTicks)


joue la note de frquence frequency
pendant une dure de 10MsecTicks x 10 millisecondes

void playSound(TSounds sound)


joue un son du systme. Sont disponibles (voir documentation):
soundBlip
soundBeepBeep

Les capteurs et moteurs : setup
Setup, pour indiquer au compilateur:

quels sont les capteurs connects ?


sur quels ports sont ils connect ?
dans quel mode de fonctionnement ?
quel noms/identifiants leur donne ton ?

quel est le type de moteur ?


quel nom/identifiant lui donne ton ?
est il pilot en boucle ouverte ou asservie en vitesse (boucle ferm) ?
Les capteurs et moteurs : setup
Ouvrir la fentre setup (ci-dessous) 2.Choisir un identifiant alias
(son nom dans le code c)

3.Choisir le mode
de fonctionnement
Port de la brique EV3
(o est connect le capteur) 1.Choisir le type du capteur connect
ou no sensor
Les capteurs et moteurs : setup
Les modes de fonctionnement des capteurs :
ultrason : 1. distance en cm
2. distance inch

contact : 1. mode touch (1 contact ou 0 non)

gyroscope : 1. angle only


2. rate only (vitesse angulaire)
3. angle and rate?

capteur de couleur:
1. reflected (lumire rflechie)
2. ambient (lumire ambiante)
3. color (mesure couleur)
Le modes raw donne des valeurs non normalises entre 0 et 100%.
Les capteurs et moteurs : setup
3. Si on veut inverser
le sens de rotation positif dun moteur
1.Choisir un nom/identifiant
Inutile: mettre None

2.Type du moteur

4. Commande vitesse en boucle ouverte


ou asservie (boucle ferm :PID avec vitesse
Medium Large drive du codeur du moteur)
Les capteurs et moteurs : setup
Une fois le setup valid,
le code correspondant la configuration est automatiquement insr dans le source.

Source.c :
#pragma config(Sensor, S1, gyroscope, sensorEV3_Gyro, modeEV3Gyro_RateAndAngle)
#pragma config(Sensor, S2, color_sensor, sensorEV3_Color)
#pragma config(Sensor, S3, ultrason, sensorEV3_Ultrasonic)
#pragma config(Sensor, S4, touch1, sensorEV3_Touch)

#pragma config(Motor, motorA, armMotor, tmotorEV3_Medium, PIDControl, encoder)


#pragma config(Motor, motorB, leftMotor, tmotorEV3_Large, PIDControl, encoder)
#pragma config(Motor, motorC, rightMotor, tmotorEV3_Large, PIDControl, encoder)
#pragma config(Motor, motorD, , tmotorEV3_Large, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//

PS: rien ninterdit dcrire ce code de prprocesseur sans passer par linterface graphique.
Les capteurs
float getUSDistance(tSensors capteur)
retourne la distance dans lunit correspondant au mode;
le capteur est soit le port S1,S2,S3,S4 ou le nom dalias
dfini dans le setup pour le capteur ultrason.

bool getTouchValue(tSensors capteur)


retourne 1 si capteur press, 0 sinon

void resetGyro(tSensors capteur)


remet 0 langle du gyroscope
long getGyroDegrees(tSensors capteur)
retourne langle accumul par le capteur en degrs
le signe indique la direction (positif=sens trigonomtrique)
long getGyroRate(tSensors capteur)
retourne la vitesse angulaire signe en degrs/seconde
Les capteurs
En fonction du mode slectionn pour le capteur de couleur:

int getColorReflected(tSensors capteur)


retourne en % (0-100) la quantit de lumire rflchie (LED on)

int getColorAmbient(tSensors capteur)


retourne en % (0-100) la quantit de lumire reue (LED off)

TLegoColors getColorName(tSensors capteur)


retourne une valeur entre 0 et 7 correspondant une couleur
la valeur reue peut tre stocke dans un int et compare aux
constantes: colorNone, colorBrown, colorWhite, colorRed,
colorYellow, colorGreen, colorBlue, colorBlack
Les capteurs
task main()
{
int color;
setMotorSpeed(leftMotor,50);
while(1)
{ color=getColorName(S3);
if (color==(int)colorRed) Si couleur dtecte rouge,
{ playSound(soundBeepBeep);} jouer un son

if (getTouchValue(touchSensor)==1) En cas de contact,


{setMotorSpeed(leftMotor,0);} stopper moteur

if (getUSDistance(sonarSensor)<10) En cas dobstacle 10 cm,


playSound(soundException); jouer un son.
sleep(100);
}
}
Le moteur

Le codeur de position incrmental:

void resetMotorEncoder(tMotor Motor)


remet 0 la position du moteur;
le moteur Motor correspond un port motorA,motorB,
motorC, motorD ou un nom dalias dfini dans le setup.

float getMotorEncoder(tMotor Motor)


retourne la valeur courante du codeur du moteur en degrs
Les capteurs
Exemple : Tant que la roue na pas fait 2 tours, avancer 50% de la vitesse max.

task main()
{
resetMotorEncoder(leftMotor);
setMotorSpeed(leftMotor,50);

while( getMotorEncoder(leftMotor) < (360*2) )


{}

setMotorSpeed(leftMotor,0);

}
Le moteur

La commande en vitesse des moteurs:

void setMotorSpeed(tMotor Motor, int speed)


speed est compris entre 100%(vitesse max) et -100% (vitesse max
en sens inverse), 0 met le moteur larrt;
-speed est un % de la tension de la batterie en mode boucle ouverte
-speed est un % de la vitesse maximale en boucle ferme (rgulation:
si les frottements ou la charge , U pour maintenir une mme vitesse )

bool getMotorRunning(tMotor nMotorIndex)


retourne 1 si le moteur est en mouvement ou 0 sinon
Le moteur
La commande en vitesse des moteurs:

void setMotorSyncTime(tMotor Motor1, tMotor Motor2,


long TurnRatio, long TimeMsec, long Speed)

synchronise les 2 moteurs pendant TimeMsec millisecondes ;


speed (-100100%) est la vitesse maximale des moteurs ;
TurnRatio influe sur le pourcentage de speed appliqu chaque moteur :
. 0, les 2 moteurs vont la mme vitesse
. 100, le moteur1 reoit speed et le moteur2 -speed
. -100, le moteur1 reoit -speed et le moteur2 speed
. 50, le moteur1 reoit speed et le moteur2 0
. 25, le moteur 1 reoit speed et le moteur 2 speed/2

Le moteur
La commande en position des moteurs:

void setMotorTarget(tMotor Motor,


float position, int speed)
provoque la rotation du moteur jusqu la position absolue en degrs
du codeur avec la vitesse donne par speed (-100%...100%)

void moveMotorTarget(tMotor Motor,


float position, int speed)
provoque la rotation du moteur jusqu la position relative (par rapport
position courante) en degrs du codeur avec la vitesse donne par speed

void waitUntilMotorStop(tMotor Motor)


attend larrt du moteur avant de continuer
(trs utile avant de commencer un nouveau mouvement)
Le moteur
La commande en position des moteurs:

void setMotorSyncEncoder(tMotor Motor1, tMotor Motor2,


long TurnRatio, long EncoderCount, long Speed)

synchronise les 2 moteurs jusqu atteindre un nombre de pas codeur


EncoderCount ;
speed (-100100%) est la vitesse maximale des moteurs ;
TurnRatio influe sur le pourcentage de speed appliqu chaque moteur :
. 0, les 2 moteurs vont la mme vitesse
. 100, le moteur1 reoit speed et le moteur2 -speed
. -100, le moteur1 reoit -speed et le moteur2 speed
. 50, le moteur1 reoit speed et le moteur2 0
. 25, le moteur 1 reoit speed et le moteur 2 speed/2
Evitement dobstacle avec robot tribot
task main()
{
while(1)
{ setMotorSpeed(leftMotor,50);
setMotorSpeed(rightMotor,50);

if (getUSDistance(sonarSensor)<14)

{setMotorSpeed(leftMotor,0);
setMotorSpeed(rightMotor,0);

setMotorSpeed(leftMotor,50);
sleep(700);
}
}}
Evitement dobstacle avec robot tribot
(en mieux) task main()
{
while(1)
{ setMotorSpeed(leftMotor,50);
setMotorSpeed(rightMotor,50);

while (getUSDistance(sonarSensor)>14);

{setMotorSpeed(leftMotor,0);
setMotorSpeed(rightMotor,0);

moveMotorTarget(leftMotor,360,50);
waitUntilMotorStop(leftMotor);
}
}}
Iconographie
[techcamp] http://www.techcamp.com.au/?page_id=523
[Helix84] Vector remaked svg version by user:Helix84
[encoder]
http://www.electronicproducts.com/Electromechanical_Components/
Choosing_a_sensor_to_measure_rotation.aspx
[philo] http://www.philohome.com/nxtmotor/nxtmotor.htm
[electroiq] http://electroiq.com/blog/2010/11/introduction-to-mems-gyroscopes/
[escplanta] http://escplantagenet.org/informatique/robotique/ping1.html
[dcmotor] http://www.trainsjouets.webege.com/lesmoteurs/index.html
[dcmodel]
http://robotics.ee.uwa.edu.au/courses/embedded/tutorials/tutorials/tutorial_6/
Tutorial_6.htm
[hbridge] http://www.hassockshog.co.uk/motor_controller_description.htm
Artist Martz 90

S-ar putea să vă placă și