|
/*
|
|
Klikimouse5 aneb objects forever! + RX/TX LEDs
|
|
3 tlacitka a LED+330 Ohm odpor proti zemi
|
|
Macros for Mouse and Keyboard (ArduinoMicro)
|
|
|
|
Based on:
|
|
|
|
ButtonMouseControl
|
|
For Leonardo and Due boards only.
|
|
http://www.arduino.cc/en/Tutorial/ButtonMouseControl
|
|
https://www.arduino.cc/en/Tutorial/KeyboardAndMouseControl
|
|
*/
|
|
|
|
|
|
#include <Keyboard.h>
|
|
#include <Mouse.h>
|
|
|
|
|
|
// set pin numbers for the buttons and led:
|
|
const int button_B = 4;
|
|
const int button_C = 3;
|
|
const int button_A = 2;
|
|
const int led = 8; // led proti GND
|
|
const int RXled = 17; // led proti VCC
|
|
const int TXled = 30; // led proti VCC
|
|
const int C_led = 10; // led proti GND
|
|
|
|
#define UNUSED(x) (void)(x)
|
|
#define FAST_MOUSE 25
|
|
#define SLOW_MOUSE 1000
|
|
#define T_RUNC 80
|
|
#define T_RUN 128
|
|
#define T_CLIMBC 96
|
|
#define T_CLIMB1 900
|
|
#define T_CLIMB2 250
|
|
|
|
#define MOUSE_STEP_MAX 125
|
|
|
|
class Point { // {{{ int x; int y }; // Beware, Mouse can move only -128..127
|
|
public:
|
|
int x;
|
|
int y;
|
|
Point():x(0),y(0){}; // zero constructor
|
|
Point(const Point &cp):x(cp.x),y(cp.y) {}; // copy constructor
|
|
Point(int _x, int _y):x(_x),y(_y) {}; // from int
|
|
bool isZero() {return (x==0 && y==0);};
|
|
void set(int _x, int _y) {x=_x;y=_y;};
|
|
void set(const Point &val) {x=val.x;y=val.y;};
|
|
void add(const Point &val) {x+=val.x;y+=val.y;};
|
|
void sub(const Point &val) {x-=val.x;y-=val.y;};
|
|
void negate() {x=-x;y=-y;};
|
|
void negX() {x=-x;};
|
|
void negY() {y=-y;};
|
|
void clipBy(int val) { // {{{ if val <0 set (0,0)
|
|
if (val <0) val=0;
|
|
x=(x>=0)?min(x,val):max(x,-val);
|
|
y=(y>=0)?min(y,val):max(y,-val);
|
|
}; // }}}
|
|
}; // }}}
|
|
Point DFS(2*275, 2*342); // DAGGERFALL Full_Screen
|
|
Point DFS2(275, 342); // DAGGERFALL Full_Screen / 2 = Center
|
|
Point DFS4(275/2, 342/2); // DAGGERFALL Full_Screen / 4 = moves
|
|
|
|
Point Mouse_at(0,0); // Supposed position of mouse, updated by MouseMoveHere, could/should be set to (0,0) at start of any sequence of more movements
|
|
Point tgt; // temp variable for target of moving
|
|
bool MouseMoveHere( Point &tgt ) { // {{{ RELATIVE, TRUE=target reached, tgt=={0,0}; MODIFIES tgt,Mouse_at; Move mouse tovard tgt by moving MOUSE_STEP_MAX on each axe max : Point here={1234,-321}; while (!MouseMoveHere(here)){}; if (here.x==0 && here.y==0) {print("OK");};
|
|
if (tgt.isZero()) return true;
|
|
Point step(tgt);
|
|
step.clipBy(MOUSE_STEP_MAX);
|
|
tgt.sub(step);
|
|
Mouse_at.add(step);
|
|
//Serial.print(step.x);Serial.print(",");Serial.print(step.y);Serial.print(" => ");
|
|
//Serial.print(tgt.x);Serial.print(",");Serial.print(tgt.y);Serial.print(" => ");
|
|
//Serial.print(Mouse_at.x);Serial.print(",");Serial.print(Mouse_at.y);Serial.println();
|
|
Mouse.move(step.x,step.y);
|
|
return tgt.isZero();
|
|
}; //}}}
|
|
|
|
class Base{ // {{{
|
|
public:
|
|
virtual void start(){ stop_me=false;}; // initialise class for next round of cycles
|
|
virtual void restart(){ stop();}; // class button was pressed again, maybe stop it?
|
|
virtual void stop(){ stop_me=true;}; // prepare class for finishing as soon as possible
|
|
virtual unsigned long long pause(unsigned long x){ UNUSED(x); return 1;}; // pause ms before next cycle, 0..not changed; x=current internal state (nonzero)
|
|
virtual unsigned long next(unsigned long x){ UNUSED(x); return 0;}; // next internal state; x=current internal state (nonzero)
|
|
protected:
|
|
bool stop_me; // true = finish as soon as possible
|
|
}; // }}}
|
|
class Blink : public Base { // {{{
|
|
public:
|
|
virtual void start(){ stop_me=false; count=0;};
|
|
virtual void stop(){ stop_me=true; count=0;};
|
|
virtual unsigned long long pause(unsigned long x){ UNUSED(x); return 100;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
if (x == 1) return 2;
|
|
if (stop_me) x=0; else if (!count) x=0; else {--count; x=1;};
|
|
return x;
|
|
}; // }}}
|
|
void set_count(byte x){ if (x) count=x-1; else count=0;};
|
|
private:
|
|
byte count;
|
|
}; // }}}
|
|
|
|
/* {{{ FAPCEO
|
|
// {{{ ROUTES
|
|
#define ROUTES 5
|
|
struct T_routes { Point go_there; long clicks; int wait; };
|
|
T_routes routes[ROUTES] = {
|
|
{ Point(800,0), 10, 0 }, // 11->case
|
|
{ Point(-200,150), 1, 0 }, // case->floor
|
|
{ Point(-600,-150), 1, 0 }, // floor->11
|
|
{ Point(800,400), 2, 0 }, // 11->upgrade
|
|
{ Point(-800,-400), 20*60-14, 0 }, // and back to 11 (~60 sec, -14 = other clicks)
|
|
};
|
|
// }}}
|
|
class FastClickLearn : public Base { // {{{ 20 clicku/sec, ROUTE: 1 min fast click; 11->case; 10 click; case-> floor; click; floor -> 11; click; 11-> upgrade; click; upgrade ->11
|
|
public:
|
|
virtual void start(){ stop_me=false; Mouse_at.set(0,0); route_at=0; };
|
|
virtual unsigned long long pause(unsigned long x){ UNUSED(x); return 25;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
T_routes *r; // temp
|
|
if (route_at>ROUTES) stop_me=true; // ERROR
|
|
if (stop_me) {x=0; Mouse.release(MOUSE_LEFT); tgt.set(Mouse_at); tgt.negate(); while (!MouseMoveHere(tgt)){}; return 0;}
|
|
switch (x) {
|
|
case 1: ++x; r=&routes[route_at];
|
|
wait=r->wait*4;
|
|
clicks=r->clicks;
|
|
tgt.set(r->go_there);
|
|
while (!MouseMoveHere(tgt)){}; // Move to current target
|
|
// break; // fall thru !!!
|
|
case 2: ++x; if (--clicks<0) { ++x; } else { Mouse.press(MOUSE_LEFT); }; break;
|
|
case 3: (clicks >0)? --x:++x; Mouse.release(MOUSE_LEFT); break;
|
|
case 4: if (--wait <0) ++x; else break; // if wait <=0 fall thru !!!
|
|
case 5: ++route_at; if (route_at >=ROUTES) route_at=0; x=1; break;
|
|
|
|
default: x=0;break;
|
|
};
|
|
return x;
|
|
}; // }}}
|
|
// case 2: MouseMoveHere(tgt);if (tgt.isZero()) ++x; break; // Move to next target
|
|
|
|
private:
|
|
unsigned int route_at;
|
|
int wait; long clicks;
|
|
|
|
}; // }}}
|
|
}}} */
|
|
class Recast : public Base { // {{{
|
|
public:
|
|
virtual void start(){ stop_me=false; count=20;};
|
|
virtual void restart(){ count+=20;};
|
|
virtual void stop(){ stop_me=true; count=0;};
|
|
virtual unsigned long long pause(unsigned long x){ UNUSED(x); return 70;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1: ++x;Keyboard.press(KEY_END);break;
|
|
case 2: ++x;Keyboard.release(KEY_END);break;
|
|
case 3: ++x;Mouse.press(MOUSE_LEFT);break;
|
|
case 4:
|
|
if (stop_me) x=0; else if (!count) x=0; else {--count; x=1;}
|
|
Mouse.release(MOUSE_LEFT);
|
|
break;
|
|
default: x=0;break;
|
|
}
|
|
return x;
|
|
}; // }}}
|
|
private:
|
|
byte count;
|
|
}; // }}}
|
|
class ClickYes : public Base { // {{{
|
|
public:
|
|
virtual void start(){ stop_me=false; count=40;};
|
|
virtual void restart(){ count=+40;};
|
|
virtual void stop(){ stop_me=true; count=0;};
|
|
virtual unsigned long long pause(unsigned long x){ UNUSED(x); return FAST_MOUSE;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1: ++x;Mouse.press(MOUSE_LEFT);break;
|
|
case 2: ++x;Mouse.release(MOUSE_LEFT);break;
|
|
case 3: ++x;Keyboard.press('y');break;
|
|
case 4:
|
|
if (stop_me) x=0; else if (!count) x=0; else {--count; x=1;}
|
|
Keyboard.release('y');
|
|
break;
|
|
default: x=0;break;
|
|
}
|
|
return x;
|
|
}; // }}}
|
|
private:
|
|
byte count;
|
|
}; // }}}
|
|
class Relearn : public Base { // {{{ Rest / Loiter / 3 hours / Enter } x 3 + Center / click / Training
|
|
public:
|
|
virtual unsigned long long pause(unsigned long x){ // {{{
|
|
unsigned long long p;
|
|
switch (x) {
|
|
case 15: case 115: case 215: p=6000;break; // 6sec = 3 hours countdown
|
|
case 1: case 101: case 201:
|
|
case 5: case 105: case 205:
|
|
case 9: case 109: case 209:
|
|
case 221: case 223:
|
|
case 220: case 222: case 224:
|
|
p=60;break; // time to actualise mouse
|
|
case 6: case 106: case 206: p=FAST_MOUSE+2;break; // longer click on camp
|
|
case 7: case 107: case 207:
|
|
case 18: case 118: case 218:
|
|
case 219: p=200;break; // time to actualise mouse - Trainer screen is slow
|
|
default: p=FAST_MOUSE;break;
|
|
};
|
|
return p;
|
|
}; // }}}
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1: case 101: case 201:
|
|
case 2: case 102: case 202:
|
|
case 3: case 103: case 203: ++x;break;
|
|
case 4: case 104: case 204: ++x;tgt.set(DFS); while (!MouseMoveHere(tgt)){};break;
|
|
// ++x;Mouse.move(127,127,0);break; // to right down
|
|
case 5: case 105: case 205:
|
|
++x; // Mouse.move(-120,-50);break; // to Camp
|
|
case 6: case 106: case 206: ++x;Keyboard.press('r');break; // Mouse.click() is too fast, need press/release (Rest)
|
|
case 7: case 107: case 207: ++x;Keyboard.release('r');break;
|
|
case 8: case 108: case 208: ++x;tgt.set(-DFS2.x/2,-1.25*DFS2.y); while (!MouseMoveHere(tgt)){};break; // Mouse is NOT accelerated over long fast moves (To Loiter)
|
|
case 9: case 109: case 209: ++x;break; // Mouse.move(0,-70,0);break;
|
|
case 10: case 110: case 210: ++x;Mouse.press(MOUSE_LEFT);break;
|
|
case 11: case 111: case 211: ++x;Mouse.release(MOUSE_LEFT);break;
|
|
case 12: case 112: case 212: ++x;Keyboard.press('3');break; // 3 hours
|
|
case 13: case 113: case 213: ++x;Keyboard.release('3');break;
|
|
case 14: case 114: case 214: ++x;Keyboard.press(KEY_RETURN);break;
|
|
case 15: case 115: case 215: ++x;Keyboard.release(KEY_RETURN);break; // wait here
|
|
// waiting for 3 hour countdown
|
|
case 16: case 116: case 216: ++x;Keyboard.press(KEY_RETURN);break;
|
|
case 17: case 117: case 217: ++x;Keyboard.release(KEY_RETURN);break;
|
|
// x3
|
|
case 18: case 118: case 218: ++x;break;
|
|
// 218->219 to Trainer; else back and again
|
|
case 19: case 119: ++x;tgt.set(60,300); while (!MouseMoveHere(tgt)){};break; // Mouse is NOT accelerated over long fast moves (Back To Loiter)
|
|
case 20: case 120: ++x;break; // Mouse.move(0,120,0);break;
|
|
case 21: case 121: x += (101-21); break; // loop: 23->101, 123->201
|
|
// To Trainer
|
|
case 219: ++x;tgt.set(DFS);while (!MouseMoveHere(tgt)){};break;
|
|
// click Trainer
|
|
case 220: ++x;tgt.set(-DFS2.x,-DFS2.y-78);while (!MouseMoveHere(tgt)){}; Mouse.press(MOUSE_LEFT);break;
|
|
case 221: ++x;Mouse.release(MOUSE_LEFT);break;
|
|
// Train?
|
|
case 222: ++x;Mouse.press(MOUSE_LEFT);break;
|
|
case 223: ++x;Mouse.release(MOUSE_LEFT);break;
|
|
// yes
|
|
case 224: ++x;Keyboard.press('y');break;
|
|
case 225: ++x;Keyboard.release('y');break;
|
|
//
|
|
default: x=0;break;
|
|
}
|
|
return x;
|
|
}; // }}}
|
|
}; // }}}
|
|
class Skills : public Base { // {{{ Open minor skills tab
|
|
public:
|
|
virtual unsigned long long pause(unsigned long x){ UNUSED(x); return FAST_MOUSE;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
++x;tgt.set(DFS);tgt.negX();tgt.add(tgt); while (!MouseMoveHere(tgt)){}; break;
|
|
case 5:
|
|
++x;Mouse.move(20,-20,0);break;
|
|
case 6: ++x;break;
|
|
case 7: ++x;Mouse.press(MOUSE_LEFT);break; // Mouse.click() is too fast, need press/release
|
|
case 8: ++x;Mouse.release(MOUSE_LEFT);break;
|
|
case 9: ++x;break;
|
|
case 10:
|
|
++x;Mouse.move(40,-75,0);break; // Mouse is accelerated over long fast moves
|
|
case 11: ++x;Mouse.press(MOUSE_LEFT);break;
|
|
case 12: ++x;Mouse.release(MOUSE_LEFT);break;
|
|
default: x=0;break;
|
|
};
|
|
return x;
|
|
}; // }}}
|
|
|
|
}; // }}}
|
|
class Swing : public Base { // {{{
|
|
public:
|
|
virtual void start(){ stop_me=false; count=20;};
|
|
virtual void restart(){ count+=20;};
|
|
virtual void stop(){ stop_me=true; count=0;};
|
|
virtual unsigned long long pause(unsigned long x){ if ((x ==4)) return 1.5*SLOW_MOUSE; else return FAST_MOUSE;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1: ++x;tgt.set(DFS);tgt.negate(); while (!MouseMoveHere(tgt)){}; break;
|
|
case 2: ++x;tgt.set(DFS2.x,DFS4.y); while (!MouseMoveHere(tgt)){}; break;
|
|
case 3: ++x;Mouse.press(MOUSE_RIGHT);break;
|
|
case 4: ++x;tgt.set(0,DFS2.x/2); while (!MouseMoveHere(tgt)){}; break;
|
|
case 5: ++x;Mouse.release(MOUSE_RIGHT);break;
|
|
case 6: ++x;break;
|
|
case 7:
|
|
if (stop_me) x=0; else if (count<0) {x=0;count=0;} else {--count; x=1;};
|
|
break;
|
|
default: x=0;break;
|
|
};
|
|
return x;
|
|
}; // }}}
|
|
private:
|
|
int count;
|
|
|
|
}; // }}}
|
|
class T_run : public Base { // {{{
|
|
public:
|
|
virtual void start(){ stop_me=false; count+=T_RUNC;};
|
|
virtual void stop(){ stop_me=true; count=0;};
|
|
virtual unsigned long long pause(unsigned long x){ UNUSED(x); return T_RUN;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1: ++x;Keyboard.press(KEY_UP_ARROW);break;
|
|
case 2: ++x;Keyboard.press('p');break;
|
|
case 3: ++x;Keyboard.release(KEY_UP_ARROW);break;
|
|
case 4: ++x;Keyboard.release('p');break;
|
|
case 5: ++x;Keyboard.press(KEY_DOWN_ARROW);break;
|
|
case 6: ++x;Keyboard.press('p');break;
|
|
case 7: ++x;Keyboard.release(KEY_DOWN_ARROW);break;
|
|
case 8:
|
|
if (stop_me) x=0; else if (!count) x=0; else {--count; x=1;}
|
|
Keyboard.release('p');
|
|
break;
|
|
default: x=0;break;
|
|
}
|
|
return x;
|
|
}; // }}}
|
|
private:
|
|
byte count;
|
|
}; // }}}
|
|
class T_climb : public Base { // {{{
|
|
public:
|
|
virtual void start(){ stop_me=false; count=+T_CLIMBC;};
|
|
virtual void stop(){ stop_me=true; count=0;};
|
|
virtual unsigned long long pause(unsigned long x){ return (x & 1)?T_CLIMB1:T_CLIMB2;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1: ++x;Keyboard.press(KEY_UP_ARROW);break;
|
|
case 2:
|
|
if (stop_me) x=0; else if (!count) x=0; else {--count; x=1;}
|
|
Keyboard.release(KEY_UP_ARROW);
|
|
break;
|
|
default: x=0;break;
|
|
}
|
|
return x;
|
|
}; // }}}
|
|
private:
|
|
byte count;
|
|
}; // }}}
|
|
class Corners : public Base { // {{{ TL/DR/TR/DL/Tl
|
|
public:
|
|
virtual unsigned long long pause(unsigned long x){ // {{{
|
|
unsigned long long p;
|
|
p=1000; // 1s
|
|
if (x==9) p=10;
|
|
|
|
return p;
|
|
}; // }}}
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1:++x;//tgt.set(-1000,-1000); ++x;while (!MouseMoveHere(tgt)){delay(D);};break;
|
|
case 2:tgt.set(DFS2); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 3:tgt.set(DFS2); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 4:tgt.set(DFS2);tgt.negate(); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 5:tgt.set(DFS2);tgt.negY(); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 6:tgt.set(DFS2);tgt.negX(); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 7:tgt.set(DFS2);tgt.negX(); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 8:tgt.set(DFS2);tgt.negY(); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 9:tgt.set(DFS2);tgt.negate(); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
default: x=0;break;
|
|
}
|
|
return x;
|
|
}; // }}}
|
|
}; // }}}
|
|
class TestMove : public Base { // {{{ TL/DR/TR/DL/Tl
|
|
public:
|
|
virtual unsigned long long pause(unsigned long x){ // {{{
|
|
unsigned long long p;
|
|
p=FAST_MOUSE;
|
|
return p;
|
|
}; // }}}
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
switch (x) {
|
|
case 1:tgt.set(DFS2); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 2:tgt.set(DFS2); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
case 3:tgt.set(-DFS2.x,-DFS2.y-78); ++x;while (!MouseMoveHere(tgt)){};break;
|
|
default: x=0;break;
|
|
}
|
|
return x;
|
|
}; // }}}
|
|
}; // }}}
|
|
class FastClick : public Base { // {{{ 20 clicku / sec
|
|
public:
|
|
virtual unsigned long long pause(unsigned long x){ UNUSED(x); return 25;}; // 20 clicku/sec = 50ms / click = 25 ms / press/release
|
|
virtual void restart(){ stop_me = true;};
|
|
virtual unsigned long next(unsigned long x){ // {{{
|
|
// Serial.print(x);Serial.print(" -> ");
|
|
switch (x) {
|
|
case 1: ++x;Mouse.press(MOUSE_LEFT);break;
|
|
case 2:
|
|
if (stop_me) x=0; else { x=1;}
|
|
Mouse.release(MOUSE_LEFT);
|
|
break;
|
|
default: x=0;break;
|
|
};
|
|
// Serial.print(x);Serial.print(" => ");
|
|
return x;
|
|
}; // }}}
|
|
private:
|
|
byte count;
|
|
}; // }}}
|
|
|
|
#define DEFAULT_DELAY 25
|
|
#define DEFAULT_DEBOUNCE 100
|
|
|
|
unsigned long state = 0; // state of state automat - 0 = inactive; 1 = start state
|
|
Base *automat = NULL;
|
|
Base *next_automat = NULL;
|
|
unsigned long c_state = 0;
|
|
Blink *blink=new Blink;
|
|
// {{{ Automats
|
|
#define AUTOMATS 5
|
|
struct T_automat {Base *A; Base *B;};
|
|
T_automat automats[AUTOMATS] ={
|
|
{new Recast, new ClickYes}, // 1
|
|
{new T_run, new T_climb}, // 2
|
|
{new Relearn, new Skills}, // 3
|
|
{new FastClick, new Swing}, // 4
|
|
{new Recast, new Swing} // 5
|
|
// {new Corners, new TestMove},
|
|
};
|
|
// {new FastClick, new FastClickLearn},
|
|
//}}}
|
|
unsigned long long responseDelay = DEFAULT_DELAY; // repepeat delay between states
|
|
unsigned long long debounceDelay = DEFAULT_DEBOUNCE; // debounce delay of the button, in ms
|
|
bool somePressed=true; // pressed any button => digitalRead()==0
|
|
bool debouncing=false;
|
|
bool led_shines=false;
|
|
|
|
unsigned long milsDebounce;
|
|
unsigned long milsState;
|
|
unsigned long currentMillis;
|
|
void setup() { // {{{
|
|
Serial.begin(9600);
|
|
// initialize the buttons' inputs:
|
|
pinMode(button_B, INPUT_PULLUP);
|
|
pinMode(button_C, INPUT_PULLUP);
|
|
pinMode(button_A, INPUT_PULLUP);
|
|
pinMode(led, OUTPUT);
|
|
// initialize mouse control:
|
|
Mouse.begin();
|
|
Keyboard.begin();
|
|
milsDebounce=millis();
|
|
milsState=millis();
|
|
delay(1000);
|
|
Serial.println("Klikimouse5 2023.07.29 10:45:37 ");
|
|
Serial.println("{new Recast, new ClickYes}, // 1");
|
|
Serial.println("{new T_run, new T_climb}, // 2");
|
|
Serial.println("{new Relearn, new Skills}, // 3");
|
|
Serial.println("{new FastClick, new Swing}, // 4");
|
|
Serial.println("{new Recast, new Swing} // 5");
|
|
pinMode(RXled, OUTPUT);
|
|
pinMode(TXled, OUTPUT);
|
|
pinMode(C_led, OUTPUT);
|
|
digitalWrite(RXled,HIGH);
|
|
digitalWrite(TXled,HIGH);
|
|
digitalWrite(C_led,LOW);
|
|
|
|
} // }}}
|
|
|
|
void loop() {
|
|
digitalWrite(RXled,!((c_state+1) & _BV(0)));
|
|
digitalWrite(TXled,!((c_state+1) & _BV(1)));
|
|
digitalWrite(C_led, ((c_state+1) & _BV(2)));
|
|
currentMillis=millis(); // {{{ prolog
|
|
bool act_B= ! digitalRead(button_B);
|
|
bool act_C= ! digitalRead(button_C);
|
|
bool act_A= ! digitalRead(button_A);
|
|
|
|
if (debouncing and ((currentMillis-milsDebounce) >= debounceDelay)) {
|
|
debouncing = false;
|
|
};
|
|
// }}}
|
|
if (! debouncing) { // {{{ check for change
|
|
if ( (act_B || act_C || act_A) != somePressed){ // {{{ somePressed changed !
|
|
// {{{ start debouncing
|
|
milsDebounce=currentMillis;
|
|
somePressed=(act_B || act_C || act_A);
|
|
debouncing=true;
|
|
// }}}
|
|
if (act_C) { // act_C if possible
|
|
next_automat = NULL;
|
|
if (automat) automat->stop();
|
|
else {
|
|
if (++c_state >=AUTOMATS) c_state=0;
|
|
automat=blink;
|
|
automat->start();
|
|
responseDelay = automat->pause(state);
|
|
blink->set_count(c_state+1);
|
|
state = 1;
|
|
led_shines = false;
|
|
// Serial.println(c_state); // Serial běží "na pozadí" a bliká LEDkama
|
|
};
|
|
};
|
|
if (act_B) { // act_B if possible
|
|
if (automat && (automat == automats[c_state].B)) automat->restart();
|
|
else {
|
|
if (automat) automat->stop();
|
|
next_automat = automats[c_state].B;
|
|
};
|
|
};
|
|
if (act_A) { // act_A high priority
|
|
if (automat && (automat == automats[c_state].A)) automat->restart();
|
|
else {
|
|
if (automat) automat->stop();
|
|
next_automat = automats[c_state].A;
|
|
};
|
|
};
|
|
}; // }}}
|
|
}; // }}} ! debouncing
|
|
|
|
if ((currentMillis-milsState) >= responseDelay){ // {{{ next state
|
|
milsState = currentMillis; // next step
|
|
if (state == 0) {
|
|
if (automat) automat->stop();
|
|
automat = NULL;
|
|
responseDelay = DEFAULT_DELAY;
|
|
if (next_automat) {
|
|
state = 1;
|
|
automat = next_automat;
|
|
next_automat = NULL;
|
|
automat->start();
|
|
responseDelay = automat->pause(state);
|
|
led_shines = false;
|
|
};
|
|
};
|
|
if (state){
|
|
responseDelay = automat->pause(state);
|
|
state = automat->next(state);
|
|
// Serial.print((long)(void *)automat,HEX);Serial.print(":");
|
|
// Serial.println(state);
|
|
led_shines = !led_shines;
|
|
} else {
|
|
led_shines = false;
|
|
};
|
|
digitalWrite(led,led_shines);
|
|
}; // }}}
|
|
}
|