Darduino
Blog de tutos autour de l' Attiny 85, de l'Arduino Uno. les sujets : random, CharliePlexing et leds.
dimanche 24 mai 2015
dimanche 17 mai 2015
Dé Attiny 85 en CharliePlexing moulé en résine Crystal
le résultat : gauche dernière version, à droite première version (démoulée trop tôt).
les images de ce tuto sont issues de plusieurs expériences autour du même sujet. Le sketch et les indications de montages sont le résultat des derniers essais.
Inventaire :
- Leds 5 mm (acheté par 1000 ebay chine)
- tilt sensor ebay
- Attiny85 + support ebay
- support pile bouton CR2432 ebay
- 4 Resistances 39 ohms
- Resine Crystal
- un gloss ultra brillant pour résine (amazon)
- moule 3x3x3 cube silicone
- de la pâte Playdoh
Les trucs qui n'ont pas fonctionné :
- l'interrupteur (bloqué par la résine)
- le random standard
Les étapes importantes du montage :
1. Le CharliePlexing
voir le wiki : http://en.wikipedia.org/wiki/Charlieplexing
Dans notre cas nous avons 7 leds à piloter, le nombre de pins nécessaires est de 4. la règle avec 4 pins on peut piloter : (4*4)-4 = 12 pins.
le schéma pins <-> leds est le suivant :
![]() |
---|
2. Souder les leds et respecter la forme finale.
Afin de respecter la forme finale, j'utilise une plaquette en bois percée en 5 mm. Utilisation de pâte Play-Doh pour maintenir les composants. Sur la led 4 faire attention aux croisements, le vernis à ongle peut être utilisé pour isoler. Tester et valider qu'il n'y a pas de faux contacts.
3. Souder l'Attiny 85 avec son support
Les pins 1, 2, 3 et 4 sont reliés à des résistances de 39 ohms, reliées aux 4 brins issues des leds. Le mapping avec le schéma initial est :
bleu = 1
vert = 2
rouge = 3
noir = 4
|
![]() |
Le tilt sensor est utilisé comme interrupteur. il est composé de deux pins : l'un raccordé au (+) de la pile bouton et l'autre au (+) de l'Attiny. pour comprendre le tilt sensor voir :
http://www.learningaboutelectronics.com/Articles/Tilt-sensor-circuit.php
Le (-) de la pile bouton est relié au GND de l'Attiny.
|
---|---|
|
Souder la pile bouton
C'est la dernière étape de soudure, le système complet doit tenir dans le moule (à glaçon) prévu pour le dé. Il s'agit d'un moule à glaçon de 3x3x3 cm en silicone.
Les étapes de la programmation :
- chargement du programme sur Attiny
- Programmation du charlieplexing
- Programmation du random (différent sur Attiny et pas fiable en standard).
- Programmer le lancement
1) le chargement du programme sur Attiny
Le meilleur tuto sur le sujet est sur le lien suivant : http://highlowtech.org/?p=1695
et faire le test avec un programme simple (voir blink).
Pour ma part, j'utilise un arduino pour programmer l'Attiny.
Pour ma part, j'utilise un arduino pour programmer l'Attiny.
il s'agit d'un shield arduino, connecté pour charger l'attiny.
A savoir, la vitesse par défaut 1mhz de l'Attiny n'est pas suffisante pour un affichage fluide.
A 8 mhz c'est parfait. pour changer la vitesse, il faut choisir l'attiny 85 à 8mhz.
avant de téléverser le programme, il faut graver la sequence d'initialisation pour changer la vitesse :
A savoir, la vitesse par défaut 1mhz de l'Attiny n'est pas suffisante pour un affichage fluide.
A 8 mhz c'est parfait. pour changer la vitesse, il faut choisir l'attiny 85 à 8mhz.
avant de téléverser le programme, il faut graver la sequence d'initialisation pour changer la vitesse :
2) Programmation Charlieplexing
les indispensables :
une table pour identifier chaque led : (1 pour pole +, 2 pour -, 3 pour inactif).
On initialise un tableau d'équivalence pour piloter chaque led.
On initialise un tableau d'équivalence pour piloter chaque led.
// 1= output high // 2= output low // 3= input low int tabled[7][4] ={ //row 1 2 3 4 {1,2,3,3}, //led 1 {2,1,3,3}, //led 2 {1,3,2,3}, //led 3 {3,1,2,3}, //led 4 {3,3,1,2}, //led 5 {3,3,2,1}, //led 6 {3,2,3,1}, //led 7 };
l'affichage d'une led se fait en déterminant la polarité des pins :
switch (tabled[numled][i]) {
case 1 :
pinMode(pin_switch + i, OUTPUT);
break;
case 2 :
pinMode(pin_switch + i, OUTPUT);
break;
case 3 :
pinMode(pin_switch + i, INPUT);
break;
default :
break;
switch (tabled[numled][i]) {
case 1 :
digitalWrite(pin_switch + i, HIGH);
break;
case 2 :
digitalWrite(pin_switch + i, LOW);
break;
case 3 :
digitalWrite(pin_switch + i, LOW);
break;
default :
break;
3) La programmation du random
La fonction randomSeed avec la lecture du port analogique retourne la même série de valeurs.
j'ai utilisé deux techniques pour m'assurer un random parfait :
j'ai utilisé deux techniques pour m'assurer un random parfait :
4) Le programme
Chaque chiffre du dé correspond à un ensemble de leds allumées. la clé est une table décrivant cette correspondance.
/* Charliplexing 7 LEDs dice description : 1 5 2 4 6 3 7 -------------------------------------------------------------------------------- Row 1 (R1): Arduino Pin 10 or ATTINY Pin 1 Row 2 (R2): Arduino Pin 11 or ATTINY Pin 2 Row 3 (R3): Arduino Pin 12 or ATTINY Pin 3 Row 4 (R4): Arduino Pin 13 or ATTINY Pin 4 See pin_switch var Arduino vs Attiny -------------------------------------------------------------------------------- variable pinMode state L OUTPUT LOW H OUTPUT HIGH Z INPUT LOW --------------------------------------------------------------------------------- */ #define ATTINY_MODE 1 // Comment for ARDUINO //#define TEST_MODE 1 // Comment for production version //#define ATTINYfd_1 1 //Attiny à 1 mhz #define ATTINYfd_8 1 //Attiny à 8 mhz //#define ATTINYfd_20 1 //Attiny à 20 mhz// Library #include < EEPROM.h > // save data for random #include < Entropy.h > // GNU random const int coef = 5; #if !defined (ATTINY_MODE) //ARDUINO const int temps_affiche = 500; //display refresh rate = 500 for arduino 150 for ATTINY const int temps_une_led = 30; // display repet light per led = 30 for arduino and 5 for ATTINY const int pin_switch = 10; // match pin between ATTINY and arduino #endif #if defined(ATTINYfd_1) const int temps_affiche = 150; //display refresh rate = 500 for arduino 150 for ATTINY const int temps_une_led = 24; // display repet light per led = 30 for arduino and 5 for ATTINY const int pin_switch = 1; // match pin between ATTINY and arduino #endif #if defined(ATTINYfd_8) const int temps_affiche = 300; //display refresh rate = 500 for arduino 150 for ATTINY const int temps_une_led = 100; // display repet light per led = 30 for arduino and 5 for ATTINY const int pin_switch = 1; // match pin between ATTINY and arduino #endif // dice number To led matrix byte dede[8][7] ={ //3 4 5 6 7 8 9 {0,0,0,0,0,0,0}, // 0 nothing {0,0,0,1,0,0,0}, // 1 {0,0,1,0,1,0,0}, // 2 {1,0,0,1,0,0,1}, // 3 {1,0,1,0,1,0,1}, // 4 {1,0,1,1,1,0,1}, // 5 {1,1,1,0,1,1,1}, // 6 {1,1,1,1,1,1,1}, // 7 all }; // 1= output high // 2= output low // 3= input low int tabled[7][4] ={ //row 1 2 3 4 {1,2,3,3}, //led 1 {2,1,3,3}, //led 2 {1,3,2,3}, //led 3 {3,1,2,3}, //led 4 {3,3,1,2}, //led 5 {3,3,2,1}, //led 6 {3,2,3,1}, //led 7 }; void setup() { uint8_t random_byte; unsigned int id = EEPROM.read(0); Entropy.Initialize(); if (Entropy.available()) { randomSeed(id); id = Entropy.random(); } EEPROM.write(0, id); #if !defined (ATTINY_MODE) Serial.begin (115200); Serial.println ("setup"); Serial.println ("id : "); Serial.print (id+1); Serial.println(""); #endif #if !defined (TEST_MODE) Lancedes(); #endif } void loop() { #if defined (TEST_MODE) afficheled(0,temps_affiche*coef); afficheled(1,temps_affiche*coef); afficheled(2,temps_affiche*coef); afficheled(3,temps_affiche*coef); afficheled(4,temps_affiche*coef); afficheled(5,temps_affiche*coef); afficheled(6,temps_affiche*coef); affichede(1, temps_affiche); affichede(2, temps_affiche); affichede(3, temps_affiche); affichede(4, temps_affiche); affichede(5, temps_affiche); affichede(6, temps_affiche); #endif } // ***** affiche led ***** void afficheled(int numled,int temps) { int i,j; //boucle de repetition nombre de temps //par defaut 1 if (numled > 6 || numled < 0) affiche_erreur (1); for(i=0;i < 4;i++) // changement des pins arduino { switch (tabled[numled][i]) { case 1 : pinMode(pin_switch + i, OUTPUT); break; case 2 : pinMode(pin_switch + i, OUTPUT); break; case 3 : pinMode(pin_switch + i, INPUT); break; default : break; } } if (temps ==0) temps=1; for (j=0;j < temps;j++) { for(i=0;i < 4;i++) // changement des pins arduino { switch (tabled[numled][i]) { case 1 : digitalWrite(pin_switch + i, HIGH); break; case 2 : digitalWrite(pin_switch + i, LOW); break; case 3 : digitalWrite(pin_switch + i, LOW); break; default : break; } } } } // ***** set up leds corresponding the number ***** void affichede(int n ,int temps) { int i,j; int tp_led , tp_boucle; if (n > 6 || n < 1) affiche_erreur (2); tp_led = temps_une_led / n; tp_boucle= temps; //boucle de repetition nombre de temps //par defaut 1 if (tp_boucle ==0) tp_boucle=1; for (j=0;j < tp_boucle;j++) { for(i=0;i < 7;i++) if (dede[n][i]==1) afficheled(i,tp_led); } } void affiche_erreur(int erreur) { int i,j; switch (erreur) { case 1 : // erreur affiche led for (i=0;i < 10;i++) for (j=1;j < 8;j++) afficheled(j,temps_affiche); break; case 2 : // erreur affichede for (i=0;i < 10;i++) for (j=1;j < 4;j++) afficheled(j,temps_affiche); break; default : break; } } void Lancedes() { int n,i; int loto1; // résultat random du nombre de tour de dès avant résultat int maxi =15; // maxi du random du nombre de tour de dès avant résultat int mini = 5; // mini du random du nombre de tour de dès avant résultat int delay1; // temps d'affichage entre deux tours avant final int resultat = 10; // résultat intermediaire int ancienresultat = 10; // empeche deux fois le meme nombre loto1 = Entropy.random(mini,maxi); for (n=0; n < loto1;n++) { while (resultat == ancienresultat) resultat=Entropy.random(1,7); ancienresultat=resultat; delay1=(temps_affiche)/(loto1-n); affichede(resultat,delay1); } #if !defined (ATTINY_MODE) Serial.print ("resultat final :"); Serial.print(resultat); Serial.print(" nb resul inter : "); Serial.println(loto1); #endif affichede(resultat,temps_affiche*100); }
Le moulage en résine :
Avant de mouler l'ensemble, il faut protéger l'emplacement de la pile bouton pour pouvoir la changer.
j'utilise la pâte Playdoh, mais le résidu n'est pas évident à retirer après.
Le séchage est long > 3 jours, 1 semaine est recommandé. il est important de ne pas démouler avant l'heure.
Après séchage, si le dé n'est pas entièrement transparent, utilisez le vernis Gloss.
jeudi 31 juillet 2014
Deux dés Arduino / Conception / Page 2
Tutoriel pour deux dés
retour conception page 1
Organisation des leds :
Avec 2 dés, il faut gérer l'affichage de 14 leds avec seulement 7 sorties Arduino.
Le dispositif est similaire avec une double connexion des 7 pins sur les leds symétriques des deux dés.
Nous utilisons deux transistors NPN(Explication composant pnp) avec 3 pattes, qui laissent passer le courant aux extrémités lorsque nous envoyons du courant sur la patte centrale. Nous raccordons aux sorties 10 et 11 chacun des transistors. toutes les cathodes (-) d'un dés sont rattachées à une patte extérieur du composant NPN. la patte libre est connectée au GND (-).
Pour afficher un chiffre différent, on éteint un dés et on allume l'autre ensuite on alterne. Ce fonctionnement impose un affichage, continu en alternance de chaque dés.
Le dispositif est similaire avec une double connexion des 7 pins sur les leds symétriques des deux dés.
Nous utilisons deux transistors NPN(Explication composant pnp) avec 3 pattes, qui laissent passer le courant aux extrémités lorsque nous envoyons du courant sur la patte centrale. Nous raccordons aux sorties 10 et 11 chacun des transistors. toutes les cathodes (-) d'un dés sont rattachées à une patte extérieur du composant NPN. la patte libre est connectée au GND (-).
Pour afficher un chiffre différent, on éteint un dés et on allume l'autre ensuite on alterne. Ce fonctionnement impose un affichage, continu en alternance de chaque dés.
le script de fonctionnement pour les deux dés est le suivant :
//organisation des dès avec sorties :
// 6 4
// 7 5 3
// 8 2
int butPin = 9; // bouton
int transi1 = 10; // transistor 1
int transi2 = 11; // transistor 2
byte dede[8][7] ={
//2 3 4 5 6 7 8
{0,0,0,0,0,0,0}, // 0 rien
{0,0,0,1,0,0,0}, // 1
{1,0,0,0,1,0,0}, // 2
{0,0,1,1,0,0,1}, // 3
{1,0,1,0,1,0,1}, // 4
{1,0,1,1,1,0,1}, // 5
{1,1,1,0,1,1,1}, // 6
{1,1,1,1,1,1,1}, // 7 tout
};
byte resultatloto[2][30]; // remplissage du résultat des deux dès lancés
int resultdesun=0;
int resultdesdeux=0;
int attenteboucle = 5; //10 en standard = calcul la vitesse de changement
void setup()
{
int i;
for (i=2; i<9; i++) pinMode(i,OUTPUT); // led pins
pinMode(transi1,OUTPUT);
pinMode(transi2,OUTPUT);
pinMode(butPin,INPUT);
digitalWrite(butPin, HIGH); // indispensable pour la lecture du switch proto
// start/stop button
turnOnNumber(0);
randomSeed(analogRead(0)); // initialise le random
Serial.begin(9600);
}
void loop()
{
Lancedes();
}
void Lancedes()
{
int n,i;
int loto1;
int loto2;
int maxi =15;
int delay1;
int resultat = 10;
int ancienresultat = 10; // empeche deux fois le meme nombre
// test bouton si actionné
if (digitalRead(butPin) == HIGH)
{
// Calcul et chargement du résultat dans resultatloto (tableau des resultats)
randomSeed(analogRead(0)); // initialise le random
loto1 = random(5,maxi);
randomSeed(analogRead(1)); // initialise le random
loto2 = random(5,maxi);
for (n=0; n < maxi;n++)
{
while (resultat == ancienresultat) resultat=random(1,7);
ancienresultat=resultat;
if (n<loto1) resultatloto[0][n]=resultat;
else resultatloto[0][n]=0;
}
// resultat final sur premier dés
resultdesun = resultatloto[0][loto1-1];
for (n=0; n < maxi ;n++)
{
while (resultat == ancienresultat) resultat=random(1,7);
ancienresultat=resultat;
if (n<loto2) resultatloto[1][n]=resultat;
else resultatloto[1][n]=0;
}
// resultat final sur deuxième dés
resultdesdeux = resultatloto[1][loto2-1];
// affichage des résultats
if (loto1<loto2) maxi = loto2; // determine la boucle max pour les deux dès
else maxi = loto1;
// boucle avec affichage de plus en plus lent
for (n=0; n<maxi; n++)
{
delay1=(n+1) * 2;
for (i=0;i<delay1;i++)
{
if (resultatloto[0][n] != 0)
{
resultdesun = resultatloto[0][n];
}
else
{
resultdesun = resultatloto[0][loto1-1];
}
if (resultatloto[1][n]!=0)
{
resultdesdeux = resultatloto[1][n];
}
else
{
resultdesdeux = resultatloto[1][loto2-1];
}
// Serial.println(resultdesun);
// Serial.println(resultdesdeux);
digitalWrite(transi1,HIGH);
digitalWrite(transi2,LOW);
turnOnNumber(resultdesun);
delay(attenteboucle);
digitalWrite(transi2,HIGH);
digitalWrite(transi1,LOW);
turnOnNumber(resultdesdeux);
delay(attenteboucle);
}
}
}
digitalWrite(transi1,HIGH);
digitalWrite(transi2,LOW);
turnOnNumber(resultdesun);
delay(attenteboucle);
digitalWrite(transi2,HIGH);
digitalWrite(transi1,LOW);
turnOnNumber(resultdesdeux);
delay(attenteboucle);
}
// ***** set up leds corresponding the number *****
void turnOnNumber(int n)
{
int i;
for(i=0;i<7;i++) //n en décalage de 1 lié à la gestion tableau qui commence à0
{
if (dede[n][i]==0) digitalWrite(i+2, LOW);
else digitalWrite(i+2, HIGH);
}
}
lundi 28 juillet 2014
Deux dés Arduino / Conception / Page 1
DEUX DES ARDUINO / CONCEPTION
Tutorial pour un dés seul
Organisation des leds :
Un dé est composé de 7 leds. Chaque led est reliée à une sortie Arduino.Voila à quoi ça ressemble :
Ce dispositif permet d'afficher un dé. Voici l'exemple image et script qui fonctionne avec ce dispositif:
Dispositif Arduino 1 dé
Sketch Arduino Uno 1 dé
/****************************************************************************************
------------------------------------- Programme 1 dés ----------------------------------------------
Déclaration des variables
ButPin pour le bouton
etat pour le resultat du bouton
dede est un tableau contenant les positions
des 7 leds pour toutes les combinaisons d'un dés
organisation des dès avec sorties :
led-pin relationships: 6 4
7 5 3
8 2
*****************************************************************************************/
int butPin = 9;
int etat =0;
byte dede[8][7] ={
//2 3 4 5 6 7 8 numéro des pins associés aux leds
{0,0,0,0,0,0,0}, // 0 rien
{0,0,0,1,0,0,0}, // 1
{1,0,0,0,1,0,0}, // 2
{0,0,1,1,0,0,1}, // 3
{1,0,1,0,1,0,1}, // 4
{1,0,1,1,1,0,1}, // 5
{1,1,1,0,1,1,1}, // 6
{1,1,1,1,1,1,1}, // 7 tout
};
// initialisation partie du programme qui s'execute une fois
void setup()
{
int i; // utilisé pour la boucle qui suit
// initialisation des pins 2 à 8 pour les leds
for (i=2; i<9; i++) pinMode(i,OUTPUT); // led pins
pinMode(butPin,INPUT); // initialisation du bouton switch
turnOnNumber(0); // extinction des leds
randomSeed(analogRead(0)); // initialise le random astuce pour avoir un vrai random
Serial.begin(9600);
}
void loop()
{
int n;
int loto;
int resultat = 10;
int ancienresultat = 10; // empeche deux fois le meme nombre
// lecture du bouton
etat= digitalRead(butPin);
if ( etat == HIGH)
{
turnOnNumber(7);
delay(500);
turnOnNumber(0);
delay(500);
loto = random(5,30);
for (n=2; n <loto;n++)
{
while (resultat == ancienresultat) resultat=random(1,7);
turnOnNumber(resultat);
ancienresultat=resultat;
delay(500-((loto-n)*20));
}
}
}
// ***** set up leds corresponding the number *****
void turnOnNumber(int n)
{
int i;
for(i=0;i<7;i++) //n en décalage de 1 lié à la gestion tableau qui commence à0
{
if (dede[n][i]==0) digitalWrite(i+2, LOW);
else digitalWrite(i+2, HIGH);
}
} //******************************************* FIN DU PROGRAMME ********************************
La suite affichage de deux dés
Inscription à :
Articles (Atom)