diff --git a/vscode/singing_picture/.vscode/settings.json b/vscode/singing_picture/.vscode/settings.json new file mode 100644 index 0000000..7f0005a --- /dev/null +++ b/vscode/singing_picture/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "svn.ignoreMissingSvnWarning": true +} \ No newline at end of file diff --git a/vscode/singing_picture/platformio.ini b/vscode/singing_picture/platformio.ini index 9e5adb9..6a2d33f 100644 --- a/vscode/singing_picture/platformio.ini +++ b/vscode/singing_picture/platformio.ini @@ -13,7 +13,4 @@ platform = espressif32 board = lolin32 framework = arduino monitor_speed = 115200 -lib_deps = - dfrobot/DFRobotDFPlayerMini@^1.0.5 - plerup/EspSoftwareSerial@^6.15.2 board_build.f_cpu = 80000000L diff --git a/vscode/singing_picture/src/main.cpp b/vscode/singing_picture/src/main.cpp index 3d11929..eb10d72 100644 --- a/vscode/singing_picture/src/main.cpp +++ b/vscode/singing_picture/src/main.cpp @@ -1,54 +1,258 @@ -#include "Arduino.h" -#include "DFRobotDFPlayerMini.h" -#include "SoftwareSerial.h" +#include +#define MV_ONE_IS_PLAYING 3100 +#define MS_TO_WAIT_BEFORE_NEXT_MOVE 10000 //ms to wait before new movement is valid +#define MS_TO_WAIT_BEFORE_VALID_NO_MOVEMEVENT 5000 //ms a no movement phase must be +#define MS_TO_WAIT_BEFORE_NEXT_PRESS 200 -#define BUTTON D1 +const uint8_t vol_down_out = 17; +const uint8_t button_vol_down = 5; +const uint8_t button_vol_up = 18; +const uint8_t button_pin = 2; +const uint8_t movesensor_pin = 4; +const uint8_t busyanalog_pin = 36; // to get status of all players +const uint8_t blue_isplaying_led_pin = 22; +const uint8_t red_button_pressed_led_pin = 19; +const uint8_t red_movement_detected_led_pin = 19; +const uint8_t mp3player_control_pin[] = {15,13,12,14,27,26,25,33,32}; +const uint8_t mp3player_nr = sizeof(mp3player_control_pin)/sizeof(mp3player_control_pin[0]); +void play_sequence(void); +void check_players_state(void); +void check_button(void); +void check_movement(void); +void set_leds(void); +void set_volume(void); -SoftwareSerial mySoftSer_1(13, 12); // RX, TX -SoftwareSerial mySoftSer_2(14, 27); - -DFRobotDFPlayerMini child_1; -DFRobotDFPlayerMini child_2; - -void setup() { - - Serial.begin(115200); // start serial interface - - if (!child_1.begin(mySoftSer_1, false)) { //Use softwareSerial to communicate with mp3. - Serial.println(F("Unable to begin Child 1:")); - Serial.println(F("1.Please recheck the connection!")); - Serial.println(F("2.Please insert the SD card!")); - while(true){ - delay(0); // Code to compatible with ESP8266 watch dog. - } +void setup() +{ + Serial.begin(115200); + Serial.println("Setting button,movement sensor pin to input."); + pinMode(vol_down_out, INPUT); + digitalWrite(vol_down_out,HIGH); + pinMode(button_vol_up, INPUT_PULLUP); + pinMode(button_pin, INPUT_PULLUP); + pinMode(movesensor_pin, INPUT_PULLDOWN); + pinMode(blue_isplaying_led_pin, OUTPUT); + pinMode(red_button_pressed_led_pin, OUTPUT); + pinMode(red_movement_detected_led_pin, OUTPUT); + Serial.println("Setting all control pins to outputs and disable playing."); + for(uint8_t ix = 0; ix < mp3player_nr; ix++) + { + pinMode(mp3player_control_pin[ix], OUTPUT); + digitalWrite(mp3player_control_pin[ix],HIGH); + pinMode(mp3player_control_pin[ix], INPUT); } - Serial.println(F("Child 1 online.")); - child_1.volume(10); //Set volume value. From 0 to 30 - - if (!child_2.begin(mySoftSer_2, false)) { //Use softwareSerial to communicate with mp3. - Serial.println(F("Unable to begin Child 2:")); - Serial.println(F("1.Please recheck the connection!")); - Serial.println(F("2.Please insert the SD card!")); - while(true){ - delay(0); // Code to compatible with ESP8266 watch dog. - } - } - Serial.println(F("Child 2 online.")); - child_2.volume(10); //Set volume value. From 0 to 30 - - //WiFi.mode(WIFI_OFF); - //WiFi.forceSleepBegin(); - delay(10); - - } -void loop() -{ - child_1.play(1); //Play the first mp3 - child_1.readState() - delay(1000); +bool movement = false; +bool there_was_no_movement_in_between = true; +bool is_playing = false; +bool button_pressed = false; +bool button_upvol_pressed = false; +bool button_downvol_pressed = false; +unsigned long last_move_ms = 0; +unsigned long last_no_move_ms = 0; +unsigned long last_button_ms = 0; +unsigned long last_upvol_button_ms = 0; +unsigned long last_downvol_button_ms = 0; + +void loop() +{ + check_players_state(); + check_movement(); + check_button(); + set_leds(); + set_volume(); + play_sequence(); + delay(100); +} + +void set_volume(void) +{ + //if(is_playing == false) + if(0 == 0) + { + if(button_downvol_pressed) + { + Serial.println("Decreasing volume ..."); + pinMode(vol_down_out, OUTPUT); + digitalWrite(vol_down_out,LOW); + delay(10000); + digitalWrite(vol_down_out,HIGH); + pinMode(vol_down_out, INPUT); + Serial.println("Done."); + } + + if(button_upvol_pressed) + { + Serial.println("Increasing volume."); + for(uint8_t ix= 0; ix < mp3player_nr; ix++) + { + pinMode(mp3player_control_pin[ix],OUTPUT); + digitalWrite(mp3player_control_pin[ix],LOW); + } + delay(10000); + for(uint8_t ix= 0; ix < mp3player_nr; ix++) + { + digitalWrite(mp3player_control_pin[ix],HIGH); + pinMode(mp3player_control_pin[ix],INPUT); + } + Serial.println("Done."); + } + } + button_downvol_pressed = false; + button_upvol_pressed = false; +} + + +void check_button(void) +{ + if( MS_TO_WAIT_BEFORE_NEXT_PRESS < millis() - last_button_ms) + { + if(false == button_pressed && LOW == digitalRead(button_pin)) + { + Serial.println("Button pressed ..."); + last_button_ms = millis(); + button_pressed = true; + } + } + + if( MS_TO_WAIT_BEFORE_NEXT_PRESS < millis() - last_upvol_button_ms) + { + if(false == button_upvol_pressed && LOW == digitalRead(button_vol_up)) + { + Serial.println("Volume up button pressed ..."); + last_upvol_button_ms = millis(); + button_upvol_pressed = true; + } + } + + if( MS_TO_WAIT_BEFORE_NEXT_PRESS < millis() - last_downvol_button_ms) + { + if(false == button_downvol_pressed && LOW == digitalRead(button_vol_down)) + { + Serial.println("Volume down button pressed ..."); + last_downvol_button_ms = millis(); + button_downvol_pressed = true; + } + } + +} + +void set_leds(void) +{ + /* + if( true == button_pressed) + digitalWrite(red_button_pressed_led_pin,HIGH); + else + digitalWrite(red_button_pressed_led_pin,LOW); + */ + if( true == is_playing) + digitalWrite(blue_isplaying_led_pin,HIGH); + else + digitalWrite(blue_isplaying_led_pin,LOW); + + if( true == movement) + digitalWrite(red_movement_detected_led_pin,HIGH); + else + { + if(there_was_no_movement_in_between == true) + digitalWrite(red_movement_detected_led_pin,LOW); + } +} + +void check_movement(void) +{ + int act_movement = digitalRead(movesensor_pin); + /*if(act_movement == LOW) + Serial.println("No movement."); + else + Serial.println("Movement."); + */ + if(LOW == act_movement ) + { + if( false == there_was_no_movement_in_between) + { + if(MS_TO_WAIT_BEFORE_VALID_NO_MOVEMEVENT < millis()-last_no_move_ms) + { + there_was_no_movement_in_between = true; + Serial.printf("No movement anymore ...\n"); + } + } + } + else + { + last_no_move_ms = millis(); + } + + if( true == is_playing) + { + last_move_ms = millis(); + } + else + { + if(HIGH == act_movement && true == there_was_no_movement_in_between) + { + there_was_no_movement_in_between = false; + if(MS_TO_WAIT_BEFORE_NEXT_MOVE < millis()-last_move_ms) + { + last_move_ms = millis(); + movement = true; + Serial.printf("New movement detected ...\n"); + } + } + } +} + +void check_players_state(void) +{ + // 0 ... 0V - 4095 ... 3.3V + uint16_t voltage_dig = analogRead(busyanalog_pin); + uint16_t voltage_mV = map(voltage_dig,0,4095,0,3300); + //Serial.printf("Voltage at busy pins is: dig=%d , ana=%dmV\n", voltage_dig, voltage_mV); + if(voltage_mV < MV_ONE_IS_PLAYING) + { + if(false == is_playing) + { + Serial.println("At least one player is playing now."); + } + is_playing = true; + } + else + { + if(true == is_playing) + { + Serial.println("All players off now."); + } + is_playing = false; + } +} + +void play_sequence(void) +{ + if(false == is_playing) + { + //Serial.println("All players still off ."); + if(true == button_pressed || true == movement ) + { + Serial.println("All players starting now."); + for(uint8_t ix= 0; ix < mp3player_nr; ix++) + { + pinMode(mp3player_control_pin[ix],OUTPUT); + digitalWrite(mp3player_control_pin[ix],LOW); + } + Serial.println("All players started."); + delay(500); + for(uint8_t ix= 0; ix < mp3player_nr; ix++) + { + digitalWrite(mp3player_control_pin[ix],HIGH); + pinMode(mp3player_control_pin[ix],INPUT); + } + is_playing = true; + } + } + button_pressed = false; + movement = false; +} -} \ No newline at end of file diff --git a/vscode/singing_picture_uno/.gitignore b/vscode/singing_picture_uno/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/vscode/singing_picture_uno/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/vscode/singing_picture_uno/.vscode/extensions.json b/vscode/singing_picture_uno/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/vscode/singing_picture_uno/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/vscode/singing_picture_uno/include/README b/vscode/singing_picture_uno/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/vscode/singing_picture_uno/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/vscode/singing_picture_uno/lib/README b/vscode/singing_picture_uno/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/vscode/singing_picture_uno/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/vscode/singing_picture_uno/platformio.ini b/vscode/singing_picture_uno/platformio.ini new file mode 100644 index 0000000..5f00a21 --- /dev/null +++ b/vscode/singing_picture_uno/platformio.ini @@ -0,0 +1,16 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:uno] +platform = atmelavr +board = uno +framework = arduino +monitor_speed = 9600 +lib_deps = dfrobot/DFRobotDFPlayerMini@^1.0.5 diff --git a/vscode/singing_picture_uno/src/main.cpp b/vscode/singing_picture_uno/src/main.cpp new file mode 100644 index 0000000..7596fa4 --- /dev/null +++ b/vscode/singing_picture_uno/src/main.cpp @@ -0,0 +1,272 @@ +/*************************************************** + Durch Wolfgang Ewald modifizierte Version des FullFunction.ino Beispielsketches der DFRobotDFPlayerMini Bibliothek: + + DFPlayer - A Mini MP3 Player For Arduino + + + *************************************************** + This example shows the all the function of library for DFPlayer. + + Created 2016-12-07 + By [Angelo qiao](Angelo.qiao@dfrobot.com) + + GNU Lesser General Public License. + See for details. + All above must be included in any redistribution + ****************************************************/ + +/***********Notice and Trouble shooting*************** + 1.Connection and Diagram can be found here + + 2.This code is tested on Arduino Uno, Leonardo, Mega boards. + ****************************************************/ + +#include "Arduino.h" +#include "SoftwareSerial.h" +#include "DFRobotDFPlayerMini.h" + +SoftwareSerial mySoftwareSerial(10,11); // RX, TX +DFRobotDFPlayerMini myDFPlayer; +void printDetail(uint8_t type, int value); +void readCommand(); +void printHelp(); + + +void setup() +{ + mySoftwareSerial.begin(9600); + Serial.begin(9600); + + Serial.println(); + Serial.println(F("DFRobot DFPlayer Mini Demo")); + Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)")); + + if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3. + Serial.println(F("Unable to begin:")); + Serial.println(F("1.Please recheck the connection!")); + Serial.println(F("2.Please insert the SD card!")); + while(true); + } + Serial.println(F("DFPlayer Mini online.")); + printHelp(); + + myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms + + //----Set volume---- + myDFPlayer.volume(10); //Set volume value (0~30). + // myDFPlayer.volumeUp(); //Volume Up + // myDFPlayer.volumeDown(); //Volume Down + + //----Set different EQ---- + myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); +// myDFPlayer.EQ(DFPLAYER_EQ_POP); +// myDFPlayer.EQ(DFPLAYER_EQ_ROCK); +// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ); +// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC); +// myDFPlayer.EQ(DFPLAYER_EQ_BASS); + + //----Set device we use SD as default---- +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK); + myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP); +// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH); + + //----Mp3 control---- +// myDFPlayer.sleep(); //sleep +// myDFPlayer.reset(); //Reset the module +// myDFPlayer.enableDAC(); //Enable On-chip DAC +// myDFPlayer.disableDAC(); //Disable On-chip DAC +// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15 + + +} + +void loop(){ + if(Serial.available()){ + readCommand(); + } + + if (myDFPlayer.available()) { + printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states. + } +} + +void readCommand(){ + char cmd = ' '; + int value1, value2 = 0; + cmd = Serial.read(); + value1 = Serial.parseInt(); + value2 = Serial.parseInt(); + + switch(cmd){ + case 'h': + printHelp(); + break; + + case '>': + myDFPlayer.next(); + break; + + case '<': + myDFPlayer.previous(); + break; + + case 'p': + if(value2 == 0) myDFPlayer.play(value1); + else if(value1 != 0) myDFPlayer.playFolder(value1, value2); + break; + + case 'P': + if(value2 == 0) myDFPlayer.playMp3Folder(value1); + else if(value1 != 0)myDFPlayer.playLargeFolder(value1, value2); + break; + + case '+': + myDFPlayer.volumeUp(); + break; + + case '-': + myDFPlayer.volumeDown(); + break; + + case 'v': + myDFPlayer.volume(value1); + break; + + case 'b': + myDFPlayer.pause(); + break; + + case 's': + myDFPlayer.start(); + break; + + case 'z': + myDFPlayer.sleep(); + break; + + case 'L': + if(value1 == 0) myDFPlayer.enableLoopAll(); + else myDFPlayer.loopFolder(value1); + break; + + case 'l': + if(value1 == 0) myDFPlayer.disableLoopAll(); + else myDFPlayer.loop(value1); + break; + + case 'A': + myDFPlayer.advertise(value1); + break; + + case 'a': + myDFPlayer.stopAdvertise(); + break; + + case 'q': + if(value1 == 1) Serial.println(myDFPlayer.readState()); + else if(value1 == 2) Serial.println(myDFPlayer.readVolume()); + else if(value1 == 3) Serial.println(myDFPlayer.readEQ()); + else if(value1 == 4) Serial.println(myDFPlayer.readFileCounts()); + else if(value1 == 5) Serial.println(myDFPlayer.readFolderCounts()); + else if(value1 == 6) Serial.println(myDFPlayer.readCurrentFileNumber()); + break; + default: + Serial.println("Ungültiges Kommando"); + break; + } + +} + +void printHelp(){ + Serial.println("DFPlayer Commands:"); + Serial.println(" h - help"); + Serial.println(" > - next "); + Serial.println(" < - previous"); + Serial.println(" p3 - play"); + Serial.println(" p3,5 - play folder 3, file 5"); + Serial.println(" P3,5 - play large folder 3, file 5"); + Serial.println(" P3 - play file 3 in MP3 folder"); + Serial.println(" + - volume up"); + Serial.println(" - - volume down"); + Serial.println(" v10 - set volume to 10"); + Serial.println(" b - Pause"); + Serial.println(" s - start "); + Serial.println(" z - sleep "); + Serial.println(" L - enable loop all"); + Serial.println(" l - disable loop all"); + Serial.println(" L3 - loop folder 3"); + Serial.println(" l3 - loop file 3"); + Serial.println(" A3 - advertise file 3"); + Serial.println(" a - stop advertise "); + Serial.println(" qx - query No. x"); + Serial.println(" x = 1 - read state"); + Serial.println(" x = 2 - read volume"); + Serial.println(" x = 3 - read equalizer"); + Serial.println(" x = 4 - read file counts"); + Serial.println(" x = 5 - read current file number"); + Serial.println(" x = 6 - read file counts in folder"); + Serial.println(" x = 7 - read folder counts"); +} + +void printDetail(uint8_t type, int value){ + switch (type) { + case TimeOut: + Serial.println(F("Time Out!")); + break; + case WrongStack: + Serial.println(F("Stack Wrong!")); + break; + case DFPlayerCardInserted: + Serial.println(F("Card Inserted!")); + break; + case DFPlayerCardRemoved: + Serial.println(F("Card Removed!")); + break; + case DFPlayerCardOnline: + Serial.println(F("Card Online!")); + break; + case DFPlayerUSBInserted: + Serial.println("USB Inserted!"); + break; + case DFPlayerUSBRemoved: + Serial.println("USB Removed!"); + break; + case DFPlayerPlayFinished: + Serial.print(F("Number:")); + Serial.print(value); + Serial.println(F(" Play Finished!")); + break; + case DFPlayerError: + Serial.print(F("DFPlayerError:")); + switch (value) { + case Busy: + Serial.println(F("Card not found")); + break; + case Sleeping: + Serial.println(F("Sleeping")); + break; + case SerialWrongStack: + Serial.println(F("Get Wrong Stack")); + break; + case CheckSumNotMatch: + Serial.println(F("Check Sum Not Match")); + break; + case FileIndexOut: + Serial.println(F("File Index Out of Bound")); + break; + case FileMismatch: + Serial.println(F("Cannot Find File")); + break; + case Advertise: + Serial.println(F("In Advertise")); + break; + default: + break; + } + break; + default: + break; + } +} \ No newline at end of file diff --git a/vscode/singing_picture_uno/test/README b/vscode/singing_picture_uno/test/README new file mode 100644 index 0000000..b94d089 --- /dev/null +++ b/vscode/singing_picture_uno/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html