Edellisiin kysymyksiin:
-Kyllä siinä on jossakin liimattu tuo paperi, en tiedä missä ja kuka.
-Vastuksen paikan näet kytkentäkuvasta
-Ledit toimivat myös tuolla 5V ja samalla regulla. Minulla on tuossa 120 Ohm vastukset ja sillä menee jokin 10mA vain ledissä… eli aika vähän. Voisi siis varmaan pistää pienemmätkin vastukset.
Sitten asiaan:
Noniin sain vihdoin kytkennät piirrettyä… ei se montaa tuntia vaatinut mutta motivaatiota sitäkin enemmän. Huomasin samalla myös että tuo Uno version kytkennät ovat eri kuin tuossa pääkirjoituksen koodissa näkyy. Siksi tässä on myös koodi jolla tuo Uno versio pyörii. En nyt takaa että kuvat olisivat täydellisen oikein eli varauksella sitten kytkette Kannattaa tarkistaa että jalat on oikein merkattu ennenkuin kytkee!
Jätin kuvista piirtämättä kerrokset 2-7 koska ne ovat lähes identtiset kerroksen 1 kanssa. Ainut ero on tietysti se, että kerrosten linkitys vaihtuu kerroksen mukaan. Ylin kerros on 8 ja alin 1. Nuoli näyttää katselusuunnan, eli kirjaimet “lentävät” katselusuuntaa kohti"
Koodi Unolle ja ohessa oleville kytkennöille:
[code]#include <avr/interrupt.h>
byte aakkoset[29][8] = {{0,0,0,0,0,0,0,0},
{0,24,36,66,126,66,66,66},
{0,56,36,36,56,36,36,56},
{0,28,34,64,64,64,34,28},
{0,120,68,68,68,68,68,120},
{0,124,64,64,120,64,64,124},
{0,124,64,64,120,64,64,64},
{0,60,66,64,78,66,66,60},
{0,68,68,68,124,68,68,68},
{0,16,16,16,16,16,16,16},
{0,8,8,8,8,72,72,48},
{0,68,72,80,96,80,72,68},
{0,64,64,64,64,64,64,124},
{0,65,99,85,73,65,65,65},
{0,66,98,114,90,78,70,66},
{60,66,66,66,66,66,66,60},
{0,56,36,36,56,32,32,32},
{56,68,130,130,130,154,68,58},
{0,56,36,36,56,36,36,36},
{56,68,64,56,4,4,68,56},
{0,127,8,8,8,8,8,8},
{0,66,66,66,66,66,66,60},
{0,65,65,34,34,20,20,8},
{0,130,130,146,146,170,68,0},
{129,66,36,24,24,36,66,129},
{130,130,68,40,16,16,16,16},
{0,126,4,8,16,32,64,126},
{102,24,36,66,126,66,66,66},
{102,24,36,66,66,66,36,24}};
int rivi[8]={14,15,16,17,18,19,12,13};
//int rivi[8] = {0,1,2,3,4,5,6,7}; // A0,A1,A2,A3,A4,A5,D12,D13 !!!
int clock=11; //D11
int enable = 7; //D7
int k1=10;//D10
int k2=9;//D9
int k3=8;//D8
volatile byte kuva[8][8]; // Z-kerros , Y-sivu
volatile int kerros=0;
volatile boolean tyhjennetaan=false;
void setup(){
TCCR2A = 0x00;
TCCR2B = 0x00;
//Interruppi asetukset
TCCR2A |= (0x01 << WGM21);
OCR2A = 40;
TCNT2 = 0x00;
TCCR2B |= (0x01 << CS22) | (0x01 << CS21);
TIMSK2 |= (0x01 << OCIE2A);
for(int i=0; i<8; i++){
pinMode(rivi[i],OUTPUT);
}
pinMode(clock,OUTPUT);
pinMode(enable,OUTPUT);
pinMode(k1,OUTPUT);
pinMode(k2,OUTPUT);
pinMode(k3,OUTPUT);
}
//Interruppi, Sytyttää aina yhden kerroksen kerrallaan ja palaa pääohjelmaan
ISR (TIMER2_COMPA_vect){
if(tyhjennetaan){
for(int a=0; a<8; a++){
for(int b=0; b<8; b++){
kuva[a][b]=0;
}}
tyhjennetaan=false;
}
else{
digitalWrite(enable,LOW); //Ledit offfffff
//Kerroksen lisäys ja asetus
kerros++;
if(kerros>=8){kerros=0;}
SetKerros(kerros);
// Kerroksen ledien asetus
for(int i=0; i<8; i++){
digitalWrite(clock,LOW);
//PORTD = kuva[kerros][i]; vanha
PORTC= B00111111 & kuva[kerros][i]; //ensimmäiset 6 lähtöä
PORTB= (PORTB & B00001111) | ((B11000000 & kuva[kerros][i])>>2); //
digitalWrite(clock,HIGH);
}
//Ledien sytytys
digitalWrite(enable,HIGH);
}
}
//----------------------------LOOOOOOOOP------------------------------
void loop(){
splash(3);
kirjain_lento(‘l’,50);
kirjain_lento(‘e’,50);
kirjain_lento(‘d’,50);
kirjain_lento(‘i’,50);
kirjain_lento(’ ',50);
kirjain_lento(‘k’,50);
kirjain_lento(‘u’,50);
kirjain_lento(‘u’,50);
kirjain_lento(‘t’,50);
kirjain_lento(‘i’,50);
kirjain_lento(‘o’,50);
aalto(15);
merenaalto(15);
antiaalto(15);
sineCubeP(15,50);
sineCubeV(15,50);
effect_random_filler(10,1);
delay(500);
effect_random_filler(10,0);
effect_rain(200);
tyhjenna();
for(int j=0; j<5;j++){
for(int i=0; i<4; i++){
tyhjenna();
box_wireframe(i,i,i,7-i,7-i,7-i);
delay(j50);
}
for(int i=3; i>0; i–){
tyhjenna();
box_wireframe(i,i,i,7-i,7-i,7-i);
delay(j50);
}
}
tyhjenna();
box_wireframe(0,0,0,7,7,7);
delay(2000);
tyhjenna();
tayta();
delay(3000);
tyhjenna();
}
//-------------------------------------------------------------------
void sineCube(){
float phase=0;
int size=8;
float Z=0;
unsigned long tikit;
for(int g=0; g<14; g++){
for(phase=0; phase<2*PI; phase=phase+0.09){
tyhjenna();
for(int x = 0; x < size; x++){
for(int y = 0; y < size; y++){
Z = sin(phase + sqrt(pow(skaalaus(x,0,7,-PI,PI),2) + pow(skaalaus(y,0,7,-PI,PI),2)));
Z = round(skaalaus(Z,-1,1,0,size-1));
int z = int(Z);
setLed(x,y,z);
}
}
tikit=millis();
while(tikit+5>millis()){
;
}
}
}
}
//-----------------------------------------------------------------
//Pysty liike
void sineCubeP(int kierrokset, int tauko){
float phase=0;
float Z=0;
for(int g=0; g<kierrokset; g++){
for(phase=0; phase<2*PI; phase=phase+0.39){
tyhjenna();
for(int x = 0; x < 4; x++){
for(int y = 0; y < 4; y++){
Z = sin(phase + sqrt(pow(skaalaus(x,0,7,-PI,PI),2) + pow(skaalaus(y,0,7,-PI,PI),2)));
Z = round(skaalaus(Z,-1,1,0,7));
int z = int(Z);
setLed(x,y,z);
setLed(x,7-y,z);
setLed(7-x,y,z);
setLed(7-x,7-y,z);
}
}
delay(tauko);
}
}
}
//-----------------------------------------------------------------
//vaaka liike
void sineCubeV(int kierrokset, int tauko){
float phase=0;
float Y=0;
for(int g=0; g<kierrokset; g++){
for(phase=0; phase<2*PI; phase=phase+0.39){
tyhjenna();
for(int x = 0; x < 4; x++){
for(int z = 0; z < 4; z++){
Y = sin(phase + sqrt(pow(skaalaus(x,0,7,-PI,PI),2) + pow(skaalaus(z,0,7,-PI,PI),2)));
Y = round(skaalaus(Y,-1,1,0,7));
int y = int(Y);
setLed(x,y,z);
setLed(x,y,7-z);
setLed(7-x,y,z);
setLed(7-x,y, 7-z);
}
}
delay(tauko);
}
}
}
//-----------------------------------------------------------------
//aaltoilu
void aalto(int kierrokset){
for(int g=0; g<kierrokset; g++){
for(float kierros=0; kierros< 2*PI; kierros=kierros+0.39){
for(int x=0; x<8; x++){
int z = int(round(skaalaus(sin(kierros + skaalaus(x,0,7,0,PI)),-1,1,0,7) ));
setLed(x,0,z);
setLed(x,1,z);
setLed(x,2,z);
setLed(x,3,z);
setLed(x,4,z);
setLed(x,5,z);
setLed(x,6,z);
setLed(x,7,z);
}
delay(50);
tyhjenna();
}
}
}
//-----------------------------------------------------------------
//aaltoilu
void merenaalto(int kierrokset){
for(int g=0; g<kierrokset; g++){
for(float kierros=0; kierros< 2*PI; kierros=kierros+0.39){
for(int x=0; x<8; x++){
int z = int(round(skaalaus(sin(kierros + skaalaus(x,0,7,0,PI)),-1,1,0,7) ));
for(int i=0; i<=z; i++){
setLed(x,0,i);
setLed(x,1,i);
setLed(x,2,i);
setLed(x,3,i);
setLed(x,4,i);
setLed(x,5,i);
setLed(x,6,i);
setLed(x,7,i);
}
}
delay(50);
tyhjenna();
}
}
}
//-----------------------------------------------------------------
//käänteinen aaltoilu
void antiaalto(int kierrokset){
for(int g=0; g<kierrokset; g++){
for(float kierros=0; kierros< 2*PI; kierros=kierros+0.39){
tayta();
for(int x=0; x<8; x++){
int z = int(round(skaalaus(sin(kierros + skaalaus(x,0,7,0,PI)),-1,1,0,7) ));
resLed(x,0,z);
resLed(x,1,z);
resLed(x,2,z);
resLed(x,3,z);
resLed(x,4,z);
resLed(x,5,z);
resLed(x,6,z);
resLed(x,7,z);
if(z<7){
resLed(x,0,z+1);
resLed(x,1,z+1);
resLed(x,2,z+1);
resLed(x,3,z+1);
resLed(x,4,z+1);
resLed(x,5,z+1);
resLed(x,6,z+1);
resLed(x,7,z+1);
}
if(z>0){
resLed(x,0,z-1);
resLed(x,1,z-1);
resLed(x,2,z-1);
resLed(x,3,z-1);
resLed(x,4,z-1);
resLed(x,5,z-1);
resLed(x,6,z-1);
resLed(x,7,z-1);
}
}
delay(50);
}
}
tyhjenna();
}
//-----------------------------------------------------------------
float skaalaus(float in, float inMin, float inMax, float outMin, float outMax){
float out;
out = (in-inMin)/(inMax-inMin)*(outMax-outMin) + outMin;
return out;
}
//----------------------------------------------------------
void splash(int kiertomaara){
for(int i=0; i<kiertomaara; i++){
//täytto
for(int j=0; j<8; j++){
kuva[j][0]=255;
kuva[j][1]=255;
kuva[j][2]=255;
kuva[j][3]=255;
kuva[j][4]=255;
kuva[j][5]=255;
kuva[j][6]=255;
kuva[j][7]=255;
delay(15);
}
delay(100);
//tyhjennys
for(int j=0; j<8; j++){
kuva[j][0]=0;
kuva[j][1]=0;
kuva[j][2]=0;
kuva[j][3]=0;
kuva[j][4]=0;
kuva[j][5]=0;
kuva[j][6]=0;
kuva[j][7]=0;
delay(15+j*10);
}
}
}
//----------------------------------------------------------
// Set or clear exactly 512 voxels in a random order.
void effect_random_filler (int viive, int state){
int x,y,z;
int loop = 0;
if (state == 1){tyhjenna();}
else{tayta();}
while (loop<511){
x = rand()%8;
y = rand()%8;
z = rand()%8;
if ((state == 0 && getLed(x,y,z) == 0x01) || (state == 1 && getLed(x,y,z) == 0x00))
{
altervoxel(x,y,z,state);
delay(viive);
loop++;
}
}
}
//---------------------------------------------------------------------
void box_walls(int x1, int y1, int z1, int x2, int y2, int z2)
{
int iy;
int iz;
argorder(x1, x2, &x1, &x2);
argorder(y1, y2, &y1, &y2);
argorder(z1, z2, &z1, &z2);
for (iz=z1;iz<=z2;iz++)
{
for (iy=y1;iy<=y2;iy++)
{
if (iy == y1 || iy == y2 || iz == z1 || iz == z2)
{
kuva[iz][iy] = byteline(x1,x2);
} else
{
kuva[iz][iy] |= ((0x01 << x1) | (0x01 << x2));
}
}
}
}
//-----------------------------------------------------------------
void effect_rain (int iterations)
{
int i, ii;
int rnd_x;
int rnd_y;
int rnd_num;
for (ii=0;ii<iterations;ii++)
{
rnd_num = rand()%4;
for (i=0; i < rnd_num;i++)
{
rnd_x = rand()%8;
rnd_y = rand()%8;
setLed(rnd_x,rnd_y,7);
}
delay(50);
shift(1,-1);
}
}
//--------------------------------------------------------------------
void draw_positions_axis (char axis, unsigned char positions[64], int invert)
{
int x, y, p;
tyhjenna();
for (x=0; x<8; x++)
{
for (y=0; y<8; y++)
{
if (invert)
{
p = (7-positions[(x8)+y]);
} else
{
p = positions[(x8)+y];
}
if (axis == 1)
setLed(x,y,p);
if (axis == 2)
setLed(x,p,y);
if (axis == 3)
setLed(p,y,x);
}
}
}
//-------------------------------------------------------------------
void kirjain_lento(char kirjain, int nopeus){
tyhjenna();
if(kirjain==32){kirjain=0;};
if(kirjain>64 && kirjain<91){kirjain = kirjain - 64;}; //A-Z (isot)
if(kirjain>96 && kirjain<123){kirjain = kirjain - 96;}; //A-Z (pienet)
if(kirjain ==63 ){kirjain=27;};// Ä
if(kirjain ==33 ){kirjain=28;};// Ö
for(int i=0; i<8; i++){
//piirretään kirjain
kuva[7][i]=aakkoset[kirjain][0];
kuva[6][i]=aakkoset[kirjain][1];
kuva[5][i]=aakkoset[kirjain][2];
kuva[4][i]=aakkoset[kirjain][3];
kuva[3][i]=aakkoset[kirjain][4];
kuva[2][i]=aakkoset[kirjain][5];
kuva[1][i]=aakkoset[kirjain][6];
kuva[0][i]=aakkoset[kirjain][7];
delay(nopeus);//Tauko
if(i==7){
delay(3*nopeus);
}
//Tyhjennetään uutta sivua varten
kuva[0][i]=0;
kuva[1][i]=0;
kuva[2][i]=0;
kuva[3][i]=0;
kuva[4][i]=0;
kuva[5][i]=0;
kuva[6][i]=0;
kuva[7][i]=0;
}
}
//---------------------------------------------------------------------
void effect_axis_updown_randsuspend (char axis, int tauko, int sleep, int invert){
unsigned char positions[64];
unsigned char destinations[64];
int i,px;
//set 64 rand pos
for(i=0; i<64; i++){
positions[i] = 0;
destinations[i] = rand()%8;
}
//loop 8 times to allow dest. 7 to reach all the way
for(i=0; i<8; i++){
//For every iteration, move all position one step closer to dest.
for(px=0; px<64; px++){
if(positions[px]<destinations[px]){positions[px]++;}
//piirto ja tauko
draw_positions_axis(axis, positions, invert);
delayMicroseconds(tauko);
}
}
//set all destin. to 7 opposite<>start
for(i=0; i<64; i++){destinations[i]=7;}
//suspend the positions in mid air for while
delay(sleep);
for(i=0; i<8; i++){
for(px=0; px<64; px++){
if(positions[px]<destinations[px]){positions[px]++;}
if(positions[px]>destinations[px]){positions[px]–;}
}
draw_positions_axis(axis, positions, invert);
delayMicroseconds(tauko);
}
}
//----------------------------------------------------------------------
void setLed( int x, int y, int z){
if(inrange(x,y,z)){kuva[z][y] |= (1<< x);}
}
void resLed( int x, int y, int z){
if(inrange(x,y,z)){kuva[z][y] &= ~(1<<x);}
}
boolean getLed( int x, int y, int z){
if(inrange(x,y,z)){
if(kuva[z][y] & (1<<x)){ return true;}
else{ return false;}
}
else{ return false;}
}
void altervoxel(int x, int y, int z, int state)
{
if (state == 1){
setLed(x,y,z);}
else{
resLed(x,y,z);}
}
void tayta(){
for(int a=0; a<8; a++){
for(int b=0; b<8; b++){
kuva[a][b]=255;
}}
}
void tyhjenna(){
tyhjennetaan=true;
while(tyhjennetaan==true){
;
}
}
boolean inrange(int x, int y, int z){
if(x >= 0 && x < 8 && y >= 0 && y < 8 && z >= 0 && z < 8){return true;}
else{return false;}
}
// Draw a wireframe box. This only draws the corners and edges,
// no walls.
void box_wireframe(int x1, int y1, int z1, int x2, int y2, int z2)
{
int iy;
int iz;
argorder(x1, x2, &x1, &x2);
argorder(y1, y2, &y1, &y2);
argorder(z1, z2, &z1, &z2);
// Lines along X axis
kuva[z1][y1] = byteline(x1,x2);
kuva[z1][y2] = byteline(x1,x2);
kuva[z2][y1] = byteline(x1,x2);
kuva[z2][y2] = byteline(x1,x2);
// Lines along Y axis
for (iy=y1;iy<=y2;iy++)
{
setLed(x1,iy,z1);
setLed(x1,iy,z2);
setLed(x2,iy,z1);
setLed(x2,iy,z2);
}
// Lines along Z axis
for (iz=z1;iz<=z2;iz++)
{
setLed(x1,y1,iz);
setLed(x1,y2,iz);
setLed(x2,y1,iz);
setLed(x2,y2,iz);
}
}
char byteline (int start, int end){
return ((0xff<<start) & ~(0xff<<(end+1)));
}
void argorder(int ix1, int ix2, int *ox1, int *ox2){
if (ix1>ix2){
int tmp;
tmp = ix1;
ix1= ix2;
ix2 = tmp;
}
*ox1 = ix1;
*ox2 = ix2;
}
// Draw a line between any coordinates in 3d space.
// Uses integer values for input, so dont expect smooth animations.
void line(int x1, int y1, int z1, int x2, int y2, int z2){
float xy; // how many voxels do we move on the y axis for each step on the x axis
float xz; // how many voxels do we move on the y axis for each step on the x axis
unsigned char x,y,z;
unsigned char lasty,lastz;
int X,Y,Z;
// We always want to draw the line from x=0 to x=7.
// If x1 is bigget than x2, we need to flip all the values.
if (x1>x2){
int tmp;
tmp = x2; x2 = x1; x1 = tmp;
tmp = y2; y2 = y1; y1 = tmp;
tmp = z2; z2 = z1; z1 = tmp;
}
if (y1>y2){
xy = (float)(y1-y2)/(float)(x2-x1);
lasty = y2;
} else
{
xy = (float)(y2-y1)/(float)(x2-x1);
lasty = y1;
}
if (z1>z2)
{
xz = (float)(z1-z2)/(float)(x2-x1);
lastz = z2;
} else
{
xz = (float)(z2-z1)/(float)(x2-x1);
lastz = z1;
}
// For each step of x, y increments by:
for (x = x1; x<=x2;x++)
{
y = (xy*(x-x1))+y1;
z = (xz*(x-x1))+z1;
//X=int(x);
//Y=int(y);
//Z=int(z);
setLed(X,Y,Z);
}
}
// Shift the entire contents of the cube along an axis
// This is great for effects where you want to draw something
// on one side of the cube and have it flow towards the other
// side. Like rain flowing down the Z axiz.
void shift (char axis, int direction){
int i, x ,y;
int ii, iii;
int state;
for (i = 0; i < 8; i++){
if (direction == -1)
{
ii = i;
} else
{
ii = (7-i);
}
for (x = 0; x < 8; x++){
for (y = 0; y < 8; y++){
if (direction == -1)
{
iii = ii+1;
} else
{
iii = ii-1;
}
if (axis == 1)
{
state = getLed(x,y,iii);
altervoxel(x,y,ii,state);
}
if (axis == 2)
{
state = getLed(x,iii,y);
altervoxel(x,ii,y,state);
}
if (axis == 3)
{
state = getLed(iii,y,x);
altervoxel(ii,y,x,state);
}
}
}
}
if (direction == -1)
{
i = 7;
} else
{
i = 0;
}
for (x = 0; x < 8; x++)
{
for (y = 0; y < 8; y++)
{
if (axis == 1)
resLed(x,y,i);
if (axis == 2)
resLed(x,i,y);
if (axis == 3)
resLed(i,y,x);
}
}
}
//---------------------------------------------------------------------------
void SetKerros(int x){
switch(x){
case 0:
//1 kerros
digitalWrite(k1,LOW);
digitalWrite(k2,LOW);
digitalWrite(k3,LOW);
break;
case 1:
//2 kerros
digitalWrite(k1,HIGH);
digitalWrite(k2,LOW);
digitalWrite(k3,LOW);
break;
case 2:
//3 kerros
digitalWrite(k1,LOW);
digitalWrite(k2,HIGH);
digitalWrite(k3,LOW);
break;
case 3:
//4 kerros
digitalWrite(k1,HIGH);
digitalWrite(k2,HIGH);
digitalWrite(k3,LOW);
break;
case 4:
//5 kerros
digitalWrite(k1,LOW);
digitalWrite(k2,LOW);
digitalWrite(k3,HIGH);
break;
case 5:
//6 kerros
digitalWrite(k1,HIGH);
digitalWrite(k2,LOW);
digitalWrite(k3,HIGH);
break;
case 6:
//7 kerros
digitalWrite(k1,LOW);
digitalWrite(k2,HIGH);
digitalWrite(k3,HIGH);
break;
case 7:
//8 kerros
digitalWrite(k1,HIGH);
digitalWrite(k2,HIGH);
digitalWrite(k3,HIGH);
break;
}
}[/code]
Ledikuutio_Kytkennät.pdf (48.8 KB)