You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

304 lines
9.5 KiB
Arduino

/*
DYNAMIC GLYPH
keyboard module for text input
// board info: LilyGO TTGO T8 ESP32-S2 - with SD Card Slot
// board select: ESP32S2 DEV Module
current USB port: 142300
Rotary encoder:
Two pins are for the internal push button (D and E);
the other two (A and B) provide rotation signal relative to the third pin (C),
which is normally connected to the ground.
The output pins A and B should be pulled high which can be done using internal pull up resitors of Arduino.
Also note that when the encoder is rotated, then lines A and B are mechanical connected to pin C (ground)
in certain order, which allows to detemine the direction of rotation.
tutorial: https://github.com/igorantolic/ai-esp32-rotary-encoder/blob/master/README.md
(look for: Connecting Rotary Encoder with Switch (no pcb version))
LCD documentation:
https://github.com/DFRobot/DFRobot_RGBLCD1602
to make the LCD work on this ESP32, there need to be some manual changes in this library!
find the file DFRobot_RGBLCD1602.cpp under Dokumente/Arduino/libraries/DFRobot_RGBLCD1602
search for the line "_pWire->begin" and manually define two pins as SDA pin (here: 34) and as SCL pin (here:33) for IC2 connection
GND is a ground pin. Connect it to the ground of the ESP32.
VCC supplies power to the module and LCD. Connect it to the ESP32s VIN pin or an external 5V power supply.
SDA is the I2C data pin. Connect it to the ESP32s I2C data pin.
SCL is the I2C clock pin. Connect it to the ESP32s I2C clock pin.
TO DO:
reread and organize the code and all comments to clean up
special characters dont work? problematic index[70] and above
super slow clean up loop?
LCD
document changes in the library
implement interrupts for all pin so that it doesnt iterate through all code every time butr only if a change is detected
*/
//include libaries
#include "AiEsp32RotaryEncoder.h" //library to use the encoder_value function
#include "DFRobot_RGBLCD1602.h" //include library for LCD display
#include <stdio.h> //include library to access a character in a string by referring to its index number
//declare LCD display
DFRobot_RGBLCD1602 lcd(/*lcdCols*/16,/*lcdRows*/2); //16 characters and 2 lines of show
//library: manually define two pins as SDA pin (here: 34) and as SCL pin (here:33) for IC2 connection (see documentation above)
//rotary encoder
//define pins and steps
#define ROTARY_ENCODER_A_PIN 2 // CLK (Output A) determines the amount of rotation. Each time the knob is turned in either direction, the CLK output goes through one cycle of going HIGH and then LOW.
#define ROTARY_ENCODER_B_PIN 3 // DT (Output B) is similar to CLK output, but it lags behind CLK by a 90° phase shift. This output is used to determine the direction of rotation.
#define ROTARY_ENCODER_BUTTON_PIN 45 // SW is the output of the push button switch (active low). When the knob is depressed, the voltage goes LOW.
#define ROTARY_ENCODER_STEPS 1 //depends on encoder type, may vary between 1 and 4
AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_STEPS);
//define pins:
#define spaceButton 4 //button to submit data to the next module
#define backspaceButton 5 // button to delete the last glyph in text
#define clearButton 0 // button to clear text completely
#define powerDisplay 35 //switch to turn on/off the display
//define variables:
//text:
String glyphs; //declares variable for the array of glyphs
String text; //declares variable for the text
//module in/out data
String input;
String newData;
String output;
String moduleID = "#DG"; //Dynamic Glyphs
int counter = 0; //counter will change each time the knob is rotated one detent (click).
//define function for rotary encoder (will be called):
void IRAM_ATTR readEncoderISR()
{
rotaryEncoder.readEncoder_ISR();
}
void setup() {
// put your setup code here, to run once:
// set mode for digital input to not give floating values, but either 0 or 1:
pinMode(ROTARY_ENCODER_A_PIN, INPUT_PULLUP);
pinMode(ROTARY_ENCODER_B_PIN, INPUT_PULLUP);
pinMode(ROTARY_ENCODER_BUTTON_PIN, INPUT);
pinMode(backspaceButton, INPUT_PULLUP);
pinMode(clearButton, INPUT_PULLUP);
pinMode(spaceButton, INPUT_PULLUP);
pinMode(powerDisplay, INPUT_PULLUP); //on/off toggle switch
// initialize serial and serial1 communication at 115200 and 9600 bits per second:
Serial.begin(115200); //goes to serial monitor, just for debugging purposes
Serial1.begin(9600); // goes to the next module via patch cable (use transmit pin TX on IO17 and also connect to GND)
//Serial1.setTimeout(100); // there is a small bug, so there needs to be a checksum?
rotaryEncoder.begin();
rotaryEncoder.setup(readEncoderISR);
rotaryEncoder.setBoundaries(0, 89, true); //minValue, maxValue, circleValues true|false (when max go to min and vice versa, should be aligned with number of glyphs)
rotaryEncoder.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
//initialize LCD display (+color) and IIC
lcd.init();
lcd.setColorWhite();
//define the array of glyphs
//note: the array starts at 0 and ends at 90. For certain characters such as " and \ a backspace is added
glyphs = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,:;?!-_+%=&#*\"'/|()[]{}^<>@"; //90
text = "";
lcd.setCursor(14,0);
lcd.blink();
}
void loop() {
//rotary encoder:
if (rotaryEncoder.encoderChanged()){
lcd.stopBlink();
counter = rotaryEncoder.readEncoder();
//Serial.println(counter);
// print to serial monitor for debugging purpose:
//Serial.println(rotaryEncoder.readEncoder());
//Serial.println(glyphs[counter]);
lcd.setCursor(14,0);
lcd.print(glyphs[counter]);
}
if (rotaryEncoder.isEncoderButtonClicked()){
text += glyphs[counter];
Serial.println("button was pressed");
int len = text.length();
//Serial.println(len);
if (len <= 12) {
lcd.setCursor(0,0);
lcd.print(text);
}
else {
String textCut = text.substring(len-12);
lcd.setCursor(0,0);
lcd.print(textCut);
Serial.println(textCut);
}
//print to serial monitor for debugging purpose:
//Serial.println("button was pressed, the following letter is added: ");
//Serial.println(text);
//Serial.println(textCut);
}
//powerDisplay: toggle switch display on / off
// read digital input
int powerDisplayValue = digitalRead(powerDisplay);
// redefine range for power:
if(powerDisplayValue == 0) {
lcd.noDisplay();
}
else {
lcd.display();
}
//spaceButton: button to add a space to the text string
// read digital input
int spaceButtonValue = digitalRead(spaceButton);
// if space button is pressed, append space to the text variable:
if(spaceButtonValue == 0) {
text += " ";
int len = text.length();
//Serial.println(len);
if (len <= 12) {
lcd.setCursor(0,0);
lcd.print(text);
}
else {
String textCut = text.substring(len-12);
lcd.setCursor(0,0);
lcd.print(textCut);
Serial.println(textCut);
}
// print to serial monitor for debugging purpose:
//Serial.println("Space Button was pressed. A space was added to the text: ");
//Serial.println(text);
//Serial.println(textCut);
}
//clearButton: button to clear text variable completely
// read digital input
int clearButtonValue = digitalRead(clearButton);
// if clear button is pressed, clear the text variable:
if (clearButtonValue == 0){
text = "";
lcd.setCursor(0,0);
lcd.print(" "); //replace old text on LCD with empty spaces
// print to serial monitor for debugging purpose:
//Serial.println("Clear Button was pressed. The whole text was deleted.");
//Serial.println(text);
//Serial.println(textCut);
}
// backspaceButton: button to delete the last glyph in text
// read digital input
int backspaceButtonValue = digitalRead(backspaceButton);
// if backspace button is pressed, delete the last character from string:
if(backspaceButtonValue == 0) {
int lastIndex = text.length() - 1; //find last character in text string
text.remove(lastIndex); //delete last character in text string
lcd.setCursor(lastIndex,0); //move cursor to the position of the last character
lcd.print(" "); //replace the last character with a space
int len = text.length();
//Serial.println(len);
if (len <= 12) {
lcd.setCursor(0,0);
lcd.print(text);
}
else {
String textCut = text.substring(len-12);
lcd.setCursor(0,0);
lcd.print(textCut);
}
// print to serial monitor for debugging purpose:
//Serial.println("Backspace Button was pressed. The last glyph in text was deleted: ");
//Serial.println(text);
//Serial.println(textCut);
}
Serial.println(text + glyphs[counter]);
//put all values in a string to define the new data from this module:
newData = "&&&" + String(moduleID) + "," + String(text) + "&&&";
//newData = "&&&" + String(moduleID) + "," + "this text was written with DYNAMIC GLYPH" + "&&&";
output = newData;
Serial.println(output);
//Send data to next module (TX):
Serial1.println(output); //the data received + new data
// print to serial monitor for debugging purpose:
// Serial.println("Dynamic Glyph, new data: " + newData);
// Serial.println("This is the output I send: " + output);
}