/* Project: Inclinometer with Arduino 101 and Multi-Function Shield Author: LAGSILVA Revision: V1.2 (Including Temperature) Date: 02.Sep.2018 */ #define SDA_PORT PORTD #define SDA_PIN 5 #define SCL_PORT PORTD #define SCL_PIN 6 #include #include // Module connection pins (Digital Pins) #define LATCH_PIN 4 // Arduino 101 conection on Pin #4 = Latch of Display Module #define CLK_PIN 7 // Arduino 101 conection on Pin #7 = Clock of Display Module #define DATA_PIN 8 // Arduino 101 conection on Pin #8 = Data of Display Module #define BTN_1_PIN A1 #define BTN_2_PIN A2 #define BTN_3_PIN A3 // Front: Upside Down: // A D // ---- ---- // F | | B C | | E // -G - -G - // E | | C B | | F // ---- ---- // D A // // Chars Code {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, = , ||, º, C, F} byte N[] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6, 0x28, 0x12, 0xC6, 0x9C, 0x8E}; int delayRefresh; byte view; unsigned long ti; float AcX, AcY, AcZ, gX, gY, gZ; int uniAngle, dezAngle; int axis, angle, angleX, angleRefX, angleY, angleRefY, temp; boolean axisX, axisY, tempStatus, tCelsius; void setup() { pinMode(LATCH_PIN, OUTPUT); pinMode(CLK_PIN, OUTPUT); pinMode(DATA_PIN, OUTPUT); pinMode(BTN_1_PIN, INPUT); pinMode(BTN_2_PIN, INPUT); pinMode(BTN_3_PIN, INPUT); pinMode(13, OUTPUT); digitalWrite(13, HIGH); CurieTimerOne.start(180000, kbdRead); CurieIMU.begin(); // Set the accelerometer range to 2G CurieIMU.setAccelerometerRange(2); // Set gyro range to 250º/second CurieIMU.setGyroRange(250); view = 0; // Front View (regular view as default) axisX = true; axisY = false; angleRefX = 0; angleRefY = 0; axis = 0; tempStatus = false; tCelsius = true; } void loop() { delayRefresh = 70; CurieIMU.readAccelerometerScaled(AcX, AcY, AcZ); // Read Accelerometers (G = m/s/s) CurieIMU.readGyroScaled(gX, gY, gZ); // Read Gyro (º/s) temp = (CurieIMU.readTemperature() / 512) + 13; // Read the temperature in Celsius degrees (ºC) if (AcX < 0) { view = 0; // Front View (regular view) } if (AcX > 0) { view = 1; // Front View (Upside Down) } angleX = atan(AcX / AcZ) * 180 / PI - angleRefX; angleY = atan(AcY / AcZ) * 180 / PI - angleRefY; if ((abs(gY) > 5) && (abs(gX) < 2) && (axis == 0)) { axisX = true; axisY = false; } if ((abs(gX) > 5) && (abs(gY) < 2) && (axis == 0)) { axisX = false; axisY = true; } if (axisX) { angle = angleX; } if (axisY) { angle = angleY; } uniAngle = abs(int(angle)) % 10; dezAngle = abs(int(angle)) / 10; // Display the Angle (-XXº) or Temperature (ºC / ºF) if (tempStatus == false) { ti = millis(); // Initial time for blinking dot while ((millis() - ti) < delayRefresh) { // Timer in miliseconds to refresh the display if (view == 0) { // Front View mode (1) if (angle < 0) { displayChars(2, view, 0); // Display Minus Signal "-" at Digi 0 } displayChars(N[abs(dezAngle)], view, 1); // Display Digit 1 displayChars(N[abs(uniAngle)], view, 2); // Display Digit 2 if (axisY) { displayChars(N[10], view, 3); // Display Degree Symbol "||" for Y-axis } if (axisX) { displayChars(N[11], view, 3); // Display Degree Symbol "=" for X-axis } } if (view == 1) { // Front Upside Down mode (2) if (angle < 0) { displayChars(2, view, 3); // Display Minus Signal "-" at Digit 3 } displayChars(N[dezAngle], view, 2); // Display Digit 2 displayChars(N[uniAngle], view, 1); // Display Digit 1 if (axisY) { displayChars(N[10], view, 0); // Display Symbol "||" for Y-axis } if (axisX) { displayChars(N[11], view, 0); // Display Symbol "=" for X-axis } } } } if (tempStatus == true) { if (!tCelsius) { // Temperature conversion - Celsius to Fahrenheit temp = temp * 9 / 5 + 32; } ti = millis(); // Initial time for blinking dot while ((millis() - ti) < delayRefresh) { // Timer in miliseconds to refresh the display if (view == 0) { // Front View mode (1) displayChars(N[temp / 10], view, 0); // Display Digit 0 displayChars(N[temp % 10], view, 1); // Display Digit 1 displayChars(N[12], view, 2); // Display Digit 2 - Symbol "º" if (tCelsius) { displayChars(N[13], view, 3); // Display Degree Symbol "C" } else { displayChars(N[14], view, 3); // Display Degree Symbol "F" } } if (view == 1) { // Front View mode (1) displayChars(N[temp / 10], view, 3); // Display Digit 0 displayChars(N[temp % 10], view, 2); // Display Digit 1 displayChars(N[12], view, 1); // Display Digit 2 - Symbol "º" if (tCelsius) { displayChars(N[13], view, 0); // Display Degree Symbol "C" } else { displayChars(N[14], view, 0); // Display Degree Symbol "F" } } } displayChars(0, 1, 0); // Clear Digit 0 displayChars(0, 1, 1); // Clear Digit 1 displayChars(0, 1, 2); // Clear Digit 2 displayChars(0, 1, 3); // Clear Digit 3 } } void displayChars(byte num, byte statusM, byte disp) { // Chars Display Routine if (statusM == 1) { // Front Upside Down num = ((num >> 2) << 5) | ((num >> 5 ) << 2) | (num & 2); } digitalWrite(LATCH_PIN, LOW); shiftOut(DATA_PIN, CLK_PIN, LSBFIRST, ~num); // Display number shiftOut(DATA_PIN, CLK_PIN, LSBFIRST, 128 >> disp); // Set Digit (0-1-2-3) digitalWrite(LATCH_PIN, HIGH); } void kbdRead() { // Push Buttons Reading if (!digitalRead(BTN_1_PIN)) { // Set mode axis = (axis + 1) % 4; if (axis == 0) { // Set mode "auto view" (X & Y axis) tempStatus = false; } if (axis == 1) { // Set mode X-axis only axisX = true; axisY = false; } if (axis == 2) { // Set mode Y-axis only axisX = false; axisY = true; } if (axis == 3) { // Set Temperature mode tempStatus = true; } } if (!digitalRead(BTN_2_PIN) && !tempStatus) { // Set reference for X & Y axis angleRefX = angleX; angleRefY = angleY; } if (!digitalRead(BTN_2_PIN) && tempStatus) { // Set temperature scale (ºC or ºF) in temperature mode tCelsius = !tCelsius; } if (!digitalRead(BTN_3_PIN) && !tempStatus) { // Reset X & Y axis to original values/reference angleRefX = 0; angleRefY = 0; } }