Pages: 1 ... 5 6 [7] 8 9   Go Down
Author Topic: Bogue avec la bibliothèque Servo, comment corriger ce problème ???  (Read 8839 times)
0 Members and 1 Guest are viewing this topic.
Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1398
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non, va pas te taper un mur...

J'imagine qu'à force de gens comme nous qui tenteront de réécrire les fonctions basiques, on arrivera enfin à voir, sentir et utiliser toute la puissance d'un petit 328p. Il doit forcément déjà exister des IDE pile-poil qui remplaceraient à merveille arduino (c'est quand même terrible de voir qu'ils utilisent encore la plateforme java, alors que même sous visualC, ça tournerait bien plus vite), et on achètera du chinois moins cher, et arduino sombrera dans la cupidité aveugle de sa team.

En attendant, on va développer notre propre lib servo sous arduino, il faut bien un début...
Logged

Sherbrooke, Québec, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Et bien cher Super_Cinci,



En fin de lecture des « autres sujets dans la même section. », j'y étais déjà !

Mais ton dernier message, c'est le genre qui "pile-poil" redonne espoir en l'humanité, car il y a quelques heures, le niveau était bien bas !

En espérant que l'IDE de remplacement sera pour les trois environnements (Linux, Apple et Microsoft), voir plus. Car je ne retournerai assurément pas sous Apple ou Microsoft. Le libre et ouvert, rien d'autre !!!

...
En attendant, on va développer notre propre lib servo sous arduino, il faut bien un début...

Parlent de « notre propre lib servo », où en sommes-nous ?

Est-il vraiment possible d'utiliser un servomoteur sans perdre la variation 0 à 255 des autres broches PWM ?

Avec les histoires que je viens lire, il est facile de comprendre pourquoi tout part en lambeau !

L'ami René
Logged

Tous pour un et un pour tous !

Sherbrooke, Québec, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut Super_Cinci,

Comment arriver au même résultat que :

Code:
#define servo46 OCR5A // Accès au registre servo46 Timer5

Mais sans utiliser de directive de compilation et dans le code source du fichier ".ino" ?

On dit comme ça, définir en C++ d'Arduino une variable avec une adresse mémoire prédéfinie ?

Merci d'avance !

L'ami René
Logged

Tous pour un et un pour tous !

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1398
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

je suis en plein dedans...

alors voilà le chemin complet de la définition de OCR1A sur UNO (j'ai pas encore vu le code MEGA2560, mais c'est exactement pareil, seule l'adresse change). Par ordre de compilation :

Code:
// dans le fichier main.cpp :
#include <arduino.h>

// dans le fichier arduino.h :
#include io.h

// dans le fichier io.h
#include <sfr_defs.h>
#include <iom328p.h>

// dans le fichier sfr_defs.h :
#define _SFR_MEM16(mem_addr) (mem_addr)

// dans le fichier iom328.h :
#define OCR1A _SFR_MEM16(0x88)

// dans ton fichier
#define servo10 OCR1A

tout ça alors qu'on pourrait virer tous les fichiers et écrire

Code:
const ptr servo10 = 0x0088;
« Last Edit: September 26, 2013, 03:29:41 pm by Super_Cinci » Logged

Sherbrooke, Québec, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour Super_Circin,

Un très grand merci !

Alors pour remplacer « #define servo46 OCR5A » ...

Dans les 448 page, je n'ai pas trouvé de référence à l'adresse « 0x0088 ». Alors, je ne peux suivre la logique servo10 = 0x0088, donc servoXX = ... !

Pour Timer5, j'ai trouvé les adresse suivantes :

Code:
0x005C jmp TIM5_CAPT ; Timer5 Capture Handler
0x005E jmp TIM5_COMPA ; Timer5 CompareA Handler
0x0060 jmp TIM5_COMPB ; Timer5 CompareB Handler
0x0062 jmp TIM5_COMPC ; Timer5 CompareC Handler
0x0064 jmp TIM5_OVF ; Timer5 Overflow Handler

47 $005C TIMER5 CAPT Timer/Counter5 Capture Event
48 $005E TIMER5 COMPA Timer/Counter5 Compare Match A
49 $0060 TIMER5 COMPB Timer/Counter5 Compare Match B
50 $0062 TIMER5 COMPC Timer/Counter5 Compare Match C
51 $0064 TIMER5 OVF Timer/Counter5 Overflow

Et pour OCR5A j'ai trouvé :

Code:
17.11.26 OCR5AH and OCR5AL – Output Compare Register 5 A
(0x129) OCR5A[15:8]
(0x128) OCR5A[7:0]
OCR5AH
OCR5AL

(0x129) OCR5AH Timer/Counter5 - Output Compare Register A High Byte 164
(0x128) OCR5AL Timer/Counter5 - Output Compare Register A Low Byte 164


Pour la broche PWM 46 est-ce que cela ne serait pas l'adresse « 0x005C » ou « 0x129 » ?

J'ai essayé la ligne « const ptr servo10 = 0x0088; », mais il y a toujours des erreurs à la compilation :

J'ai essayé des lignes du genre de ce qui suit, mais aussi toujours des erreurs à la compilation :

Code:
...
/**************** MEGA UNIQUEMENT =  ******************************/
//#define servo46 OCR5A // Accès au registre servo46 Timer5
const int *servo10 = 0x0088;
const int &servo10 = 0x0088;
const ptr servo46 = 0x129;// Accès au registre servo46 Timer5
const byte &servo46 = 0x129;// Accès au registre servo46 Timer5
const int &servo46 = 0x129;// Accès au registre servo46 Timer5
const word &servo46 = 0x129;// Accès au registre servo46 Timer5
...
// Utilisation...
    servo46 = map (PotentiometreValeur, 0, 1023, 1046, 4564);
//    *servo46 = map (PotentiometreValeur, 0, 1023, 1046, 4564);
//    &servo46 = map (PotentiometreValeur, 0, 1023, 1046, 4564);
...
/**************** FIN MEGA  ******************************/

Tu peux m'aider avec la ligne de code Arduino exacte pour « servo10 » et/ou « servo46 » ?

L'ami René
Logged

Tous pour un et un pour tous !

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1398
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pourquoi ne veux-tu pas garder #define servo46 OCR5A ? ça marche très bien! je t'ai juste montré le fastidieux chemin pour comprendre comment ça marchait...

de plus, le type ptr n'est pas bon je pense.
« Last Edit: September 27, 2013, 12:54:47 am by Super_Cinci » Logged

Sherbrooke, Québec, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut Super_Cinci

Pourquoi ne veux-tu pas garder #define servo46 OCR5A ? ça marche très bien!...

J'ai plusieurs raisons, alors, dans le désordre :

1) Pour rendre le code source plus modulable, car en général, on regroupe les directives de compilation hors de la structure des fonctions qui utilisent ces constantes et variables que sont les « #define ».

2) Pour rendre le code source plus modulable, car en général, on regroupe les directives de compilation au début (en haut du code source) et c'est parfois loin des fonctions qui les utilisent.

3) De manière générale simplement mettre où je veux dans mon code des déclarations de constante et de variable.

4) Tu le soulignes toi-même, la lourdeur des directives de compilation.

5) En général, avoir le moins possible recourt aux directives de compilation.

Etc. Les goûts de chacun sont dans la nature et la manière de programmer aussi.

... je t'ai juste montré le fastidieux chemin pour comprendre comment ça marchait...

Et je t'en remercie !

... de plus, le type ptr n'est pas bon je pense.

Je le confirme et c'est pour cela que je souhaiterais que tu m'aides avec la ligne de code Arduino pour « servo10 » et/ou « servo46 » ?

Te ne dis rien sur le « Dans les 448 pages, je n'ai pas trouvé de référence à l'adresse « 0x0088 ». Alors, je ne peux suivre la logique servo10 = 0x0088, donc servoXX = ... ! »

Cela pourrait me permettre de faire les corrélations « nom des registres » et « adresse des registres », etc., car je veux me constituer en un seul tableau de référence, car éplucher à chaque fois qu'on a besoin d'une référence, les 448 pages cela fait beaucoup. Souviens-toi j'ai écrit il y a un ou deux jours :

...
3) Tout reprendre au début et me faire une table de référence systématique des ports PWM des Arduino Mega, Nano et Uno avec registre individuel et lier à quelle minuterie, etc.

Pour aujourd'hui, je vais opter pour l'option # 3.

Dans cette optique, est-ce qu'il existe déjà un tableau de ce genre quelque part, sans devoir éplucher 25 pages des 448 pages pour chaque Arduino ?

Je vais préparer des codes sources exemples pour bien cerner la question des PWM avec 1 moteur CC et un servomoteur.

Mais si j'ai bien compris la base, par exemple pour un Mega, la minuterie 5 "Timer" s'applique nécessairement et simultanément aux « Périodes » des broches 44, 45 et 46, mais par la suite, je peux contrôler individuellement la « Fréquence » de la broche 44 ou 45 ou 46 ? Mais c'est peut-être l'inverse (Fréquence, Période) ?

Je recherche donc des exemples pour en faire des corrélations et devenir autonome avec registre, minuteries, fréquences, périodes, etc.

Et j'aurais besoin de ton aide avec la ligne de code qui remplace « const ptr servo10 = 0x0088; »  et/ou « const ... servo46 = ... » ?

D'avoir un exemple qui fonctionne m'aidera dans bien d'autres situations et cas de figure. Travailler avec des pointeurs ou par adresse c'est très utile. En Langage Pascal, je maîtrisais cela parfaitement, et je souhaiterais maîtriser cela en C++ aussi, de la ma demande...

L'ami René
Logged

Tous pour un et un pour tous !

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1398
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

En Langage Pascal, je maîtrisais cela parfaitement, et je souhaiterais maîtriser cela en C++ aussi, de la ma demande...
Salut René,

Moi aussi, j'ai eu maîtrisé grandement turboPascal 7 dans les années 90, et c'est pour cela que j'ai encore 3 PC 386 encore en état de marche, avec un bon vieux DOS 6.1 et Win95B pour jouer de temps en temps.

d'ailleurs, le mot clé "ptr" vient de là si mes souvenirs sont bons.

dans ton cas, tu peux regarder le fichier hardware\tools\avr\avr\include\avr\iom2560.h, c'est celui qui contient toutes les adresses des vecteurs / registres du 2560 (iom328p.h pour la UNO). Je ne pense pas qu'il soit vraiment utile d'aller chercher à courcircuiter ce fichier, car notre #define servoXX OCRnX est bien plus lisible qu'un #define servoXX (@)0x0088 (je n'ai pas la syntaxe exacte, il faut que le compilateur reconnaisse servoXX comme une adresse mémoire). de plus, à la compilation, le code assembleur (code machine qui est inscrit directement dans la flash du processeur), il y a deux façons d'accéder aux registres en fonction de leurs emplacements, ce qui ne rend pas les choses plus faciles pour nous. certains registres sont accessibles directement dans les registres E/S, d'autres via la RAM...

Code:
  TCCR0A |= 0x02;    /* sera compilé par :
     in  r24,0x24  // R24 = TCCR0A;
     ori r24,0x02  // R24 |= 0x02;
     out 0x24,r24  // TCCR0A = R24;  */

  TIMSK0 |= 0x01;    /* sera compilé par :
     ldi r30,0x6E  //  la paire de registres r31:r30 correspond au registre 16 bits "Z"
     ldi r31,0x00  // Z = 0x006E;  // adresse du registre TIMSK0
     ld  r24,Z     // R24 = @Z; // Charger la valeur de l'adresse Z dans R24
     ori r24,0x01  // R24 |= 0x01;
     st  Z,r24     // @Z = R24;   //Stocker R24 à l'adresse Z  */

On voit bien ici que pour deux registres du timer 0 (MEGA2560), l'accès ne se fait pas du tout pareil, car TIMSK0 est dans la plage "SRAM" du chip (adresse 0x006E par l'instruction "ld", plage d'E/S étendue), alors que TCCR0A est dans la table des registres (adresse 0x24 par l'instruction "in" plage E/S). Dans les deux cas, il faut de toute façon passer par les registres internes du CPU (R0 à R31, X, Y et Z).
Logged

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1398
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

(suite)

Tu peux regarder la page 27 du datasheet qui explique d'ailleurs pourquoi de temps en temps on rajoute 0x20 à l'adresse d'un registre, mais même si je maîtrise parfaitement l'anglais technique, là, j'ai pas encore tout compris...

Les adresses vecteurs / registres sont bien à la page 411... Ce tableau, la page 27 et les fichiers .h que j'ai cité plus haut font l'ensemble le plus complet qu'il puisse y avoir pour comprendre le fonctionnement de l'affectation / modification des registres et ports I/O. Je ne peux pas t'en donner plus.

Quote
1) Pour rendre le code source plus modulable,(...)
ce que tu veux, c'est pouvoir modifier l'angle du servo sur la pin XX? je ne vois pas plus simple qu'écrire servoXX = angle. Tu veux déplacer ton servo sur une pin YY sans toucher à ton code? il suffit de changer le #define servoXX = OCRnX en #define servoXX = OCRnY (changer le Y, car changer de timer te demandera quand même de modifier le code, mais uniquement l'appel à servoInit().

le mieux est souvent l'ennemi du bien...

Mieux vaut te concentrer sur le contenu des registres et leurs interactions sur le fonctionnement du µP que de tenter de bidouiller les adresses. Comme tu le vois dans l'exemple assembleur, malgré des #define dans tous les sens, on ne pourra pas mieux optimiser l'accès à ces registres.
Code:
servo46 = 4341;    /* serait donc compilé par :    4341 = 0x10F5 ...
    ldi r17,0x10;  // poids fort de 0x10F5
    ldi r16,0xF5;  // poids faible de 0x10F5
    ldi r30,0x29  //  la paire de registres r31:r30 correspond au registre 16 bits "Z"
    ldi r31,0x01  // Z = 0x0129;  // adresse du registre OCR5AH
    st  Z,r17     // @Z = R17;   //Stocker R17 à l'adresse Z 
    dec r30       // r30--;     // Z=0x0128 maintenant, adresse de OCR5AL
    st  Z,r16     // @Z = R17;   //Stocker R17 à l'adresse Z  */
« Last Edit: September 27, 2013, 06:19:32 am by Super_Cinci » Logged

Sherbrooke, Québec, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut Super_Cinci,

...
Quote
1) Pour rendre le code source plus modulable,(...)

ce que tu veux, c'est pouvoir modifier l'angle du servo sur la pin XX? je ne vois pas plus simple qu'écrire servoXX = angle.

Non, c'est le « #define ... » que je trouve lourd et pénible !!!

De même, je préférerais écrire « servo46 (UneValeur); » au lieu de « servo46 = UneValeur; », pour toutes sortes de raisons, dans toutes sortes de situations, c'est global, pas seulement pour les servomoteurs.

Et c'est pour ça qu'un exemple réel de code pour remplacer « #define servo46 OCR5A  » m'aurait été très utile.

L'ami René
Logged

Tous pour un et un pour tous !

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1398
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

alors ceci :

Code:
#define servo46(valeur) (OCR5A = (valeur))

niveau compilation, c'est tout pareil.

par contre, pour lire la valeur du servo, "valeur = servo46;" ne marchera plus.
« Last Edit: September 27, 2013, 07:28:47 am by Super_Cinci » Logged

Sherbrooke, Québec, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rebonjour Super_Cinci,

Et bonjour à tous les autres, si vous connaissez la réponse, vous pouvez nous l'écrire !

Une autre manière de dire que je veux remplacer la ligne de code « #define servo46 OCR5A », ce serait de dire que :

Comment faire pour que l'adresse mémoire de ma variable « servo46 » soit la même que l'adresse mémoire du registre « OCR5A » ?

En langage Pascal, cela se fait facilement, alors en C++ cela devrait être encore plus facile !

L'ami René
Logged

Tous pour un et un pour tous !

Sherbrooke, Québec, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alors là, je fais un Lucky-Luck de moi, je tire plus vite que mon ombre !    smiley-mr-green

Je viens de répondre à ton dernier message, avant même de l'avoir lu !

L'ami René
Logged

Tous pour un et un pour tous !

Sherbrooke, Québec, Canada
Offline Offline
Full Member
***
Karma: 1
Posts: 246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rebonjour,

Bon, j'ai trouvé sur « Programmation C » :

http://fr.wikibooks.org/wiki/Programmation_C/Pointeurs !

et

http://fr.wikibooks.org/wiki/Programmation_C_Types_avanc%C3%A9s#D.C3.A9finitions_de_synonymes_de_types_.28typedef.29

Il y a donc deux manières en C :

1) :
Code:
uint16_t *servo46 = &OCR5A;// Accès au registre servo46 Timer5

2) :
Code:
// Définition du type de variable « t_Pointeur », qui est un pointeur « * »,
// de type « uint16_t » nommé « Pointeur ».
typedef uint16_t t_Pointeur *Pointeur;
Pointeur servo46 = &OCR5A;// Accès au registre servo46 Timer5

Mais, n'y l'une n'y l'autre ne fonction en Arduino ! smiley-zipper smiley-zipper smiley-zipper

L'ami René
Logged

Tous pour un et un pour tous !

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1398
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Une autre manière de dire que je veux remplacer la ligne de code « #define servo46 OCR5A », ce serait de dire que :
OK, cette ligne ne te plait pas.
Comment faire pour que l'adresse mémoire de ma variable « servo46 » soit la même que l'adresse mémoire du registre « OCR5A » ?
Ben justement, #define servo46 OCR5A fait que partout où tu utiliseras la variable servo46, ça écrira ou lira à l'adresse mémoire du registre OCR5A. Si tu préfères, ce #define déclare une variable de type word nommée servo46 à l'adresse du registre OCR5A.

si tu fais "servo46 = 1345;", tu peux aller vérifier, la case mémoire à l'adresse 0x0088 contiendra 1345. si tu fais valeur = servo46, alors ça affectera à valeur le contenu de la case mémoire d'adresse 0x0088.

je ne comprends pas ce que tu cherches à faire en fait. tu voudrais changer quelque chose qui pourtant répond à ta question...
Logged

Pages: 1 ... 5 6 [7] 8 9   Go Up
Jump to: