Étape 8: logiciel
#define DRAW_PWM_DELAY 10
#define MAX_INTENSITY 8
* LED Driver
columnPins Byte = {2,3,4,6,7,8,11,12,13} ; connexions de matrice colonnes
levelPins Byte = {5,9,10} ; connexions des niveaux de matrice
Initialise le pilote LED (montre broche modes et désactive toutes les LED)
void ledInit() {}
pour (octet i = 0; i < 9; i ++) {}
pinMode (columnPins [i], sortie) ;
digitalWrite (columnPins [i], faible) ;
}
pour (octet i = 0; i < 3; i ++) {}
pinMode (levelPins [i], sortie) ;
digitalWrite (levelPins [i], HIGH) ;
}
}
allumer les LEDs unique
causes autres LED à lumière vers le haut si le pilote n’est pas dans l’état initialisé
(vous ne pouvez pas adresser toutes les 27 LED avec seulement 12 broches à la fois)
Sub ledOn (colonne byte, octet niveau) {}
digitalWrite (columnPins [colonne], HIGH) ;
digitalWrite (levelPins [niveau], faible) ;
}
même chose que ledOn
void ledOff (colonne byte, octet niveau) {}
digitalWrite (columnPins [colonne], faible) ;
digitalWrite (levelPins [niveau], HIGH) ;
}
/********************************************************************************
* Base Drawing API (tampon de voxel, système de coordonnées cartésiennes, etc..)
********************************************************************************/
mémoire tampon d’octets [27] ; tampon de voxel
dessine le tampon de voxel (en ignorant les intensités)
n’importe quel voxel > 1 s’allume la LED correspondante
{} void draw (n octets)
int col, lvl ;
pour (t octets = 1; t < n; t ++) {}
pour (octet i = 0; i < 27; i ++) {}
Si (buffer[i]) {}
Col = i / 3 ;
lvl = i 3 %;
ledOn(col,lvl) ;
delayMicroseconds(DRAW_PWM_DELAY) ;
ledOff(col,lvl) ;
} else {}
delayMicroseconds(DRAW_PWM_DELAY) ;
}
}
}
}
{} void draw()
Draw(1) ;
}
dessine le tampon de voxel (prend en compte des intensités)
Cette fonction utilise un logiciel PWM et est environ 128 fois plus lente
que le binaire dessiner fonction
void drawPwm() {}
int col, lvl ;
pour (t octets = 1; t < = 128; t ++) {}
pour (octet i = 0; i < 27; i ++) {}
Si (! () t% (1 < <(8-buffer[i]))) {
Col = i / 3 ;
lvl = i 3 %;
ledOn(col,lvl) ;
delayMicroseconds(DRAW_PWM_DELAY) ;
ledOff(col,lvl) ;
} else {}
delayMicroseconds(DRAW_PWM_DELAY) ;
}
}
}
}
efface le tampon de voxel
void clearBuffer() {}
pour (octet i = 0; i < 27; i ++) {}
tampon [i] = 0 ;
}
}
remplit la mémoire tampon de voxel
void fillBuffer (valeur d’octet) {}
pour (octet i = 0; i < 27; i ++) {}
tampon [i] = value ;
}
}
Récupère les valeurs de tampon de voxel (à l’aide des coordonnées cartésiennes)
getVoxel octet (char x, y de char, char z) {}
octet j’ai = 9 * x - y + 3 * z + 13 ;
retour de tampon [i] ;
}
définit les valeurs de tampon de voxel (à l’aide des coordonnées cartésiennes)
void setVoxel (char char y, x, valeur byte, char z) {}
octet j’ai = 9 * x - y + 3 * z + 13 ;
Si (i > = 0 & & j’ai < = 27) {}
tampon [i] = value ;
}
}
interpole points arbitraires entre les voxels
point de consigne nulle (float x, float y, float z, valeur d’octet) {}
char xint = x > 0 ? 1:-1 ;
Chantal de char = y > 0 ? 1:-1 ;
char zint = z > 0 ? 1:-1 ;
Interpolate(x,y,z,value,0,0,0) ;
Interpolate(x,y,z,value,0,yint,0) ;
Interpolate(x,y,z,value,0,0,Zint) ;
Interpolate(x,y,z,value,0,yint,Zint) ;
Interpolate(x,y,z,value,xInt,0,0) ;
Interpolate(x,y,z,value,xInt,yint,0) ;
Interpolate(x,y,z,value,xInt,0,Zint) ;
Interpolate(x,y,z,value,xInt,yint,Zint) ;
}
void interpoler (float x, float y, float z, valeur byte, char xint, Brigitte char, char zint) {}
flotteur d = sqrt(pow(xint-x,2) + pow(yint-y,2) + pow(zint-z,2)) ;
octet j’ai = 9 * xint - Brigitte + 3 * zint + 13 ;
Si (i > = 0 & & j’ai < = 27) {}
tampon [i] += (valeur * (1D)) ;
}
}
/********************************************************************************
* Quelques démos
********************************************************************************/
Jeux de broches États manuellement (pilote non utilisé)
void demoLowLevel() {}
ledInit() ;
se passe rien de visible ici
pour (octet lvl = 0; lvl < 3; lvl ++) {}
digitalWrite (levelPins [lvl], faible) ;
}
maintenant, nous sélectionnons des colonnes entières
pour (cycle octets = 0; cycle < 2; cycle ++) {}
pour (col octets = 0; col < 9; col ++) {}
digitalWrite (columnPins [col], cycle % 2 == 0 ? HAUT : BAS) ;
Delay(100) ;
}
}
ledInit() ;
se passe rien de visible ici
pour (col octets = 0; col < 9; col ++) {}
digitalWrite (columnPins [col], HIGH) ;
}
maintenant, nous sélectionnons tout niveaux
pour (cycle octets = 0; cycle < 2; cycle ++) {}
pour (octet lvl = 0; lvl < 3; lvl ++) {}
digitalWrite (levelPins [lvl], cycle % 2 == 0 ? BAS : ÉLEVÉ) ;
Delay(200) ;
}
}
ledInit() ;
}
quelques rotations (aucun pilote utilisé aussi bien)
void demoRotation() {}
séquence de rotation
seq Byte = {0,1,2,5,8,7,6,3} ;
ledInit() ;
active tous les niveaux
pour (octet lvl = 0; lvl < 3; lvl ++) {}
digitalWrite (levelPins [lvl], faible) ;
}
colonne du milieu
digitalWrite (columnPins [4], HIGH) ;
maintenant, nous sélectionnons des colonnes entières
cycles d’int = 3 * 3 * 9 ;
pour (cycle int = 0; cycle < cycles ; cycle ++) {}
digitalWrite (columnPins [seq [cycle 8 %]], HIGH) ;
digitalWrite (columnPins [seq [(cycle-1) %8]], faible) ;
Si (cycle > = 3 * 9) {}
digitalWrite (columnPins [seq [(cycle+4) %8]], élevé) ;
digitalWrite (columnPins [seq [(cycle+3) %8]], faible) ;
}
Si (cycle > = 2 * 3 * 9) {}
digitalWrite (columnPins [seq [(cycle+2) %8]], élevé) ;
digitalWrite (columnPins [seq [(cycle+1) %8]], faible) ;
digitalWrite (columnPins [seq [(cycle+6) %8]], élevé) ;
digitalWrite (columnPins [seq [(cycle+5) %8]], faible) ;
}
Delay(100) ;
}
ledInit() ;
}
accès direct au tampon voxel (coordonnées cartésiennes ne pas utilisées)
void demoFill() {}
clearBuffer() ;
pour (cycle int = 0; cycle < 2; cycle ++) {}
pour (int i = 0; i < 27; i ++) {}
Si (cycle % 2 == 0) {}
tampon [i] = 8 ;
} else {}
tampon [i] = 0 ;
}
Draw(50) ;
}
}
}
traite les voxels comme bacs et remplissez-les peu à peu au hasard
void demoBinFill() {}
clearBuffer() ;
pour (int i = 0; i < 100; i ++) {}
buffer[Random(0,28)] += 2 ;
drawPwm() ;
}
}
pur hasard sparkle
void demoSparkle() {}
pour (densité int = 0; densité < 50 ; densité ++) {}
pour (cycle int = 0; cycle < 3; cycle ++) {}
clearBuffer() ;
pour (int i = 0; i < densité; i ++) {}
buffer[Random(0,28)] = random(0,9) ;
}
drawPwm() ;
}
}
}
rend tous les LEDs impulsion synchrone
void demoPulse() {}
pour (cycle int = 0; cycle < 80 ; cycle ++) {}
fillBuffer(-abs(cycle%16-8)+8) ;
drawPwm() ;
}
}
vague "pulsé"
void demoPulseWave() {}
r de l’octet ;
pour (cycle octets = 0; cycle < 80 ; cycle ++) {}
pour (char x =-1; x < = 1; x ++) {}
pour (char y =-1; y < = 1; y ++) {}
pour (char z =-1; z < = 1; z ++) {}
r = (x * x + y * y + z * z) ;
setVoxel (x, y, z, - abs((cycle-r)%16-8)+8) ;
}
}
}
drawPwm() ;
}
}
montre interpolation
void demoGlowfly() {}
float dx, dy, dz ;
étapes d’octets = 10 ;
flotteur px = random(-100,101)/100.0 ;
flotteur py = random(-100,101)/100.0 ;
flotteur pz = random(-100,101)/100.0 ;
pour (cycle int = 0; cycle < 8; cycle ++) {}
DX = (random(-100,101)/100,0 - px) / étapes ;
DY = (random(-100,101)/100,0 - py) / étapes ;
DZ = (random(-100,101)/100,0 - pz) / étapes ;
pour (int i = 0; i < étapes; i ++) {
PX += dx ;
py += dy ;
PZ = dz ;
clearBuffer() ;
point de consigne (px, py, pz, MAX_INTENSITY) ;
drawPwm() ;
}
}
}