M5 Paper e-ink CalculatorΒΆ
I added an M5 Paper to my collection of dev boards and decided to make a basic calculator to teach my son to count. Since he is only a few months old he mostly uses it as an expensive teething device.
The functionality is as follows:
Has a button to perform addition and add 1 to the current number
Has a button to reset to zero
Displays the number in decimal, binary and hex
Render the total as a dice depiction
Refresh will use fastest refresh type
Every 10th reset will do a full screen refresh to clear ink artefact
Shutdown after 15 minutes
I did notice that the platformio output for the serial monitor was
producing garbage output which was fixed by hard coding the
monitor_speed
in the platformio.ini
file as follows:
[env:m5stack-core2]
platform = espressif32
board = m5stack-core2
framework = arduino
lib_extra_dirs = ~/Documents/Arduino/libraries
lib_deps = m5stack/M5EPD@^0.1.1
monitor_speed = 115200
Sample CodeΒΆ
#include <string>
#include "Free_Fonts.h" // Include the header file attached to this sketch
#include <bitset>
#include<bits/stdc++.h>
using namespace std;
uint counter = 1;
void touchDectector() {
if (M5.TP.avaliable())// check if touch driver is reachable
{
int c = 0;
M5.TP.flush();// reset values
while (M5.TP.getFingerNum() == 0)// while no fingers are detected
{
delay(50);
M5.TP.update();
// Serial.println("waiting...");
c++;
if (c >= 18000)// to go to sleep if nothing has happened after 15 mins-> energy saving
{
c = 0;
Turn_off();
}
}
if (M5.TP.getFingerNum() > 0)// if a finger has been detected
{
c = 0;
while (M5.TP.getFingerNum() == 0) // waiting for input
{
delay(50);
M5.TP.update();
c++;
if (c >= 18000) {
c = 0;
M5.TP.flush();
Turn_off();
}
}
if (M5.TP.getFingerNum() > 0) // when input is received
{
int i;
int b = 15;
tp_finger_t FingerItem = M5.TP.readFinger(i);
point[i][0] = FingerItem.x;
point[i][1] = FingerItem.y;
Serial.print("finger x: ");
Serial.println(FingerItem.x);
Serial.print("finger y: ");
Serial.println(FingerItem.y);
//if reset area pushed
if (FingerItem.y <= 520 && FingerItem.x <= 140) {
counter = 1;
canvas.fillRect(0, 220, 550, 380, 0); //middle
canvas.useFreetypeFont(false);
canvas.setFreeFont(&FreeSansBold9pt7b);
canvas.setTextSize(4);
canvas.drawString("1", 260, 30, GFXFF);
drawDie();
canvas.pushCanvas(0, 0, UPDATE_MODE_DU4);
M5.TP.flush();
} else {
counter++;
}
canvas.useFreetypeFont(false);
canvas.setFreeFont(&FreeSansBold24pt7b);
char res[1000];
itoa(counter, res, 2); //binary
// itoa(a,res,8); //octal
canvas.useFreetypeFont(false);
canvas.setFreeFont(&FreeMono9pt7b);
canvas.setTextSize(2);
canvas.fillRect(25, 125, 500, 100, 0); //top
canvas.drawString(res, 25, 125, GFXFF); //left binary
itoa(counter, res, 16); //hex
canvas.drawString(res, 455, 125, GFXFF); //right hex
String myString = String(counter);
canvas.useFreetypeFont(false);
canvas.setFreeFont(&FreeSansBold24pt7b);
canvas.setTextSize(30);
canvas.fillRect(20, 220, 510, 340, 0); //middle
canvas.drawString(myString, 90, 230, GFXFF);
//dice here
drawDie();
// decide if full refresh
if (counter % 10 == 0) {
canvas.pushCanvas(0, 0, UPDATE_MODE_GC16);
} else {
canvas.pushCanvas(0, 0, UPDATE_MODE_DU4);
}
M5.TP.flush();
}
}
}
}
void drawDie() {
int xoffset = 25;
int yoffset = 530;
int diameter = 10;
int xincrement = diameter * 2.5;
int yincrement = diameter * 2.5;
int currentDie = 1;
int dotsleft = 0;
int diecount = (counter + 6 - 1) / 6; //round to highest like ceil(conter/6)
for (int i = 1; i <= counter; i++) {
if (currentDie >= 2) {
dotsleft = i - ((currentDie - 1) * 6);
} else {
dotsleft = i;
}
switch (dotsleft) {
case 1:
//middle dot
canvas.fillCircle(xoffset + ((xincrement * 2) / 2), yoffset + (yincrement * 2 / 2), diameter, 255);
break;
case 2:
canvas.fillCircle(xoffset, yoffset, diameter, 255); //top left
canvas.fillCircle(xoffset + xincrement * 2, yoffset + yincrement * 2, diameter, 255); //bottom right
canvas.fillCircle(xoffset + ((xincrement * 2) / 2), yoffset + (yincrement * 2 / 2), diameter,
0); //white out middle
break;
case 3:
canvas.fillCircle(xoffset, yoffset, diameter, 255); //top left
canvas.fillCircle(xoffset + xincrement * 2, yoffset + yincrement * 2, diameter, 255); //bottom right
//middle dot
canvas.fillCircle(xoffset + ((xincrement * 2) / 2), yoffset + (yincrement * 2 / 2), diameter, 255);
break;
case 4:
//clear dice here
canvas.fillRect(xoffset, yoffset, diameter * 6, diameter * 6, 0); //cear dice area
canvas.fillCircle(xoffset, yoffset, diameter, 255); //top left
canvas.fillCircle(xoffset + xincrement * 2, yoffset, diameter, 255); //top right
canvas.fillCircle(xoffset, yoffset + yincrement * 2, diameter, 255); //bottom left
canvas.fillCircle(xoffset + xincrement * 2, yoffset + yincrement * 2, diameter, 255); //bottom right
break;
case 5:
canvas.fillRect(xoffset, yoffset, diameter * 6, diameter * 6, 0); //cear dice area
canvas.fillRect(xoffset, yoffset, diameter * 6, diameter * 6, 0); //cear dice area
canvas.fillCircle(xoffset, yoffset, diameter, 255); //top left
canvas.fillCircle(xoffset + xincrement * 2, yoffset, diameter, 255); //top right
canvas.fillCircle(xoffset, yoffset + yincrement * 2, diameter, 255); //bottom left
canvas.fillCircle(xoffset + xincrement * 2, yoffset + yincrement * 2, diameter, 255); //bottom right
canvas.fillCircle(xoffset + ((xincrement * 2) / 2), yoffset + (yincrement * 2 / 2), diameter,
255); //middle
break;
case 6:
canvas.fillRect(xoffset, yoffset, diameter * 6, diameter * 6, 0); //cear dice area
canvas.fillCircle(xoffset, yoffset, diameter, 255); //top left
canvas.fillCircle(xoffset + xincrement * 2, yoffset, diameter, 255); //top right
canvas.fillCircle(xoffset, yoffset + yincrement * 2, diameter, 255); //bottom left
canvas.fillCircle(xoffset + xincrement * 2, yoffset + yincrement * 2, diameter, 255); //bottom right
// canvas.fillCircle(xoffset + ((xincrement*2)/2),yoffset + (yincrement*2/2) ,diameter,255); //middle
canvas.fillCircle(xoffset, yoffset + (yincrement * 2 / 2), diameter, 255); //middle left
canvas.fillCircle(xoffset + xincrement * 2, yoffset + (yincrement * 2 / 2), diameter,
255); //middle right
break;
}
if (i % 6 == 0) {
currentDie++;
xoffset += diameter + (3 * 25);
}
}
}
void mode1() {
canvas.deleteCanvas();
canvas.createCanvas(540, 960);
canvas.setTextSize(22);
canvas.useFreetypeFont(false);
canvas.setFreeFont(&FreeSansBold24pt7b);
canvas.drawString("1", 90, 230, GFXFF);
canvas.setTextSize(8);
canvas.drawString("+1", 75, 655, GFXFF);
canvas.useFreetypeFont(false);
canvas.setFreeFont(&FreeSansBold9pt7b);
canvas.setTextSize(4);
canvas.drawString("1", 260, 30, GFXFF);
drawDie();
canvas.drawRect(20, 15 + (118 * 0), 500, 100, 15); //top
canvas.drawRect(20, 45 + (118 * 5), 500, 300, 15); //bottom
canvas.pushCanvas(0, 0, UPDATE_MODE_GC16);
while (true) {
touchDectector();
delay(250);
}
delay(5000);
Turn_off();
}
Comments
comments powered by Disqus