Skip to content

The Preferences function of ESP32-S3-WROOM-1U-N4R8 in USBHID mode does not work. #11284

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

Open
1 task done
Ccccraz opened this issue Apr 23, 2025 · 9 comments
Open
1 task done
Labels
Status: Awaiting Response awaiting a response from the author

Comments

@Ccccraz
Copy link

Ccccraz commented Apr 23, 2025

Board

ESP32-S3-WROOM-1U-N4R8

Device Description

Image

For reference, below is my board.json configuration, and I believe the flash configuration here should be correct:

{
  "build": {
    "arduino":{
      "ldscript": "esp32s3_out.ld",
      "memory_type": "qio_opi"
    },
    "core": "esp32",
    "extra_flags": [
      "-DBOARD_HAS_PSRAM",
      "-DARDUINO_ESP32S3_DEV",
      "-DARDUINO_USB_MODE=0",
      "-DARDUINO_RUNNING_CORE=1",
      "-DARDUINO_EVENT_RUNNING_CORE=1"
    ],
    "f_cpu": "240000000L",
    "f_flash": "80000000L",
    "flash_mode": "qio",
    "hwids": [
      [
        "0x303A",
        "0x1001"
      ]
    ],
    "mcu": "esp32s3",
    "variant": "esp32s3"
  },
}

I don't know where this problem comes from? Maybe it's the USB? Or I made some stupid mistakes in the code that I didn't notice.

Hardware Configuration

GPIO19, GPIO20 directly used as USB signal lines

Version

latest stable Release (if not listed below)

IDE Name

VScode

Operating System

Windows 11

Flash frequency

80Mhz

PSRAM enabled

yes

Upload speed

460800

Description

I am developing a HID project based on the ESP32S3 using platformIO. Everything is going smoothly. However, today when I tried to use Preferences.h to persist some data, I found that I couldn’t do it.

I found a similar issue at #8429, and later I confirmed that the flash of the ESP32-S3-WROOM-1U-N4R8 I am using is operating in qio mode, so the solution in this issue does not work to me.

Sketch

AT8236HID::AT8236HID(uint8_t in1_pin, uint8_t in2_pin, float speed)
    : _in1_pin(in1_pin), _in2_pin(in2_pin), _speed(constrain(speed, 0.0f, 1.0f))
{
    pump_prefs.begin(pref_namespace, true);

    if (!pump_prefs.isKey(pref_device_id))
    {
        pump_prefs.end();
        pump_prefs.begin(pref_namespace, false);
        pump_prefs.putUInt(pref_device_id, 2);
        pump_prefs.end();
        pump_prefs.begin(pref_namespace, true);
    }

    _device_id = pump_prefs.getUInt(pref_device_id);
    pump_prefs.end();
}

auto AT8236HID::_onSetFeature(uint8_t report_id, const uint8_t *buffer, uint16_t len) -> void
{
    feature_t feature{};
    memcpy(&feature, buffer, sizeof(feature));

    if (feature.device_id != _device_id)
        return;

    _device_id = feature.new_device_id;

    pump_prefs.begin(pref_namespace, false);
    pump_prefs.putUInt(pref_device_id, _device_id);
    pump_prefs.end();
}


I initialize them here:

    const char *pref_namespace{"app-name"};
    const char *pref_device_id{"device_id"};
    Preferences pump_prefs{};

Debug Message

In USBHID mode, I don't know how to obtain the debug output.

Other Steps to Reproduce

I'm trying to build a minimal example to reproduce this problem.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@Ccccraz Ccccraz added the Status: Awaiting triage Issue is waiting for triage label Apr 23, 2025
@Jason2866
Copy link
Collaborator

Please post your complete platformio.ini

@Jason2866 Jason2866 added Status: Awaiting Response awaiting a response from the author and removed Status: Awaiting triage Issue is waiting for triage labels Apr 23, 2025
@Ccccraz
Copy link
Author

Ccccraz commented Apr 23, 2025

Hi thanks for your follow up, here is my platformio.ini

[env:simia]
platform = espressif32
board = waveshare_esp32s3_zero
framework = arduino
lib_deps = 
	ccccraz/simia_embedded@^0.0.2
	mathertel/OneButton@^2.6.1

it is pretty simple.

I've just built a simple usbcdc environment for testing. I found that there is an error when I use preferences in the class, but there is no problem when I only use it in setup() or loop(). I'm checking if this is a known issue.

@lbernstone
Copy link
Contributor

lbernstone commented Apr 23, 2025

I think you want flash_mode to be dio even when memory_type is qio_opi. This behavior of the flash is a symptom of memory misconfiguration.

@Ccccraz
Copy link
Author

Ccccraz commented Apr 23, 2025

Hi, guys. Although I haven't figured out this problem yet, I fixed my problem by moving all the preferences objects out of the class and using them directly in the setup() and loop()

@Ccccraz
Copy link
Author

Ccccraz commented Apr 23, 2025

I think you want flash_mode to be dio even when memory_type is qio_opi. This behavior of the flash is a symptom of memory misconfiguration.

Oh, thank you very much for your advice. I'll do a test quickly.

@lbernstone
Copy link
Contributor

Hi, guys. Although I haven't figured out this problem yet, I fixed my problem by moving all the preferences objects out of the class and using them directly in the setup() and loop()

Make sure that you aren't losing track of the handle in localizing. IE, don't try to re-use a handle/object from outside, keep the nvs handle (aka, the state) completely internal to the class.

@Ccccraz
Copy link
Author

Ccccraz commented Apr 23, 2025

I think you want flash_mode to be dio even when memory_type is qio_opi. This behavior of the flash is a symptom of memory misconfiguration.

Hi! If my understanding is correct, I modify my board.json to:

{
  "build": {
    "arduino": {
      "ldscript": "esp32s3_out.ld",
      "memory_type": "qio_opi"
    },
    "core": "esp32",
    "extra_flags": [
      "-DBOARD_HAS_PSRAM",
      "-DARDUINO_ESP32S3_DEV",
      "-DARDUINO_USB_CDC_ON_BOOT",
      "-DARDUINO_USB_MODE=0",
      "-DARDUINO_RUNNING_CORE=1",
      "-DARDUINO_EVENT_RUNNING_CORE=1"
    ],
    "f_cpu": "240000000L",
    "f_flash": "80000000L",
    "flash_mode": "dio",
    "hwids": [
      [
        "0x303A",
        "0x1001"
      ]
    ],
    "mcu": "esp32s3",
    "variant": "esp32s3"
  },
}

then I create a very sample class:

#ifndef TMP_H
#define TMP_H

#include <Preferences.h>

class Tmp
{
  private:
  public:
    Preferences tmp_prefs;
    const char *tmp_prefs_name = "tmp-app";
    const char *tmp_prefs_key = "tmp";

    uint32_t value{0};

    Tmp();
    void getTmp();
    ~Tmp() = default;
};

Tmp::Tmp()
{
    tmp_prefs.begin(tmp_prefs_name, false);
    tmp_prefs.putUInt(tmp_prefs_key, 100);
    tmp_prefs.end();
}

inline void Tmp::getTmp()
{
    tmp_prefs.begin(tmp_prefs_name, true);
    value = tmp_prefs.getUInt(tmp_prefs_key, 10);
    tmp_prefs.end();
}

#endif // TMP_H

and a main func:

#include <Arduino.h>

#include "USB.h"
#include "tmp.h"

USBCDC USBSerial;

Tmp tmp{};

void setup()
{
    Serial.begin(115200);
    Serial.setDebugOutput(true);

    tmp.getTmp();

    USBSerial.begin();
    USB.begin();
}

void loop()
{
    while (true)
    {
        USBSerial.println(tmp.value);
        delay(1000);
    }
}

The verification logic here is: tmp is written with 100 during initialization, and tmp.getTmp() will modify tmp.value to the value written during initialization. So in theory, I should be able to see 100 in the serial monitor. However, the final result is 60, which is the value I wrote during the last test:

Image

As you've just added, in this example, the handle of preferences should always be kept internally.

This test code was tested in a header-only environment. I also tested it in a normal environment and removed all the "inline" keywords, and the results were the same.

@Jason2866
Copy link
Collaborator

Jason2866 commented Apr 23, 2025

The entry flash_modewill be auto corrected if the entry memory_type is set
See https://github.com/pioarduino/platform-espressif32/blob/b5f52780f89ec1055f91ece174cd2e9be02d06dd/builder/main.py#L90-L108

The boards json is fine as it is. NOT the reason for issues. BUT with your platformio.ini you are not using latest actual Arduino core.
change to:

[env:simia]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip
board = waveshare_esp32s3_zero
framework = arduino
lib_deps = 
	ccccraz/simia_embedded@^0.0.2
	mathertel/OneButton@^2.6.1

@Ccccraz
Copy link
Author

Ccccraz commented Apr 23, 2025

The entry flash_modewill be auto corrected if the entry memory_type is set See https://github.com/pioarduino/platform-espressif32/blob/b5f52780f89ec1055f91ece174cd2e9be02d06dd/builder/main.py#L90-L108

The boards json is fine as it is. NOT the reason for issues. BUT with your platformio.ini you are not using latest actual Arduino core. change to:

[env:simia]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip
board = waveshare_esp32s3_zero
framework = arduino
lib_deps = 
	ccccraz/simia_embedded@^0.0.2
	mathertel/OneButton@^2.6.1

Ok cool! I will test it tomorrow morning! thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting Response awaiting a response from the author
Projects
None yet
Development

No branches or pull requests

3 participants