diff --git a/exampleProjects/touch/.gitignore b/exampleProjects/touch/.gitignore new file mode 100644 index 0000000..338de3b --- /dev/null +++ b/exampleProjects/touch/.gitignore @@ -0,0 +1,8 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch + +.venv/ +boost_1_86_0/ diff --git a/exampleProjects/touch/README.md b/exampleProjects/touch/README.md new file mode 100644 index 0000000..f481bd8 --- /dev/null +++ b/exampleProjects/touch/README.md @@ -0,0 +1,18 @@ +# Mac instructions to instal python dependencies after cloning +- `python3 -m venv .venv` (`py -m venv .venv` on win) to create the `.venv` folder (this can take a while) +- `source .venv/bin/activate` to activate the `venv` + - or potentially `source .venv/Scripts/activate` on windoze + - after this, `where python3` (`where python` on win) should return a python inside the `.venv` folder +- `python3 -m pip install --upgrade pip` +- `python3 -m pip install -r requirements.txt` +- to deactivate the venv: `deactivate` + +# Windows instructions to instal python dependencies after cloning +- `python -m venv .venv` to create the `.venv` folder (this can take a while) +- `source .venv/Scripts/activate` to activate the `venv` + - after this, `where python` should return a path inside the `.venv` folder +- `python -m pip install --upgrade pip` +- `python -m pip install -r requirements.txt` +- to deactivate the venv: `deactivate` + +After doing either of the above, VSCode should "just work" ™️ \ No newline at end of file diff --git a/exampleProjects/touch/diagram.json b/exampleProjects/touch/diagram.json new file mode 100644 index 0000000..ec7beb4 --- /dev/null +++ b/exampleProjects/touch/diagram.json @@ -0,0 +1,31 @@ +{ + "version": 1, + "author": "Vincent Berthiaume", + "editor": "wokwi", + "parts": [ + { "type": "wokwi-tinypico", "id": "esp", "top": -0.7, "left": 81.4, "attrs": {} }, + { + "type": "board-ili9341-cap-touch", + "id": "lcd1", + "top": -143.24, + "left": -230.78, + "attrs": {} + } + ], + "connections": [ + [ "esp:TX0", "$serialMonitor:RX", "", [] ], + [ "esp:RX0", "$serialMonitor:TX", "", [] ], + [ "lcd1:GND", "esp:GND.1", "black", [ "v67.2", "h240", "v-105.4" ] ], + [ "esp:3V3", "lcd1:VCC", "red", [ "h-38.4", "v134.1", "h-240" ] ], + [ "lcd1:LED", "esp:3V3", "red", [ "v28.8", "h76.8", "v-86.4", "h134.4" ] ], + [ "lcd1:CS", "esp:14", "orange", [ "v57.6", "h211.2", "v-133.8" ] ], + [ "lcd1:RST", "esp:15", "gold", [ "v48", "h192", "v-124.8" ] ], + [ "lcd1:D/C", "esp:27", "green", [ "v19.2", "h172.8", "v-114.9" ] ], + [ "lcd1:MOSI", "esp:23", "green", [ "v38.4", "h288" ] ], + [ "lcd1:MISO", "esp:19", "green", [ "v105.6", "h278.4", "v-153.6" ] ], + [ "lcd1:SCK", "esp:18", "green", [ "v86.4", "h307.2", "v9.6" ] ], + [ "lcd1:SDA", "esp:25", "violet", [ "v9.6", "h96", "v-124.8" ] ], + [ "lcd1:SCL", "esp:26", "green", [ "v28.8", "h115.2", "v-134.4" ] ] + ], + "dependencies": {} +} \ No newline at end of file diff --git a/exampleProjects/touch/include/README b/exampleProjects/touch/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/exampleProjects/touch/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/exampleProjects/touch/lib/README b/exampleProjects/touch/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/exampleProjects/touch/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/exampleProjects/touch/platformio.ini b/exampleProjects/touch/platformio.ini new file mode 100644 index 0000000..9c354f2 --- /dev/null +++ b/exampleProjects/touch/platformio.ini @@ -0,0 +1,33 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:tinypico] +platform = espressif32 +board = tinypico +framework = arduino +lib_deps = + tinypico/TinyPICO Helper Library + adafruit/Adafruit GFX Library + adafruit/Adafruit ILI9341 + adafruit/Adafruit FT6206 Library +build_flags = + -I../../include/ + -I../../3rdparty/ + ; TODO: currently this is copy pasted right in the repo -- how should we deal with this? + -Iboost_1_86_0/ + -std=gnu++2a + -O0 +build_unflags = + -std=gnu++11 + -std=gnu++14 + -std=gnu++17 + -Os +; enable this to debug wokwi in vscode, see https://docs.wokwi.com/vscode/debugging +; build_type = debug diff --git a/exampleProjects/touch/src/main.cpp b/exampleProjects/touch/src/main.cpp new file mode 100644 index 0000000..8f3ea2e --- /dev/null +++ b/exampleProjects/touch/src/main.cpp @@ -0,0 +1,127 @@ +//======================== setup pins ======================= +constexpr int TFT_CS { 14 }; +constexpr int TFT_DC { 27 }; +constexpr int pico_SDA { 25 }; +constexpr int pico_SCL { 26 }; + +//========================= setup screen ======================= +#include // Core graphics library +#include // Hardware-specific library for ST7789 +#include +#include + +Adafruit_ILI9341 tft { TFT_CS, TFT_DC }; +Adafruit_FT6206 ctp; + +constexpr int RECT_COUNT = 16; +int SCREEN_HEIGHT = -1; +int SCREEN_WIDTH = -1; +int RECT_HEIGHT = -1; + +//======================== setup puara-gestures ======================= +#include +puara_gestures::Touch touch; +int discrete_touch[RECT_COUNT] = { 0 }; + +//======================== main code ======================= +void setup (void) +{ + Serial.begin (9600); + Serial.println (F ("Touch Puara Gesture Test!")); + + Wire.setPins (pico_SDA, pico_SCL); + Wire.begin(); + + tft.begin(); + SCREEN_HEIGHT = tft.height(); + Serial.println (F ("Screen is Initialized")); + SCREEN_WIDTH = tft.width(); + RECT_HEIGHT = SCREEN_HEIGHT / RECT_COUNT; + + Serial.println (F ("Touchscreen is initialized")); + + // pass in 'sensitivity' coefficient + if (! ctp.begin (40)) + { + Serial.println ("Couldn't start touchscreen controller"); + while (1) + ; + } + Serial.println ("touchscreen started"); + + // Display introductory text + tft.fillScreen (ILI9341_BLACK); + tft.setTextColor (ILI9341_WHITE); + tft.setTextSize (2); + tft.setCursor (10, 100); + tft.println ("Puara Gesture Test!"); + tft.setTextSize (1); + tft.setCursor (10, 130); + tft.println ("Touch the screen to begin."); + + // Wait for a touch before proceeding + while (! ctp.touched()) + delay (50); + + // Draw rectangles + tft.fillScreen (ILI9341_BLACK); + for (int i = 0; i < RECT_COUNT; i++) + tft.drawRect (0, i * RECT_HEIGHT, SCREEN_WIDTH, RECT_HEIGHT, ILI9341_WHITE); +} + +void updateAndPrintTouch() +{ + static float prev_touchAll = -1.0f; // Initialize with an invalid value + static float prev_brush = -1.0f; + static float prev_rub = -1.0f; + + touch.updateTouchArray (discrete_touch, RECT_COUNT); + if (touch.brush != prev_brush || touch.rub != prev_rub) + { + Serial.println ("brush;" + String (touch.brush, 6) + ";rub;" + String (touch.rub, 6)); + prev_brush = touch.brush; + prev_rub = touch.rub; + } +} + +void loop() +{ + static int prev_touch[RECT_COUNT] = { 0 }; // Keep track of previous touch states + + // Reset the current touch array + std::fill (discrete_touch, discrete_touch + RECT_COUNT, 0); + + // Check for touches + if (ctp.touched()) + { + TS_Point p { ctp.getPoint() }; + p.x = map (p.x, 0, 240, 240, 0); + p.y = map (p.y, 0, 320, 320, 0); + + // Determine which rectangle is touched + const int rectIndex { p.y / RECT_HEIGHT }; + if (rectIndex >= 0 && rectIndex < RECT_COUNT) + discrete_touch[rectIndex] = 1; + } + + // Update the screen based on touch states + for (int i = 0; i < RECT_COUNT; i++) + { + if (discrete_touch[i] == 1 && prev_touch[i] == 0) + { + // Rectangle is touched - make it white + tft.fillRect (0, i * RECT_HEIGHT, SCREEN_WIDTH, RECT_HEIGHT, ILI9341_WHITE); + } + else if (discrete_touch[i] == 0 && prev_touch[i] == 1) + { + // Rectangle no longer touched - make it black + tft.fillRect (0, i * RECT_HEIGHT, SCREEN_WIDTH, RECT_HEIGHT, ILI9341_BLACK); + tft.drawRect (0, i * RECT_HEIGHT, SCREEN_WIDTH, RECT_HEIGHT, ILI9341_WHITE); + } + } + + // Update previous touch state + std::copy (discrete_touch, discrete_touch + RECT_COUNT, prev_touch); + + updateAndPrintTouch(); +} diff --git a/exampleProjects/touch/test/README b/exampleProjects/touch/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/exampleProjects/touch/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/exampleProjects/touch/wokwi.toml b/exampleProjects/touch/wokwi.toml new file mode 100644 index 0000000..58ebe52 --- /dev/null +++ b/exampleProjects/touch/wokwi.toml @@ -0,0 +1,5 @@ +[wokwi] +version = 1 +elf = ".pio/build/tinypico/firmware.elf" +firmware = ".pio/build/tinypico/firmware.bin" +gdbServerPort = 3333