├── version.md ├── firmware.bin ├── .gitignore ├── src ├── calendarApp.h ├── flashlightApp.h ├── calculatorApp.h ├── mediaApp.h ├── clockApp.h ├── mainMenu.h ├── phoneApp.h ├── main.h ├── contactsApp.h ├── settingsApp.h ├── messagesApp.h ├── flashlightApp.cpp ├── calendarApp.cpp ├── calculatorApp.cpp ├── mainMenu.cpp ├── mediaApp.cpp ├── contactsApp.cpp ├── clockApp.cpp ├── messagesApp.cpp └── phoneApp.cpp ├── .gitmodules ├── ringo.csv ├── platformio.ini ├── BUILD.md ├── LICENSE ├── lib └── README └── README.md /version.md: -------------------------------------------------------------------------------- 1 | # Current Ringo version 2 | version=105 3 | -------------------------------------------------------------------------------- /firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircuitMess/CircuitMess-Ringo-firmware/HEAD/firmware.bin -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .pioenvs 3 | .piolibdeps 4 | .vscode 5 | include 6 | .travis.yml 7 | test 8 | .history 9 | -------------------------------------------------------------------------------- /src/calendarApp.h: -------------------------------------------------------------------------------- 1 | #ifndef calendarApp_h 2 | #define calendarApp_h 3 | 4 | #include "main.h" 5 | void calendarApp(); 6 | #endif -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/MAKERphone"] 2 | path = lib/MAKERphone 3 | url = https://github.com/CircuitMess/CircuitMess-Ringo.git 4 | -------------------------------------------------------------------------------- /src/flashlightApp.h: -------------------------------------------------------------------------------- 1 | #ifndef flashlightApp_h 2 | #define flashlightApp_h 3 | 4 | #include "main.h" 5 | void flashlightApp(); 6 | #endif -------------------------------------------------------------------------------- /src/calculatorApp.h: -------------------------------------------------------------------------------- 1 | #ifndef calculatorApp_h 2 | #define calculatorApp_h 3 | 4 | #include "main.h" 5 | void calculatorApp(); 6 | 7 | #endif -------------------------------------------------------------------------------- /ringo.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | nvs, data, nvs, 0x9000, 0x5000, 3 | otadata, data, ota, 0xe000, 0x2000, 4 | app0, app, ota_0, 0x10000, 0x1E0000, 5 | app1, app, ota_1, 0x1F0000,0x1E0000, 6 | eeprom, data, 0x99, 0x3D0000,0x1000, 7 | spiffs, data, spiffs, 0x3D1000,0x2F000, 8 | -------------------------------------------------------------------------------- /src/mediaApp.h: -------------------------------------------------------------------------------- 1 | #ifndef media_h 2 | #define media_h 3 | 4 | #include "main.h" 5 | extern String mediaItems[3]; 6 | extern String photoFiles[100]; 7 | extern uint8_t photoCount; 8 | 9 | void mediaApp(); 10 | int8_t mediaMenu(String* title, uint8_t length); 11 | void mediaMenuDrawBox(String title, uint8_t i, int32_t y); 12 | void mediaMenuDrawCursor(uint8_t i, int32_t y, bool pressed); 13 | int16_t audioPlayer(uint16_t index); 14 | void listPhotos(const char *dirname, uint8_t levels); 15 | 16 | #endif -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:lolin32] 12 | platform = espressif32@1.12.1 13 | board = lolin32 14 | framework = arduino 15 | board_build.partitions = ringo.csv 16 | monitor_speed = 115200 17 | upload_speed = 921600 18 | -------------------------------------------------------------------------------- /src/clockApp.h: -------------------------------------------------------------------------------- 1 | #ifndef clockApp_h 2 | #define clockApp_h 3 | 4 | #include "main.h" 5 | void clockApp(); 6 | void clockStopwatch(); 7 | int8_t clockMenu(String* title, uint8_t length, int8_t prevCursor); 8 | void clockMenuDrawBox(String title, uint8_t i, int32_t y); 9 | void clockAlarm(); 10 | int8_t clockAlarmMenu(uint8_t* alarmsArray, uint8_t length); 11 | void clockAlarmMenuDrawBox(uint8_t alarmIndex, uint8_t i, int32_t y); 12 | void clockAlarmEdit(uint8_t index); 13 | extern String alarmTrack[5]; 14 | void clockTimer(); 15 | extern uint8_t alarmHours[5]; 16 | extern uint8_t alarmMins[5]; 17 | extern uint8_t alarmEnabled[5]; 18 | extern bool alarmRepeat[5]; 19 | extern bool alarmRepeatDays[5][7]; 20 | #endif -------------------------------------------------------------------------------- /src/mainMenu.h: -------------------------------------------------------------------------------- 1 | #ifndef mainMenu_h 2 | #define mainMenu_h 3 | 4 | #include "main.h" 5 | #include "messagesApp.h" 6 | #include "mediaApp.h" 7 | #include "contactsApp.h" 8 | #include "settingsApp.h" 9 | #include "phoneApp.h" 10 | #include "clockApp.h" 11 | #include "calculatorApp.h" 12 | #include "flashlightApp.h" 13 | #include "calendarApp.h" 14 | extern uint16_t directoryCount; 15 | extern String directories[100]; 16 | extern String BinaryFiles[100]; 17 | extern uint16_t binaryCount;//Number of binary files available for loading 18 | 19 | void listDirectories(const char * dirname); 20 | void listBinaries(const char * dirname, uint8_t levels); 21 | int16_t scrollingMainMenu(); 22 | void mainMenu(); 23 | 24 | #endif -------------------------------------------------------------------------------- /src/phoneApp.h: -------------------------------------------------------------------------------- 1 | #ifndef phoneApp_h 2 | #define phoneApp_h 3 | 4 | #include "main.h" 5 | void phoneApp(); 6 | 7 | // Call log 8 | void callLog(); 9 | int callLogMenu(JsonArray &call_log, int prevCursor); 10 | uint8_t showCall(int id, String number, uint32_t dateTime, String contact, String duration, uint8_t direction); 11 | void callLogMenuDrawCursor(uint8_t i, int32_t y); 12 | void callLogDrawBoxSD(JsonObject& object, uint8_t i, int32_t y); 13 | void sendMMI(String code); 14 | struct contactsX 15 | { 16 | //uint8_t id; 17 | String name; 18 | String number; 19 | uint32_t score; 20 | bool initd = false; 21 | }; 22 | String sortAndGetFav(); 23 | void phoneMenuDrawBox(String name, String number, uint8_t i, int32_t y, bool blState, int32_t cPos, bool inputFlag); 24 | void phoneMenuDrawCursor(uint8_t i, int32_t y); 25 | void drawStuff(); 26 | String getContact(String data, int no); 27 | #endif 28 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef Main_h 2 | #define Main_h 3 | #include "sprites.c" 4 | #include 5 | 6 | extern MAKERphone mp; 7 | extern int backgroundColors[7]; 8 | extern String backgroundColorsNames[7]; 9 | extern String titles[9]; 10 | // extern Oscillator *osc; 11 | extern int textPointer; 12 | extern StaticJsonBuffer jb; 13 | extern String audioFiles[100]; 14 | extern uint16_t audioCount; 15 | 16 | void menuDrawBox(String text, uint8_t i, int32_t y); 17 | int8_t menu(const char* title, String* items, uint8_t length); 18 | void menuDrawCursor(uint8_t i, int32_t y); 19 | String readSerial(); 20 | uint16_t countSubstring(String string, String substring); 21 | void callNumber(String number); 22 | int16_t audioPlayerMenu(const char* title, String* items, uint16_t length, uint16_t index = 0); 23 | void listAudio(const char * dirname, uint8_t levels); 24 | bool startupWizard(); 25 | void controlTry(); 26 | #endif 27 | -------------------------------------------------------------------------------- /src/contactsApp.h: -------------------------------------------------------------------------------- 1 | #ifndef contacts_h 2 | #define contacts_h 3 | #include "main.h" 4 | //Contacts app 5 | void contactsMenuDrawBox(String name, String number, uint8_t i, int32_t y, bool smsflag); 6 | uint8_t deleteContactSD(String name, String number); 7 | uint8_t newContact(String *name, String *number); 8 | void parse_contacts(); 9 | void contactsMenuNewBox(uint8_t i, int32_t y); 10 | void contactsMenuDrawCursor(uint8_t i, int32_t y, bool smsflag); 11 | void contactsMenuNewBoxCursor(uint8_t i, int32_t y); 12 | int contactsMenu(JsonArray *contacts, bool smsFlag); 13 | void contactsApp(bool smsFlag); 14 | String readAllContacts(); 15 | void callNumber(String number); 16 | int8_t viewContact(JsonObject &object); 17 | extern int textPointer; 18 | String searchContacts(String input); 19 | void contactsMenuSearchBox(uint8_t i, int32_t y, String input, bool blinkState); 20 | void contactsMenuSearchBoxCursor(uint8_t i, int32_t y); 21 | #endif 22 | -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | CircuitMess-Ringo-firmware Development 2 | -------------------------------------- 3 | 4 | CircuitMess-Ringo-firmware is built using [PlatformIO](https://platformio.org). 5 | 6 | ## Getting the code 7 | 8 | ```sh 9 | git clone https://github.com/CircuitMess/CircuitMess-Ringo-firmware 10 | cd CircuitMess-Ringo-firmware 11 | git submodule update --init 12 | ``` 13 | 14 | ## Develop with IDE 15 | 16 | Install a [PlatformIO IDE](https://platformio.org/install/ide). 17 | 18 | Open CircuitMess-Ringo-firmware in your IDE, and build and/or upload code from there, after connecting Ringo via USB. 19 | 20 | ## Build with Command Line 21 | 22 | Install the [PlatformIO CLI](https://docs.platformio.org/en/latest/installation.html#installation-methods) according to their documentation. 23 | 24 | ```sh 25 | # build firmware only, output in .pio/build/lolin32/firmware.bin 26 | pio run 27 | 28 | # OR build and install new firmware, simply connect Ringo via USB first 29 | pio run -t upload 30 | ``` 31 | -------------------------------------------------------------------------------- /src/settingsApp.h: -------------------------------------------------------------------------------- 1 | #ifndef settings_h 2 | #define settings_h 3 | 4 | #include "main.h" 5 | bool settingsApp(); 6 | int8_t settingsMenu(String* title, uint8_t length); 7 | void settingsMenuDrawBox(String title, uint8_t i, int32_t y); 8 | void settingsMenuDrawCursor(uint8_t i, int32_t y, bool pressed); 9 | 10 | void networkMenu(); 11 | void displayMenu(); 12 | void soundMenu(); 13 | void securityMenu(); 14 | void timeMenu(); 15 | bool updateMenu(); 16 | void wifiConnect(); 17 | int8_t checkForUpdate(); 18 | bool fetchUpdate(); 19 | 20 | int8_t notificationsAudioMenu(String* items, uint8_t length); 21 | void notificationsDrawBox(String text, uint8_t i, int32_t y); 22 | void notificationsDrawCursor(uint8_t i, int32_t y); 23 | int8_t wifiNetworksMenu(String* items, String *signals, uint8_t length); 24 | void wifiDrawBox(String text, String signalStrength, uint8_t i, int32_t y); 25 | void wifiDrawCursor(uint8_t i, int32_t y); 26 | int16_t ringtoneAudioMenu(String* items, uint16_t length); 27 | 28 | extern String settingsItems[6]; 29 | extern uint16_t pinNumber; 30 | extern uint8_t timesRemaining; 31 | extern bool pinLock; 32 | 33 | #endif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 CircuitMess 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /src/messagesApp.h: -------------------------------------------------------------------------------- 1 | #ifndef messages_h 2 | #define messages_h 3 | 4 | #include "main.h" 5 | extern int16_t y; 6 | extern String smsContent[SMS_LIMIT]; 7 | extern String phoneNumber[SMS_LIMIT]; 8 | extern String tempDate[SMS_LIMIT]; 9 | extern uint16_t smsYear[SMS_LIMIT]; 10 | extern uint8_t smsDay[SMS_LIMIT]; 11 | extern uint8_t smsMonth[SMS_LIMIT]; 12 | extern uint8_t smsMinute[SMS_LIMIT]; 13 | extern uint8_t smsSecond[SMS_LIMIT]; 14 | extern uint8_t smsHour[SMS_LIMIT]; 15 | extern uint32_t start; 16 | extern uint32_t end; 17 | extern String input; 18 | extern String buffer; 19 | extern int textPointer; 20 | 21 | uint16_t countSubstring(String string, String substring); 22 | String readSerial(); 23 | String readSms(uint8_t index); 24 | String readAllSms(); 25 | bool viewSms(String content, String contact, uint32_t date, bool direction); 26 | void smsMenuDrawBox(String contact, DateTime date, String content, uint8_t i, int32_t y); 27 | void smsMenuComposeBox(uint8_t i, int32_t y); 28 | void smsMenuDrawCursor(uint8_t i, int32_t y); 29 | void smsMenuComposeBoxCursor(uint8_t i, int32_t y); 30 | int16_t smsMenu(JsonArray& messages, int16_t prevCursor); 31 | void messagesApp(); 32 | void composeSMS(JsonArray *messages); 33 | void incomingMessagePopup(); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # CircuitMess Ringo firmware 4 | 5 | A repository for the core firmware that comes pre-loaded on every CircuitMess Ringo. 6 | 7 | Functionalities that are currently available: 8 | - home screen 9 | - call log 10 | - caller app 11 | - SMS app 12 | - sleep mode 13 | - calculator app 14 | - clock app 15 | - media app (photos and videos) 16 | - settings app 17 | - loading other apps (.bin format) from SD card 18 | - music player (.wav) 19 | - basic notification sounds and ringtones 20 | 21 | Here are some examples of how the current version of the firmware looks: 22 | 23 | ### **Home** 24 | 25 | ![alt text](https://old.circuitmess.com/wp-content/uploads/screenshot_46-export.png) 26 | 27 |
28 | 29 | ### **Main menu** 30 | 31 | ![alt text](https://old.circuitmess.com/wp-content/uploads/screenshot_28-export.png) 32 | 33 |
34 | 35 | ### **Apps** 36 | 37 | ![alt text](https://old.circuitmess.com/wp-content/uploads/screenshot_30-export.png) 38 | 39 | ### **Wi-Fi** 40 | 41 | ![alt text](https://old.circuitmess.com/wp-content/uploads/screenshot_44-export.png) 42 | 43 | ## **Settings** 44 | 45 | ![alt text](https://old.circuitmess.com/wp-content/uploads/screenshot_45-export.png) 46 | 47 |
48 | 49 | ## Meta 50 | 51 | 52 | 53 | 54 | 55 | **CircuitMess** - https://www.circuitmess.com/ - @circuitmess.com 56 | 57 | **Facebook** - https://www.facebook.com/makerbuino/ 58 | 59 | **Instagram** - https://www.instagram.com/thecircuitmess/ 60 | 61 | **Twitter** - https://twitter.com/circuitmess 62 | 63 | **YouTube** - https://www.youtube.com/channel/UCVUvt1CeoZpCSnwg3oBMsOQ 64 | 65 | Copyright © 2019 CircuitMess 66 | 67 | Licensed under [MIT license](https://opensource.org/licenses/MIT) 68 | 69 | -------------------------------------------------------------------------------- /src/flashlightApp.cpp: -------------------------------------------------------------------------------- 1 | #include "flashlightApp.h" 2 | 3 | void colorChange(uint8_t col){ 4 | for(int i = 0; i < 8; i++) 5 | { 6 | switch(col) 7 | { 8 | case 0: 9 | mp.leds[i] = CRGB::Cyan; 10 | break; 11 | case 1: 12 | mp.leds[i] = CRGB::Green; 13 | break; 14 | case 2: 15 | mp.leds[i] = CRGB::Red; 16 | break; 17 | case 3: 18 | mp.leds[i] = CRGB::Yellow; 19 | break; 20 | case 4: 21 | mp.leds[i] = CRGB::White; 22 | break; 23 | case 5: 24 | mp.leds[i] = CRGB::Orange; 25 | break; 26 | case 6: 27 | mp.leds[i] = CRGB::Fuchsia; 28 | break; 29 | } 30 | } 31 | mp.pixelsBrightness = 5; 32 | // mp.update(); 33 | } 34 | 35 | void flashlightApp() 36 | { 37 | bool state = 0; 38 | uint8_t color = 4; 39 | uint8_t localBrightness = mp.pixelsBrightness; 40 | while(1) 41 | { 42 | for(int i = 0; i < 8; i++) 43 | { 44 | switch(color) 45 | { 46 | case 0: 47 | mp.leds[i] = CRGB::Cyan; 48 | break; 49 | case 1: 50 | mp.leds[i] = CRGB::Green; 51 | break; 52 | case 2: 53 | mp.leds[i] = CRGB::Red; 54 | break; 55 | case 3: 56 | mp.leds[i] = CRGB::Yellow; 57 | break; 58 | case 4: 59 | mp.leds[i] = CRGB::White; 60 | break; 61 | case 5: 62 | mp.leds[i] = CRGB::Orange; 63 | break; 64 | case 6: 65 | mp.leds[i] = CRGB::Fuchsia; 66 | break; 67 | } 68 | } 69 | mp.pixelsBrightness = 5; 70 | mp.display.fillScreen(TFT_BLACK); 71 | mp.display.setTextColor(TFT_WHITE); 72 | mp.display.setTextFont(2); 73 | mp.display.setTextSize(1); 74 | mp.display.setCursor(2, 110); 75 | mp.display.print("Color"); 76 | mp.display.setCursor(112, 110); 77 | mp.display.print("On/Off"); 78 | // mp.display.setCursor(95, 110); 79 | // mp.display.print("Brightness"); 80 | if(!state) 81 | { 82 | mp.pixelsBrightness = 0; 83 | mp.display.drawIcon(flashlightOff, 46, 10, 34, 50, 2, TFT_GREEN); 84 | } 85 | else 86 | mp.display.drawIcon(flashlightOn, 46, 10, 34, 50, 2, TFT_GREEN); 87 | 88 | if(mp.buttons.released(BTN_HOME)) { 89 | mp.exitedLockscreen = true; 90 | mp.lockscreen(); 91 | } 92 | 93 | if(mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) 94 | { 95 | mp.buttons.update(); 96 | state = !state; 97 | Serial.println(state); 98 | delay(5); 99 | } 100 | if(mp.buttons.released(BTN_B)) 101 | { 102 | mp.buttons.update(); 103 | for(int i = 0; i < 8; i++) 104 | mp.leds[i] = CRGB::Black; 105 | 106 | mp.pixelsBrightness = localBrightness; // rad lampe u pozadini 107 | break; 108 | } 109 | if(mp.buttons.released(BTN_FUN_LEFT)) 110 | { 111 | mp.buttons.update(); 112 | while(1) 113 | { 114 | mp.display.fillScreen(TFT_BLACK); 115 | mp.display.setTextColor(TFT_WHITE); 116 | mp.display.setTextFont(2); 117 | mp.display.setTextSize(1); 118 | mp.display.setCursor(2, 110); 119 | mp.display.print("Color"); 120 | mp.display.setCursor(112, 110); 121 | mp.display.print("On/Off"); 122 | if(!state) 123 | { 124 | mp.pixelsBrightness = 0; 125 | mp.display.drawIcon(flashlightOff, 46, 10, 34, 50, 2, TFT_GREEN); 126 | } 127 | else 128 | mp.display.drawIcon(flashlightOn, 46, 10, 34, 50, 2, TFT_GREEN); 129 | 130 | mp.display.fillRect(15, 51, 130, 24, backgroundColors[color]); 131 | mp.display.drawRect(14, 50, 132, 26, TFT_BLACK); 132 | mp.display.setTextColor(TFT_BLACK); 133 | mp.display.setCursor(0, mp.display.height() / 2 - 10); 134 | mp.display.printCenter(backgroundColorsNames[color]); 135 | mp.display.drawBitmap(22, 57, arrowLeft, TFT_BLACK, 2); 136 | mp.display.drawBitmap(130, 57, arrowRight, TFT_BLACK, 2); 137 | if (millis() % 1000 <= 500) 138 | { 139 | if (color == 0) 140 | { 141 | mp.display.drawBitmap(130, 57, arrowRight, backgroundColors[color], 2); 142 | mp.display.drawBitmap(11*2, 57, arrowLeft, TFT_BLACK, 2); 143 | mp.display.drawBitmap(66*2, 57, arrowRight, TFT_BLACK, 2); 144 | } 145 | else if (color == 6) 146 | { 147 | mp.display.drawBitmap(22, 57, arrowLeft, backgroundColors[color], 2); 148 | mp.display.drawBitmap(10*2, 57, arrowLeft, TFT_BLACK, 2); 149 | mp.display.drawBitmap(65*2, 57, arrowRight, TFT_BLACK, 2); 150 | } 151 | else 152 | { 153 | mp.display.drawBitmap(130, 57, arrowRight, backgroundColors[color], 2); 154 | mp.display.drawBitmap(22, 57, arrowLeft, backgroundColors[color], 2); 155 | mp.display.drawBitmap(10*2, 57, arrowLeft, TFT_BLACK, 2); 156 | mp.display.drawBitmap(66*2, 57, arrowRight, TFT_BLACK, 2); 157 | } 158 | } 159 | 160 | if (mp.buttons.released(BTN_LEFT) && color > 0) 161 | { 162 | mp.buttons.update(); 163 | mp.osc->note(75, 0.05); 164 | mp.osc->play(); 165 | color--; 166 | } 167 | if (mp.buttons.released(BTN_RIGHT) && color < 6) 168 | { 169 | mp.buttons.update(); 170 | mp.osc->note(75, 0.05); 171 | mp.osc->play(); 172 | color++; 173 | } 174 | if(state) 175 | colorChange(color); 176 | if(mp.buttons.released(BTN_FUN_LEFT)) 177 | { 178 | mp.buttons.update(); 179 | break; 180 | } 181 | if(mp.buttons.released(BTN_FUN_RIGHT)) 182 | { 183 | mp.buttons.update(); 184 | state = !state; 185 | } 186 | if(mp.buttons.released(BTN_A) || mp.buttons.released(BTN_B)) 187 | break; 188 | mp.update(); 189 | if(mp.buttons.released(BTN_FUN_LEFT)) break; 190 | if(mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) 191 | { 192 | state = !state; 193 | Serial.println(state); 194 | delay(5); 195 | while(!mp.update()); 196 | } 197 | } 198 | mp.buttons.update(); 199 | } 200 | mp.update(); 201 | } 202 | } -------------------------------------------------------------------------------- /src/calendarApp.cpp: -------------------------------------------------------------------------------- 1 | #include "calendarApp.h" 2 | void calendarApp() 3 | { 4 | int startDay = 0; // Sunday's value is 0, Saturday is 6 5 | int8_t days[5][7] = { 6 | {-1, -1, -1, -1, -1, -1, -1}, 7 | {-1, -1, -1, -1, -1, -1, -1}, 8 | {-1, -1, -1, -1, -1, -1, -1}, 9 | {-1, -1, -1, -1, -1, -1, -1}, 10 | {-1, -1, -1, -1, -1, -1, -1} 11 | }; 12 | String week6 = ""; 13 | int newWeekStart = 0; // used to show start of next week of the month 14 | String monthNames PROGMEM = "JanFebMarAprMayJunJulAugSepOctNovDec"; 15 | static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; 16 | int monthLength = 0; 17 | uint8_t offset = 7; 18 | mp.updateTimeRTC(); 19 | uint8_t month = mp.clockMonth; 20 | uint16_t year = mp.clockYear; 21 | 22 | while(!mp.buttons.released(BTN_B)) 23 | { 24 | //printing the month 25 | { 26 | mp.display.setTextFont(2); 27 | mp.display.setTextSize(1); 28 | mp.display.setTextColor(TFT_BLACK); 29 | mp.display.fillScreen(TFT_WHITE); 30 | mp.display.setTextColor(TFT_BLACK); 31 | mp.display.drawString("Mo Tu We Th Fr Sa Su", 5,9 - offset); 32 | if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12){ 33 | monthLength = 31; 34 | } 35 | else {monthLength = 30;} 36 | if(month == 2){monthLength = 28;} 37 | 38 | int y = year - (month < 3); 39 | startDay = (y +y/4 -y/100 + y/400 + t[month-1] + 1)% 7; // Sunday's value is 0 40 | // now build first week string 41 | switch (startDay){ 42 | case 1: 43 | // Monday 44 | for (int i = 1; i < 8; i++) 45 | days[0][i-1] = i; 46 | break; 47 | 48 | case 2: 49 | // Tuesday 50 | for (int i = 1; i < 7; i++) 51 | days[0][i] = i; 52 | 53 | break; 54 | 55 | case 3: 56 | // Wednesday 57 | for (int i = 1; i < 6; i++) 58 | days[0][i+1] = i; 59 | 60 | break; 61 | 62 | case 4: 63 | // Thursday 64 | for (int i = 1; i < 5; i++) 65 | days[0][i+2] = i; 66 | break; 67 | 68 | case 5: 69 | // Friday 70 | for (int i = 1; i < 4; i++) 71 | days[0][i+3] = i; 72 | break; 73 | 74 | case 6: 75 | // Saturday 76 | for (int i = 1; i < 3; i++) 77 | days[0][i+4] = i; 78 | if(monthLength == 31) 79 | week6 = "31"; 80 | break; 81 | 82 | case 0: 83 | // Sunday 84 | days[0][6] = 1; 85 | if(monthLength == 30){week6 = "30";} 86 | else if(monthLength == 31){week6 = "30 31";} 87 | 88 | break; 89 | } // end first week 90 | startDay += 6; 91 | if(startDay > 6) 92 | startDay %= 7; 93 | 94 | newWeekStart = (7-startDay) + 1; 95 | for (int f = newWeekStart; f < newWeekStart + 7; f++) 96 | days[1][f - newWeekStart] = f; 97 | 98 | newWeekStart = (14-startDay)+1; 99 | for (int f = newWeekStart; f < newWeekStart + 7; f++) 100 | days[2][f - newWeekStart] = f; 101 | 102 | newWeekStart = (21-startDay)+1; 103 | for (int f = newWeekStart; f < newWeekStart + 7; f++) 104 | days[3][f - newWeekStart] = f; 105 | 106 | newWeekStart = (28-startDay)+1; 107 | // is is February? 108 | if(newWeekStart > 28 && month == 2){ 109 | // do nothing unless its a leap year 110 | if (year==(year/4)*4) // its a leap year 111 | days[4][0] = 29; 112 | } 113 | else{ // print up to 30 anyway 114 | if(month == 2){ // its February 115 | for (int f = newWeekStart; f < 29; f++) 116 | days[4][f - newWeekStart] = f; 117 | // is it a leap year 118 | if (year==(year/4)*4) // its a leap year 119 | days[4][29 - newWeekStart] = 29; 120 | } 121 | else{ 122 | for (int f = newWeekStart; f < 31; f++) 123 | days[4][f - newWeekStart] = f; 124 | // are there 31 days 125 | if (monthLength == 31 && days[4][6] == -1) 126 | days[4][31 - newWeekStart] = 31; 127 | } 128 | } 129 | mp.display.setCursor(6, 100 - offset); 130 | if(week6 != "") 131 | { 132 | mp.display.print(week6.c_str()); 133 | week6 = ""; 134 | } 135 | mp.display.setCursor(0, 110); 136 | mp.display.printCenter(String(monthNames.substring((month - 1) * 3, month * 3)) + " " + year); 137 | mp.display.fillRect(2 + 111, 18, 44, 90, TFT_LIGHTGREY); 138 | for (int y = 0; y < 5;y++) 139 | { 140 | mp.display.drawFastHLine(2, 18 + 15 * y, 155, TFT_BLACK); 141 | for(int x = 0; x<7;x++) 142 | { 143 | mp.display.drawFastVLine(2 + 22 * x, 18, 90, TFT_BLACK); 144 | if(month == mp.clockMonth && days[y][x] == mp.clockDay && year == mp.clockYear && millis()%500 >= 250) 145 | mp.display.fillRect(3 + 22 * x, 19 + 15 * y, 21, 14, TFT_RED); 146 | mp.display.setCursor(6 + 22 * x, 18 + 15 * y); 147 | if(days[y][x] < 10) 148 | mp.display.setCursor(6 + 4 + 22 * x, 18 + 15 * y); 149 | if(days[y][x] > 0) 150 | mp.display.print(days[y][x]); 151 | // Serial.print(days[y][x]); 152 | // Serial.print("|"); 153 | days[y][x] = -1; 154 | } 155 | // Serial.print("\n-----------\n"); 156 | // delay(5); 157 | } 158 | mp.display.drawFastVLine(2 + 154, 18, 90, TFT_BLACK); 159 | mp.display.drawFastHLine(2, 18 + 75, 155, TFT_BLACK); 160 | mp.display.drawFastHLine(2, 18 + 90, 155, TFT_BLACK); 161 | 162 | } 163 | if(mp.buttons.released(BTN_HOME)) { 164 | mp.exitedLockscreen = true; 165 | mp.lockscreen(); // Robert 166 | } 167 | if(mp.buttons.released(BTN_LEFT)) 168 | { 169 | while(!mp.update()); 170 | if(month > 1) 171 | month--; 172 | else 173 | { 174 | month = 12; 175 | year--; 176 | } 177 | } 178 | if(mp.buttons.released(BTN_RIGHT)) 179 | { 180 | while(!mp.update()); 181 | if(month < 12) 182 | month++; 183 | else 184 | { 185 | month = 1; 186 | year++; 187 | } 188 | } 189 | mp.update(); 190 | } 191 | while(!mp.update()); 192 | } 193 | -------------------------------------------------------------------------------- /src/calculatorApp.cpp: -------------------------------------------------------------------------------- 1 | #include "calculatorApp.h" 2 | void calculatorApp() 3 | { 4 | String input = "0"; 5 | double result = 0; 6 | double helper = 0; 7 | char key; 8 | uint8_t tempCursor; 9 | uint8_t cursor = 0; 10 | uint32_t blinkMillis = millis(); 11 | uint32_t helpMillisOne; 12 | int8_t operation = -1; 13 | bool blinkState = 0; 14 | bool clear = 0; 15 | bool set = 0; 16 | 17 | while(1) 18 | { 19 | mp.display.fillScreen(0xA794); 20 | mp.display.drawRect(6,5, 149, 40, TFT_BLACK); 21 | mp.display.fillRect(7,6,147,38, TFT_LIGHTGREY); 22 | for (int y = 0; y < 2; y++) 23 | { 24 | for (int x = 0; x < 4; x++) 25 | { 26 | mp.display.drawRect(8 + 37 * x, 49 + 27 * y, 33, 23, TFT_BLACK); 27 | mp.display.fillRect(9 + 37 * x, 50 + 27 * y, 31, 21, TFT_LIGHTGREY); 28 | switch (y*4 + x) 29 | { 30 | case 0: 31 | mp.display.drawBitmap(18, 54, calculatorPlus); 32 | break; 33 | case 1: 34 | mp.display.drawBitmap(55, 59, calculatorMinus); 35 | break; 36 | case 2: 37 | mp.display.drawBitmap(92, 54, calculatorMultiply); 38 | break; 39 | case 3: 40 | mp.display.drawBitmap(128, 54, calculatorDivide); 41 | break; 42 | case 4: 43 | mp.display.drawBitmap(15, 79, calculatorRoot); 44 | break; 45 | case 5: 46 | mp.display.drawBitmap(55, 80, calculatorPotency); 47 | break; 48 | case 6: 49 | mp.display.drawBitmap(87, 79, calculatorReciprocal); 50 | break; 51 | case 7: 52 | mp.display.drawBitmap(133, 91, calculatorDecimalPoint); 53 | break; 54 | } 55 | } 56 | } 57 | // mp.display.drawRect(119, 103, 33, 23, TFT_BLACK); 58 | // mp.display.fillRect(120, 104, 31, 21, 0x4D42); 59 | mp.display.setCursor(7, 110); 60 | mp.display.setTextFont(2); 61 | mp.display.setTextSize(1); 62 | mp.display.setTextColor(TFT_BLACK); 63 | mp.display.print("Erase"); 64 | mp.display.setCursor(110, 110); 65 | mp.display.println("Equals"); 66 | // key = mp.buttons.getKey(); 67 | 68 | if(input.length() < 8 || clear) { 69 | for(int i = 0; i < 11; i++) { 70 | if(i == 9) { 71 | continue; 72 | } 73 | 74 | if(mp.buttons.released(i)) { 75 | if(i == 10) { 76 | key = '0'; 77 | } else { 78 | key = '1' + i; 79 | } 80 | 81 | if(clear) { 82 | input = "0"; 83 | clear = 0; 84 | } 85 | if(input == "0") { 86 | input = ""; 87 | } 88 | 89 | input.concat(key); 90 | } 91 | } 92 | } 93 | 94 | 95 | // if(key != NO_KEY && key > 47 && key < 58 && input.length() < 8) 96 | // { 97 | // if(clear) 98 | // { 99 | // input = "0"; 100 | // clear = 0; 101 | // } 102 | // if(input == "0") 103 | // input = ""; 104 | // input.concat(key); 105 | // } 106 | 107 | if(millis() - blinkMillis > 250) 108 | { 109 | blinkState = !blinkState; 110 | blinkMillis = millis(); 111 | } 112 | mp.display.fillRect(7,6,147,38, TFT_LIGHTGREY); 113 | mp.display.setTextSize(2); 114 | mp.display.setTextFont(2); 115 | mp.display.setTextWrap(0); 116 | mp.display.setCursor(200, 200); 117 | tempCursor = mp.display.cursor_x; 118 | mp.display.print(input); 119 | tempCursor = mp.display.cursor_x - tempCursor; 120 | mp.display.setCursor(145-tempCursor, 7); 121 | mp.display.print(input); 122 | 123 | mp.display.drawRect(7 + 37 * (cursor % 4), 48 + 27 * (int)(cursor / 4), 35, 25, blinkState ? TFT_RED : 0xA794); 124 | mp.display.drawRect(6 + 37 * (cursor % 4), 47 + 27 * (int)(cursor / 4), 37, 27, blinkState ? TFT_RED : 0xA794); 125 | 126 | if(mp.buttons.held(BTN_FUN_LEFT, 40)) 127 | { 128 | while(!mp.update()); 129 | result = 0; 130 | operation = -1; 131 | input = "0"; 132 | clear = 0; 133 | helper = 0; 134 | } 135 | if(mp.buttons.released(BTN_FUN_LEFT)) 136 | { 137 | if(input == "Error") input = ""; 138 | else input.remove(input.length() - 1); 139 | if(input == "") 140 | input = "0"; 141 | } 142 | if(mp.buttons.released(BTN_HOME)) { 143 | mp.exitedLockscreen = true; 144 | mp.lockscreen(); 145 | } 146 | if(mp.buttons.pressed(BTN_LEFT)) 147 | { 148 | mp.display.drawRect(7 + 37 * (cursor % 4), 48 + 27 * (int)(cursor / 4), 35, 25, 0xA794); 149 | mp.display.drawRect(6 + 37 * (cursor % 4), 47 + 27 * (int)(cursor / 4), 37, 27, 0xA794); 150 | if(cursor%4 > 0) 151 | cursor--; 152 | else 153 | cursor += 3; 154 | blinkState = 1; 155 | blinkMillis = millis(); 156 | helpMillisOne = millis(); 157 | while(!mp.update()); 158 | //while (helpMillisOne + 50 > millis()); 159 | } 160 | if(mp.buttons.pressed(BTN_RIGHT)) 161 | { 162 | mp.display.drawRect(7 + 37 * (cursor % 4), 48 + 27 * (int)(cursor / 4), 35, 25, 0xA794); 163 | mp.display.drawRect(6 + 37 * (cursor % 4), 47 + 27 * (int)(cursor / 4), 37, 27, 0xA794); 164 | if(cursor%4 < 3) 165 | cursor++; 166 | else 167 | cursor -= 3; 168 | blinkState = 1; 169 | blinkMillis = millis(); 170 | while(!mp.update()); 171 | } 172 | if(mp.buttons.pressed(BTN_DOWN)) 173 | { 174 | mp.display.drawRect(7 + 37 * (cursor % 4), 48 + 27 * (int)(cursor / 4), 35, 25, 0xA794); 175 | mp.display.drawRect(6 + 37 * (cursor % 4), 47 + 27 * (int)(cursor / 4), 37, 27, 0xA794); 176 | if((int)(cursor/4) < 1) 177 | cursor += 4; 178 | else 179 | cursor -= 4; 180 | blinkState = 1; 181 | blinkMillis = millis(); 182 | while(!mp.update()); 183 | } 184 | if(mp.buttons.pressed(BTN_UP)) 185 | { 186 | mp.display.drawRect(7 + 37 * (cursor % 4), 48 + 27 * (int)(cursor / 4), 35, 25, 0xA794); 187 | mp.display.drawRect(6 + 37 * (cursor % 4), 47 + 27 * (int)(cursor / 4), 37, 27, 0xA794); 188 | if((int)(cursor/4) > 0) 189 | cursor -= 4; 190 | else 191 | cursor += 4; 192 | blinkState = 1; 193 | blinkMillis = millis(); 194 | while(!mp.update()); 195 | } 196 | if(mp.buttons.released(BTN_A)) 197 | { 198 | if(cursor == 4) 199 | { 200 | result = input.toDouble(); 201 | // Serial.println(sqrt((double)(result))); 202 | result = sqrt(result); 203 | if(result == int(result)) 204 | input = String((int)(round(result))); 205 | else 206 | input = String(result); 207 | } 208 | else if(cursor == 6) 209 | { 210 | result = input.toDouble(); 211 | result = 1/result; 212 | if(result == int(result)) 213 | input = String((int)(round(result))); 214 | else 215 | input = String(result); 216 | } 217 | else if(cursor == 7 && input.indexOf('.') == -1 && input.length() < 8) 218 | { 219 | if(input == "" || clear) 220 | { 221 | input = "0"; 222 | clear = 0; 223 | } 224 | input.concat('.'); 225 | } 226 | else if(operation == -1 && cursor != 4 && cursor != 6) 227 | { 228 | clear = 1; 229 | result = input.toDouble(); 230 | set = 0; 231 | operation = cursor; 232 | } 233 | else if(operation > -1 && cursor != 4 && cursor != 6) 234 | { 235 | if(!set) 236 | { 237 | helper = input.toDouble(); 238 | set = 1; 239 | } 240 | 241 | set = 0; 242 | if(operation == cursor && !clear) 243 | { 244 | switch (operation) 245 | { 246 | case 0: 247 | result += helper; 248 | break; 249 | case 1: 250 | result -= helper; 251 | break; 252 | case 2: 253 | result *= helper; 254 | break; 255 | case 3: 256 | result /= helper; 257 | break; 258 | case 5: 259 | result = pow(result, helper); 260 | break; 261 | } 262 | if(result == int(result)) 263 | input = String((int)(round(result))); 264 | else 265 | input = String(result); 266 | set = 1; 267 | clear = 1; 268 | } 269 | else 270 | operation = cursor; 271 | 272 | } 273 | 274 | while(!mp.update()); 275 | Serial.println(operation); 276 | } 277 | if(mp.buttons.released(BTN_FUN_RIGHT)) 278 | { 279 | while(!mp.update()); 280 | if(operation != -1 && !clear) 281 | { 282 | if(!set) 283 | { 284 | helper = input.toDouble(); 285 | set = 1; 286 | } 287 | set = 0; 288 | switch (operation) 289 | { 290 | case 0: 291 | result += input.toDouble(); 292 | break; 293 | case 1: 294 | result -= input.toDouble(); 295 | break; 296 | case 2: 297 | result *= input.toDouble(); 298 | break; 299 | case 3: 300 | result /= input.toDouble(); 301 | break; 302 | case 5: 303 | result = pow(result, helper); 304 | break; 305 | } 306 | if(result == int(result)) 307 | input = String((int)(round(result))); 308 | else 309 | input = String(result); 310 | operation = -1; 311 | } 312 | } 313 | if(input.length() > 8 || input == "inf") 314 | { 315 | input = "Error"; 316 | clear = 1; 317 | } 318 | if(mp.buttons.released(BTN_B)) 319 | break; 320 | helpMillisOne = millis(); 321 | mp.update(); 322 | while (helpMillisOne + 50 > millis()); 323 | } 324 | while(!mp.update()); 325 | } 326 | -------------------------------------------------------------------------------- /src/mainMenu.cpp: -------------------------------------------------------------------------------- 1 | #include "mainMenu.h" 2 | uint8_t pageIndex = 0; 3 | uint8_t cameraY = 0; 4 | uint16_t directoryCount = 0; 5 | String directories[100]; 6 | String BinaryFiles[100]; 7 | uint16_t binaryCount = 0; 8 | void listDirectories(const char * dirname) 9 | { 10 | 11 | directoryCount = 0; 12 | Serial.printf("Listing directory: %s\n", dirname); 13 | 14 | File root = SD.open(dirname); 15 | if (!root) { 16 | Serial.println(F("Failed to open directory")); 17 | return; 18 | } 19 | if (!root.isDirectory()) { 20 | Serial.println(F("Not a directory")); 21 | return; 22 | 23 | } 24 | int counter = 0; 25 | 26 | File file = root.openNextFile(); 27 | while (file) { 28 | 29 | if (file.isDirectory()) { 30 | String Name(file.name()); 31 | Serial.println(Name); 32 | if(Name != "/Images\0" && Name != "/Music\0" && Name != "/Video\0" 33 | && Name != "/System Volume Information\0" && SD.exists(String(Name + "/" + Name + ".BIN"))) 34 | { 35 | Serial.println(Name); 36 | directories[directoryCount] = Name.substring(1); 37 | counter++; 38 | directoryCount++; 39 | } 40 | } 41 | file = root.openNextFile(); 42 | } 43 | } 44 | void listBinaries(const char * dirname, uint8_t levels) 45 | { 46 | 47 | binaryCount = 0; 48 | Serial.printf("Listing directory: %s\n", dirname); 49 | 50 | File root = SD.open(dirname); 51 | if (!root) { 52 | Serial.println(F("Failed to open directory")); 53 | return; 54 | } 55 | if (!root.isDirectory()) { 56 | Serial.println(F("Not a directory")); 57 | return; 58 | 59 | } 60 | int counter = 1; 61 | 62 | File file = root.openNextFile(); 63 | while (file) { 64 | 65 | /*if (file.isDirectory()) { 66 | Serial.print(F(" DIR : ")); 67 | Serial.println(file.name()); 68 | if (levels) { 69 | listBinaries(fs, file.name(), levels - 1); 70 | } 71 | } 72 | else { 73 | String Name = file.name(); 74 | if (Name.endsWith(F(F(".bin"))) 75 | { 76 | Serial.print(file.name()); 77 | BinaryFiles[counter-1] = file.name(); 78 | } 79 | }*/ 80 | //char temp[100]; 81 | // file.getName(temp, 100); 82 | String Name(file.name()); 83 | Serial.println(Name); 84 | if (Name.endsWith(F(".BIN")) || Name.endsWith(F(".bin"))) 85 | { 86 | Serial.print(counter); 87 | Serial.print(F(". ")); 88 | Serial.println(Name); 89 | BinaryFiles[counter - 1] = Name; 90 | counter++; 91 | binaryCount++; 92 | } 93 | file = root.openNextFile(); 94 | } 95 | } 96 | int16_t scrollingMainMenu(uint16_t _cursor) 97 | { 98 | bool SDinserted = mp.SDinsertedFlag; 99 | bool cursorState = 0; 100 | uint16_t index = 0; 101 | uint8_t cursorX = 0; 102 | uint8_t cursorY = 0; 103 | uint8_t elements = 9 + directoryCount; //9 default apps 104 | uint8_t x_elements = 3; 105 | uint8_t y_elements = ceil((float)elements/x_elements); 106 | 107 | uint8_t pageNumber; 108 | if(elements < 6) 109 | pageNumber = 0; 110 | else 111 | pageNumber = ceil((float)(elements - 6)/3); 112 | cursorY = int(_cursor / x_elements); 113 | cursorX = _cursor % x_elements; 114 | Serial.println(cursorY); 115 | String appNames[] = {"Clock", "Calculator", "Flashlight", "Calendar", "Invaders"}; 116 | String passcode = ""; 117 | uint32_t passcodeMillis = millis(); 118 | uint32_t elapsedMillis = millis(); 119 | uint32_t elapsedMillis2 = millis(); 120 | bool newScreen = 1; 121 | mp.display.fillScreen(TFT_BLACK); 122 | Serial.println(mp.buttons.timeHeld(BTN_A)); 123 | // while(!mp.update()); 124 | while (1) 125 | { 126 | mp.display.fillRect(0,0,mp.display.width(), 14, TFT_BLACK); 127 | mp.display.setTextSize(1); 128 | mp.display.setTextColor(TFT_WHITE); 129 | 130 | // Draw the icons 131 | if(newScreen) 132 | { 133 | mp.display.fillScreen(TFT_BLACK); 134 | for (int i = 0; i < 6;i++) 135 | { 136 | uint8_t tempX = i%x_elements; 137 | uint8_t tempY = i/x_elements; 138 | switch (pageIndex * 3 + i) 139 | { 140 | case 0: 141 | // Serial.println(index); 142 | // Serial.println(i); 143 | // Serial.println(tempX); 144 | // Serial.println(tempY); 145 | // Serial.println(F("-------------")); 146 | // delay(5); 147 | mp.display.drawIcon(bigPhone, 4 + tempX * 52, 18 + tempY * 56, width, bigIconHeight, 2); 148 | break; 149 | case 1: 150 | mp.display.drawIcon(bigContacts, 4 + tempX * 52, 18 + tempY * 56, width, bigIconHeight, 2); 151 | break; 152 | case 2: 153 | mp.display.drawIcon(bigMessages, 4 + tempX * 52, 18 + tempY * 56, width, bigIconHeight, 2); 154 | break; 155 | case 3: 156 | mp.display.drawIcon(bigSettings, 4 + tempX * 52, 18 + tempY * 56, width, bigIconHeight, 2); 157 | break; 158 | case 4: 159 | mp.display.drawIcon(bigMedia, 4 + tempX * 52, 18 + tempY * 56, width, bigIconHeight, 2); 160 | break; 161 | // case 5: 162 | // mp.display.drawIcon(bigApps, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 163 | // break; 164 | case 5: 165 | mp.display.drawIcon(clock_icon, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 166 | break; 167 | case 6: 168 | mp.display.drawIcon(calculator_icon, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 169 | break; 170 | case 7: 171 | mp.display.drawIcon(flash_icon, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 172 | break; 173 | case 8: 174 | mp.display.drawIcon(calendar_icon, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 175 | break; 176 | default: 177 | if(pageIndex * 3 + i < elements) 178 | { 179 | Serial.println(directories[pageIndex * 3 + i - 9]); 180 | delay(5); 181 | if(SD.exists(String("/" + directories[pageIndex * 3 + i - 9] + "/icon.bmp"))) 182 | mp.display.drawBmp(String("/" + directories[pageIndex * 3 + i - 9] + "/icon.bmp"), 4 + tempX * 52, 18 + tempY * 56, 2); 183 | else 184 | mp.display.drawIcon(defaultIcon, 4 + tempX * 52, 18 + tempY * 56, width, bigIconHeight, 2); 185 | } 186 | break; 187 | } 188 | } 189 | newScreen = 0; 190 | } 191 | 192 | mp.display.fillRect(0, 0, 160, 12, TFT_BLACK); 193 | while(cursorY*x_elements + cursorX >= elements) 194 | cursorX--; 195 | 196 | index = cursorY * x_elements + cursorX; 197 | // Serial.println(index); 198 | // Serial.println(pageIndex); 199 | // Serial.println(F("-----------------")); 200 | // delay(5); 201 | mp.display.setTextFont(2); 202 | mp.display.setCursor(0,-2); 203 | mp.display.drawFastHLine(0, 14, mp.display.width(), TFT_WHITE); 204 | if(index < 9) 205 | mp.display.print(titles[index]); 206 | else 207 | mp.display.print(directories[index-9]); 208 | 209 | if (millis() - elapsedMillis >= 250) { 210 | elapsedMillis = millis(); 211 | cursorState = !cursorState; 212 | } 213 | if (millis() - elapsedMillis2 >= 100) { 214 | elapsedMillis2 = millis(); 215 | } 216 | if (millis() - passcodeMillis >= 1000) 217 | passcode = ""; 218 | 219 | // mp.display.drawIcon(bigMessages, 4 + cursorX*52, 18 + cursorY*56, width, bigIconHeight, 2); 220 | 221 | mp.display.drawRect(3 + cursorX * 52, 17 + (cameraY) * 56, 50, 54, cursorState ? TFT_RED : TFT_BLACK); 222 | mp.display.drawRect(2 + cursorX * 52, 16 + (cameraY) * 56, 52, 56, cursorState ? TFT_RED : TFT_BLACK); 223 | 224 | /////////////////////////////////////// 225 | //////Checking for button input//////// 226 | /////////////////////////////////////// 227 | if (mp.buttons.released(BTN_A) ) //CONFIRM 228 | { 229 | // mp.osc->note(75, 0.05); 230 | // mp.osc->play(); 231 | mp.buttons.update(); 232 | return cursorY * x_elements + cursorX; //returns index of selected icon 233 | } 234 | if (mp.buttons.pressed(BTN_UP)) //UP 235 | { 236 | mp.display.drawRect(3 + cursorX * 52, 17 + (cameraY) * 56, 50, 54, TFT_BLACK); 237 | mp.display.drawRect(2 + cursorX * 52, 16 + (cameraY) * 56, 52, 56, TFT_BLACK); 238 | mp.osc->note(75, 0.05); 239 | mp.osc->play(); 240 | passcode += "UP"; 241 | passcodeMillis = millis(); 242 | mp.leds[0] = CRGB::Blue; 243 | mp.leds[7] = CRGB::Blue; 244 | FastLED.clear(); 245 | while(!mp.update()); 246 | 247 | if (cursorY == 0) 248 | { 249 | newScreen = 1; 250 | cursorY = y_elements-1; 251 | 252 | if(pageNumber > 0) 253 | { 254 | cameraY = 1; 255 | pageIndex = pageNumber; 256 | } 257 | } 258 | else if(cameraY % 2 == 1) 259 | { 260 | cursorY--; 261 | cameraY = 0; 262 | } 263 | else if(cameraY % 2 == 0 && pageIndex > 0) 264 | { 265 | newScreen = 1; 266 | cameraY = 0; 267 | cursorY--; 268 | pageIndex--; 269 | } 270 | elapsedMillis = millis(); 271 | cursorState = 1; 272 | } 273 | if (mp.buttons.pressed(BTN_DOWN))//DOWN 274 | { 275 | mp.display.drawRect(3 + cursorX * 52, 17 + (cameraY) * 56, 50, 54, TFT_BLACK); 276 | mp.display.drawRect(2 + cursorX * 52, 16 + (cameraY) * 56, 52, 56, TFT_BLACK); 277 | mp.osc->note(75, 0.05); 278 | mp.osc->play(); 279 | passcode += "DOWN"; 280 | passcodeMillis = millis(); 281 | mp.leds[3] = CRGB::Blue; 282 | mp.leds[4] = CRGB::Blue; 283 | FastLED.clear(); 284 | while(!mp.update()); 285 | 286 | if (cursorY == y_elements - 1) 287 | { 288 | newScreen = 1; 289 | cursorY = 0; 290 | pageIndex = 0; 291 | cameraY = 0; 292 | } 293 | else if(cameraY % 2 == 0) 294 | { 295 | cursorY++; 296 | cameraY++; 297 | } 298 | else if (cameraY % 2 == 1 && pageIndex < pageNumber) 299 | { 300 | newScreen = 1; 301 | cameraY = 1; 302 | cursorY++; 303 | pageIndex++; 304 | } 305 | 306 | elapsedMillis = millis(); 307 | cursorState = 1; 308 | } 309 | if (mp.buttons.pressed(BTN_LEFT)) //LEFT 310 | { 311 | mp.display.drawRect(3 + cursorX * 52, 17 + (cameraY) * 56, 50, 54, TFT_BLACK); 312 | mp.display.drawRect(2 + cursorX * 52, 16 + (cameraY) * 56, 52, 56, TFT_BLACK); 313 | mp.osc->note(75, 0.05); 314 | mp.osc->play(); 315 | passcode += "LEFT"; 316 | passcodeMillis = millis(); 317 | mp.leds[6] = CRGB::Blue; 318 | mp.leds[5] = CRGB::Blue; 319 | FastLED.clear(); 320 | while(!mp.update()); 321 | 322 | if (cursorX == 0) { 323 | cursorX = x_elements - 1; 324 | } 325 | else 326 | cursorX--; 327 | elapsedMillis = millis(); 328 | cursorState = 1; 329 | } 330 | if (mp.buttons.pressed(BTN_RIGHT))//RIGHT 331 | { 332 | mp.display.drawRect(3 + cursorX * 52, 17 + (cameraY) * 56, 50, 54, TFT_BLACK); 333 | mp.display.drawRect(2 + cursorX * 52, 16 + (cameraY) * 56, 52, 56, TFT_BLACK); 334 | mp.osc->note(75, 0.05); 335 | mp.osc->play(); 336 | passcode += "RIGHT"; 337 | passcodeMillis = millis(); 338 | mp.leds[1] = CRGB::Blue; 339 | mp.leds[2] = CRGB::Blue; 340 | FastLED.clear(); 341 | while(!mp.update()); 342 | 343 | if (cursorX == x_elements - 1) { 344 | cursorX = 0; 345 | } 346 | else 347 | cursorX++; 348 | elapsedMillis = millis(); 349 | cursorState = 1; 350 | } 351 | if (mp.buttons.released(BTN_B))//B BUTTON 352 | { 353 | 354 | mp.leds[0] = CRGB::Red; 355 | mp.leds[7] = CRGB::Red; 356 | FastLED.show(); 357 | FastLED.clear(); 358 | while(!mp.update()); 359 | pageIndex = 0; 360 | cameraY = 0; 361 | return -2; 362 | } 363 | // if (passcode == "UPUPDOWNDOWNLEFTRIGHTLEFTRIGHT") 364 | // return -3; 365 | if(SDinserted != mp.SDinsertedFlag) 366 | { 367 | SDinserted = mp.SDinsertedFlag; 368 | pageIndex = 0; 369 | cameraY = 0; 370 | return -1; 371 | } 372 | if(mp.exitedLockscreen) 373 | { 374 | mp.display.fillScreen(TFT_BLACK); 375 | for (int i = 0; i < 6;i++) 376 | { 377 | uint8_t tempX = i%x_elements; 378 | uint8_t tempY = i/x_elements; 379 | switch (pageIndex * 3 + i) 380 | { 381 | case 0: 382 | // Serial.println(index); 383 | // Serial.println(i); 384 | // Serial.println(tempX); 385 | // Serial.println(tempY); 386 | // Serial.println(F("-------------")); 387 | // delay(5); 388 | mp.display.drawIcon(bigPhone, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 389 | break; 390 | case 1: 391 | mp.display.drawIcon(bigContacts, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 392 | break; 393 | case 2: 394 | mp.display.drawIcon(bigMessages, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 395 | break; 396 | case 3: 397 | mp.display.drawIcon(bigSettings, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 398 | break; 399 | case 4: 400 | mp.display.drawIcon(bigMedia, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 401 | break; 402 | // case 5: 403 | // mp.display.drawIcon(bigApps, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 404 | // break; 405 | case 5: 406 | mp.display.drawIcon(clock_icon, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 407 | break; 408 | case 6: 409 | mp.display.drawIcon(calculator_icon, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 410 | break; 411 | case 7: 412 | mp.display.drawIcon(flash_icon, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 413 | break; 414 | case 8: 415 | mp.display.drawIcon(calendar_icon, 4 + tempX*52, 18 + tempY*56, width, bigIconHeight, 2); 416 | break; 417 | default: 418 | if(pageIndex * 3 + i < elements) 419 | { 420 | Serial.println(directories[pageIndex * 3 + i - 9]); 421 | delay(5); 422 | if(SD.exists(String("/" + directories[pageIndex * 3 + i - 9] + "/icon.bmp"))) 423 | mp.display.drawBmp(String("/" + directories[pageIndex * 3 + i - 9] + "/icon.bmp"), 4 + tempX * 52, 18 + tempY * 56, 2); 424 | else 425 | mp.display.drawIcon(defaultIcon, 4 + tempX * 52, 18 + tempY * 56, width, bigIconHeight, 2); 426 | } 427 | break; 428 | } 429 | } 430 | } 431 | mp.update(); 432 | } 433 | } 434 | void mainMenu() 435 | { 436 | while(1) 437 | { 438 | int16_t index = 0; 439 | Serial.println(F("entered main menu")); 440 | mp.dataRefreshFlag = 0; 441 | listDirectories("/"); 442 | while (1) 443 | { 444 | index = scrollingMainMenu(index); 445 | Serial.println(index); 446 | delay(5); 447 | if (index == -2) 448 | { 449 | Serial.println(F("pressed")); 450 | mp.lockscreen(); 451 | break; 452 | } 453 | else if(index == -1) 454 | break; 455 | else if(index < 9) 456 | { 457 | if (titles[index] == "Apps") 458 | { 459 | mp.display.fillScreen(TFT_BLACK); 460 | mp.display.setCursor(0, mp.display.height()/2 - 20); 461 | mp.display.setTextFont(2); 462 | mp.display.printCenter(F("PLACEHOLDER")); 463 | mp.display.setCursor(0, mp.display.height()/2); 464 | mp.display.printCenter(F("PLACEHOLDER")); 465 | uint32_t tempMillis = millis(); 466 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 467 | mp.update(); 468 | while(!mp.update()); 469 | } 470 | 471 | if (titles[index] == "Messages") 472 | { 473 | if(mp.SDinsertedFlag) 474 | { 475 | while(!mp.update()); 476 | messagesApp(); 477 | } 478 | else if(!mp.SDinsertedFlag) 479 | { 480 | mp.display.fillScreen(TFT_BLACK); 481 | mp.display.setTextColor(TFT_WHITE); 482 | mp.display.setCursor(0, mp.display.height()/2 - 20); 483 | mp.display.setTextFont(2); 484 | mp.display.printCenter(F("Can't access SMS!")); 485 | mp.display.setCursor(0, mp.display.height()/2); 486 | mp.display.printCenter(F("SD card missing")); 487 | uint32_t tempMillis = millis(); 488 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 489 | mp.update(); 490 | while(!mp.update()); 491 | } 492 | } 493 | 494 | if (titles[index] == "Media") 495 | { 496 | mp.display.fillScreen(TFT_BLACK); 497 | mp.display.setTextColor(TFT_WHITE); 498 | if(mp.SDinsertedFlag) 499 | mediaApp(); 500 | else 501 | { 502 | mp.display.setCursor(0, mp.display.height()/2 - 20); 503 | mp.display.setTextFont(2); 504 | mp.display.printCenter(F("No SD inserted!")); 505 | mp.display.setCursor(0, mp.display.height()/2); 506 | mp.display.printCenter(F("Insert SD card and reset")); 507 | uint32_t tempMillis = millis(); 508 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 509 | mp.update(); 510 | while(!mp.update()); 511 | } 512 | } 513 | 514 | if (titles[index] == "Phone") 515 | { 516 | mp.display.fillScreen(TFT_BLACK); 517 | mp.display.setTextColor(TFT_WHITE); 518 | phoneApp(); 519 | 520 | } 521 | 522 | if (titles[index] == "Contacts") { 523 | mp.display.fillScreen(TFT_BLACK); 524 | mp.display.setTextColor(TFT_WHITE); 525 | if(mp.SDinsertedFlag) 526 | { 527 | mp.display.fillScreen(TFT_BLACK); 528 | mp.display.setCursor(0,mp.display.height()/2 -16); 529 | mp.display.printCenter(F("Loading contacts...")); 530 | contactsApp(false); 531 | } 532 | else if(!mp.SDinsertedFlag) 533 | { 534 | mp.display.setCursor(0, mp.display.height()/2 - 20); 535 | mp.display.setTextFont(2); 536 | mp.display.printCenter(F("No SD inserted!")); 537 | mp.display.setCursor(0, mp.display.height()/2); 538 | mp.display.printCenter(F("Insert SD and reset")); 539 | uint32_t tempMillis = millis(); 540 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 541 | mp.update(); 542 | while(!mp.update()); 543 | } 544 | } 545 | 546 | if (titles[index] == "Settings") 547 | if(settingsApp()) 548 | { 549 | pageIndex = 0; 550 | cameraY = 0; 551 | return; 552 | } 553 | if(titles[index] == "Clock") 554 | clockApp(); 555 | if(titles[index] == "Calculator") 556 | calculatorApp(); 557 | if(titles[index] == "Flashlight") 558 | flashlightApp(); 559 | if(titles[index] == "Calendar") 560 | calendarApp(); 561 | } 562 | else 563 | { 564 | mp.display.fillScreen(TFT_BLACK); 565 | mp.display.setCursor(0,mp.display.height() / 2 - 16); 566 | mp.display.printCenter(F("LOADING NOW...")); 567 | while(!mp.update()); 568 | 569 | String foo = directories[index - 9]; //9 is the number of preloaded apps 570 | initWavLib(); 571 | mp.updateFromFS(String("/" + foo + "/" + foo + ".bin")); 572 | } 573 | mp.update(); 574 | 575 | } 576 | } 577 | } 578 | -------------------------------------------------------------------------------- /src/mediaApp.cpp: -------------------------------------------------------------------------------- 1 | #include "mediaApp.h" 2 | // uint8_t cursor = 0; 3 | // int32_t cameraY = 0; 4 | // int32_t cameraY_actual = 0; 5 | String mediaItems[3] PROGMEM = { 6 | "Music", 7 | "Photo", 8 | "Video", 9 | }; 10 | String photoFiles[100]; 11 | uint8_t photoCount = 0; 12 | bool firstPass = 0; 13 | MPTrack* mp3; 14 | 15 | //Media app 16 | 17 | void mediaApp() { 18 | mp.dataRefreshFlag = 0; 19 | while(1) 20 | { 21 | int8_t input = mediaMenu(mediaItems, 2); 22 | 23 | if(input == 0) //music 24 | { 25 | 26 | listAudio("/Music", 0); 27 | String tempList[audioCount]; 28 | uint16_t tempCount = audioCount; 29 | for (int i = 0; i < audioCount;i++) 30 | tempList[i] = audioFiles[i]; 31 | listAudio("/Ringtones", 0); 32 | for (int i = 0; i < tempCount;i++) 33 | audioFiles[i + audioCount] = tempList[i]; 34 | audioCount += tempCount; 35 | 36 | if(audioCount > 0) 37 | { 38 | int16_t index =0; 39 | while (1) 40 | { 41 | index = audioPlayerMenu("Select file to play:", audioFiles, audioCount, index); 42 | if (index == -1) 43 | break; 44 | mp.display.fillScreen(TFT_LIGHTGREY); 45 | Serial.print("before audio player: "); 46 | Serial.println(ESP.getFreeHeap()); 47 | delay(5); 48 | index = audioPlayer(index); 49 | if(!mp.SDinsertedFlag) 50 | break; 51 | Serial.print("after audio player: "); 52 | Serial.println(ESP.getFreeHeap()); 53 | delay(5); 54 | } 55 | } 56 | else 57 | { 58 | mp.display.fillScreen(TFT_BLACK); 59 | mp.display.setTextColor(TFT_WHITE); 60 | mp.display.setCursor(0, mp.display.height()/2 - 16); 61 | mp.display.setTextFont(2); 62 | mp.display.printCenter(F("No audio files!")); 63 | uint32_t tempMillis = millis(); 64 | while(millis() < tempMillis + 2000) 65 | { 66 | mp.update(); 67 | if(mp.buttons.pressed(BTN_A) || mp.buttons.pressed(BTN_B)) 68 | { 69 | while(!mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 70 | mp.update(); 71 | break; 72 | } 73 | } 74 | while(!mp.update()); 75 | } 76 | } 77 | else if(input == 1) //photos 78 | { 79 | mp.display.setTextColor(TFT_BLACK); 80 | mp.display.setTextSize(1); 81 | mp.display.setTextFont(2); 82 | mp.display.drawRect(14, 45, 134, 38, TFT_BLACK); 83 | mp.display.drawRect(13, 44, 136, 40, TFT_BLACK); 84 | mp.display.fillRect(15, 46, 132, 36, TFT_WHITE); 85 | mp.display.setCursor(47, 55); 86 | mp.display.printCenter(F("Loading photos")); 87 | while(!mp.update()); 88 | listPhotos("/Images", 0); 89 | if(photoCount > 0) 90 | { 91 | int16_t index = 0; 92 | while (1) 93 | { 94 | index = audioPlayerMenu("Select photo to open:", photoFiles, photoCount, index); 95 | if (index == -1) 96 | break; 97 | 98 | if(photoFiles[index].endsWith(".bmp") || photoFiles[index].endsWith(".BMP")) 99 | mp.display.drawBmp(photoFiles[index], 0,0); 100 | else 101 | mp.drawJpeg(photoFiles[index], 0, 0); 102 | while(!mp.update()); 103 | bool firstRefresh = 1; 104 | while(1) 105 | { 106 | if(mp.buttons.released(BTN_HOME)) { 107 | mp.exitedLockscreen = true; 108 | mp.lockscreen(); 109 | } 110 | if(mp.buttons.released(BTN_A) || mp.buttons.released(BTN_B) || !mp.SDinsertedFlag) 111 | break; 112 | if(mp.buttons.released(BTN_LEFT)) 113 | { 114 | firstRefresh = 1; 115 | if(index > 0) 116 | index--; 117 | else 118 | index = photoCount - 1; 119 | if(photoFiles[index].endsWith(".bmp") || photoFiles[index].endsWith(".BMP")) 120 | mp.display.drawBmp(photoFiles[index], 0,0); 121 | else 122 | mp.drawJpeg(photoFiles[index], 0, 0); 123 | while(!mp.update()); 124 | } 125 | if(mp.buttons.released(BTN_RIGHT)) 126 | { 127 | firstRefresh = 1; 128 | if(index < photoCount - 1) 129 | index++; 130 | else 131 | index = 0; 132 | if(photoFiles[index].endsWith(".bmp") || photoFiles[index].endsWith(".BMP")) 133 | mp.display.drawBmp(photoFiles[index], 0,0); 134 | else 135 | mp.drawJpeg(photoFiles[index], 0, 0); 136 | while(!mp.update()); 137 | } 138 | if(mp.buttons.holdForUnlock && firstRefresh) 139 | { 140 | firstRefresh = 0; 141 | if(photoFiles[index].endsWith(".bmp") || photoFiles[index].endsWith(".BMP")) 142 | mp.display.drawBmp(photoFiles[index], 0,0); 143 | else 144 | mp.drawJpeg(photoFiles[index], 0, 0); 145 | while(!mp.update()); 146 | } 147 | mp.update(); 148 | } 149 | Serial.println(F("out")); 150 | while(!mp.update()); 151 | } 152 | } 153 | else 154 | { 155 | mp.display.fillScreen(TFT_BLACK); 156 | mp.display.setTextColor(TFT_WHITE); 157 | mp.display.setCursor(0, mp.display.height()/2 - 16); 158 | mp.display.setTextFont(2); 159 | mp.display.printCenter(F("No photos found!")); 160 | uint32_t tempMillis = millis(); 161 | while(millis() < tempMillis + 2000) 162 | { 163 | mp.update(); 164 | if(mp.buttons.pressed(BTN_A) || mp.buttons.pressed(BTN_B)) 165 | { 166 | while(!mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 167 | mp.update(); 168 | break; 169 | } 170 | } 171 | while(!mp.update()); 172 | } 173 | while(!mp.update()); 174 | } 175 | else if(input == -1) 176 | break; 177 | } 178 | } 179 | int8_t mediaMenu(String* title, uint8_t length) { 180 | bool pressed = 0; 181 | int8_t cursor = 0; 182 | int32_t cameraY = 0; 183 | int32_t cameraY_actual = 0; 184 | mp.dataRefreshFlag = 0; 185 | bool blinkState = 0; 186 | uint32_t blinkMillis = millis(); 187 | uint8_t boxHeight; 188 | boxHeight = 54; //actually 2 less than that 189 | while (1) { 190 | if(!mp.SDinsertedFlag) 191 | return -1; 192 | mp.update(); 193 | mp.display.fillScreen(TFT_BLACK); 194 | mp.display.setCursor(0, 0); 195 | cameraY_actual = (cameraY_actual + cameraY) / 2; 196 | if (cameraY_actual - cameraY == 1) { 197 | cameraY_actual = cameraY; 198 | } 199 | if(millis() - blinkMillis > 350) 200 | { 201 | blinkMillis = millis(); 202 | blinkState = !blinkState; 203 | } 204 | for (uint8_t i = 0; i < length; i++) { 205 | mediaMenuDrawBox(title[i], i, cameraY_actual); 206 | } 207 | if(blinkState) 208 | mediaMenuDrawCursor(cursor, cameraY_actual, pressed); 209 | 210 | if(mp.buttons.released(BTN_HOME)) { 211 | mp.exitedLockscreen = true; 212 | mp.lockscreen(); 213 | } 214 | if (!mp.buttons.pressed(BTN_DOWN) && !mp.buttons.pressed(BTN_UP)) 215 | pressed = 0; 216 | 217 | if (mp.buttons.released(BTN_A)) { //BUTTON CONFIRM 218 | mp.osc->note(75, 0.05); 219 | mp.osc->play(); 220 | while(!mp.update());// Exit when pressed 221 | break; 222 | } 223 | 224 | if (mp.buttons.released(BTN_UP)) { //BUTTON UP 225 | blinkState = 1; 226 | blinkMillis = millis(); 227 | mp.osc->note(75, 0.05); 228 | mp.osc->play(); 229 | if (cursor == 0) { 230 | cursor = length - 1; 231 | if (length > 6) { 232 | cameraY = -(cursor - 2) * boxHeight; 233 | } 234 | } 235 | else { 236 | cursor--; 237 | if (cursor > 0 && (cursor * boxHeight + cameraY + settingsMenuYOffset) < boxHeight) { 238 | cameraY += 15; 239 | } 240 | } 241 | pressed = 1; 242 | } 243 | 244 | if (mp.buttons.released(BTN_DOWN)) { //BUTTON DOWN 245 | blinkState = 1; 246 | blinkMillis = millis(); 247 | mp.osc->note(75, 0.05); 248 | mp.osc->play(); 249 | cursor++; 250 | if ((cursor * boxHeight + cameraY + settingsMenuYOffset) > 128) { 251 | cameraY -= boxHeight; 252 | } 253 | if (cursor >= length) { 254 | cursor = 0; 255 | cameraY = 0; 256 | 257 | } 258 | pressed = 1; 259 | } 260 | 261 | 262 | if (mp.buttons.released(BTN_B) == 1) //BUTTON BACK 263 | { 264 | return -1; 265 | } 266 | } 267 | 268 | return cursor; 269 | 270 | } 271 | void mediaMenuDrawBox(String title, uint8_t i, int32_t y) { 272 | uint8_t boxHeight; 273 | uint8_t offset = 11; 274 | boxHeight = 54; 275 | y += i * boxHeight + offset; 276 | if (y < 0 || y > mp.display.width()) { 277 | return; 278 | } 279 | 280 | 281 | if (title == "Music") //red 282 | { 283 | mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2, 0xFC92); 284 | mp.display.drawIcon(mediaMusicIcon, 4, y + 3, 24,24,2); 285 | } 286 | if (title == "Photo") //blue 287 | { 288 | mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2, 0x963F); 289 | mp.display.drawIcon(mediaPhotoIcon, 4, y + 3, 24,24,2, 0xFC92); 290 | } 291 | // if (title == "Video") //yellow 292 | // { 293 | // mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2, TFT_DARKGREY); 294 | // } 295 | mp.display.setTextColor(TFT_BLACK); 296 | mp.display.setTextSize(2); 297 | mp.display.setTextFont(2); 298 | mp.display.drawString(title, 60, y + 10); 299 | mp.display.setTextColor(TFT_WHITE); 300 | mp.display.setTextSize(1); 301 | } 302 | void mediaMenuDrawCursor(uint8_t i, int32_t y, bool pressed) { 303 | uint8_t boxHeight; 304 | boxHeight = 54; 305 | uint8_t offset = 11; 306 | y += i * boxHeight + offset; 307 | mp.display.drawRect(0, y-1, mp.display.width()-1, boxHeight+2, TFT_RED); 308 | mp.display.drawRect(1, y, mp.display.width()-3, boxHeight, TFT_RED); 309 | } 310 | 311 | 312 | 313 | int16_t audioPlayer(uint16_t index) { 314 | uint8_t scale= 2; 315 | bool playState = 1; 316 | bool loop = 0; 317 | bool shuffleReset = 0; 318 | bool allTrue = 0; 319 | bool shuffle = 0; 320 | bool shuffleList[audioCount]; 321 | if(!firstPass) 322 | { 323 | mp3 = new MPTrack((char*)audioFiles[index].c_str()); 324 | addTrack(mp3); 325 | } 326 | while(1) 327 | { 328 | bool trackAdded = 0; 329 | for(uint8_t i = 0; i < 4;i++) 330 | { 331 | if(tracks[i] == mp3) 332 | { 333 | trackAdded = 1; 334 | break; 335 | } 336 | } 337 | if(!trackAdded && mp.SDinsertedFlag) 338 | { 339 | addTrack(mp3); 340 | Serial.println("Track added"); 341 | } 342 | else if(!mp.SDinsertedFlag) 343 | return 0; 344 | 345 | if(firstPass) 346 | { 347 | if(mp3->reloadFile((char*)audioFiles[index].c_str())) 348 | Serial.println("OK"); 349 | else 350 | Serial.println("ERROR"); 351 | } 352 | else 353 | firstPass = 1; 354 | 355 | if(playState); 356 | mp3->play(); 357 | //mp.osc->setVolume(0); 358 | if(mp.mediaVolume == 0) 359 | mp3->setVolume(0); 360 | else 361 | mp3->setVolume(mp.mediaVolume*40); 362 | 363 | while (1) 364 | { 365 | mp.display.fillScreen(backgroundColors[mp.backgroundIndex]); 366 | mp.display.drawBitmap(2*scale, 20*scale, previous, TFT_BLACK, scale); 367 | mp.display.drawBitmap(65*scale, 20*scale, next, TFT_BLACK, scale); 368 | mp.display.drawBitmap(2*scale, 75, repeatSprite, TFT_BLACK, scale); 369 | mp.display.drawBitmap(66*scale, 37*scale, shuffleIcon, TFT_BLACK, scale); 370 | if(playState) 371 | mp.display.drawBitmap(37*scale, 19*scale, play, TFT_BLACK, scale); 372 | else 373 | mp.display.drawBitmap(72, 40, pause2, TFT_BLACK, scale); 374 | mp.display.drawBitmap(17*scale, 2*scale, cover2, TFT_BLACK, scale); 375 | mp.display.setTextColor(TFT_BLACK); 376 | 377 | 378 | mp.display.setTextSize(1); 379 | mp.display.setTextWrap(0); 380 | mp.display.drawBitmap(4,2, fullSound, TFT_BLACK, 2); 381 | mp.display.setCursor(24, 2); 382 | mp.display.print(mp.mediaVolume); 383 | mp.display.setCursor(1, 111); 384 | if(audioFiles[index].length() > 20) 385 | mp.display.print(audioFiles[index]); 386 | else 387 | mp.display.printCenter(audioFiles[index]); 388 | mp.display.fillRect(141,74, 4,4, shuffle ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 389 | mp.display.fillRect(14,73, 4,4, loop ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 390 | 391 | bool trackAdded = 0; 392 | for(uint8_t i = 0; i < 4;i++) 393 | { 394 | if(tracks[i] == mp3) 395 | { 396 | trackAdded = 1; 397 | break; 398 | } 399 | } 400 | if(!trackAdded && mp.SDinsertedFlag) 401 | { 402 | addTrack(mp3); 403 | Serial.println("Track added"); 404 | } 405 | else if(!mp.SDinsertedFlag) 406 | return 0; 407 | if (mp.buttons.released(BTN_B)) 408 | { 409 | mp.buttons.update(); 410 | mp3->stop(); 411 | Serial.println(F("Stopped")); 412 | delay(5); 413 | return index; 414 | } 415 | if(mp.buttons.released(BTN_HOME)) { 416 | mp3->stop(); 417 | mp.exitedLockscreen = true; 418 | mp.lockscreen(); 419 | } 420 | 421 | if (mp.buttons.released(BTN_A)) //PLAY/PAUSE BUTTON 422 | { 423 | mp.buttons.update(); 424 | if(playState) 425 | { 426 | mp3->pause(); 427 | //mp.osc->setVolume(mp.oscillatorVolumeList[mp.mediaVolume]); // Robert v1 -- turns on menu sounds when song stops playing 428 | mp.display.fillScreen(backgroundColors[mp.backgroundIndex]); 429 | 430 | //draw bitmaps 431 | mp.display.drawBitmap(2*scale, 20*scale, previous, TFT_BLACK, scale); 432 | mp.display.drawBitmap(65*scale, 20*scale, next, TFT_BLACK, scale); 433 | mp.display.drawBitmap(2*scale, 75, repeatSprite, TFT_BLACK, scale); 434 | mp.display.drawBitmap(66*scale, 37*scale, shuffleIcon, TFT_BLACK, scale); 435 | mp.display.drawBitmap(72, 40, pause2, TFT_BLACK, scale); 436 | mp.display.drawBitmap(17*scale, 2*scale, cover2, TFT_BLACK, scale); 437 | 438 | //prepare for text printing 439 | mp.display.setTextColor(TFT_BLACK); 440 | mp.display.setTextSize(1); 441 | mp.display.setTextWrap(0); 442 | 443 | //drawtext 444 | mp.display.setCursor(1, 111); 445 | if(audioFiles[index].length() > 20) 446 | mp.display.print(audioFiles[index]); 447 | else 448 | mp.display.printCenter(audioFiles[index]); 449 | mp.display.drawBitmap(4,2, fullSound, TFT_BLACK, 2); 450 | mp.display.setCursor(24, 2); 451 | mp.display.print(mp.mediaVolume); 452 | mp.display.fillRect(141,74, 4,4, shuffle ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 453 | mp.display.fillRect(14,73, 4,4, loop ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 454 | 455 | } 456 | else 457 | { 458 | shuffleReset = 0; 459 | mp.display.fillScreen(backgroundColors[mp.backgroundIndex]); 460 | 461 | //draw bitmaps 462 | mp.display.drawBitmap(2*scale, 20*scale, previous, TFT_BLACK, scale); 463 | mp.display.drawBitmap(65*scale, 20*scale, next, TFT_BLACK, scale); 464 | mp.display.drawBitmap(2*scale, 75, repeatSprite, TFT_BLACK, scale); 465 | mp.display.drawBitmap(66*scale, 37*scale, shuffleIcon, TFT_BLACK, scale); 466 | mp.display.drawBitmap(37*scale, 19*scale, play, TFT_BLACK, scale); 467 | mp.display.drawBitmap(17*scale, 2*scale, cover2, TFT_BLACK, scale); 468 | 469 | 470 | 471 | //prepare for text printing 472 | mp.display.setTextColor(TFT_BLACK); 473 | mp.display.setTextSize(1); 474 | mp.display.setTextWrap(0); 475 | 476 | //drawtext 477 | mp.display.setCursor(1, 111); 478 | if(audioFiles[index].length() > 20) 479 | mp.display.print(audioFiles[index]); 480 | else 481 | mp.display.printCenter(audioFiles[index]); 482 | mp.display.drawBitmap(4,2, fullSound, TFT_BLACK, 2); 483 | mp.display.setCursor(24, 2); 484 | mp.display.print(mp.mediaVolume); 485 | mp.display.fillRect(141,74, 4,4, shuffle ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 486 | mp.display.fillRect(14,73, 4,4, loop ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 487 | mp3->resume(); 488 | } 489 | playState = !playState; 490 | } 491 | /* 492 | if (mp.buttons.released(BTN_DOWN) && mp.mediaVolume > 0) //DOWN 493 | { 494 | mp.buttons.update(); 495 | mp.mediaVolume--; 496 | if(mp.mediaVolume == 0) 497 | mp3->setVolume(0); 498 | else 499 | mp3->setVolume(mp.mediaVolume*21); 500 | 501 | // mp3->setVolume(256/14*mp.mediaVolume); 502 | mp.osc->setVolume(mp.oscillatorVolumeList[mp.mediaVolume]); 503 | //prepare for text printing 504 | mp.display.setTextColor(TFT_BLACK); 505 | mp.display.setTextFont(2); 506 | mp.display.setTextSize(1); 507 | mp.display.setTextWrap(0); 508 | mp.display.fillRect(4,2, 15, 15, backgroundColors[mp.backgroundIndex]); 509 | //drawtext 510 | mp.display.drawBitmap(4,2, fullSound, TFT_BLACK, 2); 511 | mp.display.setCursor(24, 2); 512 | mp.display.print(mp.mediaVolume); 513 | } 514 | */ 515 | if (mp.buttons.repeat(BTN_DOWN,13) && mp.mediaVolume > 0) //DOWN 516 | { 517 | mp.buttons.update(); 518 | mp.mediaVolume--; 519 | if(mp.mediaVolume == 0) 520 | mp3->setVolume(0); 521 | else 522 | mp3->setVolume(mp.mediaVolume*40); 523 | 524 | // mp3->setVolume(256/14*mp.mediaVolume); 525 | mp.osc->setVolume(mp.oscillatorVolumeList[mp.mediaVolume]); 526 | //prepare for text printing 527 | mp.display.setTextColor(TFT_BLACK); 528 | mp.display.setTextFont(2); 529 | mp.display.setTextSize(1); 530 | mp.display.setTextWrap(0); 531 | mp.display.fillRect(4,2, 15, 15, backgroundColors[mp.backgroundIndex]); 532 | //drawtext 533 | mp.display.drawBitmap(4,2, fullSound, TFT_BLACK, 2); 534 | mp.display.setCursor(24, 2); 535 | mp.display.print(mp.mediaVolume); 536 | } 537 | /* 538 | if (mp.buttons.released(BTN_UP) && mp.mediaVolume < 14) //UP 539 | { 540 | mp.buttons.update(); 541 | mp.mediaVolume++; 542 | if(mp.mediaVolume == 0) 543 | mp3->setVolume(0); 544 | else 545 | mp3->setVolume(mp.mediaVolume*21); 546 | // mp3->setVolume(256/14*mp.mediaVolume); 547 | mp.osc->setVolume(mp.oscillatorVolumeList[mp.mediaVolume]); 548 | //prepare for text printing 549 | mp.display.setTextColor(TFT_BLACK); 550 | mp.display.setTextFont(2); 551 | mp.display.setTextSize(1); 552 | mp.display.setTextWrap(0); 553 | mp.display.fillRect(4,2, 15, 15, backgroundColors[mp.backgroundIndex]); 554 | //drawtext 555 | mp.display.drawBitmap(4,2, fullSound, TFT_BLACK, 2); 556 | mp.display.setCursor(24, 2); 557 | mp.display.print(mp.mediaVolume); 558 | } 559 | */ 560 | if (mp.buttons.repeat(BTN_UP,13) && mp.mediaVolume < 14) //UP 561 | { 562 | mp.buttons.update(); 563 | mp.mediaVolume++; 564 | if(mp.mediaVolume == 0) 565 | mp3->setVolume(0); 566 | else 567 | mp3->setVolume(mp.mediaVolume*40); 568 | // mp3->setVolume(256/14*mp.mediaVolume); 569 | mp.osc->setVolume(mp.oscillatorVolumeList[mp.mediaVolume]); 570 | //prepare for text printing 571 | mp.display.setTextColor(TFT_BLACK); 572 | mp.display.setTextFont(2); 573 | mp.display.setTextSize(1); 574 | mp.display.setTextWrap(0); 575 | mp.display.fillRect(4,2, 15, 15, backgroundColors[mp.backgroundIndex]); 576 | //drawtext 577 | mp.display.drawBitmap(4,2, fullSound, TFT_BLACK, 2); 578 | mp.display.setCursor(24, 2); 579 | mp.display.print(mp.mediaVolume); 580 | } 581 | if(mp.buttons.released(BTN_LEFT)) //previous 582 | { 583 | Serial.println("previous"); 584 | mp.buttons.update(); 585 | playState = 1; 586 | if(shuffle && !shuffleReset) 587 | { 588 | bool allTrue=1; 589 | for(int i = 0; i < audioCount;i++) 590 | if(!shuffleList[i]) 591 | allTrue = 0; 592 | if(allTrue) 593 | { 594 | memset(shuffleList, 0, sizeof(shuffleList)); 595 | if(!loop) 596 | { 597 | playState = 0; // Robert -- added 1 598 | shuffleReset = 1; // Robert -- added 0 599 | } 600 | } 601 | uint16_t randNumber = random(0,audioCount); 602 | 603 | while(shuffleList[randNumber]) 604 | randNumber = random(0,audioCount); 605 | index = randNumber; 606 | shuffleList[randNumber] = 1; 607 | } 608 | else 609 | { 610 | if(!loop && !shuffleReset) 611 | { 612 | if(index > 0) 613 | index--; 614 | else 615 | { 616 | playState = 1; 617 | index = audioCount-1; 618 | } 619 | } 620 | } 621 | if(shuffleReset) 622 | playState = 1; 623 | mp3->stop(); 624 | break; 625 | } 626 | if(mp.buttons.released(BTN_RIGHT)) //next 627 | { 628 | Serial.println("next"); 629 | mp.buttons.update(); 630 | playState = 1; 631 | if(shuffle && !shuffleReset) 632 | { 633 | bool allTrue=1; 634 | for(int i = 0; i < audioCount;i++) 635 | if(!shuffleList[i]) 636 | allTrue = 0; 637 | if(allTrue) 638 | { 639 | memset(shuffleList, 0, sizeof(shuffleList)); 640 | if(!loop) 641 | { 642 | playState = 1; 643 | shuffleReset = 0; 644 | } 645 | } 646 | uint16_t randNumber = random(0,audioCount); 647 | 648 | while(shuffleList[randNumber] == 1 || index == randNumber) 649 | randNumber = random(0,audioCount); 650 | index = randNumber; 651 | shuffleList[randNumber] = 1; 652 | } 653 | else if(!shuffle && !shuffleReset) 654 | { 655 | if(!loop && !shuffleReset) 656 | { 657 | if(index < audioCount - 1) 658 | index++; 659 | else 660 | { 661 | shuffleReset = 0; 662 | index = 0; 663 | playState = 1; 664 | } 665 | } 666 | // index = (index < audioCount - 1) ? index++ : 0; 667 | } 668 | if(shuffleReset) 669 | playState = 1; 670 | mp3->stop(); 671 | break; 672 | } 673 | if(mp.buttons.released(BTN_FUN_RIGHT)) //shuffle button 674 | { 675 | mp.buttons.update(); 676 | if(!shuffle) 677 | memset(shuffleList, 0, sizeof(shuffleList)); 678 | shuffle = !shuffle; 679 | mp.display.fillRect(141,74, 4,4, shuffle ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 680 | mp.display.fillRect(141,74, 4,4, shuffle ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 681 | shuffleList[index] = 1; 682 | 683 | } 684 | if(mp.buttons.released(BTN_FUN_LEFT)) //loop button 685 | { 686 | mp.buttons.update(); 687 | loop = !loop; 688 | mp.display.fillRect(14,73, 4,4, loop ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 689 | mp.display.fillRect(14,73, 4,4, loop ? TFT_BLACK : backgroundColors[mp.backgroundIndex]); 690 | } 691 | // if(mp.buttons.getJoystickX() == 1104) 692 | // Serial.print("joystick X break "); 693 | // if(mp.buttons.getJoystickY() == 1104) 694 | // Serial.print("joystick Y break "); 695 | Serial.print("joystick X: "); 696 | Serial.println(mp.buttons.getJoystickX()); 697 | Serial.print("joystick Y: "); 698 | Serial.println(mp.buttons.getJoystickY()); 699 | Serial.println("------------------"); 700 | mp.update(); 701 | if(mp3->isPlaying() < 1 && playState) //if the current song is finished, play the next one 702 | { 703 | Serial.println("song end"); 704 | if(shuffle && !shuffleReset) 705 | { 706 | allTrue=1; 707 | for(int i = 0; i < audioCount;i++) 708 | if(!shuffleList[i]) 709 | allTrue = 0; 710 | if(allTrue) 711 | { 712 | memset(shuffleList, 0, sizeof(shuffleList)); 713 | if(!loop) 714 | { 715 | playState = 1; 716 | shuffleReset = 0; 717 | } 718 | } 719 | uint16_t randNumber = random(0,audioCount); 720 | 721 | while(shuffleList[randNumber] || index == randNumber) 722 | randNumber = random(0,audioCount); 723 | index = randNumber; 724 | shuffleList[randNumber] = 1; 725 | } 726 | else if(!shuffle && !shuffleReset) 727 | { 728 | if(!loop) 729 | { 730 | if(index < audioCount - 1) 731 | index++; 732 | else 733 | { 734 | index = 0; 735 | playState = 1; 736 | } 737 | } 738 | } 739 | break; 740 | } 741 | } 742 | } 743 | } 744 | void listPhotos(const char * dirname, uint8_t levels) { 745 | photoCount = 0; 746 | 747 | Serial.printf("Listing directory: %s\n", dirname); 748 | File root = SD.open(dirname); 749 | if (!root) { 750 | Serial.println(F("Failed to open directory")); 751 | return; 752 | } 753 | if (!root.isDirectory()) { 754 | Serial.println(F("Not a directory")); 755 | return; 756 | } 757 | int counter = 1; 758 | File file = root.openNextFile(); 759 | while (file) { 760 | // char temp[100]; 761 | // file.getName(temp, 100); 762 | String Name(file.name()); 763 | Serial.println(Name); 764 | if (Name.endsWith(F(".jpeg")) || Name.endsWith(F(".JPEG")) 765 | || Name.endsWith(F(".jpg")) || Name.endsWith(F(".JPG")) 766 | || Name.endsWith(F(".bmp")) || Name.endsWith(F(".BMP"))) 767 | { 768 | Serial.print(counter); 769 | Serial.print(F(". ")); 770 | Serial.println(Name); 771 | photoFiles[counter - 1] = Name; 772 | Serial.println(Name); 773 | photoCount++; 774 | counter++; 775 | } 776 | file = root.openNextFile(); 777 | } 778 | } 779 | -------------------------------------------------------------------------------- /src/contactsApp.cpp: -------------------------------------------------------------------------------- 1 | #include "contactsApp.h" 2 | //Contacts app 3 | uint8_t contactsMenuCursor = 0; 4 | uint8_t searchId = 0; 5 | bool helpPop; 6 | 7 | void contactsMenuDrawCursor(uint8_t i, int32_t y, bool smsflag) 8 | { 9 | uint8_t offset = smsflag ? 19 : 29; 10 | uint8_t boxHeight = 28; 11 | y += i * boxHeight + offset; 12 | mp.display.drawRect(0, y, mp.display.width(), boxHeight + 1, TFT_RED); 13 | } 14 | void contactsMenuNewBoxCursor(uint8_t i, int32_t y) 15 | { 16 | uint8_t offset = 14; 17 | uint8_t boxHeight = 22; 18 | y += offset + 1; 19 | mp.display.drawRect(0, y, mp.display.width(), boxHeight, TFT_RED); 20 | } 21 | void contactsMenuSearchBoxCursor(uint8_t i, int32_t y) 22 | { 23 | uint8_t offset = 35; 24 | uint8_t boxHeight = 22; 25 | y += offset + 1; 26 | mp.display.drawRect(0, y, mp.display.width(), boxHeight, TFT_RED); 27 | } 28 | void contactsMenuNewBox(uint8_t i, int32_t y) 29 | { 30 | uint8_t offset = 14; 31 | uint8_t boxHeight = 22; 32 | y += offset + 1; 33 | if (y < -22 || y > mp.display.height()) 34 | { 35 | return; 36 | } 37 | mp.display.setFreeFont(TT1); 38 | mp.display.setTextSize(1); 39 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight - 2, TFT_DARKGREY); 40 | mp.display.drawBitmap(2, y + 1, newContactIcon, TFT_WHITE, 2); 41 | mp.display.setTextColor(TFT_WHITE); 42 | mp.display.setCursor(32, y + 2); 43 | mp.display.setTextFont(2); 44 | mp.display.print("New contact"); 45 | 46 | } 47 | void contactsMenuSearchBox(uint8_t i, int32_t y, String typed, String suggested, bool blinkState) 48 | { 49 | uint8_t offset = 35; 50 | uint8_t boxHeight = 22; 51 | 52 | y += offset + 1; 53 | if (y < -22 || y > mp.display.height()) 54 | { 55 | return; 56 | } 57 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight - 2, TFT_DARKGREY); 58 | mp.display.drawBitmap(0, y + 2, contactSearchIcon, TFT_WHITE, 2); 59 | 60 | if(typed.length() >= 1) 61 | { 62 | mp.display.setTextColor(TFT_WHITE); 63 | mp.display.setCursor(32, y + 2); 64 | mp.display.setTextFont(2); 65 | mp.display.print(typed); 66 | mp.display.setTextColor(TFT_CYAN); 67 | //mp.display.setCursor(typed.length() * 10 + 1, y + 1); 68 | mp.display.setCursor(mp.display.getCursorX(), y + 2); 69 | if(suggested.length() > 1) 70 | suggested.remove(0, typed.length()); 71 | else 72 | suggested = ""; 73 | 74 | mp.display.print(suggested); 75 | 76 | } 77 | else 78 | { 79 | // mp.textInput(""); 80 | mp.display.setCursor(32, y + 2); 81 | mp.display.setTextColor(TFT_LIGHTGREY); 82 | mp.display.print("Search"); 83 | mp.display.setCursor(32, y + 2); 84 | } 85 | if(blinkState == 1) 86 | mp.display.drawFastVLine(mp.display.getCursorX(), mp.display.getCursorY()+3, 10, TFT_WHITE); 87 | } 88 | uint8_t deleteContactSD(String name, String number) 89 | { 90 | while (1) 91 | { 92 | mp.display.fillScreen(TFT_BLACK); 93 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 94 | mp.display.setTextFont(2); 95 | mp.display.setCursor(0,-2); 96 | mp.display.drawFastHLine(0, 14, BUF2WIDTH, TFT_WHITE); 97 | mp.display.setTextColor(TFT_WHITE); 98 | mp.display.print("Delete contact"); 99 | mp.display.setTextColor(TFT_WHITE); 100 | mp.display.setCursor(4, 17); 101 | mp.display.print("Are you sure?"); 102 | mp.display.setCursor(4, 33); 103 | mp.display.print(name); 104 | mp.display.setCursor(4, 49); 105 | mp.display.print(number); 106 | mp.display.drawFastHLine(0, 112, BUF2WIDTH, TFT_WHITE); 107 | mp.display.fillRect(0, 113, mp.display.width(), 30, TFT_DARKGREY); 108 | mp.display.setCursor(110, 113); 109 | mp.display.print("Confirm"); 110 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 111 | { 112 | Serial.println("Go back"); 113 | mp.textInput(""); 114 | while(!mp.update()); 115 | break; 116 | } 117 | if (mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) // DELETE 118 | { 119 | while(!mp.update()); 120 | return 1; 121 | } 122 | mp.update(); 123 | } 124 | return 0; 125 | } 126 | 127 | void contactsApp(bool smsFlag) 128 | { 129 | Serial.println(""); 130 | Serial.println("Begin contacts"); 131 | File file = SD.open("/.core/contacts.json", "r"); 132 | 133 | if(file.size() < 2) 134 | { // empty -> FILL 135 | Serial.println("Override"); 136 | file.close(); 137 | jb.clear(); 138 | JsonArray& jarr = jb.createArray(); 139 | delay(10); 140 | File file1 = SD.open("/.core/contacts.json", "w"); 141 | jarr.prettyPrintTo(file1); 142 | file1.close(); 143 | file = SD.open("/.core/contacts.json", "r"); 144 | if(!file) 145 | Serial.println("CONTACTS ERROR"); 146 | } 147 | 148 | jb.clear(); 149 | JsonArray& jarr = jb.parseArray(file); 150 | file.close(); 151 | 152 | if(!jarr.success()) 153 | { 154 | Serial.println("Error"); 155 | mp.display.fillScreen(TFT_BLACK); 156 | mp.display.setCursor(0, mp.display.height()/2 - 16); 157 | mp.display.setTextFont(2); 158 | mp.display.printCenter("Error loading contacts"); 159 | while (mp.buttons.released(BTN_B) == 0)//BUTTON BACK 160 | mp.update(); 161 | while(!mp.update()); 162 | } 163 | else 164 | { 165 | /* 166 | Serial.println("Read from .json"); 167 | for (JsonObject& elem : jarr) 168 | { 169 | 170 | Serial.println(elem["name"].as()); 171 | Serial.println(elem["number"].as()); 172 | } 173 | */ 174 | while(1) 175 | { 176 | int menuChoice = -1; 177 | menuChoice = contactsMenu(&jarr, false); 178 | mp.update(); 179 | 180 | if (menuChoice != -2) 181 | { 182 | if (menuChoice == 0) //creating new contact 183 | { 184 | String name; 185 | String number = "+"; 186 | if(newContact(&name, &number)) 187 | { 188 | JsonObject& newContact = jb.createObject(); 189 | newContact["name"] = name; 190 | newContact["number"] = number; 191 | jarr.add(newContact); 192 | File file = SD.open("/.core/contacts.json", "w"); 193 | jarr.prettyPrintTo(file); 194 | jarr.prettyPrintTo(Serial); 195 | file.close(); 196 | } 197 | } 198 | else if(menuChoice < -2000 && menuChoice != -3000) // view contact 199 | { 200 | int id = 0; 201 | if(menuChoice < -3000) 202 | id = menuChoice + 4000 - 1; 203 | else 204 | id = menuChoice + 3000 - 1; 205 | int8_t info = viewContact(jarr[id]); 206 | if(info == -1) 207 | { 208 | String name, number; 209 | name = jarr[id]["name"].as(); 210 | number = jarr[id]["number"].as(); 211 | 212 | if(newContact(&name, &number)){ 213 | JsonObject& newContact = jb.createObject(); 214 | newContact["name"] = name; 215 | newContact["number"] = number; 216 | jarr[id] = newContact; 217 | File file = SD.open("/.core/contacts.json", "w"); 218 | jarr.prettyPrintTo(file); 219 | jarr.prettyPrintTo(Serial); 220 | file.close(); 221 | } 222 | } 223 | else if(info == 1) //call number 224 | { 225 | if(mp.sim_module_version == 255) 226 | { 227 | mp.display.fillScreen(TFT_BLACK); 228 | mp.display.setTextColor(TFT_WHITE); 229 | mp.display.setTextSize(1); 230 | mp.display.setCursor(0, mp.display.height()/2 - 20); 231 | mp.display.setTextFont(2); 232 | mp.display.printCenter(F("No network board!")); 233 | mp.display.setCursor(0, mp.display.height()/2); 234 | mp.display.printCenter(F("Insert board and reset")); 235 | uint32_t tempMillis = millis(); 236 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 237 | mp.update(); 238 | while(!mp.update()); 239 | } 240 | else if(mp.airplaneMode) 241 | { 242 | mp.display.fillScreen(TFT_BLACK); 243 | mp.display.setCursor(0, mp.display.height()/2 - 20); 244 | mp.display.setTextFont(2); 245 | mp.display.printCenter(F("Can't make calls!")); 246 | mp.display.setCursor(0, mp.display.height()/2); 247 | mp.display.printCenter(F("Turn off airplane mode")); 248 | uint32_t tempMillis = millis(); 249 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 250 | mp.update(); 251 | while(!mp.update()); 252 | } 253 | else if(!mp.simInserted) 254 | { 255 | mp.display.setTextColor(TFT_BLACK); 256 | mp.display.setTextSize(1); 257 | mp.display.setTextFont(2); 258 | mp.display.drawRect(14, 45, 134, 38, TFT_BLACK); 259 | mp.display.drawRect(13, 44, 136, 40, TFT_BLACK); 260 | mp.display.fillRect(15, 46, 132, 36, TFT_WHITE); 261 | mp.display.setCursor(47, 55); 262 | mp.display.printCenter(F("SIM card missing!")); 263 | uint32_t tempMillis = millis(); 264 | while(millis() < tempMillis + 2000) 265 | { 266 | mp.update(); 267 | if(mp.buttons.pressed(BTN_A) || mp.buttons.pressed(BTN_B)) 268 | { 269 | while(!mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 270 | mp.update(); 271 | break; 272 | } 273 | } 274 | while(!mp.update()); 275 | } 276 | else 277 | { 278 | callNumber(jarr[id]["number"].as()); 279 | } 280 | 281 | } 282 | } 283 | else if (menuChoice < -10 && !smsFlag && menuChoice != -1000 && menuChoice != -3000) //deleting contact 284 | { 285 | int id = menuChoice + 1000 - 1; 286 | if(deleteContactSD(jarr[id]["name"], jarr[id]["number"])) 287 | { 288 | jarr.remove(id); 289 | File file = SD.open("/.core/contacts.json", "w"); 290 | jarr.prettyPrintTo(file); 291 | file.close(); 292 | contactsMenuCursor = 0; 293 | } 294 | } 295 | else 296 | { 297 | 298 | while(!mp.update()); 299 | } 300 | } 301 | else 302 | { 303 | contactsMenuCursor = 0; 304 | break; 305 | } 306 | } 307 | } 308 | } 309 | 310 | 311 | uint8_t newContact(String *name, String *number) 312 | { 313 | String content = *name; 314 | String contact = *number; 315 | String prevContent = ""; 316 | mp.textPointer = name->length(); 317 | char key = NO_KEY; 318 | bool cursor = 0; //editing contacts or text content 319 | unsigned long elapsedMillis = millis(); 320 | bool blinkState = 1; 321 | // bool plusSign = 0; 322 | while (1) 323 | { 324 | 325 | mp.display.fillScreen(TFT_BLACK); 326 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 327 | mp.display.setTextFont(2); 328 | mp.display.setCursor(0,-2); 329 | mp.display.drawFastHLine(0, 14, BUF2WIDTH, TFT_WHITE); 330 | mp.display.setTextColor(TFT_WHITE); 331 | mp.display.print("Contacts"); 332 | mp.display.fillRect(0,60,160,50, TFT_DARKGREY); 333 | mp.display.setCursor(4, 60); 334 | mp.display.print("Enter your country code"); 335 | mp.display.setCursor(4, 76); 336 | mp.display.printCenter("(example: +001 for USA)"); 337 | mp.display.setCursor(4, 92); 338 | mp.display.printCenter("Press A to save"); 339 | 340 | 341 | if(mp.buttons.released(BTN_HOME)) { 342 | mp.exitedLockscreen = true; 343 | mp.lockscreen(); 344 | } 345 | if (millis() - elapsedMillis >= multi_tap_threshold) //cursor blinking routine 346 | { 347 | elapsedMillis = millis(); 348 | blinkState = !blinkState; 349 | } 350 | if (cursor == 0) //inputting the contact number 351 | { 352 | key = mp.buttons.getKey(); 353 | if (mp.buttons.released(BTN_FUN_LEFT) && contact.length() > 1) 354 | contact.remove(contact.length() - 1); 355 | if (key != NO_KEY && isdigit(key) && contact.length() < 14) 356 | contact += key; 357 | mp.display.setTextWrap(1); 358 | mp.display.setCursor(4, 20); 359 | mp.display.setTextFont(2); 360 | if (content == "") 361 | { 362 | mp.display.setTextColor(TFT_LIGHTGREY); 363 | mp.display.print(F("Name")); 364 | mp.display.setTextColor(TFT_WHITE); 365 | } 366 | else 367 | mp.display.print(content); 368 | mp.display.setTextFont(2); 369 | mp.display.setCursor(4, 38); 370 | mp.display.print("Num: "); 371 | mp.display.print(contact); 372 | if (blinkState == 1) 373 | mp.display.drawFastVLine(mp.display.getCursorX() + 1, mp.display.getCursorY() + 3, 11, TFT_WHITE); 374 | } 375 | else //inputting contact name 376 | { 377 | mp.display.setTextColor(TFT_WHITE); 378 | mp.display.setCursor(4, 38); 379 | mp.display.print("Num: "); 380 | if (contact == "+") 381 | { 382 | mp.display.setTextColor(TFT_LIGHTGREY); 383 | mp.display.print(F("+XXXXXXXXXXXX")); 384 | mp.display.setTextColor(TFT_WHITE); 385 | } 386 | else 387 | mp.display.print(contact); 388 | prevContent = content; 389 | content = mp.textInput(content, 18); 390 | if (prevContent != content) 391 | { 392 | blinkState = 1; 393 | elapsedMillis = millis(); 394 | } 395 | mp.display.setTextColor(TFT_LIGHTGREY); 396 | mp.display.setTextWrap(1); 397 | mp.display.setCursor(2*2, 10*2); 398 | mp.display.print(content); 399 | mp.display.setTextColor(TFT_WHITE); 400 | if(blinkState == 1) 401 | mp.display.drawFastVLine(mp.display.getCursorX() + 1, mp.display.getCursorY() + 3, 11, TFT_WHITE); 402 | } 403 | mp.display.setTextColor(TFT_WHITE); 404 | mp.display.setCursor(130, 110); 405 | mp.display.print("Help"); 406 | mp.display.setTextColor(TFT_WHITE); 407 | mp.display.setCursor(4, 110); 408 | mp.display.print("Erase"); 409 | 410 | if (mp.buttons.released(BTN_DOWN) && cursor == 1) { //BUTTON UP 411 | while(!mp.update()); 412 | cursor = 0; 413 | } 414 | 415 | if (mp.buttons.released(BTN_UP) && cursor == 0) { //BUTTON DOWN 416 | while(!mp.update()); 417 | cursor = 1; 418 | } 419 | if(mp.buttons.released(BTN_FUN_RIGHT)){ 420 | helpPop = !helpPop; 421 | mp.display.drawIcon(TextHelperPopup, 0, 0, 160, 128, 1, TFT_WHITE); 422 | while(!mp.update()); 423 | } 424 | while (helpPop) 425 | { 426 | if(mp.buttons.released(BTN_FUN_RIGHT) || mp.buttons.released(BTN_B)) 427 | { 428 | helpPop = !helpPop; 429 | } 430 | mp.update(); 431 | } 432 | if (mp.buttons.released(BTN_B)) { //BUTTON BACK 433 | mp.buttons.update(); 434 | while(1) 435 | { 436 | mp.display.fillScreen(TFT_DARKGREY); 437 | mp.display.setTextColor(TFT_WHITE); 438 | mp.display.setTextSize(1); 439 | mp.display.setTextFont(2); 440 | mp.display.drawRect(10, 45, 142, 38, TFT_BLACK); 441 | mp.display.drawRect(9, 44, 144, 40, TFT_BLACK); 442 | mp.display.setCursor(47, 48); 443 | mp.display.printCenter("Exit without saving?"); 444 | mp.display.setCursor(47, 61); 445 | mp.display.printCenter("A: Yes B: No"); 446 | if(mp.buttons.released(BTN_B)) 447 | { 448 | mp.buttons.update(); 449 | break; 450 | } 451 | if(mp.buttons.released(BTN_A)) 452 | { 453 | mp.buttons.update(); 454 | return 0; 455 | } 456 | mp.update(); 457 | } 458 | } 459 | if (mp.buttons.released(BTN_A)) // SAVE CONTACT 460 | { 461 | while(!mp.update()); 462 | if(contact != "+" && content != "") 463 | { 464 | *name = content; 465 | *number = contact; 466 | return 1; 467 | } 468 | } 469 | mp.update(); 470 | } 471 | return 0; 472 | } 473 | 474 | int contactsMenu(JsonArray *contacts, bool smsFlag) 475 | { 476 | mp.textInput(""); 477 | mp.textPointer = 0; 478 | int32_t cameraY = 0; 479 | int32_t cameraY_actual = 0; 480 | uint8_t length = contacts->size(); 481 | uint8_t offset = 19; 482 | uint8_t boxHeight = 28; 483 | bool blinkState = 0; 484 | String number = ""; 485 | String searchBuf = "", tmpSearchBuf = ""; 486 | uint32_t blinkMillis = millis(); 487 | bool cursorState = 0; 488 | uint32_t cursorMillis = millis(); 489 | if (length > 2 && contactsMenuCursor > 2) 490 | { 491 | cameraY = -(contactsMenuCursor - 1) * (boxHeight + 1) + offset + 11 ; 492 | } 493 | if(!smsFlag) 494 | { 495 | length += 1; 496 | } 497 | 498 | while (1) 499 | { 500 | mp.display.fillScreen(TFT_BLACK); 501 | mp.display.setCursor(0, 0); 502 | cameraY_actual = (cameraY_actual + cameraY) / 2; 503 | if (cameraY_actual - cameraY == 1) 504 | { 505 | cameraY_actual = cameraY; 506 | } 507 | if(millis() - blinkMillis > 350) 508 | { 509 | blinkMillis = millis(); 510 | blinkState = !blinkState; 511 | } 512 | int i = 0; 513 | if(!smsFlag) 514 | { 515 | contactsMenuNewBox(0, cameraY_actual); 516 | contactsMenuSearchBox(0, cameraY_actual, searchBuf, searchContacts(searchBuf), cursorState); 517 | } 518 | else 519 | { 520 | i = -1; 521 | } 522 | for (JsonObject& elem : *contacts) 523 | { 524 | contactsMenuDrawBox(elem["name"].as(), elem["number"].as(), i+1, cameraY_actual, smsFlag); 525 | i++; 526 | } 527 | if(blinkState) 528 | { 529 | if(contactsMenuCursor == 0 && smsFlag == 0) 530 | contactsMenuNewBoxCursor(contactsMenuCursor, cameraY_actual); 531 | else if(contactsMenuCursor == 1 && smsFlag == 0) 532 | contactsMenuSearchBoxCursor(contactsMenuCursor, cameraY_actual); 533 | else if(smsFlag == 0) 534 | contactsMenuDrawCursor(contactsMenuCursor - 1, cameraY_actual, smsFlag); 535 | else 536 | contactsMenuDrawCursor(contactsMenuCursor, cameraY_actual, smsFlag); 537 | 538 | } 539 | //--------------------------------SEARCH INPUT START---------------------------------------- 540 | if(contactsMenuCursor == 1 && !smsFlag) 541 | { 542 | if(millis() - cursorMillis > multi_tap_threshold) 543 | { 544 | cursorState = !cursorState; 545 | cursorMillis = millis(); 546 | } 547 | tmpSearchBuf = searchBuf; 548 | searchBuf = mp.textInput(searchBuf, 14); 549 | if(searchBuf != tmpSearchBuf) 550 | { 551 | cursorMillis = millis(); 552 | cursorState = 1; 553 | } 554 | } 555 | else 556 | { 557 | mp.textInput(""); 558 | mp.textPointer = 0; 559 | searchBuf = ""; 560 | tmpSearchBuf = ""; 561 | cursorMillis = millis(); 562 | cursorState = 0; 563 | } 564 | //--------------------------------SEARCH INPUT END------------------------------------------ 565 | mp.display.fillRect(0, 0, mp.display.width(), 13, TFT_DARKGREY); 566 | mp.display.setTextFont(2); 567 | mp.display.setCursor(0,-2); 568 | mp.display.drawFastHLine(0, 13, BUF2WIDTH, TFT_WHITE); 569 | mp.display.setTextSize(1); 570 | mp.display.setTextColor(TFT_WHITE); 571 | mp.display.print("Contacts"); 572 | mp.display.fillRect(0, smsFlag ? 104 : 112, 160, 28, TFT_BLACK); 573 | mp.display.drawFastHLine(0, 112, BUF2WIDTH, TFT_WHITE); 574 | mp.display.fillRect(0, 113, mp.display.width(), 30, TFT_DARKGREY); 575 | mp.display.setCursor(115, 113); 576 | if(smsFlag) 577 | { 578 | mp.display.print("Select"); 579 | } 580 | else 581 | { 582 | mp.display.printCenter("Delete View"); 583 | } 584 | 585 | if(mp.buttons.released(BTN_HOME)) 586 | { 587 | mp.exitedLockscreen = true; 588 | mp.lockscreen(); 589 | } 590 | if (mp.buttons.released(BTN_A) && contactsMenuCursor == 0 && !smsFlag) 591 | { //BUTTON CONFIRM 592 | Serial.println("pressed1"); 593 | mp.buttons.update(); 594 | break; 595 | } 596 | if((mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) && contactsMenuCursor == 1 && !smsFlag ) 597 | { 598 | Serial.println("pressed2"); 599 | mp.buttons.update(); 600 | if(searchContacts(searchBuf).length() > 0) 601 | { 602 | searchBuf= ""; 603 | mp.textInput(""); 604 | mp.textPointer = 0; 605 | return -3000 + 1 + searchId; 606 | } 607 | 608 | } 609 | if (mp.buttons.released(BTN_FUN_LEFT) && contactsMenuCursor != 0 && !smsFlag && contactsMenuCursor != 1) 610 | { 611 | mp.buttons.update(); 612 | return -1000 + contactsMenuCursor - 1; 613 | } 614 | else if(mp.buttons.released(BTN_FUN_LEFT) && contactsMenuCursor == 1) 615 | { 616 | if(tmpSearchBuf.length() >= 1) 617 | { 618 | if(tmpSearchBuf.length() <= 1) 619 | tmpSearchBuf = ""; 620 | else 621 | tmpSearchBuf.remove(tmpSearchBuf.length() - 1); 622 | 623 | } 624 | 625 | } 626 | //Check if we're picking a number for sending a message (smsFlag == true) 627 | //if so, return the number of the picked contact 628 | else if((mp.buttons.released(BTN_FUN_RIGHT) || mp.buttons.released(BTN_A)) && smsFlag) 629 | { 630 | Serial.println("pressed3"); 631 | mp.buttons.update(); 632 | return contactsMenuCursor - 1; 633 | } 634 | if ((mp.buttons.released(BTN_FUN_RIGHT) || mp.buttons.released(BTN_A)) && contactsMenuCursor > 1 && !smsFlag) 635 | { 636 | Serial.println("pressed4"); 637 | mp.buttons.update(); 638 | return -3000 + contactsMenuCursor - 1; 639 | } 640 | 641 | if (mp.buttons.released(BTN_UP)) 642 | { //BUTTON UP 643 | blinkState = 1; 644 | blinkMillis = millis(); 645 | while(!mp.update()); 646 | if(contactsMenuCursor == 1 && !smsFlag) 647 | { 648 | Serial.println("cleared"); 649 | mp.textInput(""); 650 | mp.textPointer = 0; 651 | mp.prevKeyMillis = 0; 652 | searchBuf = ""; 653 | tmpSearchBuf = ""; 654 | } 655 | if (contactsMenuCursor == 0) 656 | { 657 | if(smsFlag) 658 | { 659 | contactsMenuCursor = length - 1; 660 | } 661 | else 662 | { 663 | contactsMenuCursor = length; 664 | } 665 | if (length > 2) 666 | { 667 | cameraY = -(contactsMenuCursor - 2) * (boxHeight); 668 | } 669 | } 670 | else 671 | { 672 | 673 | contactsMenuCursor--; 674 | if (contactsMenuCursor > 0 && (contactsMenuCursor * (boxHeight) + cameraY + offset) < (boxHeight)) 675 | { 676 | cameraY += (boxHeight); 677 | } 678 | } 679 | } 680 | 681 | if (mp.buttons.released(BTN_DOWN)) 682 | { //BUTTON DOWN 683 | blinkState = 1; 684 | blinkMillis = millis(); 685 | while(!mp.update()); 686 | if(contactsMenuCursor == 1 && !smsFlag) 687 | { 688 | Serial.println("cleared"); 689 | mp.textInput(""); 690 | mp.textPointer = 0; 691 | mp.prevKeyMillis = 0; 692 | searchBuf = ""; 693 | tmpSearchBuf = ""; 694 | } 695 | contactsMenuCursor++; 696 | if ((contactsMenuCursor * (boxHeight) + cameraY + offset) > 80) 697 | { 698 | cameraY -= (boxHeight); 699 | } 700 | if(smsFlag) 701 | { 702 | if (contactsMenuCursor >= length) 703 | { 704 | contactsMenuCursor = 0; 705 | cameraY = 0; 706 | } 707 | } 708 | else 709 | { 710 | if (contactsMenuCursor >= length + 1) 711 | { 712 | contactsMenuCursor = 0; 713 | cameraY = 0; 714 | } 715 | } 716 | } 717 | if (mp.buttons.released(BTN_B) == 1) 718 | { 719 | while(!mp.update()); 720 | return -2; 721 | } 722 | 723 | mp.update(); 724 | } 725 | return contactsMenuCursor; 726 | } 727 | 728 | void contactsMenuDrawBox(String name, String number, uint8_t i, int32_t y, bool smsflag) 729 | { 730 | uint8_t offset = smsflag ? 19 : 29; 731 | uint8_t boxHeight = 28; 732 | y += i * boxHeight + offset; 733 | if (y < smsflag ? -28 : 0 || y > mp.display.height()) 734 | { 735 | return; 736 | } 737 | mp.display.setTextSize(1); 738 | mp.display.setTextFont(2); 739 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight-1, TFT_DARKGREY); 740 | mp.display.setTextColor(TFT_WHITE); 741 | mp.display.setCursor(2, y + 2); 742 | mp.display.drawString(name, 4, y); 743 | mp.display.drawString(number, 4, y + 12); 744 | 745 | } 746 | 747 | String readAllContacts() 748 | { 749 | String buffer; 750 | Serial1.print(F("AT+CPBR=1,250\r")); 751 | buffer = readSerial(); 752 | delay(5); 753 | if (buffer.indexOf("CPBR:") != -1 || buffer.indexOf("OK") != -1) 754 | { 755 | return buffer; 756 | } 757 | else return ""; 758 | } 759 | int8_t viewContact(JsonObject &contact) 760 | { 761 | while (1) 762 | { 763 | mp.display.fillScreen(TFT_BLACK); 764 | mp.display.fillRect(0, 0, mp.display.width(), 13, TFT_DARKGREY); 765 | mp.display.setTextFont(2); 766 | mp.display.setCursor(0,-2); 767 | mp.display.drawFastHLine(0, 13, BUF2WIDTH, TFT_WHITE); 768 | mp.display.setTextColor(TFT_WHITE); 769 | mp.display.print("Contacts"); 770 | 771 | // if (millis() - elapsedMillis >= multi_tap_threshold) { 772 | // elapsedMillis = millis(); 773 | // blinkState = !blinkState; 774 | // } 775 | mp.display.setCursor(2, 18); 776 | mp.display.print("Name:"); 777 | mp.display.setCursor(4, 34); 778 | mp.display.print(contact["name"].as()); 779 | mp.display.setCursor(4, 54); 780 | mp.display.print("Number:"); 781 | mp.display.setCursor(2, 70); 782 | mp.display.print(contact["number"].as()); 783 | mp.display.drawFastHLine(0, 112, BUF2WIDTH, TFT_WHITE); 784 | mp.display.fillRect(0, 113, mp.display.width(), 30, TFT_DARKGREY); 785 | mp.display.setCursor(110, 113); 786 | mp.display.printCenter("Edit Call"); 787 | // if (blinkState){ 788 | // mp.display.drawRect(mp.display.width() / 2 - 29, 102, 30*2, 9*2, TFT_RED); 789 | // mp.display.setTextColor(TFT_RED); 790 | // mp.display.setCursor(28*2, 103); 791 | // mp.display.printCenter("DELETE"); 792 | // } 793 | // else { 794 | // mp.display.fillRect(mp.display.width() / 2 - 29, 102, 30*2, 9*2, TFT_RED); 795 | // mp.display.setTextColor(TFT_WHITE); 796 | // mp.display.setCursor(28*2, 103); 797 | // mp.display.print("DELETE"); 798 | // } 799 | 800 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 801 | { 802 | Serial.println("Go back"); 803 | while(!mp.update()); 804 | break; 805 | } 806 | if (mp.buttons.released(BTN_FUN_RIGHT)) // call 807 | { 808 | while(!mp.update()); 809 | // Serial.println("Delete"); 810 | // mp.display.fillScreen(TFT_BLACK); 811 | // mp.display.setTextFont(2); 812 | // mp.display.setCursor(34, mp.display.height()/2 -16); 813 | // mp.display.printCenter("Deleting contact..."); 814 | // mp.update(); 815 | return 1; 816 | } 817 | if(mp.buttons.released(BTN_FUN_LEFT)) //edit 818 | { 819 | while(!mp.update()); 820 | return -1; 821 | } 822 | mp.update(); 823 | } 824 | return 0; 825 | } 826 | 827 | 828 | String searchContacts(String input) 829 | { 830 | String ret = ""; 831 | if(input.length() <= 0) 832 | return ""; 833 | //OPEN FILE START 834 | File file1 = SD.open("/.core/contacts.json", "r"); 835 | if (file1.size() < 2) 836 | { 837 | Serial.println("Override"); 838 | file1.close(); 839 | jb.clear(); 840 | JsonArray &contactsjarr = jb.createArray(); 841 | delay(10); 842 | File file2 = SD.open("/.core/contacts.json", "w"); 843 | contactsjarr.prettyPrintTo(file2); 844 | file2.close(); 845 | file1 = SD.open("/.core/contacts.json", "r"); 846 | if (!file1) 847 | Serial.println("CONTACTS ERROR"); 848 | } 849 | jb.clear(); 850 | JsonArray &contactsjarr = jb.parseArray(file1); 851 | file1.close(); 852 | //OPEN FILE END 853 | if (!contactsjarr.success()) 854 | { 855 | Serial.println("Error"); 856 | } 857 | else 858 | { 859 | input.toLowerCase(); 860 | String nameBuf = "", real = ""; 861 | int16_t i = 0; 862 | for (JsonObject &elem : contactsjarr) 863 | { 864 | nameBuf = elem["name"].as(); 865 | real = nameBuf; 866 | nameBuf.toLowerCase(); 867 | if(nameBuf.startsWith(input)) 868 | { 869 | ret = real; 870 | searchId = i; 871 | break; 872 | } 873 | i++; 874 | } 875 | } 876 | 877 | return ret; 878 | } -------------------------------------------------------------------------------- /src/clockApp.cpp: -------------------------------------------------------------------------------- 1 | #include "clockApp.h" 2 | void clockApp() 3 | { 4 | String clockItems[4] = { 5 | "Alarm", 6 | "Clock", 7 | "Stopwatch", 8 | "Timer" 9 | }; 10 | int8_t index = 0; 11 | while(1) 12 | { 13 | index = clockMenu(clockItems, 4, index); 14 | if(index == -1) 15 | break; 16 | switch(index) 17 | { 18 | case 0: 19 | clockAlarm(); 20 | break; 21 | 22 | case 1: 23 | { 24 | uint32_t timer = millis(); 25 | bool blinkState = 0; 26 | String temp = ""; 27 | String monthsList[] PROGMEM = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; 28 | while(!mp.buttons.released(BTN_B) && !mp.buttons.released(BTN_A)) 29 | { 30 | mp.display.fillScreen(0x963F); 31 | // date and time 32 | mp.updateTimeRTC(); 33 | mp.display.setTextFont(2); 34 | mp.display.setTextSize(2); 35 | mp.display.setTextColor(TFT_BLACK); 36 | mp.display.setCursor(15, 25); 37 | temp = ""; 38 | if (mp.clockHour < 10) 39 | temp.concat("0"); 40 | temp.concat(mp.clockHour); 41 | temp.concat(":"); 42 | if (mp.clockMinute < 10) 43 | temp.concat("0"); 44 | temp.concat(mp.clockMinute); 45 | temp.concat(":"); 46 | if (mp.clockSecond < 10) 47 | temp.concat("0"); 48 | temp.concat(mp.clockSecond); 49 | 50 | mp.display.printCenter(temp); 51 | mp.display.setTextSize(1); 52 | mp.display.setCursor(63, 85); 53 | temp = ""; 54 | if (mp.clockDay < 10) 55 | temp.concat("0"); 56 | temp.concat(mp.clockDay); 57 | if(mp.clockDay < 20 && mp.clockDay > 10) 58 | temp.concat("th"); 59 | else if(mp.clockDay%10 == 1) 60 | temp.concat("st"); 61 | else if(mp.clockDay%10 == 2) 62 | temp.concat("nd"); 63 | else if(mp.clockDay%10 == 3) 64 | temp.concat("rd"); 65 | else 66 | temp.concat("th"); 67 | temp.concat(" of "); 68 | temp.concat(monthsList[mp.clockMonth - 1]); 69 | 70 | mp.display.printCenter(temp); 71 | mp.display.setCursor(0,100); 72 | mp.display.printCenter(mp.clockYear); 73 | 74 | 75 | if(millis()-timer >= 1000) 76 | { 77 | blinkState = !blinkState; 78 | timer = millis(); 79 | } 80 | mp.update(); 81 | 82 | } 83 | while(!mp.update()); 84 | } 85 | break; 86 | 87 | case 2: 88 | clockStopwatch(); 89 | break; 90 | 91 | case 3: 92 | clockTimer(); 93 | break; 94 | 95 | } 96 | } 97 | } 98 | int8_t clockMenu(String* title, uint8_t length, int8_t prevCursor) { 99 | uint8_t offset = 4; 100 | uint32_t blinkMillis = millis(); 101 | bool blinkState = 0; 102 | uint8_t cursor = prevCursor; 103 | int32_t cameraY = 0; 104 | int32_t cameraY_actual = 0; 105 | mp.dataRefreshFlag = 0; 106 | uint8_t boxHeight = 30; //actually 2 less than that 107 | while (1) { 108 | mp.update(); 109 | mp.display.fillScreen(TFT_BLACK); 110 | mp.display.setCursor(0, 0); 111 | cameraY_actual = (cameraY_actual + cameraY) / 2; 112 | if (cameraY_actual - cameraY == 1) { 113 | cameraY_actual = cameraY; 114 | } 115 | 116 | for (uint8_t i = 0; i < length; i++) { 117 | clockMenuDrawBox(title[i], i, cameraY_actual); 118 | } 119 | uint8_t y = cameraY_actual; 120 | uint8_t i = cursor; 121 | if(millis() - blinkMillis >= 350) 122 | { 123 | blinkState = !blinkState; 124 | blinkMillis = millis(); 125 | } 126 | if (blinkState) 127 | { 128 | y += i * boxHeight + offset; 129 | mp.display.drawRect(0, y-1, mp.display.width()-1, boxHeight+2, TFT_RED); 130 | mp.display.drawRect(1, y, mp.display.width()-3, boxHeight, TFT_RED); 131 | } 132 | 133 | if(mp.buttons.released(BTN_HOME)) { 134 | mp.exitedLockscreen = true; 135 | mp.lockscreen(); 136 | } 137 | if (mp.buttons.released(BTN_A)) { //BUTTON CONFIRM 138 | mp.osc->note(75, 0.05); 139 | mp.osc->play(); 140 | while(!mp.update());// Exit when pressed 141 | break; 142 | } 143 | 144 | if (mp.buttons.released(BTN_UP)) { //BUTTON UP 145 | mp.osc->note(75, 0.05); 146 | mp.osc->play(); 147 | blinkState = 1; 148 | blinkMillis = millis(); 149 | if (cursor == 0) { 150 | cursor = length - 1; 151 | if (length > 6) { 152 | cameraY = -(cursor - 2) * boxHeight; 153 | } 154 | } 155 | else { 156 | cursor--; 157 | if (cursor > 0 && (cursor * boxHeight + cameraY + offset) < boxHeight) { 158 | cameraY += 15; 159 | } 160 | } 161 | } 162 | 163 | if (mp.buttons.released(BTN_DOWN)) { //BUTTON DOWN 164 | mp.osc->note(75, 0.05); 165 | mp.osc->play(); 166 | blinkState = 1; 167 | blinkMillis = millis(); 168 | cursor++; 169 | if ((cursor * boxHeight + cameraY + offset) > 128) { 170 | cameraY -= boxHeight; 171 | } 172 | if (cursor >= length) { 173 | cursor = 0; 174 | cameraY = 0; 175 | 176 | } 177 | } 178 | 179 | 180 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 181 | { 182 | return -1; 183 | } 184 | } 185 | return cursor; 186 | } 187 | void clockMenuDrawBox(String title, uint8_t i, int32_t y) { 188 | uint8_t offset = 4; 189 | uint8_t boxHeight; 190 | boxHeight = 30; 191 | y += i * boxHeight + offset; 192 | if (y < 0 || y > mp.display.width()) { 193 | return; 194 | } 195 | mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2,TFT_DARKGREY); 196 | if (title == "Alarm") 197 | { 198 | mp.display.drawBitmap(5, y + 2, alarmIcon, 0xFC92, 2); 199 | mp.display.setTextColor(0xFC92); 200 | // mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2, 0xFC92); 201 | 202 | } 203 | else if (title == "Clock") 204 | { 205 | mp.display.drawBitmap(5, y + 2, clockIcon, 0x963F, 2); 206 | mp.display.setTextColor(0x963F); 207 | // mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2, 0x963F); 208 | } 209 | else if (title == "Stopwatch") 210 | { 211 | mp.display.drawBitmap(5, y + 2, stopwatchIcon, 0xFF92, 2); 212 | mp.display.setTextColor(0xFF92); 213 | // mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2, 0xFF92); 214 | 215 | } 216 | else if (title == "Timer") 217 | { 218 | mp.display.drawBitmap(5, y + 2, timerIcon, 0x97F6, 2); 219 | mp.display.setTextColor(0x97F6); 220 | // mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2, 0x97F6); 221 | 222 | } 223 | // mp.display.setTextColor(TFT_BLACK); 224 | mp.display.setTextSize(2); 225 | mp.display.setTextFont(1); 226 | mp.display.drawString(title, 40, y + 8); 227 | mp.display.setTextColor(TFT_WHITE); 228 | mp.display.setTextSize(1); 229 | } 230 | void clockStopwatch() 231 | { 232 | bool running = 0; 233 | String temp; 234 | uint32_t timeMillis = 0; 235 | uint32_t timeActual = 0; 236 | uint32_t blinkMills = millis(); 237 | bool blinkState = 1; 238 | while(!mp.buttons.released(BTN_B)) 239 | { 240 | mp.display.setTextColor(TFT_BLACK); 241 | mp.display.fillScreen(0xFF92); 242 | mp.display.setTextFont(2); 243 | mp.display.setTextSize(1); 244 | mp.display.setCursor(123,110); 245 | mp.display.print("Reset"); 246 | mp.display.setTextFont(2); 247 | mp.display.setTextSize(2); 248 | mp.display.setCursor(15, 25); 249 | int seconds = timeActual / 1000; 250 | int centiseconds = timeActual % 1000 / 10; 251 | temp = ""; 252 | if(seconds > 59) 253 | { 254 | int mins = seconds / 60; 255 | if (mins < 10) 256 | temp.concat("0"); 257 | temp.concat(mins); 258 | temp.concat(":"); 259 | } 260 | if (seconds % 60 < 10) 261 | temp.concat("0"); 262 | temp.concat(seconds % 60); 263 | temp.concat(":"); 264 | if (centiseconds < 10) 265 | temp.concat("0"); 266 | temp.concat(centiseconds); 267 | mp.display.printCenter(temp); 268 | 269 | if(!blinkState) 270 | { 271 | if(seconds > 59) 272 | { 273 | mp.display.fillRect(0, 0, 56, 60, 0xFF92); 274 | mp.display.fillRect(64, 0, 33, 60, 0xFF92); 275 | mp.display.fillRect(102, 0, 50, 60, 0xFF92); 276 | } 277 | else 278 | { 279 | mp.display.fillRect(0, 0, 75, 60, 0xFF92); 280 | mp.display.fillRect(82, 0, 70, 60, 0xFF92); 281 | } 282 | } 283 | if(!running) 284 | { 285 | mp.display.drawBitmap(72, 90, pause2, TFT_BLACK, 2); 286 | if(mp.buttons.released(BTN_A)) 287 | { 288 | blinkState = 1; 289 | blinkMills = millis(); 290 | running = 1; 291 | timeMillis = millis() - timeActual; 292 | while(!mp.update()); 293 | } 294 | if(mp.buttons.released(BTN_FUN_RIGHT)) 295 | { 296 | timeMillis = 0; 297 | timeActual = 0; 298 | } 299 | if (millis() - blinkMills >= 350) 300 | { 301 | blinkMills = millis(); 302 | blinkState = !blinkState; 303 | } 304 | } 305 | if(running) 306 | { 307 | mp.display.drawBitmap(72, 88, play, TFT_BLACK, 2); 308 | 309 | timeActual = millis() - timeMillis; 310 | if(mp.buttons.released(BTN_A)) 311 | { 312 | running = 0; 313 | timeMillis = millis(); 314 | while(!mp.update()); 315 | } 316 | if(mp.buttons.released(BTN_FUN_RIGHT)) 317 | { 318 | running = 0; 319 | timeMillis = 0; 320 | timeActual = 0; 321 | } 322 | } 323 | mp.update(); 324 | } 325 | while(!mp.update()); 326 | } 327 | 328 | void clockAlarm() 329 | { 330 | mp.loadAlarms(); 331 | uint16_t alarmCount = 0; 332 | for (int i = 0; i < 5;i++) 333 | { 334 | if(mp.alarmEnabled[i] != 2) 335 | alarmCount++; 336 | } 337 | uint8_t alarmsArray[alarmCount]; 338 | uint8_t temp = 0; 339 | for (int i = 0; i < 5;i++) 340 | { 341 | if(mp.alarmEnabled[i] != 2) 342 | { 343 | alarmsArray[temp] = i; 344 | temp++; 345 | } 346 | } 347 | while(1) 348 | { 349 | int8_t index = clockAlarmMenu(alarmsArray, alarmCount + 1) - 1; 350 | if(index == -1) 351 | { 352 | int8_t newAlarm = -1; 353 | for(int i = 0;i<5;i++) 354 | { 355 | if(mp.alarmEnabled[i] == 2) 356 | { 357 | newAlarm = i; 358 | break; 359 | } 360 | } 361 | if(newAlarm == -1) 362 | { 363 | mp.display.setTextColor(TFT_BLACK); 364 | mp.display.setTextSize(1); 365 | mp.display.setTextFont(2); 366 | mp.display.drawRect(14, 45, 134, 38, TFT_BLACK); 367 | mp.display.drawRect(13, 44, 136, 40, TFT_BLACK); 368 | mp.display.fillRect(15, 46, 132, 36, 0xFC92); 369 | mp.display.setCursor(47, 55); 370 | mp.display.printCenter("Limit reached!"); 371 | uint32_t tempMillis = millis(); 372 | while(millis() < tempMillis + 3000) 373 | { 374 | mp.update(); 375 | if(mp.buttons.pressed(BTN_A) || mp.buttons.pressed(BTN_B)) 376 | { 377 | while(!mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 378 | mp.update(); 379 | break; 380 | } 381 | } 382 | } 383 | else 384 | { 385 | clockAlarmEdit(newAlarm); 386 | alarmCount = 0; 387 | for (int i = 0; i < 5;i++) 388 | { 389 | if(mp.alarmEnabled[i] != 2) 390 | alarmCount++; 391 | } 392 | temp = 0; 393 | for (int i = 0; i < 5;i++) 394 | { 395 | if(mp.alarmEnabled[i] != 2) 396 | { 397 | alarmsArray[temp] = i; 398 | temp++; 399 | } 400 | } 401 | } 402 | 403 | } 404 | else if(index == -2) 405 | break; 406 | else if(index < -2) 407 | { 408 | index = alarmsArray[-(index + 4)]; 409 | Serial.printf("Deleting alarm on index %d\n", index); 410 | mp.alarmEnabled[index] = 2; 411 | mp.alarmHours[index] = 12; 412 | mp.alarmMins[index] = 0; 413 | mp.alarmRepeat[index] = 0; 414 | for (int i = 0;i<7;i++) 415 | mp.alarmRepeatDays[index][i] = 0; 416 | mp.alarmTrack[index] = "/Ringtones/Default ringtone.wav"; 417 | alarmCount = 0; 418 | for (int i = 0; i < 5;i++) 419 | { 420 | if(mp.alarmEnabled[i] != 2) 421 | alarmCount++; 422 | } 423 | temp = 0; 424 | for (int i = 0; i < 5;i++) 425 | { 426 | if(mp.alarmEnabled[i] != 2) 427 | { 428 | alarmsArray[temp] = i; 429 | temp++; 430 | } 431 | } 432 | mp.saveAlarms(); 433 | } 434 | else 435 | { 436 | Serial.println(index); 437 | clockAlarmEdit(index); 438 | alarmCount = 0; 439 | for (int i = 0; i < 5;i++) 440 | { 441 | if(mp.alarmEnabled[i] != 2) 442 | alarmCount++; 443 | } 444 | temp = 0; 445 | for (int i = 0; i < 5;i++) 446 | { 447 | if(mp.alarmEnabled[i] != 2) 448 | { 449 | alarmsArray[temp] = i; 450 | temp++; 451 | } 452 | } 453 | } 454 | } 455 | } 456 | int8_t clockAlarmMenu(uint8_t* alarmsArray, uint8_t length) { 457 | uint8_t offset = 1; 458 | uint8_t cursor = 0; 459 | int32_t cameraY = 0; 460 | int32_t cameraY_actual = 0; 461 | uint8_t bottomBezel = 30; 462 | mp.dataRefreshFlag = 0; 463 | uint8_t boxHeight; 464 | boxHeight = 28; //actually 2 less than that 465 | bool blinkState = 0; 466 | uint32_t blinkMillis = millis(); 467 | while (1) { 468 | mp.update(); 469 | mp.display.fillScreen(0xFC92); 470 | mp.display.setCursor(0, 0); 471 | cameraY_actual = (cameraY_actual + cameraY) / 2; 472 | if (cameraY_actual - cameraY == 1) { 473 | cameraY_actual = cameraY; 474 | } 475 | 476 | for (uint8_t i = 0; i < length; i++) { 477 | if(i < 1) 478 | { 479 | uint8_t temp = cameraY_actual; 480 | temp += i * boxHeight + offset; 481 | mp.display.fillRect(2, temp + 1, mp.display.width() - 4, boxHeight-2,TFT_DARKGREY); 482 | mp.display.setTextColor(TFT_WHITE); 483 | mp.display.setTextFont(2); 484 | mp.display.setTextSize(3); 485 | mp.display.setCursor(0, temp-12); 486 | mp.display.printCenter("+"); 487 | 488 | } 489 | else 490 | { 491 | if(cameraY_actual < 128-bottomBezel) 492 | clockAlarmMenuDrawBox(alarmsArray[i-1], i, cameraY_actual); 493 | } 494 | } 495 | uint8_t y = cameraY_actual; 496 | uint8_t i = cursor; 497 | if(millis() - blinkMillis > 350) 498 | { 499 | blinkMillis = millis(); 500 | blinkState = !blinkState; 501 | } 502 | if(blinkState) 503 | { 504 | y += i * boxHeight + offset; 505 | mp.display.drawRect(0, y-1, mp.display.width()-1, boxHeight+2, TFT_RED); 506 | mp.display.drawRect(1, y, mp.display.width()-3, boxHeight, TFT_RED); 507 | } 508 | mp.display.fillRect(0,114, 160, 22, 0xFC92); 509 | mp.display.setCursor(2, 113); 510 | mp.display.setTextFont(2); 511 | mp.display.setTextSize(1); 512 | mp.display.setTextColor(TFT_BLACK); 513 | mp.display.print("Delete"); 514 | if (mp.buttons.released(BTN_A)) { //BUTTON CONFIRM 515 | mp.osc->note(75, 0.05); 516 | mp.osc->play(); 517 | while(!mp.update());// Exit when pressed 518 | break; 519 | } 520 | 521 | if (mp.buttons.released(BTN_UP)) { //BUTTON UP 522 | blinkMillis = millis(); 523 | blinkState = 1; 524 | mp.osc->note(75, 0.05); 525 | mp.osc->play(); 526 | if (cursor == 0) { 527 | cursor = length - 1; 528 | if (length > 4) { 529 | cameraY = -(cursor - 3) * boxHeight; 530 | } 531 | } 532 | else { 533 | cursor--; 534 | if (cursor > 0 && (cursor * boxHeight + cameraY + offset) < boxHeight) { 535 | cameraY += boxHeight; 536 | } 537 | } 538 | } 539 | 540 | if (mp.buttons.released(BTN_DOWN)) { //BUTTON DOWN 541 | blinkMillis = millis(); 542 | blinkState = 1; 543 | mp.osc->note(75, 0.05); 544 | mp.osc->play(); 545 | cursor++; 546 | if ((cursor * boxHeight + cameraY + offset) > 128 - bottomBezel) { 547 | cameraY -= boxHeight; 548 | } 549 | if (cursor >= length) { 550 | cursor = 0; 551 | cameraY = 0; 552 | 553 | } 554 | } 555 | 556 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 557 | return -1; 558 | if(mp.buttons.released(BTN_FUN_LEFT) && cursor > 0) 559 | { 560 | mp.update(); 561 | return -(cursor + 2); 562 | } 563 | } 564 | return cursor; 565 | } 566 | void clockAlarmMenuDrawBox(uint8_t alarmIndex, uint8_t i, int32_t y) { 567 | uint8_t offset = 1; 568 | uint8_t boxHeight; 569 | boxHeight = 28; 570 | y += i * boxHeight + offset; 571 | if (y < 0 || y > mp.display.width()) { 572 | return; 573 | } 574 | mp.display.fillRect(2, y + 1, mp.display.width() - 4, boxHeight-2,TFT_DARKGREY); 575 | mp.display.setTextFont(2); 576 | mp.display.setTextSize(2); 577 | mp.display.setCursor(5, y-2); 578 | if (mp.alarmHours[alarmIndex] < 10) 579 | mp.display.print("0"); 580 | mp.display.print(mp.alarmHours[alarmIndex]); 581 | mp.display.print(":"); 582 | if (mp.alarmMins[alarmIndex] < 10) 583 | mp.display.print("0"); 584 | mp.display.print(mp.alarmMins[alarmIndex]); 585 | mp.display.setTextSize(1); 586 | mp.display.setCursor(130, y + 7); 587 | mp.display.print(mp.alarmEnabled[alarmIndex] ? "ON" : "OFF"); 588 | 589 | mp.display.setCursor(80, y + 11); 590 | mp.display.print(mp.alarmRepeat[alarmIndex] ? "repeat" : "once"); 591 | } 592 | void clockAlarmEdit(uint8_t index) 593 | { 594 | bool enabled = 0; 595 | bool repeat = 0; 596 | uint8_t hours = 12; 597 | uint8_t mins = 0; 598 | String temp; 599 | bool days[7] = {0, 0, 0, 0, 1, 1, 0}; 600 | uint8_t cursorX = 0; 601 | uint8_t cursorY = 0; 602 | char key; 603 | uint32_t blinkMillis = millis(); 604 | uint32_t color = TFT_BLACK; 605 | bool blinkState = 1; 606 | uint8_t start = 0; 607 | String parsedRingtone; 608 | String localRingtone = mp.alarm_path; 609 | if(mp.SDinsertedFlag) 610 | { 611 | listAudio("/Music", 0); 612 | String tempList[audioCount]; 613 | uint16_t tempCount = audioCount; 614 | for (int i = 0; i < audioCount;i++) 615 | tempList[i] = audioFiles[i]; 616 | listAudio("/Ringtones", 0); 617 | for (int i = 0; i < tempCount;i++) 618 | audioFiles[i + audioCount] = tempList[i]; 619 | audioCount += tempCount; 620 | } 621 | if(mp.alarmEnabled[index] != 2) 622 | { 623 | hours = mp.alarmHours[index]; 624 | mins = mp.alarmMins[index]; 625 | enabled = mp.alarmEnabled[index]; 626 | localRingtone = mp.alarmTrack[index]; 627 | for(int i = 0; i < 7; i++) 628 | { 629 | days[i] = mp.alarmRepeatDays[index][i]; 630 | } 631 | repeat = mp.alarmRepeat[index]; 632 | } 633 | while (localRingtone.indexOf("/", start) != -1) 634 | start = mp.alarm_path.indexOf("/", start) + 1; 635 | parsedRingtone = localRingtone.substring(start, localRingtone.indexOf(".")); 636 | start = 0; 637 | while(1) 638 | { 639 | color = TFT_BLACK; 640 | key = mp.buttons.getKey(); 641 | mp.display.fillScreen(0xFC92); 642 | //Hour black 643 | mp.display.setTextColor(TFT_BLACK); 644 | mp.display.setCursor(15, 4); 645 | mp.display.setTextFont(2); 646 | mp.display.setTextSize(2); 647 | temp = ""; 648 | if (hours < 10) 649 | temp.concat("0"); 650 | temp.concat(hours); 651 | temp.concat(":"); 652 | if (mins < 10) 653 | temp.concat("0"); 654 | temp.concat(mins); 655 | mp.display.print(temp); 656 | mp.display.drawRect(115, 11, 20, 20, TFT_BLACK); 657 | mp.display.drawRect(116, 12, 18, 18, TFT_BLACK); 658 | if(enabled) 659 | { 660 | mp.display.setTextFont(1); 661 | mp.display.setTextSize(2); 662 | mp.display.setCursor(120, 14); 663 | mp.display.print("X"); 664 | mp.display.setTextFont(2); 665 | } 666 | else 667 | color = TFT_DARKGREY; 668 | mp.display.setTextColor(color); 669 | mp.display.setCursor(15,38); 670 | mp.display.setTextSize(1); 671 | if(enabled) 672 | { 673 | if(!repeat) 674 | { 675 | mp.display.setCursor(42, 38); 676 | mp.display.print("once/"); 677 | mp.display.setTextColor(TFT_DARKGREY); 678 | mp.display.print("repeat"); 679 | mp.display.setCursor(85,56); 680 | mp.display.printCenter("M T W T F S S"); 681 | temp = ""; 682 | for(int i = 0; i<7;i++) 683 | { 684 | temp.concat(days[i] ? "X" : "O"); 685 | if(i < 6) 686 | temp.concat(" "); 687 | } 688 | mp.display.setCursor(0,71); 689 | mp.display.printCenter(temp); 690 | mp.display.setTextColor(TFT_BLACK); 691 | } 692 | else 693 | { 694 | mp.display.setCursor(42, 38); 695 | mp.display.setTextColor(TFT_DARKGREY); 696 | mp.display.print("once"); 697 | mp.display.setTextColor(TFT_BLACK); 698 | mp.display.print("/repeat"); 699 | mp.display.setCursor(85,56); 700 | mp.display.printCenter("M T W T F S S"); 701 | temp = ""; 702 | for(int i = 0; i<7;i++) 703 | { 704 | temp.concat(days[i] ? "X" : "O"); 705 | if(i < 6) 706 | temp.concat(" "); 707 | } 708 | mp.display.setCursor(0,71); 709 | mp.display.printCenter(temp); 710 | } 711 | 712 | } 713 | else 714 | { 715 | mp.display.printCenter("once/repeat"); 716 | mp.display.setCursor(85,56); 717 | mp.display.printCenter("M T W T F S S"); 718 | temp = ""; 719 | for(int i = 0; i<7;i++) 720 | { 721 | temp.concat(days[i] ? "X" : "O"); 722 | if(i < 6) 723 | temp.concat(" "); 724 | } 725 | mp.display.setCursor(0,71); 726 | mp.display.printCenter(temp); 727 | } 728 | mp.display.drawRect(20, 88, 120, 20, color); 729 | mp.display.drawRect(19, 87, 122, 22, color); 730 | mp.display.setCursor(0,90); 731 | mp.display.printCenter(parsedRingtone); 732 | mp.display.setCursor(4, 112); 733 | mp.display.setTextColor(TFT_BLACK); 734 | mp.display.print("Erase"); 735 | mp.display.setCursor(125, 112); 736 | mp.display.setTextColor(TFT_BLACK); 737 | mp.display.print("Save"); 738 | if(millis()-blinkMillis >= 350) 739 | { 740 | blinkState = !blinkState; 741 | blinkMillis = millis(); 742 | } 743 | switch (cursorY) 744 | { 745 | case 0: 746 | if(key != NO_KEY) 747 | { 748 | blinkState = 1; 749 | blinkMillis = millis(); 750 | } 751 | switch (cursorX) 752 | { 753 | case 0: 754 | if(mp.buttons.released(BTN_FUN_LEFT)) 755 | { 756 | while(!mp.update()); 757 | hours /= 10; 758 | } 759 | else if (isdigit(key) && hours < 10) 760 | hours = hours * 10 + key - 48; 761 | if(!blinkState) 762 | mp.display.fillRect(0, 0, 46, 41, 0xFC92); 763 | break; 764 | case 1: 765 | if(mp.buttons.released(BTN_FUN_LEFT)) 766 | { 767 | while(!mp.update()); 768 | mins /= 10; 769 | } 770 | else if (isdigit(key) && mins < 10) 771 | mins = mins * 10 + key - 48; 772 | if(!blinkState) 773 | mp.display.fillRect(51, 0, 40, 41, 0xFC92); 774 | break; 775 | case 2: 776 | if(!blinkState) 777 | { 778 | mp.display.drawRect(115, 11, 20, 20, 0xFC92); 779 | mp.display.drawRect(116, 12, 18, 18, 0xFC92); 780 | } 781 | if(mp.buttons.released(BTN_A)) 782 | { 783 | while(!mp.update()); 784 | enabled = !enabled; 785 | blinkState = 1; 786 | blinkMillis = millis(); 787 | } 788 | break; 789 | } 790 | 791 | if(mp.buttons.released(BTN_RIGHT) && cursorX < 2) 792 | { 793 | blinkState = 0; 794 | blinkMillis = millis(); 795 | cursorX++; 796 | mins %= 60; 797 | hours %= 24; 798 | while(!mp.update()); 799 | } 800 | if(mp.buttons.released(BTN_LEFT) && cursorX > 0) 801 | { 802 | blinkState = 0; 803 | blinkMillis = millis(); 804 | cursorX--; 805 | mins %= 60; 806 | hours %= 24; 807 | while(!mp.update()); 808 | } 809 | break; 810 | 811 | case 1: 812 | cursorX = repeat; 813 | if(!blinkState) 814 | { 815 | if(cursorX == 0) 816 | mp.display.fillRect(0, 43, 71, 12, 0xFC92); 817 | else if(cursorX == 1) 818 | mp.display.fillRect(78, 41, 50, 14, 0xFC92); 819 | } 820 | if(mp.buttons.released(BTN_RIGHT) && cursorX < 1) 821 | { 822 | blinkState = 0; 823 | blinkMillis = millis(); 824 | repeat = 1; 825 | while(!mp.update()); 826 | } 827 | if(mp.buttons.released(BTN_LEFT) && cursorX > 0) 828 | { 829 | blinkState = 0; 830 | blinkMillis = millis(); 831 | repeat = 0; 832 | while(!mp.update()); 833 | } 834 | break; 835 | 836 | case 2: 837 | if(!blinkState) 838 | mp.display.fillRect(29 + 14*cursorX, 57, 15, 15, 0xFC92); 839 | if(mp.buttons.released(BTN_RIGHT) && cursorX < 6) 840 | { 841 | cursorX++; 842 | blinkState = 0; 843 | blinkMillis = millis(); 844 | while(!mp.update()); 845 | } 846 | if(mp.buttons.released(BTN_LEFT) && cursorX > 0) 847 | { 848 | cursorX--; 849 | blinkState = 0; 850 | blinkMillis = millis(); 851 | while(!mp.update()); 852 | } 853 | if(mp.buttons.released(BTN_A)) 854 | { 855 | days[cursorX] = !days[cursorX]; 856 | blinkState = 1; 857 | blinkMillis = millis(); 858 | while(!mp.update()); 859 | } 860 | break; 861 | 862 | case 3: 863 | if(!blinkState) 864 | { 865 | mp.display.drawRect(20, 88, 120, 20, 0xFC92); 866 | mp.display.drawRect(19, 87, 122, 22, 0xFC92); 867 | } 868 | if(mp.buttons.released(BTN_A)) 869 | { 870 | if(mp.SDinsertedFlag) 871 | { 872 | while(!mp.update()); 873 | if(audioCount == 0) 874 | { 875 | mp.display.fillScreen(0xFC92); 876 | mp.display.setCursor(0, mp.display.height()/2 - 16); 877 | mp.display.setTextFont(2); 878 | mp.display.printCenter("No audio tracks found!"); 879 | uint32_t tempMillis = millis(); 880 | while(millis() < tempMillis + 2000) 881 | { 882 | mp.update(); 883 | if(mp.buttons.pressed(BTN_A) || mp.buttons.pressed(BTN_B)) 884 | { 885 | while(!mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 886 | mp.update(); 887 | break; 888 | } 889 | } 890 | } 891 | else 892 | { 893 | int8_t i = audioPlayerMenu("Select ringtone:", audioFiles, audioCount); 894 | mp.display.setTextColor(TFT_BLACK); 895 | if (i >= 0) 896 | localRingtone = audioFiles[i]; 897 | else 898 | Serial.println("pressed B in menu"); 899 | start = 0; 900 | while (localRingtone.indexOf("/", start) != -1) 901 | start = localRingtone.indexOf("/", start) + 1; 902 | parsedRingtone = localRingtone.substring(start, localRingtone.indexOf(".")); 903 | } 904 | } 905 | else 906 | { 907 | mp.display.setTextColor(TFT_BLACK); 908 | mp.display.setTextSize(1); 909 | mp.display.setTextFont(2); 910 | mp.display.drawRect(14, 45, 134, 38, TFT_BLACK); 911 | mp.display.drawRect(13, 44, 136, 40, TFT_BLACK); 912 | mp.display.fillRect(15, 46, 132, 36, 0xA7FF); 913 | mp.display.setCursor(47, 55); 914 | mp.display.printCenter("No SD card!"); 915 | uint32_t tempMillis = millis(); 916 | while(millis() < tempMillis + 1500) 917 | { 918 | mp.update(); 919 | if(mp.buttons.pressed(BTN_A) || mp.buttons.pressed(BTN_B)) 920 | { 921 | while(!mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 922 | mp.update(); 923 | break; 924 | } 925 | } 926 | while(!mp.update()); 927 | } 928 | 929 | } 930 | 931 | break; 932 | } 933 | if(mp.buttons.released(BTN_UP) && cursorY>0) 934 | { 935 | if (cursorY == 3 && !repeat) 936 | cursorY--; 937 | cursorY--; 938 | cursorX = 0; 939 | blinkState = 0; 940 | blinkMillis = millis(); 941 | while(!mp.update()); 942 | } 943 | if (mp.buttons.released(BTN_DOWN) && cursorY < 3 && enabled) 944 | { 945 | if (cursorY == 1 && !repeat) 946 | cursorY++; 947 | cursorY++; 948 | cursorX = 0; 949 | blinkState = 0; 950 | blinkMillis = millis(); 951 | while(!mp.update()); 952 | 953 | } 954 | if(mp.buttons.released(BTN_FUN_RIGHT)) 955 | { 956 | mp.display.setTextColor(TFT_BLACK); 957 | mp.display.setTextSize(1); 958 | mp.display.setTextFont(2); 959 | mp.display.drawRect(14, 49, 134, 26, TFT_BLACK); 960 | mp.display.drawRect(13, 48, 136, 28, TFT_BLACK); 961 | mp.display.fillRect(15, 50, 132, 24, 0xFC92); 962 | mp.display.setCursor(47, 53); 963 | mp.display.printCenter("Alarms saved!"); 964 | while(!mp.update()); 965 | mp.alarmHours[index] = hours; 966 | mp.alarmMins[index] = mins; 967 | mp.alarmEnabled[index] = enabled; 968 | mp.alarmTrack[index] = localRingtone; 969 | for(int i = 0; i < 7; i++) 970 | { 971 | mp.alarmRepeatDays[index][i] = days[i]; 972 | } 973 | mp.alarmRepeat[index] = repeat; 974 | mp.saveAlarms(); 975 | uint32_t tempMillis = millis(); 976 | while(millis() < tempMillis + 1000) 977 | { 978 | mp.update(); 979 | if(mp.buttons.pressed(BTN_A) || mp.buttons.pressed(BTN_B)) 980 | { 981 | while(!mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 982 | mp.update(); 983 | break; 984 | } 985 | } 986 | //save RTC and exit 987 | return; 988 | } 989 | if(mp.buttons.released(BTN_B)) 990 | { 991 | mp.buttons.update(); 992 | 993 | while(1) 994 | { 995 | mp.display.fillScreen(0xFC92); 996 | mp.display.setTextColor(TFT_BLACK); 997 | mp.display.setTextSize(1); 998 | mp.display.setTextFont(2); 999 | mp.display.drawRect(10, 45, 142, 38, TFT_BLACK); 1000 | mp.display.drawRect(9, 44, 144, 40, TFT_BLACK); 1001 | mp.display.setCursor(47, 48); 1002 | mp.display.printCenter("Exit without saving?"); 1003 | mp.display.setCursor(47, 61); 1004 | mp.display.printCenter("A: Yes B: No"); 1005 | if(mp.buttons.released(BTN_B)) 1006 | { 1007 | while(!mp.update()); 1008 | break; 1009 | } 1010 | if(mp.buttons.released(BTN_A)) 1011 | return; 1012 | mp.update(); 1013 | } 1014 | } 1015 | mp.update(); 1016 | } 1017 | 1018 | } 1019 | void clockTimer() 1020 | { 1021 | uint8_t hours = 0; 1022 | uint8_t mins = 0; 1023 | uint8_t secs = 0; 1024 | uint8_t cursor = 0; 1025 | uint32_t blinkMillis = millis(); 1026 | bool blinkState = 1; 1027 | uint32_t timeMillis = millis(); 1028 | uint8_t state = 0; 1029 | String temp = ""; 1030 | char key; 1031 | mp.display.setTextColor(TFT_BLACK); 1032 | uint16_t _tempSleepTime = mp.sleepTime; 1033 | mp.sleepTime = 0; 1034 | while (!mp.buttons.released(BTN_B)) 1035 | { 1036 | 1037 | key = mp.buttons.getKey(); 1038 | mp.display.fillScreen(0x97F6); 1039 | temp = ""; 1040 | if (hours < 10) 1041 | temp.concat("0"); 1042 | temp.concat(hours); 1043 | temp.concat(":"); 1044 | if (mins < 10) 1045 | temp.concat("0"); 1046 | temp.concat(mins); 1047 | temp.concat(":"); 1048 | if (secs < 10) 1049 | temp.concat("0"); 1050 | temp.concat(secs); 1051 | mp.display.setTextFont(2); 1052 | mp.display.setTextSize(2); 1053 | mp.display.setCursor(15, 25); 1054 | mp.display.printCenter(temp); 1055 | if(millis()-blinkMillis >= 500) 1056 | { 1057 | blinkState = !blinkState; 1058 | blinkMillis = millis(); 1059 | } 1060 | 1061 | mp.display.setTextFont(2); 1062 | mp.display.setTextSize(1); 1063 | mp.display.setCursor(123,110); 1064 | switch (state) 1065 | { 1066 | case 0: 1067 | if(key != NO_KEY) 1068 | { 1069 | if(mp.buttons.released(BTN_FUN_RIGHT) && (secs > 0 || mins > 0 || hours > 0)) 1070 | { 1071 | while(!mp.update()); 1072 | if(secs > 59) 1073 | { 1074 | secs %= 60; 1075 | mins++; 1076 | } 1077 | if(mins > 59) 1078 | { 1079 | mins %= 60; 1080 | hours++; 1081 | } 1082 | timeMillis = millis(); 1083 | state = 1; 1084 | break; 1085 | } 1086 | blinkState = 1; 1087 | blinkMillis = millis(); 1088 | switch (cursor) 1089 | { 1090 | case 0: 1091 | if(mp.buttons.released(BTN_FUN_LEFT)) 1092 | { 1093 | secs /= 10; 1094 | while(!mp.update()); 1095 | } 1096 | else if (isdigit(key) && secs < 10) 1097 | secs = secs * 10 + key - 48; 1098 | break; 1099 | case 1: 1100 | if(mp.buttons.released(BTN_FUN_LEFT)) 1101 | { 1102 | mins /= 10; 1103 | while(!mp.update()); 1104 | } 1105 | else if (isdigit(key) && mins < 10) 1106 | mins = mins * 10 + key - 48; 1107 | break; 1108 | case 2: 1109 | if(mp.buttons.released(BTN_FUN_LEFT)) 1110 | { 1111 | hours /= 10; 1112 | while(!mp.update()); 1113 | } 1114 | else if (isdigit(key) && hours < 10) 1115 | hours = hours * 10 + key - 48; 1116 | break; 1117 | } 1118 | } 1119 | mp.display.print("Start"); 1120 | mp.display.setCursor(2,110); 1121 | mp.display.print("Erase"); 1122 | 1123 | if(mp.buttons.released(BTN_LEFT) && cursor < 2) 1124 | { 1125 | blinkState = 0; 1126 | blinkMillis = millis(); 1127 | cursor++; 1128 | while(!mp.update()); 1129 | } 1130 | if(mp.buttons.released(BTN_RIGHT) && cursor > 0) 1131 | { 1132 | blinkState = 0; 1133 | blinkMillis = millis(); 1134 | cursor--; 1135 | while(!mp.update()); 1136 | } 1137 | if(mp.buttons.released(BTN_A) && (secs > 0 || mins > 0 || hours > 0)) 1138 | { 1139 | if(secs > 59) 1140 | { 1141 | secs %= 60; 1142 | mins++; 1143 | } 1144 | if(mins > 59) 1145 | { 1146 | mins %= 60; 1147 | hours++; 1148 | } 1149 | state = 1; 1150 | while(!mp.update()); 1151 | break; 1152 | } 1153 | if(!blinkState) 1154 | { 1155 | switch (cursor) 1156 | { 1157 | case 0: 1158 | mp.display.fillRect(102, 0, 50, 60, 0x97F6); 1159 | break; 1160 | 1161 | case 1: 1162 | mp.display.fillRect(64, 0, 33, 60, 0x97F6); 1163 | break; 1164 | 1165 | case 2: 1166 | mp.display.fillRect(0, 0, 56, 60, 0x97F6); 1167 | break; 1168 | } 1169 | } 1170 | break; 1171 | 1172 | case 1: 1173 | mp.display.print("Pause"); 1174 | mp.display.setCursor(2,110); 1175 | mp.display.print("Reset"); 1176 | if(millis()-timeMillis >= 1000) 1177 | { 1178 | timeMillis = millis(); 1179 | if(secs > 0) 1180 | secs--; 1181 | else 1182 | { 1183 | if(mins == 0 && hours == 0) 1184 | { 1185 | uint32_t callMillis = millis(); 1186 | bool playState = 1; 1187 | while(!mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 1188 | { 1189 | mp.display.fillScreen(0x97F6); 1190 | temp = ""; 1191 | if (hours < 10) 1192 | temp.concat("0"); 1193 | temp.concat(hours); 1194 | temp.concat(":"); 1195 | if (mins < 10) 1196 | temp.concat("0"); 1197 | temp.concat(mins); 1198 | temp.concat(":"); 1199 | if (secs < 10) 1200 | temp.concat("0"); 1201 | temp.concat(secs); 1202 | mp.display.setTextFont(2); 1203 | mp.display.setTextSize(2); 1204 | mp.display.setCursor(15, 25); 1205 | mp.display.printCenter(temp); 1206 | mp.display.setTextFont(2); 1207 | mp.display.setTextSize(1); 1208 | mp.display.setCursor(123,110); 1209 | mp.display.fillRect(0, 64, 160, 100, 0x97F6); 1210 | mp.display.setCursor(70, 85); 1211 | mp.display.printCenter("(press A)"); 1212 | mp.display.setCursor(70, 70); 1213 | if(millis()%700 >= 350) 1214 | mp.display.printCenter("DONE!"); 1215 | if(millis() - callMillis >= 1000) 1216 | { 1217 | playState = 1; 1218 | callMillis = millis(); 1219 | } 1220 | if(playState) 1221 | { 1222 | mp.playNotificationSound(4); 1223 | playState = 0; 1224 | } 1225 | mp.update(); 1226 | } 1227 | mp.osc->stop(); 1228 | while(!mp.update()); 1229 | mp.osc->setVolume(mp.oscillatorVolumeList[mp.mediaVolume]); 1230 | state = 0; 1231 | break; 1232 | } 1233 | secs = 59; 1234 | if(mins > 0) 1235 | mins--; 1236 | else 1237 | { 1238 | mins = 59; 1239 | if(hours > 0) 1240 | hours--; 1241 | else 1242 | mins = 0; 1243 | } 1244 | } 1245 | } 1246 | if(mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) 1247 | { 1248 | state = 2; 1249 | while(!mp.update()); 1250 | break; 1251 | } 1252 | if(mp.buttons.released(BTN_FUN_LEFT)) 1253 | { 1254 | state = 0; 1255 | secs = 0; 1256 | mins = 0; 1257 | hours = 0; 1258 | while(!mp.update()); 1259 | break; 1260 | } 1261 | break; 1262 | 1263 | case 2: 1264 | // if(!blinkState) 1265 | // { 1266 | // mp.display.fillRect(102, 0, 50, 60, 0x97F6); 1267 | // mp.display.fillRect(64, 0, 33, 60, 0x97F6); 1268 | // mp.display.fillRect(0, 0, 56, 60, 0x97F6); 1269 | // } 1270 | if(mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) 1271 | { 1272 | state = 1; 1273 | mp.display.fillRect(0, 64, 160, 100, 0x97F6); 1274 | mp.display.setCursor(123,110); 1275 | mp.display.print("Pause"); 1276 | mp.display.setCursor(2,110); 1277 | mp.display.print("Reset"); 1278 | while(!mp.update()); 1279 | break; 1280 | } 1281 | if(mp.buttons.released(BTN_FUN_LEFT)) 1282 | { 1283 | state = 0; 1284 | secs = 0; 1285 | mins = 0; 1286 | hours = 0; 1287 | while(!mp.update()); 1288 | break; 1289 | } 1290 | mp.display.setCursor(70, 75); 1291 | mp.display.printCenter("paused"); 1292 | mp.display.setCursor(114,110); 1293 | mp.display.print("Resume"); 1294 | mp.display.setCursor(2,110); 1295 | mp.display.print("Reset"); 1296 | break; 1297 | } 1298 | mp.update(); 1299 | } 1300 | while(!mp.update()); 1301 | mp.sleepTime = _tempSleepTime; 1302 | mp.sleepTimer = millis(); 1303 | } 1304 | -------------------------------------------------------------------------------- /src/messagesApp.cpp: -------------------------------------------------------------------------------- 1 | #include "messagesApp.h" 2 | #include "contactsApp.h" 3 | int16_t y = 0; 4 | /* 5 | [ 6 | { 7 | number: "123123", 8 | dateTime: "2018-12-12 12:12:12", 9 | text: "asd asd asd asd" 10 | } 11 | ] 12 | */ 13 | 14 | //Messages app 15 | void messagesApp() 16 | { 17 | Serial.println("Load messages app"); 18 | int16_t menuChoice = -1; 19 | mp.dataRefreshFlag = 0; 20 | File file = SD.open("/.core/messages.json", "r"); 21 | 22 | if(file.size() < 2){ // empty -> FILL 23 | Serial.println("Override"); 24 | file.close(); 25 | jb.clear(); 26 | // JsonArray& jarr = jb.parseArray("[{\"number\":\"123123\", \"dateTime\":\"2018-12-12 12:12:12\", \"text\":\"asd asd asd asd\"}]"); 27 | // JsonArray& jarr = jb.parseArray("[{\"number\":\"123123\", \"dateTime\":\"2018-12-12 12:12:12\", \"text\":\"asd asd asd asd\"}, {\"number\":\"09123\", \"dateTime\":\"2018-12-12 12:12:12\", \"text\":\"Some other text\"}, {\"number\":\"911\", \"dateTime\":\"2018-03-12 12:12:12\", \"text\":\"Help\"}]"); 28 | JsonArray& jarr = jb.createArray(); 29 | delay(10); 30 | File file1 = SD.open("/.core/messages.json", "w"); 31 | jarr.prettyPrintTo(file1); 32 | file1.close(); 33 | file = SD.open("/.core/messages.json", "r"); 34 | if(!file.available()) 35 | Serial.println("Messages ERROR"); 36 | Serial.println(file.size()); 37 | } 38 | 39 | jb.clear(); 40 | JsonArray& jarr = jb.parseArray(file); 41 | file.close(); 42 | jarr.prettyPrintTo(Serial); 43 | if(!jarr.success()) 44 | { 45 | Serial.println("Error"); 46 | mp.display.fillScreen(TFT_BLACK); 47 | mp.display.setCursor(0, mp.display.height()/2 - 16); 48 | mp.display.setTextFont(2); 49 | mp.display.printCenter("Error loading data"); 50 | jb.clear(); 51 | while (mp.buttons.released(BTN_B) == 0)//BUTTON BACK 52 | mp.update(); 53 | while(!mp.update()); 54 | } 55 | else 56 | { 57 | while (1) 58 | { 59 | menuChoice = smsMenu(jarr, menuChoice); 60 | Serial.print("chosen: "); 61 | Serial.println(menuChoice); 62 | 63 | if (menuChoice == -1) 64 | break; 65 | 66 | else if (menuChoice == -2) 67 | { 68 | if(mp.sim_module_version == 255) 69 | { 70 | mp.display.fillScreen(TFT_BLACK); 71 | mp.display.setTextColor(TFT_WHITE); 72 | mp.display.setTextSize(1); 73 | mp.display.setCursor(0, mp.display.height()/2 - 20); 74 | mp.display.setTextFont(2); 75 | mp.display.printCenter(F("No network board!")); 76 | mp.display.setCursor(0, mp.display.height()/2); 77 | mp.display.printCenter(F("Insert board and reset")); 78 | uint32_t tempMillis = millis(); 79 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 80 | mp.update(); 81 | while(!mp.update()); 82 | } 83 | else if(!mp.simInserted) 84 | { 85 | mp.display.fillScreen(TFT_BLACK); 86 | mp.display.setCursor(0, mp.display.height()/2 - 20); 87 | mp.display.setTextFont(2); 88 | mp.display.printCenter(F("No SIM inserted!")); 89 | mp.display.setCursor(0, mp.display.height()/2); 90 | mp.display.printCenter(F("Insert SIM and reset")); 91 | uint32_t tempMillis = millis(); 92 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 93 | mp.update(); 94 | while(!mp.update()); 95 | } 96 | else if(mp.airplaneMode) 97 | { 98 | mp.display.fillScreen(TFT_BLACK); 99 | mp.display.setCursor(0, mp.display.height()/2 - 20); 100 | mp.display.setTextFont(2); 101 | mp.display.printCenter(F("Can't send SMS!")); 102 | mp.display.setCursor(0, mp.display.height()/2); 103 | mp.display.printCenter(F("Turn off airplane mode")); 104 | uint32_t tempMillis = millis(); 105 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 106 | mp.update(); 107 | while(!mp.update()); 108 | } 109 | else 110 | { 111 | bool readyForCall = 0; 112 | uint32_t timeoutMillis = millis(); 113 | while(Serial1.available()) 114 | Serial1.read(); 115 | while(!readyForCall && millis() - timeoutMillis < 10000) 116 | { 117 | if(mp.sim_module_version == 1) 118 | { 119 | Serial1.println("AT+CCALR?"); 120 | String input = mp.waitForOK(); 121 | 122 | uint16_t helper = input.indexOf(" ", input.indexOf("+CCALR:")); 123 | readyForCall = input.substring(helper + 1, helper + 2).toInt(); 124 | Serial.println(input); 125 | if(!readyForCall) 126 | { 127 | mp.display.fillScreen(TFT_BLACK); 128 | mp.display.setTextColor(TFT_WHITE); 129 | mp.display.setTextSize(1); 130 | mp.display.setCursor(0, mp.display.height()/2 - 20); 131 | mp.display.setTextFont(2); 132 | mp.display.printCenter(F("Registering to network")); 133 | mp.display.setCursor(0, mp.display.height()/2); 134 | mp.display.printCenter(F("Please wait...")); 135 | while(!mp.update()); 136 | delay(1000); 137 | } 138 | } 139 | else 140 | { 141 | Serial1.println("AT+CREG?"); 142 | String input = mp.waitForOK(); 143 | 144 | uint16_t helper = input.indexOf(",", input.indexOf("+CREG:")); 145 | readyForCall = input.substring(helper + 1, helper + 2).toInt(); 146 | Serial.println(input); 147 | if(!readyForCall) 148 | { 149 | mp.display.fillScreen(TFT_BLACK); 150 | mp.display.setTextColor(TFT_WHITE); 151 | mp.display.setTextSize(1); 152 | mp.display.setCursor(0, mp.display.height()/2 - 20); 153 | mp.display.setTextFont(2); 154 | mp.display.printCenter(F("Registering to network")); 155 | mp.display.setCursor(0, mp.display.height()/2); 156 | mp.display.printCenter(F("Please wait...")); 157 | while(!mp.update()); 158 | delay(1000); 159 | } 160 | } 161 | } 162 | mp.networkRegistered = readyForCall; 163 | if(readyForCall) 164 | { 165 | if(mp.signalStrength == 99) 166 | { 167 | Serial1.println("AT+CSQ"); 168 | String buffer = ""; 169 | uint32_t current = millis(); 170 | while(buffer.indexOf("+CSQ:") == -1 && millis() - current >= 2000) 171 | buffer = Serial1.readString(); 172 | if(buffer.indexOf("+CSQ:") != -1) 173 | mp.signalStrength = buffer.substring(buffer.indexOf(" ", buffer.indexOf("+CSQ:")) + 1, buffer.indexOf(",", buffer.indexOf(" ", buffer.indexOf("+CSQ:")))).toInt(); 174 | if(mp.signalStrength == 99) 175 | { 176 | mp.display.fillScreen(TFT_BLACK); 177 | mp.display.setTextColor(TFT_WHITE); 178 | mp.display.setTextSize(1); 179 | mp.display.setCursor(0, mp.display.height()/2 - 20); 180 | mp.display.setTextFont(2); 181 | mp.display.printCenter(F("No signal!")); 182 | mp.display.setCursor(0, mp.display.height()/2); 183 | mp.display.printCenter(F("Check your antenna")); 184 | uint32_t tempMillis = millis(); 185 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 186 | mp.update(); 187 | while(!mp.update()); 188 | } 189 | else 190 | { 191 | composeSMS(&jarr); 192 | File file = SD.open("/.core/messages.json", "r"); 193 | jb.clear(); 194 | JsonArray& jarr = jb.parseArray(file); 195 | file.close(); 196 | if(!jarr.success()) 197 | { 198 | Serial.println("Error"); 199 | mp.display.fillScreen(TFT_BLACK); 200 | mp.display.setCursor(0, mp.display.height()/2 - 16); 201 | mp.display.setTextFont(2); 202 | mp.display.printCenter("Error loading data"); 203 | 204 | while (mp.buttons.released(BTN_B) == 0)//BUTTON BACK 205 | mp.update(); 206 | while(!mp.update()); 207 | } 208 | mp.newMessage = 0; 209 | } 210 | } 211 | else 212 | { 213 | composeSMS(&jarr); 214 | File file = SD.open("/.core/messages.json", "r"); 215 | jb.clear(); 216 | JsonArray& jarr = jb.parseArray(file); 217 | file.close(); 218 | if(!jarr.success()) 219 | { 220 | Serial.println("Error"); 221 | mp.display.fillScreen(TFT_BLACK); 222 | mp.display.setCursor(0, mp.display.height()/2 - 16); 223 | mp.display.setTextFont(2); 224 | mp.display.printCenter("Error loading data"); 225 | 226 | while (mp.buttons.released(BTN_B) == 0)//BUTTON BACK 227 | mp.update(); 228 | while(!mp.update()); 229 | } 230 | mp.newMessage = 0; 231 | } 232 | } 233 | else 234 | { 235 | mp.display.fillScreen(TFT_BLACK); 236 | mp.display.setTextColor(TFT_WHITE); 237 | mp.display.setTextSize(1); 238 | mp.display.setCursor(0, mp.display.height()/2 - 20); 239 | mp.display.setTextFont(2); 240 | mp.display.printCenter(F("Network unavailable")); 241 | mp.display.setCursor(0, mp.display.height()/2); 242 | mp.display.printCenter(F("Try again later")); 243 | uint32_t tempMillis = millis(); 244 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 245 | mp.update(); 246 | while(!mp.update()); 247 | } 248 | } 249 | menuChoice = -1; 250 | } 251 | 252 | else if(menuChoice == -3) 253 | { 254 | File file = SD.open("/.core/messages.json", "r"); 255 | jb.clear(); 256 | JsonArray& jarr = jb.parseArray(file); 257 | file.close(); 258 | if(!jarr.success()) 259 | { 260 | Serial.println("Error"); 261 | mp.display.fillScreen(TFT_BLACK); 262 | mp.display.setCursor(0, mp.display.height()/2 - 16); 263 | mp.display.setTextFont(2); 264 | mp.display.printCenter("Error loading data"); 265 | 266 | while (mp.buttons.released(BTN_B) == 0)//BUTTON BACK 267 | mp.update(); 268 | while(!mp.update()); 269 | } 270 | mp.newMessage = 0; 271 | menuChoice = -1; 272 | } 273 | 274 | else if(menuChoice > -1) 275 | { 276 | bool helper = 0; 277 | String temp = jarr[menuChoice]["contact"].as(); 278 | if(temp == "") 279 | { 280 | helper = viewSms(jarr[menuChoice]["text"].as(), jarr[menuChoice]["number"].as(), 281 | jarr[menuChoice]["dateTime"].as(), jarr[menuChoice]["direction"].as()); 282 | } 283 | else 284 | { 285 | helper = viewSms(jarr[menuChoice]["text"].as(), jarr[menuChoice]["contact"].as(), 286 | jarr[menuChoice]["dateTime"].as(), jarr[menuChoice]["direction"].as()); 287 | } 288 | if(helper) 289 | { 290 | jarr.remove(menuChoice); 291 | File file = SD.open("/.core/messages.json", "w"); 292 | jarr.prettyPrintTo(file); 293 | file.close(); 294 | menuChoice--; 295 | } 296 | else if(!jarr[menuChoice]["read"].as()) 297 | { 298 | jarr[menuChoice]["read"] = 1; 299 | File temp = SD.open("/.core/messages.json", "w"); 300 | jarr.prettyPrintTo(temp); 301 | temp.close(); 302 | file = SD.open("/.core/messages.json", "r"); 303 | if(!file.available()) 304 | Serial.println("Messages ERROR"); 305 | jb.parseArray(file); 306 | file.close(); 307 | } 308 | } 309 | else 310 | { 311 | menuChoice = -(menuChoice + 3); 312 | menuChoice--; 313 | } 314 | } 315 | } 316 | } 317 | 318 | bool viewSms(String content, String contact, uint32_t date, bool direction) 319 | { 320 | String input = ""; 321 | String buffer = ""; 322 | uint16_t awayX = 0; 323 | String helpString = ""; 324 | int16_t leftX = 0; 325 | int16_t oldX = 0; 326 | int16_t oldY = 0; 327 | bool lineFlag = false; 328 | y = 14; //Beggining point 329 | unsigned long elapsedMillis = millis(); 330 | bool blinkState = 1; 331 | DateTime time = DateTime(date); 332 | String contactLabel = mp.checkContact(contact); 333 | 334 | for(int i = 0; i < 10; i++) 335 | { 336 | if(mp.notificationTypeList[i] == 2 && mp.notificationDescriptionList[i] == contact && mp.notificationTimeList[i] == time) 337 | { 338 | mp.removeNotification(i); 339 | break; 340 | } 341 | } 342 | while (1) 343 | { 344 | mp.display.fillScreen(TFT_DARKGREY); 345 | mp.display.setTextWrap(1); 346 | mp.display.setCursor(2, y); 347 | lineFlag = false; 348 | for(uint16_t i = 0; i < content.length(); i++) 349 | { 350 | leftX = 154 - mp.display.getCursorX(); 351 | if(mp.display.getCursorX() < 2) mp.display.setCursor(2, mp.display.getCursorY()); 352 | if( content[i] == ' ' || i==0) { 353 | helpString = ""; 354 | for(uint8_t j = 1; j < 24; j++){ 355 | if (j == 22) { 356 | lineFlag = true; 357 | mp.display.print(content[i]); 358 | } 359 | else if(content[i+j] != ' ' && i+j != content.length()-1) helpString += content[i+j]; 360 | else { 361 | oldX = mp.display.getCursorX(); 362 | oldY = mp.display.getCursorY(); 363 | mp.display.setCursor(0, -20); 364 | mp.display.print(helpString); 365 | awayX = mp.display.getCursorX(); 366 | mp.display.setCursor(oldX, oldY); 367 | //mp.display.print(content[i]); 368 | if(awayX > leftX) mp.display.println(""); 369 | else mp.display.print(content[i]); 370 | if(mp.display.getCursorX() < 2) mp.display.setCursor(2, mp.display.getCursorY()); 371 | break; 372 | } 373 | } 374 | } 375 | else mp.display.print(content[i]); 376 | if (lineFlag && mp.display.getCursorX() > 140 ) { 377 | mp.display.print("-"); 378 | mp.display.println(); 379 | mp.display.setCursor(2, mp.display.getCursorY()); 380 | lineFlag = false; 381 | } 382 | 383 | if(mp.display.getCursorY() > 120) 384 | break; 385 | } 386 | 387 | if (mp.buttons.repeat(BTN_DOWN, 3)) { //BUTTON DOWN 388 | if (mp.display.cursor_y >= 94) 389 | { 390 | 391 | // if (!mp.buttons.released(BTN_DOWN)) 392 | y -= 4; 393 | // while (!mp.buttons.released(BTN_DOWN)) 394 | // { 395 | // if (millis() - buttonHeld > 100) { 396 | // y -= 4; 397 | // } 398 | // mp.update(); 399 | // break; 400 | // } 401 | } 402 | } 403 | 404 | if (mp.buttons.repeat(BTN_UP, 3)) { //BUTTON UP 405 | if (y < 14) 406 | { 407 | y += 4; 408 | } 409 | } 410 | 411 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 412 | { 413 | break; 414 | } 415 | 416 | if (millis() - elapsedMillis >= 1000) 417 | { 418 | elapsedMillis = millis(); 419 | blinkState = !blinkState; 420 | } 421 | if(mp.buttons.released(BTN_FUN_LEFT)) 422 | { 423 | return 1; 424 | } 425 | 426 | if (blinkState == 1) 427 | { 428 | mp.display.setTextColor(TFT_WHITE); 429 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 430 | mp.display.setTextFont(2); 431 | mp.display.setCursor(2,-1); 432 | mp.display.drawFastHLine(0, 14, mp.display.width(), TFT_WHITE); 433 | mp.display.print(direction ? "From: " : "To: "); 434 | if(contactLabel != "") 435 | mp.display.print(contactLabel); 436 | else 437 | mp.display.print(contact); 438 | } 439 | else 440 | { 441 | mp.display.setTextColor(TFT_WHITE); 442 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 443 | mp.display.setTextFont(2); 444 | mp.display.setCursor(2,-1); 445 | mp.display.drawFastHLine(0, 14, mp.display.width(), TFT_WHITE); 446 | char buf[100]; 447 | strncpy(buf, "DD.MM.YYYY hh:mm:ss\0", 100); 448 | mp.display.print(time.format(buf)); 449 | } 450 | mp.display.fillRect(0,110, 160, 18, TFT_DARKGREY); 451 | mp.display.drawFastHLine(0,111, 160, TFT_WHITE); 452 | mp.display.setCursor(4, 112); 453 | mp.display.print("Erase"); 454 | mp.update(); 455 | } 456 | // while(!mp.update()); 457 | mp.buttons.update(); 458 | return 0; 459 | } 460 | void smsMenuDrawBox(String contact, DateTime date, String content, bool direction, bool isRead, uint8_t i, int32_t y) 461 | { 462 | uint8_t offset; 463 | uint8_t boxHeight; 464 | uint8_t composeHeight; 465 | int sms_day = date.day(); 466 | int sms_month = date.month(); 467 | mp.display.setTextSize(1); 468 | offset = 19; 469 | composeHeight=21; 470 | boxHeight = 30; 471 | mp.display.setTextFont(2); 472 | //String contactLabel = mp.checkContact(contact); 473 | String contactLabel = ""; 474 | 475 | y += (i-1) * (boxHeight-1) + composeHeight + offset; 476 | if (y < 0 || y > mp.display.height()) 477 | { 478 | return; 479 | } 480 | String monthsList[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; 481 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight-2, isRead ? TFT_DARKGREY : 0xA534); 482 | 483 | if(direction) 484 | mp.display.drawBitmap(3, y + 6, incomingMessageIcon, TFT_BLUE, 2); 485 | else 486 | mp.display.drawBitmap(3, y + 6, outgoingMessageIcon, TFT_GREEN, 2); 487 | 488 | mp.display.setTextColor(TFT_WHITE); 489 | mp.display.setCursor(22, y - 1); 490 | 491 | if(contact.length() > 13 && contactLabel == "") 492 | { 493 | for(int i = 0; i < contact.length(); i++) 494 | { 495 | mp.display.print(contact[i]); 496 | if(mp.display.getCursorX() > 105) 497 | { 498 | mp.display.print("..."); 499 | break; 500 | } 501 | } 502 | } 503 | else 504 | { 505 | if(contactLabel != "") 506 | mp.display.print(contactLabel); 507 | else 508 | mp.display.print(contact); 509 | 510 | } 511 | // mp.display.drawString(contact, 22, y-1); 512 | mp.display.drawString(content, 22, y + 13); 513 | 514 | mp.display.setTextFont(1); 515 | mp.display.setCursor(127, y+3); 516 | mp.display.print(monthsList[sms_month-1]); 517 | mp.display.setCursor(mp.display.getCursorX() + 2, mp.display.getCursorY()); 518 | mp.display.print(sms_day); 519 | } 520 | void smsMenuDrawCursor(uint8_t i, int32_t y) 521 | { 522 | uint8_t offset; 523 | uint8_t boxHeight; 524 | uint8_t composeHeight; 525 | offset = 19; 526 | composeHeight=21; 527 | boxHeight = 30; 528 | mp.display.setTextSize(2); 529 | y += (i-1) * (boxHeight-1) + composeHeight + offset; 530 | mp.display.drawRect(0, y, mp.display.width(), boxHeight, TFT_RED); 531 | } 532 | int16_t smsMenu(JsonArray& messages, int16_t prevCursor) 533 | { 534 | int32_t cameraY = 0; 535 | int16_t cursor = 0; 536 | int32_t cameraY_actual = 0; 537 | uint8_t offset; 538 | uint8_t boxHeight; 539 | uint32_t blinkMillis = millis(); 540 | bool blinkState = 0; 541 | int length = messages.size(); 542 | uint8_t actualMessagesSize = messages.size(); 543 | for(int i = 0; i < messages.size(); i++) 544 | { 545 | if(strlen(messages[i]["text"].as()) > 160) 546 | actualMessagesSize+=strlen(messages[i]["text"].as())/160; 547 | } 548 | uint16_t sortingArray[length]; 549 | for(int i = 0; i < length; i++) 550 | sortingArray[i] = i; 551 | uint16_t min; 552 | for(int i = 0; i < length; i++) // sorting by unread 553 | { 554 | if(!messages[sortingArray[i]]["read"].as()) 555 | { 556 | for(int j = 0; j < length; j++) 557 | { 558 | if(messages[sortingArray[j]]["read"].as() && i != j) 559 | { 560 | uint16_t temp = sortingArray[j]; 561 | sortingArray[j] = sortingArray[i]; 562 | sortingArray[i] = temp; 563 | break; 564 | } 565 | } 566 | } 567 | 568 | } 569 | for(int i = 0; i < length - 1; i++) //sorting all by latest 570 | { 571 | min = i; 572 | for(int j = i + 1; j < length ; j++) 573 | if(messages[sortingArray[j]]["dateTime"].as() > messages[sortingArray[min]]["dateTime"].as() 574 | && ((!messages[sortingArray[i]]["read"].as() && !messages[sortingArray[j]]["read"].as()) 575 | || (messages[sortingArray[i]]["read"].as() && messages[sortingArray[j]]["read"].as()))) 576 | min = j; 577 | uint16_t temp = sortingArray[min]; 578 | sortingArray[min] = sortingArray[i]; 579 | sortingArray[i] = temp; 580 | } 581 | for(int i = 0; i < length; i++) 582 | if(sortingArray[i] == prevCursor) 583 | cursor = i + 1; 584 | Serial.print("Prevcursor: "); 585 | Serial.println(prevCursor); 586 | 587 | // for(int i = 0; i < length; i++) // sorting unread by latest 588 | // { 589 | // min = i; 590 | // for(int j = i + 1; j < length ; j++) 591 | // if(messages[sortingArray[j]]["dateTime"].as() > messages[sortingArray[min]]["dateTime"].as() 592 | // && !messages[sortingArray[i]]["read"].as() && !messages[sortingArray[j]]["read"].as()) 593 | // min = j; 594 | // uint16_t temp = sortingArray[min]; 595 | // sortingArray[min] = sortingArray[i]; 596 | // sortingArray[i] = temp; 597 | // } 598 | Serial.print("Cursor: "); 599 | Serial.println(cursor); 600 | // messages.prettyPrintTo(Serial); 601 | // for(int i = 0; i< length; i++) 602 | // { 603 | // Serial.print(sortingArray[i]); Serial.print(", "); 604 | // } 605 | if(prevCursor == -1) 606 | cursor = 0; 607 | offset = 19; 608 | boxHeight = 30; 609 | if (length > 2 && cursor > 2) 610 | { 611 | cameraY = -(cursor - 1) * (boxHeight - 1) + offset + 11 ; 612 | } 613 | while (1) 614 | { 615 | mp.update(); 616 | mp.display.fillScreen(TFT_BLACK); 617 | mp.display.setCursor(0, 0); 618 | cameraY_actual = (cameraY_actual + cameraY) / 2; 619 | if (cameraY_actual - cameraY == 1) 620 | { 621 | cameraY_actual = cameraY; 622 | } 623 | 624 | uint8_t i = 0; 625 | 626 | smsMenuComposeBox(i, cameraY_actual); 627 | for(int i = 0; i < length; i++) 628 | { 629 | JsonObject& elem = messages[sortingArray[i]]; 630 | DateTime date = DateTime(elem["dateTime"].as()); 631 | String temp = elem["contact"].as(); 632 | if(temp == "") 633 | smsMenuDrawBox(elem["number"].as(), date, elem["text"].as(), elem["direction"].as(), 634 | elem["read"].as(), i+1, cameraY_actual); 635 | else 636 | smsMenuDrawBox(elem["contact"].as(), date, elem["text"].as(), elem["direction"].as(), 637 | elem["read"].as(), i+1, cameraY_actual); 638 | } 639 | if(millis() - blinkMillis >= 300) 640 | { 641 | blinkMillis = millis(); 642 | blinkState = !blinkState; 643 | } 644 | if(blinkState) 645 | { 646 | if (cursor == 0) 647 | smsMenuComposeBoxCursor(cursor, cameraY_actual); 648 | else 649 | smsMenuDrawCursor(cursor, cameraY_actual); 650 | } 651 | 652 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 653 | mp.display.setTextFont(2); 654 | mp.display.setCursor(1,-1); 655 | mp.display.drawFastHLine(0, 14, BUF2WIDTH, TFT_WHITE); 656 | mp.display.setTextSize(1); 657 | mp.display.setTextColor(TFT_WHITE); 658 | mp.display.print("Messages"); 659 | mp.display.print(" "); 660 | mp.display.printf("%d/%d", actualMessagesSize, SMS_LIMIT); 661 | mp.display.drawFastHLine(0, 112, BUF2WIDTH, TFT_WHITE); 662 | mp.display.fillRect(0, 113, mp.display.width(), 30, TFT_DARKGREY); 663 | mp.display.setCursor(5, 113); 664 | mp.display.printCenter("Erase View"); 665 | mp.display.setTextSize(1); 666 | mp.display.setTextColor(TFT_WHITE); 667 | 668 | if(mp.buttons.released(BTN_HOME)) { 669 | mp.exitedLockscreen = true; 670 | mp.lockscreen(); 671 | } 672 | 673 | if (mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) 674 | { //BUTTON CONFIRM 675 | mp.osc->note(75, 0.05); 676 | mp.osc->play(); 677 | while(!mp.update());// Exit when pressed 678 | break; 679 | } 680 | 681 | if (mp.buttons.released(BTN_UP)) 682 | { //BUTTON UP 683 | blinkMillis = millis(); 684 | blinkState = 1; 685 | mp.osc->note(75, 0.05); 686 | mp.osc->play(); 687 | 688 | if (cursor == 0) 689 | { 690 | cursor = length; 691 | if (length > 2) 692 | { 693 | cameraY = -(cursor - 1) * (boxHeight-1); 694 | } 695 | } 696 | else 697 | { 698 | cursor--; 699 | if (cursor > 0 && ((cursor-1) * (boxHeight-1) + cameraY + offset + 21) < 20) 700 | { 701 | cameraY += (boxHeight-1); 702 | } 703 | } 704 | } 705 | 706 | if (mp.buttons.released(BTN_DOWN)) 707 | { //BUTTON DOWN 708 | blinkMillis = millis(); 709 | blinkState = 1; 710 | mp.osc->note(75, 0.05); 711 | mp.osc->play(); 712 | 713 | cursor++; 714 | if (cursor > 0) 715 | { 716 | if (((cursor - 1) * (boxHeight-1) + composeBoxHeight + cameraY + offset + 21) > 100) 717 | { 718 | cameraY -= boxHeight-1; 719 | } 720 | } 721 | else 722 | { 723 | if ((cursor * (boxHeight-1) + cameraY + offset + 21) > 100) 724 | { 725 | cameraY -= boxHeight-1; 726 | } 727 | } 728 | if (cursor > length) 729 | { 730 | cursor = 0; 731 | cameraY = 0; 732 | 733 | } 734 | 735 | } 736 | 737 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 738 | return -1; 739 | 740 | if(mp.buttons.released(BTN_FUN_LEFT) && cursor > 0) 741 | { 742 | String temp = messages[sortingArray[cursor - 1]]["contact"].as(); 743 | for(int i = 0; i < 10; i ++) 744 | { 745 | if(temp == "") 746 | { 747 | if(mp.notificationTypeList[i] == 2 && 748 | mp.notificationDescriptionList[i] == messages[sortingArray[cursor - 1]]["number"].as() && 749 | mp.notificationTimeList[i] == DateTime(messages[sortingArray[cursor - 1]]["dateTime"].as())) 750 | { 751 | mp.removeNotification(i); 752 | break; 753 | } 754 | } 755 | else 756 | { 757 | if(mp.notificationTypeList[i] == 2 && 758 | mp.notificationDescriptionList[i] == messages[sortingArray[cursor - 1]]["contact"].as() && 759 | mp.notificationTimeList[i] == DateTime(messages[sortingArray[cursor - 1]]["dateTime"].as())) 760 | { 761 | mp.removeNotification(i); 762 | break; 763 | } 764 | } 765 | } 766 | messages.remove(sortingArray[cursor - 1]); 767 | File file = SD.open("/.core/messages.json", "w"); 768 | messages.prettyPrintTo(file); 769 | file.close(); 770 | return -3 - sortingArray[cursor-1]; 771 | 772 | } 773 | if(mp.newMessage) 774 | { 775 | mp.newMessage = 0; 776 | return -3; 777 | } 778 | } 779 | if(cursor > 0) 780 | { 781 | cursor = sortingArray[cursor - 1]; 782 | return cursor; 783 | } 784 | else 785 | return -2; 786 | } 787 | void smsMenuComposeBoxCursor(uint8_t i, int32_t y) 788 | { 789 | uint8_t offset; 790 | uint8_t boxHeight; 791 | offset = 19; 792 | boxHeight=21; 793 | y += offset; 794 | mp.display.drawRect(0, y, mp.display.width(), boxHeight+1, TFT_RED); 795 | } 796 | void smsMenuComposeBox(uint8_t i, int32_t y) 797 | { 798 | uint8_t scale; 799 | uint8_t offset; 800 | uint8_t boxHeight; 801 | mp.display.setTextSize(1); 802 | scale = 2; 803 | offset = 19; 804 | boxHeight=21; 805 | mp.display.setTextFont(2); 806 | y += offset; 807 | if (y < 0 || y > mp.display.height()) 808 | { 809 | return; 810 | } 811 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight-1, TFT_DARKGREY); 812 | mp.display.drawBitmap(2*scale, y + 2, composeIcon, TFT_WHITE, scale); 813 | mp.display.setTextColor(TFT_WHITE); 814 | mp.display.drawString("New SMS", 20*scale, y+3); 815 | mp.display.setFreeFont(TT1); 816 | 817 | } 818 | void composeSMS(JsonArray *messages) 819 | { 820 | mp.textInput(""); 821 | mp.textPointer = 0; 822 | y = 16; //beginning point 823 | String content = ""; 824 | String contact = "+"; 825 | String prevContent = ""; 826 | int contactID = 0; 827 | String contactTemp = ""; 828 | char key = NO_KEY; 829 | bool cursor = 0; //editing contacts or text content 830 | unsigned long elapsedMillis = millis(); 831 | bool blinkState = 1; 832 | uint8_t scale = 2; 833 | bool plusSign = 0; 834 | bool helpPop; 835 | bool contactsApp = false; 836 | String contactLabel = ""; 837 | bool contactsEmpty = 0; 838 | File file = SD.open("/.core/contacts.json", "r"); 839 | if (file.size() < 2) 840 | { 841 | contactsEmpty = 1; 842 | Serial.println("Override"); 843 | file.close(); 844 | jb.clear(); 845 | JsonArray &jarr = jb.createArray(); 846 | delay(10); 847 | File file1 = SD.open("/.core/contacts.json", "w"); 848 | jarr.prettyPrintTo(file1); 849 | file1.close(); 850 | file = SD.open("/.core/contacts.json", "r"); 851 | if (!file) 852 | Serial.println("CONTACTS ERROR"); 853 | } 854 | jb.clear(); 855 | JsonArray &jarr = jb.parseArray(file); 856 | file.close(); 857 | if(jarr.measureLength() < 3) 858 | contactsEmpty = 1; 859 | while (1) 860 | { 861 | if(mp.buttons.released(BTN_HOME)) { 862 | mp.exitedLockscreen = true; 863 | mp.lockscreen(); 864 | } 865 | mp.display.fillScreen(TFT_DARKGREY); 866 | 867 | if (millis() - elapsedMillis >= multi_tap_threshold) //cursor blinking routine 868 | { 869 | elapsedMillis = millis(); 870 | blinkState = !blinkState; 871 | } 872 | 873 | if(cursor == 1) //inputting the text content 874 | { 875 | mp.display.setTextColor(TFT_WHITE); 876 | mp.display.setCursor(2, -1); 877 | mp.display.print("To: "); 878 | prevContent = content; 879 | content = mp.textInput(content, 160); 880 | if (prevContent != content) 881 | { 882 | blinkState = 1; 883 | elapsedMillis = millis(); 884 | } 885 | mp.display.setTextWrap(1); 886 | mp.display.setCursor(1*scale, y); 887 | for(int i = 0; i < content.length();i++) 888 | { 889 | mp.display.print(content[i]); 890 | if(mp.display.getCursorX() > 150) 891 | mp.display.print("\n"); 892 | } 893 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 894 | 895 | 896 | if(mp.display.getCursorY() > 120) 897 | y -= mp.display.getCursorY() - 120 + 8; 898 | if(y < 16 && mp.display.getCursorY() < 100) 899 | y += 120 - mp.display.getCursorY() + 8; 900 | if(blinkState == 1) 901 | mp.display.drawFastVLine(mp.display.getCursorX(), mp.display.getCursorY()+3, 10, TFT_WHITE); 902 | 903 | } 904 | 905 | if (cursor == 0) //inputting the contact number 906 | { 907 | key = mp.buttons.getKey(); 908 | if(mp.buttons.held(BTN_0, 20)) 909 | { 910 | contact+="+"; 911 | plusSign = 1; 912 | } 913 | if(key == '0' && plusSign) 914 | key = NO_KEY; 915 | if(plusSign && mp.buttons.released(BTN_0)) 916 | plusSign = 0; 917 | if (mp.buttons.released(BTN_FUN_LEFT)) 918 | contact.remove(contact.length() - 1); 919 | if (key != NO_KEY && isdigit(key) && contact.length() < 16) 920 | contact += key; 921 | mp.display.setTextWrap(1); 922 | 923 | mp.display.setCursor(1*scale, y); 924 | if (content == "") 925 | { 926 | mp.display.setTextColor(TFT_LIGHTGREY); 927 | mp.display.print(F("Compose...")); 928 | mp.display.setCursor(1*scale+1, y+14); 929 | mp.display.print(F("Press A to send")); 930 | mp.display.setTextColor(TFT_WHITE); 931 | } 932 | else 933 | { 934 | for(int i = 0; i < content.length();i++) 935 | { 936 | mp.display.print(content[i]); 937 | if(mp.display.getCursorX() > 150) 938 | mp.display.print("\n"); 939 | } 940 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 941 | } 942 | 943 | mp.display.setCursor(27, -1); 944 | 945 | contactLabel = mp.checkContact(contact); 946 | if(contactLabel != "") 947 | mp.display.print(contactLabel); 948 | else 949 | mp.display.print(contact); 950 | 951 | if (blinkState == 1) 952 | mp.display.drawFastVLine(mp.display.getCursorX(), mp.display.getCursorY()+3, 10, TFT_WHITE); 953 | } 954 | if ((mp.buttons.released(BTN_UP)) && cursor) { //BUTTON UP 955 | mp.buttons.update(); 956 | cursor = 0; 957 | } 958 | if ((mp.buttons.released(BTN_DOWN)) && !cursor) { //BUTTON DOWN 959 | mp.buttons.update(); 960 | cursor = 1; 961 | } 962 | 963 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 964 | { 965 | while(!mp.update()); 966 | break; 967 | } 968 | 969 | 970 | if(mp.buttons.released(BTN_FUN_RIGHT) && cursor == 1) 971 | { 972 | helpPop = !helpPop; 973 | mp.display.drawIcon(TextHelperPopup, 0, 0, 160, 128, 1, TFT_WHITE); 974 | while(!mp.update()); 975 | } 976 | while (helpPop) 977 | { 978 | if(mp.buttons.released(BTN_FUN_RIGHT) || mp.buttons.released(BTN_B)) 979 | { 980 | helpPop = !helpPop; 981 | } 982 | mp.update(); 983 | } 984 | if(mp.buttons.released(BTN_FUN_RIGHT) && cursor == 0 && contactsApp == false) 985 | { 986 | while(!mp.update()); 987 | contactsApp = true; 988 | contactID = 0; 989 | if (!jarr.success()) 990 | Serial.println("Error loading contacts"); 991 | else if(contactsEmpty) 992 | { 993 | mp.display.fillScreen(TFT_BLACK); 994 | mp.display.setCursor(0,mp.display.height()/2 -16); 995 | mp.display.printCenter(F("Contacts empty!")); 996 | uint32_t tempMillis = millis(); 997 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 998 | mp.update(); 999 | while(!mp.update()); 1000 | } 1001 | else 1002 | { 1003 | contactID = contactsMenu(&jarr, true); //call contacts app with smsFlag set to true 1004 | contactTemp = jarr[contactID+1]["number"].as(); 1005 | Serial.println("contactID"); 1006 | Serial.println(contactID); 1007 | contactID = 0; 1008 | } 1009 | if(contactTemp != "") 1010 | contact = contactTemp; 1011 | contactsApp = false; 1012 | 1013 | } 1014 | while(contactsApp) 1015 | { 1016 | if(mp.buttons.released(BTN_FUN_RIGHT) || mp.buttons.released(BTN_B)) 1017 | { 1018 | contactsApp = !contactsApp; 1019 | } 1020 | mp.update(); 1021 | } 1022 | if (mp.buttons.released(BTN_A) && contact.length() > 1 && content != "") // SEND SMS 1023 | { 1024 | mp.display.fillScreen(TFT_BLACK); 1025 | mp.display.setCursor(0, mp.display.height()/2 - 16); 1026 | mp.display.setTextFont(2); 1027 | mp.display.printCenter("Sending text..."); 1028 | if(contact.startsWith("00")) 1029 | contact = String("+" + contact.substring(2)); 1030 | while(!mp.update()); 1031 | Serial1.println("AT+CMGF=1"); 1032 | mp.waitForOK(); 1033 | 1034 | Serial1.print("AT+CMGS=\""); 1035 | Serial1.print(contact); 1036 | Serial1.println("\""); 1037 | // mp.waitForOK(); 1038 | uint32_t temp = millis(); 1039 | bool goAhead = 1; 1040 | while (!Serial1.available()) 1041 | { 1042 | if(millis()-temp > 1000) 1043 | { 1044 | Serial1.print("AT+CMGS=\""); 1045 | Serial1.print(contact); 1046 | Serial1.println("\""); 1047 | } 1048 | if(millis() - temp > 2000) 1049 | { 1050 | goAhead = 0; 1051 | break; 1052 | } 1053 | } 1054 | if(goAhead) 1055 | { 1056 | Serial.println(Serial1.readString()); 1057 | delay(5); 1058 | Serial1.print(content); 1059 | while (!Serial1.available()); 1060 | Serial.println(Serial1.readString()); 1061 | delay(5); 1062 | Serial1.println((char)26); 1063 | while (Serial1.readString().indexOf("OK") != -1); 1064 | while(!Serial1.available()); 1065 | mp.display.fillScreen(TFT_BLACK); 1066 | mp.display.printCenter("Text sent!"); 1067 | while(!mp.update()); 1068 | // String temp = mp.checkContact(contact); 1069 | mp.saveMessage((char*)content.c_str(), mp.checkContact(contact), contact, 1, 0, mp.RTC.now()); 1070 | delay(1000); 1071 | } 1072 | else 1073 | { 1074 | mp.display.fillScreen(TFT_BLACK); 1075 | mp.display.printCenter("Error sending text!"); 1076 | while(!mp.update()); 1077 | delay(1000); 1078 | } 1079 | Serial.println("cmgf checking"); 1080 | Serial1.println("AT+CMGF=0"); 1081 | mp.waitForOK(); 1082 | bool pduModeCheck = 0; 1083 | uint32_t timeout = millis(); 1084 | while(!pduModeCheck && millis() - timeout < 10000) 1085 | { 1086 | Serial1.println("AT+CMGF?"); 1087 | String ret = mp.waitForOK(); 1088 | Serial.println(ret); 1089 | Serial.println("---------"); 1090 | if(ret.indexOf("+CMGF: ") != -1 && ret.substring(ret.indexOf("+CMGF: ") + 7, ret.indexOf("+CMGF: ") + 8) == "0") 1091 | pduModeCheck = 1; 1092 | else if(ret.indexOf("+CMGF: ") != -1 && ret.substring(ret.indexOf("+CMGF: ") + 7, ret.indexOf("+CMGF: ") + 8) != "0") 1093 | { 1094 | Serial1.println("AT+CMGF=0"); 1095 | mp.waitForOK(); 1096 | delay(1000); 1097 | } 1098 | } 1099 | break; 1100 | } 1101 | mp.display.setTextColor(TFT_WHITE); 1102 | mp.display.setTextFont(2); 1103 | mp.display.setCursor(2,-1); 1104 | mp.display.drawFastHLine(0, 14, mp.display.width(), TFT_WHITE); 1105 | mp.display.print("To: "); 1106 | if(contactLabel != "") 1107 | mp.display.print(contactLabel); 1108 | else 1109 | mp.display.print(contact); 1110 | mp.display.fillRect(0,110, 160, 18, TFT_DARKGREY); 1111 | mp.display.drawFastHLine(0,111, 160, TFT_WHITE); 1112 | mp.display.setCursor(4, 112); 1113 | mp.display.print("Erase"); 1114 | if(cursor == 0) 1115 | { 1116 | mp.display.setCursor(102,112); 1117 | mp.display.print("Contacts"); 1118 | } 1119 | else if(cursor == 1) 1120 | { 1121 | mp.display.setCursor(130,112); 1122 | mp.display.print("Help"); 1123 | } 1124 | mp.update(); 1125 | if(mp.newMessage) 1126 | { 1127 | File file = SD.open("/.core/messages.json", "r"); 1128 | jb.clear(); 1129 | JsonArray& jarr = jb.parseArray(file); 1130 | file.close(); 1131 | if(!jarr.success()) 1132 | { 1133 | Serial.println("Error"); 1134 | mp.display.fillScreen(TFT_BLACK); 1135 | mp.display.setCursor(0, mp.display.height()/2 - 16); 1136 | mp.display.setTextFont(2); 1137 | mp.display.printCenter("Error loading data"); 1138 | 1139 | while (mp.buttons.released(BTN_B) == 0)//BUTTON BACK 1140 | mp.update(); 1141 | while(!mp.update()); 1142 | } 1143 | mp.newMessage = 0; 1144 | } 1145 | } 1146 | } -------------------------------------------------------------------------------- /src/phoneApp.cpp: -------------------------------------------------------------------------------- 1 | #include "phoneApp.h" 2 | void phoneApp() 3 | { 4 | mp.dataRefreshFlag = 0; 5 | String callBuffer = ""; 6 | char key = NO_KEY; 7 | mp.display.setTextWrap(0); 8 | mp.display.setTextFont(2); 9 | bool plusSign = 0; 10 | uint32_t blinkMillis = millis(); 11 | bool blinkState = 1; 12 | 13 | 14 | int32_t cameraY = 0; 15 | int32_t cameraY_actual = 0; 16 | 17 | uint8_t offset = 19; 18 | uint8_t boxHeight = 28; 19 | String favs[50] = {}; 20 | String favsNames[50] = {}; 21 | 22 | int32_t cursorPos = 0; 23 | int8_t length = 1; //5 favs + inputbox 24 | //int8_t lenActual = 0; 25 | String favsBuff = sortAndGetFav(); 26 | int entries = getContact(favsBuff, 0).toInt(); 27 | String tempBuff[50] = ""; 28 | int i = 1; 29 | Serial.println(favsBuff); 30 | favsBuff = favsBuff.substring(favsBuff.indexOf("|")+1, favsBuff.length()); 31 | Serial.println(favsBuff); 32 | 33 | char* ptr = strtok(&favsBuff[0], "|"); 34 | 35 | while(ptr != NULL) 36 | { 37 | favs[i] = ptr; 38 | favsNames[i] = mp.checkContact(favs[i]); 39 | ptr = strtok(NULL, "|"); 40 | i++; 41 | } 42 | 43 | //Serial.println("endbuff"); 44 | 45 | for(int d = 1; d <= entries; d++) 46 | { 47 | length++; 48 | Serial.println(favs[d]); 49 | } 50 | while (1) 51 | { 52 | length = 2; 53 | favs[0] = callBuffer; 54 | mp.display.fillScreen(TFT_BLACK); 55 | mp.display.setCursor(0, 0); 56 | cameraY_actual = (cameraY_actual + cameraY) / 2; 57 | if (cameraY_actual - cameraY == 1) 58 | { 59 | cameraY_actual = cameraY; 60 | } 61 | if(millis() - blinkMillis >= 350) 62 | { 63 | blinkMillis = millis(); 64 | blinkState = !blinkState; 65 | } 66 | //-------------------------------DRAW 0 START----------------------------------------- 67 | int i = -1; 68 | for(int k = 0; k < 5; k++) 69 | { 70 | if(k == 0) 71 | phoneMenuDrawBox("", favs[k], i+1, cameraY_actual, blinkState, cursorPos, k); 72 | else if(favs[k].compareTo("") != 0) 73 | { 74 | phoneMenuDrawBox(favsNames[k], favs[k], i+1, cameraY_actual, blinkState, cursorPos, k); 75 | length++; 76 | /* 77 | if(blinkState) 78 | { 79 | Serial.println("PHONEAPP-------------"); 80 | Serial.println(favs[k]); 81 | Serial.println("PHONEAPP-------------"); 82 | } 83 | */ 84 | } 85 | i++; 86 | } 87 | if(blinkState) 88 | { 89 | phoneMenuDrawCursor(cursorPos, cameraY_actual); 90 | } 91 | drawStuff(); 92 | //-------------------------------DRAW 0 END------------------------------------------- 93 | 94 | if(mp.buttons.released(BTN_UP)) 95 | { 96 | blinkState = 1; 97 | blinkMillis = millis(); 98 | while(!mp.update()); 99 | 100 | if (cursorPos == 0) 101 | { 102 | cursorPos = length - 2; 103 | if (length > 2) 104 | { 105 | cameraY = -(cursorPos - 2) * (boxHeight + 1); 106 | } 107 | } 108 | else 109 | { 110 | cursorPos--; 111 | if (cursorPos > 0 && (cursorPos * (boxHeight + 1) + cameraY + offset) < (boxHeight + 1)) 112 | { 113 | cameraY += (boxHeight + 1); 114 | } 115 | } 116 | //Serial.println("-----------------------UP"); 117 | //Serial.println(cursorPos); 118 | //Serial.println(length); 119 | //Serial.println(lenActual); 120 | //Serial.println("-----------------------"); 121 | } 122 | if (mp.buttons.released(BTN_DOWN)) 123 | { 124 | blinkState = 1; 125 | blinkMillis = millis(); 126 | while (!mp.update()); 127 | cursorPos++; 128 | if ((cursorPos * (boxHeight + 1) + cameraY + offset) > 80) 129 | { 130 | cameraY -= (boxHeight + 1); 131 | } 132 | if (cursorPos >= length - 1) 133 | { 134 | cursorPos = 0; 135 | cameraY = 0; 136 | } 137 | //Serial.println("---------------------DOWN"); 138 | //Serial.println(cursorPos); 139 | //Serial.println(length); 140 | //Serial.println(lenActual); 141 | //Serial.println("-----------------------"); 142 | } 143 | key = NO_KEY; 144 | for(int i = 0; i < 12; i++) 145 | { 146 | if(mp.buttons.released(i)) 147 | { 148 | if(i == 10) 149 | key = '0'; 150 | else if(i == 9) 151 | key = '*'; 152 | else if(i == 11) 153 | key = '#'; 154 | else 155 | key = '0' + i + 1; 156 | break; 157 | } 158 | } 159 | if(mp.buttons.released(BTN_HOME)) 160 | { 161 | mp.exitedLockscreen = true; 162 | mp.lockscreen(); 163 | } 164 | if(mp.buttons.held(BTN_0, 10)) 165 | { 166 | callBuffer+="+"; 167 | plusSign = 1; 168 | } 169 | if(key == '0' && plusSign) 170 | key = NO_KEY; 171 | if(plusSign && mp.buttons.released(BTN_0)) 172 | plusSign = 0; 173 | if (mp.buttons.released(BTN_FUN_LEFT)) 174 | { 175 | callBuffer.remove(callBuffer.length()-1); 176 | mp.buttons.update(); 177 | } 178 | if (mp.buttons.released(BTN_FUN_RIGHT)) 179 | { 180 | while(!mp.update()); 181 | if(!mp.SDinsertedFlag) 182 | { 183 | mp.display.fillScreen(TFT_BLACK); 184 | mp.display.setCursor(0, mp.display.height()/2 - 20); 185 | mp.display.setTextFont(2); 186 | mp.display.printCenter(F("No SD card inserted!")); 187 | mp.display.setCursor(0, mp.display.height()/2); 188 | mp.display.printCenter(F("Can't open call log")); 189 | uint32_t tempMillis = millis(); 190 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 191 | mp.update(); 192 | while(!mp.update()); 193 | } 194 | else 195 | callLog(); 196 | } 197 | if (key != NO_KEY) 198 | { 199 | switch (key) 200 | { 201 | case '1': 202 | mp.osc->note(NOTE_C5, 0.05); 203 | mp.osc->play(); 204 | break; 205 | case '2': 206 | mp.osc->note(NOTE_D5, 0.05); 207 | mp.osc->play(); 208 | break; 209 | case '3': 210 | mp.osc->note(NOTE_E5, 0.05); 211 | mp.osc->play(); 212 | break; 213 | case '4': 214 | mp.osc->note(NOTE_F5, 0.05); 215 | mp.osc->play(); 216 | break; 217 | case '5': 218 | mp.osc->note(NOTE_G5, 0.05); 219 | mp.osc->play(); 220 | break; 221 | case '6': 222 | mp.osc->note(NOTE_A5, 0.05); 223 | mp.osc->play(); 224 | break; 225 | case '7': 226 | mp.osc->note(NOTE_B5, 0.05); 227 | mp.osc->play(); 228 | break; 229 | case '8': 230 | mp.osc->note(NOTE_C6, 0.05); 231 | mp.osc->play(); 232 | break; 233 | case '9': 234 | mp.osc->note(NOTE_D6, 0.05); 235 | mp.osc->play(); 236 | break; 237 | case '*': 238 | mp.osc->note(NOTE_E6, 0.05); 239 | mp.osc->play(); 240 | break; 241 | case '0': 242 | mp.osc->note(NOTE_F6, 0.05); 243 | mp.osc->play(); 244 | break; 245 | case '#': 246 | mp.osc->note(NOTE_G6, 0.05); 247 | mp.osc->play(); 248 | break; 249 | 250 | default: 251 | break; 252 | } 253 | callBuffer += key; 254 | } 255 | 256 | if (mp.buttons.released(BTN_A) && (callBuffer != "" || cursorPos != 0))//initiate call 257 | { 258 | while(!mp.update()); 259 | if(mp.sim_module_version == 255) 260 | { 261 | mp.display.fillScreen(TFT_BLACK); 262 | mp.display.setTextColor(TFT_WHITE); 263 | mp.display.setTextSize(1); 264 | mp.display.setCursor(0, mp.display.height()/2 - 20); 265 | mp.display.setTextFont(2); 266 | mp.display.printCenter(F("No network board!")); 267 | mp.display.setCursor(0, mp.display.height()/2); 268 | mp.display.printCenter(F("Insert board and reset")); 269 | uint32_t tempMillis = millis(); 270 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 271 | mp.update(); 272 | while(!mp.update()); 273 | } 274 | else if(!mp.simInserted && callBuffer != "112") 275 | { 276 | mp.display.fillScreen(TFT_BLACK); 277 | mp.display.setTextColor(TFT_WHITE); 278 | mp.display.setTextSize(1); 279 | mp.display.setCursor(0, mp.display.height()/2 - 20); 280 | mp.display.setTextFont(2); 281 | mp.display.printCenter(F("No SIM inserted!")); 282 | mp.display.setCursor(0, mp.display.height()/2); 283 | mp.display.printCenter(F("Insert SIM and reset")); 284 | uint32_t tempMillis = millis(); 285 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 286 | mp.update(); 287 | while(!mp.update()); 288 | } 289 | else if(mp.airplaneMode) 290 | { 291 | mp.display.fillScreen(TFT_BLACK); 292 | mp.display.setTextColor(TFT_WHITE); 293 | mp.display.setTextSize(1); 294 | mp.display.setCursor(0, mp.display.height()/2 - 20); 295 | mp.display.setTextFont(2); 296 | mp.display.printCenter(F("Can't make calls")); 297 | mp.display.setCursor(0, mp.display.height()/2); 298 | mp.display.printCenter(F("Turn off airplane mode")); 299 | uint32_t tempMillis = millis(); 300 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 301 | mp.update(); 302 | while(!mp.update()); 303 | } 304 | else 305 | { 306 | bool readyForCall = 0; 307 | uint32_t timeoutMillis = millis(); 308 | while(Serial1.available()) 309 | Serial1.read(); 310 | while(!readyForCall && millis() - timeoutMillis < 10000) 311 | { 312 | if(mp.sim_module_version == 1) 313 | { 314 | Serial1.println("AT+CCALR?"); 315 | String input = mp.waitForOK(); 316 | 317 | uint16_t helper = input.indexOf(" ", input.indexOf("+CCALR:")); 318 | readyForCall = input.substring(helper + 1, helper + 2).toInt(); 319 | Serial.println(input); 320 | if(!readyForCall) 321 | { 322 | mp.display.fillScreen(TFT_BLACK); 323 | mp.display.setTextColor(TFT_WHITE); 324 | mp.display.setTextSize(1); 325 | mp.display.setCursor(0, mp.display.height()/2 - 20); 326 | mp.display.setTextFont(2); 327 | mp.display.printCenter(F("Registering to network")); 328 | mp.display.setCursor(0, mp.display.height()/2); 329 | mp.display.printCenter(F("Please wait...")); 330 | while(!mp.update()); 331 | delay(1000); 332 | } 333 | } 334 | else 335 | { 336 | Serial1.println("AT+CREG?"); 337 | String input = mp.waitForOK(); 338 | 339 | uint16_t helper = input.indexOf(",", input.indexOf("+CREG:")); 340 | readyForCall = input.substring(helper + 1, helper + 2).toInt(); 341 | Serial.println(input); 342 | if(!readyForCall) 343 | { 344 | mp.display.fillScreen(TFT_BLACK); 345 | mp.display.setTextColor(TFT_WHITE); 346 | mp.display.setTextSize(1); 347 | mp.display.setCursor(0, mp.display.height()/2 - 20); 348 | mp.display.setTextFont(2); 349 | mp.display.printCenter(F("Registering to network")); 350 | mp.display.setCursor(0, mp.display.height()/2); 351 | mp.display.printCenter(F("Please wait...")); 352 | while(!mp.update()); 353 | delay(1000); 354 | } 355 | } 356 | } 357 | mp.networkRegistered = readyForCall; 358 | if(readyForCall) 359 | { 360 | if(mp.signalStrength == 99) 361 | { 362 | Serial1.println("AT+CSQ"); 363 | String buffer = ""; 364 | uint32_t current = millis(); 365 | while(buffer.indexOf("+CSQ:") == -1 && millis() - current >= 2000) 366 | buffer = Serial1.readString(); 367 | if(buffer.indexOf("+CSQ:") != -1) 368 | mp.signalStrength = buffer.substring(buffer.indexOf(" ", buffer.indexOf("+CSQ:")) + 1, buffer.indexOf(",", buffer.indexOf(" ", buffer.indexOf("+CSQ:")))).toInt(); 369 | if(mp.signalStrength == 99) 370 | { 371 | mp.display.fillScreen(TFT_BLACK); 372 | mp.display.setTextColor(TFT_WHITE); 373 | mp.display.setTextSize(1); 374 | mp.display.setCursor(0, mp.display.height()/2 - 20); 375 | mp.display.setTextFont(2); 376 | mp.display.printCenter(F("No signal!")); 377 | mp.display.setCursor(0, mp.display.height()/2); 378 | mp.display.printCenter(F("Check your antenna")); 379 | uint32_t tempMillis = millis(); 380 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 381 | mp.update(); 382 | while(!mp.update()); 383 | } 384 | else 385 | { 386 | if(callBuffer.startsWith("*")) 387 | { 388 | sendMMI(callBuffer); 389 | } 390 | else 391 | { 392 | if(cursorPos == 0) 393 | { 394 | 395 | callNumber(callBuffer); 396 | } 397 | else 398 | { 399 | callBuffer = favs[cursorPos]; 400 | callNumber(callBuffer); 401 | } 402 | while(!mp.update()); 403 | } 404 | callBuffer = ""; 405 | } 406 | } 407 | else 408 | { 409 | 410 | if(callBuffer.startsWith("*") && cursorPos == 0) 411 | { 412 | sendMMI(callBuffer); 413 | } 414 | else 415 | { 416 | if (cursorPos == 0) 417 | { 418 | callNumber(callBuffer); 419 | } 420 | else 421 | { 422 | callBuffer = favs[cursorPos]; 423 | callNumber(callBuffer); 424 | } 425 | 426 | while(!mp.update()); 427 | } 428 | callBuffer = ""; 429 | } 430 | } 431 | else 432 | { 433 | mp.display.fillScreen(TFT_BLACK); 434 | mp.display.setTextColor(TFT_WHITE); 435 | mp.display.setTextSize(1); 436 | mp.display.setCursor(0, mp.display.height()/2 - 20); 437 | mp.display.setTextFont(2); 438 | mp.display.printCenter(F("Network unavailable")); 439 | mp.display.setCursor(0, mp.display.height()/2); 440 | mp.display.printCenter(F("Try again later")); 441 | uint32_t tempMillis = millis(); 442 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 443 | mp.update(); 444 | while(!mp.update()); 445 | } 446 | } 447 | } 448 | //-------------------------------DRAW 1 START----------------------------------------- 449 | if(blinkState) 450 | phoneMenuDrawCursor(cursorPos, cameraY_actual); 451 | drawStuff(); 452 | //-------------------------------DRAW 1 END------------------------------------------- 453 | if (mp.buttons.released(BTN_B)) //BACK BUTTON 454 | break; 455 | 456 | mp.update(); 457 | } 458 | while(!mp.update()); 459 | } 460 | 461 | String getContact(String data, int no) 462 | { 463 | String ret = ""; 464 | int index = data.indexOf("|") + 1; 465 | int prevIndex = 0; 466 | if(no == 0) 467 | { 468 | ret = data.substring(0, data.indexOf("|")); 469 | } 470 | else 471 | { 472 | for (int i = 0; i < no; i++) 473 | { 474 | prevIndex = index; 475 | index += data.indexOf("|", index) + 1; 476 | } 477 | ret = data.substring(prevIndex, index - 1); 478 | } 479 | return ret; 480 | } 481 | 482 | void drawStuff() 483 | { 484 | mp.display.setTextColor(TFT_WHITE); 485 | mp.display.setTextSize(1); 486 | //mp.display.fillRect(0, 79, mp.display.width(), 26, TFT_DARKGREY); 487 | mp.display.fillRect(0, 0, mp.display.width(), 18, TFT_BLACK); 488 | mp.display.fillRect(0, 110, mp.display.width(), 20, TFT_BLACK); 489 | mp.display.drawRect(108, 110, 52, 17, TFT_WHITE); 490 | mp.display.setCursor(110, 110); 491 | mp.display.setTextFont(2); 492 | mp.display.setTextColor(TFT_WHITE); 493 | mp.display.print("Call log"); 494 | mp.display.setCursor(60, -1); 495 | mp.display.print("Press A to call"); 496 | mp.display.setCursor(4, 110); 497 | mp.display.print("Erase"); 498 | mp.display.setCursor(2, -1); 499 | mp.display.setTextColor(TFT_LIGHTGREY); 500 | mp.display.print("Dialer"); 501 | mp.display.setTextColor(TFT_WHITE); 502 | } 503 | 504 | void phoneMenuDrawBox(String name, String number, uint8_t i, int32_t y, bool blState, int32_t cPos, bool inputFlag) 505 | { 506 | uint8_t offset = 19; 507 | uint8_t boxHeight = 28; 508 | y += i * boxHeight + offset; 509 | if (y < 0 || y > mp.display.height()) 510 | { 511 | return; 512 | } 513 | mp.display.setTextSize(1); 514 | mp.display.setTextFont(2); 515 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight-1, TFT_DARKGREY); 516 | mp.display.setTextColor(TFT_WHITE); 517 | mp.display.setCursor(2, y + 2); 518 | mp.display.drawString(name, 4, y); 519 | if(blState && cPos == 0 && !inputFlag) 520 | { 521 | mp.display.setTextSize(2); 522 | mp.display.setCursor(4, y - 2); 523 | mp.display.print(number); 524 | if (mp.display.cursor_x + 4 >= mp.display.width()) 525 | { 526 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight-1, TFT_DARKGREY); 527 | mp.display.setCursor(mp.display.width() - mp.display.cursor_x - 14, y - 2); 528 | mp.display.print(number); 529 | } 530 | // mp.display.drawString(number + "|", 4, y - 2); 531 | mp.display.drawFastVLine(mp.display.getCursorX() + 1, mp.display.getCursorY() + 6, 20, TFT_WHITE); 532 | mp.display.drawFastVLine(mp.display.getCursorX() + 2, mp.display.getCursorY() + 6, 20, TFT_WHITE); 533 | Serial.println(mp.display.cursor_x); 534 | // if (number.length() > 9) 535 | // { 536 | // mp.display.fillRect(0, 19, mp.display.width() - 1, 26, TFT_DARKGREY); 537 | // mp.display.setCursor((mp.display.cursor_x - (14 * (number.length() - 8))), 17); 538 | // mp.display.print(number + "|"); 539 | // } 540 | // mp.display.setCursor(0, 76); 541 | // mp.display.setTextSize(2); 542 | 543 | 544 | } 545 | else if((cPos == 0 && !inputFlag) || i == 0) 546 | { 547 | mp.display.setTextSize(2); 548 | mp.display.setCursor(4, y - 2); 549 | mp.display.print(number); 550 | if (mp.display.cursor_x + 4 >= mp.display.width()) 551 | { 552 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight-1, TFT_DARKGREY); 553 | mp.display.setCursor(mp.display.width() - mp.display.cursor_x - 14, y - 2); 554 | mp.display.print(number); 555 | } 556 | } 557 | else 558 | { 559 | mp.display.setTextSize(1); 560 | mp.display.drawString(number, 4, y + 12); 561 | } 562 | 563 | } 564 | 565 | void phoneMenuDrawCursor(uint8_t i, int32_t y) 566 | { 567 | uint8_t offset = 19; 568 | uint8_t boxHeight = 28; 569 | y += i * boxHeight + offset; 570 | mp.display.drawRect(0, y, mp.display.width(), boxHeight + 1, TFT_RED); 571 | } 572 | 573 | 574 | void phoneMenuInputBox(uint8_t i, int32_t y, String callBuffer) 575 | { 576 | uint8_t offset = 19; 577 | uint8_t boxHeight = 28; 578 | y += offset + 1; 579 | if (y < 0 || y > mp.display.height()) 580 | { 581 | return; 582 | } 583 | mp.display.setFreeFont(TT1); 584 | mp.display.setTextSize(1); 585 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight - 2, TFT_DARKGREY); 586 | //mp.display.drawBitmap(2, y + 4, newContactIcon, TFT_WHITE, 2); 587 | mp.display.setTextColor(TFT_WHITE); 588 | mp.display.setCursor(32, y + 6); 589 | mp.display.setTextFont(2); 590 | mp.display.print(callBuffer); 591 | 592 | 593 | if (mp.display.cursor_x + 4 >= mp.display.width()) 594 | { 595 | mp.display.fillRect(0, 79, mp.display.width(), 26, TFT_DARKGREY); 596 | mp.display.setCursor(mp.display.width() - mp.display.cursor_x - 14, 76); 597 | mp.display.print(callBuffer); 598 | } 599 | 600 | } 601 | 602 | void callLog() 603 | { 604 | mp.dataRefreshFlag = 0; 605 | mp.display.setTextWrap(0); 606 | mp.display.setTextFont(2); 607 | for(int i = 0; i < sizeof(mp.notificationTypeList); i++) 608 | { 609 | if(mp.notificationTypeList[i] == 1) 610 | { 611 | mp.notificationTypeList[i] = 0; 612 | mp.notificationDescriptionList[i] = ""; 613 | mp.notificationTimeList[i] = DateTime((uint32_t)0); 614 | } 615 | } 616 | mp.saveNotifications(); 617 | File file = SD.open("/.core/call_log.json", "r"); 618 | if(file.size() < 2){ // empty -> FILL 619 | Serial.println("Override"); 620 | file.close(); 621 | JsonArray& jarr = jb.createArray(); 622 | delay(10); 623 | File file1 = SD.open("/.core/call_log.json", "w"); 624 | jarr.prettyPrintTo(file1); 625 | file1.close(); 626 | file = SD.open("/.core/call_log.json", "r"); 627 | if(!file) 628 | Serial.println("CONTACTS ERROR"); 629 | } 630 | 631 | jb.clear(); 632 | JsonArray& jarr = jb.parseArray(file); 633 | file.close(); 634 | 635 | if(!jarr.success()) 636 | { 637 | Serial.println("Error"); 638 | } 639 | else 640 | { 641 | // add("5555", "2019-04-18 13:00:00", "342", &jarr); 642 | int menuChoice = -1; 643 | 644 | while (1) 645 | { 646 | menuChoice = callLogMenu(jarr, menuChoice); 647 | 648 | mp.buttons.update(); 649 | if (menuChoice != -2) 650 | { 651 | if(menuChoice >= 0) 652 | { 653 | if(showCall(menuChoice, jarr[menuChoice]["number"], jarr[menuChoice]["dateTime"], 654 | jarr[menuChoice]["contact"], jarr[menuChoice]["duration"], jarr[menuChoice]["direction"].as())){ 655 | jarr.remove(menuChoice); 656 | File file = SD.open("/.core/call_log.json", "w"); 657 | jarr.prettyPrintTo(file); 658 | file.close(); 659 | menuChoice = -1; 660 | } 661 | } 662 | else if(menuChoice == -10) 663 | { 664 | File file = SD.open("/.core/call_log.json", "r"); 665 | jb.clear(); 666 | jb.parseArray(file); 667 | file.close(); 668 | } 669 | while(!mp.update()); 670 | } 671 | else 672 | break; 673 | } 674 | } 675 | } 676 | 677 | 678 | 679 | int callLogMenu(JsonArray& call_log, int prevCursor) 680 | { 681 | uint8_t cursor = 0; 682 | int32_t cameraY = 0; 683 | int32_t cameraY_actual = 0; 684 | uint8_t length = call_log.size(); 685 | uint8_t offset = 20; 686 | uint8_t boxHeight = 28; 687 | uint16_t sortingArray[length]; 688 | bool blinkState = 0; 689 | uint32_t blinkMillis = millis(); 690 | for(int i = 0; i < length; i++) 691 | sortingArray[i] = i; 692 | uint16_t min; 693 | for(int i = 0; i < length - 1; i++) 694 | { 695 | min = i; 696 | for(int j = i + 1; j < length ; j++) 697 | if(call_log[sortingArray[j]]["dateTime"].as() > call_log[sortingArray[min]]["dateTime"].as()) 698 | min = j; 699 | uint16_t temp = sortingArray[min]; 700 | sortingArray[min] = sortingArray[i]; 701 | sortingArray[i] = temp; 702 | } 703 | for(int i = 0; i < length; i++) 704 | { 705 | if(sortingArray[i] == prevCursor) 706 | cursor = i; 707 | } 708 | if(prevCursor == -1) 709 | cursor = 0; 710 | if (length > 2 && cursor > 2) 711 | { 712 | cameraY = -(cursor - 2) * boxHeight; 713 | } 714 | while (1) { 715 | mp.display.fillScreen(TFT_BLACK); 716 | if(length == 0) 717 | { 718 | mp.display.setTextSize(2); 719 | mp.display.setCursor(0, 40); 720 | mp.display.setTextColor(TFT_WHITE); 721 | mp.display.printCenter("No calls"); 722 | cursor = 0; 723 | } 724 | else 725 | { 726 | cameraY_actual = (cameraY_actual + cameraY) / 2; 727 | if (cameraY_actual - cameraY == 1) { 728 | cameraY_actual = cameraY; 729 | } 730 | if(millis() - blinkMillis > 350) 731 | { 732 | blinkMillis = millis(); 733 | blinkState = !blinkState; 734 | } 735 | for(int i = 0; i < length; i++) 736 | { 737 | JsonObject& elem = call_log[sortingArray[i]]; 738 | callLogDrawBoxSD(elem, i, cameraY_actual); 739 | 740 | } 741 | if(blinkState) 742 | callLogMenuDrawCursor(cursor, cameraY_actual); 743 | if(mp.buttons.released(BTN_HOME)) { 744 | mp.exitedLockscreen = true; 745 | mp.lockscreen(); 746 | } 747 | 748 | if (mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) { 749 | mp.buttons.update(); 750 | break; 751 | } 752 | if (mp.buttons.released(BTN_FUN_LEFT)) //delete call log entry 753 | { 754 | mp.buttons.update(); 755 | call_log.remove(sortingArray[cursor]); 756 | File file = SD.open("/.core/call_log.json", "w"); 757 | call_log.prettyPrintTo(file); 758 | file.close(); 759 | return -10; 760 | } 761 | 762 | if (mp.buttons.released(BTN_UP)) { //BUTTON UP 763 | blinkState = 1; 764 | blinkMillis = millis(); 765 | mp.buttons.update(); 766 | if (cursor == 0) { 767 | cursor = length - 1; 768 | if (length > 3) { 769 | cameraY = -(cursor - 2) * (boxHeight); 770 | } 771 | } 772 | else { 773 | cursor--; 774 | if (cursor > 0 && (cursor * (boxHeight) + cameraY + offset) < (boxHeight)) { 775 | cameraY += (boxHeight); 776 | } 777 | } 778 | } 779 | if (mp.buttons.released(BTN_DOWN)) { //BUTTON DOWN 780 | blinkState = 1; 781 | blinkMillis = millis(); 782 | mp.buttons.update(); 783 | cursor++; 784 | if ((cursor * (boxHeight) + cameraY + offset) > 80) { 785 | cameraY -= (boxHeight); 786 | } 787 | if (cursor >= length) { 788 | cursor = 0; 789 | cameraY = 0; 790 | } 791 | } 792 | } 793 | 794 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 795 | { 796 | mp.buttons.update(); 797 | return -2; 798 | } 799 | mp.display.setCursor(0, 0); 800 | mp.display.setTextFont(2); 801 | mp.display.setTextColor(TFT_WHITE); 802 | mp.display.setTextSize(1); 803 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 804 | mp.display.setTextFont(2); 805 | mp.display.setCursor(0,-2); 806 | mp.display.drawFastHLine(0, 14, BUF2WIDTH, TFT_WHITE); 807 | mp.display.setTextSize(1); 808 | mp.display.setTextColor(TFT_WHITE); 809 | mp.display.print("Call log"); 810 | mp.display.setCursor(0,-1); 811 | mp.display.printf(" %d/40", length); 812 | mp.display.fillRect(0, 105, 160, 23, TFT_BLACK); 813 | mp.display.setCursor(5, 110); 814 | mp.display.print("Erase"); 815 | mp.display.setCursor(125, 110); 816 | mp.display.print("View"); 817 | 818 | 819 | mp.update(); 820 | 821 | } 822 | cursor = sortingArray[cursor]; 823 | return cursor; 824 | } 825 | 826 | void callLogDrawBoxSD(JsonObject& object, uint8_t i, int32_t y) 827 | { 828 | uint8_t offset = 20; 829 | uint8_t boxHeight = 28; 830 | y += i * boxHeight + offset; 831 | if (y < 0 || y > mp.display.height()) { 832 | return; 833 | } 834 | DateTime date = DateTime(object["dateTime"].as()); 835 | mp.display.setTextSize(1); 836 | mp.display.setTextFont(2); 837 | mp.display.fillRect(1, y + 1, mp.display.width() - 2, boxHeight-1, TFT_DARKGREY); 838 | mp.display.setTextColor(TFT_WHITE); 839 | mp.display.setCursor(2, y + 2); 840 | char buf[100]; 841 | strncpy(buf, "DD.MM.YYYY hh:mm:ss\0", 100); 842 | mp.display.drawString(date.format(buf), 24, y); 843 | String temp = object["contact"].as(); 844 | if(temp == "") 845 | mp.display.drawString(object["number"].as(), 24, y + 12); 846 | else 847 | mp.display.drawString(temp, 24, y + 12); 848 | 849 | switch (object["direction"].as()) 850 | { 851 | case 0: 852 | mp.display.drawBitmap(3, y + 6, missedCallIcon, TFT_RED, 2); 853 | break; 854 | case 1: 855 | mp.display.drawBitmap(3, y + 6, outgoingCallIcon, TFT_GREEN, 2); 856 | break; 857 | case 2: 858 | mp.display.drawBitmap(3, y + 6, incomingCallIcon, TFT_BLUE, 2); 859 | break; 860 | } 861 | } 862 | 863 | void callLogMenuDrawCursor(uint8_t i, int32_t y) 864 | { 865 | uint8_t offset = 20; 866 | uint8_t boxHeight = 28; 867 | y += i * boxHeight + offset; 868 | mp.display.drawRect(0, y, mp.display.width(), boxHeight + 1, TFT_RED); 869 | } 870 | 871 | uint8_t showCall(int id, String number, uint32_t dateTime, String contact, String duration, uint8_t direction) 872 | { 873 | DateTime time = DateTime(dateTime); 874 | while (1) 875 | { 876 | mp.display.fillScreen(TFT_BLACK); 877 | mp.display.fillRect(0, 0, mp.display.width(), 14, TFT_DARKGREY); 878 | mp.display.setTextFont(2); 879 | mp.display.setCursor(2,-2); 880 | mp.display.drawFastHLine(0, 14, BUF2WIDTH, TFT_WHITE); 881 | mp.display.setTextColor(TFT_WHITE); 882 | mp.display.print("Call log"); 883 | char buf[100]; 884 | strncpy(buf, "DD.MM.YYYY hh:mm:ss\0", 100); 885 | mp.display.setCursor(5,20); 886 | mp.display.print(time.format(buf)); 887 | if(contact == "") 888 | { 889 | mp.display.setCursor(5, 40); 890 | mp.display.println(number); 891 | mp.display.setCursor(5, 60); 892 | } 893 | else 894 | { 895 | mp.display.setCursor(5, 40); 896 | mp.display.println(contact); 897 | mp.display.setCursor(5, 60); 898 | mp.display.println(number); 899 | mp.display.setCursor(5, 80); 900 | } 901 | int seconds = duration.toInt() % 60; 902 | int minutes = duration.toInt() / 60; 903 | mp.display.print("Duration: "); 904 | if(minutes < 10) 905 | mp.display.print("0"); 906 | mp.display.print(minutes); 907 | mp.display.print(":"); 908 | if(seconds < 10) 909 | mp.display.print("0"); 910 | mp.display.print(seconds); 911 | 912 | mp.display.fillRect(110, 102, 45, 9*2, TFT_GREENYELLOW); 913 | mp.display.fillRect(5, 102, 45, 9*2, TFT_RED); 914 | mp.display.setTextColor(TFT_BLACK); 915 | mp.display.setCursor(9, 103); 916 | mp.display.print("Delete"); 917 | mp.display.setCursor(122, 103); 918 | mp.display.print("Call"); 919 | 920 | if (mp.buttons.released(BTN_FUN_LEFT)) //BUTTON BACK 921 | { 922 | while(!mp.update()); 923 | return 1; 924 | } 925 | if (mp.buttons.released(BTN_B)) //BUTTON BACK 926 | { 927 | Serial.println("Go back"); 928 | while(!mp.update()); 929 | break; 930 | } 931 | if (mp.buttons.released(BTN_A) || mp.buttons.released(BTN_FUN_RIGHT)) // Call 932 | { 933 | while(!mp.update()); 934 | if(mp.sim_module_version == 255) 935 | { 936 | mp.display.fillScreen(TFT_BLACK); 937 | mp.display.setTextColor(TFT_WHITE); 938 | mp.display.setTextSize(1); 939 | mp.display.setCursor(0, mp.display.height()/2 - 20); 940 | mp.display.setTextFont(2); 941 | mp.display.printCenter(F("No network board!")); 942 | mp.display.setCursor(0, mp.display.height()/2); 943 | mp.display.printCenter(F("Insert board and reset")); 944 | uint32_t tempMillis = millis(); 945 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 946 | mp.update(); 947 | while(!mp.update()); 948 | } 949 | else if(!mp.simInserted) 950 | { 951 | mp.display.fillScreen(TFT_BLACK); 952 | mp.display.setTextColor(TFT_WHITE); 953 | mp.display.setTextSize(1); 954 | mp.display.setCursor(0, mp.display.height()/2 - 20); 955 | mp.display.setTextFont(2); 956 | mp.display.printCenter(F("No SIM inserted!")); 957 | mp.display.setCursor(0, mp.display.height()/2); 958 | mp.display.printCenter(F("Insert SIM and reset")); 959 | uint32_t tempMillis = millis(); 960 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 961 | mp.update(); 962 | while(!mp.update()); 963 | } 964 | else if(mp.airplaneMode) 965 | { 966 | mp.display.fillScreen(TFT_BLACK); 967 | mp.display.setTextColor(TFT_WHITE); 968 | mp.display.setTextSize(1); 969 | mp.display.setCursor(0, mp.display.height()/2 - 20); 970 | mp.display.setTextFont(2); 971 | mp.display.printCenter(F("Can't make calls")); 972 | mp.display.setCursor(0, mp.display.height()/2); 973 | mp.display.printCenter(F("Turn off airplane mode")); 974 | uint32_t tempMillis = millis(); 975 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 976 | mp.update(); 977 | while(!mp.update()); 978 | } 979 | else 980 | { 981 | // Serial.println("AT+GSMBUSY=0"); 982 | // mp.waitForOK(); 983 | bool readyForCall = 0; 984 | uint32_t timeoutMillis = millis(); 985 | while(Serial1.available()) 986 | Serial1.read(); 987 | while(!readyForCall && millis() - timeoutMillis < 10000) 988 | { 989 | if(mp.sim_module_version == 1) 990 | { 991 | Serial1.println("AT+CCALR?"); 992 | String input = mp.waitForOK(); 993 | 994 | uint16_t helper = input.indexOf(" ", input.indexOf("+CCALR:")); 995 | readyForCall = input.substring(helper + 1, helper + 2).toInt(); 996 | Serial.println(input); 997 | if(!readyForCall) 998 | { 999 | mp.display.fillScreen(TFT_BLACK); 1000 | mp.display.setTextColor(TFT_WHITE); 1001 | mp.display.setTextSize(1); 1002 | mp.display.setCursor(0, mp.display.height()/2 - 20); 1003 | mp.display.setTextFont(2); 1004 | mp.display.printCenter(F("Registering to network")); 1005 | mp.display.setCursor(0, mp.display.height()/2); 1006 | mp.display.printCenter(F("Please wait...")); 1007 | while(!mp.update()); 1008 | delay(1000); 1009 | } 1010 | } 1011 | else 1012 | { 1013 | Serial1.println("AT+CREG?"); 1014 | String input = mp.waitForOK(); 1015 | 1016 | uint16_t helper = input.indexOf(",", input.indexOf("+CREG:")); 1017 | readyForCall = input.substring(helper + 1, helper + 2).toInt(); 1018 | Serial.println(input); 1019 | if(!readyForCall) 1020 | { 1021 | mp.display.fillScreen(TFT_BLACK); 1022 | mp.display.setTextColor(TFT_WHITE); 1023 | mp.display.setTextSize(1); 1024 | mp.display.setCursor(0, mp.display.height()/2 - 20); 1025 | mp.display.setTextFont(2); 1026 | mp.display.printCenter(F("Registering to network")); 1027 | mp.display.setCursor(0, mp.display.height()/2); 1028 | mp.display.printCenter(F("Please wait...")); 1029 | while(!mp.update()); 1030 | delay(1000); 1031 | } 1032 | } 1033 | } 1034 | 1035 | mp.networkRegistered = readyForCall; 1036 | if(readyForCall) 1037 | { 1038 | if(mp.signalStrength == 99) 1039 | { 1040 | Serial1.println("AT+CSQ"); 1041 | String buffer = ""; 1042 | uint32_t current = millis(); 1043 | while(buffer.indexOf("+CSQ:") == -1 && millis() - current >= 2000) 1044 | buffer = Serial1.readString(); 1045 | if(buffer.indexOf("+CSQ:") != -1) 1046 | mp.signalStrength = buffer.substring(buffer.indexOf(" ", buffer.indexOf("+CSQ:")) + 1, buffer.indexOf(",", buffer.indexOf(" ", buffer.indexOf("+CSQ:")))).toInt(); 1047 | if(mp.signalStrength == 99) 1048 | { 1049 | mp.display.fillScreen(TFT_BLACK); 1050 | mp.display.setTextColor(TFT_WHITE); 1051 | mp.display.setTextSize(1); 1052 | mp.display.setCursor(0, mp.display.height()/2 - 20); 1053 | mp.display.setTextFont(2); 1054 | mp.display.printCenter(F("No signal!")); 1055 | mp.display.setCursor(0, mp.display.height()/2); 1056 | mp.display.printCenter(F("Check your antenna")); 1057 | uint32_t tempMillis = millis(); 1058 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 1059 | mp.update(); 1060 | while(!mp.update()); 1061 | } 1062 | else 1063 | callNumber(number); 1064 | } 1065 | else 1066 | callNumber(number); 1067 | } 1068 | else 1069 | { 1070 | mp.display.fillScreen(TFT_BLACK); 1071 | mp.display.setTextColor(TFT_WHITE); 1072 | mp.display.setTextSize(1); 1073 | mp.display.setCursor(0, mp.display.height()/2 - 20); 1074 | mp.display.setTextFont(2); 1075 | mp.display.printCenter(F("Network unavailable")); 1076 | mp.display.setCursor(0, mp.display.height()/2); 1077 | mp.display.printCenter(F("Try again later")); 1078 | uint32_t tempMillis = millis(); 1079 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 1080 | mp.update(); 1081 | while(!mp.update()); 1082 | } 1083 | } 1084 | while(!mp.update()); 1085 | return 0; 1086 | } 1087 | 1088 | mp.update(); 1089 | } 1090 | return 0; 1091 | } 1092 | void sendMMI(String code) 1093 | { 1094 | mp.inCall = 1; 1095 | String buffer = ""; 1096 | // Serial1.println("AT+CUSD=1"); 1097 | // delay(10); 1098 | Serial1.print("AT+CUSD=1,\"");// at+cusd=1,"*101#", 15 1099 | Serial1.print(code); 1100 | Serial1.println("\", 15"); 1101 | uint32_t tempMillis = millis(); 1102 | bool cleared = 0; 1103 | while(buffer.indexOf("\r", buffer.indexOf("+CUSD: 0")) == -1 && millis() - tempMillis < 4000) 1104 | { 1105 | if(Serial1.available()) 1106 | { 1107 | tempMillis = millis(); 1108 | buffer+=(char)Serial1.read(); 1109 | Serial.println(buffer); 1110 | if(buffer.indexOf("+CUSD: 0") != -1 && !cleared) 1111 | { 1112 | buffer = "+CUSD: 0"; 1113 | cleared = 1; 1114 | } 1115 | } 1116 | mp.display.fillScreen(TFT_WHITE); 1117 | mp.display.drawRect(9, 34, 142, 60, TFT_BLACK); 1118 | mp.display.drawRect(10, 35, 140, 58, TFT_BLACK); 1119 | mp.display.fillRect(11, 36, 138, 56, TFT_WHITE); 1120 | mp.display.setTextColor(TFT_BLACK); 1121 | mp.display.setTextFont(2); 1122 | mp.display.setTextSize(1); 1123 | mp.display.setCursor(55, 54); 1124 | mp.display.printCenter("Sending USSD code"); 1125 | while(!mp.update()); 1126 | } 1127 | if(buffer.indexOf("\r", buffer.indexOf("+CUSD: 0")) == -1) 1128 | { 1129 | mp.inCall = 0; 1130 | mp.display.fillScreen(TFT_WHITE); 1131 | mp.display.drawRect(9, 34, 142, 60, TFT_BLACK); 1132 | mp.display.drawRect(10, 35, 140, 58, TFT_BLACK); 1133 | mp.display.fillRect(11, 36, 138, 56, TFT_WHITE); 1134 | mp.display.setTextColor(TFT_BLACK); 1135 | mp.display.setTextFont(2); 1136 | mp.display.setTextSize(1); 1137 | mp.display.setCursor(55, 54); 1138 | mp.display.printCenter("Invalid USSD code!"); 1139 | while(!mp.update()); 1140 | uint32_t tempMillis = millis(); 1141 | while(millis() < tempMillis + 2000 && !mp.buttons.released(BTN_A) && !mp.buttons.released(BTN_B)) 1142 | mp.update(); 1143 | return; 1144 | } 1145 | uint16_t helper = buffer.indexOf("\"") + 1; 1146 | buffer = buffer.substring(helper, buffer.indexOf("\"", helper + 1)); 1147 | Serial.println(buffer); 1148 | int32_t y = -1; 1149 | while(!mp.buttons.released(BTN_B)) 1150 | { 1151 | mp.display.fillScreen(TFT_WHITE); 1152 | // mp.display.drawRect(10, 20, 142, 88, TFT_BLACK); 1153 | // mp.display.drawRect(11, 21, 141, 86, TFT_BLACK); 1154 | mp.display.fillRect(12, 22, 138, 84, TFT_WHITE); 1155 | mp.display.setTextColor(TFT_BLACK); 1156 | mp.display.setTextFont(2); 1157 | mp.display.setTextSize(1); 1158 | mp.display.setCursor(2, y); 1159 | mp.display.setTextWrap(0); 1160 | 1161 | /* for(int i = 0; i < buffer.length();i++) 1162 | { 1163 | mp.display.print(buffer[i]); 1164 | if(mp.display.getCursorX() > 150) 1165 | { 1166 | mp.display.print("\n"); 1167 | mp.display.setCursor(5, mp.display.getCursorY()); 1168 | } 1169 | } */ 1170 | for(uint16_t i = 0; i < buffer.length(); i++) 1171 | { 1172 | int16_t leftX = 154 - mp.display.getCursorX(); 1173 | if(mp.display.getCursorX() < 2) mp.display.setCursor(2, mp.display.getCursorY()); 1174 | bool lineFlag = false; 1175 | if( buffer[i] == ' ' || i==0) { 1176 | String helpString = ""; 1177 | for(uint8_t j = 1; j < 24; j++){ 1178 | if (j == 21) { 1179 | lineFlag = true; 1180 | mp.display.print(buffer[i]); 1181 | } 1182 | else if(buffer[i+j] != ' ' && i+j != buffer.length()-1) helpString += buffer[i+j]; 1183 | else { 1184 | int16_t oldX = mp.display.getCursorX(); 1185 | int16_t oldY = mp.display.getCursorY(); 1186 | mp.display.setCursor(0, -20); 1187 | mp.display.print(helpString); 1188 | int16_t awayX = mp.display.getCursorX(); 1189 | mp.display.setCursor(oldX, oldY); 1190 | //mp.display.print(content[i]); 1191 | if(awayX > leftX) mp.display.println(""); 1192 | else mp.display.print(buffer[i]); 1193 | if(mp.display.getCursorX() < 2) mp.display.setCursor(2, mp.display.getCursorY()); 1194 | break; 1195 | } 1196 | } 1197 | } 1198 | else mp.display.print(buffer[i]); 1199 | if (lineFlag && mp.display.getCursorX() > 144 ) { 1200 | mp.display.print("-"); 1201 | mp.display.println(); 1202 | mp.display.setCursor(2, mp.display.getCursorY()); 1203 | lineFlag = false; 1204 | } 1205 | 1206 | if(mp.display.getCursorY() > 120) 1207 | break; 1208 | } 1209 | if (mp.buttons.repeat(BTN_DOWN, 3)) { //BUTTON DOWN 1210 | if (mp.display.cursor_y >= 96) 1211 | { 1212 | y -= 4; 1213 | Serial.println(y); 1214 | } 1215 | } 1216 | 1217 | if (mp.buttons.repeat(BTN_UP, 3)) { //BUTTON UP 1218 | if (y < -1) 1219 | { 1220 | y += 4; 1221 | Serial.println(y); 1222 | } 1223 | } 1224 | mp.display.fillRect(0, 111, 160, 20, TFT_DARKGREY); 1225 | mp.display.setCursor(2, 111); 1226 | mp.display.setTextColor(TFT_WHITE); 1227 | mp.display.print("Press B to go back"); 1228 | 1229 | mp.update(); 1230 | } 1231 | mp.buttons.update(); 1232 | mp.inCall = 0; 1233 | } 1234 | 1235 | String sortAndGetFav() 1236 | { 1237 | String ret = ""; 1238 | uint16_t contactCount = 0; 1239 | String contacts[50][2] = {}; 1240 | String numBuf [50] = {}; 1241 | int i, j; 1242 | 1243 | //OPEN FILES START 1244 | File file1 = SD.open("/.core/contacts.json", "r"); 1245 | if (file1.size() < 2) 1246 | { 1247 | Serial.println("Override"); 1248 | file1.close(); 1249 | jb.clear(); 1250 | JsonArray& contactsjarr = jb.createArray(); 1251 | delay(10); 1252 | File file2 = SD.open("/.core/contacts.json", "w"); 1253 | contactsjarr.prettyPrintTo(file2); 1254 | file2.close(); 1255 | file1 = SD.open("/.core/contacts.json", "r"); 1256 | if (!file1) 1257 | Serial.println("CONTACTS ERROR"); 1258 | } 1259 | jb.clear(); 1260 | JsonArray& contactsjarr = jb.parseArray(file1); 1261 | file1.close(); 1262 | //OPEN FILES END 1263 | 1264 | if(!contactsjarr.success()) 1265 | { 1266 | Serial.println("Error"); 1267 | } 1268 | else 1269 | { 1270 | i = 0; 1271 | Serial.println("json contacts loop start---------------"); 1272 | for (JsonObject& elem : contactsjarr) 1273 | { 1274 | contacts[i][0] = elem["number"].as(); 1275 | contacts[i][1] = "0"; 1276 | numBuf[i] = contacts[i][0]; 1277 | Serial.println(contacts[i][0]); 1278 | contactCount++; 1279 | i++; 1280 | } 1281 | Serial.println("json contacts loop end---------------"); 1282 | } 1283 | 1284 | File file = SD.open("/.core/call_log.json", "r"); 1285 | if(file.size() < 2) 1286 | { 1287 | Serial.println("Override"); 1288 | file.close(); 1289 | JsonArray& logjarr = jb.createArray(); 1290 | delay(10); 1291 | File file1 = SD.open("/.core/call_log.json", "w"); 1292 | logjarr.prettyPrintTo(file1); 1293 | file1.close(); 1294 | file = SD.open("/.core/call_log.json", "r"); 1295 | if(!file) 1296 | Serial.println("CALL LOG ERROR"); 1297 | } 1298 | jb.clear(); 1299 | JsonArray& logjarr = jb.parseArray(file); 1300 | file.close(); 1301 | 1302 | if(!logjarr.success()) 1303 | { 1304 | Serial.println("Error"); 1305 | } 1306 | else 1307 | { 1308 | int tempInt = 0; 1309 | for (i = 0; i < contactCount; i++) 1310 | { 1311 | /* 1312 | Serial.println("loop ins start----------------"); 1313 | Serial.println(" "); 1314 | Serial.print("i: "); 1315 | Serial.print(i); 1316 | Serial.println(" "); 1317 | */ 1318 | for (JsonObject &logelem : logjarr) 1319 | { 1320 | /* 1321 | Serial.println(" json loop ins start---------------"); 1322 | Serial.println(" "); 1323 | Serial.print(" number from log: "); 1324 | Serial.print(logelem["number"].as()); 1325 | Serial.println(" "); 1326 | Serial.print(" number from array: "); 1327 | Serial.print(contacts[i][0]); 1328 | Serial.println(" "); 1329 | */ 1330 | if (contacts[i][0] == logelem["number"].as()) 1331 | { 1332 | //Serial.println(" matches"); 1333 | tempInt = contacts[i][1].toInt(); 1334 | tempInt++; 1335 | contacts[i][1] = String(tempInt); 1336 | } 1337 | //Serial.println(" json loop ins end---------------"); 1338 | } 1339 | //Serial.println("loop ins end----------------"); 1340 | Serial.println("Contact: "); 1341 | Serial.println(contacts[i][0]); 1342 | Serial.println("Score: "); 1343 | Serial.println(contacts[i][1]); 1344 | } 1345 | } 1346 | Serial.println("SORTED BELOW THIS LINE"); 1347 | //SORT START 1348 | String temp = "", temp2 = ""; 1349 | for(i = 0; i < contactCount; i++) 1350 | { 1351 | for(j = i + 1; j < contactCount; j++) 1352 | { 1353 | if(contacts[i][1].toInt() < contacts[j][1].toInt()) 1354 | { 1355 | temp = contacts[i][1]; 1356 | temp2 = contacts[i][0]; 1357 | contacts[i][1] = contacts[j][1]; 1358 | contacts[i][0] = contacts[j][0]; 1359 | contacts[j][1] = temp; 1360 | contacts[j][0] = temp2; 1361 | } 1362 | } 1363 | } 1364 | //SORT END 1365 | ret = String(contactCount) + "|"; 1366 | for(i = 0; i < contactCount; i++) 1367 | { 1368 | ret += contacts[i][0] + "|"; 1369 | /* 1370 | Serial.println("Contact: "); 1371 | Serial.println(contacts[i][0]); 1372 | Serial.println("Score: "); 1373 | Serial.println(contacts[i][1]); 1374 | */ 1375 | } 1376 | Serial.println(ret); 1377 | return ret; 1378 | } 1379 | 1380 | --------------------------------------------------------------------------------