Skip to content

Instantly share code, notes, and snippets.

@theterg
Last active December 19, 2015 19:18
Show Gist options
  • Save theterg/6004669 to your computer and use it in GitHub Desktop.
Save theterg/6004669 to your computer and use it in GitHub Desktop.
#include <Servo.h>
#include <stdint.h>
#include <TouchScreen.h>
#include <TFT.h>
//16-bit colors, not quite HTML codes even though they look like it... It's a pain:
//http://en.wikipedia.org/wiki/High_color#16-bit_high_color
#define SAMSUNG_BLUE 0x1111
#define SAMSUNG_CYAN 0x0d3c
#define SAMSUNG_GREY 0xbdd7
#define SAMSUNG_GREY2 0xa514
//The number of frames in a vine, supposedly.
#define MAX_FRAMES 180
//Variables used for the touch screen
static unsigned int TS_MINX, TS_MAXX, TS_MINY, TS_MAXY;
static unsigned int MapX1, MapX2, MapY1, MapY2;
//init TouchScreen port pins. This would be reinitialized in setup() based on the hardware detected.
TouchScreen ts = TouchScreen(17, A2, A1, 14, 300);
//Program global variables:
static char buff[31];
static unsigned char progress = 0;
static unsigned char frames_to_record = 1;
static unsigned int travel = 200;
static unsigned char travel_locked = 1;
Servo servo;
void setup(void)
{
servo.attach(18); //Pin A4
servo.write(80);
Tft.init();//init TFT
initTouchScreenParameters();
Tft.fillRectangle(1,1,240,30,SAMSUNG_BLUE);
Tft.drawString("Kneeon Viner",24,7,2,WHITE);
//**********************************************
renderProgress();
//**********************************************
renderFrameCount(0);
//**********************************************
renderTravelAdj(0);
//*********************************************
Tft.fillRectangle(1,181,240,170,SAMSUNG_GREY);
Tft.drawString("GO!",72,234,4,BLACK);
}
//re-display the current progress bar (everything from 30 to 120 pixels in height)
void renderProgress() {
memset(buff, '\0', sizeof(buff));
sprintf(buff, "%d/%d", progress, MAX_FRAMES);
Tft.fillRectangle(1,31,240,90,SAMSUNG_GREY);
Tft.drawString("Progress:",1,37,2,BLACK);
Tft.drawString(buff,1,67,4,BLACK);
}
//re-display the frame multiplier adjustment (everything from 120 to 150 pixels in height)
//if diff is not 0, the current frame multiplier will be adjusted by that much before displaying
void renderFrameCount(int diff) {
frames_to_record += diff;
if (frames_to_record == 255) {
frames_to_record = 0;
} else if (frames_to_record > 99) {
frames_to_record = 99;
}
memset(buff, '\0', sizeof(buff));
if (frames_to_record < 9){
sprintf(buff, "DN %d frame UP", frames_to_record);
} else {
sprintf(buff, "DN %d frame UP", frames_to_record);
}
Tft.fillRectangle(1, 121,240,30,SAMSUNG_GREY2);
Tft.fillRectangle(1, 121,34, 30,SAMSUNG_CYAN);
Tft.fillRectangle(206,121,34, 30,SAMSUNG_CYAN);
Tft.drawString(buff,1,127,2,BLACK);
}
//re-display the timing adjustment (everything from 150 to 180 pixels in height)
//if diff is not 0, the current time adjustment will be adjusted by that much before displaying
void renderTravelAdj(int diff) {
memset(buff, '\0', sizeof(buff));
//do not allow the timing to be adjusted when 'travel_locked' is set:
if (travel_locked == 0x0) {
travel += diff;
sprintf(buff, "DN %d ms UP", travel);
Tft.fillRectangle(1, 151,240,30,SAMSUNG_GREY2);
Tft.fillRectangle(1, 151,34, 30,SAMSUNG_CYAN);
Tft.fillRectangle(206,151,34, 30,SAMSUNG_CYAN);
Tft.drawString(buff,1,157,2,BLACK);
} else {
sprintf(buff, " %d ms locked", travel);
Tft.fillRectangle(1, 151,240,30,SAMSUNG_GREY2);
Tft.drawString(buff,1,157,2,RED);
}
}
//actually record a frame
void doRecord() {
progress += 1;
servo.write(60); //Send the servo to 60 degrees (play with this to set the 'pressed' spot)
delay(travel); //wait for the servo to get there
servo.write(80); //Send the servo back to 80 degrees (play with this to set the 'unpressed spot'
renderProgress(); //Update the frame counter now that we've taken a frame
if (progress >= MAX_FRAMES) {
Tft.fillRectangle(1,181,240,170,SAMSUNG_GREY);
Tft.drawString("RESET",40,219,4,BLACK);
}
}
//After recording a video, display a 'RESET' button.
void doReset() {
progress = 0;
renderProgress();
Tft.fillRectangle(1,181,240,170,SAMSUNG_GREY);
Tft.drawString("GO!",72,219,4,BLACK);
}
void doTouch(){
// a point object holds x y and z coordinates
Point p = ts.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, MapX1, MapX2);
p.y = map(p.y, TS_MINY, TS_MAXY, MapY1, MapY2);
// we have some minimum pressure we consider 'valid'
// pressure of 0 means no pressing!
if (p.z < ts.pressureThreshhold) {
return;
}
if ((p.x < 40)&&(p.y > 115)&&(p.y < 150)){
renderFrameCount(-1); //frame multiplier DN button
} else if ((p.x > 200)&&(p.y > 115)&&(p.y < 150)){
renderFrameCount(1); //frame multiplier UP button
} else if ((p.x < 40)&&(p.y > 150)&&(p.y < 180)){
renderTravelAdj(-10); //timing adjustment DN button
} else if ((p.x > 200)&&(p.y > 150)&&(p.y < 180)){
renderTravelAdj(+10); //timing adjustment UP button
} else if ((p.y > 150)&&(p.y < 180)){
travel_locked = !travel_locked;
renderTravelAdj(0); //the space inbetween both timing adjustment buttons
} else if ((p.y > 190)){ //everything within the 'GO' box
if (progress < MAX_FRAMES) {
for (int i=0;i<frames_to_record;i++) {
doRecord();
}
} else {
doReset();
}
}
//Tft.fillCircle(p.x,p.y,2,GREEN);
}
void loop(void)
{
doTouch();
}
void initTouchScreenParameters()
{
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ts = TouchScreen(57, A2, A1, 54, 300); //init TouchScreen port pins
#else
ts = TouchScreen(17, A2, A1, 14, 300); //init TouchScreen port pins
#endif
//Touchscreen parameters for this hardware
TS_MINX = 140;
TS_MAXX = 900;
TS_MINY = 120;
TS_MAXY = 940;
MapX1 = 239;
MapX2 = 0;
MapY1 = 319;
MapY2 = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment