Erizo - pájaro parlante [si con un reproductor de MP3]



Érase una vez, tanto que parece falso, masterkit habló sobre un maravilloso reproductor de MP3 incorporado que puede equiparse con cualquier cosa, incluso reproductores de MP3, si primero se quita el suyo y luego se lo pone. En resumen, una cosa útil. Especialmente si quieres hacer un juguete para niños, en primer lugar, con tus propias manos y, en segundo lugar, correctamente, y no de la forma en que piensan los que los hacen a escala industrial.

Sin embargo, en el producto presentado quedé satisfecho no solo con todo, así que pensé: no puede ser tal que el aspecto chino no estuviera en Aliexpress. De hecho, había un cierto número de tales jugadores, y la familiarización con la gama de modelos mostró que hay opciones más atractivas que los modelos con una cantidad fija de memoria. A saber: con una ranura para tarjetas microSD extraíbles.

Y lejos nos vamos.



Para dejar en claro qué y dónde fue, una demostración de hedgehog en varios modos.

Frases entretenidas mientras esperas:



Encendido y apagado de cuentos, volumen con tarjetas y sacudidas:



Carga inalámbrica



Antes de continuar la historia, pido disculpas porque puedo hacer algunas imprecisiones en la descripción y el circuito, porque en el proceso no documenté nada, por así decirlo, sobre una corazonada. Utilice el sentido común y los materiales prácticos para que luego no sea insoportablemente doloroso.

Entonces, después de una breve búsqueda y comparación, me cambié a Ebay, donde obtuve lo que quería: un reproductor con un chip decodificador JQ6500, 4 megabytes de memoria interna y una ranura microSD .



¿Por qué exactamente este jugador? Porque entonces me pareció que esta es una opción ideal para el trabajo casero. Porque todo está con él. Si lo desea, úselo por separado: para esto, hay pines de reproducción / pausa, cambio de pistas, volumen, reproducción rápida de cinco pistas y un amplificador mono para conectar el altavoz directamente a la placa (también hay una salida estéreo, pero ya necesita un amplificador externo). Es decir, al menos suficiente batería, altavoz, algunos botones y una tarjeta de memoria con música.

imagen

Pero mucho más interesante es el control completo del reproductor a través de una apariencia de puerto serie. Aquí puede hacer cualquier cosa: reproducir, detener, cambiar el volumen, cambiar el ecualizador y los modos de reproducción, comenzar a reproducir canciones arbitrarias tanto en orden "directo" como desde ciertas carpetas. Y, lo que es más importante en mi caso, ya había una biblioteca preparada para Arduino.

Entonces, ya se conocen dos componentes: player y Arduino. Pero personalmente, no quería parar allí, porque es estúpido ser estúpido imitar botones con un microcontrolador completo. Se necesita algo especial para que con Emely, por así decirlo, y picas.

Por lo tanto, aquí agregamos el sensor de vibración más simple SW-18010P y el conocido lector de tarjetas RC522.

imagen

Todo para deshacerse por completo de los botones, que en el entretenido juguete me parecieron innecesarios. Juzgue usted mismo: si hay botones, el niño los presionará de alguna manera, y con mayor frecuencia, por accidente que conscientemente. Pero el cambio súper frecuente de cuentos de hadas todavía no es del todo correcto.

imagen

Aquí resulta cómo: el sensor de vibración sirve para encender el juguete cuando el niño lo recoge. El mismo sensor no permitirá que el juguete se apague hasta que el niño se lo ponga durante un tiempo suficientemente largo. En cuanto al lector de tarjetas Mifare, esto, en mi opinión, es extremadamente conveniente para cambiar cuentos de hadas. Por ejemplo, se pueden adjuntar tarjetas a los libros, y luego el niño podrá escuchar el cuento de hadas llevando el juguete al libro.

Y también se pueden adjuntar tarjetas a varios temas, y luego el niño podrá escuchar su descripción y reglas de uso. Por ejemplo, que esta figovina blanca es un refrigerador, y que almacenamos alimentos allí para que no se deterioren, y que por esta razón no vale la pena abrirla. O que este es el horno, y que puede estar caliente, por lo que no necesita colgarlo de la manija y poner las manos sobre el vidrio. Se pueden inventar muchas cosas, especialmente porque las tarjetas son boletos de metro usados ​​(sí, tengo suerte, estoy en Moscú), que se pueden recoger fácilmente en la cantidad correcta.

Por lo tanto, mientras pensaba, mientras tanto sacaba el controlador ATmega328p de las existencias , lo soldaba a la placa de pruebas y mostraba el cargador de arranque Adruino a través del Arduino Mega 2560.

imagen

Para mayor comodidad, traje el puerto serie, reinicio y conexión a tierra a un conector separado para una reprogramación rápida. Y luego me conozco a mí mismo: completaré el boceto, y luego uno no está bien, el otro está mal.

Un estabilizador de 3.3V también fue soldado a su lado, ya que el RC522, debido a un malentendido, es alimentado por este voltaje, mientras que el resto de los componentes se sienten muy bien en el 5V universal, que esperaba tomar de un banco de energía simple con baterías 18650.

imagen

La decisión de usar dicho banco de energía en lugar de Una batería descargada típica puede parecer contradictoria. Pero pensé que dado que el juguete consumirá una corriente bastante decente (solo el controlador y el jugador en modo de espera comen aproximadamente 40 mA), la capacidad de reemplazar rápidamente una batería vacía por una llena es muy útil.

Y también tuve que agregar un tweeter piezocerámico para indicar el sonido de algunos eventos (leer una tarjeta, por ejemplo). Esto, dices, es generalmente divertido: hay un orador, ¿verdad? Pues sí, no es así. Después de todo, el altavoz está conectado al reproductor y no al controlador. Y agregó un transistor como clave, que apaga el reproductor de MP3 durante el sueño, para reducir el consumo de energía.

Un lector atento puede notar que el reproductor podría ser alimentado por un pin del controlador digital, lo que funcionaría perfectamente bien. Me gustaría, pero solo en modo de espera el reproductor consume 16 mA. Y cuando la música, toma fácilmente más de 100 mA, que ya es al menos el doble de la capacidad de ATmega. Por lo tanto, tomé "cualquier" transistor npn con una corriente de colector de 300 mA y lo llevé al pin digital del controlador a través de una resistencia de aproximadamente 200 ohmios.

Pero el lector de tarjetas consume hasta 40 mA, por lo que el estabilizador que lo alimenta se puede conectar al pin digital del controlador. Lo hizo, pero todavía no funcionó, sobre lo cual, al final.

Otro punto: el jugador requiere una cabeza dinámica con una resistencia de al menos 8 ohmios. Tenía uno (un altavoz de la unidad del sistema), pero su sonido no es muy bueno. También hubo altavoces con una resistencia de 4 ohmios (de un hablante chino típico). En general, conecté ambos en serie: uno da más alto, el otro da bajo, y juntos suenan geniales.

Permaneció un poco, es decir espejo del alma Lo que es más fácil de hacer con un par de LED conectados en serie. No tomé rojo brutal, da mucho miedo. Pero ojos de color amarillo ámbar, eso es todo.

Entonces, el modelo del juguete se ensambla y se depura. Ahora lo más importante: necesita un donante de cuerpo. En realidad, realmente quería un pájaro parlantepero a juzgar por el precio de los juguetes vecinos, el placer no es del todo presupuestario. Especialmente cuando consideras que el interés del niño es algo impredecible.

Por lo tanto, para comenzar, comencé a buscar un candidato más económico para el trasplante. Y se encontró uno: el encantador erizo Evelyn , vendido en Children's World.

imagen

Por supuesto, tuve que deshacerme casi por completo del rico mundo interior del erizo. Y reemplácelo con uno casero, empacado en una jabonera común. Sin embargo, no del todo ordinario. El hecho es que, a diferencia de muchos, esta jabonera tiene una parte posterior plana, por lo que es conveniente colocar un lector de tarjetas allí: obtienes una distancia mínima. Por otro lado, la jabonera tiene algo así como un cepillo de masaje e incluso tiene agujeros, es decir. el altavoz está idealmente ubicado allí: el sonido saldrá a través de aberturas que no serán bloqueadas por los picos de masaje. Los agujeros, sin embargo, resultaron ser insuficientes, pero no importa, todavía taladré.



Lo más difícil, debo admitir, fue la cirugía para el erizo. En primer lugar, no me gusta coser. Y tuve que hacerlo decentemente: primero lo rasgué, luego abroché los bordes, luego cosí seis botones. Luego soltó seis botones y cosió cuatro botones. ¿Por qué todos? Porque al principio cosí pequeño e incorrecto, por lo que el erizo se desabrochó.



En segundo lugar, los ojos. Por supuesto, adquirí prudentemente los LED con un diámetro de 3 mm, de modo que se pueda garantizar que retraten las pupilas. Sin embargo, no fue tan fácil perforar agujeros en los ojos de Evelyn el erizo. Parecería: toma un grabador, coloca el taladro adecuado y listo. Pero resultó que durante la perforación, el plástico se convierte en una masa viscosa, donde el taladro de un grabador débil se atasca firmemente.

Y, debo decir, un erizo con un taladro que sobresale de su ojo es un espectáculo infernal.

Por cierto, ni siquiera sé qué aconsejar sobre esto. De alguna manera, torcí y aún hice agujeros, inserté LED en ellos y los llené con epoxi, y los cubrí con esmalte incoloro en la parte superior. Los ojos también se pegaron al erizo con epoxi, ya que el monte nativo murió durante el proceso de perforación. El resultado no fue perfecto, pero bastante soportable.

Cómo funciona el erizo, ya lo has visto. Por lo tanto, solo puedo duplicar el texto de su lógica actual. Inicialmente, el erizo está en modo de suspensión. Si lo levanta (o simplemente lo mueve, o mueve la superficie sobre la que descansa, etc.), se despertará con una interrupción que generará un sensor de vibración.

Después de eso, a intervalos predeterminados, el erizo hablará frases predefinidas, y si no lo toca por un tiempo, se dormirá nuevamente. Y si lo tocas, no se dormirá. Y si lo agitas por un tiempo, comenzará a contar un cuento de hadas, elegido al azar.

Si traes una carta al erizo (cuando no está durmiendo), entonces el erizo comenzará a contar una historia asociada con esta carta. No hay una unión rígida, el orden cambiará al reemplazar los cuentos de hadas. Solo se fijan dos tarjetas de servicio: para ajustar el volumen y sacrificar por la fuerza al erizo. El volumen, por cierto, se ajusta mediante el cambio secuencial de tres pasos (silencio - medio - alto).

En cuanto a los ojos ámbar, parpadean dos veces (en un ciclo) cuando el erizo se despierta, pero se calla y cambian de brillo cuando el erizo cuenta un cuento de hadas. Me pareció la mejor opción.

Durante el proceso de ensamblaje, probé otra innovación: dado que el banco de energía tiene dos conectores (entrada y salida), conecté el adaptador de carga inalámbrico Qi existente a la entrada. Y resultó que para recargar el erizo, no es necesario que lo desate, simplemente póngalo en un cargador inalámbrico por la noche. Sin embargo, solo esta función todavía está en modo de prueba.

En general, a pesar de la aparente simplicidad, algunas cosas me desconcertaron. Por ejemplo, desde el código, puede notar que envío algunos comandos al jugador varias veces seguidas, e incluso pongo un tiempo de espera al final. Y todo porque en la práctica en mi configuración la única forma es posible.

También se ve que, por alguna razón, controlo el final de la reproducción mediante la señal de hardware del reproductor, en lugar de activar el modo de reproducción de un solo archivo con un simple comando. Esto tampoco es así: por alguna razón, este modo no funciona para mí, así que cuando el final de una canción el reproductor comienza a reproducir la siguiente.

Puede parecer aún más curioso que la función aleatoria para reproducir una composición aleatoria se convierta constantemente en un bucle, en lugar de llamarse solo cuando realmente se necesita. Pero aquí está la cosa: si lo llama solo cuando es necesario, entonces, por alguna razón, en la gran mayoría de los casos, devuelve el mismo valor. Pero si se coloca en un bucle, se generan valores realmente pseudoaleatorios. En realidad, también me enteré en la práctica cuando traté de comprender el comportamiento inapropiado del erizo.

Finalmente, lo que me desconcertó por completo fue la incapacidad de hacer frente al apagado del lector de tarjetas utilizando el pin digital del controlador, desde el cual se alimenta el lector. Por alguna razón, resulta que si el pin se establece en BAJO y luego en ENTRADA, el lector no se apaga.

Al mismo tiempo, si simplemente establece BAJO, el LED del lector de tarjetas se "quema" por completo, el voltaje en la salida del estabilizador que alimenta al lector es de aproximadamente un voltio. Si luego en el pin del controlador hace ENTRADA, este voltaje aumenta a aproximadamente 3V.

Es aún más interesante que si primero configura los pines del controlador conectados al lector SS y RST en BAJO e INPUT, y luego coloca el pin de alimentación del controlador en la misma posición, el lector se apaga. E incluso entonces se enciende después de dormir, si el pin de alimentación se transfiere a SALIDA y ALTO.

Sin embargo, sucede algo irreparable con los temporizadores. Es decir, creo que sí, porque después de una finta (dormir con el lector apagado), los ojos y el contador de sacudidas funcionan de manera inadecuada, y ambos procesos están vinculados a millis (). No sé qué está sucediendo y cómo restaurar el temporizador, así que lo dejé como está: el lector de tarjetas continúa comiendo incluso durante el sueño.

Si los camaradas superiores ayudan a encontrar una salida, estaré muy agradecido. Aunque apenas creo que los camaradas mayores lean a este lugar.

En vista de lo anterior, el código del erizo de Evelyn es completamente imperfecto, pero siempre puede peinarlo (elija un código o un erizo usted mismo), optimizarlo, complementarlo, reducirlo o adaptarlo a sus necesidades. Por eso lo adjunto. Y para facilitar el uso de lo que es, la configuración máxima (probé todo en general, pero resultó como de costumbre) no está en el código, sino en la sección de definición de variables. Hay una configuración de pines, y retrasos de tiempo, y el número de pistas.

En la sección para describir los números de tarjeta, debe entenderse que las dos últimas tarjetas siempre están "reservadas" para funciones internas: cambio de volumen y modo de suspensión.

Programa de acción
/*  A0 -   MP3 (  )
 *  pin 0, 1 -   ()
 *  pin 2 -   
 *  pin 4 -   MP3 ( )
 *  pin 5 - 
 *  pin 6 -  
 *  pin 7, 8 -  MP3
 *  pin 9 -  
 *  pin 10 -  
 *  pin 11, 12, 13 - SPI 
 */ 


#include <Arduino.h>
#include <SoftwareSerial.h>
#include <JQ6500_Serial.h>
#include <avr/pgmspace.h> //  PROGMEM
#include <SPI.h>
#include <MFRC522.h>
#include <avr/sleep.h>
#include <avr/power.h>

#define adc_disable() (ADCSRA &= ~(1<<ADEN)) // disable ADC (before power-off) 
#define adc_enable() (ADCSRA |= (1<<ADEN)) // re-enable ADC

#define RST_PIN 9
#define SS_PIN 10
#define mp3Pin 4
#define mp3Busy A0
#define readerPin 6
#define tonePin 5
#define ledPin 3
#define offDelay 70000 //  
#define winkStep 1500 //   
#define on 150 //  ""
#define off 80 //  ""
#define tOut1 0 //         (x - / x1 -  )
#define tOut11 500
#define tOut2 14000
#define tOut21 15000
#define tOut3 29000
#define tOut31 30000
#define tOut4 44000
#define tOut41 45000
#define tOut5 60000
#define tOut51 65000
#define tShake 2000 //     
#define nShakeQ 10 //     
#define introQ 5 //  -
#define minVol 18 //  
#define midVol  22 //  
#define maxVol 25 //  


unsigned long dimDelay, winkStepDelay, onDelay, ledOffDelay, tShakeDelay;
boolean ledOn, ledOff, eyes, pwm;
int wink;
int pwmVal;

boolean playON = false;
boolean pwmUp = false;
byte pwmStep = 1;


unsigned int playFile;

MFRC522 mfrc522(SS_PIN, RST_PIN);       //  MFRC522
unsigned long uidDec, uidDecTemp; //       
byte bCounter, readBit, nShake, rnd;
byte vol = midVol; //     
unsigned long ticketNumber;
unsigned long offTimeOut = 0; //   
boolean mp3ON = false; //   
boolean isInt = false; //   

byte ticketQ = 32; //     (  -  )
byte fileQ = 0; //  MP3-

//    (  ,    ),         .   ,    
PROGMEM const uint32_t ticketSet[]  = {2515217196, 2540548337, 2490970856, 2486466332, 2485920633, 35870611, 37836807, 37836806, 2377004330, 2522873668, 2514304566, 23472725, 2485702426, 2374853555, 2374391583, 2492957469, 2486467162, 2489280075, 2488031661, 2491726641, 2491720188, 2490968782, 2490968783, 2488900952, 2489969016, 2506562651, 2375447052, 2375449579, 2489276180, 2483389692, 2486466331, 2484789326};

JQ6500_Serial mp3(8,7); //  

void enterSleep()
{
 mp3.playFileNumberInFolderNumber(01, 005); // -
 mp3.playFileNumberInFolderNumber(01, 005); // -
 delay(2500);
 tone(tonePin, 800, 500);
 delay(500); 
 digitalWrite(readerPin, LOW); 
 digitalWrite(mp3Pin, LOW);
 digitalWrite(ledPin, LOW);
 pinMode(ledPin, INPUT);
 pinMode(readerPin, INPUT);
 pinMode(mp3Pin, INPUT);
 
  adc_disable();

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  
  sleep_enable();
  
  sleep_mode();
  
 sleep_disable();
 power_all_enable();

 adc_enable();
 tone(tonePin, 450, 500);
 pinMode(ledPin, OUTPUT);
 pinMode(readerPin, OUTPUT);
 pinMode(mp3Pin, OUTPUT);
 digitalWrite(ledPin, LOW);
 digitalWrite(readerPin, HIGH); 
 digitalWrite(mp3Pin, HIGH);
 SPI.begin();            //  SPI
 mfrc522.PCD_Init();     //  MFRC522
 mp3Init();
 offTimeOut = millis();
 ledOffDelay = millis();
 mp3.playFileNumberInFolderNumber(01, 001); // -
 mp3.playFileNumberInFolderNumber(01, 001); // -
 delay(500);
 playON = false; 
 mp3ON = true;
}

void wakeUp() {
   detachInterrupt(0);
   ledOffDelay = millis();
   if (isInt == false) { //  
    isInt = true;
   }
   attachInterrupt(0, wakeUp, LOW); 
}

void setup() {
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, wakeUp, LOW);
  pinMode(readerPin, OUTPUT);  
  digitalWrite(readerPin, HIGH);
  SPI.begin();            //  SPI
  mfrc522.PCD_Init();     //  MFRC522
  pinMode(mp3Pin, OUTPUT);
  mp3Init();
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  eyes = false;
  ledOn = false;
  ledOff = false;
  dimDelay = millis();
  winkStepDelay = millis();
  wink = 0;
  pwmUp = true; //    
  pwmVal = 0;
  ledOffDelay = millis();
  offTimeOut = millis();  
  mp3.playFileNumberInFolderNumber(01, 001); // -
  mp3.playFileNumberInFolderNumber(01, 001); // -
  delay(500);
  playON = false; 
  mp3ON = true;
}

void loop() {

rnd = random(1, fileQ-1);

if ((millis() - offTimeOut) > offDelay) { //  

     enterSleep();

 } else { 

 ledWink(); //   


 if (isInt == true) {
  
  offTimeOut = millis(); //    -  ,    

  if (nShake == 0) {
    tShakeDelay = millis();
  }
  
  if ((millis() - tShakeDelay) < tShake){
    nShake = nShake + 1;
  } else {
    tShakeDelay = millis();
    nShake = 0;
  }

   isInt = false;
 }

 if (nShake > nShakeQ) {
  playRandom();
  nShake = 0;
 }

//    

playPreset(); //     


//   
  if (mp3ON == true) {
   
   if (playON == true) { //  ,   
    offTimeOut = millis(); //   
   }

   nShake = 0;

   eyesPWM(); //  
   

    //  MP3
    if(analogRead(mp3Busy) < 250) { //    -  ,  
     mp3ON = false; 
     playON = false;
     digitalWrite(ledPin, LOW);
    }
  }
  
 scanPlay(); //   
 
 }
}


void setBitsForGood(byte daBeat) {


  
        if (daBeat == 1) {
                bitSet(ticketNumber, bCounter);
                bCounter=bCounter+1;
                }
        else {
                bitClear(ticketNumber, bCounter);
                bCounter=bCounter+1;
        }
}

//    MP3
void mp3Init() {
  digitalWrite(mp3Pin, HIGH);
  delay(100);
  mp3.begin(9600);
  mp3.reset();
  mp3.setVolume(vol);
  mp3.setLoopMode(MP3_LOOP_NONE);

  fileQ = mp3.countFiles(MP3_SRC_SDCARD); //    
  fileQ = fileQ - introQ; //  

}


//   
void playRandom() {
   tone(tonePin, 450, 500);
   delay(500);  
   playFile = rnd;
   mp3ON = true;
   playON = true;
   mp3.playFileByIndexNumber(playFile);
   mp3.playFileByIndexNumber(playFile);
   mp3.playFileByIndexNumber(playFile);  
   delay(500);
}

// 
void ledWink() {

 //     
if ((millis() - winkStepDelay) > winkStep) { //  

// 
  if (eyes == true) { //   

    if (ledOn == false) {
      onDelay = millis(); //  
        ledOn = true; //  ,   
    }
 
    if ((millis() - onDelay) > on) { //   
      digitalWrite(ledPin, LOW); //   
      eyes = false; //   
    }

  }

// 
  if (eyes == false) { //   
    
    if (ledOff == false) {
      ledOffDelay = millis(); //  
        ledOff = true; //  ,   
    }

    if ((millis() - ledOffDelay) > off) { //   
      digitalWrite(ledPin, HIGH); //  
      eyes = true; //   
    }
  }

  if (ledOn == true && ledOff == true) { //    (  /)
    wink = wink+1;
    ledOn = false;
    ledOff = false;    
  }

  if (wink == 4) { //   /
     winkStepDelay = millis();
     wink = 0;
 }

 }

}

//     
void playPreset() {

 if (mp3ON == false) {
  
  if ((millis() - offTimeOut) > tOut2 && (millis() - offTimeOut) < tOut21) {
    mp3.playFileNumberInFolderNumber(01, 002); //   /001/002.mp3      tOut21 .
    mp3ON = true; 
    delay(500);
  }

  if ((millis() - offTimeOut) > tOut3 && (millis() - offTimeOut) < tOut31) {
    mp3.playFileNumberInFolderNumber(01, 003); //   /001/003.mp3      tOut31 .
    mp3ON = true;
    delay(500);
   }  

  if ((millis() - offTimeOut) > tOut4 && (millis() - offTimeOut) < tOut41) {
    mp3.playFileNumberInFolderNumber(01, 004); //   /001/004.mp3      tOut41 .
    mp3ON = true;  
    delay(500); 
  }    

    
 }
  
}


// 
void eyesPWM(){

 if ((millis() - winkStepDelay) > (pwmStep)/4) {
   //     MP3 
    if (pwmUp == true) {
      if (pwmVal < 128) { //   254 -    (    255,      )
        analogWrite(ledPin, pwmVal);
        pwmVal = pwmVal + 1;
        pwmStep = pwmStep - 1;
        winkStepDelay = millis();
      } else {
            pwmUp = false;
            pwmStep = 1;
            pwmVal = 128;
      } 
    }
    
    if (pwmUp == false) {
      if (pwmVal > pwmStep) {
        analogWrite(ledPin, pwmVal);
        pwmVal = pwmVal - 1;
        pwmStep = pwmStep +1 ;
        winkStepDelay = millis();
      } else {
            pwmUp = true;
            pwmStep = 128;
            pwmVal = 1;
      } 
    }
    }
  
}

//   
void scanPlay() {

 if (fileQ > 0) {
          //   
        if ( ! mfrc522.PICC_IsNewCardPresent()) {
                return;
        }

        //  
        if ( ! mfrc522.PICC_ReadCardSerial()) {
                return;
        }

        uidDec = 0;

//   ,   

        byte status;
        byte byteCount;
        byte buffer[18]; //   (16  + 2   ) 
        byte pages[2]={4, 8}; //   
        byte pageByte; //   
        
        byteCount = sizeof(buffer);
        byte bCount=0;
                

        mfrc522.MIFARE_Read(4, buffer, &byteCount);
        
          
                                bCounter = 0; // 32-   
                                
                                //  0-3
                                for (bCount=0; bCount<4; bCount++) {
                                        readBit = bitRead(buffer[6], (bCount+4));
                                        setBitsForGood(readBit);
                                }

                                //  4 - 27
                                for (pageByte=5; pageByte > 2; pageByte--) {
                                        for (bCount=0; bCount<8; bCount++) {
                                                readBit = bitRead(buffer[pageByte], bCount);
                                                setBitsForGood(readBit);
                                        }
                                }

                                //  28-31
                                for (bCount=0; bCount<4; bCount++) {
                                        readBit = bitRead(buffer[2], bCount);
                                        setBitsForGood(readBit);
                                }

                               for (byte ticketNum = 0; ticketNum < ticketQ; ticketNum++) {
                                unsigned long ticketTemp = pgm_read_dword_near(ticketSet + ticketNum);
                                if (ticketTemp == ticketNumber) {
                                  tone(tonePin, 450, 500);
                                  delay(500); 
                                  if (ticketNum < (ticketQ - 2)) {
                                    if ((ticketNum+1) < fileQ) {
                                      digitalWrite(ledPin, HIGH);
                                       playFile = ticketNum+1;
                                      mp3ON = true;
                                      playON = true;
                                      mp3.playFileByIndexNumber(playFile);
                                      mp3.playFileByIndexNumber(playFile);
                                      mp3.playFileByIndexNumber(playFile);
                                      delay(500);
                                      }
                                      return;
                                  } else {
                                    if (ticketNum == ticketQ-1) {
                                      enterSleep(); // 
                                    }
                                    if (ticketNum == ticketQ-2) {
                                      setVol(); //  
                                    }
                                  }
                                  
                                }
                               }
                        // }
                
        // Halt PICC
    mfrc522.PICC_HaltA();    


  }
  
}

//    
void setVol() {

  switch (vol) {
    case maxVol:
      vol = minVol;
      break;
    case midVol:
      vol = maxVol;
      break;
    case minVol:
      vol = midVol;
      break;
  } 

  mp3.setVolume(vol);
  
}




Un diagrama aproximadamente restaurado por el código debería tener este aspecto (pido disculpas si mis errores permanecieron en algún lugar):





Aquí:

  • U1 = ATmega328p
  • UHT7333 = HT7333
  • C1 = 0,1
  • R2 = ~50
  • R3 = 220
  • R4 = 1
  • M1 =
  • R4 = 1
  • SP1 = 8
  • Piezo =
  • T1 = NPN- 0,3
  • U2 = JQ6500 : 1 — TX, 2 — RX, 3 — GND, 4 — VCC, 5 — BUSY, 6 — SPK+, 7 — SPK -


Habrauser Chigin , por lo que muchas gracias a él, mejoró notablemente y ordenó toda esta economía. Pero tenga en cuenta que el transistor PNP ya está aquí, y la administración de energía del reproductor debe invertirse (es decir, con esta conexión, el reproductor se enciende bajo en el pin del controlador y se apaga - alto):



con la configuración actual, una batería con una capacidad de aproximadamente 2500 mAh dura aproximadamente un día usa un erizo. Sin decir mucho, pero debes entender que el horario siempre es diferente y espero que la mayor parte de la energía se gaste en el modo activo. Lo que en cierta medida nos permite descuidar la retirada completa fallida de todos los dispositivos electrónicos hedgehog en reposo.

Si se da el problema de calcular el presupuesto aproximado, obtendrá algo como esto (en USD):

  • Jugador: 8.9
  • ATmega328p: 1.1
  • Junta de desarrollo: 0.28
  • Lector RC522: 2.21
  • Cabezal Dinámico: 0.99
  • Emisor piezocerámico: 0,77
  • LED: 0.12
  • Transistor: 0.14
  • Estabilizador: 0.13
  • Sensor de vibración: 0.13
  • Jabonera: 0.99
  • Powerbank: 0,75
  • Batería 18650: 3.9
  • Adaptador de carga Qi: 1.65
  • Tarjeta de memoria: 3
  • Erizo Evelyn: 6


Un total de 31.06, pero de hecho un poco más, porque todavía necesita un cable para las conexiones y otras pequeñas cosas como adhesivo termofusible, cinta de doble cara y cinta aislante azul.

Probablemente debe haber algún tipo de frase final especialmente importante, pero definitivamente no lo tengo en mi cabeza. Probablemente tenga sentido decir que el niño está bastante contento con el juguete, y esto es definitivamente mejor (y a menudo más rápido) que encender la computadora portátil.

ps. Soy consciente de los altavoces Bluetooth, es un poco diferente, incluso si pones un erizo tan lindo.

Source: https://habr.com/ru/post/es395423/


All Articles