|
| 1 | +#include <Arduino.h> |
| 2 | +#include <TFT_eSPI.h> |
| 3 | +// Pin Description for this screen: |
| 4 | +// https://www.arthurwiz.com/software-development/177-inch-tft-lcd-display-with-st7735s-on-arduino-mega-2560 |
| 5 | +// GND - GND |
| 6 | +// VCC - 3.3v |
| 7 | +// SCK - TFT_SCLK 5 |
| 8 | +// SDA - TFT_MOSI 18 |
| 9 | +// RES - TFT_RST 22 |
| 10 | +// RS - TFT_DC 21 |
| 11 | +// CS - TFT_CS 19 |
| 12 | +// LEDA- 3.3v |
| 13 | +#include <menu.h> |
| 14 | +#include <menuIO/TFT_eSPIOut.h> |
| 15 | +#include <streamFlow.h> |
| 16 | +#include <ClickEncoder.h> |
| 17 | +// Using this library: https://github.com/soligen2010/encoder.git |
| 18 | +#include <menuIO/clickEncoderIn.h> |
| 19 | +#include <menuIO/keyIn.h> |
| 20 | +#include <menuIO/chainStream.h> |
| 21 | +#include <menuIO/serialIO.h> |
| 22 | +// For debugging the TFT_eSPIOut.h library |
| 23 | +#include <menuIO/serialOut.h> |
| 24 | +#include <menuIO/serialIn.h> |
| 25 | + |
| 26 | +using namespace Menu; |
| 27 | + |
| 28 | +// Declare pins for rotary encoder |
| 29 | +#define encA 4 |
| 30 | +#define encB 15 |
| 31 | +#define encBtn 2 |
| 32 | +#define encSteps 4 |
| 33 | + |
| 34 | +// Setup TFT colors. Probably stop using these and use the colors defined by ArduinoMenu |
| 35 | +#define BACKCOLOR TFT_BLACK |
| 36 | +#define TEXTCOLOR TFT_WHITE |
| 37 | + |
| 38 | +int chooseField = 1; |
| 39 | +int cutsMade = 0; |
| 40 | +int numberOfCuts = 5; |
| 41 | +int lengthOfCuts = 50; // Length in mm |
| 42 | +int feedLength = 304; |
| 43 | +int exitMenuOptions = 0; //Forces the menu to exit and cut the copper tape |
| 44 | + |
| 45 | +// Declare the clickencoder |
| 46 | +// Disable doubleclicks in setup makes the response faster. See: https://github.com/soligen2010/encoder/issues/6 |
| 47 | +ClickEncoder clickEncoder = ClickEncoder(encA, encB, encBtn, encSteps); |
| 48 | +ClickEncoderStream encStream(clickEncoder, 1); |
| 49 | + |
| 50 | +// TFT gfx is what the ArduinoMenu TFT_eSPIOut.h is expecting |
| 51 | +TFT_eSPI gfx = TFT_eSPI(); |
| 52 | + |
| 53 | +void feedInOut(); // Function to manually feed the tape without cutting |
| 54 | +void runCuts(); // Main loop that feeds tape and calls servoCuts() |
| 55 | +void IRAM_ATTR onTimer(); // Start the timer to read the clickEncoder every 1 ms |
| 56 | + |
| 57 | +////////////////////////////////////////////////////////// |
| 58 | +// Start ArduinoMenu |
| 59 | +////////////////////////////////////////////////////////// |
| 60 | + |
| 61 | +result doFeed() |
| 62 | +{ |
| 63 | + delay(500); |
| 64 | + exitMenuOptions = 2; |
| 65 | + return proceed; |
| 66 | +} |
| 67 | + |
| 68 | +result doRunCuts() |
| 69 | +{ |
| 70 | + delay(500); |
| 71 | + exitMenuOptions = 1; |
| 72 | + return proceed; |
| 73 | +} |
| 74 | + |
| 75 | +result updateEEPROM() |
| 76 | +{ |
| 77 | + // writeEEPROM(); |
| 78 | + return quit; |
| 79 | +} |
| 80 | + |
| 81 | +#define MAX_DEPTH 3 |
| 82 | + |
| 83 | +MENU(subMenuAdjustServo, "Adjust Servo Settings", doNothing, noEvent, noStyle |
| 84 | + // ,FIELD(settingsEEPROM.servoOpen, "Servo Open", " degrees", 0, 180, 10, 1, doNothing, noEvent, noStyle) |
| 85 | + // ,FIELD(settingsEEPROM.servoClosed, "Servo Closed", " degrees", 0, 180, 10, 1, doNothing, noEvent, noStyle) |
| 86 | + // ,SUBMENU(subMenu) |
| 87 | + , |
| 88 | + OP("Run!", doFeed, enterEvent), EXIT("<Back")); |
| 89 | + |
| 90 | +CHOOSE(chooseField, feedDirChoose, "Choose Direction:", doNothing, noEvent, noStyle, VALUE("Forward", 1, doNothing, noEvent), VALUE("Backwards", 0, doNothing, noEvent)); |
| 91 | + |
| 92 | +MENU(subMenuFeedInOut, "Feed Tape", doNothing, noEvent, noStyle, FIELD(feedLength, "Length of Feed:", "mm", 0, 1000, 10, 1, doNothing, noEvent, noStyle), SUBMENU(feedDirChoose), OP("Run!", doFeed, enterEvent), EXIT("<Back")); |
| 93 | + |
| 94 | +MENU(mainMenu, "COPPER TAPE CUTTER", doNothing, noEvent, wrapStyle, FIELD(lengthOfCuts, "Cut Size:", "mm", 0, 2000, 10, 1, doNothing, noEvent, noStyle), FIELD(numberOfCuts, "Pieces:", "", 0, 1000, 10, 1, doNothing, noEvent, noStyle), OP("Cut!", doRunCuts, enterEvent), SUBMENU(subMenuFeedInOut), SUBMENU(subMenuAdjustServo)); |
| 95 | + |
| 96 | +// define menu colors -------------------------------------------------------- |
| 97 | +#define Black RGB565(0,0,0) |
| 98 | +#define Red RGB565(255,0,0) |
| 99 | +#define Green RGB565(0,255,0) |
| 100 | +#define Blue RGB565(0,0,255) |
| 101 | +#define Gray RGB565(128,128,128) |
| 102 | +#define LighterRed RGB565(255,150,150) |
| 103 | +#define LighterGreen RGB565(150,255,150) |
| 104 | +#define LighterBlue RGB565(150,150,255) |
| 105 | +#define LighterGray RGB565(211,211,211) |
| 106 | +#define DarkerRed RGB565(150,0,0) |
| 107 | +#define DarkerGreen RGB565(0,150,0) |
| 108 | +#define DarkerBlue RGB565(0,0,150) |
| 109 | +#define Cyan RGB565(0,255,255) |
| 110 | +#define Magenta RGB565(255,0,255) |
| 111 | +#define Yellow RGB565(255,255,0) |
| 112 | +#define White RGB565(255,255,255) |
| 113 | +#define DarkerOrange RGB565(255,140,0) |
| 114 | + |
| 115 | +// TFT color table |
| 116 | +const colorDef<uint16_t> colors[] MEMMODE = { |
| 117 | + //{{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}} |
| 118 | + {{(uint16_t)Black, (uint16_t)Black}, {(uint16_t)Black, (uint16_t)Red, (uint16_t)Red}}, //bgColor |
| 119 | + {{(uint16_t)White, (uint16_t)White}, {(uint16_t)White, (uint16_t)White, (uint16_t)White}},//fgColor |
| 120 | + {{(uint16_t)Red, (uint16_t)Red}, {(uint16_t)Yellow, (uint16_t)Yellow, (uint16_t)Yellow}}, //valColor |
| 121 | + {{(uint16_t)White, (uint16_t)White}, {(uint16_t)White, (uint16_t)White, (uint16_t)White}}, //unitColor |
| 122 | + {{(uint16_t)White, (uint16_t)Gray}, {(uint16_t)Black, (uint16_t)Red, (uint16_t)White}}, //cursorColor |
| 123 | + {{(uint16_t)White, (uint16_t)Yellow}, {(uint16_t)Black, (uint16_t)Red, (uint16_t)Red}}, //titleColor |
| 124 | +}; |
| 125 | + |
| 126 | + |
| 127 | +// Define the width and height of the TFT and how much of it to take up |
| 128 | +#define GFX_WIDTH 160 |
| 129 | +#define GFX_HEIGHT 128 |
| 130 | +#define fontW 6 |
| 131 | +#define fontH 9 |
| 132 | + |
| 133 | +constMEM panel panels[] MEMMODE = {{0, 0, GFX_WIDTH / fontW, GFX_HEIGHT / fontH}}; // Main menu panel |
| 134 | +navNode* nodes[sizeof(panels) / sizeof(panel)]; //navNodes to store navigation status |
| 135 | +panelsList pList(panels, nodes, sizeof(panels) / sizeof(panel)); //a list of panels and nodes |
| 136 | +//idx_t tops[MAX_DEPTH]={0,0}; // store cursor positions for each level |
| 137 | +idx_t eSpiTops[MAX_DEPTH] = {0}; |
| 138 | +TFT_eSPIOut eSpiOut(gfx, colors, eSpiTops, pList, fontW, fontH + 1); |
| 139 | +idx_t serialTops[MAX_DEPTH] = {0}; |
| 140 | +serialOut outSerial(Serial, serialTops); |
| 141 | +menuOut *constMEM outputs[] MEMMODE = {&outSerial, &eSpiOut}; //list of output devices |
| 142 | +outputsList out(outputs, sizeof(outputs) / sizeof(menuOut *)); //outputs list |
| 143 | +serialIn serial(Serial); |
| 144 | +MENU_INPUTS(in, &encStream, &serial); // &encButton, |
| 145 | +NAVROOT(nav, mainMenu, MAX_DEPTH, in, out); |
| 146 | + |
| 147 | +// ESP32 timer thanks to: http://www.iotsharing.com/2017/06/how-to-use-interrupt-timer-in-arduino-esp32.html |
| 148 | +// and: https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/ |
| 149 | +hw_timer_t *timer = NULL; |
| 150 | +portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; |
| 151 | + |
| 152 | +////////////////////////////////////////////////////////// |
| 153 | +// End Arduino Menu |
| 154 | +////////////////////////////////////////////////////////// |
| 155 | + |
| 156 | +void setup() |
| 157 | +{ |
| 158 | + Serial.begin(115200); |
| 159 | + delay(3000); |
| 160 | + |
| 161 | + clickEncoder.setAccelerationEnabled(true); |
| 162 | + clickEncoder.setDoubleClickEnabled(false); // Disable doubleclicks makes the response faster. See: https://github.com/soligen2010/encoder/issues/6 |
| 163 | + |
| 164 | + // // ESP32 timer |
| 165 | + timer = timerBegin(0, 80, true); |
| 166 | + timerAttachInterrupt(timer, &onTimer, true); |
| 167 | + timerAlarmWrite(timer, 1000, true); |
| 168 | + timerAlarmEnable(timer); |
| 169 | + |
| 170 | + // Use this initializer if you're using a 1.8" TFT |
| 171 | + // SPI.begin(); |
| 172 | + gfx.init(); // Initialize a ST7735S chip |
| 173 | + gfx.setRotation(0); // Set the rotation (0-3) to vertical |
| 174 | + Serial.println("Initialized ST7735S TFT"); |
| 175 | + gfx.fillScreen(TFT_BLACK); |
| 176 | + Serial.println("done"); |
| 177 | + |
| 178 | + |
| 179 | + nav.showTitle = true; // Show titles in the menus and submenus |
| 180 | + // nav.timeOut = 60; // Timeout after 60 seconds of inactivity |
| 181 | + // nav.idleOn(); // Start with the main screen and not the menu |
| 182 | +} |
| 183 | + |
| 184 | +void loop() |
| 185 | +{ |
| 186 | + // Slow down the menu redraw rate |
| 187 | + constexpr int menuFPS = 1000 / 30; |
| 188 | + static unsigned long lastMenuFrame = -menuFPS; |
| 189 | + unsigned long now = millis(); |
| 190 | + //... other stuff on loop, will keep executing |
| 191 | + switch (exitMenuOptions) |
| 192 | + { |
| 193 | + case 1: |
| 194 | + { |
| 195 | + delay(500); // Pause to allow the button to come up |
| 196 | + runCuts(); |
| 197 | + break; |
| 198 | + } |
| 199 | + case 2: |
| 200 | + { |
| 201 | + delay(500); // Pause to allow the button to come up |
| 202 | + feedInOut(); |
| 203 | + break; |
| 204 | + } |
| 205 | + default: // Do the normal program functions with ArduinoMenu |
| 206 | + if (now - lastMenuFrame >= menuFPS) |
| 207 | + { |
| 208 | + lastMenuFrame = millis(); |
| 209 | + nav.poll(); // Poll the input devices |
| 210 | + } |
| 211 | + } |
| 212 | +} |
| 213 | + |
| 214 | +void runCuts() |
| 215 | +{ |
| 216 | + exitMenuOptions = 0; // Return to the menu |
| 217 | + delay(500); |
| 218 | + mainMenu.dirty = true; // Force the main menu to redraw itself |
| 219 | +} |
| 220 | + |
| 221 | +void feedInOut() |
| 222 | +{ |
| 223 | + exitMenuOptions = 0; // Return to the menu |
| 224 | + delay(500); |
| 225 | + mainMenu.dirty = true; // Force the main menu to redraw itself |
| 226 | +} |
| 227 | + |
| 228 | +// ESP32 timer |
| 229 | +void IRAM_ATTR onTimer() |
| 230 | +{ |
| 231 | + clickEncoder.service(); |
| 232 | +} |
0 commit comments