ESP32 CAM Support

@electronictechgreg,

Looking at the esp32 recipe you should not reach the 32k max characters while compiling but you may have some filenames over 260 characters.

Could you try changing the MAX_PATH under your Windows OS? https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation

Aurelien

I just purchased a new PC as of last night. My old laptop was failing. I will let you know how I make out once I get everything installed. Thank you for your help.

I understand that std::fmax is part of cmath, but when I look at one of your header file it references math.h instead.

I really don’t want to have to troubleshoot all your dependency files to solve this problem. I would think you might have a conflicting reference problem that most likely needs to be resolved.

If you guys don’t want to help, then I will move on to another ML application…

Thanks,
Tony

Hi @tcontrada, please understand that we’d love to help you, but it’s hard when we cannot replicate the error, either on the ESP32 or on a different development board.

We reference cmath here, also the only place where we use std::fmax: https://github.com/edgeimpulse/inferencing-sdk-cpp/blob/67f085eb39033edf80e1ea8e41f5c089b65187e3/tensorflow/lite/kernels/internal/max.h#L18

If you’d be interested you can find this file in the Arduino library folder, and replace it with:

/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_
#define TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_

#include <cmath>

namespace tflite {

inline float TfLiteMax(const float& x, const float& y) {
  return std::max(x, y);
}

}  // namespace tflite

#endif  // TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_

This will always default to std::max, but my feeling is there might be something wrong deeper so you’ll probably run into another error at a later point.

@tcontrada. If you went to the website I provided yesterday you would have seen they were talking about the same issue you are having. They edited the file “max.h” and added || defined(ARDUINO) as shown below. They did the same with min.h. This should resolve the issue that you are having.

#if defined(TF_LITE_USE_GLOBAL_MAX) defined(ZEPHYR)
|| defined(ARDUINO)
inline float TfLiteMax(const float& x, const float& y) {
return std::max(x, y);
}
#else
template
inline T TfLiteMax(const T& x, const T& y) {
return std::fmax(x, y);
}
#endif

Hi, yes that did fix the compile issue. But I have the long filename issue now.
I did the RegEdit for allowing long file names, but still get the error.
I saw the post about adding the platform.local.txt file to this folder,
C:\Users\MYUSER\AppData\Local\Arduino15\packages\arduino\hardware\mbed\1.1.4\

The problem is I don’t have an mbed folder along that path!!

Yes, I did state that I have the long file problem after the fmax fmin fix. I have yet to find a solution but my laptop died. So I will have to try with the new laptop when I get time. But aurel said he was going to look into the issue and find a solution.

The platform.local.txt solution works for Arduino Nano boards, I’ll boot a Windows OS tomorrow to check more deeply.
But you can already try this:

This should bypass the compiling issue but you might still having an issue during linking.

Aurelien

@electronictechgreg @tcontrada I missed the link @electronictechgreg added, but great! I’ll make sure we set that define on ESP32 targets in the future.

@aurel I tried as you asked.

I set LongPathsEnabled to 1 in the registry and rebooted my PC. I tried to recompile the sketch but sill get the same error.

fork/exec C:\Users\Greg\AppData\Local\Arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0/bin/xtensa-esp32-elf-gcc.exe: The filename or extension is too long.

Same here… Waiting for a fix, I hope!!

@tcontrada @electronictechgreg yep we’re looking at the issue on Windows tomorrow.

@aurel and @janjongboom. Thank you both for your help.

I tried with Visual Studio Code and Platformio just to try to see if it will compile. I don’t know much about how to use this compiler but I received the error below.

test_project_inference.h: No such file or directory

But I will wait for a solution in the mean time for the Arduino IDE. A solution wll eventually come about.

Hi @electronictechgreg,

I managed to compile under the Arduino IDE, basically putting all object files in an archive to bypass the Windows command line issue.

You can create a platform.local.txt file under the ESP32 target folder (C:\Users\MYUSER\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4) with the following content:

## Customized platform.local.txt to compile for ESP32 targets under Windows
## This recipe works around the Windows limit of 32k characters in a cmd line by calling .o files from a text file during linking
## Install: put file under your esp32 sub-directory - ie:C:\Users\MYUSER\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4
## You can also find the local arduino folder in the IDE under File -> Preferences -> see preferences.txt location in the bottom part of the window

## hooks

# create a txt file with all object file paths from libraries and sketch folders
recipe.hooks.linking.prelink.1.pattern=cmd /c dir /b /s {build.path}\sketch\*.o > {build.path}\obj_files_tmp.txt
recipe.hooks.linking.prelink.2.pattern=cmd /c "dir /b /s {build.path}\libraries\*.o >> {build.path}\obj_files_tmp.txt 2>nul & exit 0"

# replace \ by \\ in file paths (otherwise escaped by linker) and save in new txt file
recipe.hooks.linking.prelink.3.pattern=cmd /v /c "@echo off && for /f %a in ({build.path}\obj_files_tmp.txt) do (set line=%a && set line=!line:\=\\! && echo !line! >> {build.path}\obj_files.txt)"

# save object files in archive
recipe.hooks.linking.prelink.4.pattern=cmd /v /c "@echo off && for /f %a in ({build.path}\obj_files.txt) do ({compiler.path}{compiler.ar.cmd} {compiler.ar.flags} {compiler.ar.extra_flags} {build.path}\custom_lib.a %a)"

# delete txt file and archive after linking
recipe.hooks.linking.postlink.1.pattern=cmd /c del {build.path}\obj_files.txt
recipe.hooks.linking.postlink.2.pattern=cmd /c del {build.path}\custom_lib.a


## modify compile patterns (use custom_lib.a instead of object_files)
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -Wl,--start-group "{build.path}\custom_lib.a" "{archive_file_path}" {compiler.c.elf.libs} -Wl,--end-group -Wl,-EL -o "{build.path}/{build.project_name}.elf"

Let me know if that works for you.

Aurelien

Also, the patch around fmax is now live, just re-export your project as Arduino library.

You guys are amazing.

@aurel it compiled and uploaded to the target successfully. Next I will read through the documentation and run it on the device.

Thank you both very much for your help.

1 Like

Yes, I got the program to compile without errors and was able to download the static_buffer example to the ESP32 CAM.
Thanks!!

Now I need to figure out how to run the model that I created!

I created my image object recognition application, which I exported to the Arduino for the ESP32CAM,
So how do I get my data into the application?
When I run the application, I get the following message in the Arduino IDE Serial Port Monitor:
Edge Impulse standalone inferencing (Arduino)
The size of your ‘features’ array is not correct. Expected 9216 items, but had 0

Thanks…

You need to fill the features[] array with your image RGB values.

I’d suggest to proceed with following steps:

  1. Try it out with an existing image from your Edge Impulse project, you can copy the raw features from the Image section:

  1. Once it works, you can proceed with filling the features array directly from your ESP32Cam (you should capture a 96x96 pixels image) and check results for 1 image.

  2. Final step is to fill the features array dynamically in the loop() so your inference can run continuously.

Aurelien