Arduino & CC3000 & Motorshield & Robot - rest

I have a 4 Motor Drive car that has ARD MEGA / CC3000 / Motorshield on it.
I have written a sketch that runs REST and a webpage with buttons, which works fine in Serial.
I have written a sketch that controls the Motors Forwards / Backwards / Left / Right and this works fine.
When I combine the 2 Sketches and press FORWARD on the webpage it works but then 'Hangs'.
void loop()
{
// Handle any multicast DNS requests
mdns.update();
Adafruit_CC3000_ClientRef client = restServer.available();
rest.handle(client);
wdt_reset();
if(!cc3000.checkConnected()){while(1){}}
wdt_reset();
}
int forward(String command) {
goforwards();
return 1;
}
int backward(String command) {
gobackwards();
return 1;
}
int left(String command) {
Serial.println(F("GO LEFT..."));
//goleft();
return 1;
}
int right(String command) {
Serial.println(F("GO RIGHT..."));
//goright();
return 1;
}
int estop(String command) {
Serial.println(F("Asked to STOP..."));
allstop();
return 1;
}
void goforwards() {
Serial.println(F("GO FORWARD..."));
motor(1, FORWARD, 150); motor(4, FORWARD, 150); motor(2, FORWARD, 150); motor(3, FORWARD, 150); delay(500);
allstop();
}
void gobackwards() {
Serial.println(F("GO BACKWARD..."));
motor(1, BACKWARD, 150); motor(4, BACKWARD, 150); motor(2, BACKWARD, 150); motor(3, BACKWARD, 150); delay(500);
allstop();
}
void goleft() {motor(1, FORWARD, 175); motor(4, FORWARD, 175); motor(2, FORWARD, 50); motor(3, FORWARD, 50);delay(2000); }
void goright() {motor(1, FORWARD, 50); motor(4, FORWARD, 50); motor(2, FORWARD, 175); motor(3, FORWARD, 175); delay(2000); }
void allstop() {motor(1, RELEASE, 0); motor(2, RELEASE, 0);motor(3, RELEASE, 0);motor(4, RELEASE, 0);delay(1); }
void motor(int nMotor, int command, int speed)
{
int motorA, motorB;
if (nMotor >= 1 && nMotor <= 4)
{
switch (nMotor)
{
case 1:
motorA = MOTOR1_A;
motorB = MOTOR1_B;
break;
case 2:
motorA = MOTOR2_A;
motorB = MOTOR2_B;
break;
case 3:
motorA = MOTOR3_A;
motorB = MOTOR3_B;
break;
case 4:
motorA = MOTOR4_A;
motorB = MOTOR4_B;
break;
default:
break;
}
switch (command)
{
case FORWARD:
motor_output (motorA, HIGH, speed);
motor_output (motorB, LOW, -1); // -1: no PWM set
break;
case BACKWARD:
motor_output (motorA, LOW, speed);
motor_output (motorB, HIGH, -1); // -1: no PWM set
break;
case BRAKE:
motor_output (motorA, LOW, 255); // 255: fully on.
motor_output (motorB, LOW, -1); // -1: no PWM set
break;
case RELEASE:
motor_output (motorA, LOW, 0); // 0: output floating.
motor_output (motorB, LOW, -1); // -1: no PWM set
break;
default:
break;
}
}
}
void motor_output (int output, int high_low, int speed)
{
int motorPWM;
switch (output)
{
case MOTOR1_A:
case MOTOR1_B:
motorPWM = MOTOR1_PWM;
break;
case MOTOR2_A:
case MOTOR2_B:
motorPWM = MOTOR2_PWM;
break;
case MOTOR3_A:
case MOTOR3_B:
motorPWM = MOTOR3_PWM;
break;
case MOTOR4_A:
case MOTOR4_B:
motorPWM = MOTOR4_PWM;
break;
default:
// Use speed as error flag, -3333 = invalid output.
speed = -3333;
break;
}
if (speed != -3333)
{
shiftWrite(output, high_low);
if (speed >= 0 && speed <= 255)
{
analogWrite(motorPWM, speed);
}
}
}
void shiftWrite(int output, int high_low)
{
static int latch_copy;
static int shift_register_initialized = false;
if (!shift_register_initialized)
{
pinMode(MOTORLATCH, OUTPUT);
pinMode(MOTORENABLE, OUTPUT);
pinMode(MOTORDATA, OUTPUT);
pinMode(MOTORCLK, OUTPUT);
// Set pins for shift register to default value (low);
digitalWrite(MOTORDATA, LOW);
digitalWrite(MOTORLATCH, LOW);
digitalWrite(MOTORCLK, LOW);
// Enable the shift register, set Enable pin Low.
digitalWrite(MOTORENABLE, LOW);
// start with all outputs (of the shift register) low
latch_copy = 0;
shift_register_initialized = true;
}
// The defines HIGH and LOW are 1 and 0.
// So this is valid.
bitWrite(latch_copy, output, high_low);
// Use the default Arduino 'shiftOut()' function to
// shift the bits with the MOTORCLK as clock pulse.
// The 74HC595 shiftregister wants the MSB first.
// After that, generate a latch pulse with MOTORLATCH.
shiftOut(MOTORDATA, MOTORCLK, MSBFIRST, latch_copy);
delayMicroseconds(5); // For safety, not really needed.
digitalWrite(MOTORLATCH, HIGH);
delayMicroseconds(5); // For safety, not really needed.
digitalWrite(MOTORLATCH, LOW);
}
The code above is the Meat where something is going wrong. The code above this is all fine.
WHen the code gets the command 'forward' it runs the VOID goforwards(); but then 'hangs'. Same for 'backwards'.
Seems to get stuck in these VOIDS and so does not respond to the next command from webpage.
Any help is appreciated!

Related

How to make a sprite change based on it's position relative to the player's

I'm trying to achieve a 2.5D effect with a sprite like the effect in this https://www.youtube.com/watch?v=-Eb99eujEik video, but it selects the wrong sprite at certain angles
the code I have so far is:
void Update()
{
float angle = Quaternion.LookRotation(player.transform.position, transform.position).y - transform.rotation.y;
print(angle + ", " + Mathf.Abs(Mathf.Round(angle * 100 / 12.5f)) + ", " + Quaternion.LookRotation(player.transform.position, transform.position).y * 100);
switch (Mathf.Abs(Mathf.Round(angle * 100 / 12.5f)))
{
case 0:
sprite_comp.sprite = N;
break;
case 1:
sprite_comp.sprite = NW;
break;
case 2:
sprite_comp.sprite = W;
break;
case 3:
sprite_comp.sprite = SW;
break;
case 4:
sprite_comp.sprite = S;
break;
case 5:
sprite_comp.sprite = SE;
break;
case 6:
sprite_comp.sprite = E;
break;
case 7:
sprite_comp.sprite = NE;
break;
}
}
I solved this problem. This is an 8-directional sprite algorithm whose component works on the character that has a SpriteRenderer. This algorithm divides the sections into 22.5 degrees to determine which side should be selected. It also takes into account both the rotation of the camera and the rotation of the character due to the function of the angle of calculation from the forward of the camera and the character.
private SpriteRenderer spriteRenderer;
public Transform plane;
public Camera cam;
private const float step = 22.5f;
public Sprite N, NW, W, SW, S, SE, E, NE;
public void Start() => spriteRenderer = GetComponent<SpriteRenderer>();
public void Update()
{
var projected = Vector3.ProjectOnPlane(cam.transform.forward, plane.up);
var angle = Vector3.SignedAngle(projected, plane.forward, plane.up);
var AbsAngle = Mathf.Abs(angle);
if (AbsAngle < step) spriteRenderer.sprite = N;
else if (AbsAngle < step*3) spriteRenderer.sprite = Mathf.Sign(angle) < 0 ? NW : NE;
else if (AbsAngle < step*5) spriteRenderer.sprite = Mathf.Sign(angle) < 0 ? W : E;
else if (AbsAngle < step*7) spriteRenderer.sprite = Mathf.Sign(angle) < 0 ? SW : SE;
else spriteRenderer.sprite = S;
Billboard(spriteRenderer.transform, cam);
}
You will also need another code to hold the sprite to the camera. A billboard method is also needed to solve the problem.
public void Billboard(Transform character, Camera mainCamera)
{
var dir = plane.position - mainCamera.transform.position;
var LookAtRotation = Quaternion.LookRotation(dir);
var LookAtRotationOnly_Y = Quaternion.Euler(character.rotation.eulerAngles.x, LookAtRotation.eulerAngles.y,character.eulerAngles.z);
character.rotation = LookAtRotationOnly_Y;
}
Result

Can't find cs 1003 syntax error, ',' expected

void Update()
{
if (Input.GetButtonDown(RKey))
{
objNum = (Random.Range(0,6));
if (objNum = 1)
{
Roundcube.GetComponent<Animator>().Play(Roundcube ROLLING DICE 1);
}
if (objNum = 2)
{
Roundcube.GetComponent<Animator>().Play(Roundcube ROLLING DICE 2);
}
if (objNum = 3)
{
Roundcube.GetComponent<Animator>().Play(Roundcube ROLLING DICE 3);
}
if (objNum = 4)
{
Roundcube.GetComponent<Animator>().Play(Roundcube ROLLING DICE 4);
}
if (objNum = 5)
{
Roundcube.GetComponent<Animator>().Play(Roundcube ROLLING DICE 5);
}
if (objNum = 6)
{
Roundcube.GetComponent<Animator>().Play(Roundcube ROLLING DICE 6);
}
}
}
This is my code I have a lot of Syntax error's coming up. I'm doing this by watching a tutorial and I copied every code but it's not working. I'm a noob at Blender, sorry.
I took the advice of BugFinder and Tim Roberts.
Gave you some examples
your Animator.Play need a string and it looks like this "Text in a string"
// Before
Roundcube.GetComponent<Animator>().Play(Roundcube ROLLING DICE 6);
// After
Roundcube.GetComponent<Animator>().Play("Roundcube ROLLING DICE 6");
your if statements need to be == not =.
// Before
if (objNum = 1)
// After
if (objNum == 1)
Random.Range(NumberA,NumberB) is a random range from NumberA to NumberB -1.
so Random.Range(0,6) is 0 to 5.
so you want Random.Range(1,7) to get 1 to 6.
// Before
objNum = (Random.Range(0,6));
// After
objNum = (Random.Range(1,7));
Use a switch as Tim Roberts say.
or you can simply change the number in the string.
void Update()
{
if (Input.GetButtonDown(RKey))
{
objNum = (Random.Range(1, 7));
Animator animator = Roundcube.GetComponent<Animator>();
switch (objNum)
{
case 1:
animator.Play("Roundcube ROLLING DICE 1");
break;
case 2:
animator.Play("Roundcube ROLLING DICE 2");
break;
case 3:
animator.Play("Roundcube ROLLING DICE 3");
break;
case 4:
animator.Play("Roundcube ROLLING DICE 4");
break;
case 5:
animator.Play("Roundcube ROLLING DICE 5");
break;
case 6:
animator.Play("Roundcube ROLLING DICE 6");
break;
default:
}
// or
animator.Play($"Roundcube ROLLING DICE {objNum}");
}
}

How to I transition from "Start Game" page to playing the actual game?

var start = true; // the game will begin on the "start" screen
var play = false;
var gameOver = false;
clickX = 0; // track the mouse click location
clickY = 0;
function setup() {
createCanvas(640, 480);
}
function draw() {
//Leave this draw() function alone
if (start){
startScreen();
}
else if (play){
playScreen();
}
else if (gameOver){
gameOverScreen();
}
}
function mousePressed(){
clickX = mouseX; // grab the X location of the mouse
clickY = mouseY; // grab the Y location of the mouse
}
function startScreen(){
background(50);
textSize(20);
fill(255, 0, 0);
text('To begin playing, click mouse',60,80);
if(dist(clickX, clickY, width/2, height/2) < 100){
}
}
function playScreen(){
}
function gameOverScreen(){
}
My teacher said "add some branching logic to the mousePressed() function so that mouse clicks will change the canvas from one screen to the next. Think about how to use if() and else if() statements and those boolean "flag" variables at the top of the sketch (8 points)."
I am trying to create code that will switch the starting screen to the actual game! I'd like to do it so that when you click your
I've been looking everywhere and can't find anything helpful :( So if you have any references I can check out, I will take those too! Thank you!
to manage that state I would recommend you a switch statemen where you can iterate it using a variable with the scenario name:
let scenario ; // the game will begin on the "start" screen and will change to play or gameOver according the needs
function setup() {
createCanvas(640, 480);
scenario = 'playing'
}
function draw() {
startScreen()
text(scenario,width/2,height /2);
}
function mousePressed(){
// Here you can add different check according to each scenario
switch(scenario){
case 'start':
if(dist(mouseX, mouseY, 60, 80) < 100){
scenario = 'playing'
}
break;
case 'playing':
if(dist(mouseX, mouseY, 60, 80) < 100){
scenario = 'gameOver'
}
break;
case 'gameOver':
if(dist(mouseX, mouseY, 60, 80) < 100){
scenario = 'start'
}
break;
}
}
function startScreen(){
switch(scenario){
case 'start':
background(50);
textSize(20);
fill(255, 0, 0);
text('To begin playing, click mouse',60,80);
break;
case 'playing':
background(200,0,0);
textSize(20);
fill(255, 0, 0);
text('Click to continue to GameOver',60,80);
break;
case 'gameOver':
background(0,255,0);
textSize(20);
fill(255, 0, 0);
text('Click to go to start',60,80);
break;
}
}

Unity - GetKeyDown and GetKey using the same KeyCode to get a delay on input if held down

I an trying to get the user input do two different behaviors with the same input key.
like this :
if (Input.GetKeyDown(KeyCode.D) || Input.GetKey(KeyCode.D))
Making a tetris game: The goal is, tapping "D" once, I want tetromino to move one world unit per tap. AND when holding down the same key "D" I want the block to move right continuously until it reaches the edge of the game board, without having to tap.
This sort of works with the code above but, the problem I have is that tapping once moves 2 or 3 world unit instead of once because there is no delay before unity realizes that I am holding the key down.
I would like unity to wait .5 seconds before activating "Input.GetKey(KeyCode.D)" so that I can keep the behavior "Input.GetKeyDown(KeyCode.D)"
Bottom line,
I want to be able to tap "D" to move one world unit per tap
I want the block to move continuously right until it reaches the edge of the game board if I hold down "D" but, only after holding it down for .5 seconds
How can I do this ?
Full code for the Tetromino.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Tetromino : MonoBehaviour {
//#####################################################################################################
//#####################################################################################################
float fallTimer = 0f; // timer counting the seconds to check if mino needs to fall
public float fallSpeed = 1f; // variable to determine how fast the mino needs to fall
public bool allowRotation = true;
public bool limitRotation = false;
//#####################################################################################################
//#####################################################################################################
// Use this for initialization
void Start () {
}
//#####################################################################################################
//#####################################################################################################
// Update is called once per frame
void Update ()
{
CheckUserInput(); // --------------------------- // Checks the user input every frames
FallBehavior(); // checks if the block needs to fall and increments the timer
}
//#####################################################################################################
//#####################################################################################################
void CheckUserInput()
{
if (Input.GetKeyDown(KeyCode.D)) // moves the mino to the right
{
transform.position += new Vector3(1,0,0);
if (CheckIsValidPosition()) // if minos is not in a valid position, the transform pushes the minos
{ // back to the left, to keep it inside the grid
}
else
{
transform.position += new Vector3(-1, 0, 0); // this counters the first attempt to move
}
}
else if (Input.GetKeyDown(KeyCode.A)) // moves the mino to the left
{
transform.position += new Vector3(-1, 0, 0);
if (CheckIsValidPosition())
{
}
else
{
transform.position += new Vector3(1, 0, 0);
}
}
else if (Input.GetKeyDown(KeyCode.W)) // rotates the mino
{
if (allowRotation)
{
if (limitRotation) //limited rotation ON, to prevent rotating outside the grid
{ // after the tetromino landed at the bottom
if (transform.rotation.eulerAngles.z >= 90)
{
transform.Rotate(0, 0, -90);
}
else
{
transform.Rotate(0, 0, 90);
}
}
else
{
transform.Rotate(0, 0, 90); // 90 degrees rotation on the mino
}
if (CheckIsValidPosition())
{
}
else
{
if (limitRotation)
{
if (transform.rotation.eulerAngles.z >= 90)
{
transform.Rotate(0, 0, -90);
}
else
{
transform.Rotate(0, 0, 90);
}
}
else
{
transform.Rotate(0, 0, -90);
}
}
}
}
else if (Input.GetKeyDown(KeyCode.S))
{
transform.position += new Vector3(0, -1, 0); // makes the mino go down when pressing
if (CheckIsValidPosition())
{
}
else
{
transform.position += new Vector3(0, 1, 0);
}
}
}
//#####################################################################################################
//#####################################################################################################
/// <summary>
/// Makes the block fall by 1 unit and checks how fast it needs to fall
/// </summary>
void FallBehavior()
{
if (Time.time - fallTimer >= fallSpeed) // on the first frame, Time.time = 0 & fallTimer = 0
// so 0 - 0 = 0, is it >= then fallSpeed = 1? no
// so the if statement does not exectute, block dont fall
// after 1 sec, Time.time = 1 & fallTimer = 0
// so 1 - 0 = 1, is it >= then fallSpeed = 1? yes
// so block falls after 1 sec, because we increment it
// in the if statment also
{
transform.position += new Vector3(0, -1, 0); // moves the mino down
fallTimer = Time.time; // Time.time check the time since game started and is assigned
} // to fallTimer so that the timer updates every frame
// when called in the Update method. fallTimer = 0, 1, 2, 3 ...
if (CheckIsValidPosition()) // also helps checking if the Y is invalid, which tells the game to spawn
{ // the next tetromino when Y is less <= to the bottom of the grid
}
else
{
transform.position += new Vector3(0, 1, 0);
enabled = false; // disables the current piece, because it is at the bottom. So that the controls are not still
// attached to the current piece, after the next one spawned
FindObjectOfType<Game>().SpawnNextTetromino(); // spawns the next tetromino after the last one reached the bottom
}
}
//#####################################################################################################
//#####################################################################################################
/// <summary>
/// check the position of the individual tiles of the minos (children of the prefab)
/
/// </summary>
/// <returns></returns>
bool CheckIsValidPosition()
{
foreach (Transform mino in transform)
{
Vector2 pos = FindObjectOfType<Game>().RoundingTheMinoPosition (mino.position);
if (FindObjectOfType<Game>().CheckIsInsideGrid(pos) == false)
{
return false;
}
}
return true;
}
}
Full code of Game.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Game : MonoBehaviour {
public static int gridWidth = 10; // fixed grid size varibles
public static int gridHeight = 20; // for the blocks to fall in
// the grid need to be in a 2d array and we want to store all the x and y values for each world unit of the grid
// so that we can know which point on the grid are beind occupied by tetrominos that fell in.
//
// the array is gonna store the transforms so we use "gridWidth" and "gridHeight" to define the size of the array.
public static Transform[,] grid = new Transform[gridWidth, gridHeight];
// Use this for initialization
void Start () {
SpawnNextTetromino(); // spawns the first tetromino in the game
}
// Update is called once per frame
void Update () {
}
public void SpawnNextTetromino() // the Resources folder is included when the game compiles, we placed our prefabs
{ // in "Assets\Resources\Prefabs" to allow instantiation in the code.
// we cast a gameobject -> "(GameObject)" to let "Instantiate" know what we want to instantiate.
GameObject nextTetromino = (GameObject)Instantiate(Resources.Load(GetRandomTetromino(), typeof(GameObject)), new Vector2(5.0f, 20.0f), Quaternion.identity);
}
//gonna pass in the mino position in this method to see
// if it is still in the grid
public bool CheckIsInsideGrid(Vector2 pos)
{
return ((int)pos.x >= 0 && (int)pos.x < gridWidth && (int)pos.y >= 0);
}
public Vector2 RoundingTheMinoPosition(Vector2 pos)
{
return new Vector2(Mathf.Round(pos.x), Mathf.Round(pos.y));
}
/// <summary>
/// Genreates a random int and assings a teromino prefab to the outcome
/// </summary>
/// <returns></returns>
string GetRandomTetromino()
{
int randomTetromino = Random.Range(1, 8); //
string randomTetrominoName = null;
switch (randomTetromino)
{
case 1:
randomTetrominoName = "Prefabs/Tetromino_T";
break;
case 2:
randomTetrominoName = "Prefabs/Tetromino_Long";
break;
case 3:
randomTetrominoName = "Prefabs/Tetromino_Square";
break;
case 4:
randomTetrominoName = "Prefabs/Tetromino_J";
break;
case 5:
randomTetrominoName = "Prefabs/Tetromino_L";
break;
case 6:
randomTetrominoName = "Prefabs/Tetromino_S";
break;
case 7:
randomTetrominoName = "Prefabs/Tetromino_Z";
break;
}
return randomTetrominoName;
}
}
Looks like I misunderstood the original question. You want to move on "D" key press only but move until your you have reached the Edge when the the "D" key is held down.You need a timer when the the key is held down and this can be done with Time.deltaTime. Check while the key is held down with Input.GetKey, and if the timer reaches the amount of value you think makes it a held down, then you know the key is held down.
Also, check when the key is released with Input.GetKeyUp(KeyCode.D). If the key is released but timer has not reached the value you think makes it a held down,then it's simply a key press. It's worth doing this in a coroutine function instead of the Update function to simplify it and also reduce the amount of variables required to do it.
const float timeToCountAsHeldDown = 0.3f;
float pressTimer = 0;
IEnumerator moveChecker()
{
while (true)
{
//Check when the D key is pressed
if (Input.GetKeyDown(KeyCode.D))
{
//Continue to check if it is still heldown and keep counting the how long
while (Input.GetKey(KeyCode.D))
{
//Start incrementing timer
pressTimer += Time.deltaTime;
//Check if this counts as being "Held Down"
if (pressTimer > timeToCountAsHeldDown)
{
//It a "key held down", call the OnKeyHeldDown function and wait for it to return
yield return OnKeyHeldDown();
//No need to continue checking for Input.GetKey(KeyCode.D). Break out of this whule loop
break;
}
//Wait for a frame
yield return null;
}
}
//Check if "D" key is released
if (Input.GetKeyUp(KeyCode.D))
{
//Check if we have not not reached the timer then it is only a key press
if (pressTimer < timeToCountAsHeldDown)
{
//It just a key press, call the OnKeyPressedOnly function and wait for it to return
yield return OnKeyPressedOnly();
}
//Reset timer to 0 for the next key press
pressTimer = 0f;
}
//Wait for a frame
yield return null;
}
}
IEnumerator OnKeyPressedOnly()
{
Debug.Log("D key was only Pressed");
//Move 1 unit only
transform.position += new Vector3(1, 0, 0);
yield return null;
}
IEnumerator OnKeyHeldDown()
{
Debug.LogWarning("D key is Held Down");
//Don't move for 0.5 seconds
yield return new WaitForSeconds(0.5f);
//Move 1 unit every frame until edge detection is reached!
while (!CheckIsValidPosition())
{
transform.position += new Vector3(1, 0, 0);
//Wait for a frame
yield return null;
}
}

Two instances of class are getting mixed up?

I am creating a sort of game with Arduino and Processing. In my code, I use Daniel Shiffman's class Timer, but would like to create two different Timers using two different instances of the class.
My problem is that these two instances seem to be getting mixed up, with each one doing parts of what the other should be doing.
For example, timer should run for 10 seconds and correctTimer should run for 3 seconds, but they both run for 10 seconds. Additionally, when timer is finished, it should set the background to red and when correctTimer is finished, it should set the background to blue. However, both Timers set the background to blue when they are finished.
Does anyone have any ideas of how to fix this?
import processing.serial.*;
int end = 10;
String serial;
Serial port;
float[] array;
// --------------------------------------------------
PImage img;
PImage correct;
PImage incorrect;
float thumb;
float index;
float middle;
float ring;
float pinky;
// --------------------------------------------------
String alphabet;
int randomNum;
String letter;
// --------------------------------------------------
int savedTime;
int totalTime;
int passedTime;
boolean quit = false;
class Timer {
Timer(int tempTotalTime) {
totalTime = tempTotalTime;
}
void start() {
savedTime = millis();
//quit = false;
}
boolean isFinished() {
passedTime = millis() - savedTime;
if (passedTime > totalTime) {
return true;
} else {
return false;
}
}
}
Timer timer;
Timer correctTimer;
// --------------------------------------------------
boolean checkLetter(String letterPicked, float flexR_THUMB, float flexR_INDEX, float flexR_MIDDLE, float flexR_RING, float flexR_PINKY) {
if (letterPicked == "A") {
if (flexR_THUMB > 12000 && flexR_THUMB < 22000 &&
flexR_INDEX > 27958 && flexR_INDEX < 38500 &&
flexR_MIDDLE > 26035 && flexR_MIDDLE < 41650 &&
flexR_RING > 16492 && flexR_RING < 26000 &&
flexR_PINKY > 37528 && flexR_PINKY < 53500) {
return true;
} else {
return false;
}
}
return false; }
// --------------------------------------------------
void setup() {
size(1280, 950);
background(255);
port = new Serial(this, "/dev/tty.usbmodem1421", 9600);
port.clear();
serial = port.readStringUntil(end);
serial = null;
correct = loadImage("img/RIGHT.png");
incorrect = loadImage("img/WRONG.png");
correctTimer = new Timer(3000);
startOver();
}
// --------------------------------------------------
void startOver() {
background(255);
letter = "A";
img = loadImage("img/" + letter +".png");
image(img, 0, 0, 1280, 950);
timer = new Timer(10000);
timer.start();
}
// --------------------------------------------------
void draw() {
while(port.available() > 0) {
serial = port.readStringUntil(end);
}
if (serial != null) {
float[] array = float(split(serial, ','));
thumb = array[0];
index = array[1];
middle = array[2];
ring = array[3];
pinky = array[4];
}
if (checkLetter(letter, thumb, index, middle, ring, pinky) == true && quit == false) {
image(correct, 0, 0, 1280, 950);
quit = true;
correctTimer.start();
} else if (timer.isFinished() && quit == false) {
background(255, 0, 0);
quit = true;
correctTimer.start();
}
if (correctTimer.isFinished()) {
background(0, 0, 255);
}
}
Please try to post a MCVE instead of your whole project. Just put together a small example that demonstrates the problem. That makes it much easier for us to help you.
But your problem is caused by your savedTime, totalTime, and passedTime variables being outside the Timer class. Basically that means they're shared between all instances of the Timer class. You can use println() statements to confirm this.
To fix your problem, just move those variables inside the Timer class, so each instance has its own copy of them.
If you're still having trouble, please post a MCVE in a new question post, and we'll go from there. Good luck.