utiliser un atmega sans arduino

salut a tous
voila pour mon projet j'ai besoin de beaucoup de I/O en PWM ( + de 100 )
le soucis c'est que je me voit pas acheter 50 arduino pour avoir le bon nombre d'I/O donc je me suis dit que je pourrez utilisé un arduino pour programmer les atmega et ensuite mettre l'atmega directement sur un autre circuit ( 4? l'atmega donc plus rentables que un arduino a chaque fois )
le seul soucis c'est je me demandez si toute les I/O de l'atmega été utilisable en pwm et que mettre comme protection pour pas le cramé
sinon avez vous une solution d'une carte qui aurez beaucoup d'I/O ?
merci

L'atmega 328 gère de base 6 sorties PWM, mais il existe des scriptes pour convertir des sorties standards en sorties PWM

Cela dit, si tu as besoin de toutes ces sorties sur un meme circuit, le TLC5940 devrait t'interesser. Il permet de piloter 16 sorties PWM, mais tu peux en rajouter plusieurs a la suite. Donc, 7 circuits a la queue leu leu te donnent 112 sorties, avec seulement 5 pins de la carte utilisés.

interessant ca ^^
7 circuit avec 5 pin utilisé ? faut que tu mexplique la ^^
il ce pilote comment ? enfin comment je peux faire pour piloter des servo directement ?
une idée d'un bout de code ?
et au passage
pense tu que l'arduino arrivera a faire fonctionner 112 servo en meme temps ?
au niveau de l'alim je sais que non mais ca c'est déja fait avec de bon vieux régul mais sinon j'ai peur qu'il pedale un peu nan ?

encore un ptit truc ^^
c'est tu ou je peux en trouvé en france ??
avec les support bien sur
merci

48 servos maximum pour la Mega :

http://www.arduino.cc/playground/Code/MegaServo

c'est déjà pas trop mal ::slight_smile:

Le TLC5940 est "chainable", c'est a dire que plusieurs peuvent se brancher en parallèle, et fonctionnent comme un énorme circuit intégré modulable ( comme les registes à décallage type cd4094).

Il se pilote via une librairie:
http://www.arduino.cc/playground/Learning/TLC5940
Il gere aussi les servos (il y a un script d'exemple dans la lib)
Pour plus d'infos:
http://code.google.com/p/tlc5940arduino/
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1218174457

merci a toi erlik
je pense que je vais opté pour ca
il ce chaine comment ?
un adressage je présume ^^
mais toujours la grande question
ou en trouvé ??
le seul fournisseur que j'avais n'en a plus donc ca va va etre dur
et il me faudrait les support avec ^^
merci

Pour le cablage et l'adressage des données, tout est indiqué dans le playground et les sketchs de la librairie
http://www.arduino.cc/playground/Learning/TLC5940
Et encore un dessin si ça ne suffit pas
http://students.washington.edu/acleone/codes/tlc5940arduino/img/tlc5940arduino_wiring.png
Mais manque bien sur les éléments a piloter (leds, servos, autre)

Coté boutiques, y a de quoi faire sur le net (attention aux frais de ports, et de douane hors UE)

http://www.earthshineelectronics.com/62-tlc5940-16-channel-led-driver.html

merci a toi
sparkfun n'en a plus
farnell c'est du CMS et j'en veut pas ^^
ensuite le dernier ne m'inspire pas du tout confiance ^^
sinon oui c'est pour piloter des servo ^^

j'ai enfin réussi a en trouvé ^^
il sont commandé en attente de les recevoir ^^
encore deux petites questions ^^
dans la libraires je trouve pas comment savoir a quel tlc envoyé les données enfin piloté le servo
genre si j'en mets 5 comment je fais pour envoyé le signal pwm au 5 eme servo du 3 eme tlc ?
vu qu'il ne sont pas programmé je voit pas comment je peux savoir au quel envoyé ^^
une idée ? un début de code ??
ensuite j'ai besoin de autant de sortie que d'entrées
donc j'ai environ 80 sortie mais il m'en faut autant en entrée !!
multiplexing me semble mais quoi utilisé pour faire ca
un nom de composants ? une idée de la librairies ?
merci beaucoup

Pour les sorties, il y en a 16 par circuits. Sur le 1er circuit, elles correspondent aux channels 0 à 15. Su tu en rajoutes un, les nouvelles sont numerotés 16 à 31, etc etc. Quand tu modifies la valeur d'un channel, la lib tente de répercuter cela au TLC5940 correspondant.
Donc, tes sorties vont de 0 à [16*Nbr TLC5940 - 1]
Dans la librairie, tu as un code d'exemple avec les servos ( et comment connecter la sortie à l'entre data du servo )

#define SERVO_CHANNEL   0
int angle = 25;
    tlc_setServo(SERVO_CHANNEL, angle);
    Tlc.update();

Ou SERVO_CHANNEL correspond à la sortie 0 (1er circuit)
Si tu avais mis "SERVO_CHANNEL 35", il aurait tenté de mettre à jour le channel 35, cad sortie 4 du 3ème circuit
0->15 = circuit 1
16->31 = circuit 2
32->47 = circuit 3
etc

Il n'y a donc rien a définir, juste ne pas se planter dans les branchements et les n° de channel. A noter qu'il n'y a pas d'erreur si tu tentes de mettre a jour la valeur d'un channel qui n'existe pas

Mais comme dit avant, regarde bien les exemples, abondamment commentés, dans la librairie, ça te donnera toutes tes réponses.

merci a toi c'est pile ca que je voulais savoir ^^
ca me donne réponse a toute mes questions sauf une mais bon ^^
donc en gros quand je les chaines il comprends ca comme une extension sur le même tlc et non comme un autre tlc donc si je veut la 4 eme sortie du 3 eme tlc ca me donne le 36 ( 16+16+4 )
normalement j'ai bien capté ^^
je commence le code mais il me faudrait une infos ^^
comment avoir autant de sortie que d'entrée ?
les TLC ne sont valable que en sortie donc il me faut du multiplexing je pense

donc en gros quand je les chaines il comprends ca comme une extension sur le même tlc et non comme un autre tlc donc si je veut la 4 eme sortie du 3 eme tlc ca me donne le 36 ( 16+16+4 )

Oui, c'est ça. Mais attention, la numérotation commence de 0, donc fait attention dans les branchements

comment avoir autant de sortie que d'entrée ?
les TLC ne sont valable que en sortie donc il me faut du multiplexing je pense

Tu veux une 100ènes d'entrées ?... Ça dépendra surtout du signal entrant à lire.
Si c'est des changement d'états, tu peux tenter le PCF8575, un composant I²C qui peut gerer 16 entrées/sorties (interrupteurs), mais on ne peut en utiliser "que" 8 ( 128 entrées quand même ) sur un même bus I²C, at il n'existe qu'en SMD.
Sinon, il y a le PCF8574, du meme type que le précédant, mais gérant 8 I/O, et existant en boitier DIP. Et là, il existe en 2 "type": le PCF8574, et le PCF8574a. Ils sont strictement identique coté codage et présentation, mais leur header i2c est legerement différent. Donc, on peut en utiliser 8 de chaque par bus, soit 16 au total ( 128 entrées totales aussi )

ouep tkt je vais faire gaffe sur les numérotations ^^
ca seré des signal d'un potar ^^
en gros j'utilise le principe de la position dun potar pour faire bougé un servo en consequence
donc potar de 10Kohms
j'ai déja le code et tout
il marche pour l'arduino en lui meme donc sans extension
aprés j'aten de recevoir les tlc pour pouvoir testé avec beaucoup plus de servo mais il me faut des entrées en plus ^^

Dans ce cas, je dirais:

  • des registres de décallage type CD4094 (même principe de montage "en chaine" que le TLC5940 ), de manière a être sur de la sortie sélectionnée
  • tes potars
  • une entrée analogique

Tu relies chaque sortie des registres à un potar et toutes leurs sorties curseurs à l'entrée analogique choisie. Quand tu sélectionnes la sortie d'un des registres ( et une seule a chaque fois), elle alimente le potar et sa sortie curseur te donne la valeur analogique.

Mais ça devient une vrai usine a gaz ... Tu veux faire quoi avec tous ces servos ?...

hum non il faut que tout soit alimenté en meme temps
il faut que je recupere la sortie analogique de chaque potar en quasi temps réelle
je ne sais pas a l'avance quel potar va etre utilisé
donc voila mon soucis ^^
niveau multiplexing ca peut le faire me semble ^^

Si c'est pour lire rapidement toutes les valeurs des servos, la solution que je te propose le permet. Tout dépend de la fréquence où l'ordre de sélection de la sortie est envoyée.
Par ailleurs, tu peux utiliser 6 entrées analogiques, et diviser tes potars en 6 groupes .
6 potars ( soit un potar par groupe) ont alors leurs entrée et sortie en commun (tous sur la meme sortie de registre donc) et leur curseur a une entrée analogique
Tu vas alors 6 fois plus vite dans la lecture des données, et n'a besoin que de 3 registres (2 si tu arrives a n'utiliser "que" 96 potars :wink: )

c'est possible mais bon joré préféré du multiplexing ^^
histoire de les avoir en temps réelle xD
je sais je fait chié avec mon multiplexing mais bon
une idée de composants disposant du max d'entrée pour multiplexé ?

désolé mal vu ^^
en gros je pourré faire comme si il été en temps réelle ?
mais faut voir le taux de rafraichissement et si l'arduino arivera a suivre xD
en sachant que yora déja toute les commande de servo ( 100 pour commencé ) + les valeurs renvoyés par les potars ^^
imagine la geule du code mdr

Si tu veux du "vrai" temps reel, il existe des montages simples pour générer un signal PWM dont la valeur est définie par un potentiometre:
http://www.sonelec-musique.com/electronique_realisations_gene_pwm_001.html
Tu dépasses alors la limite des 148 servos, mais cela signifie un montage par servo ...

Cela dit, j'ai fait un code basique, pour simuler la lecture des valeurs des potentiometres, et la mise a jour de l'angle des servos. J'obtiens un temps total de 50ms par cycles, soit environ 20 lectures/écritures par secondes..

#include "Tlc5940.h"
#include "tlc_servos.h"


int analogPin = 0;

//Broche connectée sur ST_CP du 74HC595
int latchPin = 8;
//Broche connectée sur SH_CP du 74HC595
int clockPin = 12;
//Broche connectée sur DS of 74HC595
int dataPin = 11;

//Nombre total de canaux 
long nbChannel = 120; // 140 max

//Nombre total de registres
int nbRegister = nbChannel/8  + 1 ;


void setup() {
  Serial.begin(9600);    

  //Configure les broches en sortie
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  tlc_initServos();    
}

void loop() {
  unsigned long currentMillis = millis();  
  
  //séquence de comptage
  for(int selectedChannel = 0; selectedChannel < nbChannel; selectedChannel++){

    //mise à 0 de la broche latchpin maintenue basse pour toute la durée de la transmission
    digitalWrite(latchPin, LOW);

    // calcule de la sortie de registre active
    int selectedRegister = nbRegister / selectedChannel; // selection du registre
    int selectedOut = 1 << (selectedChannel % 8) ; // selection de la sortie

    // passage des registres non concernés a 0
    for (int i = 0; i < selectedRegister - 1; i++)
      shiftOut(dataPin, clockPin, LSBFIRST, 0 );   

    // activation de la sortie du registre séléctionné
    shiftOut(dataPin, clockPin, LSBFIRST, selectedOut ); 


    //remise à 1 de la broche latchpin pour signaler au CI 
    //qu'il n'est plus nécessaire d'attendre de l'information
    digitalWrite(latchPin, HIGH);


    // lecture de la valeur du potar et calcule de l'angle correspondant
    int analogValue = analogRead(analogPin);
    int angle = map(analogValue, 0, 1023, 0, 180);
    
    // mise a jour de la valeur du servo correcpondant
    tlc_setServo(selectedChannel, angle); 
  } 
    // update de tous les servos en même temps
    Tlc.update();
    
  Serial.println( millis() - currentMillis );  

}

Cela dit, il est possible d'aller plus vite, avec un cd4051 et un CD4067
Il s'agit de multiplexer qui peuvent fonctionner en entrée et sortie. Ce montage nécessite 7 pins Arduino.
Pour selectionner une des entrées/sorties de ces circuits, ils disposent de pins d'adressages ( 3 pour le cd4051 et 4 pour le CD4067). Suivant leurs valeurs (0 ou 1), on peut selectionner une I/O
Si je prend le cd4051 pour exemple, on a les pins d'adresse A, B et C:
A=0, B=0, C=0 => Entrée/sortie 0 sélectionnée
A=1, B=0, C=0 => Entrée/sortie 1 sélectionnée
A=0, B=1, C=0 => Entrée/sortie 2 sélectionnée
A=1, B=1, C=0 => Entrée/sortie 3 sélectionnée
Etc Etc

C'est donc tout bêtement du binaire

Par facilité, on va les utiliser en matrice, selon ce schéma (version de gauche ) :
http://tomekness.files.wordpress.com/2007/05/4051_examples_72dpi.jpg

Montage adapté :

Le principe est de faire 16 "groupes" de 8 potars où leur entrée est relié au CD4067 (fonctionne en sorti), et leur curseur a une entrée du cd4051 (fonctionne en entrée ). On passe des données d'adressage par manipulation de ports (bien plus rapide que digitalWrite(), mais plus complexe)

#include "Tlc5940.h"
#include "tlc_servos.h"

int analogPin = 0;

void setup() {
  Serial.begin(9600);    
  
  //initialisation des servos
  tlc_initServos();    
  
  // définition des pins 4, 5, 6 et 7 en sortie
  DDRD |= B1111000;
  // définition des pins 17, 18 et 19 en sortie
  DDRC |= B111000;

  //toutes les sorties a 0;
  PORTD = 0;
  PORTC = 0;

}

void loop() {
  unsigned long currentMillis = millis();  

  //selection d'un groupe
  for(int selectedGroupe = 0; selectedGroupe < 16; selectedGroupe++){
    //
    PORTD = selectedGroupe << 3;

    //selection d'un potar
    for (int selectedPotar = 0; selectedPotar < 8 ; selectedPotar++){
      PORTC = selectedPotar << 3;

      // lecture de la valeur du selectedPotar et calcule de l'angle correspondant
      int analogValue = analogRead(analogPin);
      int angle = map(analogValue, 0, 1023, 0, 180);

      // mise a jour de la valeur du servo correcpondant
      int selectedChannel = selectedPotar * selectedGroupe + selectedPotar ;
      tlc_setServo(selectedChannel, angle); 
    } 
  }
  // update de tous les servos en même temps
  Tlc.update();

  Serial.println( millis() - currentMillis );  

}

On tombe, avec ça, a 25ms/cycles de lecture écriture, soit 40 cycles par secondes, mais la mise en oeuvre est plus délicate

Attention, j'ai fait ces codes rapidement, il n'y a aucune certitude qu'ils fonctionnent tel quel !

perso j'opterai bien pour ton premier code la ^^
a voir ce qu'il me faut comme matos ^^
si ta un lien pour en commandé ? et une idée de câblage je pense que je vais me lancé sur celui la
merci a toi