Código
- Asi Eye
- Asi Neck com bugiganga
Asi Eye Arduino
o código para Asi eye #include // Sempre temos que incluir a biblioteca LedControl # include "LedControl.h" / * Criar objeto LetControl, definir conexões de pinos Temos 2 MAX72XX para olhos. * / # define PIN_EYES_DIN 12 # define PIN_EYES_CS 11 # define PIN_EYES_CLK 10LedControl lc =LedControl (PIN_EYES_DIN, PIN_EYES_CLK, PIN_EYES_CS, 2); // rotationbool rotateMatrix0 =false; // rotaciona a matriz 0 em 180 degbool rotateMatrix1 =false; // girar 1 matriz em 180 graus // definir a esfera do olho sem pupila byte eyeBall [8] ={B00111100, B01111110, B11111111, B11111111, B11111111, B11111111, B01111110, B00111100}; byte eyePupil =B11100111; // armazena o estado atual de LEDsbyte eyeCurrent [8]; int currentX; int currentY; int cntLoop =0; int cntEffect =0; // posições mín. E máx. # Define MIN -2 # define MAX 2 // atrasos # define DELAY_BLINK 40 // executa um efeito a cada Nº de iterações de loop, 0 para desativar # define EFFECT_ITERATION 4 / * Arduino setup * / void setup () {// MAX72XX está no modo de economia de energia na inicialização, temos que fazer uma chamada de ativação lc.shutdown (0, false); lc.shutdown (1, falso); // define o brilho para baixo lc.setIntensity (0,1); lc.setIntensity (1,1); // limpar ambos os módulos lc.clearDisplay (0); lc.clearDisplay (1); // Teste de LED // byte de linha vertical b =B10000000; for (int c =0; c <=7; c ++) {for (int r =0; r <=7; r ++) {setRow (0, r, b); setRow (1, r, b); } b =b>> 1; atraso (50); } // módulo completo b =B11111111; para (int r =0; r <=7; r ++) {setRow (0, r, b); setRow (1, r, b); } atraso (500); // limpar ambos os módulos lc.clearDisplay (0); lc.clearDisplay (1); atraso (500); // semente aleatória randomSeed (analogRead (0)); // centro dos olhos, piscar louco displayEyes (0, 0); atraso (2000); blinkEyes (verdadeiro, falso); blinkEyes (falso, verdadeiro); delay (1000);} / * Arduino loop * / void loop () {// mover para a posição aleatória, esperar tempo aleatório moveEyes (random (MIN, MAX + 1), random (MIN, MAX + 1), 50); atraso (aleatório (5, 7) * 500); // tempo de piscar? if (aleatório (0, 5) ==0) {atraso (500); blinkEyes (); atraso (500); } // tempo de efeito? if (EFFECT_ITERATION> 0) {cntLoop ++; if (cntLoop ==EFFECT_ITERATION) {cntLoop =0; if (cntEffect> 6) cntEffect =0; switch (cntEffect) {case 0:// cross eyes crossEyes (); atraso (1000); pausa; caso 1:// round spin roundSpin (2); atraso (1000); pausa; caso 2:// spin louco crazySpin (2); atraso (1000); pausa; caso 3:// meth eyes methEyes (); atraso (1000); pausa; caso 4:// olho preguiçoso lazyEye (); atraso (1000); pausa; caso 5:// blink louco blinkEyes (verdadeiro, falso); blinkEyes (falso, verdadeiro); atraso (1000); pausa; case 6:// brilho glowEyes (3); atraso (1000); pausa; padrão:break; } cntEffect ++; }}} / * Este método pisca os olhos * / void blinkEyes () {blinkEyes (true, true);} / * Este método pisca os olhos conforme os parâmetros fornecidos * / void blinkEyes (boolean blinkLeft, boolean blinkRight) {// piscar ? if (! blinkLeft &&! blinkRight) return; // feche as pálpebras para (int i =0; i <=3; i ++) {if (blinkLeft) {setRow (0, i, 0); setRow (0, 7-i, 0); } if (blinkRight) {setRow (1, i, 0); setRow (1, 7-i, 0); } atraso (DELAY_BLINK); } // abrir as pálpebras para (int i =3; i> =0; i--) {if (blinkLeft) {setRow (0, i, eyeCurrent [i]); setRow (0, 7-i, eyeCurrent [7-i]); } if (blinkRight) {setRow (1, i, eyeCurrent [i]); setRow (1, 7-i, eyeCurrent [7-i]); } atraso (DELAY_BLINK); }} / * Este método move os olhos para a posição central e, em seguida, move os olhos horizontalmente envolvendo as bordas. * / Void crazySpin (int times) {if (times ==0) return; moveEyes (0, 0, 50); atraso (500); byte row =eyePupil; for (int t =0; t > 1; linha =linha | B10000000; setRow (0, 3, linha); setRow (1, 3, linha); setRow (0, 4, linha); setRow (1, 4, linha); atraso (50); se (t ==0) atraso ((5-i) * 10); // aumenta o atraso na primeira rolagem (efeito de aceleração)} // gire de R para o centro para (int i =0; i <5; i ++) {row =row>> 1; if (i> =2) linha =linha | B10000000; setRow (0, 3, linha); setRow (1, 3, linha); setRow (0, 4, linha); setRow (1, 4, linha); atraso (50); if (t ==(vezes-1)) atraso ((i + 1) * 10); // aumenta o atraso na última rolagem (efeito de desaceleração)}}} / * Este método cruza os olhos * / void crossEyes () {moveEyes (0, 0, 50); atraso (500); byte pupilR =eyePupil; byte pupilL =eyePupil; // mova os alunos juntos para (int i =0; i <2; i ++) {pupilR =pupilR>> 1; pupilaR =pupilaR | B10000000; pupilaL =pupilaL <<1; pupilaL =pupilaL | B1; setRow (0, 3, pupilR); setRow (1, 3, pupilaL); setRow (0, 4, pupilR); setRow (1, 4, pupilaL); atraso (100); } atraso (2000); // move os alunos de volta ao centro para (int i =0; i <2; i ++) {pupilR =pupilR <<1; pupilaR =pupilaR | B1; pupilaL =pupilaL>> 1; pupilaL =pupilaL | B10000000; setRow (0, 3, pupilR); setRow (1, 3, pupilaL); setRow (0, 4, pupilR); setRow (1, 4, pupilaL); atraso (100); }} / * Este método exibe o globo ocular com deslocamento da pupila por valores de X, Y da posição central. O intervalo válido de X e Y é [MIN, MAX] Ambos os módulos de LED mostrarão olhos idênticos * / void displayEyes (int offsetX, int offsetY) {// garantir que os deslocamentos estejam em intervalos válidos offsetX =getValidValue (offsetX); offsetY =getValidValue (offsetY); // calcula os índices para as linhas do aluno (executa o deslocamento Y) int row1 =3 - offsetY; linha2 interna =4 - deslocamentoY; // define o byte da linha da pupila pupilRow =eyePupil; // executa o deslocamento X // bit shift e preenche o novo bit com 1 if (offsetX> 0) {for (int i =1; i <=offsetX; i ++) {pupilRow =pupilRow>> 1; pupilRow =pupilRow | B10000000; }} else if (offsetX <0) {for (int i =-1; i> =offsetX; i--) {pupilRow =pupilRow <<1; pupilRow =pupilRow | B1; }} // a linha da pupila não pode ter 1s, onde eyeBall tem 0s byte pupilRow1 =pupilRow &eyeBall [row1]; byte pupilRow2 =pupilRow &eyeBall [linha2]; // exibir na matriz LCD, atualizar para eyeCurrent for (int r =0; r <8; r ++) {if (r ==row1) {setRow (0, r, pupilRow1); setRow (1, r, pupilRow1); eyeCurrent [r] =pupilRow1; } else if (r ==row2) {setRow (0, r, pupilRow2); setRow (1, r, pupilRow2); eyeCurrent [r] =pupilRow2; } else {setRow (0, r, eyeBall [r]); setRow (1, r, eyeBall [r]); eyeCurrent [r] =eyeBall [r]; }} // atualiza X e Y atuais X atual =offsetX; currentY =offsetY;} / * Este método corrige o valor da coordenada fornecida * / int getValidValue (int value) {if (value> MAX) return MAX; senão se (valor =1; i--) {lc.setIntensity (0, i); lc.setIntensity (1, i); atraso (25); } atraso (150); }} / * Este método move os olhos para o centro, para fora e depois de volta para o centro * / void methEyes () {moveEyes (0, 0, 50); atraso (500); byte pupilR =eyePupil; byte pupilL =eyePupil; // mover os alunos para fora para (int i =0; i <2; i ++) {pupilR =pupilR <<1; pupilaR =pupilaR | B1; pupilaL =pupilaL>> 1; pupilaL =pupilaL | B10000000; setRow (0, 3, pupilR); setRow (1, 3, pupilaL); setRow (0, 4, pupilR); setRow (1, 4, pupilaL); atraso (100); } atraso (2000); // move as pupilas de volta ao centro para (int i =0; i <2; i ++) {pupilR =pupilR>> 1; pupilaR =pupilaR | B10000000; pupilaL =pupilaL <<1; pupilaL =pupilaL | B1; setRow (0, 3, pupilR); setRow (1, 3, pupilaL); setRow (0, 4, pupilR); setRow (1, 4, pupilaL); atraso (100); }} / * Este método move os dois olhos da posição atual para a nova posição * / void moveEyes (int newX, int newY, int stepDelay) {// define a posição atual como posição inicial int startX =currentX; int startY =currentY; // corrige novos valores X Y inválidos newX =getValidValue (newX); newY =getValidValue (newY); // etapas de avaliação int stepsX =abs (currentX - newX); etapas int Y =abs (atualY - novoY); // precisa mudar pelo menos uma posição if ((stepsX ==0) &&(stepsY ==0)) return; // avaliação da direção do movimento, nº de passos, mudança por X Y passo, realizar o movimento int dirX =(newX> =currentX)? 1:-1; int dirY =(novoY> =atualY)? 1:-1; etapas int =(etapasX> etapasY)? etapasX:etapasY; int intX, intY; float changeX =(float) stepsX / (float) steps; flutuação alteraçãoY =(flutuação) etapasY / (flutuação) etapas; para (int i =1; i <=etapas; i ++) {intX =startX + round (alterarX * i * dirX); intY =startY + round (alterarY * i * dirY); displayEyes (intX, intY); atraso (stepDelay); }} / * Este método diminui e eleva apenas a pupila direita * / void lazyEye () {moveEyes (0, 1, 50); atraso (500); // abaixa a pupila esquerda lentamente para (int i =0; i <3; i ++) {setRow (1, i + 2, eyeBall [i + 2]); setRow (1, i + 3, eyeBall [i + 3] &eyePupil); setRow (1, i + 4, eyeBall [i + 4] &eyePupil); atraso (150); } atraso (1000); // elevar a pupila esquerda rapidamente para (int i =0; i <3; i ++) {setRow (1, 4-i, eyeBall [4-i] &eyePupil); setRow (1, 5-i, eyeBall [5-i] &eyePupil); setRow (1, 6-i, eyeBall [6-i]); atraso (25); }} / * Este método gira as pupilas no sentido horário * / void roundSpin (int times) {if (times ==0) return; moveEyes (2, 0, 50); atraso (500); para (int i =0; i Asi Neck com bugiganga Arduino
isso é o que eu uso para ter certeza de que o braço da Asi se move para frente e para trás nos parâmetros // do servo. O pino DEVE ser 1 ou 4 em um Trinket. A posição do servo // é especificada em tiques do temporizador / contador bruto (1 tique =0,128 milissegundos) .// O tempo de pulso do servo é normalmente de 1-2 ms, mas pode variar ligeiramente entre // servos, então você pode precisar ajustar esses limites para corresponde à sua realidade. # define SERVO_PIN 4 // Os pinos 1 ou 4 são suportados no Trinket # define SERVO_MIN 4 // pulso de ~ 1 ms # define SERVO_MAX 26 // pulso de ~ 2 ms Adafruit_TiCoServo servo; void setup (void) {#if (F_CPU ==16000000L) // O Trinket de 16 MHz requer a configuração da pré-escala para o tempo correto. // Isso DEVE ser feito ANTES de servo.attach ()! clock_prescale_set (clock_div_1); # endif servo.attach (SERVO_PIN); pinMode (LED_PIN, OUTPUT); digitalWrite (LED_PIN, HIGH);} uint32_t lastLookTime =0; // Tempo da última virada de cabeça void loop (void) {unsigned long t =millis (); // Hora atual // Se mais de 1/2 segundo se passou desde a última volta da cabeça ... if ((t - lastLookTime)> 500) {if (random (10) ==0) {// Há um 1- chance em 10 ... // ... de mover aleatoriamente a cabeça em uma nova direção:servo.write (random (SERVO_MIN, SERVO_MAX)); lastLookTime =t; // Salve o tempo de giro da cabeça para referência futura}} // Não relacionado à verificação de giro da cabeça, if (random (10) ==0) {// há uma chance de 1 em 10 ... // .. .de um "piscar de olhos":digitalWrite (LED_PIN, LOW); // O LED desliga delay (random (50, 250)); // por apenas um curto momento aleatório digitalWrite (LED_PIN, HIGH); // então volta para ON} delay (100); // Repita o loop () cerca de 10 vezes / segundo}