Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flexible configuration #51

Closed
sle118 opened this issue Apr 30, 2021 · 200 comments
Closed

Flexible configuration #51

sle118 opened this issue Apr 30, 2021 · 200 comments

Comments

@sle118
Copy link

sle118 commented Apr 30, 2021

This is just a comment. @DustinWatts and the other contributors to this project. Feel free to close it.

I wanted to thank you for taking the time to build this. It was exactly what I was looking for!

I took the time to port the code to the TTGO T-Watch 2020 v1 which I happen to own. This wasn't a huge effort; the watch has the same capacitive touch controller that the project uses. A couple of notable differences are the screen resolution (smaller) as well as the onboard power management chip which needs to be told to power on in order to get the back light to work.

Just for fun, I spent a couple of hours refactoring a bit of the code, especially around how menus/screens are represented and loaded internally. I've done it in a way that would allow any number of menus to be created, each with an arbitrary number of buttons, and an arbitrary number of actions, all the while preserving the JSON format which you are currently using (for the sake of staying compatible with existing installs).

Essentially, there are now a few more classes:

  • Action: defines an individual action with its type (special keys, media keys,letters, etc) and associated values (int or char)
  • Button: defines a given button with its type (latch, standard, menu), as well as its latch status, both logos, etc. They are responsible to determine if they need to draw their content or not (based on status change, for example). Menu buttons are used to activate a different menu. For example button 1 on the home screen activates menu1. Eventually, menu buttons should be allowed in a sub menu (e.g. menu1 ->menu11, menu12 , etc. )
  • Menu: defines a group of buttons. Menus will trigger buttons to draw themselves, calculating the proper position and size on screen. The positions will be dynamically calculated at load time, based on the screen resolution and the number of buttons on a given menu.

Let me know your thoughts and if this is something which you'd like to see some day.

@DustinWatts
Copy link
Owner

@sle118 Sorry for the late response. I was very busy with selling ESP32 TouchDowns this week ;)

But this is amazing! Number 1 on my priorities list was refactoring the code in a way that it would allow for more actions. I know this is a much requested feature. So in answer to your question, i definitely like to see that! There is a branch called development. Which my idea was to try out all these new things. A branch where I don't have to be afraid that a pull request may break things. I invite you to share your code there!

@sle118
Copy link
Author

sle118 commented May 11, 2021

ok. Noted. I did quite a bit of refactoring to the code so it might take you a bit of time to adjust to the new reality ;)

I'm still in the very early stage and I just reached a clean compile with a ton of "//todo: " in the code to implement the features I had to butcher in order to start doing some surface testing.

It took me some time to adjust to the Arduino environment; I am used to the more bare bone environment provided by the ESP-IDF.

@DustinWatts
Copy link
Owner

If you have anything to share let me know! Looking forward to it :)

@sle118
Copy link
Author

sle118 commented May 11, 2021

I will start by reaching a minimum level of stability (e.g no crash/boot loop) and some basic navigation before sharing. But here's a glimpse of the FTAction class and how it leverages arrays to reduce code redundancy.

Definitions:


using namespace std;
#define MEDIA_2_VECTOR(m)  {m[0],m[1]}
namespace FreeTouchDeck {
     
    static const uint8_t ArrowsAndTab[]={KEY_UP_ARROW,KEY_DOWN_ARROW,KEY_LEFT_ARROW,KEY_RIGHT_ARROW,KEY_BACKSPACE,KEY_TAB,KEY_RETURN,KEY_PAGE_UP,KEY_PAGE_DOWN,KEY_DELETE} ;
    static const vector<vector<uint8_t>> Keys  = {  {
        MEDIA_2_VECTOR(KEY_MEDIA_NEXT_TRACK),
        MEDIA_2_VECTOR(KEY_MEDIA_PREVIOUS_TRACK),
        MEDIA_2_VECTOR(KEY_MEDIA_STOP),
        MEDIA_2_VECTOR(KEY_MEDIA_PLAY_PAUSE),
        MEDIA_2_VECTOR(KEY_MEDIA_MUTE),
        MEDIA_2_VECTOR(KEY_MEDIA_VOLUME_UP),
        MEDIA_2_VECTOR(KEY_MEDIA_VOLUME_DOWN),
        MEDIA_2_VECTOR(KEY_MEDIA_WWW_HOME),
        MEDIA_2_VECTOR(KEY_MEDIA_LOCAL_MACHINE_BROWSER),
        MEDIA_2_VECTOR(KEY_MEDIA_CALCULATOR),
        MEDIA_2_VECTOR(KEY_MEDIA_WWW_BOOKMARKS),
        MEDIA_2_VECTOR(KEY_MEDIA_WWW_SEARCH),
        MEDIA_2_VECTOR(KEY_MEDIA_WWW_STOP),
        MEDIA_2_VECTOR(KEY_MEDIA_WWW_BACK),
        MEDIA_2_VECTOR(KEY_MEDIA_CONSUMER_CONTROL_CONFIGURATION),
        MEDIA_2_VECTOR(KEY_MEDIA_EMAIL_READER)
    }};

    static const uint8_t OptionKeys[]={
        KEY_LEFT_CTRL,
        KEY_LEFT_SHIFT,
        KEY_LEFT_ALT,
        KEY_LEFT_GUI,
        KEY_RIGHT_CTRL,
        KEY_RIGHT_SHIFT,
        KEY_RIGHT_ALT,
        KEY_RIGHT_GUI        
    };
    static uint8_t FunctionKeys[] = {
        KEY_F1,
        KEY_F2,
        KEY_F3,
        KEY_F4,
        KEY_F5,
        KEY_F6,
        KEY_F7,
        KEY_F8,
        KEY_F9,
        KEY_F10,
        KEY_F11,
        KEY_F12,
        KEY_F13,
        KEY_F14,
        KEY_F15,
        KEY_F16,
        KEY_F17,
        KEY_F18,
        KEY_F19,
        KEY_F20,
        KEY_F21,
        KEY_F22,
        KEY_F23,
        KEY_F24                
        };
    static uint8_t Helpers[] = {
        KEY_F1,
        KEY_F2,
        KEY_F3,
        KEY_F4,
        KEY_F5,
        KEY_F6,
        KEY_F7,
        KEY_F8,
        KEY_F9,
        KEY_F10,
        KEY_F11    
        };        
    static const vector<vector<uint8_t>> Combos = {{
        {KEY_LEFT_CTRL,KEY_LEFT_SHIFT},
        {KEY_LEFT_ALT,KEY_LEFT_SHIFT},
        {KEY_LEFT_GUI,KEY_LEFT_SHIFT},
        {KEY_LEFT_CTRL,KEY_LEFT_GUI},
        {KEY_LEFT_ALT,KEY_LEFT_GUI},
        {KEY_LEFT_CTRL,KEY_LEFT_ALT},
        {KEY_LEFT_CTRL,KEY_LEFT_ALT,KEY_LEFT_GUI},
        {KEY_RIGHT_CTRL,KEY_RIGHT_SHIFT},
        {KEY_RIGHT_ALT,KEY_RIGHT_SHIFT},
        {KEY_RIGHT_GUI,KEY_RIGHT_SHIFT},
        {KEY_RIGHT_CTRL,KEY_RIGHT_GUI},
        {KEY_RIGHT_ALT,KEY_RIGHT_GUI},
        {KEY_RIGHT_CTRL,KEY_RIGHT_ALT},
        {KEY_RIGHT_CTRL,KEY_RIGHT_ALT,KEY_RIGHT_GUI}
    }};

and the embryo of the execute method

void FTAction::Execute()
  {
      Serial.println("[INFO]: BLE Keyboard action received");
      switch (Type)
      {
          case ActionTypes::NONE:
          break;
          
          case ActionTypes::DELAY:
              delay(value);
          break;
          case ActionTypes::ARROWS_AND_TAB:
              bleKeyboard.write(ArrowsAndTab[value-1]);
          break;
          case ActionTypes::MEDIAKEY:
              for(auto kp : Keys[value-1])
              {
                  bleKeyboard.write(kp);
              }
              
          break;
          case ActionTypes::LETTERS:
          case ActionTypes::SPECIAL_CHARS:
              bleKeyboard.print(symbol);
          break;
          case ActionTypes::OPTIONKEYS:
              if(value-1 <sizeof(OptionKeys)/sizeof(uint8_t))
              {
                  bleKeyboard.press(OptionKeys[value-1]);
              }
              else 
              {
                  bleKeyboard.releaseAll();
              }
          break;
          case ActionTypes::FUNCTIONKEYS:
              bleKeyboard.press(FunctionKeys[value-1]);
          break;
          case ActionTypes::NUMBERS:
              bleKeyboard.print(value);
          break;

          case ActionTypes::COMBOS:
              for(auto k  : Combos[value])
              {
                  bleKeyboard.press(k);
              }
          break;
          case ActionTypes::HELPERS:
              if(generalconfig.modifier1 != 0){
                  bleKeyboard.press(generalconfig.modifier1);
              }
              if(generalconfig.modifier2 != 0){
                  bleKeyboard.press(generalconfig.modifier2);
              }
              if(generalconfig.modifier3 != 0){
                  bleKeyboard.press(generalconfig.modifier3);
              }
              bleKeyboard.press(Helpers[value-1]);
              bleKeyboard.releaseAll();
          break;
          case ActionTypes::MENU:
          break;
          case ActionTypes::LOCAL:
              switch ((LocalActionTypes)value)
              {
              case LocalActionTypes::ENTER_CONFIG:
                  /* code */
                  break;
              case LocalActionTypes::BRIGHTNESS_DOWN:
                  if (ledBrightness > 25)
                  {
                      ledBrightness = ledBrightness - 25;
                      ledcWrite(0, ledBrightness);
                  }                
              break;
              case LocalActionTypes::BRIGHTNESS_UP:
                  if (ledBrightness < 230)
                  {
                      ledBrightness = ledBrightness + 25;
                      ledcWrite(0, ledBrightness);
                  }
              break;
              case LocalActionTypes::SLEEP:
                  if (generalconfig.sleepenable)
                  {
                      generalconfig.sleepenable = false;
                      Serial.println("[INFO]: Sleep disabled.");
                  }
                  else
                  {
                      generalconfig.sleepenable = true;
                      Interval = generalconfig.sleeptimer * 60000;
                      Serial.println("[INFO]: Sleep enabled.");
                      Serial.print("[INFO]: Timer set to: ");
                      Serial.println(generalconfig.sleeptimer);
                  }                
              break;
              default:
                  break;
              }
          break;
      
      default:
          break;
      }
      
  }

I have implemented a std::queue which receives actions. For example, pressing a button will result in a new action being inserted in the queue. Then the queue is processed in the loop()

  while (!Queue.empty())
  {
    
    ResetSleep();
    Queue.front().Execute();
    Queue.pop();
  }

@DustinWatts
Copy link
Owner

So far that is looking great!

@sle118
Copy link
Author

sle118 commented May 11, 2021

I'm thinking of implementing something similar to AutoHotkey (a reduced set to begin with) to handle sending keypresses:
https://www.autohotkey.com/docs/commands/Send.htm

This would be a complementary method to the ones that are currently implemented so backwards compatibility is preserved.

@coryb
Copy link

coryb commented May 12, 2021

I missed this issue, seems like we are working on similar problems. I just created PR #52 that makes the menus sizing configurable, not sure how incompatible this change will be with the work you are doing. I didnt touch much of the action logic, so maybe we can use the work you have done there? Or if your code is in a good state we can cancel my PR and go with your work?

@sle118
Copy link
Author

sle118 commented May 12, 2021

Well, this is annoying; it looks like the Arduino flavor of the esp-idf is stuck in the past and it's missing several of the newer c++ std features. For instance, there's no std::unique_ptr to reduce the memory footprint of vectors, lists, queues, etc. I'll see how I can work around that, given that Arduino has a broader reach with tinkerers.

@DustinWatts
Copy link
Owner

I missed this issue, seems like we are working on similar problems. I just created PR #52 that makes the menus sizing configurable, not sure how incompatible this change will be with the work you are doing. I didnt touch much of the action logic, so maybe we can use the work you have done there? Or if your code is in a good state we can cancel my PR and go with your work?

Maybe we can keep that PR open and integrate it to what @sle118 is working on?

@sle118 That is annoying, off course for a pre-build binary this wouldn't matter. But I like to keep the whole source accessible for everyone to tinker with as you stated.

I Appreciate both your work!

@sle118
Copy link
Author

sle118 commented May 12, 2021

It is a rather complete refactoring of the effort and unlikely to be compatible with existing pull requests. I will most likely push the changes to my own repo (I forked this repo) so everyone can have a look.

@coryb
Copy link

coryb commented May 12, 2021

I will try out your fork when you get it pushed to see how it compares to mine, having just gone through all this I am at least pretty familiar with the codebase now :) So maybe I can help out.

@sle118
Copy link
Author

sle118 commented May 13, 2021

I'm using a TTGO T-Watch for testing and I have basic navigation, pressing/releasing, and latch working albeit still with some glitches with transparency, which I am just starting to analyse in the original code base. Next I'm going to implement the configuration menu, for which actions are already implemented.

I have ordered the following, which is going to be easier to debug using JTAG than the watch:
http://www.makerfabs.com/esp32-3.5-inch-tft-touch-capacitive-with-camera.html

I don't need the camera, but it was cheap enough to try out.

Once I am satisfied with the results, I'll push the code to my repo. @coryb I don't plan on fine tuning all the display code, but it will be in a sufficiently good enough state for you to step in if you'd like.

Down the road, I am seriously thinking of merging the core functionality with the platform I created for a Logitech media (aka squeezebox) music streamer which I developed with friends. You can see for yourself here:
https://github.com/sle118/squeezelite-esp32

This provides a number of features:

  • full OTA capabilities from releases created on GitHub with actions or through web upload
  • Wi-Fi manager which sets up an access point to allow initial configuration of the network
  • key value pair configuration management that is thread safe
  • ability to fully use external memory; using psram from the wrover (if equipped) would dramatically improve screen refresh time
  • flexible UI which can be used to configure various system options like gpio's, audio output type (i2s or PWM chiptune), etc, making it possible for a single release binary to target various hardware platforms
    -etc

As for the UI engine, littlevgl could be an interesting component to consider.

Of course this would be a departure from the current full Arduino based approach, with bare but unleashed esp-idf. However, the Arduino platform can still be used (as a component), which means existing Arduino libraries would still work.

Anyhow, I'm just dumping some high level ideas here. I don't expect that this project would follow through such a radical change, but nevertheless I'll always keep the code available for anyone to play with.

@danielhunt
Copy link

As it happens I have also been working on making the menu system more flexible having just received my device in the post yesterday.

My own version is very similar to what @coryb has come up with - but as I am not a true C++ dev it's far less neat.

I might be interested in helping out on the frontend side of things once you have all settled on a valid codebase to run with.
Right now, #52 looks like it will be a good starting point but if @sle118 has completely overhauled the codebase I'm not sure there's much point in moving forward on anything yet.

@sle118
Copy link
Author

sle118 commented May 13, 2021

This is getting real funny!

Since I do not own the hardware, I will leave it to the group to decide which way they want to go. I have limited bandwidth and definitely cannot resolve all the issues that I have introduced with my changes!

There are many areas that I wanted to tackle but didn't get to.

@sle118
Copy link
Author

sle118 commented May 14, 2021

allright. I made good progress tonight and had navigation up and running. I have pushed whatever I have so far here
https://github.com/sle118/FreeTouchDeck

Note: I'm using VSCode with the Arduino extension, rather than the "pure" Arduino IDE.
Also Note: This WILL crash on you; after getting navigation right, I decided to start making some performance improvements. The first move was to cache logos (bitmaps) in PSRAM and render from PSRAM. Unfortunately, this was a bold change and I haven't yet come to resolving the crash. I'm pushing the changes so @danielhunt @coryb and @DustinWatts can have a look and see if you like what you see.

note that this is only addresses PART of the backend and there's still quite a bit of change to be made to de-couple the code from the hardware but it's a good start (as far as I can tell).

Please have a look and comment.

thank you!

@danielhunt
Copy link

danielhunt commented May 14, 2021

Please have a look and comment.

The diff between your code and master is so far beyond my abilities to understand 😢 :D

@DustinWatts
Copy link
Owner

Please have a look and comment.

thank you!

No thank you! :) This is a massive change and it looks great so far! I have to take some time going through it but this weekend I hope to have some time and will try it out (accepting crashes ;) ). But I like where you are going.

@sle118
Copy link
Author

sle118 commented May 14, 2021

right now it does crash on start because of my last minute change, leveraging PSRAM if present. I'll try to remediate so you have a somewhat better experience. I am not sure if it will compile on the Arduino IDE, but I think it should, given that VSCode calls it in the backend when building.... it's super super slow compared to native ESP-IDF v4.0, which leverages cMake + Ninja to speed up the build.

@sle118
Copy link
Author

sle118 commented May 14, 2021

Please have a look and comment.

The diff between your code and master is so far beyond my abilities to understand 😢 :D

Don't read with the old code in mind; read it as if you were trying to understand another piece of code.

@sle118
Copy link
Author

sle118 commented May 14, 2021

One more note here. I think I have found out the door cause of the crashes. I will have to overwrite the new operator to allocate memory in psram.

Can anyone confirm that the original hardware has a wrover or psram chip on board?

Edit: well well... I just found that the touch down hardware doesn't have the luxury of psram. So I'm going to have to rewrite portions of the code to setup arrays in the code space instead of dynamically allocated structures as I'm doing right now.

I should also receive my new test board, which will allow me to debug with JTAG instead of fishing for bugs using serial output.

Thank you for your patience!

@sle118
Copy link
Author

sle118 commented May 18, 2021

Update: I just pushed some commits which restore basic navigation. It is no longer crashing! Note that I lost border drawing around buttons and latch mode too. This shouldn't be a major thing to resolve. It turns out using std::vector wasn't a good idea since it stores all data in a contiguous memory location. This means every time I was pushing a new element, the system had to reallocate a new block of memory, possibly resulting in memory fragmentation.

@DustinWatts
Copy link
Owner

This is going amazing @sle118 ! Can you DM me your contact details? dustin_watts@yahoo.com I can arrange a ESP32 TouchDown for you so you have the exact hardware.

@danielhunt
Copy link

@sle118 while building this I get the following error:

FreeTouchDeck:360:43: error: 'CONFIG_ARDUINO_LOOP_STACK_SIZE' was not declared in this scope
   Serial.printf("Main Task size is %d\r", CONFIG_ARDUINO_LOOP_STACK_SIZE);

I presume I need to have another library or something for this to work?

@sle118
Copy link
Author

sle118 commented May 18, 2021

@danielhunt I will push some more changes today. Some minor changes were done, but now a "back button" action is possible. Useful for multi level menus!

Edit: changes pushed. Let me know if they compile now.

@DustinWatts
Copy link
Owner

@sle118

Got a few warnings (mostly unused variable, so no big deal). But did get an error. Line 284 of FTAction.cpp:

if (SetActiveScreen)
            {
                ESP_LOGD(module, "Selecting menu %s\n", symbol);
                SetActiveScreen(symbol);
            }

will always evaluate as true. So, just removing the if statement and it compiles. Next step is to actually upload to see it in action :)

@sle118
Copy link
Author

sle118 commented May 19, 2021

Which Arduino environment are you "officially using"? I'll make sure I compile it there first before committing anything. I've been using vscode with the Arduino extension because it is far better than the basic Arduino IDE and because I'm used to it, but I read that the beta Arduino environment is an improvement over the old one

@briight
Copy link

briight commented Jun 16, 2021

ok done that got a long file now
just looking through it

[I][FreeTouchDeck.ino:155] setup(): Starting system.
[I][Storage.cpp:125] InitFileSystem(): Initializing storage SPIFFS
[I][Storage.cpp:135] InitFileSystem(): Using File system SPIFFS.
[I][Storage.cpp:120] InitFileSystem(): Reached the end of the file systems list
[I][ConfigLoad.cpp:265] loadConfig(): Loading configuration from file name: /config/general.json

is the only storage i can find

@sle118
Copy link
Author

sle118 commented Jun 16, 2021

Ah!

Ok. You have to specify the GPIO for the SD card reader. For the TouchDown, it is #define SDDAT3 25 in the UserConfig.h file.

Could you remind me which board you are using?

@briight
Copy link

briight commented Jun 16, 2021

DOIT ESP32 DEVKIT V1 Board
u know how long i was looking for #define SDDAT3 25
using the search and didnt find it =(

didnt work is there anywhere else i need to define the GPIO the the sd card?

@DustinWatts
Copy link
Owner

didnt work is there anywhere else i need to define the GPIO the the sd card?

In UserConfig.h try adding #define SSDAT3 26 under:

#elif defined(ESP32DEVKIT)
#define SCREEN_ROTATION 1
#define FLIP_TOUCH_AXIS
#define INVERSE_Y_TOUCH
#define touchInterruptPin GPIO_NUM_27

So it becomes:

#elif defined(ESP32DEVKIT)
#define SCREEN_ROTATION 1
#define FLIP_TOUCH_AXIS
#define INVERSE_Y_TOUCH
#define touchInterruptPin GPIO_NUM_27
#define SSDAT3 26

Save and reupload the code...

@briight
Copy link

briight commented Jun 16, 2021

i just found this already testing
=P

@briight
Copy link

briight commented Jun 16, 2021

that why i couldnt find it wasnt in the board section i am using

@DustinWatts
Copy link
Owner

Could you remind me which board you are using?

The ESP32 DevKitC and TFT combiner board I made uses some slightly different pins. On that board SSDAT3 is on GPIO26.

@briight
Copy link

briight commented Jun 16, 2021

got the sd card working now

images load abit slow from menu to menu about 2 seconds for all to be loaded 3x4

@sle118
Copy link
Author

sle118 commented Jun 16, 2021

well, I decided to goo full blown on polymorphism for the image handlers, but I have to say this sort of things is easier to do in c# than in c++, especially because my advanced c++ knowledge is rather rusty. So jpg will take a bit of time!

@briight
Copy link

briight commented Jun 17, 2021

so i added another menu to my sdcard almost the same as my first one with a few keys changed same icons the only icon changed was the one on the main screen
it loads up the menus on the main screen fine, once in one of the menus the buttons are draw but no images and has to be restarted
in the serial monitor i get

[E][ImageWrapper.cpp:346] Draw(): Error allocating 12540 bytes of buffer for image drawing!

so i tryed uploading it straght to the eps32 and its fine

@sle118
Copy link
Author

sle118 commented Jun 17, 2021

so i added another menu to my sdcard almost the same as my first one with a few keys changed same icons the only icon changed was the one on the main screen
it loads up the menus on the main screen fine, once in one of the menus the buttons are draw but no images and has to be restarted
in the serial monitor i get

[E][ImageWrapper.cpp:346] Draw(): Error allocating 12540 bytes of buffer for image drawing!

so i tryed uploading it straght to the eps32 and its fine

Have a look at the UserConfig.h file. There you will see the following line #define BITMAP_BUFFER_FREE_RAM_PCT 0.30. this is the percentage of memory that is allowed to be allocated for image drawing buffering. I might have been too aggressive here. Please try 0.15 and see if it helps.

The fact that it works from the internal storage is likely because reading from the SD card takes some additional resources.

@sle118
Copy link
Author

sle118 commented Jun 17, 2021

Could you remind me which board you are using?

The ESP32 DevKitC and TFT combiner board I made uses some slightly different pins. On that board SSDAT3 is on GPIO26.

Perhaps this should be called out specifically in the UserConfig.h file as #ifdef TFTCOMBINER or something along these lines to make it a separate "preconfigured" section?

@briight
Copy link

briight commented Jun 17, 2021

i dont use a tft combiner , i also have other thing connected volume sliders on gpio 39,34,35,32,33,25

@sle118
Copy link
Author

sle118 commented Jun 17, 2021

i dont use a tft combiner , i also have other thing connected volume sliders on gpio 39,34,35,32,33,25

Neat! Did you go and implement AVRCP to get absolute volume controls? How do you keep the sliders levels in sync with the host's volume levels?

@briight
Copy link

briight commented Jun 17, 2021

i put another project called deej into ftd send analog data over bluetooth to deej program that hooks into the windows volume thingy carnt remember what its called now

@sle118
Copy link
Author

sle118 commented Jun 17, 2021

I just wanted to let everyone know that JPG files are now supported and will be the de-facto format going forward. I did replace all built in icons with JPG files, so you will need to adjust your personal menus.

Also, SD card init procedure will now show progress on the TFT screen.

I'll push changes when I have done sufficient testing

@sle118
Copy link
Author

sle118 commented Jun 18, 2021

I just pushed the changes. JPG is now supported FROM SPIFFS (internal storage). Don't try on SD card yet. SD support needs some attention and I'm not sure if I'm having issues because of a faulty card or because of the code. So for now stay on SPIFFS ;)

@sle118
Copy link
Author

sle118 commented Jun 19, 2021

for anyone still following this story, I have just pushed what looks like a somewhat good starting point for SD card support INCLUDING JPG !

Using JPG as opposed to using bmp means there's less data to transfer during drawing of screens, which somewhat compensates for the fact that SD cards in general are slower.

I still need to figure out a way to gracefully handle the "unexpected removal" of the card during use, but that'll come!

Hoping you all enjoy the added simplicity of editing the configuration straight from the SD card!

Comments are welcomed

Edit: I spoke too soon. I'm still getting a crash and I'm not sure why. On the regular esp-idf, I would enable core dump to figure out what's wrong, but I doubt this is an option on the Arduino platform.

@sle118
Copy link
Author

sle118 commented Jun 19, 2021

I pushed another set of changes today. These are mostly geared towards getting more stability out of the SD card. I did identify one leak and I'm hoping fixing it will have helped a bit.

Worst case, there is another memory saving I can do, which is to not initialize the spiffs when SD card is detected

@sle118
Copy link
Author

sle118 commented Jun 23, 2021

So for anyone not following on discord, I just pushed some changes

  • Lower memory footprint
  • Audio now has an ERROR signal
  • To play it safe with a smaller stack space, saving configuration is now done in a separate task that can be queued
  • ArduinoJson is no longer used.
  • Configuration now has a complete API for changing values, saving, etc
  • A few backend endpoints were added to the web server: menus.json, useractions.json, keynames.json should help with UI development
  • Web server uses cJSON now instead of ArduinoJSON
  • New storage functions to copy files across storage devices, or to copy a file to a new file name, etc
  • A home screen menu definition can now include a keyboard action. When pressing the menu button, actions will be executed and the menu will be activated. This could be used, for example to launch an application and then open the corresponding sub menu
  • Stability improvements in the ImageCache layer
  • Other general simplifications to code. For example buttons have a more streamlined way of drawing themselves
  • Activating a menu no longer forces the inline redraw. Instead, buttons are invalidated and drawn on the next pass of the regular menu draw execution

To reduce memory footprint, I also opened a pull request
DustinWatts/ESP32-BLE-Keyboard#2

@sle118
Copy link
Author

sle118 commented Jun 23, 2021

And by the way, I'm very close to calling it finish. There's a few renames of variables and methods to do, but overall I'm happy with the current state as I think it has reached a stable enough state.

Next I plan on experimenting with the Arduino cli to build for various targets using the GitHub workflows. Being able to pass extra defines on the command line means even the TFT library can be configured without having to mess with include files. I've built something similar on a different repository, except not for Arduino

@briight
Copy link

briight commented Jun 23, 2021

#define SDDAT3 25 need to be added to the devkit part =)

/* Using the ESP32 DevKit with a screen module */
#elif defined(ESP32DEVKIT)
#define SCREEN_ROTATION 1
#define FLIP_TOUCH_AXIS
#define INVERSE_Y_TOUCH
#define touchInterruptPin GPIO_NUM_27
#define SDDAT3 25
#else
#error("Unsupported platform")
#endif

@sle118
Copy link
Author

sle118 commented Jun 23, 2021

At this point, you might want to fork my repo and submit pull requests. Eventually, I think @DustinWatts would want to merge my code and make it official, so it is well spent efforts ;)

@sle118
Copy link
Author

sle118 commented Jun 24, 2021

Well I decided to finally take the plunge with a pull request. I have a couple more renames I'd like to do, but I am fairly certain that the current state of my code reached a state that is stable enough and yet offers very scalable user expansion capabilities with user actions. So there's the beginning of my contribution to this project : #64

Once this gets merge, let's close this issue and continue the discussion on Discord

DustinWatts added a commit that referenced this issue Jun 24, 2021
@sle118
Copy link
Author

sle118 commented Jun 24, 2021

Since the changes were merged, I'll go ahead and close this. Anyone interested, I'll be hanging around on Discord

@sle118 sle118 closed this as completed Jun 24, 2021
@DustinWatts
Copy link
Owner

Amazing work!

@briight
Copy link

briight commented Jun 24, 2021

prob a good idea to wait for a easy way to config the menu's, been using urs for a while now and i love it
thank you =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants