Skip to content

ports/esp32/boards: Add support for popular ESP32_CAM boards. #13253

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

Closed
wants to merge 15 commits into from
Closed

ports/esp32/boards: Add support for popular ESP32_CAM boards. #13253

wants to merge 15 commits into from

Conversation

gitcnd
Copy link

@gitcnd gitcnd commented Dec 21, 2023

Tested working boards definition for ESP32 CAM boards.
Includes build instructions, image, and sample working camera-capture micropython demo script.


@projectgus added the following information:

Has matching micropython-media PR: micropython/micropython-media#58

Chris added 4 commits December 22, 2023 08:42
Signed-off-by: Chris <cryptophoto@gmail.com>
Signed-off-by: Chris <cryptophoto@gmail.com>
Signed-off-by: Chris <cryptophoto@gmail.com>
Signed-off-by: Chris <cryptophoto@gmail.com>
@gitcnd gitcnd changed the title Add support for popular ESP32_CAM boards ports/esp32/boards: Add support for popular ESP32_CAM boards. Dec 21, 2023
@jimmo
Copy link
Member

jimmo commented Jan 8, 2024

I've never done a pull request before - let me know if I've got something wrong.

@gitcnd You shouldn't need to close and reopen a PR to make changes (ref #13247) -- see https://github.com/jimmo/git-and-micropython for some tips.

It looks like you've copied the generic board definition which includes variants which are not necessary for this board. You should be able to simplify this considerably by removing the variants (from board.json and mpconfigboard.cmake) as well as the additional sdkconfig files.

Thanks for providing the example. Rather than referencing third-party tools (ampy,mipyshell), can you please just provide an example using mpremote. I suggest just making the capture method take the arguments explictly:

def capture(filename, size, quality):
   ...

Also the board photo referenced by board.json needs to be submitted as a PR to github.com/micropython/micropython-media

@gitcnd
Copy link
Author

gitcnd commented Jan 8, 2024

There are 2 kinds of esp32 camera boards I've seen (the super cheap aliexpress ones, and the ones which come bundled with robots) which have different features. it's probably best to keep the variants so this same port works for both boards.

I don't have time to refactor my example - it's an example - if people need to build stuff or use different tools, it's still way better than nothing and a great place to start from. I suggest leaving it alone: it's tested and works great.

@gitcnd
Copy link
Author

gitcnd commented Jan 8, 2024

Also - since you told me that jpegs do not belong here - I removed the one which was there and put it into micropython-media which seems to have broken something else. Hopefully you know how to fix that, since it was your rule I followed ?

@gitcnd
Copy link
Author

gitcnd commented Jan 15, 2024

Is someone going to merge my work before it goes stale?
Note that the "failed" checks above are not real failures - the commands aborted instead of running properly (build system failure - not a PR error)

@robert-hh
Copy link
Contributor

The commit message format error is a real one, and it seems that the PR removes an image file from the docs which is still referred,

@gitcnd
Copy link
Author

gitcnd commented Jan 15, 2024

I followed the rule about where the images need to be.
Whoever wrote that doc needs to fix it to point it to the place where you told me the images need to go.

@robert-hh
Copy link
Contributor

Images for a board which is used by the site for firmware images have to go into the micropython-media repository. Images which are referred by the documentation have to be in the micropython/docs file tree in the micropython repository.

@projectgus
Copy link
Contributor

projectgus commented Jan 15, 2024

Is someone going to merge my work before it goes stale?

There's two outstanding items, as per @jimmo's review from last week:

  1. Removing variants that aren't necessary for this board. If these variants do map to real boards then this needs to be clear in the PR as well.
  2. Updating the example to use the standard (supported) MicroPython tools. It's important that MicroPython examples are consistent where possible and use tools that we support in the future. Examples using other third party tools are better published elsewhere, rather than merged into MP itself.

EDIT: Plus rebasing to update the commit messages, and please update the path in the docs so it will find the file after the micropython-media PR is merged.

If you're prepared to make those changes, please go ahead and then please be patient while someone gets back to you. Even with everything perfect it can take some time for a PR to be merged, so please expect that.

@mattytrentini
Copy link
Contributor

The more significant issue is that I don't think we can accept git clone's - manually entered - to pull in dependencies. Currently the only mechanism to add dependencies is with submodules (see GIT_SUBMODULES) - and they are added per-port.

With this board definition, the build system will not add the camera driver dependency.

Copy link

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS

Signed-off-by: Chris <cryptophoto@gmail.com>
@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

I think is is grossly unfair to force me to add new arbitrary features to my already-working example script. If you want to pay me for my time to add this for you - no problem - otherwise - "don't look a gift horse in the mouth". It's totally fine as-is.

The variants need to stay, so this works for the freenove cam boards as well.

The doc seems wrong - showing someones board instead of a picture of an ESP32 is very confusing

I've also just fixed the bug which makes pyboard.py not work for any ESP32_MB boards (broken handling of the RST and DTR lines) and updated the doc for those... but I can't work out how to make a new PR for those: it seems to have added it into this existing one.

I am totally new to this "git" contributions.

Someone is going to need to fix whatever isn't working, or spell out in babyspeak what the heck I need to do to overcome the crazy blocks that are being put on messages/code-style and whatever a "ruff" is... "exit code 1" doesn't give any clue about what it wants.

Update: it seems to be unhappy about the existing code (wanting to break function parameters out onto their own lines) - that's not my code. Is it safe to ignore that, or are you going to force me to re-write the existing code to make your ruff machine happy, before it takes my fix?

Chris added 4 commits January 16, 2024 13:51
Signed-off-by: Chris <cryptophoto@gmail.com>
Signed-off-by: Chris <cryptophoto@gmail.com>
Signed-off-by: Chris <cryptophoto@gmail.com>
@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

OK - I fixed everything I know how to fix. I have no clue how to change historical commit message formatting, and putting the file back didn't make that issue go away.

I assume the "ruff" thing is going to refactor the original source when this gets merged, right?

The board.md instructions tell users how to build (I've tested this - it works) so it's not strictly necessary to add those other peoples projects in. If you want to anyway, and know how - feel free.

Signed-off-by: Chris <cryptophoto@gmail.com>
@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

Added another bugfix: pyboard.py was waiting forever, even when the ctrl-A was lost (which always happens when the board is reset, and the board usually resets upon first serial connection when RTS is wired to reset).
Works properly now, and should reliably connect to all MCUs from now on.

Signed-off-by: Chris <cryptophoto@gmail.com>
@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

Good grief - someone REALLY needs to fix the insane code rules. The problem with forcing so many stupid formatting rules on everyone, is that every commit ends up having loads of warnings, which make nobody pay any attention to any warnings at all, which makes it easy for bugs to come in, and for malicious people to insert naughty code, because nobody has the time to proof-read this kind of silliness:-

useless redundant commas being enforced inside function calls (makes it look like something got forgotten by mistake!)
- hard_reset=False
+ hard_reset=False,

pointless spacing
- if min_num_bytes>0:
+ if min_num_bytes > 0:

Are you for real???
- data = b''
+ data = b""

And what the... double-spaces before comments???
- while retry > 0: # resend every 1s (sends get lost while resetting)
+ while retry > 0: # resend every 1s (sends get lost while resetting)

Maybe someone accidentally checked the "every single possible rule" option when adding that crazy tool to the project?

Copy link

codecov bot commented Jan 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (5d28bb4) 98.40% compared to head (f27593e) 98.36%.
Report is 51 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #13253      +/-   ##
==========================================
- Coverage   98.40%   98.36%   -0.05%     
==========================================
  Files         159      159              
  Lines       21088    21088              
==========================================
- Hits        20752    20743       -9     
- Misses        336      345       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@andrewleech
Copy link
Contributor

As mentioned in your other issue, just read / follow https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md and in particular "Automatic Pre-Commit Hooks"
This might help too: https://github.com/jimmo/git-and-micropython
The code rules in place in perfectly reasonable and carefully chosen. Just let the tools handle auto-formatting and stop worrying about it.

Signed-off-by: Chris <cryptophoto@gmail.com>
@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

I finally managed to sleuth the irritating hard-reset bug that pyboard inflicts on MCU's which have automatic (no button-press needed) firmware-update facilities in their hardware (RTS/DTR wired to reset/gpio0) - tracked it all the way back to the pyserial/pyserial#729 library, but was lucky enough to find a neat workaround.

It is thoroughly tested and works well now!

This should help a whole generation of esp32cam and similar board users save a lot of hair-pulling!!

After this is merged in, I plan to add one more feature: a text terminal - so you can use pyboard to access the REPL interactively (i.e. port my working perl version https://github.com/gitcnd/mcu_serial into pyboard)

@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

...stop worrying about it.

is that all I need to do now? I assume someone will merge this without me needing to do anything more, right ?

@stinos
Copy link
Contributor

stinos commented Jan 16, 2024

What is meant is that if you install the code formatting tools, you can then stop worrying about rules and only have to invoke the code formatter and it will do everything for you.

Maybe someone accidentally checked the "every single possible rule" option when adding that crazy tool to the project?

The nice thing about the tool is there are close to no options. Just run it and it produces super consistent code everywhere. Which is nice, because people don't want to have to read code which mixes various styles (i.e. all the things you mentioned earlier about spacing etc). Also because objectively speaking that does create a higher cognitive load than when everything looks the same.

@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

the code formatter and it will do everything for you.

is that mandatory? (I hate installing python tools in general - the bitrot, learning-curve, and security risks are astronomical)

I assume that formatter will make those changes when the merge gets done, right?

keep in mind I'm still very new to all this. I had no idea how to use "git" a month or so ago, and I can't remember ever contributing to a GitHub project I don't own myself before.

@@ -48,6 +52,10 @@ Running ``pyboard.py --help`` gives the following output:
available
--follow follow the output after running the scripts
[default if no scripts given]
--no-soft-reset Prevent performing a soft reset when connecting to MCU
--hard-reset pulse the MCU reset pin to hard-reset the MCU (if your
serial connection wires RTS to reset pin properly)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This scheme of wiring RTS to a reset pin is only used on a handful of esp32 boards, not any newer esps with built in USB, nor on any other ports.

"properly" doesn't make sense in this help message here.

Also keep in mind that pyboard.py is generally not expected to be used directly by end users any more, mpremote is the standard / promoted tool now.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not any newer esps with built in USB, nor on any other ports.

On that - do you happen to know how any of those other boards reset the ESP32 and assert GPI0 for flashing, without using RST/DSR? (assuming any of them do, and it's not necessary to physically push buttons on them for it). If there's some other trick to hard-reset modern inbuilt-USB boards, it would be worth including that feature (and porting all this to mpremote too... I've not tried it, but I expect mpremote has the same serial issue, ... time passes... yes: /mpremote/transport_serial.py is a copy/paste of pyboard.py )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most / many other mcu boards just have a separate jumper / button on the board to jump into upgrade mode - every MCU is generally different here.
Some other MCU's with built in USB have either internal mechanisms to run a bootloader.

It's not a standard feature by any account to have a hardware handled reset function over usb,
The esp board (arguably abusing) the flow control pins to do this is the first time I've ever seen this done; and it often causes conflicts where the serial port doesn't work properly on applications that try to enable flow control be default.

Indeed, having the support for this esp RTS/CTS pin control in pyboard/mpremote has broken support for some stm32 boards which enable flow control for reliable serial transfers, I'd personally prefer it was removed entirely, or at least not used by default!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This scheme of wiring RTS to a reset pin is only used on a handful of esp32 boards, not any newer esps with built in USB, nor on any other ports.

Not even all "traditional" ESP boards are the same. Same vendors save a few cent and do not add the two transistor logic to RTS/DTR, but connect Reset & GPIO0 directly to RTS and DTR. That causes problems. Likewise, not all boards with built-in USB switch to boot loader mode when the RTS/DTR toggling is applied. ESP32C3 do, ESP32S3/ESP32S2 do not.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

broken support for some stm32 boards

I own a Roland MDX-20 CNC machine with hardware flow control, so I'm extremely aware of how badly supported this idea has been over the decades (and indeed - a google of stm32 hardware flow control leads with a pile of people having problems...) but I digress.

I've got a huge selection of ESP32 and ESP8266 boards which I test on (and rPI which I own, but haven't tested with yet): I think I should buy a selection of other kinds so I can better check that my "fix" (which is in fact just making linux behave the way windows already does now with serial port RTS pins) has no negative impacts on other architectures/boards... can you point me at the one(s) I need to get (preferably aliexpress if they're there) to add to my collection ?

--no-soft-reset Prevent performing a soft reset when connecting to MCU
--hard-reset pulse the MCU reset pin to hard-reset the MCU (if your
serial connection wires RTS to reset pin properly)
--no-exclusive Open the serial device shared (not exclusive) access
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be detailed that this is a POSIX only function (https://pyserial.readthedocs.io/en/latest/pyserial_api.html) so won't work on windows.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what you mean? The code already has a custom setup for Windows, and it already uses those pins properly in there. I've got no idea why someone deliberately made this work for ESP32/ESP8266 for windows only. My fix makes it work for linux and WSL too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I'm referring to the exclusive setting in pyserial. --no-exclusive appears to be not possible on windows.

@@ -300,7 +307,28 @@ def __init__(
self.serial.rts = False # RTS False = EN High = MCU enabled
self.serial.open()
else:
self.serial = serial.Serial(device, **serial_kwargs)
#self.serial = serial.Serial(device, **serial_kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find on the glitch on the rts lines on existing port open, this old commented it code line should be removed though.

@robert-hh
Copy link
Contributor

I assume someone will merge this without me needing to do anything more, right ?

You must fix the build checks. It's not done automatically and not by someone else. To change commit messages, you can use git rebase -i. Some git tools like sublime merge allow easy editing of commits and commit messages.

In my opinion, it is as well better to split changes to pyboard.py into a separate pull request. These changes are not solely related to adding support for ESP32_CAM boards.

Besides that, expect further requests for changes to the PR.

@stinos
Copy link
Contributor

stinos commented Jan 16, 2024

is that mandatory?

Yes.

(I hate installing python tools in general - the bitrot, learning-curve, and security risks are astronomical)

Your PC is probably full of tools for which you can make the exact same claims. Package managers and OS update mechanisms are used to counter that. Though the learning curve is up to you, but in this case is close to non-exisistent: formatting is one single command with a very limited amount of options. The Python formatter itself used here is not a Python tool but written in Rust and ships as a single executable, if that helps.

I assume that formatter will make those changes when the merge gets done, right?

That would defeat the purpose mentioned earlier: code style would only become consistent after reviewing, it should be before.

keep in mind I'm still very new to all this. I had no idea how to use "git" a month or so ago, and I can't remember ever contributing to a GitHub project I don't own myself before.

Of all the things you need to do for a PR, understanding what git really does and how to work with git is probably the hardest. So look where you are already after a month :)

@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

my opinion, it is as well better to split changes to pyboard.py

mine too. there's no way to do that as far as I can tell though. I spent a good half-hour in github trying... (I was very surprised it even added my new push into my old PR in the first place).

@gitcnd
Copy link
Author

gitcnd commented Jan 16, 2024

In my opinion, it is as well better to split changes to pyboard.py into a separate pull request

OK - now I need to fix mpremote as well - this is getting messy. Do you know if it is possible to "split changes into a separate pull request"? if yes, can you point me someplace to learn how? (perplexity.ai and github itself didn't help)

@andrewleech
Copy link
Contributor

The internet is overflowing with git guides, it's true there's a fairly steep learning curve and it's hard to find the guide that matches your need.
If a gui might make things clearer I use SmartGit and GitExtensions is also very popular.

Otherwise, you likely want to "rebase interactive" to reorder your commits to move the pyboard ones next to one another, then "squash" them together, then "cherry-pick" the squashed one onto a new branch that can be pushed to create a new PR.

@mcauser
Copy link
Contributor

mcauser commented Jan 17, 2024

Good job so far. Getting into some advanced git topics.

A "pull request" points to you repo/branch and a target repo/branch, not individual commits.
You can rewrite your own branch commit history (rebasing) and the pull request comes along for the ride.
If you want to change the PR's branch names, that requires closing and creating a new PR.

To split changes, I'd run git log to list the commit hashes, make note of the ones you want to move, then checkout master, create a new branch off master, git cherry-pick on each of the target commit hashes. Now you have the "split" commits safely on another branch. Next run an interactive rebase git rebase -i and skip each of the hashes you've moved to the other branch.

If cherry picking is too hard, and you only have a few files, another option is to simply copy the files out of the directory, paste back in on a new branch. Perhaps easier done with a GUI.

Ahh, I just noticed you PR is against your master branch.
Normally, I keep master in sync with upstream/master, and use it to create feature branches for PRs.
This means I always have a clean local copy of master to create feature branches off.
(Can have multiple active feature branches/PRs).
You can't "fix it" now without closing this PR and creating a new PR off a new feature branch, so just leave it as is.
You can still split the commits into a separate branch. You can create a new branch off the current master, and rebase skip the commits you want in the first branch, and vice versa on the other branch.

3x git concepts you want to Google and become familiar with: Branching, Rebasing and Cherry picking commits.

  • Branching - working with multiple concurrent working copies of the code
  • Rebasing - editing commit history
  • Cherry picking - copying commits between branches

@gitcnd gitcnd closed this by deleting the head repository May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants