Igel - sprechender Vogel [wenn mit einem MP3-Player]



Vor langer Zeit, so sehr, dass es bereits unwahr erscheint, sprach Masterkit über einen wunderbaren eingebauten MP3-Player , der mit allem ausgestattet werden kann, auch mit MP3-Playern, wenn Sie zuerst Ihren eigenen entfernen und dann diesen aufsetzen . Kurz gesagt, eine nützliche Sache. Vor allem, wenn Sie ein Kinderspielzeug zum einen mit Ihren eigenen Händen und zum anderen richtig herstellen möchten und nicht so, wie diejenigen, die es im industriellen Maßstab herstellen.

In dem vorgestellten Produkt war ich jedoch nicht nur mit allem zufrieden, sondern dachte auch: Es kann nicht so sein, dass das chinesisch aussehende Ding nicht bei Aliexpress war. In der Tat gab es eine bestimmte Anzahl solcher Player, und die Kenntnis der Modellpalette zeigte, dass es Optionen gibt, die attraktiver sind als Modelle mit einer festen Speichermenge. Nämlich - mit einem Steckplatz für austauschbare microSD-Karten.

Und los geht's.



Um klar zu machen, was und wohin es ging, eine Igel-Demo in verschiedenen Modi.

Unterhaltsame Sätze während des Wartens:



Geschichten ein- und ausschalten, Lautstärke mit Karten ein- und ausschalten und schütteln:



Drahtloses Laden:



Bevor ich die Geschichte fortsetze, entschuldige ich mich, dass ich einige Ungenauigkeiten in der Beschreibung und den Schaltkreisen machen kann, weil ich dabei sozusagen nichts ahnungsvoll dokumentiert habe. Bitte verwenden Sie gesunden Menschenverstand und praktische Materialien, damit es später nicht unerträglich schmerzhaft wird.

Nach einer kurzen Suche und einem kurzen Vergleich wechselte ich zu Ebay, wo ich das bekam, was ich wollte - einen Player mit einem JQ6500-Decoder-Chip, 4 Megabyte internem Speicher und einem microSD-Steckplatz .



Warum genau dieser Spieler? Denn dann schien es mir, dass dies eine ideale Option für hausgemachte Arbeit ist. Weil alles bei ihm ist. Wenn Sie möchten, verwenden Sie es separat: Hierfür gibt es Wiedergabe- / Pausenstifte, Schaltspuren, Lautstärke, schnelle Wiedergabe von fünf Spuren und einen Monoverstärker zum direkten Anschließen des Lautsprechers an die Karte (es gibt auch einen Stereoausgang, aber es wird bereits ein externer Verstärker benötigt). Das heißt, zumindest genug Batterie, Lautsprecher, ein paar Tasten und eine Speicherkarte mit Musik.

Bild

Viel interessanter ist jedoch die vollständige Kontrolle des Players durch den Anschein einer seriellen Schnittstelle. Hier können Sie alles tun - abspielen, anhalten, die Lautstärke ändern, den Equalizer- und Wiedergabemodus wechseln, beliebige Songs sowohl in der Reihenfolge „durch“ als auch aus bestimmten Ordnern abspielen. Und vor allem in meinem Fall gab es bereits eine fertige Bibliothek für Arduino.

Es sind also bereits zwei Komponenten bekannt: Player und Arduino. Aber ich persönlich wollte hier nicht aufhören, weil es dumm ist, dumm zu sein, Tasten mit einem ganzen Mikrocontroller zu imitieren. Es wird etwas Besonderes benötigt, damit mit Emely sozusagen und Hechten.

Deshalb haben wir hier den einfachsten Vibrationssensor SW-18010P und den bekannten Kartenleser RC522 hinzugefügt.

Bild

Alles nur, um die Knöpfe komplett loszuwerden, was ich in dem unterhaltsamen Spielzeug für unnötig hielt. Überzeugen Sie sich selbst: Wenn es Knöpfe gibt, drückt das Kind sie irgendwie und öfter - eher zufällig als bewusst. Aber das sehr häufige Wechseln von Märchen ist immer noch nicht ganz richtig.

Bild

Hier stellt sich heraus, wie: Der Vibrationssensor dient dazu, das Spielzeug einzuschalten, wenn das Kind es aufhebt. Mit demselben Sensor kann das Spielzeug erst ausgeschaltet werden, wenn das Kind es ausreichend lange angelegt hat. Was den Mifare-Kartenleser betrifft, so ist dieses Ding meiner Meinung nach äußerst praktisch, um Märchen zu wechseln. Zum Beispiel können Karten an Bücher angehängt werden, und dann kann das Kind das Märchen hören, indem es das Spielzeug zum Buch bringt.

Außerdem können Karten an verschiedene Themen angehängt werden, und dann kann das Kind ihre Beschreibung und Nutzungsregeln anhören. Zum Beispiel, dass diese weiße Figur ein Kühlschrank ist und dass wir Lebensmittel dort aufbewahren, damit sie sich nicht verschlechtern, und dass es sich aus diesem Grund nicht lohnt, sie zu öffnen. Oder dass dies der Ofen ist und er heiß sein kann, sodass Sie nicht an seinem Griff hängen und Ihre Hände auf das Glas legen müssen. Viele Dinge können erfunden werden, insbesondere da die Karten U-Bahn-Tickets sind (ja, ich bin glücklich, ich bin in Moskau), die leicht in der richtigen Menge gesammelt werden können.

Während ich nachdachte, nahm ich in der Zwischenzeit den ATmega328p- Controller aus dem Lager , löte ihn auf das Steckbrett und ließ den Adruino-Bootloader durch den Arduino Mega 2560 flashen.

Bild

Der Einfachheit halber habe ich die serielle Schnittstelle, den Reset und die Erdung zur schnellen Neuprogrammierung an einen separaten Anschluss angeschlossen. Und dann kenne ich mich selbst - ich werde die Skizze ausfüllen, und dann ist einer nicht richtig, der andere ist falsch.

Daneben wurde auch ein 3,3-V-Stabilisator verlötet, da der RC522 aufgrund eines Missverständnisses mit dieser Spannung betrieben wird, während sich die restlichen Komponenten beim universellen 5-V-Stabilisator großartig anfühlen, den ich von einer einfachen Powerbank mit 18650- Batterien erwartet hatte .

Bild

Die Entscheidung, eine solche Powerbank anstelle von zu verwenden Eine typische leere Batterie scheint nicht intuitiv zu sein. Aber ich dachte, da das Spielzeug ziemlich ordentlichen Strom verbraucht (nur der Controller und der Player im Standby-Modus verbrauchen ungefähr 40 mA), ist die Möglichkeit, eine leere Batterie schnell durch eine volle zu ersetzen, sehr hilfreich.

Außerdem musste ich einen piezokeramischen Hochtöner hinzufügen, um einige Ereignisse akustisch anzuzeigen (z. B. Lesen einer Karte). Das, sagen Sie, ist im Allgemeinen lustig - es gibt einen Sprecher, oder? Ja, nicht so. Immerhin ist der Lautsprecher an den Player und nicht an den Controller angeschlossen. Und er fügte einen Transistor als Schlüssel hinzu, der den MP3-Player im Ruhezustand ausschaltet, um den Energieverbrauch zu senken.

Ein aufmerksamer Leser kann feststellen, dass der Player über einen digitalen Controller-Pin mit Strom versorgt werden kann, der sich perfekt zum Ein- und Ausschalten eignet. Ich würde es selbst mögen, aber nur im Standby-Modus verbraucht der Player 16 mA. Und wenn die Musik, dauert es leicht mehr als 100 mA, was bereits mindestens doppelt so viel Kapazität wie ATmega ist. Daher nahm ich "jeden" npn-Transistor mit einem Kollektorstrom von 300 mA und brachte ihn über einen Widerstand von etwa 200 Ohm an den digitalen Pin des Controllers.

Der Kartenleser verbraucht jedoch weniger als 40 mA, sodass der Stabilisator, der ihn speist, an den digitalen Pin des Controllers angeschlossen werden kann. Er tat es, arbeitete aber immer noch nicht, worüber - am Ende.

Ein weiterer solcher Punkt: Der Spieler benötigt einen dynamischen Kopf mit einem Widerstand von mindestens 8 Ohm. Ich hatte einen (einen Lautsprecher von der Systemeinheit), aber ihr Sound ist nicht sehr gut. Es gab auch Lautsprecher mit einem Widerstand von 4 Ohm (von einem typischen chinesischen Sprecher). Im Allgemeinen habe ich beide in Reihe geschaltet: einer gibt mehr hoch, der andere gibt niedrig und zusammen klingen sie einfach cool.

Blieb eine Kleinigkeit, d.h. Spiegel der Seele. Welches ist am einfachsten aus einem Paar in Reihe geschalteter LEDs zu machen. Ich habe kein brutales Rot genommen - es ist sehr beängstigend. Aber bernsteingelbe Augen - das war's.

So wird das Modell des Spielzeugs zusammengebaut und debuggt. Jetzt das Wichtigste: Sie brauchen einen Körperspender. Eigentlich wollte ich wirklich einen SprechervogelAber nach dem Preis benachbarter Spielzeuge zu urteilen, ist das Vergnügen nicht ganz budgetär. Besonders wenn man bedenkt, dass das Interesse des Kindes unvorhersehbar ist.

Daher suchte ich zunächst nach einem günstigeren Kandidaten für eine Transplantation. Und einer wurde gefunden: der charmante Igel Evelyn , der in der Kinderwelt verkauft wird.

Bild

Natürlich musste ich die reiche innere Welt des Igels fast vollständig loswerden. Und ersetzen Sie es durch ein hausgemachtes, verpackt in einer gewöhnlichen Seifenschale. Allerdings nicht ganz gewöhnlich. Tatsache ist, dass diese Seifenschale im Gegensatz zu vielen anderen eine flache Rückseite hat. Daher ist es praktisch, einen Kartenleser dort zu platzieren - Sie erhalten einen Mindestabstand. Andererseits hat die Seifenschale so etwas wie eine Massagebürste und sogar Löcher, d.h. Der Lautsprecher ist dort ideal platziert: Der Ton wird durch Öffnungen ausgegeben, die nicht durch Massagespitzen blockiert werden. Die Löcher erwiesen sich jedoch als nicht genug, aber es spielt keine Rolle - ich bohrte immer noch.



Das Schwierigste, muss ich zugeben, war die Operation für den Igel. Erstens nähe ich nicht gern. Und ich musste anständig: zuerst reiße ich es auseinander, befestige dann die Kanten zusammen und nähe dann sechs Knöpfe. Dann ließ er sechs Knöpfe los und nähte vier Knöpfe. Warum alle? Weil ich zuerst klein und falsch genäht habe, war der Igel gelöst.



Zweitens die Augen. Natürlich habe ich die LEDs mit einem Durchmesser von 3 mm umsichtig erworben, damit sie garantiert die Pupillen darstellen. Es war jedoch nicht so einfach, Löcher in die vorhandenen Augen von Evelyns Igel zu bohren. Es scheint: Sie nehmen einen Graveur, setzen den richtigen Bohrer ein - und gehen. Es stellte sich jedoch heraus, dass sich der Kunststoff beim Bohren in eine viskose Masse verwandelt, in der der Bohrer eines schwachen Graveurs festsitzt.

Und ich muss sagen, ein Igel mit einem Bohrer aus dem Auge ist ein höllisches Schauspiel.

Ich weiß übrigens nicht einmal, was ich dazu raten soll. Ich drehte mich irgendwie und machte immer noch Löcher, steckte LEDs in sie und füllte sie mit Epoxidharz und bedeckte sie mit farblosem Nagellack. Die Augen wurden auch mit Epoxidharz auf den Igel geklebt, da das einheimische Reittier während des Bohrvorgangs starb. Das Ergebnis war nicht perfekt, aber durchaus erträglich.

Wie der Igel funktioniert, haben Sie bereits gesehen. Daher kann ich nur den Text seiner aktuellen Logik duplizieren. Der Igel befindet sich zunächst im Schlafmodus. Wenn Sie es aufheben (oder einfach bewegen oder die Oberfläche bewegen, auf der es liegt usw.), wird es durch einen Interrupt geweckt, der einen Vibrationssensor erzeugt.

Danach spricht der Igel in festgelegten Intervallen vordefinierte Sätze, und wenn Sie den Igel einige Zeit nicht berühren, schläft er wieder ein. Und wenn Sie es berühren, wird es nicht einschlafen. Und wenn Sie es für eine Weile schütteln, wird es ein Märchen erzählen, das zufällig ausgewählt wird.

Wenn Sie dem Igel eine Karte bringen (wenn er nicht schläft), beginnt der Igel eine Geschichte zu erzählen, die mit dieser Karte verbunden ist. Es gibt keine starre Bindung, die Reihenfolge ändert sich beim Ersetzen von Märchen. Es sind nur zwei Servicekarten festgelegt: zum Einstellen der Lautstärke und zum gewaltsamen Einschläfern des Igels. Die Lautstärke wird übrigens durch sequentielles Umschalten von drei Schritten (leise - mittel - laut) eingestellt.

Bernsteinfarbene Augen blinken zweimal (im Zyklus), wenn der Igel aufwacht, schweigen jedoch und ändern ihre Helligkeit, wenn der Igel ein Märchen erzählt. Es schien mir die beste Option zu sein.

Während des Montageprozesses habe ich eine andere Innovation ausprobiert: Da die Power Bank über zwei Anschlüsse (Eingang und Ausgang) verfügt, habe ich den vorhandenen drahtlosen Qi-Ladeadapter an den Eingang angeschlossen. Und so stellte sich heraus, dass Sie den Igel zum Aufladen überhaupt nicht lösen müssen - legen Sie ihn einfach für die Nacht in ein kabelloses Ladegerät. Nur diese Funktion befindet sich jedoch noch im Testmodus.

Im Allgemeinen haben mich trotz der scheinbaren Einfachheit einige Dinge verwirrt. Anhand des Codes können Sie beispielsweise erkennen, dass ich mehrmals hintereinander einige Befehle an den Player sende und am Ende sogar eine Zeitüberschreitung einstelle. Und das alles, weil es in meiner Konfiguration in der Praxis nur so möglich ist.

Es ist auch zu sehen, dass ich aus irgendeinem Grund das Ende der Wiedergabe über das Hardware-Signal des Players steuere, anstatt den Wiedergabemodus nur einer Datei mit einem einfachen Befehl einzuschalten. Dies ist auch nicht einfach so: Aus irgendeinem Grund funktioniert dieser Modus bei mir nicht. Wenn also am Ende eines Songs der Player beginnt, den nächsten zu spielen.

Es mag noch merkwürdiger erscheinen, dass sich die Zufallsfunktion zum Abspielen einer zufälligen Komposition ständig in einer Schleife dreht, anstatt nur dann aufgerufen zu werden, wenn sie wirklich benötigt wird. Aber hier ist die Sache: Wenn Sie es nur dann aufrufen, wenn es benötigt wird, gibt es aus irgendeinem Grund in den allermeisten Fällen den gleichen Wert zurück. Wenn Sie jedoch eine Schleife einfügen, werden wirklich pseudozufällige Werte generiert. Eigentlich habe ich es auch in der Praxis herausgefunden, als ich versuchte, das unangemessene Verhalten des Igels zu verstehen.

Was mich schließlich völlig verblüffte, war die Unfähigkeit, den Kartenleser mit dem digitalen Pin des Controllers auszuschalten, über den der Leser mit Strom versorgt wird. Aus irgendeinem Grund stellt sich heraus, dass sich das Lesegerät nicht ausschaltet, wenn der Pin auf LOW und dann auf INPUT gesetzt ist.

Wenn Sie nur LOW einstellen, leuchtet die LED des Kartenlesers vollständig auf. Die Spannung am Ausgang des Stabilisators, der den Leser versorgt, beträgt ungefähr Volt. Wenn dann am Controller-Pin INPUT ausgeführt wird, steigt diese Spannung auf ca. 3V an.

Noch interessanter ist es, dass sich das Lesegerät ausschaltet, wenn Sie zuerst die an den SS- und RST-Leser angeschlossenen Controller-Pins auf LOW und INPUT setzen und dann den Power-Pin des Controllers in dieselbe Position bringen. Und selbst dann schaltet es sich nach dem Ruhezustand ein, wenn der Stromanschluss auf OUTPUT und HIGH übertragen wird.

Es passiert jedoch etwas irreparables mit Timern. Das heißt, ich denke schon, weil nach einer solchen Finte (Schlaf bei ausgeschaltetem Lesegerät) die Augen und der Schüttelzähler unzureichend funktionieren und beide Prozesse an millis () gebunden sind. Ich weiß nicht, was passiert und wie ich den Timer wiederherstellen kann, also habe ich ihn so belassen, wie er ist - der Kartenleser isst auch im Schlaf weiter.

Wenn hochrangige Genossen helfen, einen Ausweg zu finden, bin ich sehr dankbar. Obwohl ich kaum glaube, dass ältere Kameraden an diesem Ort lesen werden.

In Anbetracht des Vorstehenden ist Evelyns Igelcode völlig unvollkommen, aber Sie können ihn jederzeit kämmen (Code oder Igel - wählen Sie ihn selbst aus), optimieren, ergänzen, reduzieren oder auf andere Weise an Ihre Bedürfnisse anpassen. Deshalb hänge ich es an. Und um die Verwendung zu vereinfachen, befindet sich das Maximum an Einstellungen (ich habe alles im Allgemeinen ausprobiert, aber es stellte sich wie gewohnt heraus) nicht im Code, sondern im Abschnitt zur Variablendefinition. Es gibt eine Konfiguration von Pins und Zeitverzögerungen sowie die Anzahl der Spuren.

Im Abschnitt zur Beschreibung der Kartennummern ist zu verstehen, dass die letzten beiden Karten immer für interne Funktionen reserviert sind - Umschalten der Lautstärke und des Ruhemodus.

Aktionsprogramm
/*  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);
  
}




Ein durch den Code ungefähr wiederhergestelltes Diagramm sollte folgendermaßen aussehen (ich entschuldige mich, wenn meine Fehler irgendwo geblieben sind):





Hier:

  • 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 , für den er sich sehr bedankt , hat sich spürbar verbessert und all diese Wirtschaft in Ordnung gebracht. Beachten Sie jedoch, dass der PNP-Transistor bereits vorhanden ist und die Energieverwaltung des Players invertiert werden muss (d. H. Bei dieser Verbindung wird der Player am Pin des Controllers niedrig eingeschaltet und ausgeschaltet - hoch):



Bei der aktuellen Konfiguration reicht eine Batterie mit einer Kapazität von ca. 2500 mAh für etwa einen Tag aus benutze einen Igel. Um nicht viel zu sagen, aber Sie müssen verstehen, dass der Zeitplan immer anders ist und ich hoffe, dass der größte Teil der Energie im aktiven Modus verbraucht wird. Dies erlaubt es uns bis zu einem gewissen Grad, den fehlgeschlagenen vollständigen Rückzug der gesamten Igelelektronik in den Schlaf zu vernachlässigen.

Wenn Sie sich die Mühe machen, das ungefähre Budget zu berechnen, erhalten Sie ungefähr Folgendes (in USD):

  • Spieler: 8.9
  • ATmega328p: 1.1
  • Entwicklungsausschuss: 0,28
  • Reader RC522: 2.21
  • Dynamischer Kopf: 0,99
  • Piezokeramischer Emitter: 0,77
  • LEDs: 0,12
  • Transistor: 0,14
  • Stabilisator: 0,13
  • Vibrationssensor: 0,13
  • Seifenschale: 0,99
  • Powerbank: 0,75
  • 18650 Batterie: 3.9
  • Qi-Ladeadapter: 1.65
  • Speicherkarte: 3
  • Igel Evelyn: 6


Insgesamt 31.06, aber in der Tat ein bisschen mehr, weil Sie noch einen Draht für Verbindungen und andere Kleinigkeiten wie Schmelzkleber, doppelseitiges Klebeband und blaues Isolierband benötigen.

Es muss wahrscheinlich eine besonders wichtige letzte Phrase geben, aber ich habe sie definitiv nicht im Kopf. Es ist wahrscheinlich sinnvoll zu sagen, dass das Kind mit dem Spielzeug sehr zufrieden ist, und dies ist definitiv besser (und oft schneller) als das Einschalten des Laptops.

ps. Mir sind die Bluetooth-Lautsprecher bekannt, sie sind etwas anders, selbst wenn Sie einen so niedlichen Igel einsetzen.

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


All Articles