Commands by direction.
This commit is contained in:
358
8By8/8By8.ino
358
8By8/8By8.ino
@@ -21,6 +21,7 @@
|
||||
#define READ_UPDATE 0x80
|
||||
|
||||
#define DEBUG false
|
||||
#define TRACE false
|
||||
|
||||
struct Triple {
|
||||
float x;
|
||||
@@ -34,6 +35,10 @@ private:
|
||||
static volatile byte s_cDataUpdate;
|
||||
|
||||
static void AutoScanSensor() {
|
||||
if (DEBUG) {
|
||||
Serial.println("Autoscan sensor");
|
||||
}
|
||||
|
||||
int iRetry;
|
||||
|
||||
for (int i = 0; i < sizeof(SensorReader::c_uiBaud) /
|
||||
@@ -51,7 +56,7 @@ private:
|
||||
}
|
||||
if (SensorReader::s_cDataUpdate != 0) {
|
||||
Serial.print(SensorReader::c_uiBaud[i]);
|
||||
Serial.print(" baud find sensor\r\n\r\n");
|
||||
Serial.println(" baud find sensor");
|
||||
return;
|
||||
}
|
||||
iRetry--;
|
||||
@@ -94,7 +99,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
static Triple angle, acceleration;
|
||||
static Triple angle, acceleration, gyro;
|
||||
|
||||
static bool init() {
|
||||
WitInit(WIT_PROTOCOL_NORMAL, 0x50);
|
||||
@@ -112,12 +117,12 @@ public:
|
||||
// Serial.println("9600 Baud rate modified successfully");
|
||||
}
|
||||
|
||||
if (WitSetContent(RSW_ANGLE | RSW_ACC) != WIT_HAL_OK) {
|
||||
Serial.println("Set send content: angle, acc Error");
|
||||
if (WitSetContent(RSW_ANGLE | RSW_ACC || RSW_GYRO) != WIT_HAL_OK) {
|
||||
Serial.println("Set send content: angle, acc, and GYRO Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WitSetOutputRate(RRATE_2HZ) != WIT_HAL_OK) {
|
||||
if (WitSetOutputRate(RRATE_5HZ) != WIT_HAL_OK) {
|
||||
Serial.print("Set report rate failed");
|
||||
return false;
|
||||
}
|
||||
@@ -138,8 +143,6 @@ public:
|
||||
sReg[Roll + 2] / 32768.0f * 180.0f; // Unit: deg
|
||||
|
||||
SensorReader::s_cDataUpdate &= ~ANGLE_UPDATE;
|
||||
|
||||
SensorReader::s_cDataUpdate = 0;
|
||||
}
|
||||
|
||||
if (SensorReader::s_cDataUpdate & ACC_UPDATE) {
|
||||
@@ -149,9 +152,23 @@ public:
|
||||
sReg[AX + 1] / 32768.0f * 16.0f * 9.8f;
|
||||
SensorReader::acceleration.z =
|
||||
sReg[AX + 2] / 32768.0f * 16.0f * 9.8f;
|
||||
SensorReader::s_cDataUpdate &= ~ACC_UPDATE;
|
||||
}
|
||||
|
||||
if (SensorReader::s_cDataUpdate & GYRO_UPDATE) {
|
||||
SensorReader::gyro.x = sReg[GX] / 32768.0f * 2000.0f;
|
||||
SensorReader::gyro.y = sReg[GX + 1] / 32768.0f * 2000.0f;
|
||||
SensorReader::gyro.z = sReg[GX + 2] / 32768.0f * 2000.0f;
|
||||
SensorReader::s_cDataUpdate &= GYRO_UPDATE;
|
||||
}
|
||||
|
||||
SensorReader::s_cDataUpdate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static float get_angle_z() {
|
||||
return SensorReader::angle.z;
|
||||
}
|
||||
};
|
||||
|
||||
class Cube {
|
||||
@@ -487,7 +504,7 @@ public:
|
||||
char operator_chars[] = "+-*/^()";
|
||||
int operator_pos = -1;
|
||||
while (true) {
|
||||
if (DEBUG) {
|
||||
if (TRACE) {
|
||||
Serial.println("A");
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
@@ -523,7 +540,7 @@ public:
|
||||
}
|
||||
|
||||
// Find the operator position
|
||||
if (DEBUG) {
|
||||
if (TRACE) {
|
||||
Serial.println("B");
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
@@ -555,7 +572,7 @@ public:
|
||||
}
|
||||
|
||||
// Understand the number and push to stack
|
||||
if (DEBUG) {
|
||||
if (TRACE) {
|
||||
Serial.println("C");
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
@@ -575,7 +592,7 @@ public:
|
||||
}
|
||||
|
||||
// Understand the operator
|
||||
if (DEBUG) {
|
||||
if (TRACE) {
|
||||
Serial.println("D");
|
||||
Serial.print("Read operator: ");
|
||||
Serial.println(current_operator.display());
|
||||
@@ -618,7 +635,7 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
if (TRACE) {
|
||||
Serial.println("E");
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
@@ -640,6 +657,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum Modes {
|
||||
CalculateAndDraw,
|
||||
Cube,
|
||||
Rain,
|
||||
Clock,
|
||||
Words,
|
||||
};
|
||||
|
||||
int Cube::layer_count = 0;
|
||||
int Cube::brightness_count = 0;
|
||||
uint16_t Cube::LED_status[8][8] = {0};
|
||||
@@ -652,14 +677,20 @@ double *Symbol::x_value_ptr, *Symbol::y_value_ptr;
|
||||
const uint32_t SensorReader::c_uiBaud[8] = {0, 4800, 9600, 19200,
|
||||
38400, 57600, 115200, 230400};
|
||||
volatile byte SensorReader::s_cDataUpdate;
|
||||
Triple SensorReader::angle, SensorReader::acceleration;
|
||||
Triple SensorReader::angle, SensorReader::acceleration, SensorReader::gyro;
|
||||
|
||||
double x, y;
|
||||
double symbol_x, symbol_y;
|
||||
const String allowed_chars = "0123456789+-*/^()xy";
|
||||
String input = "";
|
||||
int x_offset = 0, y_offset = 0, z_offset = 0;
|
||||
double zoom = 1.0;
|
||||
float z_ref = 0.0;
|
||||
bool waiting_for_command = true;
|
||||
|
||||
int current_mode = 0;
|
||||
|
||||
byte cube_size = 1;
|
||||
byte cube_step = 1;
|
||||
|
||||
void setup() {
|
||||
for (int i = 22; i < 46; i++) {
|
||||
@@ -674,21 +705,32 @@ void setup() {
|
||||
Timer1.setPeriod(TIME_PER_LAYER_IN_US);
|
||||
|
||||
Serial.begin(9600);
|
||||
Symbol::x_value_ptr = &x;
|
||||
Symbol::y_value_ptr = &y;
|
||||
|
||||
if (DEBUG) {
|
||||
Serial.println("Into setup");
|
||||
}
|
||||
|
||||
Symbol::x_value_ptr = &symbol_x;
|
||||
Symbol::y_value_ptr = &symbol_y;
|
||||
|
||||
if (!SensorReader::init()) {
|
||||
Serial.println("Initialize sensor failed.");
|
||||
}
|
||||
else {
|
||||
if (DEBUG) {
|
||||
Serial.println("Initialize sensor success.");
|
||||
}
|
||||
}
|
||||
|
||||
Timer1.attachInterrupt(Cube::display);
|
||||
|
||||
cli();
|
||||
// timer 4 is for blinking
|
||||
TCCR4A = 0; // set entire TCCR1A register to 0
|
||||
TCCR4B = 0; // same for TCCR1B
|
||||
TCNT4 = 0; // initialize counter value to 0
|
||||
// set compare match register for 1hz increments
|
||||
OCR4A = 7812 / 1; // = (16*10^6) / (1*1024) - 1 (must be <65536)
|
||||
OCR4A = 6500 / 1; // = (16*10^6) / (1*1024) - 1 (must be <65536)
|
||||
// 15625 = 1 sec
|
||||
// turn on CTC mode
|
||||
TCCR4B |= (1 << WGM12);
|
||||
@@ -697,78 +739,214 @@ void setup() {
|
||||
// enable timer compare interrupt
|
||||
TIMSK4 |= (1 << OCIE4A);
|
||||
|
||||
// timer 5 is for read sensor data
|
||||
TCCR5A = 0;
|
||||
TCCR5B = 0;
|
||||
TCNT5 = 0;
|
||||
OCR5A = 10000 / 1;
|
||||
OCR5A = 3125 / 1;
|
||||
TCCR5B |= (1 << WGM12);
|
||||
TCCR5B |= (1 << CS12) | (1 << CS10);
|
||||
TIMSK5 |= (1 << OCIE5A);
|
||||
sei();
|
||||
|
||||
// Wait for z_ref to have value;
|
||||
delay(500);
|
||||
while (SensorReader::get_angle_z() == 0.0) {
|
||||
Serial.print("");
|
||||
continue;
|
||||
}
|
||||
|
||||
z_ref = SensorReader::angle.z;
|
||||
if (DEBUG) {
|
||||
Serial.print("Z_ref: ");
|
||||
Serial.println(z_ref);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
for (int k = 0; k < 8; k++) {
|
||||
Cube::set_status(i, j, k, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delay(5000);
|
||||
Cube::clear();
|
||||
|
||||
Serial.println("Setup complete.");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print("Zref: ");
|
||||
Serial.println(z_ref);
|
||||
switch (current_mode) {
|
||||
case Modes::CalculateAndDraw:
|
||||
calculate_and_draw();
|
||||
break;
|
||||
case Modes::Clock:
|
||||
clock();
|
||||
break;
|
||||
case Modes::Cube:
|
||||
cube();
|
||||
break;
|
||||
case Modes::Rain:
|
||||
rain();
|
||||
break;
|
||||
case Modes::Words:
|
||||
words();
|
||||
break;
|
||||
default:
|
||||
current_mode = Modes::Rain;
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("Input expression");
|
||||
while (true) {
|
||||
if (Serial.available()) {
|
||||
byte input_char = Serial.read();
|
||||
// Serial.print("Pos: ");
|
||||
// Serial.println(allowed_chars.indexOf(input_char));
|
||||
if (allowed_chars.indexOf(input_char) != -1) {
|
||||
input.concat((char)input_char);
|
||||
// Serial.print("String: ");
|
||||
// Serial.println(input);
|
||||
continue;
|
||||
}
|
||||
ISR(TIMER4_COMPA_vect) {
|
||||
Cube::do_blinking();
|
||||
}
|
||||
|
||||
if (input_char == 0x3) {
|
||||
break;
|
||||
}
|
||||
ISR(TIMER5_COMPA_vect) {
|
||||
SensorReader::read_data_from_sensor_interrupt();
|
||||
}
|
||||
|
||||
if (input_char == 0x4) {
|
||||
input = "";
|
||||
Serial.println("Clear input string");
|
||||
}
|
||||
void cube() {
|
||||
Cube::clear();
|
||||
Cube::draw_line(3 - cube_size, 3 - cube_size, 3 - cube_size,
|
||||
2 * cube_size + 2, 0, 3);
|
||||
Cube::draw_line(3 - cube_size, 4 + cube_size, 3 - cube_size,
|
||||
2 * cube_size + 2, 0, 3);
|
||||
Cube::draw_line(3 - cube_size, 3 - cube_size, 4 + cube_size,
|
||||
2 * cube_size + 2, 0, 3);
|
||||
Cube::draw_line(3 - cube_size, 4 + cube_size, 4 + cube_size,
|
||||
2 * cube_size + 2, 0, 3);
|
||||
|
||||
Cube::draw_line(3 - cube_size, 3 - cube_size, 3 - cube_size,
|
||||
2 * cube_size + 2, 1, 3);
|
||||
Cube::draw_line(4 + cube_size, 3 - cube_size, 3 - cube_size,
|
||||
2 * cube_size + 2, 1, 3);
|
||||
Cube::draw_line(3 - cube_size, 3 - cube_size, 4 + cube_size,
|
||||
2 * cube_size + 2, 1, 3);
|
||||
Cube::draw_line(4 + cube_size, 3 - cube_size, 4 + cube_size,
|
||||
2 * cube_size + 2, 1, 3);
|
||||
|
||||
Cube::draw_line(3 - cube_size, 3 - cube_size, 3 - cube_size,
|
||||
2 * cube_size + 2, 2, 3);
|
||||
Cube::draw_line(3 - cube_size, 4 + cube_size, 3 - cube_size,
|
||||
2 * cube_size + 2, 2, 3);
|
||||
Cube::draw_line(4 + cube_size, 3 - cube_size, 3 - cube_size,
|
||||
2 * cube_size + 2, 2, 3);
|
||||
Cube::draw_line(4 + cube_size, 4 + cube_size, 3 - cube_size,
|
||||
2 * cube_size + 2, 2, 3);
|
||||
|
||||
delay(50);
|
||||
cube_size += cube_step;
|
||||
if (cube_size >= 3) {
|
||||
cube_step = -1;
|
||||
}
|
||||
else if (cube_size <= 0) {
|
||||
cube_step = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void rain() {
|
||||
return;
|
||||
}
|
||||
|
||||
void clock() {
|
||||
return;
|
||||
}
|
||||
|
||||
void words() {
|
||||
return;
|
||||
}
|
||||
|
||||
void calculate_and_draw() {
|
||||
bool need_reevaluate = false;
|
||||
|
||||
if (Serial.available()) {
|
||||
if (DEBUG) {
|
||||
Serial.println(input);
|
||||
}
|
||||
byte input_char = Serial.read();
|
||||
// Serial.print("Pos: ");
|
||||
// Serial.println(allowed_chars.indexOf(input_char));
|
||||
if (allowed_chars.indexOf(input_char) != -1) {
|
||||
input.concat((char)input_char);
|
||||
// Serial.print("String: ");
|
||||
// Serial.println(input);
|
||||
}
|
||||
|
||||
if (input_char == '=') {
|
||||
need_reevaluate = true;
|
||||
}
|
||||
|
||||
if (input_char == 'c') {
|
||||
input = "";
|
||||
Serial.println("Cleared input string.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (input_char == 'h') {
|
||||
Serial.print("Current expression: ");
|
||||
if (input.length() == 0) {
|
||||
Serial.println("(none)");
|
||||
}
|
||||
else {
|
||||
Serial.println(input);
|
||||
}
|
||||
Serial.println("Use c to clear input.");
|
||||
}
|
||||
// Prioritize user input.
|
||||
}
|
||||
|
||||
if (waiting_for_command) {
|
||||
if (SensorReader::angle.x > 40.0) {
|
||||
Serial.println("a");
|
||||
if (DEBUG) {
|
||||
Serial.println("a");
|
||||
}
|
||||
y_offset += 1;
|
||||
break;
|
||||
need_reevaluate = true;
|
||||
waiting_for_command = false;
|
||||
}
|
||||
else if (SensorReader::angle.x < -40.0) {
|
||||
Serial.println("b");
|
||||
if (DEBUG) {
|
||||
Serial.println("b");
|
||||
}
|
||||
y_offset -= 1;
|
||||
break;
|
||||
need_reevaluate = true;
|
||||
waiting_for_command = false;
|
||||
}
|
||||
|
||||
if (SensorReader::angle.y > 40.0) {
|
||||
Serial.println("c");
|
||||
if (DEBUG) {
|
||||
Serial.println("c");
|
||||
}
|
||||
x_offset -= 1;
|
||||
break;
|
||||
need_reevaluate = true;
|
||||
waiting_for_command = false;
|
||||
}
|
||||
else if (SensorReader::angle.y < -40.0) {
|
||||
Serial.println("d");
|
||||
if (DEBUG) {
|
||||
Serial.println("d");
|
||||
}
|
||||
x_offset += 1;
|
||||
break;
|
||||
need_reevaluate = true;
|
||||
waiting_for_command = false;
|
||||
}
|
||||
|
||||
if (SensorReader::angle.z - z_ref > 40.0) {
|
||||
Serial.println("e");
|
||||
if (DEBUG) {
|
||||
Serial.println(SensorReader::angle.z);
|
||||
Serial.println("e");
|
||||
}
|
||||
zoom /= 2.0;
|
||||
break;
|
||||
need_reevaluate = true;
|
||||
waiting_for_command = false;
|
||||
}
|
||||
else if (SensorReader::angle.z - z_ref < -40.0) {
|
||||
Serial.println(SensorReader::angle.z);
|
||||
Serial.println("f");
|
||||
if (DEBUG) {
|
||||
Serial.println(SensorReader::angle.z);
|
||||
Serial.println("f");
|
||||
}
|
||||
zoom *= 2.0;
|
||||
break;
|
||||
need_reevaluate = true;
|
||||
waiting_for_command = false;
|
||||
}
|
||||
|
||||
if (abs(SensorReader::acceleration.x) +
|
||||
@@ -779,28 +957,66 @@ void loop() {
|
||||
y_offset = 0;
|
||||
z_offset = 0;
|
||||
zoom = 1;
|
||||
Serial.println("Reset zoom and translate.");
|
||||
need_reevaluate = true;
|
||||
waiting_for_command = false;
|
||||
}
|
||||
|
||||
if (abs(SensorReader::gyro.x) + abs(SensorReader::gyro.y) +
|
||||
abs(SensorReader::gyro.z) >
|
||||
240) {
|
||||
x_offset = 0;
|
||||
y_offset = 0;
|
||||
z_offset = 0;
|
||||
zoom = 1;
|
||||
Serial.println("Reset zoom and translate.");
|
||||
need_reevaluate = true;
|
||||
waiting_for_command = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (DEBUG) {
|
||||
Serial.print(SensorReader::angle.x);
|
||||
Serial.print(" ");
|
||||
Serial.print(SensorReader::angle.y);
|
||||
Serial.print(" ");
|
||||
Serial.println(SensorReader::angle.z);
|
||||
}
|
||||
|
||||
if (abs(SensorReader::angle.x) < 30.0 &&
|
||||
abs(SensorReader::angle.y) < 30.0 &&
|
||||
abs(SensorReader::angle.z - z_ref) < 30.0) {
|
||||
waiting_for_command = true;
|
||||
Serial.println("Waiting for new command");
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("Read: ");
|
||||
if (!need_reevaluate) {
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Expression to be evaluated: ");
|
||||
Serial.println(input);
|
||||
|
||||
Serial.print("Offset: ");
|
||||
Serial.print(x_offset);
|
||||
Serial.print(" ");
|
||||
Serial.print(y_offset);
|
||||
Serial.print(" ");
|
||||
Serial.println(z_offset);
|
||||
Serial.print("Zoom: ");
|
||||
Serial.println(zoom);
|
||||
if (DEBUG) {
|
||||
Serial.print("Offset: ");
|
||||
Serial.print(x_offset);
|
||||
Serial.print(" ");
|
||||
Serial.print(y_offset);
|
||||
Serial.print(" ");
|
||||
Serial.println(z_offset);
|
||||
Serial.print("Zoom: ");
|
||||
Serial.println(zoom);
|
||||
}
|
||||
|
||||
Calculator calculator(input);
|
||||
|
||||
Cube::clear();
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
x = (i + x_offset) * zoom;
|
||||
y = (j + y_offset) * zoom;
|
||||
symbol_x = (i + x_offset) * zoom;
|
||||
symbol_y = (j + y_offset) * zoom;
|
||||
double result = calculator.evaluate();
|
||||
int z;
|
||||
if (!(isinf(result) || isnan(result))) {
|
||||
@@ -824,18 +1040,4 @@ void loop() {
|
||||
round(-z_offset));
|
||||
}
|
||||
}
|
||||
|
||||
// delay(1000);
|
||||
|
||||
// int z = round(calculator.evaluate());
|
||||
// Serial.println(z);
|
||||
// Serial.print("Here");
|
||||
}
|
||||
|
||||
ISR(TIMER4_COMPA_vect) {
|
||||
Cube::do_blinking();
|
||||
}
|
||||
|
||||
ISR(TIMER5_COMPA_vect) {
|
||||
SensorReader::read_data_from_sensor_interrupt();
|
||||
}
|
||||
Reference in New Issue
Block a user