From 3ec8c3d57057210065dfc064c9db2278459e2c2d Mon Sep 17 00:00:00 2001 From: unlockable Date: Fri, 8 Sep 2023 17:35:49 +0800 Subject: [PATCH] Commands by direction. --- 8By8/8By8.ino | 358 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 280 insertions(+), 78 deletions(-) diff --git a/8By8/8By8.ino b/8By8/8By8.ino index f39a134..bebdf51 100644 --- a/8By8/8By8.ino +++ b/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(); } \ No newline at end of file