Show Posts
Pages: 1 ... 4 5 [6]
76  International / Français / Re: [Tests] Temps pour faire changer d'état une pin (niveau Haut/Bas) on: October 29, 2011, 12:29:10 pm
j'ai (comme 68tjs) fait cette remarque. pour ma part, je remplace souvent un digitalwrite() par un PORTB |=..., un pinmode par un DDRD &=...

De plus, il serait intéressant de voir ce que donne la compilation d'un petit programme en arduino et du même en registres, niveau taille flash. je crois qu'on y gagnerait énormément! (je pense à JF qui n'arrive pas à faire tourner une SD sur un 168... smiley-grin)

Justement, les macros que j'ai postées ci-dessus prennent en charge toute la gymnastique de traduction d'un numéro de pin arduino en un couple (Port + Adresse sur le port), de façon transparente ; elles sont strictement équivalentes à écrire PORTB |= (1 << PINBn). Et comme ce sont des macros elles sont résolues à la compilation, donc aucun appel de fonction  smiley-grin
77  International / Français / Re: [Tests] Temps pour faire changer d'état une pin (niveau Haut/Bas) on: October 28, 2011, 01:08:32 pm
Bonsoir,

Je vous recommande la librairie digitalWriteFast.
C'est un fait une série de grosses macros qui permettent de réduire fortement le temps de commutation et/ou de lecture des pins lorsque le numéro des pins est connu à la compilation.

Il suffit d'ajouter un #include "digitalWriteFast.h" dans les fichiers où vous souhaitez l'utiliser. Ensuite, il faut utiliser les fonctions digitalWriteFast, digitalReadFast, pinModeFast à la place de digitalWrite, digitalRead, pinMode.

Ci-dessous, ma version :


Code:
#ifndef DIGITAL_WRITE_FAST_H
#define DIGITAL_WRITE_FAST_H
 /**
 * \file
 * \brief Macros to use digitalWrite style syntax with most of the speed of PORT
 *
 * This library consists of a complex header file that translates
 * digitalWriteFast, pinModeFast, digitalReadFast into the corresponding PORT
 * commands.
 *
 * It provides syntax that is as novice-friendly as the arduino's pin
 * manipulation commands but an order of magnitude faster.
 *
 * It can speed things up when the pin number is known at compile time, so that
 * digitalWrite(9,HIGH); is speeded up. On the other hand a loop with
 * digitalWrite(i,HIGH); or a called function with the pin number as a passed
 * argument will not be faster.
 *
 * For more information visit <http://code.google.com/p/digitalwritefast/>.
 */
#include <WProgram.h>
#include <wiring.h>
//------------------------------------------------------------------------------
// bit operations
#define BIT_READ(value, bit) (((value) >> (bit)) & 0x01)
#define BIT_SET(value, bit) ((value) |= (1UL << (bit)))
#define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit)))
#define BIT_WRITE(value, bit, bitvalue) \
(bitvalue ? BIT_SET(value, bit) : \BIT_CLEAR(value, bit))
//------------------------------------------------------------------------------
#if !defined(digitalPinToPortReg)
//------------------------------------------------------------------------------
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// ATmega1280, ATmega2560
#define digitalPinToPortReg(P) \
(((P) >= 22 && (P) <= 29) ? &PORTA : \
((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \
(((P) >= 30 && (P) <= 37) ? &PORTC : \
((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \
((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \
(((P) >= 54 && (P) <= 61) ? &PORTF : \
((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \
((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \
(((P) == 14 || (P) == 15) ? &PORTJ : \
(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL))))))))))
#define digitalPinToDDRReg(P) \
(((P) >= 22 && (P) <= 29) ? &DDRA : \
((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \
(((P) >= 30 && (P) <= 37) ? &DDRC : \
((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \
((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \
(((P) >= 54 && (P) <= 61) ? &DDRF : \
((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \
((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \
(((P) == 14 || (P) == 15) ? &DDRJ : \
(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL))))))))))
#define digitalPinToPINReg(P) \
(((P) >= 22 && (P) <= 29) ? &PINA : \
((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \
(((P) >= 30 && (P) <= 37) ? &PINC : \
((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \
((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \
(((P) >= 54 && (P) <= 61) ? &PINF : \
((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \
((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \
(((P) == 14 || (P) == 15) ? &PINJ : \
(((P) >= 62 && (P) <= 69) ? &PINK : &PINL))))))))))
#define __digitalPinToBit(P) \
(((P) >=  7 && (P) <=  9) ? (P) - 3 : \
(((P) >= 10 && (P) <= 13) ? (P) - 6 : \
(((P) >= 22 && (P) <= 29) ? (P) - 22 : \
(((P) >= 30 && (P) <= 37) ? 37 - (P) : \
(((P) >= 39 && (P) <= 41) ? 41 - (P) : \
(((P) >= 42 && (P) <= 49) ? 49 - (P) : \
(((P) >= 50 && (P) <= 53) ? 53 - (P) : \
(((P) >= 54 && (P) <= 61) ? (P) - 54 : \
(((P) >= 62 && (P) <= 69) ? (P) - 62 : \
(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \
(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \
(((P) == 19) ? 2 : \
(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \
(((P) == 2) ? 4 : \
(((P) == 3 || (P) == 4) ? 5 : 7)))))))))))))))
#define __digitalPinToTimer(P) \
(((P) == 13 || (P) ==  4) ? &TCCR0A : \
(((P) == 11 || (P) == 12) ? &TCCR1A : \
(((P) == 10 || (P) ==  9) ? &TCCR2A : \
(((P) ==  5 || (P) ==  2 || (P) ==  3) ? &TCCR3A : \
(((P) ==  6 || (P) ==  7 || (P) ==  8) ? &TCCR4A : \
(((P) == 46 || (P) == 45 || (P) == 44) ? &TCCR5A : 0))))))
#define __digitalPinToTimerBit(P) \
(((P) == 13) ? COM0A1 : (((P) ==  4) ? COM0B1 : \
(((P) == 11) ? COM1A1 : (((P) == 12) ? COM1B1 : \
(((P) == 10) ? COM2A1 : (((P) ==  9) ? COM2B1 : \
(((P) ==  5) ? COM3A1 : (((P) ==  2) ? COM3B1 : (((P) ==  3) ? COM3C1 : \
(((P) ==  6) ? COM4A1 : (((P) ==  7) ? COM4B1 : (((P) ==  8) ? COM4C1 : \
(((P) == 46) ? COM5A1 : (((P) == 45) ? COM5B1 : COM5C1))))))))))))))
//------------------------------------------------------------------------------
#else // ATmega8, ATmega168, ATmega328
#define digitalPinToPortReg(P) \
(((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC))
#define digitalPinToDDRReg(P) \
(((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC))
#define digitalPinToPINReg(P) \
(((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC))
#define __digitalPinToBit(P) \
(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))
//------------------------------------------------------------------------------
#if defined(__AVR_ATmega8__) // ATmega8
#define __digitalPinToTimer(P) \
(((P) ==  9 || (P) == 10) ? &TCCR1A : (((P) == 11) ? &TCCR2 : 0))
#define __digitalPinToTimerBit(P) \
(((P) ==  9) ? COM1A1 : (((P) == 10) ? COM1B1 : COM21))
//------------------------------------------------------------------------------
#else // ATmega168, ATmega328
#define __digitalPinToTimer(P) \
(((P) ==  6 || (P) ==  5) ? &TCCR0A : \
(((P) ==  9 || (P) == 10) ? &TCCR1A : \
(((P) == 11 || (P) ==  3) ? &TCCR2A : 0)))
#define __digitalPinToTimerBit(P) \
(((P) ==  6) ? COM0A1 : (((P) ==  5) ? COM0B1 : \
(((P) ==  9) ? COM1A1 : (((P) == 10) ? COM1B1 : \
(((P) == 11) ? COM2A1 : COM2B1)))))
#endif  // ATmega8
#endif  // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#endif  // !defined(digitalPinToPortReg)
//------------------------------------------------------------------------------
#define __atomicWrite__(A,P,V) \
if ( (int)(A) < 0x40) { \
bitWrite(*((volatile uint8_t*) A), __digitalPinToBit(P), (V) );} \
else { \
uint8_t register saveSreg = SREG; \
cli(); \
bitWrite(*((volatile uint8_t*)A), __digitalPinToBit(P), (V) ); \
SREG=saveSreg; \
}
//------------------------------------------------------------------------------
#ifndef digitalWriteFast
#define digitalWriteFast(P, V) \
do { \
if (__builtin_constant_p(P) && __builtin_constant_p(V)) \
__atomicWrite__(digitalPinToPortReg(P),P,V) \
else  digitalWrite((P), (V)); \
} while (0)
#endif
//------------------------------------------------------------------------------
#if !defined(pinModeFast)
#define pinModeFast(P, V) \
do { \
if (__builtin_constant_p(P) && __builtin_constant_p(V)) \
__atomicWrite__(digitalPinToDDRReg(P),P,V) \
else pinMode((P), (V)); \
} while (0)
#endif
//------------------------------------------------------------------------------
#ifndef noAnalogWrite
#define noAnalogWrite(P) \
do {if (__builtin_constant_p(P) )  __atomicWrite(__digitalPinToTimer(P),P,0) \
else turnOffPWM((P)); \
} while (0)
#endif
//------------------------------------------------------------------------------
#ifndef digitalReadFast
#define digitalReadFast(P) ( (int) _digitalReadFast_((P)) )
#define _digitalReadFast_(P ) \
(__builtin_constant_p(P) ) ? ( \
( BIT_READ(*digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \
digitalRead((P))
#endif
//------------------------------------------------------------------------------
#endif // DIGITAL_WRITE_FAST
78  International / Français / Re: crontab dans sketch on: October 26, 2011, 06:54:53 am
Pour rebooter depuis un programme Arduino, tu devrais utiliser le Watchdog Timer. Attention, sur certaines cartes Arduino le bootloader désactive le watchdog timer donc il faut le modifier.

Pour le reste, il faut l'écrire dans ton programme.

Supposons que tu as une fonction testConnection et une fonction reset (qui utiliserait le watchdog timer). Pourquoi ne pas utiliser un truc dans ce genre :
Code:
const int maxErrors = 3;
int errors;

errors = 0;
do {
    if (testConnection()) break;
    ++errors;
} while (errors < maxErrors);
if (errors == maxErrors) reset();
...
// suite du programme
...

Sinon si tu veux planifier des tâches à intervalles fixes, il faut regarder du côté des Timer/Counter.
79  International / Français / Re: fréquence max sur sorties arduino? on: October 21, 2011, 07:19:16 am
Si la question est de savoir à quelle fréquence on peut commuter une sortie sur un arduino Uno, je pense que tu peux atteindre des fréquences de commutation de quelques MHz.

Par contre, hors de question d'utiliser digitalWrite, c'est beaucoup trop lent. Il faut manipuler le port directement.

Par exemple la pin désignée par le numéro 13 dans Arduino est la pin 7 du port B.

Pour l'initialiser, la commande Arduino habituelle :
Code:
pinMode(13, OUTPUT);

Ensuite, pour la faire changer d'état il suffit de faire un XOR, qui va la passer à l'état haut si elle est à l'état bas, et réciproquement.

Code:
PORTB ^= _BV(PINB7);

Cette opération ne prend pas toujours un seul cycle d'horloge, mais elle est quand même beaucoup plus rapide que de faire le classique
Code:
digitalWrite(13, LOW);
digitalWrite(13, HIGH);
80  International / Français / Re: Arduino UNO et bootload "maison" on: October 21, 2011, 05:16:02 am
ça fonctionne pas avec la UNO, j'ai une UNO, d'où ma question d'espérer la possibilité de pouvoir le faire quand même... smiley

J'utilise un Arduino Uno acheté au mois de mai et je n'ai jamais eu de problème pour l'utiliser comme programmateur avec ArduinoISP.
Peut-être que si ta carte est assez récente le problème matériel a déjà été corrigé dessus.

Récemment j'ai écrit un bootloader et pour le tester j'ai dû le charger des dizaines de fois sur le microcontrôleur ; je n'ai jamais eu de souci   smiley-slim
81  International / Français / Re: fréquence max sur sorties arduino? on: October 21, 2011, 05:04:31 am
Oui, tu peux monter beaucoup plus haut.

Je ne sais pas si ça fait partie de l'API Arduino, mais les timers 16 bits des ATmega ont un mode Fast PWM.
Tout dépendra du modèle que tu as.

Par exemple avec l'ATmega1280 l'utilisation du mode Fast PWM est décrite dans le manuel à la page 161.

Ci-dessous un exemple qui utilise le Timer/Counter2 de l'ATmega1280.

Il y a deux étapes : d'abord il faut configurer le timer.

Code:
// EXCLK = 0 and AS2 = 0 : clock the timer from the I/O clock (p.165)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// WGM20 = 1 and WGM21 = 1 : set Fast PWM mode (p.161)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
// WGM22 = 0 : set Fast PWM mode (p.161)
TCCR2B &= ~_BV(WGM22);
// COM2A1 = 1 and COM2A0 = 0 : at compare match, OC2A = 1 when the next cycle begins (p.159)
TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
// COM2B1 = 0 and COM2B0 = 0 : OC2B disconnected (p.160)
TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
// CS20 = 1, CS21 = 0 and CS22 = 0 : clock select no prescaling (p.163)
TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20);

Ensuite il suffit de modifier la valeur du registre nommé OCR2A pour changer le niveau de la PWM.
C'est très simple, il suffit de charger dedans la valeur que tu veux, comprise entre 0 et 255, pour faire varier le rapport cyclique entre 0 et 1.

Avec le code ci-dessus, la PWM est à 16MHz/256 soit 62.5kHz

Par exemple pour avoir ta sortie PWM à 0V :
Code:
OCR2A = 0;

Pour avoir ta sortie PWM à 5V :
Code:
OCR2A = 255;

Pour avoir ta sortie PWM à 2.5V :
Code:
OCR2A = 127;

En espérant que ça te soit utile  smiley
82  International / Français / Re: Transformer un arduino en carte SD on: October 14, 2011, 12:31:28 pm
De toute façon, c'est ça ou implémenter un contrôleur de carte SD sur l'Arduino ..
En plus, avoir une vraie carte SD ça donne plus de flexibilité pour générer ton BMP, alors que si tu dois tout faire avec 4ko de RAM ça peut devenir assez délicat  smiley-grin
83  International / Français / Re: Transformer un arduino en carte SD on: October 14, 2011, 09:43:05 am
Hello,

Si je comprends bien, tu veux que l'Arduino soit branché sur le port SD du cadre photo et se "fasse passer" pour une carte SD ?
Donc quand le cadre photo envoie des commandes à la carte SD, c'est l'Arduino qui les reçoit et il doit renvoyer des données, générées à partir des infos à afficher, au format BMP ?

84  Using Arduino / Microcontrollers / Compiling the bootloader: surprising result on: September 20, 2011, 08:52:07 am
Hi everyone,

I'm using Win7 x64 and I'm trying to compile the bootloader located in arduino-0022\hardware\arduino\bootloaders\atmega for the ATmega1280. I have gcc version 4.3.3 (WinAVR 20100110).

The size of the HEX file ATmegaBOOT_168_atmega1280.hex shipped with Arduino IDE is 10,921 bytes.
But when I try to compile it from ATmegaBOOT_168.c the resulting file is only 7,027 bytes long.

Below is the output from the Windows console:
c:\Program Files (x86)\arduino-0022\hardware\arduino\bootloaders\atmega>make mega
avr-gcc -g -Wall -O2 -mmcu=atmega1280 -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=0' -DBAUD_RATE=57600 -c -o ATmegaBOOT_168.o ATmegaBOOT_168.c
avr-gcc -g -Wall -O2 -mmcu=atmega1280 -DF_CPU=16000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=0' -DBAUD_RATE=57600 -Wl,--section-start=.text=0x1F000 -o ATmegaBOOT_168_atmega1280.elf ATmegaBOOT_168.o
avr-objcopy -j .text -j .data -O ihex ATmegaBOOT_168_atmega1280.elf ATmegaBOOT_168_atmega1280.hex
rm ATmegaBOOT_168.o ATmegaBOOT_168_atmega1280.elf


Is there something wrong with the options? What am I missing?

Thanks a lot
Pages: 1 ... 4 5 [6]