/**
Benjamin Roll
Spool Splitter Code
2/6/2023
**/
#include <Adafruit_GFX.h> // Core graphics library
#include <SPI.h> // this is needed for display
#include <Adafruit_ILI9341.h>
#include <Wire.h> // this is needed for FT6206
// not for this board #include <Adafruit_FT6206.h>
#include <Stepper.h>
#include <XPT2046_Touchscreen.h>
#include "pitches.h"
const int stepsPerRevolution = 200; // number of steps per revolution
const int tStepsPerRev = 200;
// initialize the stepper library on pins 8 through 11:
Stepper spool(stepsPerRevolution, 27, 29, 31, 33);
Stepper traverse(tStepsPerRev, 26, 28, 30, 32);
long Number; // input desired length of wire
int stepCount = 0; // # of steps for the spool to take
int layerCount = 0; // counter for # of wire layers
int SRCount = 0; //
int tCount = 0; //
long spoolDia = 11;
long ratio = spoolDia/0.5; // drive ratio
long revCount = 0; // # of spool stepper revs
int steps = ratio*stepsPerRevolution; // # of steps for 1 spool rotaion
long tSteps = 18.4; // # of steps traverse needs to move
long wireLength; // desired wire length in inches
long reqRevs; // # of revs to get needed wire length
int X=0;
int Y=0;
int stepperRPM = 200;
int brakeVal = 20;
bool butPress = false;
bool complete = false;
bool result = false;
bool entered = false;
bool startPressed = false;
#define TonePin 13
#define BrakePin 3
// The display/touchscreen also uses hardware SPI, plus CS=53, DC=48, MOSI=51, MISO=50, SCK=52
#define TFT_CS 53
#define TFT_DC 48
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// The XPT2046 uses hardware I2C (SCL/SDA)
#define CS_PIN 22
XPT2046_Touchscreen ts(CS_PIN);
//#define TIRQ_PIN 2
//XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, 255); // Param 2 - 255 - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
#define FRAME_X 80
#define FRAME_Y 180
#define FRAME_W 100
#define FRAME_H 50
#define TS_MINX 365
#define TS_MINY 250
#define TS_MAXX 3850
#define TS_MAXY 3850
String symbol[4][3] = {
{ "7", "8", "9"},
{ "4", "5", "6",},
{ "1", "2", "3",},
{ "C", "0", "GO", }
};
int melody[] = {
NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 8, 8, 4, 4, 4, 4, 4
};
void setup(void) {
//while (!Serial); // used for leonardo debugging
pinMode(BrakePin, OUTPUT);
/* pinMode(5, OUTPUT);
digitalWrite(5, HIGH);
pinMode(6, OUTPUT);
digitalWrite(6, HIGH);
pinMode(7, OUTPUT);
digitalWrite(7, HIGH);
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);
pinMode(37, OUTPUT);
digitalWrite(37, HIGH);
pinMode(35, OUTPUT);
digitalWrite(35, HIGH);
pinMode(33, OUTPUT);
digitalWrite(33, HIGH);
pinMode(31, OUTPUT);
digitalWrite(31, HIGH);*/
spool.setSpeed(stepperRPM);
Serial.begin(38400);
Serial.println(F("Cap Touch Paint!"));
tft.begin();
ts.begin();
tft.setRotation(0);
ts.setRotation(2);
tft.fillScreen(ILI9341_BLACK);
// Draw Start Button
tft.fillRect(FRAME_X, FRAME_Y, FRAME_W, FRAME_H, ILI9341_GREEN);
tft.setCursor(FRAME_X + 6 , FRAME_Y + (FRAME_H/2));
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(3);
tft.println("START");
//Write PWM to brake pin
analogWrite(BrakePin, brakeVal);
}
void loop() {
while (complete==false){
// Wait for a touch
if (! ts.touched() && result==false) {
return;
}
// Retrieve a point
delay (200);
TS_Point p = ts.getPoint();
/*
// Print out raw data from screen touch controller
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y);
Serial.print(" -> ");
*/
// flip it around to match the screen.
p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
X=p.x;
Y=p.y;
// Print out the remapped (rotated) coordinates
Serial.print("("); Serial.print(p.x);
Serial.print(", "); Serial.print(p.y);
Serial.println(")");
if (startPressed == false){
if ((p.y < (FRAME_Y + FRAME_H)) && (p.y > FRAME_Y)) {
if ((p.x > FRAME_X) && (p.x < (FRAME_X + FRAME_W))){
butPress = true;
startPressed = true;
}
}
}
if(butPress == true){
drawInput();
butPress = false;
return;
}
if(result == false && startPressed==true){
DetectButtons();
DisplayResult();
return;
}
if(result==true){
sSplit();
return;
}
}
splitComplete();
}
// Draw the input screen
void drawInput(){
tft.fillScreen(ILI9341_BLACK);
//Draw the Result Box
tft.fillRect(0, 0, 240, 70, ILI9341_CYAN);
//Draw First Column
tft.fillRect (0,260,80,65,ILI9341_RED);
tft.fillRect (0,200,80,65,ILI9341_BLACK);
tft.fillRect (0,140,80,65,ILI9341_BLACK);
tft.fillRect (0,80,80,65,ILI9341_BLACK);
//Draw Second Column
tft.fillRect (80,260,80,65,ILI9341_BLACK);
tft.fillRect (80,200,80,65,ILI9341_BLACK);
tft.fillRect (80,140,80,65,ILI9341_BLACK);
tft.fillRect (80,80,80,65,ILI9341_BLACK);
//Draw Third Column
tft.fillRect (160,260,80,65,ILI9341_GREEN);
tft.fillRect (160,200,80,65,ILI9341_BLACK);
tft.fillRect (160,140,80,65,ILI9341_BLACK);
tft.fillRect (160,80,80,65,ILI9341_BLACK);
//Draw Horizontal Lines
for (int h=70; h<=320; h+=65)
tft.drawFastHLine(0, h, 240, ILI9341_WHITE);
//Draw Vertical Lines
for (int v=0; v<=240; v+=80)
tft.drawFastVLine(v, 80, 240, ILI9341_WHITE);
//Display keypad lables
for (int j=0;j<4;j++) {
for (int i=0;i<3;i++) {
tft.setCursor(22 + (80*i), 100 + (65*j));
tft.setTextSize(3);
tft.setTextColor(ILI9341_WHITE);
tft.println(symbol[j][i]);
}
}
butPress = false;
return butPress;
}
void DetectButtons(){
//Detecting Buttons on Column 1
if (X<80 && X>0) {
if (Y>255 && Y<320) //If cancel Button is pressed
{
Serial.println ("Button Cancel");
Number=0;
result=false;
Serial.println (Number);
}
if (Y>190 && Y<255) //If Button 1 is pressed
{
Serial.println ("Button 1");
if (Number==0)
Number=1;
else
Number = (Number*10) + 1; //Pressed twice
Serial.println (Number);
}
if (Y>125 && Y<190) //If Button 4 is pressed
{
Serial.println ("Button 4");
if (Number==0)
Number=4;
else
Number = (Number*10) + 4; //Pressed twice
Serial.println (Number);
}
if (Y>60 && Y<125) //If Button 7 is pressed
{
Serial.println ("Button 7");
if (Number==0)
Number=7;
else
Number = (Number*10) + 7; //Pressed twice
Serial.println (Number);
}
}
//Detecting Buttons on Column 2
if (X<160 && X>80) {
if (Y>255 && Y<320)
{
Serial.println ("Button 0"); //Button 0 is Pressed
if (Number==0)
Number=0;
else
Number = (Number*10) + 0; //Pressed twice
Serial.println (Number);
}
if (Y>190 && Y<255)
{
Serial.println ("Button 2");
if (Number==0)
Number=2;
else
Number = (Number*10) + 2; //Pressed twice
Serial.println (Number);
}
if (Y>125 && Y<190)
{
Serial.println ("Button 5");
if (Number==0)
Number=5;
else
Number = (Number*10) + 5; //Pressed twice
Serial.println (Number);
}
if (Y>60 && Y<125)
{
Serial.println ("Button 8");
if (Number==0)
Number=8;
else
Number = (Number*10) + 8; //Pressed twic
Serial.println (Number);
}
}
//Detecting Buttons on Column 3
if (X<240 && X>160) {
if (Y>255 && Y<320)
{Serial.println ("Button Equal");
Number=Number;
tone(13,NOTE_A3,1000/2);
result = true;
Serial.println (Number);
}
if (Y>190 && Y<255)
{Serial.println ("Button 3");
if (Number==0)
Number=3;
else
Number = (Number*10) + 3; //Pressed twice
Serial.println (Number);
}
if (Y>125 && Y<190)
{Serial.println ("Button 6");
if (Number==0)
Number=6;
else
Number = (Number*10) + 6; //Pressed twice
Serial.println (Number);
}
if (Y>60 && Y<125)
{Serial.println ("Button 9");
if (Number==0)
Number=9;
else
Number = (Number*10) + 9; //Pressed twice
Serial.println (Number);
}
return result;
}
}
void DisplayResult(){
tft.fillRect(0, 0, 240, 80, ILI9341_CYAN); //clear result box
tft.setCursor(10, 20);
tft.setTextSize(4);
tft.setTextColor(ILI9341_BLACK);
tft.println(Number); //update new value
}
//Spool split script
void sSplit(){
wireLength = Number*12;
reqRevs = wireLength/(2*PI*(spoolDia/2));
Serial.print("number:");
Serial.println(Number);
Serial.print("wire length:");
Serial.println(wireLength);
Serial.print("Required Revs:");
Serial.println(reqRevs);
if(revCount < reqRevs){
// step one step:
spool.step(steps);
Serial.print("spoolRev:");
Serial.println(SRCount);
SRCount++;
revCount++;
traverse.step(tSteps);
Serial.print("steps:");
Serial.println(tCount);
tCount++;
if (SRCount > 10){
layerCount++;
SRCount = 0;
tSteps = -tSteps;
}
}else{
Serial.print("COMPLETE");
complete = true;
return complete;
}
}
void splitComplete(){
tft.fillScreen(ILI9341_BLACK);
// Draw Start Button
tft.setCursor(20 , 160);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(4);
tft.println("COMPLETE!");
//delay(500);
playSong();
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(TonePin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(TonePin);
}
return;
}
void playSong(){
int size = sizeof(noteDurations) / sizeof(int);
for (int thisNote = 0; thisNote < size; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(TonePin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(TonePin);
}
}