Ouriço - pássaro falante [se estiver com um MP3 player]



Há muito tempo, tanto que parece falso, o masterkit falou sobre um maravilhoso tocador de MP3 embutido que pode ser equipado com qualquer coisa, até mesmo tocadores de MP3, se você primeiro remover o seu e depois colocá-lo. Em suma, uma coisa útil. Especialmente se você quiser fazer brinquedos para crianças, primeiro com suas próprias mãos e, em segundo lugar, corretamente, e não da maneira como pensam aqueles que os fazem em escala industrial.

No entanto, no produto apresentado, fiquei satisfeito não apenas com tudo, então pensei: não é possível que a aparência chinesa não esteja no Aliexpress. De fato, havia um certo número desses players e a familiarização com a gama de modelos mostrou que existem opções mais atraentes do que modelos com uma quantidade fixa de memória. Ou seja - com um slot para cartões microSD removíveis.

E lá vamos nós.



Para deixar claro o que e para onde foi, uma demonstração de ouriço em vários modos.

Frases divertidas enquanto aguarda:



Ativando e desativando o volume com cartões e agitando:



Carregamento sem fio:



Antes de continuar a história, peço desculpas por apresentar algumas imprecisões na descrição e nos circuitos, porque no processo não documentei nada, por assim dizer, com um palpite. Por favor, use o bom senso e materiais práticos para que mais tarde não seja dolorosamente doloroso.

Então, depois de uma breve pesquisa e comparação, mudei para o Ebay, onde consegui o que queria - um player com um chip decodificador JQ6500, 4 megabytes de memória interna e um slot microSD .



Por que exatamente esse jogador? Porque então me pareceu que esta é uma opção ideal para o trabalho caseiro. Porque está tudo com ele. Se desejar, use-o separadamente: para isso, existem pinos de reprodução / pausa, alternância de faixas, volume, reprodução rápida de cinco faixas e um mono amplificador para conectar o alto-falante diretamente à placa (há também uma saída estéreo, mas ele já precisa de um amplificador externo). Ou seja, pelo menos bateria, alto-falante, alguns botões e um cartão de memória com música.

imagem

Mas muito mais interessante é o controle completo do jogador através de alguma aparência de uma porta serial. Aqui você pode fazer qualquer coisa - tocar, parar, alterar o volume, alternar os modos de equalizador e de reprodução, começar a reproduzir músicas arbitrárias na ordem "direta" e em determinadas pastas. E, importante no meu caso, já havia uma biblioteca pronta para o Arduino.

Portanto, dois componentes já são conhecidos: player e Arduino. Mas, pessoalmente, eu não queria parar por aí, porque é estúpido imitar botões com um microcontrolador inteiro. Algo especial é necessário para que, com Emely, por assim dizer, faça piques.

Portanto, adicionamos aqui o sensor de vibração mais simples SW-18010P e o conhecido leitor de cartão RC522.

imagem

Tudo apenas para me livrar completamente dos botões, que no brinquedo divertido eu achei desnecessário. Julgue por si mesmo: se houver botões, a criança de alguma forma os pressiona e com mais frequência - por acidente do que conscientemente. Mas a troca super-frequente de contos de fadas ainda não está certa.

imagem

Aqui se mostra como: o sensor de vibração serve para ligar o brinquedo quando a criança o pega. O mesmo sensor não permitirá que o brinquedo seja desligado até que a criança o instale por um tempo suficientemente longo. Quanto ao leitor de cartão Mifare, isso é extremamente conveniente para trocar contos de fadas. Por exemplo, os cartões podem ser anexados aos livros e a criança poderá ouvir o conto de fadas, trazendo o brinquedo para o livro.

E também podem ser anexados cartões a vários assuntos, e a criança poderá ouvir sua descrição e regras de uso. Por exemplo, que esta figovina branca é uma geladeira e que armazenamos alimentos lá para que não se deteriorem, e que, por esse motivo, não vale a pena abri-la. Ou que este é o forno e pode estar quente, para que você não precise se segurar na alça e colocar as mãos no vidro. Muitas coisas podem ser inventadas, especialmente porque os cartões são usados ​​bilhetes de metrô (sim, tenho sorte, estou em Moscou), que podem ser facilmente coletados na quantidade certa.

Então, enquanto eu pensei que casualmente retirado do controlador de inventário ATmega328P , soldada para um xale desenvolvimento e costurar Adruino loader através do Arduino mega 2560.

imagem

Por conveniência, levei a porta serial, a redefinição e o aterramento para um conector separado para rápida reprogramação. E então eu me conheço - preencherei o esboço e então um não está certo, o outro está errado.

Um estabilizador de 3,3V também foi soldado ao lado, já que o RC522, devido a um mal-entendido, é alimentado por essa tensão, enquanto o restante dos componentes se sente muito bem no 5V universal, que eu esperava usar em um banco de potência simples com baterias 18650 .

imagem

uma bateria descarregada típica pode parecer contra-intuitiva. Mas eu pensei que, como o brinquedo consumirá uma corrente decente (apenas o controlador e o player no modo de espera consomem cerca de 40 mA), a capacidade de substituir rapidamente uma bateria vazia por uma cheia é muito útil.

E também tive que adicionar um tweeter piezocerâmico para indicação sonora de alguns eventos (ler um cartão, por exemplo). Você diz que isso geralmente é engraçado - existe um palestrante, certo? Bem, sim, não é assim. Afinal, o alto-falante está conectado ao aparelho e não ao controlador. E ele adicionou um transistor como chave, que desliga o MP3 player durante o sono, para reduzir o consumo de energia.

Um leitor atento pode perceber que o player pode ser alimentado por um pino do controlador digital, o que seria perfeitamente adequado para ligar e desligar. Eu gostaria, mas é apenas no modo de espera que o jogador consome 16 mA. E quando a música leva facilmente mais de 100 mA, o que já é pelo menos o dobro da capacidade do ATmega. Portanto, peguei "qualquer" transistor npn com uma corrente de coletor de 300 mA e o trouxe ao pino digital do controlador através de um resistor de cerca de 200 ohms.

Mas o leitor de cartões consome em 40 mA, para que o estabilizador que o alimenta possa ser conectado ao pino digital do controlador. Ele fez isso, mas ainda não funcionou, sobre o que - no final.

Outro ponto: o jogador exige uma cabeça dinâmica com uma resistência de pelo menos 8 ohms. Eu tinha um (um alto-falante da unidade de sistema), mas o som dela não é muito bom. Havia também alto-falantes com resistência de 4 ohms (de um falante típico chinês). Em geral, conectei os dois em série: um dá mais alto, o outro dá baixo, e juntos eles soam legais.

Permaneceu um pouco, ou seja, espelho da alma. O que é mais fácil de fazer a partir de um par de LEDs conectados em série. Não tomei o vermelho brutal - é muito assustador. Mas olhos amarelo-âmbar - é isso.

Assim, o modelo do brinquedo é montado e depurado. Agora a coisa mais importante: você precisa de um doador de corpo. Na verdade, eu realmente queria um pássaro faladormas, a julgar pelo preço dos brinquedos vizinhos, o prazer não é inteiramente orçamentário. Especialmente quando você considera que o interesse da criança é algo imprevisível.

Portanto, para começar, comecei a procurar um candidato mais acessível para transplante. E um foi encontrado: o encantador ouriço Evelyn , vendido no Mundo das Crianças.

imagem

Claro, eu tive que me livrar quase completamente do rico mundo interior do ouriço. E substitua-o por um caseiro, embalado em uma saboneteira comum. No entanto, não é muito comum. O fato é que, diferentemente de muitos, essa saboneteira tem um verso plano, por isso é conveniente colocar um leitor de cartão lá - você tem uma distância mínima. Por outro lado, a saboneteira tem algo como uma escova de massagem e até tem furos, ou seja, o alto-falante é idealmente colocado ali: o som sai através de aberturas que não serão bloqueadas por picos de massagem. Os buracos, no entanto, acabaram não sendo suficientes, mas isso não importa - eu ainda perfurei.



A coisa mais difícil, devo admitir, foi a cirurgia para o ouriço. Em primeiro lugar, eu não gosto de costurar. E tive que decentemente: primeiro eu a rasgo, depois apertava as bordas, depois costurava seis botões. Então ele soltou seis botões e costurou quatro. Por que tudo? Porque no começo eu costurei pequeno e errado, então o ouriço foi desatado.



Em segundo lugar, os olhos. Obviamente, adquiri prudentemente os LEDs com um diâmetro de 3 mm, para garantir que eles retratassem as pupilas. No entanto, não era tão fácil fazer furos nos olhos existentes do ouriço de Evelyn. Parece: você pega um gravador, coloca a broca certa nele - e vai embora. Porém, durante a perfuração, o plástico se transforma em uma massa viscosa, onde a broca de um gravador fraco fica presa.

E, devo dizer, um ouriço com uma broca saindo do olho é um espetáculo infernal.

A propósito, eu nem sei o que aconselhar sobre isso. De alguma forma, torci e ainda fiz buracos, inseri LEDs neles e preenchi com epóxi e cobri com esmalte incolor por cima. Os olhos também foram colados ao ouriço com epóxi, pois a montaria nativa morreu durante o processo de perfuração. O resultado não foi perfeito, mas bastante suportável.

Como o ouriço funciona, você já viu. Portanto, só posso duplicar o texto de sua lógica atual. Inicialmente, o ouriço está no modo de suspensão. Se você pegá-lo (ou simplesmente movê-lo, ou mover a superfície sobre a qual está, etc.), ele será ativado por uma interrupção que gerará um sensor de vibração.

Depois disso, em intervalos pré-determinados, o ouriço falará frases predefinidas e, se você não tocar no ouriço por algum tempo, ele adormecerá novamente. E se você tocá-lo, não vai adormecer. E se você agitar por um tempo, começará a contar um conto de fadas, escolhido aleatoriamente.

Se você levar um cartão para o ouriço (quando ele não estiver dormindo), o ouriço começará a contar uma história associada a esse cartão. Não há ligação rígida, a ordem mudará ao substituir os contos de fadas. Apenas dois cartões de serviço são fixos: para ajustar o volume e sacrificar à força o ouriço. A propósito, o volume é ajustado pela troca seqüencial de três etapas (baixo - médio - alto).

Quanto aos olhos cor de âmbar, eles piscam duas vezes (em um ciclo) quando o ouriço acorda, mas fica em silêncio e muda de brilho quando o ouriço conta um conto de fadas. Pareceu-me a melhor opção.

Durante o processo de montagem, tentei outra inovação: como o banco de potência possui dois conectores (entrada e saída), conectei o adaptador de carregamento sem fio Qi existente à entrada. E assim, para recarregar o ouriço, você não precisa desapertá-lo - basta colocá-lo em um carregador sem fio durante a noite. No entanto, apenas esta função ainda está no modo de teste.

Em geral, apesar da aparente simplicidade, algumas coisas me intrigaram. Por exemplo, no código, você pode perceber que eu envio alguns comandos para o jogador várias vezes seguidas e até coloco um tempo limite no final. E tudo porque, na prática, na minha configuração, a única maneira possível.

Também é visto que, por algum motivo, eu controlo o final da reprodução pelo sinal de hardware do player, em vez de ativar o modo de reprodução de apenas um arquivo com um comando simples. Também não é assim: por alguma razão, esse modo não funciona para mim; portanto, quando o final de uma música, o player começa a tocar a próxima.

Pode parecer ainda mais curioso que a função aleatória para reproduzir uma composição aleatória gire constantemente em um loop, em vez de ser chamada apenas quando for realmente necessária. Mas eis o seguinte: se você o chamar apenas quando for necessário, por algum motivo, na grande maioria dos casos, ele retornará o mesmo valor. Mas se você colocar um loop, serão gerados valores realmente pseudo-aleatórios. Na verdade, também descobri na prática quando tentei entender o comportamento inadequado do ouriço.

Finalmente, o que me deixou completamente desconcertado foi a incapacidade de lidar com o desligamento do leitor de cartões usando o pino digital do controlador, do qual o leitor é alimentado. Por alguma razão, acontece que, se o pino estiver definido como LOW e depois em INPUT, o leitor não será desligado.

Ao mesmo tempo, se você simplesmente definir LOW, o LED do leitor de cartão “queima” completamente, a tensão na saída do estabilizador que fornece o leitor é de cerca de um volt. Se, então, no pino do controlador fizer INPUT, essa tensão aumenta para cerca de 3V.

É ainda mais interessante que, se você definir primeiro os pinos do controlador conectados ao leitor SS e RST como LOW e INPUT e depois colocar o pino de energia do controlador na mesma posição, o leitor será desligado. E mesmo assim ele liga após o sono, se o pino de energia for transferido para OUTPUT e HIGH.

No entanto, algo irreparável com temporizadores acontece. Ou seja, acho que sim, porque depois de uma finta (dormir com o leitor desligado), os olhos e o contador de vibrações funcionam inadequadamente, e esses dois processos estão ligados a milis (). Não sei o que está acontecendo e como restaurar o cronômetro, então deixei como está - o leitor de cartões continua a comer mesmo durante o sono.

Se camaradas seniores ajudarem a encontrar uma saída, ficarei muito agradecido. Embora eu mal acredite que camaradas mais velhos vão ler sobre este lugar.

Em vista do exposto, o código do ouriço de Evelyn é completamente imperfeito, mas você sempre pode combiná-lo (escolha um código ou um ouriço), otimizar, complementar, reduzir ou adaptar de qualquer outra forma às suas necessidades. É por isso que estou anexando. E, para facilitar o uso do que é, o máximo de configurações (tentei de tudo em geral, mas como de costume) não está no código, mas na seção de definição de variáveis. Há uma configuração de pinos, atrasos de tempo e número de faixas.

Na seção para descrição dos números de cartões, deve-se entender que os dois últimos cartões são sempre "reservados" para funções internas - alternar o volume e o modo de suspensão.

Programa de ação
/*  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);
  
}




Um diagrama aproximadamente restaurado pelo código deve ficar assim (peço desculpas se meus erros permaneceram em algum lugar):





Aqui:

  • 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 , pelo qual muitos agradecimentos a ele, melhorou visivelmente e colocou toda essa economia em ordem. Mas observe que o transistor PNP já está aqui e o gerenciamento de energia do player deve ser invertido (ou seja, com essa conexão, o player liga pouco no pino do controlador e desliga - alto):



com a configuração atual, uma bateria com capacidade de cerca de 2500 mAh é suficiente por cerca de um dia use um ouriço. Para não dizer muito, mas você precisa entender que o cronograma é sempre diferente e a maior parte da energia é gasta, espero, no modo ativo. O que, em certa medida, nos permite negligenciar a completa falha na retirada de todos os eletrônicos do ouriço para dormir.

Se você se dá ao trabalho de calcular o orçamento aproximado, obtém algo parecido com isto (em dólares americanos):

  • Jogador: 8.9
  • ATmega328p: 1.1
  • Placa de desenvolvimento: 0.28
  • Leitor RC522: 2.21
  • Cabeça dinâmica: 0,99
  • Emissor piezocerâmico: 0,77
  • LEDs: 0,12
  • Transistor: 0,14
  • Estabilizador: 0,13
  • Sensor de vibração: 0,13
  • Saboneteira: 0,99
  • Banco de potência: 0,75
  • Bateria 18650: 3.9
  • Adaptador de carregamento Qi: 1,65
  • Cartão de memória: 3
  • Ouriço Evelyn: 6


Um total de 31,06, mas na verdade um pouco mais, porque você ainda precisa de um fio para conexões e outras pequenas coisas, como adesivo hot melt, fita dupla face e fita elétrica azul.

Provavelmente deve haver algum tipo de frase final especialmente importante, mas eu definitivamente não tenho isso na minha cabeça. Provavelmente faz sentido dizer que a criança está muito feliz com o brinquedo, e isso é definitivamente melhor (e geralmente mais rápido) do que ligar o laptop.

ps. Estou ciente dos alto-falantes Bluetooth, é um pouco diferente, mesmo se você colocar um ouriço tão fofo.

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


All Articles