mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-11 22:16:56 +03:00
Merge remote-tracking branch 'upstream/rolling' into analog-digit-early-digit-test
This commit is contained in:
@@ -15,7 +15,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
concurrent_skipping: same_content_newer
|
concurrent_skipping: same_content_newer
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
@@ -25,28 +25,28 @@ jobs:
|
|||||||
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Update PIP cache on every commit
|
- name: Update PIP cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
key: pip-${{ github.run_id }}
|
key: pip-${{ github.run_id }}
|
||||||
restore-keys: pip # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: pip # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Update PlatformIO cache on every commit
|
- name: Update PlatformIO cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.platformio
|
path: ~/.platformio
|
||||||
key: platformio-${{ github.run_id }}
|
key: platformio-${{ github.run_id }}
|
||||||
restore-keys: platformio # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: platformio # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Update Build cache on every commit
|
- name: Update Build cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ./code/.pio/
|
path: ./code/.pio/
|
||||||
key: build-${{ github.run_id }}
|
key: build-${{ github.run_id }}
|
||||||
restore-keys: build # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: build # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Update generated-files cache on every commit
|
- name: Update generated-files cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
./code/.pio/build/esp32cam/firmware.bin
|
./code/.pio/build/esp32cam/firmware.bin
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.10'
|
python-version: '3.10'
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
#run: echo "Testing... ${{ github.ref_name }}, ${{ steps.vars.outputs.sha_short }}" > ./sd-card/html/version.txt; mkdir -p ./code/.pio/build/esp32cam/; cd ./code/.pio/build/esp32cam/; echo "${{ steps.vars.outputs.sha_short }}" > firmware.bin; cp firmware.bin partitions.bin; cp firmware.bin bootloader.bin # Testing
|
#run: echo "Testing... ${{ github.ref_name }}, ${{ steps.vars.outputs.sha_short }}" > ./sd-card/html/version.txt; mkdir -p ./code/.pio/build/esp32cam/; cd ./code/.pio/build/esp32cam/; echo "${{ steps.vars.outputs.sha_short }}" > firmware.bin; cp firmware.bin partitions.bin; cp firmware.bin bootloader.bin # Testing
|
||||||
run: cd code; platformio run --environment esp32cam
|
run: cd code; platformio run --environment esp32cam
|
||||||
|
|
||||||
- name: Prepare Web UI (copy data from repo, generate tooltip pages and update hashes in all files)
|
- name: Prepare Web UI (generate tooltip pages and update hashes in all files)
|
||||||
run: |
|
run: |
|
||||||
rm -rf ./html
|
rm -rf ./html
|
||||||
mkdir html
|
mkdir html
|
||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
python -m pip install markdown
|
python -m pip install markdown
|
||||||
mkdir html/param-tooltips
|
mkdir html/param-tooltips
|
||||||
cd tools/parameter-tooltip-generator
|
cd tools/parameter-tooltip-generator
|
||||||
bash generate-param-doc-tooltips.sh
|
python generate-param-doc-tooltips.py
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
cp -r ./sd-card/html/* ./html/
|
cp -r ./sd-card/html/* ./html/
|
||||||
@@ -101,10 +101,10 @@ jobs:
|
|||||||
needs: build
|
needs: build
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Update generated-files cache on every commit
|
- name: Update generated-files cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
./code/.pio/build/esp32cam/firmware.bin
|
./code/.pio/build/esp32cam/firmware.bin
|
||||||
@@ -115,7 +115,7 @@ jobs:
|
|||||||
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Update update cache on every commit
|
- name: Update update cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: update
|
path: update
|
||||||
key: update-${{ github.run_id }}
|
key: update-${{ github.run_id }}
|
||||||
@@ -144,7 +144,7 @@ jobs:
|
|||||||
cp ./sd-card/config/*.tflite ./update/config/ 2>/dev/null || true
|
cp ./sd-card/config/*.tflite ./update/config/ 2>/dev/null || true
|
||||||
|
|
||||||
- name: Upload update as update.zip artifact (Firmware + Web UI + CNN)
|
- name: Upload update as update.zip artifact (Firmware + Web UI + CNN)
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: "AI-on-the-edge-device__update__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
|
name: "AI-on-the-edge-device__update__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
|
||||||
path: ./update/*
|
path: ./update/*
|
||||||
@@ -164,10 +164,10 @@ jobs:
|
|||||||
needs: build
|
needs: build
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Update generated-files cache on every commit
|
- name: Update generated-files cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
./code/.pio/build/esp32cam/firmware.bin
|
./code/.pio/build/esp32cam/firmware.bin
|
||||||
@@ -178,7 +178,7 @@ jobs:
|
|||||||
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Update remote_setup cache on every commit
|
- name: Update remote_setup cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: remote_setup
|
path: remote_setup
|
||||||
key: remote_setup-${{ github.run_id }}
|
key: remote_setup-${{ github.run_id }}
|
||||||
@@ -205,7 +205,7 @@ jobs:
|
|||||||
cp ./sd-card/config/* ./remote_setup/config/ 2>/dev/null || true
|
cp ./sd-card/config/* ./remote_setup/config/ 2>/dev/null || true
|
||||||
|
|
||||||
- name: Upload remote_setup as remote_setup.zip artifact (Firmware + Web UI + Config)
|
- name: Upload remote_setup as remote_setup.zip artifact (Firmware + Web UI + Config)
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: "AI-on-the-edge-device__remote-setup__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
|
name: "AI-on-the-edge-device__remote-setup__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
|
||||||
path: ./remote_setup/*
|
path: ./remote_setup/*
|
||||||
@@ -220,10 +220,10 @@ jobs:
|
|||||||
needs: build
|
needs: build
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Update generated-files cache on every commit
|
- name: Update generated-files cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
./code/.pio/build/esp32cam/firmware.bin
|
./code/.pio/build/esp32cam/firmware.bin
|
||||||
@@ -234,7 +234,7 @@ jobs:
|
|||||||
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Update manual_setup cache on every commit
|
- name: Update manual_setup cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: manual_setup
|
path: manual_setup
|
||||||
key: manual_setup-${{ github.run_id }}
|
key: manual_setup-${{ github.run_id }}
|
||||||
@@ -263,7 +263,7 @@ jobs:
|
|||||||
cd ./manual_setup
|
cd ./manual_setup
|
||||||
|
|
||||||
- name: Upload manual_setup.zip artifact (Firmware + Bootloader + Partitions + Web UI)
|
- name: Upload manual_setup.zip artifact (Firmware + Bootloader + Partitions + Web UI)
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: "AI-on-the-edge-device__manual-setup__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
|
name: "AI-on-the-edge-device__manual-setup__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
|
||||||
path: ./manual_setup
|
path: ./manual_setup
|
||||||
@@ -284,24 +284,24 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Update update cache on every commit
|
- name: Update update cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: update
|
path: update
|
||||||
key: update-${{ github.run_id }}
|
key: update-${{ github.run_id }}
|
||||||
restore-keys: update # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: update # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Update remote_setup cache on every commit
|
- name: Update remote_setup cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: remote_setup
|
path: remote_setup
|
||||||
key: remote_setup-${{ github.run_id }}
|
key: remote_setup-${{ github.run_id }}
|
||||||
restore-keys: remote_setup # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
restore-keys: remote_setup # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
|
||||||
|
|
||||||
- name: Update manual_setup cache on every commit
|
- name: Update manual_setup cache on every commit
|
||||||
uses: actions/cache@v3.2.3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: manual_setup
|
path: manual_setup
|
||||||
key: manual_setup-${{ github.run_id }}
|
key: manual_setup-${{ github.run_id }}
|
||||||
@@ -396,7 +396,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get version of last release
|
- name: Get version of last release
|
||||||
id: last_release
|
id: last_release
|
||||||
@@ -410,20 +410,21 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "Updating Web installer to use firmware from ${{ steps.last_release.outputs.tag_name }}..."
|
echo "Updating Web installer to use firmware from ${{ steps.last_release.outputs.tag_name }}..."
|
||||||
rm -f docs/binary/firmware.bin
|
rm -f docs/binary/firmware.bin
|
||||||
wget https://github.com/jomjol/AI-on-the-edge-device/releases/download/${{ steps.last_release.outputs.tag_name }}/AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
|
wget ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ steps.last_release.outputs.tag_name }}/AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
|
||||||
unzip AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
|
unzip AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
|
||||||
cp -f firmware.bin docs/binary/firmware.bin
|
cp -f firmware.bin docs/binary/firmware.bin
|
||||||
echo "Updating index and manifest file..."
|
echo "Updating index and manifest file..."
|
||||||
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/index.html
|
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/index.html
|
||||||
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/manifest.json
|
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/manifest.json
|
||||||
|
|
||||||
- name: Setup Pages
|
- name: Setup Pages
|
||||||
uses: actions/configure-pages@v2
|
uses: actions/configure-pages@v4
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v1
|
uses: actions/upload-pages-artifact@v2
|
||||||
with:
|
with:
|
||||||
path: 'docs'
|
path: 'docs'
|
||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
id: deployment
|
id: deployment
|
||||||
uses: actions/deploy-pages@v1
|
uses: actions/deploy-pages@v3 # Note: v4 does not work!
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Reply Bot
|
# Reply Bot
|
||||||
# It uses the configuration in .github/label-commenter-config.yml
|
# It uses the configuration in .github/label-commenter-config.yaml
|
||||||
# See https://github.com/peaceiris/actions-label-commenter
|
# See https://github.com/peaceiris/actions-label-commenter
|
||||||
|
|
||||||
name: Reply-Bot
|
name: Reply-Bot
|
||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
## Remove labels again (issues only)
|
## Remove labels again (issues only)
|
||||||
## Make sure to also add the reply message to .github/label-commenter-config.yml!
|
## Make sure to also add the reply message to .github/label-commenter-config.yaml!
|
||||||
## This currently seems no longer to work due to changes on the actions-cool/issues-helper!
|
## This currently seems no longer to work due to changes on the actions-cool/issues-helper!
|
||||||
####################################################################
|
####################################################################
|
||||||
# - name: Remove 'Logfile' label again (issues only)
|
# - name: Remove 'Logfile' label again (issues only)
|
||||||
@@ -74,6 +74,7 @@ jobs:
|
|||||||
## Write the response
|
## Write the response
|
||||||
####################################################################
|
####################################################################
|
||||||
- name: Write Response
|
- name: Write Response
|
||||||
uses: peaceiris/actions-label-commenter@c2d00660c86f2b9ed0fb35b372c451558eba85b3
|
uses: peaceiris/actions-label-commenter@v1
|
||||||
with:
|
with:
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
github_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
config_file: .github/label-commenter-config.yaml
|
||||||
72
Changelog.md
72
Changelog.md
@@ -1,8 +1,60 @@
|
|||||||
## [unreleased] - 2023-12-21
|
## [update] - 2024-03-30
|
||||||
|
|
||||||
### Changes
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.6.0...v15.7.0)
|
||||||
|
|
||||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/rolling...v15.3.0)
|
#### Core Changes
|
||||||
|
|
||||||
|
- New tflite-Model for Analog (v13.0.0)
|
||||||
|
- New tflite-Model for Digital Hybrid (v7.0.0)
|
||||||
|
|
||||||
|
#### Bug Fixes
|
||||||
|
|
||||||
|
- tbd
|
||||||
|
|
||||||
|
## [15.7.0] - 2024-02-17
|
||||||
|
|
||||||
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.6.0...v15.7.0)
|
||||||
|
|
||||||
|
#### Core Changes
|
||||||
|
- Added new camera settings (See `Settings > Alignment > Reference Image and Camera Settings`). You might need to re-create the reference image and alignment marks. Note worthy:
|
||||||
|
- You can now crop the image
|
||||||
|
- Support to configure sharpness, grayscale, negatoive and exposure
|
||||||
|
- Enhanced various WebUI pages with better explanations and usability
|
||||||
|
- Add Firmware Version to MQTT
|
||||||
|
|
||||||
|
#### Bug Fixes
|
||||||
|
- Reverted "Implemented late analog / digital transition [#2778](https://github.com/jomjol/AI-on-the-edge-device/pull/2778) (introduced in `v15.5`) as is seems to cause issues for many users.
|
||||||
|
|
||||||
|
|
||||||
|
## [15.6.0] - 2024-02-09
|
||||||
|
|
||||||
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.5.0...v15.6.0)
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
* Fixed issues with the SD-Card initialization
|
||||||
|
|
||||||
|
## [15.5.0] - 2024-02-02
|
||||||
|
|
||||||
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.4.0...v15.5.0)
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- Update PlattformIO to v6.5.0, which means esp-idf to v5.1
|
||||||
|
- Enhance busy notification
|
||||||
|
- Implemented late analog / digital transition
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
* ATA-TRIM: workaround for old SD-cards with no trim function to work with esp-idf v5.x
|
||||||
|
* InfluxDB: Modified the time conversions to be more stable (UTC vs. local time shifts)
|
||||||
|
* Fix negatives on extended resolution false
|
||||||
|
* Show chip infos on info page
|
||||||
|
* Fix memory leaks in tflite integration
|
||||||
|
|
||||||
|
## [15.4.0] - 2023-12-22
|
||||||
|
|
||||||
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.3.0...v15.4.0)
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
|
|
||||||
@@ -19,6 +71,8 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
|||||||
- dig-class11_1700_s2.tflite
|
- dig-class11_1700_s2.tflite
|
||||||
- ana-cont_1208_s2_q.tflite
|
- ana-cont_1208_s2_q.tflite
|
||||||
|
|
||||||
|
- Added config entries for MQTT TLS
|
||||||
|
|
||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
|
|
||||||
@@ -29,11 +83,8 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
|||||||
- Memory leakage (MQTT)
|
- Memory leakage (MQTT)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [15.3.0] - 2023-07-22
|
## [15.3.0] - 2023-07-22
|
||||||
|
|
||||||
### Changes
|
|
||||||
|
|
||||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.3.0...v15.2.4)
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.3.0...v15.2.4)
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
@@ -43,13 +94,8 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
|||||||
- ana-cont_1207_s2_q.tflite
|
- ana-cont_1207_s2_q.tflite
|
||||||
- dig-cont_0620_s3_q.tflite
|
- dig-cont_0620_s3_q.tflite
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [15.2.4] - 2023-05-02
|
## [15.2.4] - 2023-05-02
|
||||||
|
|
||||||
### Changes
|
|
||||||
|
|
||||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.1...v15.2.4)
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.1...v15.2.4)
|
||||||
|
|
||||||
#### Changed
|
#### Changed
|
||||||
@@ -73,8 +119,6 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
|||||||
|
|
||||||
## [15.2.0] - 2023-04-23
|
## [15.2.0] - 2023-04-23
|
||||||
|
|
||||||
### Changes
|
|
||||||
|
|
||||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.1...v15.2.0)
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.1...v15.2.0)
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
@@ -104,8 +148,6 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
|||||||
|
|
||||||
## [15.1.1] - 2023-03-23
|
## [15.1.1] - 2023-03-23
|
||||||
|
|
||||||
### Changes
|
|
||||||
|
|
||||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.0...v15.1.1)
|
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.0...v15.1.1)
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
|||||||
@@ -69,3 +69,6 @@ pio device monitor -p /dev/ttyUSB0
|
|||||||
- `pio run --target erase` to erase the flash
|
- `pio run --target erase` to erase the flash
|
||||||
- `pio run --target upload` this will upload the `bootloader.bin, partitions.bin,firmware.bin` from the `code/.pio/build/esp32cam/` folder.
|
- `pio run --target upload` this will upload the `bootloader.bin, partitions.bin,firmware.bin` from the `code/.pio/build/esp32cam/` folder.
|
||||||
- `pio device monitor` to observe the logs via uart
|
- `pio device monitor` to observe the logs via uart
|
||||||
|
|
||||||
|
# Update Parameters
|
||||||
|
If you create or rename a parameter, make sure to update its documentation in `../param-docs/parameter-pages`! Check the `../param-docs/README.md` for more information.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -15,49 +15,100 @@
|
|||||||
#include "CImageBasis.h"
|
#include "CImageBasis.h"
|
||||||
#include "../../include/defines.h"
|
#include "../../include/defines.h"
|
||||||
|
|
||||||
class CCamera {
|
typedef enum
|
||||||
protected:
|
{
|
||||||
int ActualQuality;
|
OV2640_MODE_UXGA,
|
||||||
framesize_t ActualResolution;
|
OV2640_MODE_SVGA,
|
||||||
int brightness, contrast, saturation;
|
OV2640_MODE_CIF
|
||||||
bool isFixedExposure;
|
} ov2640_sensor_mode_t;
|
||||||
int waitbeforepicture_org;
|
|
||||||
int led_intensity = 4095;
|
|
||||||
|
|
||||||
void ledc_init(void);
|
typedef struct
|
||||||
bool CameraInitSuccessful = false;
|
{
|
||||||
bool demoMode = false;
|
framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10
|
||||||
|
gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128)
|
||||||
|
|
||||||
bool loadNextDemoImage(camera_fb_t *fb);
|
int ImageQuality; // 0 - 63
|
||||||
long GetFileSize(std::string filename);
|
int ImageBrightness; // (-2 to 2) - set brightness
|
||||||
|
int ImageContrast; //-2 - 2
|
||||||
|
int ImageSaturation; //-2 - 2
|
||||||
|
int ImageSharpness; //-2 - 2
|
||||||
|
bool ImageAutoSharpness;
|
||||||
|
int ImageSpecialEffect; // 0 - 6
|
||||||
|
int ImageWbMode; // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
|
||||||
|
int ImageAwb; // white balance enable (0 or 1)
|
||||||
|
int ImageAwbGain; // Auto White Balance enable (0 or 1)
|
||||||
|
int ImageAec; // auto exposure off (1 or 0)
|
||||||
|
int ImageAec2; // automatic exposure sensor (0 or 1)
|
||||||
|
int ImageAeLevel; // auto exposure levels (-2 to 2)
|
||||||
|
int ImageAecValue; // set exposure manually (0-1200)
|
||||||
|
int ImageAgc; // auto gain off (1 or 0)
|
||||||
|
int ImageAgcGain; // set gain manually (0 - 30)
|
||||||
|
int ImageBpc; // black pixel correction
|
||||||
|
int ImageWpc; // white pixel correction
|
||||||
|
int ImageRawGma; // (1 or 0)
|
||||||
|
int ImageLenc; // lens correction (1 or 0)
|
||||||
|
int ImageHmirror; // (0 or 1) flip horizontally
|
||||||
|
int ImageVflip; // Invert image (0 or 1)
|
||||||
|
int ImageDcw; // downsize enable (1 or 0)
|
||||||
|
|
||||||
public:
|
int ImageWidth;
|
||||||
int image_height, image_width;
|
int ImageHeight;
|
||||||
|
|
||||||
CCamera();
|
int ImageLedIntensity;
|
||||||
esp_err_t InitCam();
|
|
||||||
|
|
||||||
void LightOnOff(bool status);
|
bool ImageZoomEnabled;
|
||||||
void LEDOnOff(bool status);
|
int ImageZoomMode;
|
||||||
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
|
int ImageZoomOffsetX;
|
||||||
esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn);
|
int ImageZoomOffsetY;
|
||||||
void SetQualitySize(int qual, framesize_t resol);
|
int ImageZoomSize;
|
||||||
bool SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation);
|
|
||||||
void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol);
|
|
||||||
void SetLEDIntensity(float _intrel);
|
|
||||||
bool testCamera(void);
|
|
||||||
void EnableAutoExposure(int flash_duration);
|
|
||||||
bool getCameraInitSuccessful();
|
|
||||||
void useDemoMode(void);
|
|
||||||
|
|
||||||
|
int WaitBeforePicture;
|
||||||
|
bool isImageSize;
|
||||||
|
|
||||||
framesize_t TextToFramesize(const char * text);
|
bool CameraInitSuccessful;
|
||||||
|
bool changedCameraSettings;
|
||||||
|
bool DemoMode;
|
||||||
|
bool SaveAllFiles;
|
||||||
|
} camera_controll_config_temp_t;
|
||||||
|
|
||||||
esp_err_t CaptureToFile(std::string nm, int delay = 0);
|
extern camera_controll_config_temp_t CCstatus;
|
||||||
esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0);
|
|
||||||
|
class CCamera
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void ledc_init(void);
|
||||||
|
bool loadNextDemoImage(camera_fb_t *fb);
|
||||||
|
long GetFileSize(std::string filename);
|
||||||
|
void SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput);
|
||||||
|
void SetImageWidthHeightFromResolution(framesize_t resol);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CCamera(void);
|
||||||
|
esp_err_t InitCam(void);
|
||||||
|
|
||||||
|
void LightOnOff(bool status);
|
||||||
|
void LEDOnOff(bool status);
|
||||||
|
|
||||||
|
esp_err_t setSensorDatenFromCCstatus(void);
|
||||||
|
esp_err_t getSensorDatenToCCstatus(void);
|
||||||
|
|
||||||
|
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
|
||||||
|
esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn);
|
||||||
|
|
||||||
|
void SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize);
|
||||||
|
void SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize);
|
||||||
|
void SetCamSharpness(bool _autoSharpnessEnabled, int _sharpnessLevel);
|
||||||
|
|
||||||
|
void SetLEDIntensity(float _intrel);
|
||||||
|
bool testCamera(void);
|
||||||
|
bool getCameraInitSuccessful(void);
|
||||||
|
void useDemoMode(void);
|
||||||
|
|
||||||
|
framesize_t TextToFramesize(const char *text);
|
||||||
|
|
||||||
|
esp_err_t CaptureToFile(std::string nm, int delay = 0);
|
||||||
|
esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern CCamera Camera;
|
extern CCamera Camera;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
152
code/components/jomjol_controlcamera/ov2640_sharpness.cpp
Normal file
152
code/components/jomjol_controlcamera/ov2640_sharpness.cpp
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include "esp_camera.h"
|
||||||
|
#include "ov2640_sharpness.h"
|
||||||
|
|
||||||
|
|
||||||
|
const static uint8_t OV2640_SHARPNESS_AUTO[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0x20, 0x20,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
const static uint8_t OV2640_SHARPNESS_MANUAL[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0x00, 0x20,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
const static uint8_t OV2640_SHARPNESS_LEVEL0[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0xC0, 0x1F,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const static uint8_t OV2640_SHARPNESS_LEVEL1[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0xC1, 0x1F,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const static uint8_t OV2640_SHARPNESS_LEVEL2[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0xC2, 0x1F,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const static uint8_t OV2640_SHARPNESS_LEVEL3[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0xC4, 0x1F,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const static uint8_t OV2640_SHARPNESS_LEVEL4[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0xC8, 0x1F,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const static uint8_t OV2640_SHARPNESS_LEVEL5[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0xD0, 0x1F,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
const static uint8_t OV2640_SHARPNESS_LEVEL6[]=
|
||||||
|
{
|
||||||
|
//reg, val, mask
|
||||||
|
0xFF, 0x00, 0xFF,
|
||||||
|
0x92, 0x01, 0xFF,
|
||||||
|
0x93, 0xDF, 0x1F,
|
||||||
|
0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
const static uint8_t *OV2640_SETTING_SHARPNESS[]=
|
||||||
|
{
|
||||||
|
OV2640_SHARPNESS_LEVEL0, // -3 sharpness
|
||||||
|
OV2640_SHARPNESS_LEVEL1,
|
||||||
|
OV2640_SHARPNESS_LEVEL2,
|
||||||
|
OV2640_SHARPNESS_LEVEL3,
|
||||||
|
OV2640_SHARPNESS_LEVEL4,
|
||||||
|
OV2640_SHARPNESS_LEVEL5,
|
||||||
|
OV2640_SHARPNESS_LEVEL6 // +3 sharpness
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OV2640_MAXLEVEL_SHARPNESS 6
|
||||||
|
|
||||||
|
|
||||||
|
static int table_mask_write(sensor_t *sensor, const uint8_t* ptab)
|
||||||
|
{
|
||||||
|
uint8_t address;
|
||||||
|
uint8_t value;
|
||||||
|
uint8_t orgval;
|
||||||
|
uint8_t mask;
|
||||||
|
const uint8_t *pdata = ptab;
|
||||||
|
|
||||||
|
if (pdata == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
address = *pdata++;
|
||||||
|
value = *pdata++;
|
||||||
|
mask = *pdata++;
|
||||||
|
|
||||||
|
if ((address == 0) && (value == 0) && (mask == 0))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor->set_reg(sensor, address, mask, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ov2640_enable_auto_sharpness(sensor_t *sensor)
|
||||||
|
{
|
||||||
|
table_mask_write(sensor, OV2640_SHARPNESS_AUTO);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ov2640_set_sharpness(sensor_t *sensor, int sharpness)
|
||||||
|
{
|
||||||
|
int sharpness_temp = 0;
|
||||||
|
|
||||||
|
if (sharpness < -3)
|
||||||
|
{
|
||||||
|
sharpness_temp = -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sharpness > OV2640_MAXLEVEL_SHARPNESS - 3)
|
||||||
|
{
|
||||||
|
sharpness_temp = OV2640_MAXLEVEL_SHARPNESS - 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
table_mask_write(sensor, OV2640_SHARPNESS_MANUAL);
|
||||||
|
table_mask_write(sensor, OV2640_SETTING_SHARPNESS[sharpness_temp + 3]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
11
code/components/jomjol_controlcamera/ov2640_sharpness.h
Normal file
11
code/components/jomjol_controlcamera/ov2640_sharpness.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef OV2640_SHARPNESS_H
|
||||||
|
#define OV2640_SHARPNESS_H
|
||||||
|
|
||||||
|
#include "esp_camera.h"
|
||||||
|
|
||||||
|
int ov2640_enable_auto_sharpness(sensor_t *sensor);
|
||||||
|
int ov2640_set_sharpness(sensor_t *sensor, int sharpness); // -3 to +3, -4 for auto-sharpness
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "esp_camera.h"
|
#include "esp_camera.h"
|
||||||
#include "ClassControllCamera.h"
|
#include "ClassControllCamera.h"
|
||||||
|
#include "MainFlowControl.h"
|
||||||
|
|
||||||
#include "ClassLogFile.h"
|
#include "ClassLogFile.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
@@ -13,37 +14,35 @@
|
|||||||
|
|
||||||
static const char *TAG = "server_cam";
|
static const char *TAG = "server_cam";
|
||||||
|
|
||||||
|
void PowerResetCamera()
|
||||||
|
{
|
||||||
|
ESP_LOGD(TAG, "Resetting camera by power down line");
|
||||||
|
gpio_config_t conf;
|
||||||
|
conf.intr_type = GPIO_INTR_DISABLE;
|
||||||
|
conf.pin_bit_mask = 1LL << GPIO_NUM_32;
|
||||||
|
conf.mode = GPIO_MODE_OUTPUT;
|
||||||
|
conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||||
|
conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||||
|
gpio_config(&conf);
|
||||||
|
|
||||||
void PowerResetCamera(){
|
// carefull, logic is inverted compared to reset pin
|
||||||
|
gpio_set_level(GPIO_NUM_32, 1);
|
||||||
ESP_LOGD(TAG, "Resetting camera by power down line");
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
gpio_config_t conf;
|
gpio_set_level(GPIO_NUM_32, 0);
|
||||||
conf.intr_type = GPIO_INTR_DISABLE;
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
conf.pin_bit_mask = 1LL << GPIO_NUM_32;
|
|
||||||
conf.mode = GPIO_MODE_OUTPUT;
|
|
||||||
conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
|
||||||
conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
|
||||||
gpio_config(&conf);
|
|
||||||
|
|
||||||
// carefull, logic is inverted compared to reset pin
|
|
||||||
gpio_set_level(GPIO_NUM_32, 1);
|
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
|
||||||
gpio_set_level(GPIO_NUM_32, 0);
|
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
esp_err_t handler_lightOn(httpd_req_t *req)
|
esp_err_t handler_lightOn(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_lightOn - Start");
|
LogFile.WriteHeapInfo("handler_lightOn - Start");
|
||||||
ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri);
|
ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Camera.getCameraInitSuccessful())
|
if (Camera.getCameraInitSuccessful())
|
||||||
{
|
{
|
||||||
Camera.LightOnOff(true);
|
Camera.LightOnOff(true);
|
||||||
const char* resp_str = (const char*) req->user_ctx;
|
const char *resp_str = (const char *)req->user_ctx;
|
||||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -52,25 +51,24 @@ esp_err_t handler_lightOn(httpd_req_t *req)
|
|||||||
return ESP_ERR_NOT_FOUND;
|
return ESP_ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_lightOn - Done");
|
LogFile.WriteHeapInfo("handler_lightOn - Done");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
esp_err_t handler_lightOff(httpd_req_t *req)
|
esp_err_t handler_lightOff(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_lightOff - Start");
|
LogFile.WriteHeapInfo("handler_lightOff - Start");
|
||||||
ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri);
|
ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Camera.getCameraInitSuccessful())
|
if (Camera.getCameraInitSuccessful())
|
||||||
{
|
{
|
||||||
Camera.LightOnOff(false);
|
Camera.LightOnOff(false);
|
||||||
const char* resp_str = (const char*) req->user_ctx;
|
const char *resp_str = (const char *)req->user_ctx;
|
||||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -79,115 +77,118 @@ esp_err_t handler_lightOff(httpd_req_t *req)
|
|||||||
return ESP_ERR_NOT_FOUND;
|
return ESP_ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_lightOff - Done");
|
LogFile.WriteHeapInfo("handler_lightOff - Done");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
esp_err_t handler_capture(httpd_req_t *req)
|
esp_err_t handler_capture(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_capture - Start");
|
LogFile.WriteHeapInfo("handler_capture - Start");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Camera.getCameraInitSuccessful())
|
if (Camera.getCameraInitSuccessful())
|
||||||
{
|
{
|
||||||
int quality;
|
#ifdef DEBUG_DETAIL_ON
|
||||||
framesize_t res;
|
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||||
|
#endif
|
||||||
|
|
||||||
Camera.GetCameraParameter(req, quality, res);
|
// wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden
|
||||||
|
if (CFstatus.changedCameraSettings)
|
||||||
#ifdef DEBUG_DETAIL_ON
|
{
|
||||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||||
#endif
|
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||||
|
CFstatus.changedCameraSettings = false;
|
||||||
Camera.SetQualitySize(quality, res);
|
}
|
||||||
|
|
||||||
esp_err_t result;
|
esp_err_t result;
|
||||||
result = Camera.CaptureToHTTP(req);
|
result = Camera.CaptureToHTTP(req);
|
||||||
|
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_capture - Done");
|
LogFile.WriteHeapInfo("handler_capture - Done");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture not available!");
|
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture not available!");
|
||||||
return ESP_ERR_NOT_FOUND;
|
return ESP_ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
esp_err_t handler_capture_with_light(httpd_req_t *req)
|
esp_err_t handler_capture_with_light(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_capture_with_light - Start");
|
LogFile.WriteHeapInfo("handler_capture_with_light - Start");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Camera.getCameraInitSuccessful())
|
if (Camera.getCameraInitSuccessful())
|
||||||
{
|
{
|
||||||
char _query[100];
|
char _query[100];
|
||||||
char _delay[10];
|
char _delay[10];
|
||||||
|
|
||||||
int quality;
|
|
||||||
framesize_t res;
|
|
||||||
int delay = 2500;
|
int delay = 2500;
|
||||||
|
|
||||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "Query: %s", _query);
|
ESP_LOGD(TAG, "Query: %s", _query);
|
||||||
|
|
||||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||||
#endif
|
#endif
|
||||||
delay = atoi(_delay);
|
delay = atoi(_delay);
|
||||||
|
|
||||||
if (delay < 0)
|
if (delay < 0)
|
||||||
|
{
|
||||||
delay = 0;
|
delay = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera.GetCameraParameter(req, quality, res);
|
#ifdef DEBUG_DETAIL_ON
|
||||||
|
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_DETAIL_ON
|
// wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden
|
||||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
if (CFstatus.changedCameraSettings)
|
||||||
#endif
|
{
|
||||||
|
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||||
|
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||||
|
CFstatus.changedCameraSettings = false;
|
||||||
|
}
|
||||||
|
|
||||||
Camera.SetQualitySize(quality, res);
|
|
||||||
Camera.LightOnOff(true);
|
Camera.LightOnOff(true);
|
||||||
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
|
||||||
vTaskDelay( xDelay );
|
vTaskDelay(xDelay);
|
||||||
|
|
||||||
esp_err_t result;
|
esp_err_t result;
|
||||||
result = Camera.CaptureToHTTP(req);
|
result = Camera.CaptureToHTTP(req);
|
||||||
|
|
||||||
Camera.LightOnOff(false);
|
Camera.LightOnOff(false);
|
||||||
|
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_capture_with_light - Done");
|
LogFile.WriteHeapInfo("handler_capture_with_light - Done");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture_with_flashlight not available!");
|
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture_with_flashlight not available!");
|
||||||
return ESP_ERR_NOT_FOUND;
|
return ESP_ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
|
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Camera.getCameraInitSuccessful())
|
if (Camera.getCameraInitSuccessful())
|
||||||
{
|
{
|
||||||
@@ -197,52 +198,61 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
|||||||
char filename[100];
|
char filename[100];
|
||||||
std::string fn = "/sdcard/";
|
std::string fn = "/sdcard/";
|
||||||
|
|
||||||
|
|
||||||
int quality;
|
|
||||||
framesize_t res;
|
|
||||||
|
|
||||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "Query: %s", _query);
|
ESP_LOGD(TAG, "Query: %s", _query);
|
||||||
|
|
||||||
if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
|
if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
|
||||||
{
|
{
|
||||||
fn.append(filename);
|
fn.append(filename);
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
ESP_LOGD(TAG, "Filename: %s", fn.c_str());
|
ESP_LOGD(TAG, "Filename: %s", fn.c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
fn.append("noname.jpg");
|
fn.append("noname.jpg");
|
||||||
|
}
|
||||||
|
|
||||||
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
ESP_LOGD(TAG, "Delay: %s", _delay);
|
ESP_LOGD(TAG, "Delay: %s", _delay);
|
||||||
#endif
|
#endif
|
||||||
delay = atoi(_delay);
|
delay = atoi(_delay);
|
||||||
|
|
||||||
if (delay < 0)
|
if (delay < 0)
|
||||||
|
{
|
||||||
delay = 0;
|
delay = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
fn.append("noname.jpg");
|
fn.append("noname.jpg");
|
||||||
|
}
|
||||||
|
|
||||||
Camera.GetCameraParameter(req, quality, res);
|
#ifdef DEBUG_DETAIL_ON
|
||||||
#ifdef DEBUG_DETAIL_ON
|
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
#endif
|
||||||
#endif
|
|
||||||
Camera.SetQualitySize(quality, res);
|
// wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden
|
||||||
|
if (CFstatus.changedCameraSettings)
|
||||||
|
{
|
||||||
|
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||||
|
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||||
|
CFstatus.changedCameraSettings = false;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t result;
|
esp_err_t result;
|
||||||
result = Camera.CaptureToFile(fn, delay);
|
result = Camera.CaptureToFile(fn, delay);
|
||||||
|
|
||||||
const char* resp_str = (const char*) fn.c_str();
|
const char *resp_str = (const char *)fn.c_str();
|
||||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||||
|
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
|
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -253,38 +263,37 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void register_server_camera_uri(httpd_handle_t server)
|
void register_server_camera_uri(httpd_handle_t server)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
ESP_LOGI(TAG, "server_part_camera - Registering URI handlers");
|
ESP_LOGI(TAG, "server_part_camera - Registering URI handlers");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
httpd_uri_t camuri = { };
|
httpd_uri_t camuri = {};
|
||||||
camuri.method = HTTP_GET;
|
camuri.method = HTTP_GET;
|
||||||
|
|
||||||
camuri.uri = "/lighton";
|
camuri.uri = "/lighton";
|
||||||
camuri.handler = handler_lightOn;
|
camuri.handler = handler_lightOn;
|
||||||
camuri.user_ctx = (void*) "Light On";
|
camuri.user_ctx = (void *)"Light On";
|
||||||
httpd_register_uri_handler(server, &camuri);
|
httpd_register_uri_handler(server, &camuri);
|
||||||
|
|
||||||
camuri.uri = "/lightoff";
|
camuri.uri = "/lightoff";
|
||||||
camuri.handler = handler_lightOff;
|
camuri.handler = handler_lightOff;
|
||||||
camuri.user_ctx = (void*) "Light Off";
|
camuri.user_ctx = (void *)"Light Off";
|
||||||
httpd_register_uri_handler(server, &camuri);
|
httpd_register_uri_handler(server, &camuri);
|
||||||
|
|
||||||
camuri.uri = "/capture";
|
camuri.uri = "/capture";
|
||||||
camuri.handler = handler_capture;
|
camuri.handler = handler_capture;
|
||||||
camuri.user_ctx = NULL;
|
camuri.user_ctx = NULL;
|
||||||
httpd_register_uri_handler(server, &camuri);
|
httpd_register_uri_handler(server, &camuri);
|
||||||
|
|
||||||
camuri.uri = "/capture_with_flashlight";
|
camuri.uri = "/capture_with_flashlight";
|
||||||
camuri.handler = handler_capture_with_light;
|
camuri.handler = handler_capture_with_light;
|
||||||
camuri.user_ctx = NULL;
|
camuri.user_ctx = NULL;
|
||||||
httpd_register_uri_handler(server, &camuri);
|
httpd_register_uri_handler(server, &camuri);
|
||||||
|
|
||||||
camuri.uri = "/save";
|
camuri.uri = "/save";
|
||||||
camuri.handler = handler_capture_save_to_file;
|
camuri.handler = handler_capture_save_to_file;
|
||||||
camuri.user_ctx = NULL;
|
camuri.user_ctx = NULL;
|
||||||
httpd_register_uri_handler(server, &camuri);
|
httpd_register_uri_handler(server, &camuri);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
//#include "ClassControllCamera.h"
|
//#include "ClassControllCamera.h"
|
||||||
|
|
||||||
void register_server_camera_uri(httpd_handle_t server);
|
void register_server_camera_uri(httpd_handle_t server);
|
||||||
|
|
||||||
void PowerResetCamera();
|
void PowerResetCamera();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
/*#define MINIZ_NO_MALLOC */
|
/*#define MINIZ_NO_MALLOC */
|
||||||
|
|
||||||
#ifdef MINIZ_NO_INFLATE_APIS
|
#ifdef MINIZ_NO_INFLATE_APIS
|
||||||
#define MINIZ_NO_ARCHIVE_APIS
|
//#define MINIZ_NO_ARCHIVE_APIS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MINIZ_NO_DEFLATE_APIS
|
#ifdef MINIZ_NO_DEFLATE_APIS
|
||||||
|
|||||||
@@ -547,7 +547,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
|
|||||||
/* Get value of expected key from query string */
|
/* Get value of expected key from query string */
|
||||||
if (httpd_query_key_value(buf, "readonly", param, sizeof(param)) == ESP_OK) {
|
if (httpd_query_key_value(buf, "readonly", param, sizeof(param)) == ESP_OK) {
|
||||||
ESP_LOGI(TAG, "Found URL query parameter => readonly=%s", param);
|
ESP_LOGI(TAG, "Found URL query parameter => readonly=%s", param);
|
||||||
readonly = param && strcmp(param,"true")==0;
|
readonly = (strcmp(param,"true") == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,41 +6,36 @@
|
|||||||
#include "CRotateImage.h"
|
#include "CRotateImage.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
|
||||||
#include "ClassLogFile.h"
|
#include "ClassLogFile.h"
|
||||||
#include "psram.h"
|
#include "psram.h"
|
||||||
#include "../../include/defines.h"
|
#include "../../include/defines.h"
|
||||||
|
|
||||||
|
|
||||||
static const char *TAG = "ALIGN";
|
static const char *TAG = "ALIGN";
|
||||||
|
|
||||||
// #define DEBUG_DETAIL_ON
|
// #define DEBUG_DETAIL_ON
|
||||||
|
|
||||||
|
|
||||||
void ClassFlowAlignment::SetInitialParameter(void)
|
void ClassFlowAlignment::SetInitialParameter(void)
|
||||||
{
|
{
|
||||||
initalrotate = 0;
|
initialrotate = 0;
|
||||||
anz_ref = 0;
|
anz_ref = 0;
|
||||||
initialmirror = false;
|
|
||||||
use_antialiasing = false;
|
use_antialiasing = false;
|
||||||
initialflip = false;
|
initialflip = false;
|
||||||
SaveAllFiles = false;
|
SaveAllFiles = false;
|
||||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||||
FileStoreRefAlignment = "/sdcard/config/align.txt";
|
FileStoreRefAlignment = "/sdcard/config/align.txt";
|
||||||
ListFlowControll = NULL;
|
ListFlowControll = NULL;
|
||||||
AlignAndCutImage = NULL;
|
AlignAndCutImage = NULL;
|
||||||
ImageBasis = NULL;
|
ImageBasis = NULL;
|
||||||
ImageTMP = NULL;
|
ImageTMP = NULL;
|
||||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||||
AlgROI = (ImageData*)malloc_psram_heap(std::string(TAG) + "->AlgROI", sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
AlgROI = (ImageData *)malloc_psram_heap(std::string(TAG) + "->AlgROI", sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||||
#endif
|
#endif
|
||||||
previousElement = NULL;
|
previousElement = NULL;
|
||||||
disabled = false;
|
disabled = false;
|
||||||
SAD_criteria = 0.05;
|
SAD_criteria = 0.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow *> *lfc)
|
||||||
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
|
|
||||||
{
|
{
|
||||||
SetInitialParameter();
|
SetInitialParameter();
|
||||||
ListFlowControll = lfc;
|
ListFlowControll = lfc;
|
||||||
@@ -49,66 +44,71 @@ ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
|
|||||||
{
|
{
|
||||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowTakeImage") == 0)
|
if (((*ListFlowControll)[i])->name().compare("ClassFlowTakeImage") == 0)
|
||||||
{
|
{
|
||||||
ImageBasis = ((ClassFlowTakeImage*) (*ListFlowControll)[i])->rawImage;
|
ImageBasis = ((ClassFlowTakeImage *)(*ListFlowControll)[i])->rawImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES
|
if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "CImageBasis had to be created");
|
ESP_LOGD(TAG, "CImageBasis had to be created");
|
||||||
ImageBasis = new CImageBasis("ImageBasis", namerawimage);
|
ImageBasis = new CImageBasis("ImageBasis", namerawimage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClassFlowAlignment::ReadParameter(FILE *pfile, string &aktparamgraph)
|
||||||
bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
|
|
||||||
{
|
{
|
||||||
std::vector<string> splitted;
|
std::vector<string> splitted;
|
||||||
int suchex = 40;
|
int suchex = 40;
|
||||||
int suchey = 40;
|
int suchey = 40;
|
||||||
int alg_algo = 0; //default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023
|
int alg_algo = 0; // default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023
|
||||||
|
|
||||||
|
|
||||||
aktparamgraph = trim(aktparamgraph);
|
aktparamgraph = trim(aktparamgraph);
|
||||||
|
|
||||||
if (aktparamgraph.size() == 0)
|
if (aktparamgraph.size() == 0)
|
||||||
|
{
|
||||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (aktparamgraph.compare("[Alignment]") != 0) //Paragraph does not fit Alignment
|
if (aktparamgraph.compare("[Alignment]") != 0)
|
||||||
|
{
|
||||||
|
// Paragraph does not fit Alignment
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||||
{
|
{
|
||||||
splitted = ZerlegeZeile(aktparamgraph);
|
splitted = ZerlegeZeile(aktparamgraph);
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "FLIPIMAGESIZE") && (splitted.size() > 1))
|
if ((toUpper(splitted[0]) == "FLIPIMAGESIZE") && (splitted.size() > 1))
|
||||||
{
|
{
|
||||||
if (toUpper(splitted[1]) == "TRUE")
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
initialflip = true;
|
initialflip = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((toUpper(splitted[0]) == "INITIALMIRROR") && (splitted.size() > 1))
|
else if (((toUpper(splitted[0]) == "initialrotate") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1))
|
||||||
{
|
{
|
||||||
if (toUpper(splitted[1]) == "TRUE")
|
this->initialrotate = std::stod(splitted[1]);
|
||||||
initialmirror = true;
|
|
||||||
}
|
}
|
||||||
if (((toUpper(splitted[0]) == "INITALROTATE") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1))
|
else if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1))
|
||||||
{
|
|
||||||
this->initalrotate = std::stod(splitted[1]);
|
|
||||||
}
|
|
||||||
if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1))
|
|
||||||
{
|
{
|
||||||
suchex = std::stod(splitted[1]);
|
suchex = std::stod(splitted[1]);
|
||||||
}
|
}
|
||||||
if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1))
|
else if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1))
|
||||||
{
|
{
|
||||||
suchey = std::stod(splitted[1]);
|
suchey = std::stod(splitted[1]);
|
||||||
}
|
}
|
||||||
if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1))
|
else if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1))
|
||||||
{
|
{
|
||||||
if (toUpper(splitted[1]) == "TRUE")
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
use_antialiasing = true;
|
use_antialiasing = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((splitted.size() == 3) && (anz_ref < 2))
|
else if ((splitted.size() == 3) && (anz_ref < 2))
|
||||||
{
|
{
|
||||||
References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]);
|
References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]);
|
||||||
References[anz_ref].target_x = std::stod(splitted[1]);
|
References[anz_ref].target_x = std::stod(splitted[1]);
|
||||||
@@ -116,23 +116,32 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
|
|||||||
anz_ref++;
|
anz_ref++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
||||||
{
|
{
|
||||||
if (toUpper(splitted[1]) == "TRUE")
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
SaveAllFiles = true;
|
SaveAllFiles = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((toUpper(splitted[0]) == "ALIGNMENTALGO") && (splitted.size() > 1))
|
else if ((toUpper(splitted[0]) == "ALIGNMENTALGO") && (splitted.size() > 1))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
std::string zw2 = "Alignment mode selected: " + splitted[1];
|
std::string zw2 = "Alignment mode selected: " + splitted[1];
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
||||||
#endif
|
#endif
|
||||||
if (toUpper(splitted[1]) == "HIGHACCURACY")
|
if (toUpper(splitted[1]) == "HIGHACCURACY")
|
||||||
|
{
|
||||||
alg_algo = 1;
|
alg_algo = 1;
|
||||||
|
}
|
||||||
if (toUpper(splitted[1]) == "FAST")
|
if (toUpper(splitted[1]) == "FAST")
|
||||||
|
{
|
||||||
alg_algo = 2;
|
alg_algo = 2;
|
||||||
if (toUpper(splitted[1]) == "OFF") //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
}
|
||||||
|
if (toUpper(splitted[1]) == "OFF")
|
||||||
|
{
|
||||||
|
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||||
alg_algo = 3;
|
alg_algo = 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,55 +151,55 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
|
|||||||
References[i].search_y = suchey;
|
References[i].search_y = suchey;
|
||||||
References[i].fastalg_SAD_criteria = SAD_criteria;
|
References[i].fastalg_SAD_criteria = SAD_criteria;
|
||||||
References[i].alignment_algo = alg_algo;
|
References[i].alignment_algo = alg_algo;
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
std::string zw2 = "Alignment mode written: " + std::to_string(alg_algo);
|
std::string zw2 = "Alignment mode written: " + std::to_string(alg_algo);
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||||
if(References[0].alignment_algo != 3){
|
if (References[0].alignment_algo != 3)
|
||||||
|
{
|
||||||
LoadReferenceAlignmentValues();
|
LoadReferenceAlignmentValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string ClassFlowAlignment::getHTMLSingleStep(string host)
|
string ClassFlowAlignment::getHTMLSingleStep(string host)
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
|
|
||||||
result = "<p>Rotated Image: </p> <p><img src=\"" + host + "/img_tmp/rot.jpg\"></p>\n";
|
result = "<p>Rotated Image: </p> <p><img src=\"" + host + "/img_tmp/rot.jpg\"></p>\n";
|
||||||
result = result + "<p>Found Alignment: </p> <p><img src=\"" + host + "/img_tmp/rot_roi.jpg\"></p>\n";
|
result = result + "<p>Found Alignment: </p> <p><img src=\"" + host + "/img_tmp/rot_roi.jpg\"></p>\n";
|
||||||
result = result + "<p>Aligned Image: </p> <p><img src=\"" + host + "/img_tmp/alg.jpg\"></p>\n";
|
result = result + "<p>Aligned Image: </p> <p><img src=\"" + host + "/img_tmp/alg.jpg\"></p>\n";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowAlignment::doFlow(string time)
|
bool ClassFlowAlignment::doFlow(string time)
|
||||||
{
|
{
|
||||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||||
if (!AlgROI) // AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation
|
if (!AlgROI) // AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation
|
||||||
{
|
{
|
||||||
AlgROI = (ImageData*)heap_caps_realloc(AlgROI, sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
AlgROI = (ImageData *)heap_caps_realloc(AlgROI, sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||||
if (!AlgROI)
|
|
||||||
{
|
|
||||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlgROI");
|
|
||||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AlgROI)
|
if (!AlgROI)
|
||||||
{
|
{
|
||||||
ImageBasis->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
|
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlgROI");
|
||||||
|
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
if (AlgROI)
|
||||||
|
{
|
||||||
|
ImageBasis->writeToMemoryAsJPG((ImageData *)AlgROI, 90);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!ImageTMP)
|
if (!ImageTMP)
|
||||||
{
|
{
|
||||||
ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation!
|
ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation!
|
||||||
|
|
||||||
if (!ImageTMP)
|
if (!ImageTMP)
|
||||||
{
|
{
|
||||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!");
|
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!");
|
||||||
@@ -201,6 +210,7 @@ bool ClassFlowAlignment::doFlow(string time)
|
|||||||
|
|
||||||
delete AlignAndCutImage;
|
delete AlignAndCutImage;
|
||||||
AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP);
|
AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP);
|
||||||
|
|
||||||
if (!AlignAndCutImage)
|
if (!AlignAndCutImage)
|
||||||
{
|
{
|
||||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlignAndCutImage -> Exec this round aborted!");
|
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlignAndCutImage -> Exec this round aborted!");
|
||||||
@@ -209,6 +219,7 @@ bool ClassFlowAlignment::doFlow(string time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, initialflip);
|
CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, initialflip);
|
||||||
|
|
||||||
if (initialflip)
|
if (initialflip)
|
||||||
{
|
{
|
||||||
int _zw = ImageBasis->height;
|
int _zw = ImageBasis->height;
|
||||||
@@ -220,47 +231,46 @@ bool ClassFlowAlignment::doFlow(string time)
|
|||||||
ImageTMP->height = _zw;
|
ImageTMP->height = _zw;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialmirror)
|
if ((initialrotate != 0) || initialflip)
|
||||||
{
|
|
||||||
ESP_LOGD(TAG, "do mirror");
|
|
||||||
rt.Mirror();
|
|
||||||
|
|
||||||
if (SaveAllFiles)
|
|
||||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((initalrotate != 0) || initialflip)
|
|
||||||
{
|
{
|
||||||
if (use_antialiasing)
|
if (use_antialiasing)
|
||||||
rt.RotateAntiAliasing(initalrotate);
|
{
|
||||||
|
rt.RotateAntiAliasing(initialrotate);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
rt.Rotate(initalrotate);
|
{
|
||||||
|
rt.Rotate(initialrotate);
|
||||||
|
}
|
||||||
|
|
||||||
if (SaveAllFiles)
|
if (SaveAllFiles)
|
||||||
|
{
|
||||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
|
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no align algo if set to 3 = off //add disable aligment algo |01.2023
|
||||||
//no align algo if set to 3 = off //add disable aligment algo |01.2023
|
if (References[0].alignment_algo != 3)
|
||||||
if(References[0].alignment_algo != 3){
|
{
|
||||||
if (!AlignAndCutImage->Align(&References[0], &References[1]))
|
if (!AlignAndCutImage->Align(&References[0], &References[1]))
|
||||||
{
|
{
|
||||||
SaveReferenceAlignmentValues();
|
SaveReferenceAlignmentValues();
|
||||||
}
|
|
||||||
}// no align
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
|
||||||
if (AlgROI) {
|
|
||||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
|
||||||
if(References[0].alignment_algo != 3){
|
|
||||||
DrawRef(ImageTMP);
|
|
||||||
}
|
|
||||||
flowctrl.DigitalDrawROI(ImageTMP);
|
|
||||||
flowctrl.AnalogDrawROI(ImageTMP);
|
|
||||||
ImageTMP->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
|
|
||||||
}
|
}
|
||||||
#endif
|
} // no align
|
||||||
|
|
||||||
|
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||||
|
if (AlgROI)
|
||||||
|
{
|
||||||
|
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||||
|
if (References[0].alignment_algo != 3)
|
||||||
|
{
|
||||||
|
DrawRef(ImageTMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
flowctrl.DigitalDrawROI(ImageTMP);
|
||||||
|
flowctrl.AnalogDrawROI(ImageTMP);
|
||||||
|
ImageTMP->writeToMemoryAsJPG((ImageData *)AlgROI, 90);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SaveAllFiles)
|
if (SaveAllFiles)
|
||||||
{
|
{
|
||||||
@@ -272,18 +282,18 @@ bool ClassFlowAlignment::doFlow(string time)
|
|||||||
delete ImageTMP;
|
delete ImageTMP;
|
||||||
ImageTMP = NULL;
|
ImageTMP = NULL;
|
||||||
|
|
||||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||||
if(References[0].alignment_algo != 3){
|
if (References[0].alignment_algo != 3)
|
||||||
|
{
|
||||||
LoadReferenceAlignmentValues();
|
LoadReferenceAlignmentValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
||||||
{
|
{
|
||||||
FILE* pFile;
|
FILE *pFile;
|
||||||
std::string zwtime, zwvalue;
|
std::string zwtime, zwvalue;
|
||||||
|
|
||||||
pFile = fopen(FileStoreRefAlignment.c_str(), "w");
|
pFile = fopen(FileStoreRefAlignment.c_str(), "w");
|
||||||
@@ -291,7 +301,7 @@ void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
|||||||
if (strlen(zwtime.c_str()) == 0)
|
if (strlen(zwtime.c_str()) == 0)
|
||||||
{
|
{
|
||||||
time_t rawtime;
|
time_t rawtime;
|
||||||
struct tm* timeinfo;
|
struct tm *timeinfo;
|
||||||
char buffer[80];
|
char buffer[80];
|
||||||
|
|
||||||
time(&rawtime);
|
time(&rawtime);
|
||||||
@@ -305,30 +315,29 @@ void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
|||||||
fputs("\n", pFile);
|
fputs("\n", pFile);
|
||||||
|
|
||||||
zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y);
|
zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y);
|
||||||
zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_SAD)+ "\t" +std::to_string(References[0].fastalg_min);
|
zwvalue = zwvalue + "\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
|
||||||
zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_max)+ "\t" +std::to_string(References[0].fastalg_avg);
|
zwvalue = zwvalue + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
|
||||||
fputs(zwvalue.c_str(), pFile);
|
fputs(zwvalue.c_str(), pFile);
|
||||||
fputs("\n", pFile);
|
fputs("\n", pFile);
|
||||||
|
|
||||||
zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y);
|
zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y);
|
||||||
zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_SAD)+ "\t" +std::to_string(References[1].fastalg_min);
|
zwvalue = zwvalue + "\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
|
||||||
zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_max)+ "\t" +std::to_string(References[1].fastalg_avg);
|
zwvalue = zwvalue + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
|
||||||
fputs(zwvalue.c_str(), pFile);
|
fputs(zwvalue.c_str(), pFile);
|
||||||
fputs("\n", pFile);
|
fputs("\n", pFile);
|
||||||
|
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
||||||
{
|
{
|
||||||
FILE* pFile;
|
FILE *pFile;
|
||||||
char zw[1024];
|
char zw[1024];
|
||||||
string zwvalue;
|
string zwvalue;
|
||||||
std::vector<string> splitted;
|
std::vector<string> splitted;
|
||||||
|
|
||||||
|
|
||||||
pFile = fopen(FileStoreRefAlignment.c_str(), "r");
|
pFile = fopen(FileStoreRefAlignment.c_str(), "r");
|
||||||
|
|
||||||
if (pFile == NULL)
|
if (pFile == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -337,6 +346,7 @@ bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
|||||||
|
|
||||||
fgets(zw, 1024, pFile);
|
fgets(zw, 1024, pFile);
|
||||||
splitted = ZerlegeZeile(std::string(zw), " \t");
|
splitted = ZerlegeZeile(std::string(zw), " \t");
|
||||||
|
|
||||||
if (splitted.size() < 6)
|
if (splitted.size() < 6)
|
||||||
{
|
{
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
@@ -352,6 +362,7 @@ bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
|||||||
|
|
||||||
fgets(zw, 1024, pFile);
|
fgets(zw, 1024, pFile);
|
||||||
splitted = ZerlegeZeile(std::string(zw));
|
splitted = ZerlegeZeile(std::string(zw));
|
||||||
|
|
||||||
if (splitted.size() < 6)
|
if (splitted.size() < 6)
|
||||||
{
|
{
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
@@ -367,7 +378,6 @@ bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
|||||||
|
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
|
|
||||||
|
|
||||||
/*#ifdef DEBUG_DETAIL_ON
|
/*#ifdef DEBUG_DETAIL_ON
|
||||||
std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x);
|
std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x);
|
||||||
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
|
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
|
||||||
@@ -382,7 +392,6 @@ bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
|
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
|
||||||
{
|
{
|
||||||
if (_zw->ImageOkay())
|
if (_zw->ImageOkay())
|
||||||
|
|||||||
@@ -12,12 +12,10 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class ClassFlowAlignment :
|
class ClassFlowAlignment : public ClassFlow
|
||||||
public ClassFlow
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
float initalrotate;
|
float initialrotate;
|
||||||
bool initialmirror;
|
|
||||||
bool initialflip;
|
bool initialflip;
|
||||||
bool use_antialiasing;
|
bool use_antialiasing;
|
||||||
RefInfo References[2];
|
RefInfo References[2];
|
||||||
@@ -34,21 +32,20 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
CImageBasis *ImageBasis, *ImageTMP;
|
CImageBasis *ImageBasis, *ImageTMP;
|
||||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||||
ImageData *AlgROI;
|
ImageData *AlgROI;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ClassFlowAlignment(std::vector<ClassFlow*>* lfc);
|
ClassFlowAlignment(std::vector<ClassFlow *> *lfc);
|
||||||
|
|
||||||
CAlignAndCutImage* GetAlignAndCutImage(){return AlignAndCutImage;};
|
CAlignAndCutImage *GetAlignAndCutImage() { return AlignAndCutImage; };
|
||||||
|
|
||||||
void DrawRef(CImageBasis *_zw);
|
void DrawRef(CImageBasis *_zw);
|
||||||
|
|
||||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
bool ReadParameter(FILE *pfile, string &aktparamgraph);
|
||||||
bool doFlow(string time);
|
bool doFlow(string time);
|
||||||
string getHTMLSingleStep(string host);
|
string getHTMLSingleStep(string host);
|
||||||
string name(){return "ClassFlowAlignment";};
|
string name() { return "ClassFlowAlignment"; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // CLASSFLOWALIGNMENT_H
|
||||||
#endif //CLASSFLOWALIGNMENT_H
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ static const char* TAG = "CNN";
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNType _cnntype) : ClassFlowImage(NULL, TAG)
|
ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNType _cnntype) : ClassFlowImage(NULL, TAG) {
|
||||||
{
|
|
||||||
string cnnmodelfile = "";
|
string cnnmodelfile = "";
|
||||||
modelxsize = 1;
|
modelxsize = 1;
|
||||||
modelysize = 1;
|
modelysize = 1;
|
||||||
@@ -38,16 +37,16 @@ ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution, int prev, float _before_narrow_Analog, float analogDigitalTransitionStart)
|
string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution, int prev, float _before_narrow_Analog, float analogDigitalTransitionStart) {
|
||||||
{
|
|
||||||
string result = "";
|
string result = "";
|
||||||
|
|
||||||
if (GENERAL[_analog]->ROI.size() == 0)
|
if (GENERAL[_analog]->ROI.size() == 0) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout _analog=" + std::to_string(_analog) + ", _extendedResolution=" + std::to_string(_extendedResolution) + ", prev=" + std::to_string(prev));
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout _analog=" + std::to_string(_analog) + ", _extendedResolution=" + std::to_string(_extendedResolution) + ", prev=" + std::to_string(prev));
|
||||||
|
|
||||||
if (CNNType == Analogue || CNNType == Analogue100)
|
if (CNNType == Analogue || CNNType == Analogue100) {
|
||||||
{
|
|
||||||
float number = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float;
|
float number = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float;
|
||||||
int result_after_decimal_point = ((int) floor(number * 10) + 10) % 10;
|
int result_after_decimal_point = ((int) floor(number * 10) + 10) % 10;
|
||||||
|
|
||||||
@@ -55,37 +54,35 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
|
|||||||
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(analog) number=" + std::to_string(number) + ", result_after_decimal_point=" + std::to_string(result_after_decimal_point) + ", prev=" + std::to_string(prev));
|
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(analog) number=" + std::to_string(number) + ", result_after_decimal_point=" + std::to_string(result_after_decimal_point) + ", prev=" + std::to_string(prev));
|
||||||
result = std::to_string(prev);
|
result = std::to_string(prev);
|
||||||
|
|
||||||
if (_extendedResolution)
|
if (_extendedResolution) {
|
||||||
result = result + std::to_string(result_after_decimal_point);
|
result = result + std::to_string(result_after_decimal_point);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i)
|
for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i) {
|
||||||
{
|
|
||||||
prev = PointerEvalAnalogNew(GENERAL[_analog]->ROI[i]->result_float, prev);
|
prev = PointerEvalAnalogNew(GENERAL[_analog]->ROI[i]->result_float, prev);
|
||||||
result = std::to_string(prev) + result;
|
result = std::to_string(prev) + result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CNNType == Digital)
|
if (CNNType == Digital) {
|
||||||
{
|
for (int i = 0; i < GENERAL[_analog]->ROI.size(); ++i) {
|
||||||
for (int i = 0; i < GENERAL[_analog]->ROI.size(); ++i)
|
if (GENERAL[_analog]->ROI[i]->result_klasse >= 10) {
|
||||||
{
|
|
||||||
if (GENERAL[_analog]->ROI[i]->result_klasse >= 10)
|
|
||||||
result = result + "N";
|
result = result + "N";
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
result = result + std::to_string(GENERAL[_analog]->ROI[i]->result_klasse);
|
result = result + std::to_string(GENERAL[_analog]->ROI[i]->result_klasse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((CNNType == DoubleHyprid10) || (CNNType == Digital100))
|
if ((CNNType == DoubleHyprid10) || (CNNType == Digital100)) {
|
||||||
{
|
|
||||||
|
|
||||||
float number = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float;
|
float number = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float;
|
||||||
if (number >= 0) // NaN?
|
// NaN?
|
||||||
{
|
if (number >= 0) {
|
||||||
if (_extendedResolution) // is only set if it is the first digit (no analogue before!)
|
// is only set if it is the first digit (no analogue before!)
|
||||||
{
|
if (_extendedResolution) {
|
||||||
int result_after_decimal_point = ((int) floor(number * 10)) % 10;
|
int result_after_decimal_point = ((int) floor(number * 10)) % 10;
|
||||||
int result_before_decimal_point = ((int) floor(number)) % 10;
|
int result_before_decimal_point = ((int) floor(number)) % 10;
|
||||||
|
|
||||||
@@ -93,36 +90,32 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
|
|||||||
prev = result_before_decimal_point;
|
prev = result_before_decimal_point;
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(dig100-ext) result_before_decimal_point=" + std::to_string(result_before_decimal_point) + ", result_after_decimal_point=" + std::to_string(result_after_decimal_point) + ", prev=" + std::to_string(prev));
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(dig100-ext) result_before_decimal_point=" + std::to_string(result_before_decimal_point) + ", result_after_decimal_point=" + std::to_string(result_after_decimal_point) + ", prev=" + std::to_string(prev));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
if (_before_narrow_Analog >= 0) {
|
||||||
if (_before_narrow_Analog >= 0)
|
|
||||||
prev = PointerEvalHybridNew(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, _before_narrow_Analog, prev, true, analogDigitalTransitionStart);
|
prev = PointerEvalHybridNew(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, _before_narrow_Analog, prev, true, analogDigitalTransitionStart);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
prev = PointerEvalHybridNew(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, prev, prev);
|
prev = PointerEvalHybridNew(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, prev, prev);
|
||||||
|
}
|
||||||
result = std::to_string(prev);
|
result = std::to_string(prev);
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(dig100) prev=" + std::to_string(prev));
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(dig100) prev=" + std::to_string(prev));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
result = "N";
|
result = "N";
|
||||||
if (_extendedResolution && (CNNType != Digital))
|
if (_extendedResolution && (CNNType != Digital)) {
|
||||||
result = "NN";
|
result = "NN";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i)
|
for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i) {
|
||||||
{
|
if (GENERAL[_analog]->ROI[i]->result_float >= 0) {
|
||||||
if (GENERAL[_analog]->ROI[i]->result_float >= 0)
|
|
||||||
{
|
|
||||||
prev = PointerEvalHybridNew(GENERAL[_analog]->ROI[i]->result_float, GENERAL[_analog]->ROI[i+1]->result_float, prev);
|
prev = PointerEvalHybridNew(GENERAL[_analog]->ROI[i]->result_float, GENERAL[_analog]->ROI[i+1]->result_float, prev);
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout#PointerEvalHybridNew()= " + std::to_string(prev));
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout#PointerEvalHybridNew()= " + std::to_string(prev));
|
||||||
result = std::to_string(prev) + result;
|
result = std::to_string(prev) + result;
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout#result= " + result);
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout#result= " + result);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
prev = -1;
|
prev = -1;
|
||||||
result = "N" + result;
|
result = "N" + result;
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(result_float<0 /'N') result_float=" + std::to_string(GENERAL[_analog]->ROI[i]->result_float));
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(result_float<0 /'N') result_float=" + std::to_string(GENERAL[_analog]->ROI[i]->result_float));
|
||||||
@@ -134,15 +127,28 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
int ClassFlowCNNGeneral::PointerEvalHybridNew(float number, float number_of_predecessors, int eval_predecessors, bool Analog_Predecessors, float digitalAnalogTransitionStart)
|
* @brief Determines the number of an ROI in connection with previous ROI results
|
||||||
{
|
*
|
||||||
|
* @param number: is the current ROI as float value from recognition
|
||||||
|
* @param number_of_predecessors: is the last (lower) ROI as float from recognition
|
||||||
|
* @param eval_predecessors: is the evaluated number. Sometimes a much lower value can change higer values
|
||||||
|
* example: 9.8, 9.9, 0.1
|
||||||
|
* 0.1 => 0 (eval_predecessors)
|
||||||
|
* The 0 makes a 9.9 to 0 (eval_predecessors)
|
||||||
|
* The 0 makes a 9.8 to 0
|
||||||
|
* @param Analog_Predecessors false/true if the last ROI is an analog or digital ROI (default=false)
|
||||||
|
* runs in special handling because analog is much less precise
|
||||||
|
* @param digitalAnalogTransitionStart start of the transitionlogic begins on number_of_predecessor (default=9.2)
|
||||||
|
*
|
||||||
|
* @return int the determined number of the current ROI
|
||||||
|
*/
|
||||||
|
int ClassFlowCNNGeneral::PointerEvalHybridNew(float number, float number_of_predecessors, int eval_predecessors, bool Analog_Predecessors, float digitalAnalogTransitionStart) {
|
||||||
int result;
|
int result;
|
||||||
int result_after_decimal_point = ((int) floor(number * 10)) % 10;
|
int result_after_decimal_point = ((int) floor(number * 10)) % 10;
|
||||||
int result_before_decimal_point = ((int) floor(number) + 10) % 10;
|
int result_before_decimal_point = ((int) floor(number) + 10) % 10;
|
||||||
|
|
||||||
if (eval_predecessors < 0)
|
if (eval_predecessors < 0) {
|
||||||
{
|
|
||||||
// on first digit is no spezial logic for transition needed
|
// on first digit is no spezial logic for transition needed
|
||||||
// we use the recognition as given. The result is the int value of the recognition
|
// we use the recognition as given. The result is the int value of the recognition
|
||||||
// add precisition of 2 digits and round before trunc
|
// add precisition of 2 digits and round before trunc
|
||||||
@@ -153,8 +159,7 @@ int ClassFlowCNNGeneral::PointerEvalHybridNew(float number, float number_of_pred
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Analog_Predecessors)
|
if (Analog_Predecessors) {
|
||||||
{
|
|
||||||
result = PointerEvalAnalogToDigitNew(number, number_of_predecessors, eval_predecessors, digitalAnalogTransitionStart);
|
result = PointerEvalAnalogToDigitNew(number, number_of_predecessors, eval_predecessors, digitalAnalogTransitionStart);
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - Analog predecessor, evaluation over PointerEvalAnalogNew = " + std::to_string(result) +
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - Analog predecessor, evaluation over PointerEvalAnalogNew = " + std::to_string(result) +
|
||||||
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty));
|
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty));
|
||||||
@@ -164,26 +169,31 @@ int ClassFlowCNNGeneral::PointerEvalHybridNew(float number, float number_of_pred
|
|||||||
if ((number_of_predecessors > Digital_Transition_Area_Predecessor ) && (number_of_predecessors < (10.0 - Digital_Transition_Area_Predecessor)))
|
if ((number_of_predecessors > Digital_Transition_Area_Predecessor ) && (number_of_predecessors < (10.0 - Digital_Transition_Area_Predecessor)))
|
||||||
{
|
{
|
||||||
// no digit change, because predecessor is far enough away (0+/-DigitalTransitionRangePredecessor) --> number is rounded
|
// no digit change, because predecessor is far enough away (0+/-DigitalTransitionRangePredecessor) --> number is rounded
|
||||||
if ((result_after_decimal_point <= DigitalBand) || (result_after_decimal_point >= (10-DigitalBand))) // Band around the digit --> Round off, as digit reaches inaccuracy in the frame
|
// Band around the digit --> Round off, as digit reaches inaccuracy in the frame
|
||||||
|
if ((result_after_decimal_point <= DigitalBand) || (result_after_decimal_point >= (10-DigitalBand))) {
|
||||||
result = ((int) round(number) + 10) % 10;
|
result = ((int) round(number) + 10) % 10;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
result = ((int) trunc(number) + 10) % 10;
|
result = ((int) trunc(number) + 10) % 10;
|
||||||
|
}
|
||||||
|
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - NO analogue predecessor, no change of digits, as pre-decimal point far enough away = " + std::to_string(result) +
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - NO analogue predecessor, no change of digits, as pre-decimal point far enough away = " + std::to_string(result) +
|
||||||
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty));
|
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eval_predecessors <= 1) // Zero crossing at the predecessor has taken place (! evaluation via Prev_value and not number!) --> round up here (2.8 --> 3, but also 3.1 --> 3)
|
// Zero crossing at the predecessor has taken place (! evaluation via Prev_value and not number!) --> round up here (2.8 --> 3, but also 3.1 --> 3)
|
||||||
{
|
if (eval_predecessors <= 1) {
|
||||||
// We simply assume that the current digit after the zero crossing of the predecessor
|
// We simply assume that the current digit after the zero crossing of the predecessor
|
||||||
// has passed through at least half (x.5)
|
// has passed through at least half (x.5)
|
||||||
if (result_after_decimal_point > 5)
|
if (result_after_decimal_point > 5) {
|
||||||
// The current digit does not yet have a zero crossing, but the predecessor does..
|
// The current digit does not yet have a zero crossing, but the predecessor does..
|
||||||
result = (result_before_decimal_point + 1) % 10;
|
result = (result_before_decimal_point + 1) % 10;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
// Act. digit and predecessor have zero crossing
|
// Act. digit and predecessor have zero crossing
|
||||||
result = result_before_decimal_point % 10;
|
result = result_before_decimal_point % 10;
|
||||||
|
}
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - NO analogue predecessor, zero crossing has taken placen = " + std::to_string(result) +
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - NO analogue predecessor, zero crossing has taken placen = " + std::to_string(result) +
|
||||||
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty));
|
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty));
|
||||||
return result;
|
return result;
|
||||||
@@ -199,10 +209,12 @@ int ClassFlowCNNGeneral::PointerEvalHybridNew(float number, float number_of_pred
|
|||||||
|| result_after_decimal_point >= 4)
|
|| result_after_decimal_point >= 4)
|
||||||
// The current digit, like the previous digit, does not yet have a zero crossing.
|
// The current digit, like the previous digit, does not yet have a zero crossing.
|
||||||
result = result_before_decimal_point % 10;
|
result = result_before_decimal_point % 10;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
// current digit precedes the smaller digit (9.x). So already >=x.0 while the previous digit has not yet
|
// current digit precedes the smaller digit (9.x). So already >=x.0 while the previous digit has not yet
|
||||||
// has no zero crossing. Therefore, it is reduced by 1.
|
// has no zero crossing. Therefore, it is reduced by 1.
|
||||||
result = (result_before_decimal_point - 1 + 10) % 10;
|
result = (result_before_decimal_point - 1 + 10) % 10;
|
||||||
|
}
|
||||||
|
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - O analogue predecessor, >= 9.5 --> no zero crossing yet = " + std::to_string(result) +
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - O analogue predecessor, >= 9.5 --> no zero crossing yet = " + std::to_string(result) +
|
||||||
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty) + " result_after_decimal_point = " + std::to_string(result_after_decimal_point));
|
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty) + " result_after_decimal_point = " + std::to_string(result_after_decimal_point));
|
||||||
@@ -210,8 +222,7 @@ int ClassFlowCNNGeneral::PointerEvalHybridNew(float number, float number_of_pred
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ClassFlowCNNGeneral::PointerEvalAnalogToDigitNew(float number, float numeral_preceder, int eval_predecessors, float analogDigitalTransitionStart)
|
int ClassFlowCNNGeneral::PointerEvalAnalogToDigitNew(float number, float numeral_preceder, int eval_predecessors, float analogDigitalTransitionStart) {
|
||||||
{
|
|
||||||
int result;
|
int result;
|
||||||
int result_after_decimal_point = ((int) floor(number * 10)) % 10;
|
int result_after_decimal_point = ((int) floor(number * 10)) % 10;
|
||||||
int result_before_decimal_point = ((int) floor(number) + 10) % 10;
|
int result_before_decimal_point = ((int) floor(number) + 10) % 10;
|
||||||
@@ -253,21 +264,17 @@ int ClassFlowCNNGeneral::PointerEvalAnalogToDigitNew(float number, float numeral
|
|||||||
" number: " + std::to_string(number) +
|
" number: " + std::to_string(number) +
|
||||||
" numeral_preceder = " + std::to_string(numeral_preceder) +
|
" numeral_preceder = " + std::to_string(numeral_preceder) +
|
||||||
" eerg after comma = " + std::to_string(result_after_decimal_point));
|
" eerg after comma = " + std::to_string(result_after_decimal_point));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ClassFlowCNNGeneral::PointerEvalAnalogNew(float number, int numeral_preceder)
|
int ClassFlowCNNGeneral::PointerEvalAnalogNew(float number, int numeral_preceder) {
|
||||||
{
|
|
||||||
float number_min, number_max;
|
float number_min, number_max;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (numeral_preceder == -1)
|
if (numeral_preceder == -1) {
|
||||||
{
|
|
||||||
result = (int) floor(number);
|
result = (int) floor(number);
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalAnalogNew - No predecessor - Result = " + std::to_string(result) +
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalAnalogNew - No predecessor - Result = " + std::to_string(result) +
|
||||||
" number: " + std::to_string(number) + " numeral_preceder = " + std::to_string(numeral_preceder) + " Analog_error = " + std::to_string(Analog_error));
|
" number: " + std::to_string(number) + " numeral_preceder = " + std::to_string(numeral_preceder) + " Analog_error = " + std::to_string(Analog_error));
|
||||||
@@ -277,17 +284,14 @@ int ClassFlowCNNGeneral::PointerEvalAnalogNew(float number, int numeral_preceder
|
|||||||
number_min = number - Analog_error / 10.0;
|
number_min = number - Analog_error / 10.0;
|
||||||
number_max = number + Analog_error / 10.0;
|
number_max = number + Analog_error / 10.0;
|
||||||
|
|
||||||
if ((int) floor(number_max) - (int) floor(number_min) != 0)
|
if ((int) floor(number_max) - (int) floor(number_min) != 0) {
|
||||||
{
|
if (numeral_preceder <= Analog_error) {
|
||||||
if (numeral_preceder <= Analog_error)
|
|
||||||
{
|
|
||||||
result = ((int) floor(number_max) + 10) % 10;
|
result = ((int) floor(number_max) + 10) % 10;
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalAnalogNew - number ambiguous, correction upwards - result = " + std::to_string(result) +
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalAnalogNew - number ambiguous, correction upwards - result = " + std::to_string(result) +
|
||||||
" number: " + std::to_string(number) + " numeral_preceder = " + std::to_string(numeral_preceder) + " Analog_error = " + std::to_string(Analog_error));
|
" number: " + std::to_string(number) + " numeral_preceder = " + std::to_string(numeral_preceder) + " Analog_error = " + std::to_string(Analog_error));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (numeral_preceder >= 10 - Analog_error)
|
if (numeral_preceder >= 10 - Analog_error) {
|
||||||
{
|
|
||||||
result = ((int) floor(number_min) + 10) % 10;
|
result = ((int) floor(number_min) + 10) % 10;
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalAnalogNew - number ambiguous, downward correction - result = " + std::to_string(result) +
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalAnalogNew - number ambiguous, downward correction - result = " + std::to_string(result) +
|
||||||
" number: " + std::to_string(number) + " numeral_preceder = " + std::to_string(numeral_preceder) + " Analog_error = " + std::to_string(Analog_error));
|
" number: " + std::to_string(number) + " numeral_preceder = " + std::to_string(numeral_preceder) + " Analog_error = " + std::to_string(Analog_error));
|
||||||
@@ -295,7 +299,6 @@ int ClassFlowCNNGeneral::PointerEvalAnalogNew(float number, int numeral_preceder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
result = ((int) floor(number) + 10) % 10;
|
result = ((int) floor(number) + 10) % 10;
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalAnalogNew - number unambiguous, no correction necessary - result = " + std::to_string(result) +
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalAnalogNew - number unambiguous, no correction necessary - result = " + std::to_string(result) +
|
||||||
" number: " + std::to_string(number) + " numeral_preceder = " + std::to_string(numeral_preceder) + " Analog_error = " + std::to_string(Analog_error));
|
" number: " + std::to_string(number) + " numeral_preceder = " + std::to_string(numeral_preceder) + " Analog_error = " + std::to_string(Analog_error));
|
||||||
@@ -304,25 +307,25 @@ int ClassFlowCNNGeneral::PointerEvalAnalogNew(float number, int numeral_preceder
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph) {
|
||||||
{
|
|
||||||
std::vector<string> splitted;
|
std::vector<string> splitted;
|
||||||
|
|
||||||
aktparamgraph = trim(aktparamgraph);
|
aktparamgraph = trim(aktparamgraph);
|
||||||
|
|
||||||
if (aktparamgraph.size() == 0)
|
if (aktparamgraph.size() == 0) {
|
||||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
if (!this->GetNextParagraph(pfile, aktparamgraph)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((toUpper(aktparamgraph) != "[ANALOG]") && (toUpper(aktparamgraph) != ";[ANALOG]")
|
if ((toUpper(aktparamgraph) != "[ANALOG]") && (toUpper(aktparamgraph) != ";[ANALOG]")
|
||||||
&& (toUpper(aktparamgraph) != "[DIGIT]") && (toUpper(aktparamgraph) != ";[DIGIT]")
|
&& (toUpper(aktparamgraph) != "[DIGIT]") && (toUpper(aktparamgraph) != ";[DIGIT]")
|
||||||
&& (toUpper(aktparamgraph) != "[DIGITS]") && (toUpper(aktparamgraph) != ";[DIGITS]")
|
&& (toUpper(aktparamgraph) != "[DIGITS]") && (toUpper(aktparamgraph) != ";[DIGITS]")) {
|
||||||
) // Paragraph passt nicht
|
// Paragraph passt nicht
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (aktparamgraph[0] == ';')
|
if (aktparamgraph[0] == ';') {
|
||||||
{
|
|
||||||
disabled = true;
|
disabled = true;
|
||||||
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
|
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
|
||||||
ESP_LOGD(TAG, "[Analog/Digit] is disabled!");
|
ESP_LOGD(TAG, "[Analog/Digit] is disabled!");
|
||||||
@@ -330,36 +333,31 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) {
|
||||||
{
|
|
||||||
splitted = ZerlegeZeile(aktparamgraph);
|
splitted = ZerlegeZeile(aktparamgraph);
|
||||||
if ((toUpper(splitted[0]) == "ROIIMAGESLOCATION") && (splitted.size() > 1))
|
if ((toUpper(splitted[0]) == "ROIIMAGESLOCATION") && (splitted.size() > 1)) {
|
||||||
{
|
|
||||||
this->imagesLocation = "/sdcard" + splitted[1];
|
this->imagesLocation = "/sdcard" + splitted[1];
|
||||||
this->isLogImage = true;
|
this->isLogImage = true;
|
||||||
}
|
}
|
||||||
if ((toUpper(splitted[0]) == "LOGIMAGESELECT") && (splitted.size() > 1))
|
|
||||||
{
|
if ((toUpper(splitted[0]) == "LOGIMAGESELECT") && (splitted.size() > 1)) {
|
||||||
LogImageSelect = splitted[1];
|
LogImageSelect = splitted[1];
|
||||||
isLogImageSelect = true;
|
isLogImageSelect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "ROIIMAGESRETENTION") && (splitted.size() > 1))
|
if ((toUpper(splitted[0]) == "ROIIMAGESRETENTION") && (splitted.size() > 1)) {
|
||||||
{
|
|
||||||
this->imagesRetention = std::stoi(splitted[1]);
|
this->imagesRetention = std::stoi(splitted[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "MODEL") && (splitted.size() > 1))
|
if ((toUpper(splitted[0]) == "MODEL") && (splitted.size() > 1)) {
|
||||||
{
|
|
||||||
this->cnnmodelfile = splitted[1];
|
this->cnnmodelfile = splitted[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "CNNGOODTHRESHOLD") && (splitted.size() > 1))
|
if ((toUpper(splitted[0]) == "CNNGOODTHRESHOLD") && (splitted.size() > 1)) {
|
||||||
{
|
|
||||||
CNNGoodThreshold = std::stof(splitted[1]);
|
CNNGoodThreshold = std::stof(splitted[1]);
|
||||||
}
|
}
|
||||||
if (splitted.size() >= 5)
|
|
||||||
{
|
if (splitted.size() >= 5) {
|
||||||
general* _analog = GetGENERAL(splitted[0], true);
|
general* _analog = GetGENERAL(splitted[0], true);
|
||||||
roi* neuroi = _analog->ROI[_analog->ROI.size()-1];
|
roi* neuroi = _analog->ROI[_analog->ROI.size()-1];
|
||||||
neuroi->posx = std::stoi(splitted[1]);
|
neuroi->posx = std::stoi(splitted[1]);
|
||||||
@@ -367,19 +365,20 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
|||||||
neuroi->deltax = std::stoi(splitted[3]);
|
neuroi->deltax = std::stoi(splitted[3]);
|
||||||
neuroi->deltay = std::stoi(splitted[4]);
|
neuroi->deltay = std::stoi(splitted[4]);
|
||||||
neuroi->CCW = false;
|
neuroi->CCW = false;
|
||||||
if (splitted.size() >= 6)
|
|
||||||
{
|
if (splitted.size() >= 6) {
|
||||||
neuroi->CCW = toUpper(splitted[5]) == "TRUE";
|
neuroi->CCW = toUpper(splitted[5]) == "TRUE";
|
||||||
}
|
}
|
||||||
|
|
||||||
neuroi->result_float = -1;
|
neuroi->result_float = -1;
|
||||||
neuroi->image = NULL;
|
neuroi->image = NULL;
|
||||||
neuroi->image_org = NULL;
|
neuroi->image_org = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) {
|
||||||
{
|
if (toUpper(splitted[1]) == "TRUE") {
|
||||||
if (toUpper(splitted[1]) == "TRUE")
|
|
||||||
SaveAllFiles = true;
|
SaveAllFiles = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,55 +389,57 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
|
for (int _ana = 0; _ana < GENERAL.size(); ++_ana) {
|
||||||
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
|
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i) {
|
||||||
{
|
|
||||||
GENERAL[_ana]->ROI[i]->image = new CImageBasis("ROI " + GENERAL[_ana]->ROI[i]->name,
|
GENERAL[_ana]->ROI[i]->image = new CImageBasis("ROI " + GENERAL[_ana]->ROI[i]->name,
|
||||||
modelxsize, modelysize, modelchannel);
|
modelxsize, modelysize, modelchannel);
|
||||||
GENERAL[_ana]->ROI[i]->image_org = new CImageBasis("ROI " + GENERAL[_ana]->ROI[i]->name + " original",
|
GENERAL[_ana]->ROI[i]->image_org = new CImageBasis("ROI " + GENERAL[_ana]->ROI[i]->name + " original",
|
||||||
GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, 3);
|
GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, 3);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
general* ClassFlowCNNGeneral::FindGENERAL(string _name_number)
|
general* ClassFlowCNNGeneral::FindGENERAL(string _name_number) {
|
||||||
{
|
for (int i = 0; i < GENERAL.size(); ++i) {
|
||||||
for (int i = 0; i < GENERAL.size(); ++i)
|
if (GENERAL[i]->name == _name_number) {
|
||||||
if (GENERAL[i]->name == _name_number)
|
|
||||||
return GENERAL[i];
|
return GENERAL[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
general* ClassFlowCNNGeneral::GetGENERAL(string _name, bool _create = true)
|
general* ClassFlowCNNGeneral::GetGENERAL(string _name, bool _create = true) {
|
||||||
{
|
|
||||||
string _analog, _roi;
|
string _analog, _roi;
|
||||||
int _pospunkt = _name.find_first_of(".");
|
int _pospunkt = _name.find_first_of(".");
|
||||||
|
|
||||||
if (_pospunkt > -1)
|
if (_pospunkt > -1) {
|
||||||
{
|
|
||||||
_analog = _name.substr(0, _pospunkt);
|
_analog = _name.substr(0, _pospunkt);
|
||||||
_roi = _name.substr(_pospunkt+1, _name.length() - _pospunkt - 1);
|
_roi = _name.substr(_pospunkt+1, _name.length() - _pospunkt - 1);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
_analog = "default";
|
_analog = "default";
|
||||||
_roi = _name;
|
_roi = _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
general *_ret = NULL;
|
general *_ret = NULL;
|
||||||
|
|
||||||
for (int i = 0; i < GENERAL.size(); ++i)
|
for (int i = 0; i < GENERAL.size(); ++i) {
|
||||||
if (GENERAL[i]->name == _analog)
|
if (GENERAL[i]->name == _analog) {
|
||||||
_ret = GENERAL[i];
|
_ret = GENERAL[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!_create) // not found and should not be created
|
// not found and should not be created
|
||||||
|
if (!_create) {
|
||||||
return _ret;
|
return _ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (_ret == NULL)
|
if (_ret == NULL) {
|
||||||
{
|
|
||||||
_ret = new general;
|
_ret = new general;
|
||||||
_ret->name = _analog;
|
_ret->name = _analog;
|
||||||
GENERAL.push_back(_ret);
|
GENERAL.push_back(_ret);
|
||||||
@@ -455,8 +456,7 @@ general* ClassFlowCNNGeneral::GetGENERAL(string _name, bool _create = true)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string ClassFlowCNNGeneral::getHTMLSingleStep(string host)
|
string ClassFlowCNNGeneral::getHTMLSingleStep(string host) {
|
||||||
{
|
|
||||||
string result, zw;
|
string result, zw;
|
||||||
std::vector<HTMLInfo*> htmlinfo;
|
std::vector<HTMLInfo*> htmlinfo;
|
||||||
|
|
||||||
@@ -464,8 +464,8 @@ string ClassFlowCNNGeneral::getHTMLSingleStep(string host)
|
|||||||
result = result + "Analog Pointers: <p> ";
|
result = result + "Analog Pointers: <p> ";
|
||||||
|
|
||||||
htmlinfo = GetHTMLInfo();
|
htmlinfo = GetHTMLInfo();
|
||||||
for (int i = 0; i < htmlinfo.size(); ++i)
|
|
||||||
{
|
for (int i = 0; i < htmlinfo.size(); ++i) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << std::fixed << std::setprecision(1) << htmlinfo[i]->val;
|
stream << std::fixed << std::setprecision(1) << htmlinfo[i]->val;
|
||||||
zw = stream.str();
|
zw = stream.str();
|
||||||
@@ -473,15 +473,14 @@ string ClassFlowCNNGeneral::getHTMLSingleStep(string host)
|
|||||||
result = result + "<img src=\"" + host + "/img_tmp/" + htmlinfo[i]->filename + "\"> " + zw;
|
result = result + "<img src=\"" + host + "/img_tmp/" + htmlinfo[i]->filename + "\"> " + zw;
|
||||||
delete htmlinfo[i];
|
delete htmlinfo[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlinfo.clear();
|
htmlinfo.clear();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowCNNGeneral::doFlow(string time)
|
bool ClassFlowCNNGeneral::doFlow(string time) {
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef HEAP_TRACING_CLASS_FLOW_CNN_GENERAL_DO_ALING_AND_CUT
|
#ifdef HEAP_TRACING_CLASS_FLOW_CNN_GENERAL_DO_ALING_AND_CUT
|
||||||
//register a buffer to record the memory trace
|
//register a buffer to record the memory trace
|
||||||
ESP_ERROR_CHECK( heap_trace_init_standalone(trace_record, NUM_RECORDS) );
|
ESP_ERROR_CHECK( heap_trace_init_standalone(trace_record, NUM_RECORDS) );
|
||||||
@@ -489,8 +488,9 @@ bool ClassFlowCNNGeneral::doFlow(string time)
|
|||||||
ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
|
ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (disabled)
|
if (disabled) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!doAlignAndCut(time)){
|
if (!doAlignAndCut(time)){
|
||||||
return false;
|
return false;
|
||||||
@@ -511,79 +511,80 @@ bool ClassFlowCNNGeneral::doFlow(string time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowCNNGeneral::doAlignAndCut(string time)
|
bool ClassFlowCNNGeneral::doAlignAndCut(string time) {
|
||||||
{
|
if (disabled) {
|
||||||
if (disabled)
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
|
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
|
||||||
|
|
||||||
for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
|
for (int _ana = 0; _ana < GENERAL.size(); ++_ana) {
|
||||||
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
|
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i) {
|
||||||
{
|
|
||||||
ESP_LOGD(TAG, "General %d - Align&Cut", i);
|
ESP_LOGD(TAG, "General %d - Align&Cut", i);
|
||||||
|
|
||||||
caic->CutAndSave(GENERAL[_ana]->ROI[i]->posx, GENERAL[_ana]->ROI[i]->posy, GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, GENERAL[_ana]->ROI[i]->image_org);
|
caic->CutAndSave(GENERAL[_ana]->ROI[i]->posx, GENERAL[_ana]->ROI[i]->posy, GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, GENERAL[_ana]->ROI[i]->image_org);
|
||||||
if (SaveAllFiles)
|
if (SaveAllFiles) {
|
||||||
{
|
if (GENERAL[_ana]->name == "default") {
|
||||||
if (GENERAL[_ana]->name == "default")
|
|
||||||
GENERAL[_ana]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
GENERAL[_ana]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
GENERAL[_ana]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
GENERAL[_ana]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GENERAL[_ana]->ROI[i]->image_org->Resize(modelxsize, modelysize, GENERAL[_ana]->ROI[i]->image);
|
GENERAL[_ana]->ROI[i]->image_org->Resize(modelxsize, modelysize, GENERAL[_ana]->ROI[i]->image);
|
||||||
if (SaveAllFiles)
|
if (SaveAllFiles) {
|
||||||
{
|
if (GENERAL[_ana]->name == "default") {
|
||||||
if (GENERAL[_ana]->name == "default")
|
|
||||||
GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClassFlowCNNGeneral::DrawROI(CImageBasis *_zw)
|
void ClassFlowCNNGeneral::DrawROI(CImageBasis *_zw) {
|
||||||
{
|
if (_zw->ImageOkay()) {
|
||||||
if (_zw->ImageOkay())
|
if (CNNType == Analogue || CNNType == Analogue100) {
|
||||||
{
|
|
||||||
if (CNNType == Analogue || CNNType == Analogue100)
|
|
||||||
{
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int g = 255;
|
int g = 255;
|
||||||
int b = 0;
|
int b = 0;
|
||||||
|
|
||||||
for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
|
for (int _ana = 0; _ana < GENERAL.size(); ++_ana) {
|
||||||
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
|
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i) {
|
||||||
{
|
|
||||||
_zw->drawRect(GENERAL[_ana]->ROI[i]->posx, GENERAL[_ana]->ROI[i]->posy, GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, r, g, b, 1);
|
_zw->drawRect(GENERAL[_ana]->ROI[i]->posx, GENERAL[_ana]->ROI[i]->posy, GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, r, g, b, 1);
|
||||||
_zw->drawEllipse( (int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), (int) (GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->deltay/2), r, g, b, 2);
|
_zw->drawEllipse( (int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), (int) (GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->deltay/2), r, g, b, 2);
|
||||||
_zw->drawLine((int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) GENERAL[_ana]->ROI[i]->posy, (int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay), r, g, b, 2);
|
_zw->drawLine((int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) GENERAL[_ana]->ROI[i]->posy, (int) (GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax/2), (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay), r, g, b, 2);
|
||||||
_zw->drawLine((int) GENERAL[_ana]->ROI[i]->posx, (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), (int) GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax, (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), r, g, b, 2);
|
_zw->drawLine((int) GENERAL[_ana]->ROI[i]->posx, (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), (int) GENERAL[_ana]->ROI[i]->posx + GENERAL[_ana]->ROI[i]->deltax, (int) (GENERAL[_ana]->ROI[i]->posy + GENERAL[_ana]->ROI[i]->deltay/2), r, g, b, 2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
for (int _dig = 0; _dig < GENERAL.size(); ++_dig) {
|
||||||
for (int _dig = 0; _dig < GENERAL.size(); ++_dig)
|
for (int i = 0; i < GENERAL[_dig]->ROI.size(); ++i) {
|
||||||
for (int i = 0; i < GENERAL[_dig]->ROI.size(); ++i)
|
|
||||||
_zw->drawRect(GENERAL[_dig]->ROI[i]->posx, GENERAL[_dig]->ROI[i]->posy, GENERAL[_dig]->ROI[i]->deltax, GENERAL[_dig]->ROI[i]->deltay, 0, 0, (255 - _dig*100), 2);
|
_zw->drawRect(GENERAL[_dig]->ROI[i]->posx, GENERAL[_dig]->ROI[i]->posy, GENERAL[_dig]->ROI[i]->deltax, GENERAL[_dig]->ROI[i]->deltay, 0, 0, (255 - _dig*100), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowCNNGeneral::getNetworkParameter()
|
bool ClassFlowCNNGeneral::getNetworkParameter() {
|
||||||
{
|
if (disabled) {
|
||||||
if (disabled)
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
CTfLiteClass *tflite = new CTfLiteClass;
|
CTfLiteClass *tflite = new CTfLiteClass;
|
||||||
string zwcnn = "/sdcard" + cnnmodelfile;
|
string zwcnn = "/sdcard" + cnnmodelfile;
|
||||||
zwcnn = FormatFileName(zwcnn);
|
zwcnn = FormatFileName(zwcnn);
|
||||||
ESP_LOGD(TAG, "%s", zwcnn.c_str());
|
ESP_LOGD(TAG, "%s", zwcnn.c_str());
|
||||||
|
|
||||||
if (!tflite->LoadModel(zwcnn)) {
|
if (!tflite->LoadModel(zwcnn)) {
|
||||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't load tflite model " + cnnmodelfile + " -> Init aborted!");
|
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't load tflite model " + cnnmodelfile + " -> Init aborted!");
|
||||||
LogFile.WriteHeapInfo("getNetworkParameter-LoadModel");
|
LogFile.WriteHeapInfo("getNetworkParameter-LoadModel");
|
||||||
@@ -598,16 +599,14 @@ bool ClassFlowCNNGeneral::getNetworkParameter()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CNNType == AutoDetect)
|
if (CNNType == AutoDetect) {
|
||||||
{
|
|
||||||
tflite->GetInputDimension(false);
|
tflite->GetInputDimension(false);
|
||||||
modelxsize = tflite->ReadInputDimenstion(0);
|
modelxsize = tflite->ReadInputDimenstion(0);
|
||||||
modelysize = tflite->ReadInputDimenstion(1);
|
modelysize = tflite->ReadInputDimenstion(1);
|
||||||
modelchannel = tflite->ReadInputDimenstion(2);
|
modelchannel = tflite->ReadInputDimenstion(2);
|
||||||
|
|
||||||
int _anzoutputdimensions = tflite->GetAnzOutPut();
|
int _anzoutputdimensions = tflite->GetAnzOutPut();
|
||||||
switch (_anzoutputdimensions)
|
switch (_anzoutputdimensions) {
|
||||||
{
|
|
||||||
case 2:
|
case 2:
|
||||||
CNNType = Analogue;
|
CNNType = Analogue;
|
||||||
ESP_LOGD(TAG, "TFlite-Type set to Analogue");
|
ESP_LOGD(TAG, "TFlite-Type set to Analogue");
|
||||||
@@ -633,7 +632,8 @@ bool ClassFlowCNNGeneral::getNetworkParameter()
|
|||||||
if (modelxsize==32 && modelysize == 32) {
|
if (modelxsize==32 && modelysize == 32) {
|
||||||
CNNType = Analogue100;
|
CNNType = Analogue100;
|
||||||
ESP_LOGD(TAG, "TFlite-Type set to Analogue100");
|
ESP_LOGD(TAG, "TFlite-Type set to Analogue100");
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
CNNType = Digital100;
|
CNNType = Digital100;
|
||||||
ESP_LOGD(TAG, "TFlite-Type set to Digital");
|
ESP_LOGD(TAG, "TFlite-Type set to Digital");
|
||||||
}
|
}
|
||||||
@@ -648,10 +648,10 @@ bool ClassFlowCNNGeneral::getNetworkParameter()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
bool ClassFlowCNNGeneral::doNeuralNetwork(string time) {
|
||||||
{
|
if (disabled) {
|
||||||
if (disabled)
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
string logPath = CreateLogFolder(time);
|
string logPath = CreateLogFolder(time);
|
||||||
|
|
||||||
@@ -674,11 +674,11 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int n = 0; n < GENERAL.size(); ++n) // For each NUMBER
|
// For each NUMBER
|
||||||
{
|
for (int n = 0; n < GENERAL.size(); ++n) {
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Processing Number '" + GENERAL[n]->name + "'");
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Processing Number '" + GENERAL[n]->name + "'");
|
||||||
for (int roi = 0; roi < GENERAL[n]->ROI.size(); ++roi) // For each ROI
|
// For each ROI
|
||||||
{
|
for (int roi = 0; roi < GENERAL[n]->ROI.size(); ++roi) {
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "ROI #" + std::to_string(roi) + " - TfLite");
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "ROI #" + std::to_string(roi) + " - TfLite");
|
||||||
//ESP_LOGD(TAG, "General %d - TfLite", i);
|
//ESP_LOGD(TAG, "General %d - TfLite", i);
|
||||||
|
|
||||||
@@ -697,14 +697,17 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
|||||||
f2 = tflite->GetOutputValue(1);
|
f2 = tflite->GetOutputValue(1);
|
||||||
float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1);
|
float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1);
|
||||||
|
|
||||||
if(GENERAL[n]->ROI[roi]->CCW)
|
if(GENERAL[n]->ROI[roi]->CCW) {
|
||||||
GENERAL[n]->ROI[roi]->result_float = 10 - (result * 10);
|
GENERAL[n]->ROI[roi]->result_float = 10 - (result * 10);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
GENERAL[n]->ROI[roi]->result_float = result * 10;
|
GENERAL[n]->ROI[roi]->result_float = result * 10;
|
||||||
|
}
|
||||||
|
|
||||||
ESP_LOGD(TAG, "General result (Analog)%i - CCW: %d - %f", roi, GENERAL[n]->ROI[roi]->CCW, GENERAL[n]->ROI[roi]->result_float);
|
ESP_LOGD(TAG, "General result (Analog)%i - CCW: %d - %f", roi, GENERAL[n]->ROI[roi]->CCW, GENERAL[n]->ROI[roi]->result_float);
|
||||||
if (isLogImage)
|
if (isLogImage) {
|
||||||
LogImage(logPath, GENERAL[n]->ROI[roi]->name, &GENERAL[n]->ROI[roi]->result_float, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
LogImage(logPath, GENERAL[n]->ROI[roi]->name, &GENERAL[n]->ROI[roi]->result_float, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Digital:
|
case Digital:
|
||||||
@@ -714,22 +717,19 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
|||||||
GENERAL[n]->ROI[roi]->result_klasse = tflite->GetClassFromImageBasis(GENERAL[n]->ROI[roi]->image);
|
GENERAL[n]->ROI[roi]->result_klasse = tflite->GetClassFromImageBasis(GENERAL[n]->ROI[roi]->image);
|
||||||
ESP_LOGD(TAG, "General result (Digit)%i: %d", roi, GENERAL[n]->ROI[roi]->result_klasse);
|
ESP_LOGD(TAG, "General result (Digit)%i: %d", roi, GENERAL[n]->ROI[roi]->result_klasse);
|
||||||
|
|
||||||
if (isLogImage)
|
if (isLogImage) {
|
||||||
{
|
|
||||||
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
||||||
if (isLogImageSelect)
|
if (isLogImageSelect) {
|
||||||
{
|
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos) {
|
||||||
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos)
|
|
||||||
LogImage(logPath, _imagename, NULL, &GENERAL[n]->ROI[roi]->result_klasse, time, GENERAL[n]->ROI[roi]->image_org);
|
LogImage(logPath, _imagename, NULL, &GENERAL[n]->ROI[roi]->result_klasse, time, GENERAL[n]->ROI[roi]->image_org);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
LogImage(logPath, _imagename, NULL, &GENERAL[n]->ROI[roi]->result_klasse, time, GENERAL[n]->ROI[roi]->image_org);
|
LogImage(logPath, _imagename, NULL, &GENERAL[n]->ROI[roi]->result_klasse, time, GENERAL[n]->ROI[roi]->image_org);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
||||||
case DoubleHyprid10:
|
case DoubleHyprid10:
|
||||||
{
|
{
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CNN Type: DoubleHyprid10");
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CNN Type: DoubleHyprid10");
|
||||||
@@ -752,62 +752,56 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
|||||||
|
|
||||||
float result = _num;
|
float result = _num;
|
||||||
|
|
||||||
if (_valplus > _valminus)
|
if (_valplus > _valminus) {
|
||||||
{
|
|
||||||
result = result + _valplus / (_valplus + _val);
|
result = result + _valplus / (_valplus + _val);
|
||||||
_fit = _val + _valplus;
|
_fit = _val + _valplus;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
result = result - _valminus / (_val + _valminus);
|
result = result - _valminus / (_val + _valminus);
|
||||||
_fit = _val + _valminus;
|
_fit = _val + _valminus;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (result >= 10)
|
|
||||||
|
if (result >= 10) {
|
||||||
result = result - 10;
|
result = result - 10;
|
||||||
if (result < 0)
|
}
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
result = result + 10;
|
result = result + 10;
|
||||||
|
}
|
||||||
|
|
||||||
string zw = "_num (p, m): " + to_string(_num) + " " + to_string(_numplus) + " " + to_string(_numminus);
|
string zw = "_num (p, m): " + to_string(_num) + " " + to_string(_numplus) + " " + to_string(_numminus);
|
||||||
zw = zw + " _val (p, m): " + to_string(_val) + " " + to_string(_valplus) + " " + to_string(_valminus);
|
zw = zw + " _val (p, m): " + to_string(_val) + " " + to_string(_valplus) + " " + to_string(_valminus);
|
||||||
zw = zw + " result: " + to_string(result) + " _fit: " + to_string(_fit);
|
zw = zw + " result: " + to_string(result) + " _fit: " + to_string(_fit);
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw);
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw);
|
||||||
|
|
||||||
|
|
||||||
_result_save_file = result;
|
_result_save_file = result;
|
||||||
|
|
||||||
if (_fit < CNNGoodThreshold)
|
if (_fit < CNNGoodThreshold) {
|
||||||
{
|
|
||||||
GENERAL[n]->ROI[roi]->isReject = true;
|
GENERAL[n]->ROI[roi]->isReject = true;
|
||||||
result = -1;
|
result = -1;
|
||||||
_result_save_file+= 100; // In case fit is not sufficient, the result should still be saved with "-10x.y".
|
_result_save_file+= 100; // In case fit is not sufficient, the result should still be saved with "-10x.y".
|
||||||
string zw = "Value Rejected due to Threshold (Fit: " + to_string(_fit) + ", Threshold: " + to_string(CNNGoodThreshold) + ")";
|
string zw = "Value Rejected due to Threshold (Fit: " + to_string(_fit) + ", Threshold: " + to_string(CNNGoodThreshold) + ")";
|
||||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, zw);
|
LogFile.WriteToFile(ESP_LOG_WARN, TAG, zw);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
GENERAL[n]->ROI[roi]->isReject = false;
|
GENERAL[n]->ROI[roi]->isReject = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GENERAL[n]->ROI[roi]->result_float = result;
|
GENERAL[n]->ROI[roi]->result_float = result;
|
||||||
ESP_LOGD(TAG, "Result General(Analog)%i: %f", roi, GENERAL[n]->ROI[roi]->result_float);
|
ESP_LOGD(TAG, "Result General(Analog)%i: %f", roi, GENERAL[n]->ROI[roi]->result_float);
|
||||||
|
|
||||||
if (isLogImage)
|
if (isLogImage) {
|
||||||
{
|
|
||||||
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
||||||
if (isLogImageSelect)
|
if (isLogImageSelect) {
|
||||||
{
|
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos) {
|
||||||
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos)
|
|
||||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case Digital100:
|
case Digital100:
|
||||||
case Analogue100:
|
case Analogue100:
|
||||||
{
|
{
|
||||||
@@ -820,28 +814,27 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
|||||||
|
|
||||||
_num = tflite->GetOutClassification();
|
_num = tflite->GetOutClassification();
|
||||||
|
|
||||||
if(GENERAL[n]->ROI[roi]->CCW)
|
if(GENERAL[n]->ROI[roi]->CCW) {
|
||||||
GENERAL[n]->ROI[roi]->result_float = 10 - ((float)_num / 10.0);
|
GENERAL[n]->ROI[roi]->result_float = 10 - ((float)_num / 10.0);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
GENERAL[n]->ROI[roi]->result_float = (float)_num / 10.0;
|
GENERAL[n]->ROI[roi]->result_float = (float)_num / 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
_result_save_file = GENERAL[n]->ROI[roi]->result_float;
|
_result_save_file = GENERAL[n]->ROI[roi]->result_float;
|
||||||
|
|
||||||
|
|
||||||
GENERAL[n]->ROI[roi]->isReject = false;
|
GENERAL[n]->ROI[roi]->isReject = false;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Result General(Analog)%i - CCW: %d - %f", roi, GENERAL[n]->ROI[roi]->CCW, GENERAL[n]->ROI[roi]->result_float);
|
ESP_LOGD(TAG, "Result General(Analog)%i - CCW: %d - %f", roi, GENERAL[n]->ROI[roi]->CCW, GENERAL[n]->ROI[roi]->result_float);
|
||||||
|
|
||||||
if (isLogImage)
|
if (isLogImage) {
|
||||||
{
|
|
||||||
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
string _imagename = GENERAL[n]->name + "_" + GENERAL[n]->ROI[roi]->name;
|
||||||
if (isLogImageSelect)
|
if (isLogImageSelect) {
|
||||||
{
|
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos) {
|
||||||
if (LogImageSelect.find(GENERAL[n]->ROI[roi]->name) != std::string::npos)
|
|
||||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
LogImage(logPath, _imagename, &_result_save_file, NULL, time, GENERAL[n]->ROI[roi]->image_org);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -860,93 +853,94 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowCNNGeneral::isExtendedResolution(int _number)
|
bool ClassFlowCNNGeneral::isExtendedResolution(int _number) {
|
||||||
{
|
if (CNNType == Digital) {
|
||||||
if (CNNType == Digital)
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<HTMLInfo*> ClassFlowCNNGeneral::GetHTMLInfo()
|
std::vector<HTMLInfo*> ClassFlowCNNGeneral::GetHTMLInfo() {
|
||||||
{
|
|
||||||
std::vector<HTMLInfo*> result;
|
std::vector<HTMLInfo*> result;
|
||||||
|
|
||||||
for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
|
for (int _ana = 0; _ana < GENERAL.size(); ++_ana) {
|
||||||
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
|
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i) {
|
||||||
{
|
|
||||||
ESP_LOGD(TAG, "Image: %d", (int) GENERAL[_ana]->ROI[i]->image);
|
ESP_LOGD(TAG, "Image: %d", (int) GENERAL[_ana]->ROI[i]->image);
|
||||||
if (GENERAL[_ana]->ROI[i]->image)
|
if (GENERAL[_ana]->ROI[i]->image) {
|
||||||
{
|
if (GENERAL[_ana]->name == "default") {
|
||||||
if (GENERAL[_ana]->name == "default")
|
|
||||||
GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
GENERAL[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HTMLInfo *zw = new HTMLInfo;
|
HTMLInfo *zw = new HTMLInfo;
|
||||||
if (GENERAL[_ana]->name == "default")
|
if (GENERAL[_ana]->name == "default") {
|
||||||
{
|
|
||||||
zw->filename = GENERAL[_ana]->ROI[i]->name + ".jpg";
|
zw->filename = GENERAL[_ana]->ROI[i]->name + ".jpg";
|
||||||
zw->filename_org = GENERAL[_ana]->ROI[i]->name + ".jpg";
|
zw->filename_org = GENERAL[_ana]->ROI[i]->name + ".jpg";
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
zw->filename = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg";
|
zw->filename = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg";
|
||||||
zw->filename_org = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg";
|
zw->filename_org = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CNNType == Digital)
|
if (CNNType == Digital) {
|
||||||
zw->val = GENERAL[_ana]->ROI[i]->result_klasse;
|
zw->val = GENERAL[_ana]->ROI[i]->result_klasse;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
zw->val = GENERAL[_ana]->ROI[i]->result_float;
|
zw->val = GENERAL[_ana]->ROI[i]->result_float;
|
||||||
|
}
|
||||||
|
|
||||||
zw->image = GENERAL[_ana]->ROI[i]->image;
|
zw->image = GENERAL[_ana]->ROI[i]->image;
|
||||||
zw->image_org = GENERAL[_ana]->ROI[i]->image_org;
|
zw->image_org = GENERAL[_ana]->ROI[i]->image_org;
|
||||||
|
|
||||||
result.push_back(zw);
|
result.push_back(zw);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ClassFlowCNNGeneral::getNumberGENERAL()
|
int ClassFlowCNNGeneral::getNumberGENERAL() {
|
||||||
{
|
|
||||||
return GENERAL.size();
|
return GENERAL.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string ClassFlowCNNGeneral::getNameGENERAL(int _analog)
|
string ClassFlowCNNGeneral::getNameGENERAL(int _analog) {
|
||||||
{
|
if (_analog < GENERAL.size()) {
|
||||||
if (_analog < GENERAL.size())
|
|
||||||
return GENERAL[_analog]->name;
|
return GENERAL[_analog]->name;
|
||||||
|
}
|
||||||
|
|
||||||
return "GENERAL DOES NOT EXIST";
|
return "GENERAL DOES NOT EXIST";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
general* ClassFlowCNNGeneral::GetGENERAL(int _analog)
|
general* ClassFlowCNNGeneral::GetGENERAL(int _analog) {
|
||||||
{
|
if (_analog < GENERAL.size()) {
|
||||||
if (_analog < GENERAL.size())
|
|
||||||
return GENERAL[_analog];
|
return GENERAL[_analog];
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClassFlowCNNGeneral::UpdateNameNumbers(std::vector<std::string> *_name_numbers)
|
void ClassFlowCNNGeneral::UpdateNameNumbers(std::vector<std::string> *_name_numbers) {
|
||||||
{
|
for (int _dig = 0; _dig < GENERAL.size(); _dig++) {
|
||||||
for (int _dig = 0; _dig < GENERAL.size(); _dig++)
|
|
||||||
{
|
|
||||||
std::string _name = GENERAL[_dig]->name;
|
std::string _name = GENERAL[_dig]->name;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int i = 0; i < (*_name_numbers).size(); ++i)
|
|
||||||
{
|
for (int i = 0; i < (*_name_numbers).size(); ++i) {
|
||||||
if ((*_name_numbers)[i] == _name)
|
if ((*_name_numbers)[i] == _name) {
|
||||||
found = true;
|
found = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found) {
|
||||||
(*_name_numbers).push_back(_name);
|
(*_name_numbers).push_back(_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -955,26 +949,25 @@ string ClassFlowCNNGeneral::getReadoutRawString(int _analog)
|
|||||||
{
|
{
|
||||||
string rt = "";
|
string rt = "";
|
||||||
|
|
||||||
if (_analog >= GENERAL.size() || GENERAL[_analog]==NULL || GENERAL[_analog]->ROI.size() == 0)
|
if (_analog >= GENERAL.size() || GENERAL[_analog]==NULL || GENERAL[_analog]->ROI.size() == 0) {
|
||||||
return rt;
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < GENERAL[_analog]->ROI.size(); ++i)
|
for (int i = 0; i < GENERAL[_analog]->ROI.size(); ++i) {
|
||||||
{
|
if (CNNType == Analogue || CNNType == Analogue100) {
|
||||||
if (CNNType == Analogue || CNNType == Analogue100)
|
|
||||||
{
|
|
||||||
rt = rt + "," + RundeOutput(GENERAL[_analog]->ROI[i]->result_float, 1);
|
rt = rt + "," + RundeOutput(GENERAL[_analog]->ROI[i]->result_float, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CNNType == Digital)
|
if (CNNType == Digital) {
|
||||||
{
|
if (GENERAL[_analog]->ROI[i]->result_klasse >= 10) {
|
||||||
if (GENERAL[_analog]->ROI[i]->result_klasse == 10)
|
|
||||||
rt = rt + ",N";
|
rt = rt + ",N";
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
rt = rt + "," + RundeOutput(GENERAL[_analog]->ROI[i]->result_klasse, 0);
|
rt = rt + "," + RundeOutput(GENERAL[_analog]->ROI[i]->result_klasse, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((CNNType == DoubleHyprid10) || (CNNType == Digital100))
|
if ((CNNType == DoubleHyprid10) || (CNNType == Digital100)) {
|
||||||
{
|
|
||||||
rt = rt + "," + RundeOutput(GENERAL[_analog]->ROI[i]->result_float, 1);
|
rt = rt + "," + RundeOutput(GENERAL[_analog]->ROI[i]->result_float, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ struct NumberPost {
|
|||||||
bool AllowNegativeRates;
|
bool AllowNegativeRates;
|
||||||
bool checkDigitIncreaseConsistency;
|
bool checkDigitIncreaseConsistency;
|
||||||
time_t lastvalue;
|
time_t lastvalue;
|
||||||
|
time_t timeStampTimeUTC;
|
||||||
string timeStamp;
|
string timeStamp;
|
||||||
double FlowRateAct; // m3 / min
|
double FlowRateAct; // m3 / min
|
||||||
double PreValue; // last value that was read out well
|
double PreValue; // last value that was read out well
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ bool ClassFlowInfluxDB::doFlow(string zwtime)
|
|||||||
std::string resultraw = "";
|
std::string resultraw = "";
|
||||||
std::string resultrate = "";
|
std::string resultrate = "";
|
||||||
std::string resulttimestamp = "";
|
std::string resulttimestamp = "";
|
||||||
|
long int timeutc;
|
||||||
string zw = "";
|
string zw = "";
|
||||||
string namenumber = "";
|
string namenumber = "";
|
||||||
|
|
||||||
@@ -152,6 +153,7 @@ bool ClassFlowInfluxDB::doFlow(string zwtime)
|
|||||||
resulterror = (*NUMBERS)[i]->ErrorMessageText;
|
resulterror = (*NUMBERS)[i]->ErrorMessageText;
|
||||||
resultrate = (*NUMBERS)[i]->ReturnRateValue;
|
resultrate = (*NUMBERS)[i]->ReturnRateValue;
|
||||||
resulttimestamp = (*NUMBERS)[i]->timeStamp;
|
resulttimestamp = (*NUMBERS)[i]->timeStamp;
|
||||||
|
timeutc = (*NUMBERS)[i]->timeStampTimeUTC;
|
||||||
|
|
||||||
if ((*NUMBERS)[i]->FieldV1.length() > 0)
|
if ((*NUMBERS)[i]->FieldV1.length() > 0)
|
||||||
{
|
{
|
||||||
@@ -167,7 +169,7 @@ bool ClassFlowInfluxDB::doFlow(string zwtime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result.length() > 0)
|
if (result.length() > 0)
|
||||||
InfluxDBPublish(measurement, namenumber, result, resulttimestamp);
|
InfluxDBPublish(measurement, namenumber, result, timeutc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ bool ClassFlowInfluxDBv2::doFlow(string zwtime)
|
|||||||
std::string resultraw = "";
|
std::string resultraw = "";
|
||||||
std::string resultrate = "";
|
std::string resultrate = "";
|
||||||
std::string resulttimestamp = "";
|
std::string resulttimestamp = "";
|
||||||
|
long int resulttimeutc = 0;
|
||||||
string zw = "";
|
string zw = "";
|
||||||
string namenumber = "";
|
string namenumber = "";
|
||||||
|
|
||||||
@@ -212,6 +213,8 @@ bool ClassFlowInfluxDBv2::doFlow(string zwtime)
|
|||||||
resulterror = (*NUMBERS)[i]->ErrorMessageText;
|
resulterror = (*NUMBERS)[i]->ErrorMessageText;
|
||||||
resultrate = (*NUMBERS)[i]->ReturnRateValue;
|
resultrate = (*NUMBERS)[i]->ReturnRateValue;
|
||||||
resulttimestamp = (*NUMBERS)[i]->timeStamp;
|
resulttimestamp = (*NUMBERS)[i]->timeStamp;
|
||||||
|
resulttimeutc = (*NUMBERS)[i]->timeStampTimeUTC;
|
||||||
|
|
||||||
|
|
||||||
if ((*NUMBERS)[i]->FieldV2.length() > 0)
|
if ((*NUMBERS)[i]->FieldV2.length() > 0)
|
||||||
{
|
{
|
||||||
@@ -229,8 +232,7 @@ bool ClassFlowInfluxDBv2::doFlow(string zwtime)
|
|||||||
printf("vor sende Influx_DB_V2 - namenumber. %s, result: %s, timestampt: %s", namenumber.c_str(), result.c_str(), resulttimestamp.c_str());
|
printf("vor sende Influx_DB_V2 - namenumber. %s, result: %s, timestampt: %s", namenumber.c_str(), result.c_str(), resulttimestamp.c_str());
|
||||||
|
|
||||||
if (result.length() > 0)
|
if (result.length() > 0)
|
||||||
InfluxDB_V2_Publish(measurement, namenumber, result, resulttimestamp);
|
InfluxDB_V2_Publish(measurement, namenumber, result, resulttimeutc);
|
||||||
// InfluxDB_V2_Publish(namenumber, result, resulttimestamp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,15 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
#include "ClassFlowTakeImage.h"
|
#include "ClassFlowTakeImage.h"
|
||||||
#include "Helper.h"
|
#include "Helper.h"
|
||||||
#include "ClassLogFile.h"
|
#include "ClassLogFile.h"
|
||||||
|
|
||||||
#include "CImageBasis.h"
|
#include "CImageBasis.h"
|
||||||
#include "ClassControllCamera.h"
|
#include "ClassControllCamera.h"
|
||||||
|
#include "MainFlowControl.h"
|
||||||
|
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
@@ -13,13 +19,13 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
// #define DEBUG_DETAIL_ON
|
// #define DEBUG_DETAIL_ON
|
||||||
|
|
||||||
// #define WIFITURNOFF
|
// #define WIFITURNOFF
|
||||||
|
|
||||||
static const char* TAG = "TAKEIMAGE";
|
static const char *TAG = "TAKEIMAGE";
|
||||||
|
|
||||||
esp_err_t ClassFlowTakeImage::camera_capture(){
|
esp_err_t ClassFlowTakeImage::camera_capture(void)
|
||||||
string nm = namerawimage;
|
{
|
||||||
|
string nm = namerawimage;
|
||||||
Camera.CaptureToFile(nm);
|
Camera.CaptureToFile(nm);
|
||||||
time(&TimeImageTaken);
|
time(&TimeImageTaken);
|
||||||
localtime(&TimeImageTaken);
|
localtime(&TimeImageTaken);
|
||||||
@@ -30,150 +36,480 @@ esp_err_t ClassFlowTakeImage::camera_capture(){
|
|||||||
void ClassFlowTakeImage::takePictureWithFlash(int flash_duration)
|
void ClassFlowTakeImage::takePictureWithFlash(int flash_duration)
|
||||||
{
|
{
|
||||||
// in case the image is flipped, it must be reset here //
|
// in case the image is flipped, it must be reset here //
|
||||||
rawImage->width = image_width;
|
rawImage->width = CCstatus.ImageWidth;
|
||||||
rawImage->height = image_height;
|
rawImage->height = CCstatus.ImageHeight;
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
ESP_LOGD(TAG, "flash_duration: %d", flash_duration);
|
ESP_LOGD(TAG, "flash_duration: %d", flash_duration);
|
||||||
|
|
||||||
Camera.CaptureToBasisImage(rawImage, flash_duration);
|
Camera.CaptureToBasisImage(rawImage, flash_duration);
|
||||||
|
|
||||||
time(&TimeImageTaken);
|
time(&TimeImageTaken);
|
||||||
localtime(&TimeImageTaken);
|
localtime(&TimeImageTaken);
|
||||||
|
|
||||||
if (SaveAllFiles) rawImage->SaveToFile(namerawimage);
|
if (CCstatus.SaveAllFiles)
|
||||||
|
{
|
||||||
|
rawImage->SaveToFile(namerawimage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassFlowTakeImage::SetInitialParameter(void)
|
void ClassFlowTakeImage::SetInitialParameter(void)
|
||||||
{
|
{
|
||||||
waitbeforepicture = 5;
|
|
||||||
isImageSize = false;
|
|
||||||
ImageQuality = -1;
|
|
||||||
TimeImageTaken = 0;
|
TimeImageTaken = 0;
|
||||||
ImageQuality = 5;
|
|
||||||
rawImage = NULL;
|
rawImage = NULL;
|
||||||
ImageSize = FRAMESIZE_VGA;
|
|
||||||
SaveAllFiles = false;
|
|
||||||
disabled = false;
|
disabled = false;
|
||||||
FixedExposure = false;
|
|
||||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auslesen der Kameraeinstellungen aus der config.ini
|
||||||
|
// wird beim Start aufgerufen
|
||||||
|
bool ClassFlowTakeImage::ReadParameter(FILE *pfile, string &aktparamgraph)
|
||||||
|
{
|
||||||
|
Camera.getSensorDatenToCCstatus(); // Kamera >>> CCstatus
|
||||||
|
|
||||||
ClassFlowTakeImage::ClassFlowTakeImage(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
|
std::vector<string> splitted;
|
||||||
|
|
||||||
|
aktparamgraph = trim(aktparamgraph);
|
||||||
|
|
||||||
|
if (aktparamgraph.size() == 0)
|
||||||
|
{
|
||||||
|
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aktparamgraph.compare("[TakeImage]") != 0)
|
||||||
|
{
|
||||||
|
// Paragraph does not fit TakeImage
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||||
|
{
|
||||||
|
splitted = ZerlegeZeile(aktparamgraph);
|
||||||
|
|
||||||
|
if ((toUpper(splitted[0]) == "RAWIMAGESLOCATION") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
imagesLocation = "/sdcard" + splitted[1];
|
||||||
|
isLogImage = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "RAWIMAGESRETENTION") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
this->imagesRetention = std::stod(splitted[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.SaveAllFiles = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.SaveAllFiles = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "WAITBEFORETAKINGPICTURE") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _WaitBeforePicture = std::stoi(splitted[1]);
|
||||||
|
if (_WaitBeforePicture != 0)
|
||||||
|
{
|
||||||
|
CCstatus.WaitBeforePicture = _WaitBeforePicture;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.WaitBeforePicture = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMGAINCEILING") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
std::string _ImageGainceiling = toUpper(splitted[1]);
|
||||||
|
if (_ImageGainceiling == "X4")
|
||||||
|
{
|
||||||
|
CCstatus.ImageGainceiling = GAINCEILING_4X;
|
||||||
|
}
|
||||||
|
else if (_ImageGainceiling == "X8")
|
||||||
|
{
|
||||||
|
CCstatus.ImageGainceiling = GAINCEILING_8X;
|
||||||
|
}
|
||||||
|
else if (_ImageGainceiling == "X16")
|
||||||
|
{
|
||||||
|
CCstatus.ImageGainceiling = GAINCEILING_16X;
|
||||||
|
}
|
||||||
|
else if (_ImageGainceiling == "X32")
|
||||||
|
{
|
||||||
|
CCstatus.ImageGainceiling = GAINCEILING_32X;
|
||||||
|
}
|
||||||
|
else if (_ImageGainceiling == "X64")
|
||||||
|
{
|
||||||
|
CCstatus.ImageGainceiling = GAINCEILING_64X;
|
||||||
|
}
|
||||||
|
else if (_ImageGainceiling == "X128")
|
||||||
|
{
|
||||||
|
CCstatus.ImageGainceiling = GAINCEILING_128X;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageGainceiling = GAINCEILING_2X;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMQUALITY") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageQuality = std::stoi(splitted[1]);
|
||||||
|
if ((_ImageQuality >= 0) && (_ImageQuality <= 63))
|
||||||
|
{
|
||||||
|
CCstatus.ImageQuality = _ImageQuality;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMBRIGHTNESS") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageBrightness = std::stoi(splitted[1]);
|
||||||
|
if ((_ImageBrightness >= -2) && (_ImageBrightness <= 2))
|
||||||
|
{
|
||||||
|
CCstatus.ImageBrightness = _ImageBrightness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMCONTRAST") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageContrast = std::stoi(splitted[1]);
|
||||||
|
if ((_ImageContrast >= -2) && (_ImageContrast <= 2))
|
||||||
|
{
|
||||||
|
CCstatus.ImageContrast = _ImageContrast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMSATURATION") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageSaturation = std::stoi(splitted[1]);
|
||||||
|
if ((_ImageSaturation >= -2) && (_ImageSaturation <= 2))
|
||||||
|
{
|
||||||
|
CCstatus.ImageSaturation = _ImageSaturation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMSHARPNESS") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageSharpness = std::stoi(splitted[1]);
|
||||||
|
if ((_ImageSharpness >= -2) && (_ImageSharpness <= 2))
|
||||||
|
{
|
||||||
|
CCstatus.ImageSharpness = _ImageSharpness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAUTOSHARPNESS") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageAutoSharpness = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageAutoSharpness = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMSPECIALEFFECT") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
std::string _ImageSpecialEffect = toUpper(splitted[1]);
|
||||||
|
if (_ImageSpecialEffect == "NEGATIVE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageSpecialEffect = 1;
|
||||||
|
}
|
||||||
|
else if (_ImageSpecialEffect == "GRAYSCALE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageSpecialEffect = 2;
|
||||||
|
}
|
||||||
|
else if (_ImageSpecialEffect == "RED")
|
||||||
|
{
|
||||||
|
CCstatus.ImageSpecialEffect = 3;
|
||||||
|
}
|
||||||
|
else if (_ImageSpecialEffect == "GREEN")
|
||||||
|
{
|
||||||
|
CCstatus.ImageSpecialEffect = 4;
|
||||||
|
}
|
||||||
|
else if (_ImageSpecialEffect == "BLUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageSpecialEffect = 5;
|
||||||
|
}
|
||||||
|
else if (_ImageSpecialEffect == "RETRO")
|
||||||
|
{
|
||||||
|
CCstatus.ImageSpecialEffect = 6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageSpecialEffect = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMWBMODE") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
std::string _ImageWbMode = toUpper(splitted[1]);
|
||||||
|
if (_ImageWbMode == "SUNNY")
|
||||||
|
{
|
||||||
|
CCstatus.ImageWbMode = 1;
|
||||||
|
}
|
||||||
|
else if (_ImageWbMode == "CLOUDY")
|
||||||
|
{
|
||||||
|
CCstatus.ImageWbMode = 2;
|
||||||
|
}
|
||||||
|
else if (_ImageWbMode == "OFFICE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageWbMode = 3;
|
||||||
|
}
|
||||||
|
else if (_ImageWbMode == "HOME")
|
||||||
|
{
|
||||||
|
CCstatus.ImageWbMode = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageWbMode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAWB") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageAwb = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageAwb = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAWBGAIN") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageAwbGain = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageAwbGain = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAEC") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageAec = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageAec = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAEC2") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageAec2 = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageAec2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAELEVEL") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageAeLevel = std::stoi(splitted[1]);
|
||||||
|
if ((_ImageAeLevel >= -2) && (_ImageAeLevel <= 2))
|
||||||
|
{
|
||||||
|
CCstatus.ImageAeLevel = _ImageAeLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAECVALUE") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageAecValue = std::stoi(splitted[1]);
|
||||||
|
if ((_ImageAecValue >= 0) && (_ImageAecValue <= 1200))
|
||||||
|
{
|
||||||
|
CCstatus.ImageAecValue = _ImageAecValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAGC") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageAgc = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageAgc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMAGCGAIN") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageAgcGain = std::stoi(splitted[1]);
|
||||||
|
if ((_ImageAgcGain >= 0) && (_ImageAgcGain <= 30))
|
||||||
|
{
|
||||||
|
CCstatus.ImageAgcGain = _ImageAgcGain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMBPC") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageBpc = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageBpc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMWPC") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageWpc = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageWpc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMRAWGMA") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageRawGma = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageRawGma = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMLENC") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageLenc = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageLenc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMHMIRROR") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageHmirror = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageHmirror = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMVFLIP") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageVflip = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageVflip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMDCW") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageDcw = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageDcw = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMZOOM") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.ImageZoomEnabled = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.ImageZoomEnabled = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETX") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
CCstatus.ImageZoomOffsetX = std::stoi(splitted[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETY") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
CCstatus.ImageZoomOffsetY = std::stoi(splitted[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "CAMZOOMSIZE") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
int _ImageZoomSize = std::stoi(splitted[1]);
|
||||||
|
if (_ImageZoomSize >= 0)
|
||||||
|
{
|
||||||
|
CCstatus.ImageZoomSize = _ImageZoomSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "LEDINTENSITY") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
float ledintensity = std::stof(splitted[1]);
|
||||||
|
Camera.SetLEDIntensity(ledintensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1))
|
||||||
|
{
|
||||||
|
if (toUpper(splitted[1]) == "TRUE")
|
||||||
|
{
|
||||||
|
CCstatus.DemoMode = true;
|
||||||
|
Camera.useDemoMode();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCstatus.DemoMode = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||||
|
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||||
|
|
||||||
|
rawImage = new CImageBasis("rawImage");
|
||||||
|
rawImage->CreateEmptyImage(CCstatus.ImageWidth, CCstatus.ImageHeight, 3);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassFlowTakeImage::ClassFlowTakeImage(std::vector<ClassFlow *> *lfc) : ClassFlowImage(lfc, TAG)
|
||||||
{
|
{
|
||||||
imagesLocation = "/log/source";
|
imagesLocation = "/log/source";
|
||||||
imagesRetention = 5;
|
imagesRetention = 5;
|
||||||
SetInitialParameter();
|
SetInitialParameter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
|
||||||
{
|
|
||||||
std::vector<string> splitted;
|
|
||||||
|
|
||||||
aktparamgraph = trim(aktparamgraph);
|
|
||||||
int _brightness = -100;
|
|
||||||
int _contrast = -100;
|
|
||||||
int _saturation = -100;
|
|
||||||
|
|
||||||
if (aktparamgraph.size() == 0)
|
|
||||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (aktparamgraph.compare("[TakeImage]") != 0) // Paragraph does not fit TakeImage
|
|
||||||
return false;
|
|
||||||
|
|
||||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
|
||||||
{
|
|
||||||
splitted = ZerlegeZeile(aktparamgraph);
|
|
||||||
if ((toUpper(splitted[0]) == "RAWIMAGESLOCATION") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
imagesLocation = "/sdcard" + splitted[1];
|
|
||||||
isLogImage = true;
|
|
||||||
}
|
|
||||||
if ((toUpper(splitted[0]) == "IMAGEQUALITY") && (splitted.size() > 1))
|
|
||||||
ImageQuality = std::stod(splitted[1]);
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "IMAGESIZE") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
ImageSize = Camera.TextToFramesize(splitted[1].c_str());
|
|
||||||
isImageSize = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
if (toUpper(splitted[1]) == "TRUE")
|
|
||||||
SaveAllFiles = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "WAITBEFORETAKINGPICTURE") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
waitbeforepicture = stoi(splitted[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "RAWIMAGESRETENTION") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
this->imagesRetention = std::stoi(splitted[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "BRIGHTNESS") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
_brightness = stoi(splitted[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "CONTRAST") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
_contrast = stoi(splitted[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "SATURATION") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
_saturation = stoi(splitted[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "FIXEDEXPOSURE") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
if (toUpper(splitted[1]) == "TRUE")
|
|
||||||
FixedExposure = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "LEDINTENSITY") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
float ledintensity = stof(splitted[1]);
|
|
||||||
ledintensity = min((float) 100, ledintensity);
|
|
||||||
ledintensity = max((float) 0, ledintensity);
|
|
||||||
Camera.SetLEDIntensity(ledintensity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1))
|
|
||||||
{
|
|
||||||
if (toUpper(splitted[1]) == "TRUE")
|
|
||||||
Camera.useDemoMode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation);
|
|
||||||
Camera.SetQualitySize(ImageQuality, ImageSize);
|
|
||||||
|
|
||||||
image_width = Camera.image_width;
|
|
||||||
image_height = Camera.image_height;
|
|
||||||
rawImage = new CImageBasis("rawImage");
|
|
||||||
rawImage->CreateEmptyImage(image_width, image_height, 3);
|
|
||||||
|
|
||||||
waitbeforepicture_store = waitbeforepicture;
|
|
||||||
if (FixedExposure && (waitbeforepicture > 0))
|
|
||||||
{
|
|
||||||
// ESP_LOGD(TAG, "Fixed Exposure enabled!");
|
|
||||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
|
||||||
Camera.EnableAutoExposure(flash_duration);
|
|
||||||
waitbeforepicture = 0.2;
|
|
||||||
// flash_duration = (int) (waitbeforepicture * 1000);
|
|
||||||
// takePictureWithFlash(flash_duration);
|
|
||||||
// rawImage->SaveToFile("/sdcard/init2.jpg");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string ClassFlowTakeImage::getHTMLSingleStep(string host)
|
string ClassFlowTakeImage::getHTMLSingleStep(string host)
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
@@ -181,64 +517,68 @@ string ClassFlowTakeImage::getHTMLSingleStep(string host)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wird bei jeder Auswertrunde aufgerufen
|
||||||
bool ClassFlowTakeImage::doFlow(string zwtime)
|
bool ClassFlowTakeImage::doFlow(string zwtime)
|
||||||
{
|
{
|
||||||
psram_init_shared_memory_for_take_image_step();
|
psram_init_shared_memory_for_take_image_step();
|
||||||
|
|
||||||
string logPath = CreateLogFolder(zwtime);
|
string logPath = CreateLogFolder(zwtime);
|
||||||
|
|
||||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
|
||||||
|
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash");
|
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIFITURNOFF
|
||||||
|
esp_wifi_stop(); // to save power usage and
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WIFITURNOFF
|
// wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden
|
||||||
esp_wifi_stop(); // to save power usage and
|
if (CFstatus.changedCameraSettings)
|
||||||
#endif
|
{
|
||||||
|
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
|
||||||
|
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize);
|
||||||
|
CFstatus.changedCameraSettings = false;
|
||||||
|
}
|
||||||
|
|
||||||
takePictureWithFlash(flash_duration);
|
takePictureWithFlash(flash_duration);
|
||||||
|
|
||||||
#ifdef WIFITURNOFF
|
#ifdef WIFITURNOFF
|
||||||
esp_wifi_start();
|
esp_wifi_start();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_DETAIL_ON
|
||||||
#ifdef DEBUG_DETAIL_ON
|
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After takePictureWithFlash");
|
||||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After takePictureWithFlash");
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage);
|
LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage);
|
||||||
|
|
||||||
RemoveOldLogs();
|
RemoveOldLogs();
|
||||||
|
|
||||||
#ifdef DEBUG_DETAIL_ON
|
#ifdef DEBUG_DETAIL_ON
|
||||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After RemoveOldLogs");
|
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After RemoveOldLogs");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
psram_deinit_shared_memory_for_take_image_step();
|
psram_deinit_shared_memory_for_take_image_step();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
esp_err_t ClassFlowTakeImage::SendRawJPG(httpd_req_t *req)
|
esp_err_t ClassFlowTakeImage::SendRawJPG(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
|
||||||
time(&TimeImageTaken);
|
time(&TimeImageTaken);
|
||||||
localtime(&TimeImageTaken);
|
localtime(&TimeImageTaken);
|
||||||
|
|
||||||
return Camera.CaptureToHTTP(req, flash_duration);
|
return Camera.CaptureToHTTP(req, flash_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageData *ClassFlowTakeImage::SendRawImage(void)
|
||||||
ImageData* ClassFlowTakeImage::SendRawImage()
|
|
||||||
{
|
{
|
||||||
CImageBasis *zw = new CImageBasis("SendRawImage", rawImage);
|
CImageBasis *zw = new CImageBasis("SendRawImage", rawImage);
|
||||||
ImageData *id;
|
ImageData *id;
|
||||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
|
||||||
Camera.CaptureToBasisImage(zw, flash_duration);
|
Camera.CaptureToBasisImage(zw, flash_duration);
|
||||||
time(&TimeImageTaken);
|
time(&TimeImageTaken);
|
||||||
localtime(&TimeImageTaken);
|
localtime(&TimeImageTaken);
|
||||||
@@ -248,7 +588,7 @@ ImageData* ClassFlowTakeImage::SendRawImage()
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t ClassFlowTakeImage::getTimeImageTaken()
|
time_t ClassFlowTakeImage::getTimeImageTaken(void)
|
||||||
{
|
{
|
||||||
return TimeImageTaken;
|
return TimeImageTaken;
|
||||||
}
|
}
|
||||||
@@ -257,4 +597,3 @@ ClassFlowTakeImage::~ClassFlowTakeImage(void)
|
|||||||
{
|
{
|
||||||
delete rawImage;
|
delete rawImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,47 +9,32 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class ClassFlowTakeImage :
|
class ClassFlowTakeImage : public ClassFlowImage
|
||||||
public ClassFlowImage
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
float waitbeforepicture;
|
|
||||||
float waitbeforepicture_store;
|
|
||||||
framesize_t ImageSize;
|
|
||||||
bool isImageSize;
|
|
||||||
int ImageQuality;
|
|
||||||
time_t TimeImageTaken;
|
time_t TimeImageTaken;
|
||||||
string namerawimage;
|
string namerawimage;
|
||||||
int image_height, image_width;
|
|
||||||
bool SaveAllFiles;
|
|
||||||
bool FixedExposure;
|
|
||||||
|
|
||||||
|
esp_err_t camera_capture(void);
|
||||||
|
|
||||||
void CopyFile(string input, string output);
|
|
||||||
|
|
||||||
esp_err_t camera_capture();
|
|
||||||
void takePictureWithFlash(int flash_duration);
|
void takePictureWithFlash(int flash_duration);
|
||||||
|
|
||||||
|
|
||||||
void SetInitialParameter(void);
|
void SetInitialParameter(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CImageBasis *rawImage;
|
CImageBasis *rawImage;
|
||||||
|
|
||||||
ClassFlowTakeImage(std::vector<ClassFlow*>* lfc);
|
ClassFlowTakeImage(std::vector<ClassFlow *> *lfc);
|
||||||
|
|
||||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
bool ReadParameter(FILE *pfile, string &aktparamgraph);
|
||||||
bool doFlow(string time);
|
bool doFlow(string time);
|
||||||
string getHTMLSingleStep(string host);
|
string getHTMLSingleStep(string host);
|
||||||
time_t getTimeImageTaken();
|
time_t getTimeImageTaken(void);
|
||||||
string name(){return "ClassFlowTakeImage";};
|
string name() { return "ClassFlowTakeImage"; };
|
||||||
|
|
||||||
ImageData* SendRawImage();
|
ImageData *SendRawImage(void);
|
||||||
esp_err_t SendRawJPG(httpd_req_t *req);
|
esp_err_t SendRawJPG(httpd_req_t *req);
|
||||||
|
|
||||||
~ClassFlowTakeImage(void);
|
~ClassFlowTakeImage(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // CLASSFFLOWTAKEIMAGE_H
|
||||||
#endif //CLASSFFLOWTAKEIMAGE_H
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -10,25 +10,78 @@
|
|||||||
#include "CImageBasis.h"
|
#include "CImageBasis.h"
|
||||||
#include "ClassFlowControll.h"
|
#include "ClassFlowControll.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10
|
||||||
|
gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128)
|
||||||
|
|
||||||
|
int ImageQuality; // 0 - 63
|
||||||
|
int ImageBrightness; // (-2 to 2) - set brightness
|
||||||
|
int ImageContrast; //-2 - 2
|
||||||
|
int ImageSaturation; //-2 - 2
|
||||||
|
int ImageSharpness; //-2 - 2
|
||||||
|
bool ImageAutoSharpness;
|
||||||
|
int ImageSpecialEffect; // 0 - 6
|
||||||
|
int ImageWbMode; // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
|
||||||
|
int ImageAwb; // white balance enable (0 or 1)
|
||||||
|
int ImageAwbGain; // Auto White Balance enable (0 or 1)
|
||||||
|
int ImageAec; // auto exposure off (1 or 0)
|
||||||
|
int ImageAec2; // automatic exposure sensor (0 or 1)
|
||||||
|
int ImageAeLevel; // auto exposure levels (-2 to 2)
|
||||||
|
int ImageAecValue; // set exposure manually (0-1200)
|
||||||
|
int ImageAgc; // auto gain off (1 or 0)
|
||||||
|
int ImageAgcGain; // set gain manually (0 - 30)
|
||||||
|
int ImageBpc; // black pixel correction
|
||||||
|
int ImageWpc; // white pixel correction
|
||||||
|
int ImageRawGma; // (1 or 0)
|
||||||
|
int ImageLenc; // lens correction (1 or 0)
|
||||||
|
int ImageHmirror; // (0 or 1) flip horizontally
|
||||||
|
int ImageVflip; // Invert image (0 or 1)
|
||||||
|
int ImageDcw; // downsize enable (1 or 0)
|
||||||
|
|
||||||
|
int ImageWidth;
|
||||||
|
int ImageHeight;
|
||||||
|
|
||||||
|
int ImageLedIntensity;
|
||||||
|
|
||||||
|
bool ImageZoomEnabled;
|
||||||
|
int ImageZoomMode;
|
||||||
|
int ImageZoomOffsetX;
|
||||||
|
int ImageZoomOffsetY;
|
||||||
|
int ImageZoomSize;
|
||||||
|
|
||||||
|
int WaitBeforePicture;
|
||||||
|
bool isImageSize;
|
||||||
|
|
||||||
|
bool CameraInitSuccessful;
|
||||||
|
bool changedCameraSettings;
|
||||||
|
bool DemoMode;
|
||||||
|
bool SaveAllFiles;
|
||||||
|
} camera_flow_config_temp_t;
|
||||||
|
|
||||||
|
extern camera_flow_config_temp_t CFstatus;
|
||||||
extern ClassFlowControll flowctrl;
|
extern ClassFlowControll flowctrl;
|
||||||
|
|
||||||
|
esp_err_t setCCstatusToCFstatus(void); // CCstatus >>> CFstatus
|
||||||
|
esp_err_t setCFstatusToCCstatus(void); // CFstatus >>> CCstatus
|
||||||
|
esp_err_t setCFstatusToCam(void); // CFstatus >>> Kamera
|
||||||
|
|
||||||
void register_server_main_flow_task_uri(httpd_handle_t server);
|
void register_server_main_flow_task_uri(httpd_handle_t server);
|
||||||
|
|
||||||
void CheckIsPlannedReboot();
|
void CheckIsPlannedReboot(void);
|
||||||
bool getIsPlannedReboot();
|
bool getIsPlannedReboot(void);
|
||||||
|
|
||||||
void InitializeFlowTask();
|
void InitializeFlowTask(void);
|
||||||
void DeleteMainFlowTask();
|
void DeleteMainFlowTask(void);
|
||||||
bool isSetupModusActive();
|
bool isSetupModusActive(void);
|
||||||
|
|
||||||
int getCountFlowRounds();
|
int getCountFlowRounds(void);
|
||||||
|
|
||||||
#ifdef ENABLE_MQTT
|
#ifdef ENABLE_MQTT
|
||||||
esp_err_t MQTTCtrlFlowStart(std::string _topic);
|
esp_err_t MQTTCtrlFlowStart(std::string _topic);
|
||||||
#endif //ENABLE_MQTT
|
#endif // ENABLE_MQTT
|
||||||
|
|
||||||
esp_err_t GetRawJPG(httpd_req_t *req);
|
esp_err_t GetRawJPG(httpd_req_t *req);
|
||||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
|
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
|
||||||
|
|
||||||
#endif //MAINFLOWCONTROL_H
|
#endif // MAINFLOWCONTROL_H
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
|||||||
|
|
||||||
idf_component_register(SRCS ${app_sources}
|
idf_component_register(SRCS ${app_sources}
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES esp_timer esp-tflite-micro jomjol_logfile fatfs sdmmc)
|
REQUIRES esp_timer esp-tflite-micro jomjol_logfile fatfs sdmmc vfs)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "sdmmc_cmd.h"
|
#include "sdmmc_cmd.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|||||||
651
code/components/jomjol_helper/sdcard_init.c
Normal file
651
code/components/jomjol_helper/sdcard_init.c
Normal file
@@ -0,0 +1,651 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "sdcard_init.h"
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "ffconf.h"
|
||||||
|
#include "esp_compiler.h"
|
||||||
|
#include "esp_vfs.h"
|
||||||
|
#include "vfs_fat_internal.h"
|
||||||
|
#include "diskio_impl.h"
|
||||||
|
#include "diskio_sdmmc.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "driver/sdmmc_defs.h"
|
||||||
|
|
||||||
|
#if SOC_SDMMC_HOST_SUPPORTED
|
||||||
|
#include "driver/sdmmc_host.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static sdmmc_card_t* s_cards[FF_VOLUMES] = { NULL };
|
||||||
|
static bool s_disk_status_check_en[FF_VOLUMES] = { };
|
||||||
|
|
||||||
|
static const char* TAG = "sdcard_init";
|
||||||
|
|
||||||
|
#define CHECK_EXECUTE_RESULT(err, str) do { \
|
||||||
|
if ((err) !=ESP_OK) { \
|
||||||
|
ESP_LOGE(TAG, str" (0x%x).", err); \
|
||||||
|
goto cleanup; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
typedef struct vfs_fat_sd_ctx_t {
|
||||||
|
BYTE pdrv; //Drive number that is mounted
|
||||||
|
esp_vfs_fat_mount_config_t mount_config; //Mount configuration
|
||||||
|
FATFS *fs; //FAT structure pointer that is registered
|
||||||
|
sdmmc_card_t *card; //Card info
|
||||||
|
char *base_path; //Path where partition is registered
|
||||||
|
} vfs_fat_sd_ctx_t;
|
||||||
|
|
||||||
|
static vfs_fat_sd_ctx_t *s_ctx[FF_VOLUMES] = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This `s_saved_ctx_id` is only used by `esp_vfs_fat_sdmmc_unmount`, which is deprecated.
|
||||||
|
* This variable together with `esp_vfs_fat_sdmmc_unmount` should be removed in next major version
|
||||||
|
*/
|
||||||
|
static uint32_t s_saved_ctx_id = FF_VOLUMES;
|
||||||
|
|
||||||
|
|
||||||
|
static void call_host_deinit_mh(const sdmmc_host_t *host_config);
|
||||||
|
static esp_err_t partition_card_mh(const esp_vfs_fat_mount_config_t *mount_config, const char *drv, sdmmc_card_t *card, BYTE pdrv);
|
||||||
|
|
||||||
|
|
||||||
|
//Check if SD/MMC card is present
|
||||||
|
static DSTATUS ff_sdmmc_card_available_mh(BYTE pdrv)
|
||||||
|
{
|
||||||
|
sdmmc_card_t* card = s_cards[pdrv];
|
||||||
|
assert(card);
|
||||||
|
esp_err_t err = sdmmc_get_status(card);
|
||||||
|
|
||||||
|
if (unlikely(err != ESP_OK)) {
|
||||||
|
ESP_LOGE(TAG, "Check status failed (0x%x)", err);
|
||||||
|
return STA_NOINIT;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ff_sdmmc_status() and ff_sdmmc_initialize() return STA_NOINIT when sdmmc_get_status()
|
||||||
|
* fails. This error value is checked throughout the FATFS code.
|
||||||
|
* Both functions return 0 on success.
|
||||||
|
*/
|
||||||
|
DSTATUS ff_sdmmc_initialize_mh (BYTE pdrv)
|
||||||
|
{
|
||||||
|
return ff_sdmmc_card_available_mh(pdrv);
|
||||||
|
}
|
||||||
|
|
||||||
|
DSTATUS ff_sdmmc_status_mh(BYTE pdrv)
|
||||||
|
{
|
||||||
|
if (s_disk_status_check_en[pdrv]) {
|
||||||
|
return ff_sdmmc_card_available_mh(pdrv);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DRESULT ff_sdmmc_read_mh (BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
|
||||||
|
{
|
||||||
|
sdmmc_card_t* card = s_cards[pdrv];
|
||||||
|
assert(card);
|
||||||
|
esp_err_t err = sdmmc_read_sectors(card, buff, sector, count);
|
||||||
|
if (unlikely(err != ESP_OK)) {
|
||||||
|
ESP_LOGE(TAG, "sdmmc_read_blocks failed (%d)", err);
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
DRESULT ff_sdmmc_write_mh (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count)
|
||||||
|
{
|
||||||
|
sdmmc_card_t* card = s_cards[pdrv];
|
||||||
|
assert(card);
|
||||||
|
esp_err_t err = sdmmc_write_sectors(card, buff, sector, count);
|
||||||
|
if (unlikely(err != ESP_OK)) {
|
||||||
|
ESP_LOGE(TAG, "sdmmc_write_blocks failed (%d)", err);
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if FF_USE_TRIM
|
||||||
|
DRESULT ff_sdmmc_trim_mh (BYTE pdrv, DWORD start_sector, DWORD sector_count)
|
||||||
|
{
|
||||||
|
sdmmc_card_t* card = s_cards[pdrv];
|
||||||
|
assert(card);
|
||||||
|
sdmmc_erase_arg_t arg;
|
||||||
|
|
||||||
|
arg = sdmmc_can_discard(card) == ESP_OK ? SDMMC_DISCARD_ARG : SDMMC_ERASE_ARG;
|
||||||
|
esp_err_t err = sdmmc_erase_sectors(card, start_sector, sector_count, arg);
|
||||||
|
if (unlikely(err != ESP_OK)) {
|
||||||
|
ESP_LOGE(TAG, "sdmmc_erase_sectors failed (%d)", err);
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
#endif //FF_USE_TRIM
|
||||||
|
|
||||||
|
DRESULT ff_sdmmc_ioctl_mh (BYTE pdrv, BYTE cmd, void* buff)
|
||||||
|
{
|
||||||
|
sdmmc_card_t* card = s_cards[pdrv];
|
||||||
|
assert(card);
|
||||||
|
switch(cmd) {
|
||||||
|
case CTRL_SYNC:
|
||||||
|
return RES_OK;
|
||||||
|
case GET_SECTOR_COUNT:
|
||||||
|
*((DWORD*) buff) = card->csd.capacity;
|
||||||
|
return RES_OK;
|
||||||
|
case GET_SECTOR_SIZE:
|
||||||
|
*((WORD*) buff) = card->csd.sector_size;
|
||||||
|
return RES_OK;
|
||||||
|
case GET_BLOCK_SIZE:
|
||||||
|
return RES_ERROR;
|
||||||
|
#if FF_USE_TRIM
|
||||||
|
case CTRL_TRIM:
|
||||||
|
if (sdmmc_can_trim(card) != ESP_OK) {
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
return ff_sdmmc_trim_mh (pdrv, *((DWORD*)buff), //start_sector
|
||||||
|
(*((DWORD*)buff + 1) - *((DWORD*)buff) + 1)); //sector_count
|
||||||
|
#endif //FF_USE_TRIM
|
||||||
|
}
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ff_sdmmc_set_disk_status_check_mh(BYTE pdrv, bool enable)
|
||||||
|
{
|
||||||
|
s_disk_status_check_en[pdrv] = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ff_diskio_register_sdmmc_mh(BYTE pdrv, sdmmc_card_t* card)
|
||||||
|
{
|
||||||
|
static const ff_diskio_impl_t sdmmc_impl = {
|
||||||
|
.init = &ff_sdmmc_initialize_mh,
|
||||||
|
.status = &ff_sdmmc_status_mh,
|
||||||
|
.read = &ff_sdmmc_read_mh,
|
||||||
|
.write = &ff_sdmmc_write_mh,
|
||||||
|
.ioctl = &ff_sdmmc_ioctl_mh
|
||||||
|
};
|
||||||
|
s_cards[pdrv] = card;
|
||||||
|
s_disk_status_check_en[pdrv] = false;
|
||||||
|
ff_diskio_register(pdrv, &sdmmc_impl);
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE ff_diskio_get_pdrv_card_mh(const sdmmc_card_t* card)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < FF_VOLUMES; i++) {
|
||||||
|
if (card == s_cards[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static bool s_get_context_id_by_card_mh(const sdmmc_card_t *card, uint32_t *out_id)
|
||||||
|
{
|
||||||
|
vfs_fat_sd_ctx_t *p_ctx = NULL;
|
||||||
|
for (int i = 0; i < FF_VOLUMES; i++) {
|
||||||
|
p_ctx = s_ctx[i];
|
||||||
|
if (p_ctx) {
|
||||||
|
if (p_ctx->card == card) {
|
||||||
|
*out_id = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t s_get_unused_context_id_mh(void)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < FF_VOLUMES; i++) {
|
||||||
|
if (!s_ctx[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FF_VOLUMES;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t mount_prepare_mem_mh(const char *base_path, BYTE *out_pdrv, char **out_dup_path, sdmmc_card_t** out_card)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
char* dup_path = NULL;
|
||||||
|
sdmmc_card_t* card = NULL;
|
||||||
|
|
||||||
|
// connect SDMMC driver to FATFS
|
||||||
|
BYTE pdrv = FF_DRV_NOT_USED;
|
||||||
|
|
||||||
|
if (ff_diskio_get_drive(&pdrv) != ESP_OK || pdrv == FF_DRV_NOT_USED) {
|
||||||
|
ESP_LOGD(TAG, "the maximum count of volumes is already mounted");
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not using ff_memalloc here, as allocation in internal RAM is preferred
|
||||||
|
card = (sdmmc_card_t*)malloc(sizeof(sdmmc_card_t));
|
||||||
|
|
||||||
|
if (card == NULL) {
|
||||||
|
ESP_LOGD(TAG, "could not locate new sdmmc_card_t");
|
||||||
|
err = ESP_ERR_NO_MEM;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
dup_path = strdup(base_path);
|
||||||
|
|
||||||
|
if(!dup_path){
|
||||||
|
ESP_LOGD(TAG, "could not copy base_path");
|
||||||
|
err = ESP_ERR_NO_MEM;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_card = card;
|
||||||
|
*out_pdrv = pdrv;
|
||||||
|
*out_dup_path = dup_path;
|
||||||
|
return ESP_OK;
|
||||||
|
cleanup:
|
||||||
|
free(card);
|
||||||
|
free(dup_path);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t s_f_mount_mh(sdmmc_card_t *card, FATFS *fs, const char *drv, uint8_t pdrv, const esp_vfs_fat_mount_config_t *mount_config)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
FRESULT res = f_mount(fs, drv, 1);
|
||||||
|
if (res != FR_OK) {
|
||||||
|
err = ESP_FAIL;
|
||||||
|
ESP_LOGW(TAG, "failed to mount card (%d)", res);
|
||||||
|
|
||||||
|
bool need_mount_again = (res == FR_NO_FILESYSTEM || res == FR_INT_ERR) && mount_config->format_if_mount_failed;
|
||||||
|
|
||||||
|
if (!need_mount_again) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = partition_card_mh(mount_config, drv, card, pdrv);
|
||||||
|
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "mounting again");
|
||||||
|
res = f_mount(fs, drv, 0);
|
||||||
|
|
||||||
|
if (res != FR_OK) {
|
||||||
|
err = ESP_FAIL;
|
||||||
|
ESP_LOGD(TAG, "f_mount failed after formatting (%d)", res);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t mount_to_vfs_fat_mh(const esp_vfs_fat_mount_config_t *mount_config, sdmmc_card_t *card, uint8_t pdrv, const char *base_path, FATFS **out_fs)
|
||||||
|
{
|
||||||
|
FATFS *fs = NULL;
|
||||||
|
esp_err_t err;
|
||||||
|
ff_diskio_register_sdmmc_mh(pdrv, card);
|
||||||
|
ff_sdmmc_set_disk_status_check_mh(pdrv, mount_config->disk_status_check_enable);
|
||||||
|
ESP_LOGD(TAG, "using pdrv=%i", pdrv);
|
||||||
|
char drv[3] = {(char)('0' + pdrv), ':', 0};
|
||||||
|
|
||||||
|
// connect FATFS to VFS
|
||||||
|
err = esp_vfs_fat_register(base_path, drv, mount_config->max_files, &fs);
|
||||||
|
*out_fs = fs;
|
||||||
|
|
||||||
|
if (err == ESP_ERR_INVALID_STATE) {
|
||||||
|
// it's okay, already registered with VFS
|
||||||
|
} else if (err != ESP_OK) {
|
||||||
|
ESP_LOGD(TAG, "esp_vfs_fat_register failed 0x(%x)", err);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to mount partition
|
||||||
|
err = s_f_mount_mh(card, fs, drv, pdrv, mount_config);
|
||||||
|
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (fs) {
|
||||||
|
f_mount(NULL, drv, 0);
|
||||||
|
}
|
||||||
|
esp_vfs_fat_unregister_path(base_path);
|
||||||
|
ff_diskio_unregister(pdrv);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t partition_card_mh(const esp_vfs_fat_mount_config_t *mount_config, const char *drv, sdmmc_card_t *card, BYTE pdrv)
|
||||||
|
{
|
||||||
|
FRESULT res = FR_OK;
|
||||||
|
esp_err_t err;
|
||||||
|
const size_t workbuf_size = 4096;
|
||||||
|
void* workbuf = NULL;
|
||||||
|
ESP_LOGW(TAG, "partitioning card");
|
||||||
|
|
||||||
|
workbuf = ff_memalloc(workbuf_size);
|
||||||
|
|
||||||
|
if (workbuf == NULL) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
LBA_t plist[] = {100, 0, 0, 0};
|
||||||
|
res = f_fdisk(pdrv, plist, workbuf);
|
||||||
|
|
||||||
|
if (res != FR_OK) {
|
||||||
|
err = ESP_FAIL;
|
||||||
|
ESP_LOGD(TAG, "f_fdisk failed (%d)", res);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t alloc_unit_size = esp_vfs_fat_get_allocation_unit_size(card->csd.sector_size, mount_config->allocation_unit_size);
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "formatting card, allocation unit size=%d", alloc_unit_size);
|
||||||
|
const MKFS_PARM opt = {(BYTE)FM_ANY, 0, 0, 0, alloc_unit_size};
|
||||||
|
res = f_mkfs(drv, &opt, workbuf, workbuf_size);
|
||||||
|
|
||||||
|
if (res != FR_OK) {
|
||||||
|
err = ESP_FAIL;
|
||||||
|
ESP_LOGD(TAG, "f_mkfs failed (%d)", res);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(workbuf);
|
||||||
|
return ESP_OK;
|
||||||
|
fail:
|
||||||
|
free(workbuf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SOC_SDMMC_HOST_SUPPORTED
|
||||||
|
static esp_err_t init_sdmmc_host_mh(int slot, const void *slot_config, int *out_slot)
|
||||||
|
{
|
||||||
|
*out_slot = slot;
|
||||||
|
return sdmmc_host_init_slot(slot, (const sdmmc_slot_config_t*) slot_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_vfs_fat_sdmmc_mount_mh(const char* base_path, const sdmmc_host_t* host_config, const void* slot_config, const esp_vfs_fat_mount_config_t* mount_config, sdmmc_card_t** out_card)
|
||||||
|
{
|
||||||
|
esp_err_t err;
|
||||||
|
vfs_fat_sd_ctx_t *ctx = NULL;
|
||||||
|
uint32_t ctx_id = FF_VOLUMES;
|
||||||
|
FATFS *fs = NULL;
|
||||||
|
int card_handle = -1; //uninitialized
|
||||||
|
sdmmc_card_t* card = NULL;
|
||||||
|
BYTE pdrv = FF_DRV_NOT_USED;
|
||||||
|
char* dup_path = NULL;
|
||||||
|
bool host_inited = false;
|
||||||
|
|
||||||
|
err = mount_prepare_mem_mh(base_path, &pdrv, &dup_path, &card);
|
||||||
|
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "mount_prepare failed");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = (*host_config->init)();
|
||||||
|
CHECK_EXECUTE_RESULT(err, "host init failed");
|
||||||
|
//deinit() needs to be called to revert the init
|
||||||
|
host_inited = true;
|
||||||
|
//If this failed (indicated by card_handle != -1), slot deinit needs to called()
|
||||||
|
//leave card_handle as is to indicate that (though slot deinit not implemented yet.
|
||||||
|
err = init_sdmmc_host_mh(host_config->slot, slot_config, &card_handle);
|
||||||
|
CHECK_EXECUTE_RESULT(err, "slot init failed");
|
||||||
|
|
||||||
|
// probe and initialize card
|
||||||
|
err = sdmmc_card_init(host_config, card);
|
||||||
|
CHECK_EXECUTE_RESULT(err, "sdmmc_card_init failed");
|
||||||
|
|
||||||
|
err = mount_to_vfs_fat_mh(mount_config, card, pdrv, dup_path, &fs);
|
||||||
|
CHECK_EXECUTE_RESULT(err, "mount_to_vfs failed");
|
||||||
|
|
||||||
|
if (out_card != NULL) {
|
||||||
|
*out_card = card;
|
||||||
|
}
|
||||||
|
|
||||||
|
//For deprecation backward compatibility
|
||||||
|
if (s_saved_ctx_id == FF_VOLUMES) {
|
||||||
|
s_saved_ctx_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = calloc(sizeof(vfs_fat_sd_ctx_t), 1);
|
||||||
|
|
||||||
|
if (!ctx) {
|
||||||
|
CHECK_EXECUTE_RESULT(ESP_ERR_NO_MEM, "no mem");
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->pdrv = pdrv;
|
||||||
|
memcpy(&ctx->mount_config, mount_config, sizeof(esp_vfs_fat_mount_config_t));
|
||||||
|
ctx->card = card;
|
||||||
|
ctx->base_path = dup_path;
|
||||||
|
ctx->fs = fs;
|
||||||
|
ctx_id = s_get_unused_context_id_mh();
|
||||||
|
assert(ctx_id != FF_VOLUMES);
|
||||||
|
s_ctx[ctx_id] = ctx;
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
cleanup:
|
||||||
|
if (host_inited) {
|
||||||
|
call_host_deinit_mh(host_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(card);
|
||||||
|
free(dup_path);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static esp_err_t init_sdspi_host_mh(int slot, const void *slot_config, int *out_slot)
|
||||||
|
{
|
||||||
|
esp_err_t err = sdspi_host_init_device((const sdspi_device_config_t*)slot_config, out_slot);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG,
|
||||||
|
"Failed to attach sdspi device onto an SPI bus (rc=0x%x), please initialize the \
|
||||||
|
bus first and check the device parameters."
|
||||||
|
, err);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_vfs_fat_sdspi_mount_mh(const char* base_path, const sdmmc_host_t* host_config_input, const sdspi_device_config_t* slot_config, const esp_vfs_fat_mount_config_t* mount_config, sdmmc_card_t** out_card)
|
||||||
|
{
|
||||||
|
const sdmmc_host_t* host_config = host_config_input;
|
||||||
|
esp_err_t err;
|
||||||
|
vfs_fat_sd_ctx_t *ctx = NULL;
|
||||||
|
uint32_t ctx_id = FF_VOLUMES;
|
||||||
|
FATFS *fs = NULL;
|
||||||
|
int card_handle = -1; //uninitialized
|
||||||
|
bool host_inited = false;
|
||||||
|
BYTE pdrv = FF_DRV_NOT_USED;
|
||||||
|
sdmmc_card_t* card = NULL;
|
||||||
|
char* dup_path = NULL;
|
||||||
|
|
||||||
|
err = mount_prepare_mem_mh(base_path, &pdrv, &dup_path, &card);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "mount_prepare failed");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
//the init() function is usually empty, doesn't require any deinit to revert it
|
||||||
|
err = (*host_config->init)();
|
||||||
|
CHECK_EXECUTE_RESULT(err, "host init failed");
|
||||||
|
|
||||||
|
err = init_sdspi_host_mh(host_config->slot, slot_config, &card_handle);
|
||||||
|
CHECK_EXECUTE_RESULT(err, "slot init failed");
|
||||||
|
//Set `host_inited` to true to indicate that host_config->deinit() needs
|
||||||
|
//to be called to revert `init_sdspi_host`
|
||||||
|
host_inited = true;
|
||||||
|
|
||||||
|
//The `slot` argument inside host_config should be replaced by the SD SPI handled returned
|
||||||
|
//above. But the input pointer is const, so create a new variable.
|
||||||
|
|
||||||
|
sdmmc_host_t new_config;
|
||||||
|
|
||||||
|
if (card_handle != host_config->slot) {
|
||||||
|
new_config = *host_config_input;
|
||||||
|
host_config = &new_config;
|
||||||
|
new_config.slot = card_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// probe and initialize card
|
||||||
|
err = sdmmc_card_init(host_config, card);
|
||||||
|
CHECK_EXECUTE_RESULT(err, "sdmmc_card_init failed");
|
||||||
|
|
||||||
|
err = mount_to_vfs_fat_mh(mount_config, card, pdrv, dup_path, &fs);
|
||||||
|
CHECK_EXECUTE_RESULT(err, "mount_to_vfs failed");
|
||||||
|
|
||||||
|
if (out_card != NULL) {
|
||||||
|
*out_card = card;
|
||||||
|
}
|
||||||
|
|
||||||
|
//For deprecation backward compatibility
|
||||||
|
if (s_saved_ctx_id == FF_VOLUMES) {
|
||||||
|
s_saved_ctx_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = calloc(sizeof(vfs_fat_sd_ctx_t), 1);
|
||||||
|
|
||||||
|
if (!ctx) {
|
||||||
|
CHECK_EXECUTE_RESULT(ESP_ERR_NO_MEM, "no mem");
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->pdrv = pdrv;
|
||||||
|
memcpy(&ctx->mount_config, mount_config, sizeof(esp_vfs_fat_mount_config_t));
|
||||||
|
ctx->card = card;
|
||||||
|
ctx->base_path = dup_path;
|
||||||
|
ctx->fs = fs;
|
||||||
|
ctx_id = s_get_unused_context_id_mh();
|
||||||
|
assert(ctx_id != FF_VOLUMES);
|
||||||
|
s_ctx[ctx_id] = ctx;
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (host_inited) {
|
||||||
|
call_host_deinit_mh(host_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(card);
|
||||||
|
free(dup_path);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void call_host_deinit_mh(const sdmmc_host_t *host_config)
|
||||||
|
{
|
||||||
|
if (host_config->flags & SDMMC_HOST_FLAG_DEINIT_ARG) {
|
||||||
|
host_config->deinit_p(host_config->slot);
|
||||||
|
} else {
|
||||||
|
host_config->deinit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t unmount_card_core_mh(const char *base_path, sdmmc_card_t *card)
|
||||||
|
{
|
||||||
|
BYTE pdrv = ff_diskio_get_pdrv_card_mh(card);
|
||||||
|
|
||||||
|
if (pdrv == 0xff) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unmount
|
||||||
|
char drv[3] = {(char)('0' + pdrv), ':', 0};
|
||||||
|
f_mount(0, drv, 0);
|
||||||
|
// release SD driver
|
||||||
|
ff_diskio_unregister(pdrv);
|
||||||
|
|
||||||
|
call_host_deinit_mh(&card->host);
|
||||||
|
free(card);
|
||||||
|
|
||||||
|
esp_err_t err = esp_vfs_fat_unregister_path(base_path);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_vfs_fat_sdmmc_unmount_mh(void)
|
||||||
|
{
|
||||||
|
esp_err_t err = unmount_card_core_mh(s_ctx[s_saved_ctx_id]->base_path, s_ctx[s_saved_ctx_id]->card);
|
||||||
|
free(s_ctx[s_saved_ctx_id]);
|
||||||
|
s_ctx[s_saved_ctx_id] = NULL;
|
||||||
|
s_saved_ctx_id = FF_VOLUMES;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_vfs_fat_sdcard_unmount_mh(const char *base_path, sdmmc_card_t *card)
|
||||||
|
{
|
||||||
|
uint32_t id = FF_VOLUMES;
|
||||||
|
bool found = s_get_context_id_by_card_mh(card, &id);
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(s_ctx[id]);
|
||||||
|
s_ctx[id] = NULL;
|
||||||
|
|
||||||
|
esp_err_t err = unmount_card_core_mh(base_path, card);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_vfs_fat_sdcard_format_mh(const char *base_path, sdmmc_card_t *card)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
|
||||||
|
if (!card) {
|
||||||
|
ESP_LOGE(TAG, "card not initialized");
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE pdrv = ff_diskio_get_pdrv_card_mh(card);
|
||||||
|
|
||||||
|
if (pdrv == 0xff) {
|
||||||
|
ESP_LOGE(TAG, "card driver not registered");
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t workbuf_size = 4096;
|
||||||
|
void *workbuf = ff_memalloc(workbuf_size);
|
||||||
|
|
||||||
|
if (workbuf == NULL) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
//unmount
|
||||||
|
char drv[3] = {(char)('0' + pdrv), ':', 0};
|
||||||
|
f_mount(0, drv, 0);
|
||||||
|
|
||||||
|
//format
|
||||||
|
uint32_t id = FF_VOLUMES;
|
||||||
|
bool found = s_get_context_id_by_card_mh(card, &id);
|
||||||
|
assert(found);
|
||||||
|
size_t alloc_unit_size = esp_vfs_fat_get_allocation_unit_size(card->csd.sector_size, s_ctx[id]->mount_config.allocation_unit_size);
|
||||||
|
ESP_LOGI(TAG, "Formatting card, allocation unit size=%d", alloc_unit_size);
|
||||||
|
const MKFS_PARM opt = {(BYTE)FM_ANY, 0, 0, 0, alloc_unit_size};
|
||||||
|
FRESULT res = f_mkfs(drv, &opt, workbuf, workbuf_size);
|
||||||
|
free(workbuf);
|
||||||
|
|
||||||
|
if (res != FR_OK) {
|
||||||
|
ret = ESP_FAIL;
|
||||||
|
ESP_LOGD(TAG, "f_mkfs failed (%d)", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
//mount back
|
||||||
|
esp_err_t err = s_f_mount_mh(card, s_ctx[id]->fs, drv, pdrv, &s_ctx[id]->mount_config);
|
||||||
|
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
unmount_card_core_mh(base_path, card);
|
||||||
|
ESP_LOGE(TAG, "failed to format, resources recycled, please mount again");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
111
code/components/jomjol_helper/sdcard_init.h
Normal file
111
code/components/jomjol_helper/sdcard_init.h
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "sdmmc_cmd.h"
|
||||||
|
#include "driver/sdmmc_types.h"
|
||||||
|
#include "driver/sdspi_host.h"
|
||||||
|
#include "ff.h"
|
||||||
|
#include "esp_vfs_fat.h"
|
||||||
|
#include "wear_levelling.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convenience function to get FAT filesystem on SD card registered in VFS
|
||||||
|
*
|
||||||
|
* This is an all-in-one function which does the following:
|
||||||
|
* - initializes SDMMC driver or SPI driver with configuration in host_config
|
||||||
|
* - initializes SD card with configuration in slot_config
|
||||||
|
* - mounts FAT partition on SD card using FATFS library, with configuration in mount_config
|
||||||
|
* - registers FATFS library with VFS, with prefix given by base_prefix variable
|
||||||
|
*
|
||||||
|
* This function is intended to make example code more compact.
|
||||||
|
* For real world applications, developers should implement the logic of
|
||||||
|
* probing SD card, locating and mounting partition, and registering FATFS in VFS,
|
||||||
|
* with proper error checking and handling of exceptional conditions.
|
||||||
|
*
|
||||||
|
* @note Use this API to mount a card through SDSPI is deprecated. Please call
|
||||||
|
* `esp_vfs_fat_sdspi_mount()` instead for that case.
|
||||||
|
*
|
||||||
|
* @param base_path path where partition should be registered (e.g. "/sdcard")
|
||||||
|
* @param host_config Pointer to structure describing SDMMC host. When using
|
||||||
|
* SDMMC peripheral, this structure can be initialized using
|
||||||
|
* SDMMC_HOST_DEFAULT() macro. When using SPI peripheral,
|
||||||
|
* this structure can be initialized using SDSPI_HOST_DEFAULT()
|
||||||
|
* macro.
|
||||||
|
* @param slot_config Pointer to structure with slot configuration.
|
||||||
|
* For SDMMC peripheral, pass a pointer to sdmmc_slot_config_t
|
||||||
|
* structure initialized using SDMMC_SLOT_CONFIG_DEFAULT.
|
||||||
|
* @param mount_config pointer to structure with extra parameters for mounting FATFS
|
||||||
|
* @param[out] out_card if not NULL, pointer to the card information structure will be returned via this argument
|
||||||
|
* @return
|
||||||
|
* - ESP_OK on success
|
||||||
|
* - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called
|
||||||
|
* - ESP_ERR_NO_MEM if memory can not be allocated
|
||||||
|
* - ESP_FAIL if partition can not be mounted
|
||||||
|
* - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers
|
||||||
|
*/
|
||||||
|
esp_err_t esp_vfs_fat_sdmmc_mount_mh(const char* base_path, const sdmmc_host_t* host_config, const void* slot_config, const esp_vfs_fat_mount_config_t* mount_config, sdmmc_card_t** out_card);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convenience function to get FAT filesystem on SD card registered in VFS
|
||||||
|
*
|
||||||
|
* This is an all-in-one function which does the following:
|
||||||
|
* - initializes an SPI Master device based on the SPI Master driver with configuration in
|
||||||
|
* slot_config, and attach it to an initialized SPI bus.
|
||||||
|
* - initializes SD card with configuration in host_config_input
|
||||||
|
* - mounts FAT partition on SD card using FATFS library, with configuration in mount_config
|
||||||
|
* - registers FATFS library with VFS, with prefix given by base_prefix variable
|
||||||
|
*
|
||||||
|
* This function is intended to make example code more compact.
|
||||||
|
* For real world applications, developers should implement the logic of
|
||||||
|
* probing SD card, locating and mounting partition, and registering FATFS in VFS,
|
||||||
|
* with proper error checking and handling of exceptional conditions.
|
||||||
|
*
|
||||||
|
* @note This function try to attach the new SD SPI device to the bus specified in host_config.
|
||||||
|
* Make sure the SPI bus specified in `host_config->slot` have been initialized by
|
||||||
|
* `spi_bus_initialize()` before.
|
||||||
|
*
|
||||||
|
* @param base_path path where partition should be registered (e.g. "/sdcard")
|
||||||
|
* @param host_config_input Pointer to structure describing SDMMC host. This structure can be
|
||||||
|
* initialized using SDSPI_HOST_DEFAULT() macro.
|
||||||
|
* @param slot_config Pointer to structure with slot configuration.
|
||||||
|
* For SPI peripheral, pass a pointer to sdspi_device_config_t
|
||||||
|
* structure initialized using SDSPI_DEVICE_CONFIG_DEFAULT().
|
||||||
|
* @param mount_config pointer to structure with extra parameters for mounting FATFS
|
||||||
|
* @param[out] out_card If not NULL, pointer to the card information structure will be returned via
|
||||||
|
* this argument. It is suggested to hold this handle and use it to unmount the card later if
|
||||||
|
* needed. Otherwise it's not suggested to use more than one card at the same time and unmount one
|
||||||
|
* of them in your application.
|
||||||
|
* @return
|
||||||
|
* - ESP_OK on success
|
||||||
|
* - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called
|
||||||
|
* - ESP_ERR_NO_MEM if memory can not be allocated
|
||||||
|
* - ESP_FAIL if partition can not be mounted
|
||||||
|
* - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers
|
||||||
|
*/
|
||||||
|
esp_err_t esp_vfs_fat_sdspi_mount_mh(const char* base_path, const sdmmc_host_t* host_config_input, const sdspi_device_config_t* slot_config, const esp_vfs_fat_mount_config_t* mount_config, sdmmc_card_t** out_card);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -443,7 +443,7 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
|||||||
//free_psram_heap(std::string(TAG) + "->rgb_image (LoadFromMemory)", rgb_image);
|
//free_psram_heap(std::string(TAG) + "->rgb_image (LoadFromMemory)", rgb_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
|
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, STBI_rgb);
|
||||||
bpp = channels;
|
bpp = channels;
|
||||||
ESP_LOGD(TAG, "Image loaded from memory: %d, %d, %d", width, height, channels);
|
ESP_LOGD(TAG, "Image loaded from memory: %d, %d, %d", width, height, channels);
|
||||||
|
|
||||||
@@ -459,6 +459,44 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CImageBasis::crop_image(unsigned short cropLeft, unsigned short cropRight, unsigned short cropTop, unsigned short cropBottom)
|
||||||
|
{
|
||||||
|
unsigned int maxTopIndex = cropTop * width * channels;
|
||||||
|
unsigned int minBottomIndex = ((width*height) - (cropBottom * width)) * channels;
|
||||||
|
unsigned short maxX = width - cropRight; // In pixels
|
||||||
|
unsigned short newWidth = width - cropLeft - cropRight;
|
||||||
|
unsigned short newHeight = height - cropTop - cropBottom;
|
||||||
|
|
||||||
|
unsigned int writeIndex = 0;
|
||||||
|
// Loop over all bytes
|
||||||
|
for (int i = 0; i < width * height * channels; i += channels) {
|
||||||
|
// Calculate current X, Y pixel position
|
||||||
|
int x = (i/channels) % width;
|
||||||
|
|
||||||
|
// Crop from the top
|
||||||
|
if (i < maxTopIndex) { continue; }
|
||||||
|
|
||||||
|
// Crop from the bottom
|
||||||
|
if (i > minBottomIndex) { continue; }
|
||||||
|
|
||||||
|
// Crop from the left
|
||||||
|
if (x <= cropLeft) { continue; }
|
||||||
|
|
||||||
|
// Crop from the right
|
||||||
|
if (x > maxX) { continue; }
|
||||||
|
|
||||||
|
// If we get here, keep the pixels
|
||||||
|
for (int c = 0; c < channels; c++) {
|
||||||
|
rgb_image[writeIndex++] = rgb_image[i+c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the new dimensions of the framebuffer for further use.
|
||||||
|
width = newWidth;
|
||||||
|
height = newHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CImageBasis::CImageBasis(string _name, CImageBasis *_copyfrom)
|
CImageBasis::CImageBasis(string _name, CImageBasis *_copyfrom)
|
||||||
{
|
{
|
||||||
name = _name;
|
name = _name;
|
||||||
@@ -598,6 +636,20 @@ CImageBasis::CImageBasis(string _name, uint8_t* _rgb_image, int _channels, int _
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CImageBasis::Negative(void)
|
||||||
|
{
|
||||||
|
RGBImageLock();
|
||||||
|
|
||||||
|
for (int i = 0; i < width * height * channels; i += channels) {
|
||||||
|
for (int c = 0; c < channels; c++) {
|
||||||
|
rgb_image[i+c] = 255 - rgb_image[i+c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RGBImageRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
|
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
|
||||||
{
|
{
|
||||||
stbi_uc* p_source;
|
stbi_uc* p_source;
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class CImageBasis
|
|||||||
void drawEllipse(int x1, int y1, int radx, int rady, int r, int g, int b, int thickness = 1);
|
void drawEllipse(int x1, int y1, int radx, int rady, int r, int g, int b, int thickness = 1);
|
||||||
|
|
||||||
void setPixelColor(int x, int y, int r, int g, int b);
|
void setPixelColor(int x, int y, int r, int g, int b);
|
||||||
|
void Negative(void);
|
||||||
void Contrast(float _contrast);
|
void Contrast(float _contrast);
|
||||||
bool ImageOkay();
|
bool ImageOkay();
|
||||||
bool CopyFromMemory(uint8_t* _source, int _size);
|
bool CopyFromMemory(uint8_t* _source, int _size);
|
||||||
@@ -74,6 +75,7 @@ class CImageBasis
|
|||||||
|
|
||||||
void Resize(int _new_dx, int _new_dy);
|
void Resize(int _new_dx, int _new_dy);
|
||||||
void Resize(int _new_dx, int _new_dy, CImageBasis *_target);
|
void Resize(int _new_dx, int _new_dy, CImageBasis *_target);
|
||||||
|
void crop_image(unsigned short cropLeft, unsigned short cropRight, unsigned short cropTop, unsigned short cropBottom);
|
||||||
|
|
||||||
void LoadFromMemory(stbi_uc *_buffer, int len);
|
void LoadFromMemory(stbi_uc *_buffer, int len);
|
||||||
|
|
||||||
|
|||||||
@@ -18,50 +18,6 @@ CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_t
|
|||||||
doflip = _flip;
|
doflip = _flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CRotateImage::Mirror(){
|
|
||||||
int memsize = width * height * channels;
|
|
||||||
uint8_t* odata;
|
|
||||||
if (ImageTMP)
|
|
||||||
{
|
|
||||||
odata = ImageTMP->RGBImageLock();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int x_source, y_source;
|
|
||||||
stbi_uc* p_target;
|
|
||||||
stbi_uc* p_source;
|
|
||||||
|
|
||||||
RGBImageLock();
|
|
||||||
|
|
||||||
for (int x = 0; x < width; ++x)
|
|
||||||
for (int y = 0; y < height; ++y)
|
|
||||||
{
|
|
||||||
p_target = odata + (channels * (y * width + x));
|
|
||||||
|
|
||||||
x_source = width - x;
|
|
||||||
y_source = y;
|
|
||||||
|
|
||||||
p_source = rgb_image + (channels * (y_source * width + x_source));
|
|
||||||
for (int _channels = 0; _channels < channels; ++_channels)
|
|
||||||
p_target[_channels] = p_source[_channels];
|
|
||||||
}
|
|
||||||
|
|
||||||
// memcpy(rgb_image, odata, memsize);
|
|
||||||
memCopy(odata, rgb_image, memsize);
|
|
||||||
if (!ImageTMP)
|
|
||||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
|
||||||
|
|
||||||
if (ImageTMP)
|
|
||||||
ImageTMP->RGBImageRelease();
|
|
||||||
|
|
||||||
RGBImageRelease();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
|
void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
|
||||||
{
|
{
|
||||||
int org_width, org_height;
|
int org_width, org_height;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ class CRotateImage: public CImageBasis
|
|||||||
void RotateAntiAliasing(float _angle, int _centerx, int _centery);
|
void RotateAntiAliasing(float _angle, int _centerx, int _centery);
|
||||||
|
|
||||||
void Translate(int _dx, int _dy);
|
void Translate(int _dx, int _dy);
|
||||||
void Mirror();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CROTATEIMAGE_H
|
#endif //CROTATEIMAGE_H
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "ClassLogFile.h"
|
#include "ClassLogFile.h"
|
||||||
#include "esp_http_client.h"
|
#include "esp_http_client.h"
|
||||||
|
#include "time_sntp.h"
|
||||||
#include "../../include/defines.h"
|
#include "../../include/defines.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ void InfluxDB_V2_Init(std::string _uri, std::string _bucket, std::string _org, s
|
|||||||
_influxDB_V2_Token = _token;
|
_influxDB_V2_Token = _token;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string _content, std::string _timestamp)
|
void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC)
|
||||||
{
|
{
|
||||||
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||||
esp_http_client_config_t http_config = {
|
esp_http_client_config_t http_config = {
|
||||||
@@ -41,28 +42,20 @@ void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string
|
|||||||
.user_data = response_buffer
|
.user_data = response_buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDB_V2_Publish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp);
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDB_V2_Publish - Key: " + _key + ", Content: " + _content + ", timeUTC: " + std::to_string(_timeUTC));
|
||||||
|
|
||||||
std::string payload;
|
std::string payload;
|
||||||
char nowTimestamp[21];
|
char nowTimestamp[21];
|
||||||
|
|
||||||
if (_timestamp.length() > 0)
|
if (_timeUTC > 0)
|
||||||
{
|
{
|
||||||
struct tm tm;
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Timestamp (UTC): " + std::to_string(_timeUTC));
|
||||||
|
sprintf(nowTimestamp,"%ld000000000", _timeUTC); // UTC
|
||||||
time_t t;
|
|
||||||
time(&t);
|
|
||||||
localtime_r(&t, &tm); // Extract DST setting from actual time to consider it for timestamp evaluation
|
|
||||||
|
|
||||||
strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm);
|
|
||||||
t = mktime(&tm);
|
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Timestamp: " + _timestamp + ", Timestamp (UTC): " + std::to_string(t));
|
|
||||||
|
|
||||||
sprintf(nowTimestamp,"%ld000000000", (long) t); // UTC
|
|
||||||
payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "no timestamp given");
|
||||||
payload = _measurement + " " + _key + "=" + _content;
|
payload = _measurement + " " + _key + "=" + _content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +130,7 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, std::string _timestamp) {
|
void InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC) {
|
||||||
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||||
esp_http_client_config_t http_config = {
|
esp_http_client_config_t http_config = {
|
||||||
.user_agent = "ESP32 Meter reader",
|
.user_agent = "ESP32 Meter reader",
|
||||||
@@ -156,25 +149,17 @@ void InfluxDBPublish(std::string _measurement, std::string _key, std::string _co
|
|||||||
std::string payload;
|
std::string payload;
|
||||||
char nowTimestamp[21];
|
char nowTimestamp[21];
|
||||||
|
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp);
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", timeUTC: " + std::to_string(_timeUTC));
|
||||||
|
|
||||||
if (_timestamp.length() > 0)
|
if (_timeUTC > 0)
|
||||||
{
|
{
|
||||||
struct tm tm;
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Timestamp (UTC): " + std::to_string(_timeUTC));
|
||||||
|
sprintf(nowTimestamp,"%ld000000000", _timeUTC); // UTC
|
||||||
time_t t;
|
|
||||||
time(&t);
|
|
||||||
localtime_r(&t, &tm); // Extract DST setting from actual time to consider it for timestamp evaluation
|
|
||||||
|
|
||||||
strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm);
|
|
||||||
t = mktime(&tm);
|
|
||||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Timestamp: " + _timestamp + ", Timestamp (UTC): " + std::to_string(t));
|
|
||||||
|
|
||||||
sprintf(nowTimestamp,"%ld000000000", (long) t); // UTC
|
|
||||||
payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "no timestamp given");
|
||||||
payload = _measurement + " " + _key + "=" + _content;
|
payload = _measurement + " " + _key + "=" + _content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
|
|
||||||
// Interface to InfluxDB v1.x
|
// Interface to InfluxDB v1.x
|
||||||
void InfluxDBInit(std::string _influxDBURI, std::string _database, std::string _user, std::string _password);
|
void InfluxDBInit(std::string _influxDBURI, std::string _database, std::string _user, std::string _password);
|
||||||
void InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, std::string _timestamp);
|
void InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC);
|
||||||
|
|
||||||
// Interface to InfluxDB v2.x
|
// Interface to InfluxDB v2.x
|
||||||
void InfluxDB_V2_Init(std::string _uri, std::string _bucket, std::string _org, std::string _token);
|
void InfluxDB_V2_Init(std::string _uri, std::string _bucket, std::string _org, std::string _token);
|
||||||
void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string _content, std::string _timestamp);
|
void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ static const char *TAG = "MQTT SERVER";
|
|||||||
extern const char* libfive_git_version(void);
|
extern const char* libfive_git_version(void);
|
||||||
extern const char* libfive_git_revision(void);
|
extern const char* libfive_git_revision(void);
|
||||||
extern const char* libfive_git_branch(void);
|
extern const char* libfive_git_branch(void);
|
||||||
|
extern std::string getFwVersion(void);
|
||||||
|
|
||||||
std::vector<NumberPost*>* NUMBERS;
|
std::vector<NumberPost*>* NUMBERS;
|
||||||
bool HomeassistantDiscovery = false;
|
bool HomeassistantDiscovery = false;
|
||||||
@@ -151,6 +152,7 @@ bool MQTThomeassistantDiscovery(int qos) {
|
|||||||
// Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category
|
// Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category
|
||||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "uptime", "Uptime", "clock-time-eight-outline", "s", "", "", "diagnostic", qos);
|
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "uptime", "Uptime", "clock-time-eight-outline", "s", "", "", "diagnostic", qos);
|
||||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "MAC", "MAC Address", "network-outline", "", "", "", "diagnostic", qos);
|
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "MAC", "MAC Address", "network-outline", "", "", "", "diagnostic", qos);
|
||||||
|
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "fwVersion", "Firmware Version", "application-outline", "", "", "", "diagnostic", qos);
|
||||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "hostname", "Hostname", "network-outline", "", "", "", "diagnostic", qos);
|
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "hostname", "Hostname", "network-outline", "", "", "", "diagnostic", qos);
|
||||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "freeMem", "Free Memory", "memory", "B", "", "measurement", "diagnostic", qos);
|
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "freeMem", "Free Memory", "memory", "B", "", "measurement", "diagnostic", qos);
|
||||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "wifiRSSI", "Wi-Fi RSSI", "wifi", "dBm", "signal_strength", "", "diagnostic", qos);
|
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "wifiRSSI", "Wi-Fi RSSI", "wifi", "dBm", "signal_strength", "", "diagnostic", qos);
|
||||||
@@ -244,6 +246,7 @@ bool publishStaticData(int qos) {
|
|||||||
|
|
||||||
int aFreeInternalHeapSizeBefore = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
int aFreeInternalHeapSizeBefore = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||||
|
|
||||||
|
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "fwVersion", getFwVersion().c_str(), qos, retainFlag);
|
||||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "MAC", getMac(), qos, retainFlag);
|
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "MAC", getMac(), qos, retainFlag);
|
||||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "IP", *getIPAddress(), qos, retainFlag);
|
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "IP", *getIPAddress(), qos, retainFlag);
|
||||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "hostname", wlan_config.hostname, qos, retainFlag);
|
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "hostname", wlan_config.hostname, qos, retainFlag);
|
||||||
|
|||||||
@@ -333,3 +333,17 @@ CTfLiteClass::~CTfLiteClass()
|
|||||||
|
|
||||||
psram_free_shared_tensor_arena_and_model_memory();
|
psram_free_shared_tensor_arena_and_model_memory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SUPRESS_TFLITE_ERRORS
|
||||||
|
namespace tflite
|
||||||
|
{
|
||||||
|
//tflite::ErrorReporter
|
||||||
|
// int OwnMicroErrorReporter::Report(const char* format, va_list args)
|
||||||
|
|
||||||
|
int OwnMicroErrorReporter::Report(const char* format, va_list args)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
|||||||
|
|
||||||
idf_component_register(SRCS ${app_sources}
|
idf_component_register(SRCS ${app_sources}
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES esp-tflite-micro jomjol_logfile jomjol_configfile)
|
REQUIRES esp_netif esp-tflite-micro jomjol_logfile jomjol_configfile)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "esp_sleep.h"
|
#include "esp_sleep.h"
|
||||||
#include "esp_sntp.h"
|
#include "esp_netif_sntp.h"
|
||||||
|
|
||||||
#include "../../include/defines.h"
|
#include "../../include/defines.h"
|
||||||
|
|
||||||
#include "ClassLogFile.h"
|
#include "ClassLogFile.h"
|
||||||
@@ -31,6 +32,9 @@ std::string getNtpStatusText(sntp_sync_status_t status);
|
|||||||
static void setTimeZone(std::string _tzstring);
|
static void setTimeZone(std::string _tzstring);
|
||||||
static std::string getServerName(void);
|
static std::string getServerName(void);
|
||||||
|
|
||||||
|
int LocalTimeToUTCOffsetSeconds;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string ConvertTimeToString(time_t _time, const char * frm)
|
std::string ConvertTimeToString(time_t _time, const char * frm)
|
||||||
{
|
{
|
||||||
@@ -89,15 +93,51 @@ bool time_manual_reset_sync(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int getUTCOffsetSeconds(std::string &zeitzone)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
int vorzeichen = 1;
|
||||||
|
int minuten = 0;
|
||||||
|
int stunden = 0;
|
||||||
|
time_t now;
|
||||||
|
struct tm timeinfo;
|
||||||
|
|
||||||
|
time (&now);
|
||||||
|
localtime_r(&now, &timeinfo);
|
||||||
|
char buffer[80];
|
||||||
|
strftime(buffer, 80, "%z", &timeinfo);
|
||||||
|
zeitzone = std::string(buffer);
|
||||||
|
|
||||||
|
if (zeitzone.length() == 5)
|
||||||
|
{
|
||||||
|
if (zeitzone[0] == '-')
|
||||||
|
vorzeichen = -1;
|
||||||
|
|
||||||
|
stunden = stoi(zeitzone.substr(1, 2));
|
||||||
|
minuten = stoi(zeitzone.substr(3, 2));
|
||||||
|
|
||||||
|
offset = ((stunden * 60) + minuten) * 60;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void setTimeZone(std::string _tzstring)
|
void setTimeZone(std::string _tzstring)
|
||||||
{
|
{
|
||||||
setenv("TZ", _tzstring.c_str(), 1);
|
setenv("TZ", _tzstring.c_str(), 1);
|
||||||
tzset();
|
tzset();
|
||||||
|
|
||||||
_tzstring = "Time zone set to " + _tzstring;
|
_tzstring = "Time zone set to " + _tzstring;
|
||||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _tzstring);
|
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _tzstring);
|
||||||
|
|
||||||
|
std::string zeitzone;
|
||||||
|
LocalTimeToUTCOffsetSeconds = getUTCOffsetSeconds(zeitzone);
|
||||||
|
// std::string zw = std::to_string(LocalTimeToUTCOffsetSeconds);
|
||||||
|
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "time zone: " + zeitzone + " Delta to UTC: " + std::to_string(LocalTimeToUTCOffsetSeconds) + " seconds");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string getNtpStatusText(sntp_sync_status_t status) {
|
std::string getNtpStatusText(sntp_sync_status_t status) {
|
||||||
if (status == SNTP_SYNC_STATUS_COMPLETED) {
|
if (status == SNTP_SYNC_STATUS_COMPLETED) {
|
||||||
return "Synchronized";
|
return "Synchronized";
|
||||||
@@ -235,21 +275,13 @@ bool setupTime() {
|
|||||||
|
|
||||||
if (useNtp) {
|
if (useNtp) {
|
||||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Configuring NTP Client...");
|
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Configuring NTP Client...");
|
||||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG(timeServer.c_str());
|
||||||
sntp_setservername(0, timeServer.c_str());
|
config.sync_cb = time_sync_notification_cb;
|
||||||
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
|
esp_netif_sntp_init(&config);
|
||||||
|
|
||||||
setTimeZone(timeZone);
|
setTimeZone(timeZone);
|
||||||
|
|
||||||
sntp_init();
|
|
||||||
/*
|
|
||||||
if (!wait_for_timesync())
|
|
||||||
{
|
|
||||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Timesync at startup failed.");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The RTC keeps the time after a restart (Except on Power On or Pin Reset)
|
/* The RTC keeps the time after a restart (Except on Power On or Pin Reset)
|
||||||
* There should only be a minor correction through NTP */
|
* There should only be a minor correction through NTP */
|
||||||
|
|
||||||
@@ -258,6 +290,7 @@ bool setupTime() {
|
|||||||
localtime_r(&now, &timeinfo);
|
localtime_r(&now, &timeinfo);
|
||||||
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d %H:%M:%S", &timeinfo);
|
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d %H:%M:%S", &timeinfo);
|
||||||
|
|
||||||
|
|
||||||
if (getTimeIsSet()) {
|
if (getTimeIsSet()) {
|
||||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Time is already set: " + std::string(strftime_buf));
|
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Time is already set: " + std::string(strftime_buf));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,5 +28,7 @@ bool setupTime();
|
|||||||
|
|
||||||
bool time_manual_reset_sync(void);
|
bool time_manual_reset_sync(void);
|
||||||
|
|
||||||
|
extern int LocalTimeToUTCOffsetSeconds;
|
||||||
|
|
||||||
|
|
||||||
#endif //TIMESNTP_H
|
#endif //TIMESNTP_H
|
||||||
@@ -378,7 +378,7 @@ void wifi_scan(void)
|
|||||||
else {
|
else {
|
||||||
if (esp_wifi_scan_get_ap_records(&max_number_of_ap_found, wifi_ap_records) != ESP_OK) { // Retrieve results (and free internal heap)
|
if (esp_wifi_scan_get_ap_records(&max_number_of_ap_found, wifi_ap_records) != ESP_OK) { // Retrieve results (and free internal heap)
|
||||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "wifi_scan: esp_wifi_scan_get_ap_records: Error retrieving datasets");
|
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "wifi_scan: esp_wifi_scan_get_ap_records: Error retrieving datasets");
|
||||||
delete wifi_ap_records;
|
delete[] wifi_ap_records;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,7 +401,7 @@ void wifi_scan(void)
|
|||||||
APWithBetterRSSI = true;
|
APWithBetterRSSI = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete wifi_ap_records;
|
delete[] wifi_ap_records;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
#define FLASH_GPIO GPIO_NUM_4 // PIN for flashlight LED
|
#define FLASH_GPIO GPIO_NUM_4 // PIN for flashlight LED
|
||||||
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
||||||
#define CAM_LIVESTREAM_REFRESHRATE 500 // Camera livestream feature: Waiting time in milliseconds to refresh image
|
#define CAM_LIVESTREAM_REFRESHRATE 500 // Camera livestream feature: Waiting time in milliseconds to refresh image
|
||||||
|
// #define GRAYSCALE_AS_DEFAULT
|
||||||
|
|
||||||
|
|
||||||
//ClassControllCamera + ClassFlowTakeImage
|
//ClassControllCamera + ClassFlowTakeImage
|
||||||
@@ -167,15 +168,6 @@
|
|||||||
#define LWT_DISCONNECTED "connection lost"
|
#define LWT_DISCONNECTED "connection lost"
|
||||||
|
|
||||||
|
|
||||||
//CTfLiteClass
|
|
||||||
#define TFLITE_MINIMAL_CHECK(x) \
|
|
||||||
if (!(x)) { \
|
|
||||||
fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); \
|
|
||||||
exit(1); \
|
|
||||||
}
|
|
||||||
// #define SUPRESS_TFLITE_ERRORS // use, to avoid error messages from TFLITE
|
|
||||||
|
|
||||||
|
|
||||||
// connect_wlan.cpp
|
// connect_wlan.cpp
|
||||||
//******************************
|
//******************************
|
||||||
/* WIFI roaming functionalities 802.11k+v (uses ca. 6kB - 8kB internal RAM; if SCAN CACHE activated: + 1kB / beacon)
|
/* WIFI roaming functionalities 802.11k+v (uses ca. 6kB - 8kB internal RAM; if SCAN CACHE activated: + 1kB / beacon)
|
||||||
|
|||||||
@@ -3,12 +3,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
//#include "freertos/FreeRTOS.h"
|
|
||||||
//#include "freertos/task.h"
|
|
||||||
//#include "freertos/event_groups.h"
|
|
||||||
|
|
||||||
//#include "driver/gpio.h"
|
|
||||||
//#include "sdkconfig.h"
|
|
||||||
#include "esp_psram.h"
|
#include "esp_psram.h"
|
||||||
#include "esp_pm.h"
|
#include "esp_pm.h"
|
||||||
|
|
||||||
@@ -16,17 +10,13 @@
|
|||||||
|
|
||||||
#include "esp_chip_info.h"
|
#include "esp_chip_info.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// SD-Card ////////////////////
|
// SD-Card ////////////////////
|
||||||
//#include "nvs_flash.h"
|
#include "sdcard_init.h"
|
||||||
#include "esp_vfs_fat.h"
|
#include "esp_vfs_fat.h"
|
||||||
//#include "sdmmc_cmd.h"
|
#include "ffconf.h"
|
||||||
#include "driver/sdmmc_host.h"
|
#include "driver/sdmmc_host.h"
|
||||||
//#include "driver/sdmmc_defs.h"
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
#include "ClassLogFile.h"
|
#include "ClassLogFile.h"
|
||||||
|
|
||||||
#include "connect_wlan.h"
|
#include "connect_wlan.h"
|
||||||
@@ -38,7 +28,6 @@
|
|||||||
#include "server_ota.h"
|
#include "server_ota.h"
|
||||||
#include "time_sntp.h"
|
#include "time_sntp.h"
|
||||||
#include "configFile.h"
|
#include "configFile.h"
|
||||||
//#include "ClassControllCamera.h"
|
|
||||||
#include "server_main.h"
|
#include "server_main.h"
|
||||||
#include "server_camera.h"
|
#include "server_camera.h"
|
||||||
#ifdef ENABLE_MQTT
|
#ifdef ENABLE_MQTT
|
||||||
@@ -49,7 +38,6 @@
|
|||||||
#include "sdcard_check.h"
|
#include "sdcard_check.h"
|
||||||
|
|
||||||
#include "../../include/defines.h"
|
#include "../../include/defines.h"
|
||||||
//#include "server_GPIO.h"
|
|
||||||
|
|
||||||
#ifdef ENABLE_SOFTAP
|
#ifdef ENABLE_SOFTAP
|
||||||
#include "softAP.h"
|
#include "softAP.h"
|
||||||
@@ -101,6 +89,8 @@ bool setCpuFrequency(void);
|
|||||||
|
|
||||||
static const char *TAG = "MAIN";
|
static const char *TAG = "MAIN";
|
||||||
|
|
||||||
|
#define MOUNT_POINT "/sdcard"
|
||||||
|
|
||||||
|
|
||||||
bool Init_NVS_SDCard()
|
bool Init_NVS_SDCard()
|
||||||
{
|
{
|
||||||
@@ -112,26 +102,30 @@ bool Init_NVS_SDCard()
|
|||||||
|
|
||||||
ESP_LOGD(TAG, "Using SDMMC peripheral");
|
ESP_LOGD(TAG, "Using SDMMC peripheral");
|
||||||
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
||||||
|
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
|
||||||
|
|
||||||
// This initializes the slot without card detect (CD) and write protect (WP) signals.
|
// This initializes the slot without card detect (CD) and write protect (WP) signals.
|
||||||
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
|
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
|
||||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||||
|
|
||||||
// To use 1-line SD mode, uncomment the following line:
|
// Set bus width to use:
|
||||||
#ifdef __SD_USE_ONE_LINE_MODE__
|
#ifdef __SD_USE_ONE_LINE_MODE__
|
||||||
slot_config.width = 1;
|
slot_config.width = 1;
|
||||||
#endif
|
#else
|
||||||
|
slot_config.width = 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
// GPIOs 15, 2, 4, 12, 13 should have external 10k pull-ups.
|
// Enable internal pullups on enabled pins. The internal pullups
|
||||||
// Internal pull-ups are not sufficient. However, enabling internal pull-ups
|
// are insufficient however, please make sure 10k external pullups are
|
||||||
// does make a difference some boards, so we do that here.
|
// connected on the bus. This is for debug / example purpose only.
|
||||||
gpio_set_pull_mode(GPIO_NUM_15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1- line modes
|
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
||||||
gpio_set_pull_mode(GPIO_NUM_2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
|
|
||||||
#ifndef __SD_USE_ONE_LINE_MODE__
|
// Der PullUp des GPIO13 wird durch slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
|
||||||
gpio_set_pull_mode(GPIO_NUM_4, GPIO_PULLUP_ONLY); // D1, needed in 4-line mode only
|
// nicht gesetzt, da er eigentlich nicht benötigt wird,
|
||||||
gpio_set_pull_mode(GPIO_NUM_12, GPIO_PULLUP_ONLY); // D2, needed in 4-line mode only
|
// dies führt jedoch bei schlechten Kopien des AI_THINKER Boards
|
||||||
#endif
|
// zu Problemen mit der SD Initialisierung und eventuell sogar zur reboot-loops.
|
||||||
gpio_set_pull_mode(GPIO_NUM_13, GPIO_PULLUP_ONLY); // D3, needed in 4- and 1-line modes
|
// Um diese Probleme zu kompensieren, wird der PullUp manuel gesetzt.
|
||||||
|
gpio_set_pull_mode(GPIO_NUM_13, GPIO_PULLUP_ONLY); // HS2_D3
|
||||||
|
|
||||||
// Options for mounting the filesystem.
|
// Options for mounting the filesystem.
|
||||||
// If format_if_mount_failed is set to true, SD card will be partitioned and
|
// If format_if_mount_failed is set to true, SD card will be partitioned and
|
||||||
@@ -139,15 +133,18 @@ bool Init_NVS_SDCard()
|
|||||||
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
|
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
|
||||||
.format_if_mount_failed = false,
|
.format_if_mount_failed = false,
|
||||||
.max_files = 12, // previously -> 2022-09-21: 5, 2023-01-02: 7
|
.max_files = 12, // previously -> 2022-09-21: 5, 2023-01-02: 7
|
||||||
.allocation_unit_size = 16 * 1024
|
.allocation_unit_size = 0, // 0 = auto
|
||||||
|
.disk_status_check_enable = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
sdmmc_card_t* card;
|
sdmmc_card_t* card;
|
||||||
|
const char mount_point[] = MOUNT_POINT;
|
||||||
|
|
||||||
// Use settings defined above to initialize SD card and mount FAT filesystem.
|
// Use settings defined above to initialize SD card and mount FAT filesystem.
|
||||||
// Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function.
|
// Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function.
|
||||||
// Please check its source code and implement error recovery when developing
|
// Please check its source code and implement error recovery when developing
|
||||||
// production applications.
|
// production applications.
|
||||||
ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
|
ret = esp_vfs_fat_sdmmc_mount_mh(mount_point, &host, &slot_config, &mount_config, &card);
|
||||||
|
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
if (ret == ESP_FAIL) {
|
if (ret == ESP_FAIL) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "MainFlowControl.h"
|
#include "MainFlowControl.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "esp_chip_info.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -170,6 +171,27 @@ esp_err_t info_get_handler(httpd_req_t *req)
|
|||||||
httpd_resp_sendstr(req, zw.c_str());
|
httpd_resp_sendstr(req, zw.c_str());
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
else if (_task.compare("ChipCores") == 0)
|
||||||
|
{
|
||||||
|
esp_chip_info_t chipInfo;
|
||||||
|
esp_chip_info(&chipInfo);
|
||||||
|
httpd_resp_sendstr(req, to_string(chipInfo.cores).c_str());
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
else if (_task.compare("ChipRevision") == 0)
|
||||||
|
{
|
||||||
|
esp_chip_info_t chipInfo;
|
||||||
|
esp_chip_info(&chipInfo);
|
||||||
|
httpd_resp_sendstr(req, to_string(chipInfo.revision).c_str());
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
else if (_task.compare("ChipFeatures") == 0)
|
||||||
|
{
|
||||||
|
esp_chip_info_t chipInfo;
|
||||||
|
esp_chip_info(&chipInfo);
|
||||||
|
httpd_resp_sendstr(req, to_string(chipInfo.features).c_str());
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char formatted[256];
|
char formatted[256];
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
[common:esp32-idf]
|
[common:esp32-idf]
|
||||||
extends = common:idf
|
extends = common:idf
|
||||||
platform = platformio/espressif32 @ 6.3.2
|
platform = platformio/espressif32 @ 6.5.0
|
||||||
framework = espidf
|
framework = espidf
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common:idf.lib_deps}
|
${common:idf.lib_deps}
|
||||||
|
|||||||
@@ -109,11 +109,6 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
|
|||||||
|
|
||||||
CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024
|
CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024
|
||||||
CONFIG_HTTPD_PURGE_BUF_LEN=16
|
CONFIG_HTTPD_PURGE_BUF_LEN=16
|
||||||
<<<<<<< Updated upstream
|
|
||||||
=======
|
|
||||||
CONFIG_HTTPD_WS_SUPPORT=y
|
|
||||||
CONFIG_LWIP_MAX_SOCKETS=12
|
|
||||||
>>>>>>> Stashed changes
|
|
||||||
|
|
||||||
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16
|
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16
|
||||||
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=16
|
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=16
|
||||||
|
|||||||
@@ -33,7 +33,17 @@ std::string process_doFlow(UnderTestPost* _underTestPost) {
|
|||||||
return _underTestPost->getReadout(0);
|
return _underTestPost->getReadout(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief setup flow like it runs after recognition.
|
||||||
|
*
|
||||||
|
* @param analog the analog recognitions as array begins with the highest ROI
|
||||||
|
* @param digits the digital regocnitions as array begins with the highest ROI
|
||||||
|
* @param digType type of the model defaults do Digital100
|
||||||
|
* @param checkConsistency for Digital type only. Not relvant for newer models
|
||||||
|
* @param extendedResolution the lowest ROI will directly used (9.7 => 9.7) if false 9.7 => 9
|
||||||
|
* @param decimal_shift the decimal point offset. -3 corresponds to x.yyy
|
||||||
|
* @return std::string the value result
|
||||||
|
*/
|
||||||
std::string process_doFlow(std::vector<float> analog, std::vector<float> digits, t_CNNType digType,
|
std::string process_doFlow(std::vector<float> analog, std::vector<float> digits, t_CNNType digType,
|
||||||
bool checkConsistency, bool extendedResolution, int decimal_shift) {
|
bool checkConsistency, bool extendedResolution, int decimal_shift) {
|
||||||
// setup the classundertest
|
// setup the classundertest
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ void testNegative_Issues() {
|
|||||||
setPreValue(underTestPost, preValue_extended);
|
setPreValue(underTestPost, preValue_extended);
|
||||||
std::string result = process_doFlow(underTestPost);
|
std::string result = process_doFlow(underTestPost);
|
||||||
TEST_ASSERT_EQUAL_STRING("Neg. Rate - Read: - Raw: 22017.98 - Pre: 22018.09 ", underTestPost->getReadoutError().c_str());
|
TEST_ASSERT_EQUAL_STRING("Neg. Rate - Read: - Raw: 22017.98 - Pre: 22018.09 ", underTestPost->getReadoutError().c_str());
|
||||||
|
// if negativ no result any more
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_STRING("", result.c_str());
|
TEST_ASSERT_EQUAL_STRING("", result.c_str());
|
||||||
delete underTestPost;
|
delete underTestPost;
|
||||||
|
|
||||||
|
|||||||
@@ -138,10 +138,6 @@ void task_UnityTesting(void *pvParameter)
|
|||||||
RUN_TEST(test_doFlowPP3);
|
RUN_TEST(test_doFlowPP3);
|
||||||
printf("---------------------------------------------------------------------------\n");
|
printf("---------------------------------------------------------------------------\n");
|
||||||
RUN_TEST(test_doFlowPP4);
|
RUN_TEST(test_doFlowPP4);
|
||||||
printf("---------------------------------------------------------------------------\n");
|
|
||||||
RUN_TEST(test_doFlowPP_rainman110);
|
|
||||||
printf("---------------------------------------------------------------------------\n");
|
|
||||||
RUN_TEST(test_doFlowPP_rainman110_transition);
|
|
||||||
UNITY_END();
|
UNITY_END();
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
@@ -153,11 +149,24 @@ void task_UnityTesting(void *pvParameter)
|
|||||||
*/
|
*/
|
||||||
extern "C" void app_main()
|
extern "C" void app_main()
|
||||||
{
|
{
|
||||||
initGPIO();
|
initGPIO();
|
||||||
Init_NVS_SDCard();
|
Init_NVS_SDCard();
|
||||||
esp_log_level_set("*", ESP_LOG_DEBUG); // set all components to DEBUG level
|
esp_log_level_set("*", ESP_LOG_ERROR); // set all components to ERROR level
|
||||||
|
|
||||||
// Create dedicated testing task (heap size can be configured - large enough to handle a lot of testing cases)
|
UNITY_BEGIN();
|
||||||
// ********************************************
|
RUN_TEST(testNegative_Issues);
|
||||||
xTaskCreate(&task_UnityTesting, "task_UnityTesting", 12 * 1024, NULL, tskIDLE_PRIORITY+2, NULL);
|
RUN_TEST(testNegative);
|
||||||
|
|
||||||
|
RUN_TEST(test_analogToDigit_Standard);
|
||||||
|
RUN_TEST(test_analogToDigit_Transition);
|
||||||
|
RUN_TEST(test_doFlowPP);
|
||||||
|
RUN_TEST(test_doFlowPP1);
|
||||||
|
RUN_TEST(test_doFlowPP2);
|
||||||
|
RUN_TEST(test_doFlowPP3);
|
||||||
|
RUN_TEST(test_doFlowPP4);
|
||||||
|
|
||||||
|
// getReadoutRawString test
|
||||||
|
RUN_TEST(test_getReadoutRawString);
|
||||||
|
|
||||||
|
UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
3
param-docs/.idea/.gitignore
generated
vendored
Normal file
3
param-docs/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
8
param-docs/.idea/generate-param-docs.iml
generated
Normal file
8
param-docs/.idea/generate-param-docs.iml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.10" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
param-docs/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
param-docs/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
4
param-docs/.idea/misc.xml
generated
Normal file
4
param-docs/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
param-docs/.idea/modules.xml
generated
Normal file
8
param-docs/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/generate-param-docs.iml" filepath="$PROJECT_DIR$/.idea/generate-param-docs.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
param-docs/.idea/vcs.xml
generated
Normal file
6
param-docs/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
17
param-docs/README.md
Normal file
17
param-docs/README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Parameter Documentation
|
||||||
|
Each parameter which is listed in the [configfile](https://github.com/jomjol/AI-on-the-edge-device/blob/rolling/sd-card/config/config.ini) has its own description page in the folder `parameter-pages` (grouped by the config sections).
|
||||||
|
Those pages can be edited as needed.
|
||||||
|
|
||||||
|
During a Github action build, those parameter pages will be used to generate the tooltips in the web interface. And they also are used to build the [Online Documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Parameters).
|
||||||
|
|
||||||
|
If you create or rename a parameter, make sure to also update its description page!
|
||||||
|
|
||||||
|
## Template Generator
|
||||||
|
The script `generate-template-param-doc-pages.py` should be run whenever a new parameter gets added to the config file.
|
||||||
|
It then checks if there is already a page for each of the parameters.
|
||||||
|
- If no page exists yet, a templated page gets generated.
|
||||||
|
- Existing pages do not get modified.
|
||||||
|
|
||||||
|
If the parameter is listed in `expert-params.txt`, an **Expert warning** will be shown.
|
||||||
|
|
||||||
|
If the parameter is listed in `hidden-in-ui.txt`, a **Note** will be shown.
|
||||||
46
param-docs/expert-params.txt
Normal file
46
param-docs/expert-params.txt
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
WaitBeforeTakingPicture
|
||||||
|
CamFrameSize
|
||||||
|
CamGainceiling
|
||||||
|
CamQuality
|
||||||
|
CamAutoSharpness
|
||||||
|
CamSharpness
|
||||||
|
CamSpecialEffect
|
||||||
|
CamWbMode
|
||||||
|
CamAwb
|
||||||
|
CamAwbGain
|
||||||
|
CamAec
|
||||||
|
CamAec2
|
||||||
|
CamAeLevel
|
||||||
|
CamAecValue
|
||||||
|
CamAgc
|
||||||
|
CamAgcGain
|
||||||
|
CamBpc
|
||||||
|
CamWpc
|
||||||
|
CamRawGma
|
||||||
|
CamLenc
|
||||||
|
CamDcw
|
||||||
|
CamZoom
|
||||||
|
CamZoomSize
|
||||||
|
CamZoomOffsetX
|
||||||
|
CamZoomOffsetY
|
||||||
|
demo
|
||||||
|
SearchFieldX
|
||||||
|
SearchFieldY
|
||||||
|
AlignmentAlgo
|
||||||
|
CNNGoodThreshold
|
||||||
|
PreValueAgeStartup
|
||||||
|
ErrorMessage
|
||||||
|
CheckDigitIncreaseConsistency
|
||||||
|
IO0
|
||||||
|
IO1
|
||||||
|
IO3
|
||||||
|
IO4
|
||||||
|
IO12
|
||||||
|
IO13
|
||||||
|
AutoStart
|
||||||
|
Hostname
|
||||||
|
RSSIThreshold
|
||||||
|
TimeServer
|
||||||
|
CACert
|
||||||
|
ClientCert
|
||||||
|
ClientKey
|
||||||
95
param-docs/generate-template-param-doc-pages.py
Normal file
95
param-docs/generate-template-param-doc-pages.py
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
"""
|
||||||
|
For each parameter which can be found in the config file,
|
||||||
|
create a markdown file with a templated content if it does not exist yet.
|
||||||
|
The files are grouped in sub folders representing the config sections.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import configparser
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
|
||||||
|
configFileUrl = "https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/rolling/sd-card/config/config.ini"
|
||||||
|
|
||||||
|
parameterDocsFolder = "parameter-pages"
|
||||||
|
parameterTemplateFile = "./templates/parameter.md"
|
||||||
|
expertParameterListFile = "./expert-params.txt"
|
||||||
|
hiddenInUiParameterListFile = "./hidden-in-ui.txt"
|
||||||
|
|
||||||
|
|
||||||
|
# Fetch default config file from URL
|
||||||
|
print("Fetching %r..." % configFileUrl)
|
||||||
|
with urllib.request.urlopen(configFileUrl) as response:
|
||||||
|
content = response.read().decode("utf-8")
|
||||||
|
|
||||||
|
lines = str(content).split("\n")
|
||||||
|
|
||||||
|
for l in range(len(lines)):
|
||||||
|
lines[l] = lines[l].strip() + "\n"
|
||||||
|
if lines[l][0] == ";":
|
||||||
|
lines[l] = lines[l][1:] # Remove comment
|
||||||
|
|
||||||
|
content = "".join(lines)
|
||||||
|
|
||||||
|
# Fetch list of expert parameters
|
||||||
|
with open(expertParameterListFile) as f:
|
||||||
|
expertParameters = f.read().splitlines()
|
||||||
|
|
||||||
|
# Fetch list of parameters not available through the UI
|
||||||
|
with open(hiddenInUiParameterListFile) as f:
|
||||||
|
hiddenInUiParameters = f.read().splitlines()
|
||||||
|
|
||||||
|
|
||||||
|
config = configparser.ConfigParser(allow_no_value=True)
|
||||||
|
config.optionxform = str # Make it case-insensitive
|
||||||
|
config.read_string(content)
|
||||||
|
|
||||||
|
#shutil.rmtree(parameterDocsFolder)
|
||||||
|
if not os.path.exists(parameterDocsFolder):
|
||||||
|
os.mkdir(parameterDocsFolder)
|
||||||
|
|
||||||
|
with open(parameterTemplateFile, 'r') as parameterTemplateFileHandle:
|
||||||
|
parameterTemplate = parameterTemplateFileHandle.read()
|
||||||
|
|
||||||
|
|
||||||
|
print("For each section/parameter, check if there is already a documentation page in the folder %r..." % (os.getcwd() + "/" + parameterDocsFolder))
|
||||||
|
for section in config:
|
||||||
|
if section != "DEFAULT":
|
||||||
|
#print(section)
|
||||||
|
|
||||||
|
subFolder = parameterDocsFolder + "/" + section
|
||||||
|
|
||||||
|
if not os.path.exists(subFolder):
|
||||||
|
os.mkdir(subFolder)
|
||||||
|
|
||||||
|
for parameter in config[section]:
|
||||||
|
if not " " in parameter: # Ignore parameters with whitespaces in them (special format, not part of editable config)
|
||||||
|
value = config[section][parameter]
|
||||||
|
#print(" %s = %s" % (parameter, value))
|
||||||
|
|
||||||
|
if "main." in parameter:
|
||||||
|
parameter = parameter.replace("main.", "NUMBER.")
|
||||||
|
|
||||||
|
"""
|
||||||
|
For each config line, create a markdown file
|
||||||
|
"""
|
||||||
|
parameterDocFile = subFolder + '/' + parameter + ".md"
|
||||||
|
|
||||||
|
if not os.path.exists(parameterDocFile): # File does not exist yet, generate template
|
||||||
|
print("%r does not exit yet, generating a templated file for it" % (os.getcwd() + "/" + parameterDocFile))
|
||||||
|
with open(parameterDocFile, 'w') as paramFileHandle:
|
||||||
|
content = parameterTemplate
|
||||||
|
content = content.replace("$NAME", parameter)
|
||||||
|
content = content.replace("$DEFAULT", value)
|
||||||
|
|
||||||
|
if parameter in expertParameters:
|
||||||
|
content = content.replace("$EXPERT_PARAMETER", "!!! Warning\n This is an **Expert Parameter**! Only change it if you understand what it does!") # Note: Needs a 4 whitespace Intent!
|
||||||
|
else:
|
||||||
|
content = content.replace("$EXPERT_PARAMETER", "")
|
||||||
|
|
||||||
|
if parameter in hiddenInUiParameters:
|
||||||
|
content = content.replace("$HIDDEN_IN_UI", "!!! Note\n This parameter is not accessible through the Web Interface Configuration Page!") # Note: Needs a 4 whitespace Intent!
|
||||||
|
else:
|
||||||
|
content = content.replace("$HIDDEN_IN_UI", "")
|
||||||
|
|
||||||
|
paramFileHandle.write(content)
|
||||||
4
param-docs/hidden-in-ui.txt
Normal file
4
param-docs/hidden-in-ui.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
InitialRotate
|
||||||
|
MainTopicMQTT
|
||||||
|
AutoAdjustSummertime
|
||||||
|
SetupMode
|
||||||
14
param-docs/parameter-pages/Alignment/AlignmentAlgo.md
Normal file
14
param-docs/parameter-pages/Alignment/AlignmentAlgo.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Parameter `AlignmentAlgo`
|
||||||
|
Default Value: `Default`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
Algorithm used for the alignment step.
|
||||||
|
|
||||||
|
Available options:
|
||||||
|
|
||||||
|
- `Default`: Use only red color channel
|
||||||
|
- `HighAccuracy`: Use all 3 color channels (3x slower)
|
||||||
|
- `Fast`: First time use `HighAccuracy`, then only check if the image is shifted
|
||||||
|
- `Off`: Disable alignment algorithm
|
||||||
11
param-docs/parameter-pages/Alignment/FlipImageSize.md
Normal file
11
param-docs/parameter-pages/Alignment/FlipImageSize.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Parameter `FlipImageSize`
|
||||||
|
Default Value: `false`
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
This parameter can also be set on the Reference Image configuration page!
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
After changing this parameter you need to update your reference image and alignment markers!
|
||||||
|
|
||||||
|
This parameter can be used to rotate the viewport together with the alignment rotation:
|
||||||
|

|
||||||
10
param-docs/parameter-pages/Alignment/InitialMirror.md
Normal file
10
param-docs/parameter-pages/Alignment/InitialMirror.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Parameter `InitialMirror`
|
||||||
|
Default Value: `false`
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
This parameter can also be set on the Reference Image configuration page!
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
After changing this parameter you need to update your reference image and alignment markers!
|
||||||
|
|
||||||
|
Option for initially mirroring the image on the original x-axis.
|
||||||
12
param-docs/parameter-pages/Alignment/InitialRotate.md
Normal file
12
param-docs/parameter-pages/Alignment/InitialRotate.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Parameter `InitialRotate`
|
||||||
|
Default Value: `0`
|
||||||
|
|
||||||
|
Unit: Degrees
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
This parameter can also be set on the Reference Image configuration page!
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
After changing this parameter you need to update your reference image and alignment markers!
|
||||||
|
|
||||||
|
Initial rotation of image before alignment in degree (`-360` .. `+360`)
|
||||||
14
param-docs/parameter-pages/Alignment/SearchFieldX.md
Normal file
14
param-docs/parameter-pages/Alignment/SearchFieldX.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Parameter `SearchFieldX`
|
||||||
|
Default Value: `20`
|
||||||
|
|
||||||
|
Unit: Pixels
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
X-size (width) in which the reference is searched.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
Since the alignment is one of the steps using a lot of computation time,
|
||||||
|
the search field should be as small as possible.
|
||||||
|
The calculation time goes quadratic with the search field size.
|
||||||
14
param-docs/parameter-pages/Alignment/SearchFieldY.md
Normal file
14
param-docs/parameter-pages/Alignment/SearchFieldY.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Parameter `SearchFieldY`
|
||||||
|
Default Value: `20`
|
||||||
|
|
||||||
|
Unit: Pixels
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
Y-size (height) in which the reference is searched.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
Since the alignment is one of the steps using a lot of computation time,
|
||||||
|
the search field should be as small as possible.
|
||||||
|
The calculation time goes quadratic with the search field size.
|
||||||
10
param-docs/parameter-pages/Analog/CNNGoodThreshold.md
Normal file
10
param-docs/parameter-pages/Analog/CNNGoodThreshold.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Parameter `CNNGoodThreshold`
|
||||||
|
Default Value: `0.5`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
Threshold above which the classification should be to accept the value (only meaningful for digits).
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is only supported for the `ana-class100` models!
|
||||||
5
param-docs/parameter-pages/Analog/ExtendedResolution.md
Normal file
5
param-docs/parameter-pages/Analog/ExtendedResolution.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Parameter `ExtendedResolution`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This parameter is unused!
|
||||||
|
Use [`NUMBER.ExtendedResolution`](../Parameters/#PostProcessing-NUMBER.ExtendedResolution) instead!
|
||||||
4
param-docs/parameter-pages/Analog/Model.md
Normal file
4
param-docs/parameter-pages/Analog/Model.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Parameter `Model`
|
||||||
|
Default Value: `/config/ana-cont_*.tflite` (See [/config/config.ini](https://github.com/jomjol/AI-on-the-edge-device/blob/master/sd-card/config/config.ini))
|
||||||
|
|
||||||
|
Path to CNN model file for image recognition. See [here](../Choosing-the-Model) for details.
|
||||||
7
param-docs/parameter-pages/Analog/ROIImagesLocation.md
Normal file
7
param-docs/parameter-pages/Analog/ROIImagesLocation.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Parameter `ROIImagesLocation`
|
||||||
|
Default Value: `/log/analog`
|
||||||
|
|
||||||
|
Location to store separated analog images on the SD-Card.
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
A SD-Card has limited write cycles. Since the device does not do [Wear Leveling](https://en.wikipedia.org/wiki/Wear_leveling), this can wear out your SD-Card!
|
||||||
6
param-docs/parameter-pages/Analog/ROIImagesRetention.md
Normal file
6
param-docs/parameter-pages/Analog/ROIImagesRetention.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Parameter `ROIImagesRetention`
|
||||||
|
Default Value: `3`
|
||||||
|
|
||||||
|
Unit: Days
|
||||||
|
|
||||||
|
Days to keep the separated analog images (`0` = forever).
|
||||||
12
param-docs/parameter-pages/AutoTimer/AutoStart.md
Normal file
12
param-docs/parameter-pages/AutoTimer/AutoStart.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Parameter `AutoStart`
|
||||||
|
Default Value: `true`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
Automatically start the Flow (Digitization Rounds) immediately after power up.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
Typically this is set to `true`.
|
||||||
|
The main reasons to set it to `false` is when you want to trigger it manually using the
|
||||||
|
[REST API](../REST-API) or [MQTT-API](../MQTT-API) or for debugging.
|
||||||
7
param-docs/parameter-pages/AutoTimer/Interval.md
Normal file
7
param-docs/parameter-pages/AutoTimer/Interval.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Parameter `Interval`
|
||||||
|
Default Value: `5`
|
||||||
|
|
||||||
|
Unit: Minutes
|
||||||
|
|
||||||
|
Interval in which the Flow (Digitization Round) is run.
|
||||||
|
If a round takes longer than this interval, the next round gets postponed until the current round completes.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Parameter `DataFilesRetention`
|
||||||
|
Default Value: `3`
|
||||||
|
|
||||||
|
Unit: Days
|
||||||
|
|
||||||
|
Number of days to keep the data files (`0` = forever).
|
||||||
8
param-docs/parameter-pages/DataLogging/DataLogActive.md
Normal file
8
param-docs/parameter-pages/DataLogging/DataLogActive.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Parameter `DataLogActive`
|
||||||
|
Default Value: `true`
|
||||||
|
Activate data logging to the SD-Card.
|
||||||
|
|
||||||
|
The files will be stored in `/log/data/data_YYYY-MM-DD.csv`. See [`Data Logging`](../data-logging) for details.
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
A SD-Card has limited write cycles. Since the device does not do [Wear Leveling](https://en.wikipedia.org/wiki/Wear_leveling), this can wear out your SD-Card!
|
||||||
16
param-docs/parameter-pages/Debug/LogLevel.md
Normal file
16
param-docs/parameter-pages/Debug/LogLevel.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Parameter `LogLevel`
|
||||||
|
Default Value: `1` (`ERROR`)
|
||||||
|
Define the log level for the logging to the SD-Card.
|
||||||
|
|
||||||
|
Available options:
|
||||||
|
|
||||||
|
- `1`: `ERROR`
|
||||||
|
- `2`: `WARNING`
|
||||||
|
- `3`: `INFO`
|
||||||
|
- `4`: `DEBUG`
|
||||||
|
|
||||||
|
As higher the level, as more log messages get written to the SD-Card.
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
`DEBUG` or `INFO` might damage the SD-Card if enabled long term due to excessive writes to the SD-Card!
|
||||||
|
A SD-Card has limited write cycles. Since the device does not do [Wear Leveling](https://en.wikipedia.org/wiki/Wear_leveling), this can wear out your SD-Card!
|
||||||
6
param-docs/parameter-pages/Debug/LogfilesRetention.md
Normal file
6
param-docs/parameter-pages/Debug/LogfilesRetention.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Parameter `LogfilesRetention`
|
||||||
|
Default Value: `3`
|
||||||
|
|
||||||
|
Unit: Days
|
||||||
|
|
||||||
|
Number of days to keep the log files (`0` = forever).
|
||||||
10
param-docs/parameter-pages/Digits/CNNGoodThreshold.md
Normal file
10
param-docs/parameter-pages/Digits/CNNGoodThreshold.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Parameter `CNNGoodThreshold`
|
||||||
|
Default Value: `0.5`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
Threshold above which the classification should be to accept the value (only meaningful for digits).
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is only supported for the `dig-class100` models!
|
||||||
4
param-docs/parameter-pages/Digits/Model.md
Normal file
4
param-docs/parameter-pages/Digits/Model.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Parameter `Model`
|
||||||
|
Default Value: `/config/dig-cont_*.tflite` (See [/config/config.ini](https://github.com/jomjol/AI-on-the-edge-device/blob/master/sd-card/config/config.ini))
|
||||||
|
|
||||||
|
Path to CNN model file for image recognition. See [here](../Choosing-the-Model) for details.
|
||||||
7
param-docs/parameter-pages/Digits/ROIImagesLocation.md
Normal file
7
param-docs/parameter-pages/Digits/ROIImagesLocation.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Parameter `ROIImagesLocation`
|
||||||
|
Default Value: `/log/digit`
|
||||||
|
|
||||||
|
Location to store separated digit images on the SD-Card.
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
A SD-Card has limited write cycles. Since the device does not do [Wear Leveling](https://en.wikipedia.org/wiki/Wear_leveling), this can wear out your SD-Card!
|
||||||
6
param-docs/parameter-pages/Digits/ROIImagesRetention.md
Normal file
6
param-docs/parameter-pages/Digits/ROIImagesRetention.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Parameter `ROIImagesRetention`
|
||||||
|
Default Value: `3`
|
||||||
|
|
||||||
|
Unit: Days
|
||||||
|
|
||||||
|
Days to keep the separated digit images (`0` = forever).
|
||||||
21
param-docs/parameter-pages/GPIO/IO0.md
Normal file
21
param-docs/parameter-pages/GPIO/IO0.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Parameter `IO0`
|
||||||
|
Default Value: `input disabled 10 false false`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
This parameter can be used to configure the GPIO `IO0` pin.
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This pin is only usable with restrictions!
|
||||||
|
It must be disabled when the camera is used.
|
||||||
|
Additionally, it is used to activate Bootloader mode and must therefore be HIGH after a reset!
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- `GPIO 0 state`: One of `input`, `input pullup`, `input pulldown` or `output`.
|
||||||
|
- `GPIO 0 use interrupt`: Enable interrupt trigger
|
||||||
|
- `GPIO 0 PWM duty resolution`: LEDC PWM duty resolution in bit
|
||||||
|
- `GPIO 0 enable MQTT`: Enable MQTT publishing/subscribing
|
||||||
|
- `GPIO 0 enable HTTP`: Enable HTTP write/read
|
||||||
|
- `GPIO 0 name`: MQTT topic name (empty = `GPIO0`). Allowed characters: `a-z, A-Z, 0-9, _, -`.
|
||||||
19
param-docs/parameter-pages/GPIO/IO1.md
Normal file
19
param-docs/parameter-pages/GPIO/IO1.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Parameter `IO1`
|
||||||
|
Default Value: `input disabled 10 false false`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
This parameter can be used to configure the GPIO `IO1` pin.
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This pin is by default used for the serial communication as TX pin (USB logging)!
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- `GPIO 1 state`: One of `input`, `input pullup`, `input pulldown` or `output`.
|
||||||
|
- `GPIO 1 use interrupt`: Enable interrupt trigger
|
||||||
|
- `GPIO 1 PWM duty resolution`: LEDC PWM duty resolution in bit
|
||||||
|
- `GPIO 1 enable MQTT`: Enable MQTT publishing/subscribing
|
||||||
|
- `GPIO 1 enable HTTP`: Enable HTTP write/read
|
||||||
|
- `GPIO 1 name`: MQTT topic name (empty = `GPIO1`). Allowed characters: `a-z, A-Z, 0-9, _, -`.
|
||||||
19
param-docs/parameter-pages/GPIO/IO12.md
Normal file
19
param-docs/parameter-pages/GPIO/IO12.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Parameter `IO12`
|
||||||
|
Default Value: `input-pullup disabled 10 false false`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
This parameter can be used to configure the GPIO `IO12` pin.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
This pin is usable without known restrictions!
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- `GPIO 12 state`: One of `external-flash-ws281x`, `input`, `input pullup`, `input pulldown` or `output`.
|
||||||
|
- `GPIO 12 use interrupt`: Enable interrupt trigger
|
||||||
|
- `GPIO 12 PWM duty resolution`: LEDC PWM duty resolution in bit
|
||||||
|
- `GPIO 12 enable MQTT`: Enable MQTT publishing/subscribing
|
||||||
|
- `GPIO 12 enable HTTP`: Enable HTTP write/read
|
||||||
|
- `GPIO 12 name`: MQTT topic name (empty = `GPIO12`). Allowed characters: `a-z, A-Z, 0-9, _, -`.
|
||||||
19
param-docs/parameter-pages/GPIO/IO13.md
Normal file
19
param-docs/parameter-pages/GPIO/IO13.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Parameter `IO13`
|
||||||
|
Default Value: `input-pullup disabled 10 false false`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
This parameter can be used to configure the GPIO `IO13` pin.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
This pin is usable without known restrictions!
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- `GPIO 13 state`: One of `input`, `input pullup`, `input pulldown` or `output`.
|
||||||
|
- `GPIO 13 use interrupt`: Enable interrupt trigger
|
||||||
|
- `GPIO 13 PWM duty resolution`: LEDC PWM duty resolution in bit
|
||||||
|
- `GPIO 13 enable MQTT`: Enable MQTT publishing/subscribing
|
||||||
|
- `GPIO 13 enable HTTP`: Enable HTTP write/read
|
||||||
|
- `GPIO 13 name`: MQTT topic name (empty = `GPIO13`). Allowed characters: `a-z, A-Z, 0-9, _, -`.
|
||||||
19
param-docs/parameter-pages/GPIO/IO3.md
Normal file
19
param-docs/parameter-pages/GPIO/IO3.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Parameter `IO3`
|
||||||
|
Default Value: `input disabled 10 false false`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
This parameter can be used to configure the GPIO `IO3` pin.
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This pin is by default used for the serial communication as RX pin (USB logging)!
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- `GPIO 3 state`: One of `input`, `input pullup`, `input pulldown` or `output`.
|
||||||
|
- `GPIO 3 use interrupt`: Enable interrupt trigger
|
||||||
|
- `GPIO 3 PWM duty resolution`: LEDC PWM duty resolution in bit
|
||||||
|
- `GPIO 3 enable MQTT`: Enable MQTT publishing/subscribing
|
||||||
|
- `GPIO 3 enable HTTP`: Enable HTTP write/read
|
||||||
|
- `GPIO 3 name`: MQTT topic name (empty = `GPIO3`). Allowed characters: `a-z, A-Z, 0-9, _, -`.
|
||||||
20
param-docs/parameter-pages/GPIO/IO4.md
Normal file
20
param-docs/parameter-pages/GPIO/IO4.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Parameter `IO4`
|
||||||
|
Default Value: `built-in-led disabled 10 false false`
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||||
|
|
||||||
|
This parameter can be used to configure the GPIO `IO4` pin.
|
||||||
|
|
||||||
|
!!! Warning
|
||||||
|
This pin is only usable with restrictions!
|
||||||
|
By default, it is used for build-in flash light (onboard LED).
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
- `GPIO 4 state`: One of `built-in-led`, `input`, `input pullup`, `input pulldown` or `output`.
|
||||||
|
- `GPIO 4 use interrupt`: Enable interrupt trigger
|
||||||
|
- `GPIO 4 PWM duty resolution`: LEDC PWM duty resolution in bit
|
||||||
|
- `GPIO 4 enable MQTT`: Enable MQTT publishing/subscribing
|
||||||
|
- `GPIO 4 enable HTTP`: Enable HTTP write/read
|
||||||
|
- `GPIO 4 name`: MQTT topic name (empty = `GPIO4`). Allowed characters: `a-z, A-Z, 0-9, _, -`.
|
||||||
5
param-docs/parameter-pages/GPIO/LEDColor.md
Normal file
5
param-docs/parameter-pages/GPIO/LEDColor.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Parameter `LEDColor`
|
||||||
|
Default Value: `150 150 150`
|
||||||
|
|
||||||
|
Color of the attached LEDs to GPIO12 in **R**ed, **G**reen **B**lue from `0` (full off) .. `255` (full on)
|
||||||
|
(See `IO12` parameter).
|
||||||
4
param-docs/parameter-pages/GPIO/LEDNumbers.md
Normal file
4
param-docs/parameter-pages/GPIO/LEDNumbers.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Parameter `LEDNumbers`
|
||||||
|
Default Value: `2`
|
||||||
|
|
||||||
|
Number of LEDs on the external LED-stripe attached to GPIO12 (See `IO12` parameter).
|
||||||
3
param-docs/parameter-pages/GPIO/LEDType.md
Normal file
3
param-docs/parameter-pages/GPIO/LEDType.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Parameter `LEDType`
|
||||||
|
Default Value: `WS2812`
|
||||||
|
Type of the `WS2812x` which is connected to GPIO12 (See `IO12` parameter).
|
||||||
8
param-docs/parameter-pages/GPIO/MainTopicMQTT.md
Normal file
8
param-docs/parameter-pages/GPIO/MainTopicMQTT.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Parameter `MainTopicMQTT`
|
||||||
|
Default Value: `wasserzaehler/GPIO`
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
This parameter is not accessible through the Web Interface Configuration Page!
|
||||||
|
|
||||||
|
The GPIO Interface is prepared to report it's status and status changes as a MQTT topic. With this parameter you configure the MQTT main topic, under which the status is published.
|
||||||
|
As this parameter is still experimental it can only be set manually in the `config.ini` itself and has not been tested in detail so far.
|
||||||
7
param-docs/parameter-pages/InfluxDB/Database.md
Normal file
7
param-docs/parameter-pages/InfluxDB/Database.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Parameter `Database`
|
||||||
|
Default Value: `''`
|
||||||
|
|
||||||
|
Name of the InfluxDB v1 Database into which to publish the values.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
See section `InfluxDBv2` for InfluxDB v2 support!
|
||||||
4
param-docs/parameter-pages/InfluxDB/NUMBER.Field.md
Normal file
4
param-docs/parameter-pages/InfluxDB/NUMBER.Field.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Parameter `<NUMBER>.Field`
|
||||||
|
Default Value: `undefined`
|
||||||
|
|
||||||
|
Dedicated definition of the field for InfluxDB use for saving in the Influx database (e.g.: "watermeter/value").
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Parameter `Measurement`
|
||||||
|
Default Value: `undefined`
|
||||||
|
|
||||||
|
Name of the InfluxDB v1 Measurement to use to publish the value.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
See section `InfluxDBv2` for InfluxDB v2 support!
|
||||||
7
param-docs/parameter-pages/InfluxDB/Uri.md
Normal file
7
param-docs/parameter-pages/InfluxDB/Uri.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Parameter `Uri`
|
||||||
|
Default Value: `undefined`
|
||||||
|
|
||||||
|
URI of the HTTP interface to InfluxDB v1, without trailing slash, e.g. `http://192.168.1.1:8086`.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
See section `InfluxDBv2` for InfluxDB v2 support!
|
||||||
7
param-docs/parameter-pages/InfluxDB/password.md
Normal file
7
param-docs/parameter-pages/InfluxDB/password.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Parameter `password`
|
||||||
|
Default Value: `undefined`
|
||||||
|
|
||||||
|
Password for the InfluxDB v1 authentication.
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
See section `InfluxDBv2` for InfluxDB v2 support!
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user