Étape 4: programmation
Comme nous l’avons dit à l’étape 3, nous recommandons fortement de regarder cette vidéo : http://www.youtube.com/watch?v=FehBLNHMlfo. Il montre comment effectivement connecter l’Arduino à la TLC en premier lieu, est un excellent endroit pour commencer. En ce qui concerne la programmation, nous diviser le travail entre deux Arduinos et les ont poussés à communiquer. Les programmes suivants sont simplement le cadre pour un produit final. L’Arduino pilote de LED est terminée, tandis que le contrôleur est simplement un shell pour tout ce que vous voulez programmer le Conseil à faire :Driver de LED Arduino :
Texas Instruments TLC 5940 avec Arduino
Avec l’aide de www.kevindarrah.com
#include < SPI.h > //Serial Peripheral Interface Library
Inclure la Lib Tranfer facile
#include < EasyTransfer.h >
EasyTransfer ET ;
Cela doit être exactement la même chose sur l’autre Arduino
struct RECEIVE_DATA_STRUCTURE {}
int LEDGrid [18] ;
};
int LEDData [18] ;
Matrice RECEIVE_DATA_STRUCTURE ;
ch de l’octet = 0, chbit = 0, spibit = 0, spibyte = 0; / / variables utilisées par routine void tlc
int SINData ; //variable utilisé pour déplacer des données vers le TLC
transferbyte Byte [48];// octets qui sont envoyés à la tlc5940 via SPI
48 car 16 circuits @ 12bits donne 384bits, 384/8 = 48 octets, 12 bits à 8 bit conversion
octet DCvalue [32]; / / 0-63, 6 DOT Correction octets
int i, j, k, l, m, n ; misc variables
int count = 0 ;
//*******************************************************************************************
//*******************************************************************************************
void setup() {/ / MAIN d’installation principal d’installation SETUP installation principale MAIN SETUP
ET.begin(details(matrix), & série) ;
pinMode (sortie 7,); //XLAT
pinMode (sortie 3,); //OSC2B GSCLK
pinMode (sortie 4); //VPRG
pinMode (sortie 11,); //MOSI données
pinMode (sortie 13,); //SPI horloge
Broche 5 est l’essai à blanc
Mettre en place le SPI
SPI.setBitOrder (MSBFIRST); //Most Bit significatif première
SPI.setDataMode(SPI_MODE0); / / Mode 0 Rising edge de données, gardez horloge faible
SPI.setClockDivider (SPI_CLOCK_DIV4); //Run les données à 16MHz/4-4MHz
pour (i = 0; i < 48; i ++) //clear les données d’échelle de gris
transferbyte [i] = 0 ;
pour (i = 0; j’ai < 32; i ++) //set des données de Correction de la Dot à max (décimal pour 6 bit 63)
DCvalue [i] = 63 ;
Serial.Begin (9600); //debugging ?
mettre en place la Correction DOT
DotCorrection(); / / sub routine aide à
noInterrupts(); / / définir les compteurs, alors n’allez pas dans les interruptions
TCCR2A = B00010010 ; //Timer 2 la valeur comparer activant/désactivant Mode broche 5 à 8MHz, Arduino Digital 3
MINUTERIE 2 EST GSCLCK
Prédiviseur minuterie 2 définie sur 1, 16/1 = 16 MHz, mais alterne broche 5 autre chaque cycle, 8MHz
TCCR2B = B00000001 ;
TCCR1A = B00000000 ; //Timer 1 n’est pas activer/désactiver quoi que ce soit, utilisé pour le comptage
Prédiviseur minuterie 1 la valeur Fclk/256
Pourquoi ? Il faut compter 4096 impulsions sur Timer 2 - broche 5
8 MHz = 1 impulsion chaque 125ns--4096 impulsions auraient besoin 512us
Minuterie 1 tourne à 16MHz/256 = 62,5 kHz, nous avons besoin d’un match à chaque 512us
Fondamentalement, je peux obtenir une interruption à appelé chaque 512us, donc...
Je dois exécuter Timer 2 @ 8MHz pour 512us obtenir 4096 impulsions
Je ne peux pas compter ces directy impulsions (trop vite), donc
Je vais compter à l’aide de la minuterie 1, qui en fait un décompte chaque 16us
Le compteur commence à 0, donc nous allons le définir à 31 pour obtenir une interruption après 512us
TCCR1B = B00001100 ; //Mode=CTC avec OSCR1A = haut et 256 comme le Prédiviseur
Masquer l’ensemble vers le haut, appellera ISR (interrompre Service Routine) pour comparer match sur A
TIMSK1 = B00000010 ;
Ce sont les valeurs correspondantes pour les compteurs
0 signifie ici qu'il correspondra à un cycle de l’horloge/diviseur
OCR1A = 31 ; //to obtenir notre interruption de 512us
interrupts(); / / le coup d’envoi des minuteries !
attachInterrupt (0, mise à jour, en hausse) ;
48
pour (i = 0; j’ai < 48; i ++) //wipe les données dans tlc
TLC (i, 0); / / c’est comment vous mettre à jour les LEDs, tlc est une sous-routine avec deux entrées
Canal de TLC(Channel, value) dans ce cas est de 0-32 et la valeur est 0-4095 rapport cyclique
4095 est 100 % sur
pinMode (sortie 5,); //BLANK, nous avons mis cette broche ici, donc il reste dans une haute impédance
indiquer tout au long de l’installation, sinon les voyants deviennent fous ! même si vous écrivez cette haute
pour (int i = 0; i < 22; i ++) {}
TLC((i*3),4095) ;
}
Delay(100) ;
pour (int i = 0; i < 22; i ++) {}
TLC((i*3),0) ;
}
pour (int i = 0; i < 22; i ++) {}
TLC((i*3)+1,4095) ;
}
Delay(100) ;
pour (int i = 0; i < 22; i ++) {}
TLC((i*3)+1,0) ;
}
pour (int i = 0; i < 22; i ++) {}
TLC((i*3)+2,4095) ;
}
Delay(100) ;
pour (int i = 0; i < 22; i ++) {}
TLC((i*3)+2,0) ;
}
}
void loop() {/ / principal MAIN boucle boucle principale boucle boucle boucle de MAIN MAIN
updateLED() ;
Ce serait un bon endroit pour mettre les animations dû au fait que vous pouvez utiliser toutes
des combos couleur, pas seulement 10 ou plus.
}
{ISR(TIMER1_OVF_vect)}
} / / Cours limite drapeau interrompre vous devez cela même si vous ne l’utilisez pas
{ISR(TIMER1_COMPB_vect)}
} / / Comparer B - non utilisé
ISR(TIMER1_COMPA_vect) {/ / Interrupt pour compter les 4096 impulsions sur GSLCK
PORTD | = 1 << 5; / / écriture vierge haute pour réinitialiser le compteur de 4096 dans le TLC
PORTD | = 1 << 7; / / écriture haute XLAT de verrouillage dans les données du dernier flux de données
PORTD & = ~ (1 << 7); //XLAT pouvez aller faible maintenant
PORTD & = ~ (1 << 5); //Blank passe bas pour lancer le prochain cycle
SPI.end (); //end le SPI, donc nous pouvons écrire sur la broche horloge
PORTB | = 1 << 5; / / SPI horloge pin pour lui donner le compte supplémentaire
PORTB & = ~ (1 << 5); / / la fiche technique dit vous avez besoin de cela pour une raison quelconque ?
SPI.begin(); / / start le SPI vers le haut
pour (SINData = 95 ; SINData > = 0 ; SINData--) {/ / envoie les données !
SPI.transfer(transferbyte[SINData]); / / port le SPI ne comprend qu’octets-8 bits de large
Le TLC a besoin de 12 bits pour chaque canal, 64 canaux de 12 bits fois donne 768 bits
768/8 = 96 octets, 0-95
}
Count ++ ;
}
void updateLED() {}
ET.receiveData() ;
pour (int i = 0; i < 18; i ++) {}
Imprimer ce qui se passe
Serial.Print (matrice. LEDGrid[i]) ;
Serial.Print(",") ;
Commutateur qui reçoit les données de 0 à 10 et qui convertit en couleurs.
commutateur (matrice. {LEDGrid[i])}
case 0: / / OFF
TLC(((3*i)),0) ;
TLC(((3*i)+1),0) ;
TLC(((3*i)+2),0) ;
rupture ;
cas 1: / / rouge
TLC(((3*i)),4095) ;
TLC(((3*i)+1),0) ;
TLC(((3*i)+2),0) ;
rupture ;
case 2: / / vert
TLC(((3*i)),0) ;
TLC(((3*i)+1),0) ;
TLC(((3*i)+2),4095) ;
rupture ;
case 3: / / bleu
TLC(((3*i)),0) ;
TLC(((3*i)+1),4095) ;
TLC(((3*i)+2),0) ;
rupture ;
case 4: / / violet
TLC(((3*i)),2000) ;
TLC(((3*i)+1),4095) ;
TLC(((3*i)+2),0) ;
rupture ;
cas 5: / / TEAL
TLC(((3*i)),0) ;
TLC(((3*i)+1),4095) ;
TLC(((3*i)+2),4095) ;
rupture ;
case 6: / / jaune
TLC(((3*i)),3000) ;
TLC(((3*i)+1),0) ;
TLC(((3*i)+2),4095) ;
rupture ;
cas 7: / / rose
TLC(((3*i)),4095) ;
TLC(((3*i)+1),3500) ;
TLC(((3*i)+2),3500) ;
rupture ;
cas 8: / / ORANGE
TLC(((3*i)),2232) ;
TLC(((3*i)+1),0) ;
TLC(((3*i)+2),1108) ;
rupture ;
9-affaire: / / LIGHT BLUE
TLC(((3*i)),1000) ;
TLC(((3*i)+1),4095) ;
TLC(((3*i)+2),2000) ;
rupture ;
10-affaire: / / blanc
TLC(((3*i)),1500) ;
TLC(((3*i)+1),4095) ;
TLC(((3*i)+2),4095) ;
rupture ;
par défaut :
TLC(((3*i)),100) ;
TLC(((3*i)+1),200) ;
TLC(((3*i)+2),200) ;
}
}
Serial.println("") ;
}
void tlc (canal int, int valeur) {/ / TLC à TLC de mise à jour de mise à jour de TLC à TLC de mise à jour Update
Cette routine doit se passer aussi vite que possible!!!
if(value>4095)
valeur = 4095 ;
if(Value<0)
valeur = 0 ;
Nous avons besoin de convertir la valeur de 12 bits dans un octet de 8 bits, le SPI ne peut pas écrire 12bits
Nous comprendre où dans tous les octets à écrire, donc nous n’avons pas de perdre du temps
mise à jour de tout
12 bits en octets, un début de 12 bits sera soit à 0 ou 4 dans un octet
spibit = 0 ;
Si //if (bitRead (canal, 0)) la lecture de la valeur est impair, le début est à un 4
spibit = 4 ;
Il s’agit d’une simplification du canal * 12 bits/8 bits
spibyte = int (canal * 3/2); //this attribue automatiquement l’octet, la valeur 12 bits commence dans
pour (chbit = 0; chbit < 12 ; chbit ++, spibit ++) {/ / start dès où ira la mise à jour
if(spibit==8) {//during le cycle de 12 bits, la limite de l’octet sera atteint
spibyte ++; //roll dans l’octet suivant
spibit = 0; //reset le bit compter dans l’octet
}
Si (bitRead (value, chbit)) //check la valeur de 1 et de 0
bitSet (transferbyte [spibyte], spibit); //transferbyte, c’est ce qui est écrit à la TLC
d’autre
bitClear (transferbyte [spibyte], spibit) ;
} //0-12 bit boucle
}
void DotCorrection() {}
PORTD | = 1 << 4; //VPRG DC mode haute
spibyte = 0; //reset nos variables
spibit = 0 ;
pour (ch = 0; ch < 32; ch ++) {/ / 6 bit un morceau x 32 sorties
pour (chbit = 0; chbit < 6; chbit ++) {}
{if(spibit==8)}
spibyte ++ ;
spibit = 0 ;
}
Si (bitRead (DCvalue [ch], chbit)) //all 6 bits
bitSet (transferbyte [spibyte], spibit); //setting bit 7 de l’octet de transfert
d’autre
bitClear (transferbyte [spibyte], spibit) ;
spibit ++ ;
}
}
SPI.begin() ;
pour (j = spibyte; j > = 0; j--) {}
SPI.transfer(transferbyte[j]) ;
}
PORTD | = 1 << 7 ;
PORTD & = ~ (1 << 7) ;
PORTD & = ~ (1 << 4); //VPRG est bon pour aller en mode normal, basse
}
Contrôleur Arduino :
/*
Données lues :
0: ARRÊT VRAIMENT MAINTENANT
1: IDK ROUGE
2: JOUER VERT
3: BLUE NOTE
4: PURPLE BAR
5: TEAL -
6: JAUNE -
7: ROSE -
8: ORANGE -
9: L-BLEU -
10 : BLANC -
DEF:TEST-
*/
L’ensemble de données ci-dessus correspond à des données de couleur définies dans l’Arduino pilote de LED
Inclure la Lib Tranfer facile
#include < EasyTransfer.h >
EasyTransfer ET ;
Cela doit être exactement la même chose sur l’autre Arduino
struct SEND_DATA_STRUCTURE {}
int LEDGrid [18] ;
};
Matrice SEND_DATA_STRUCTURE ;
//----------------------------Variables-------------------------
int buttonRaw [6] [3] ;
int LEDData [6] [3] ;
//--------------------------------------------------------------
void setup() {}
Commencer la série sur 9600 - débogage
Serial.Begin(9600) ;
EasyTransfer commence
ET.begin(details(matrix), & série) ;
Epingles de 7-9 sont utilisés pour les fils de bouton
pinMode (7, sortie) ;
pinMode (sortie 8) ;
pinMode (sortie 9) ;
Définir haut-parleur port - pas effectivement utilisée dans ce programme de shell
pinMode (sortie 2) ;
buttonCheck() ;
}
//------------------------------Setup---------------------------
void loop() {}
buttonCheck() ;
Update() ;
Ajouter réellement programme dans cet espace. Lire les valeurs de bouton, définissez le
lumières et sons. Son tout à vous. C’est le cadre
tout ce que vous voudrez.
}
//-----------------------------Programs--------------------------
Mise à jour : ajoutez light réel envoi mécanique. Il suffit de mettre LEDData [x] [y]
coordonnée de tableau qui correspond à la lumière appropriée pour un certain nombre
de 0 à 10, tel que défini au sommet de ce programme.
{} void update()
pour (int y = 0; y < 3; y ++) {}
pour (int x = 0; x < 6; x ++) {}
matrice. LEDGrid [gridCount] = LEDData [x] [y] ;
gridCount ++ ;
}
Delay(5) ;
}
gridCount = 0 ;
ET.sendData() ;
}
//-------------------
Cocher le bouton : vérifie les valeurs de bouton et enregistre ces données brutes dans un tableau.
L’ordre va de (0,0)-(6,0), puis (0,1)-(6,1), etc. Ces données peuvent
être utilisé pour activer/désactiver des valeurs, etc..
void buttonCheck() {}
pour (int y = 0; y < 3; y ++) {}
digitalWrite(7+y,HIGH) ;
pour (int x = 0; x < 6; x ++) {}
buttonRaw [x] [y] = analogRead (x) ;
}
digitalWrite(7+y,LOW) ;
}
}