Hello, I have been working on a code over the past week, where the Arduino would be using the onboard 9-axis IMU chip to approximate rotation. The code I have is working properly and will do the appropriate slowing whenever it reaches an angle threshold. The problem I am having, is that the servos are not even attempting to move. I know the BLE Sense uses 3.3 V on its output so I am powering the Servos using a separate power source where the ground is connected to the Arduino board. I really need the servos to move as that is the whole point of the code.
Below is the code. I have had to use the outdated board config in the code, because the new board config, does not work servo library with its MBed_nano architecture.
Code:
/*-----------------------------------------------------------------------------------------------------
// Creator: Zachary D. Arnold
// Date Made: May 10, 2021
// Date Edited: May 11, 2021
// Modified By: Zachary D. Arnold
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
// Purpose: Creating a failsafe protocal for parachute deployment system on ENES 100 Bottle Rockets
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
// Board: Arduino Nano 33 BLE Sense
// Board in Code: Arduino Nano 33 BLE (from arduino MBed OS Boards)
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//Required materials for correct setup:
// 1)Ardunino Nano 33 BLE/Ardunino Nano 33 BLE Sense (or any ardunino board with attachments for
// gyroscope [gyroscope needs to be a minimum of 3 axis {see commented code 2 for this use}])
// 2)2 Micro servo motors. (Can uses at smallest SG90's)
// 3)7 Male-to-female jumper cables. (If using boards with male headers [4 male-to-female when not
// using Nano 33 BLE board.])
// 4)1 Mini breadboard
// 5)6 Male-to-male jumper cables. (If using boards with male headers [12 male-to-male when not
// using Nano 33 BLE board.])
// 6)1 9V Battery. (Dependent on the board setup)
// 7)1 RGB LED
// 8)3 220 Ohm Resistors
// 9)1 Power Supply Board with Supplied Case
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
// Section 1
//-----------------------------------------------------------------------------------------------------
// Use: Creates a section where constant variables are defined and where required libraries are added.
//-----------------------------------------------------------------------------------------------------
*/
#include <Arduino_LSM9DS1.h>
//Includes a library which the arduino can use to access sensor data.
#include <Servo.h>
//Includes a library which the arduino can use to control motor outputs.
#define BLUE 2
//Creates a definition for a term that has a number connected to it.
#define GREEN 3
//Creates a definition for a term that has a number connected to it.
#define RED 4
//Creates a definition for a term that has a number connected to it.
float xa,ya,za,x,y,z;
//Creates variables that the code can reference later.
//These variables have a decimal point that "floats", which means that the variable has precision of
//6 to 7 digits. (This is not just to the right of the decimal, but in both directions.)
//Good for small numbers that will contain decimals.
//Also good for making pointers.
int n;
//Creates a variable that the code can reference later.
//This variable has only the integer. This means that no rounding or spproximation is made.
//Good for only numbers that will not ever contain decimals.
Servo servo1;
//Creates a servo motor for the code.
Servo servo2;
//Creates a servo motor for the code.
/*
//-----------------------------------------------------------------------------------------------------
// Section 2
//-----------------------------------------------------------------------------------------------------
// Use: Creates a section where sensors can be initialized. This "loop" will only run once.
//-----------------------------------------------------------------------------------------------------
*/
void setup() {
//The use of the term "void" tells the code to neglect any output that is not determined inside the
//loop.
Serial.begin(9600);
//Starts the
servo1.attach(9);
//Tells the arduino what digital pin the servo motor is attached to.
servo2.attach(9);
//Tells the arduino what digital pin the servo motor is attached to.
servo1.write(90);
//Gives a command to the servo motor, which will act as the base position for this script.
servo2.write(90);
//Gives a command to the servo motor, which will act as the base position for this script.
pinMode(RED, OUTPUT);
//Set the term "RED" to a pin, that is determined to be an output.
pinMode(GREEN, OUTPUT);
//Set the term "GREEN" to a pin, that is determined to be an output.
pinMode(BLUE, OUTPUT);
//Set the term "BLUE" to a pin, that is determined to be an output.
digitalWrite(RED, LOW);
//Tells the value of the pin connected to the term "Red".
//The use of "HIGH" acts like a one, where as "LOW" is a zero.
digitalWrite(GREEN, LOW);
//Tells the value of the pin connected to the term "GREEN".
//The use of "HIGH" acts like a one, where as "LOW" is a zero.
digitalWrite(BLUE, HIGH);
//Tells the value of the pin connected to the term "BLUE".
//The use of "HIGH" acts like a one, where as "LOW" is a zero.
n = 1;
//Defines a value for the constant "n".
//This is a 1 so we can start the loop below.
if (!IMU.begin()) {
//This type of statement is used to determine if the condition is true or false.
//The condition for this loop is defined inside the parentheses.
//The use of "!" says that the statement is not occuring.
Serial.println("Failed to initialize IMU!");
//The use of "Serial", opens communication between a device and the arduino.
//The use of "println", returns the number of bytes written.
//The use of parentheses tells the "println" function where to look and the quotation
//marks determine the use of characters.
digitalWrite(BLUE, LOW);
//Tells the value of the pin connected to the term "BLUE".
digitalWrite(GREEN, LOW);
//Tells the value of the pin connected to the term "GREEN".
digitalWrite(RED, HIGH);
//Tells the value of the pin connected to the term "Red".
while (1);
//Creates a while loop. This type of loop will continue to run while the condition
//inside the parentheses is true.
}
while(!Serial);{
//Creates a while loop. This type of loop will continue to run while the condition
//inside the parentheses is true.
//The use of "!" says that the statement is not occuring.
Serial.println("Started");
//Prints the term "Started once the loop has begun."
}
}
/*
//-----------------------------------------------------------------------------------------------------
// Section 3
//-----------------------------------------------------------------------------------------------------
// Use: Creates a section where the main script runs. This code will continue until it is told to exit.
//-----------------------------------------------------------------------------------------------------
*/
void loop() {
//The use of the term "void" tells the code to neglect any output that is not determined inside the
//loop.
while (n == 1){
//Creates a while loop. This type of loop will continue to run while the condition
//inside the parentheses is true.
// LED Color:
digitalWrite(BLUE, LOW);
//Tells the value of the pin connected to the term "BLUE".
digitalWrite(RED, LOW);
//Tells the value of the pin connected to the term "Red".
digitalWrite(GREEN, HIGH);
//Tells the value of the pin connected to the term "GREEN".
//Angle Finding:
if(IMU.accelerationAvailable()){
//This type of statement is used to determine if the condition is true or false.
//The condition for this loop is defined inside the parentheses.
IMU.readAcceleration(xa,ya,za);
//Tells the code what variables to attach the values read to.
//These values are then attached to the variables for each run of the loop.
//Each new iteration of the loop, overwrites the previous value.
x = RAD_TO_DEG * (atan2(-ya,-za) + PI);
//Uses trig functions to convert the radian values into degree values.
//The trig function used is arctan. This is used by the term "atan2".
//The "atan" tells what type of trig function is being used.
//The "2" tells how many variables or terms are being defined by it.
//The term "RAD_TO_DEG" is a constant defined inside the arduino coding.
y = RAD_TO_DEG * (atan2(-xa,-za) + PI);
//Uses trig functions to convert the radian values into degree values.
//The trig function used is arctan. This is used by the term "atan2".
//The "atan" tells what type of trig function is being used.
//The "2" tells how many variables or terms are being defined by it.
//The term "RAD_TO_DEG" is a constant defined inside the arduino coding.
z = RAD_TO_DEG * (atan2(-ya,-xa) + PI);
//Uses trig functions to convert the radian values into degree values.
//The trig function used is arctan. This is used by the term "atan2".
//The "atan" tells what type of trig function is being used.
//The "2" tells how many variables or terms are being defined by it.
//The term "RAD_TO_DEG" is a constant defined inside the arduino coding.
//Logic Statements:
if (x >= 80 && x <= 280){
//This type of statement is used to determine if the condition is true or false.
//The condition for this loop is defined inside the parentheses.
//The use of the operator ">=" states greater than or equal to.
//The use of the operator "<=" states less than or equal to.
//The use of the logic term "&&" states both definition must be met to be true.
servo1.write(45);
//Moves the servo by giving it directions to change its position.
servo2.write(45);
//Moves the servo by giving it directions to change its position.
delay (1000);
//Makes a time (in milliseconds) the the code must wait until continuing.
}
else if (y >= 80 && y <= 280){
//This type of statement is used to determine another case of "if".
//The condition for this loop is defined inside the parentheses.
//The use of the operator ">=" states greater than or equal to.
//The use of the operator "<=" states less than or equal to.
//The use of the logic term "&&" states both definition must be met to be true.
servo1.write(45);
//Moves the servo by giving it directions to change its position.
servo2.write(45);
//Moves the servo by giving it directions to change its position.
delay (1000);
//Makes a time (in milliseconds) the the code must wait until continuing.
}
if ((servo1.read() == 45)||(servo2.read() == 45)){
//This type of statement is used to determine if the condition is true or false.
//The condition for this loop is defined inside the parentheses.
//The use of the logic term "||" states either definitions must be met to be true.
n = 0;
//Redefines the value of n. This is done to exit the while loop.
//LED Color:
digitalWrite(BLUE, LOW);
//Tells the value of the pin connected to the term "BLUE".
digitalWrite(GREEN, LOW);
//Tells the value of the pin connected to the term "GREEN".
digitalWrite(RED, HIGH);
//Tells the value of the pin connected to the term "Red".
}
else{
//This type of statement is used to determine all other possiblities when the "if"
//statement is false.
//By default, even if "else" is false. The code will view it as true, if all other "if"
//statements are also false.
n = 1;
//Redefines the value of n. This is done so the loop can continue.
}
//Prints angles:
Serial.print("Angle X = ");
//Prints the terms.
Serial.println(x);
//Prints the value of the variable.
Serial.print("Angle Y = ");
//Prints the terms.
Serial.println(y);
//Prints the value of the variable.
Serial.print("Angle Z = ");
//Prints the terms.
Serial.println(z);
//Prints the value of the variable.
Serial.println("---------------------------------------------------");
//Prints a devisor line for each iteration of the loop.
delay(3);
//Gives a small time delay so data can somewhat be monitered, while the loop is running.
}
}
}
/*
//-----------------------------------------------------------------------------------------------------
// Section 4
//-----------------------------------------------------------------------------------------------------
// Use: Creates a section for extra comments.
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//The use of these three buttons together will display a window where outputs can be seen as data:
// SHIFT + CTRL + M
//The use of these three buttons together will display a window where outputs can be seen as a graph:
// SHIFT + CTRL + L
*/
/*
//-----------------------------------------------------------------------------------------------------
// Section 5
//-----------------------------------------------------------------------------------------------------
// Use: Creates a section for conclusions.
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
//The use of this code should allow for the students bottle rocket projects to become safer for the
//students envolved while also increasing the safety for students in close proximity. This code also
//allows first year engineering students to experience arduino coding, and have a basic introduction
//into C++. This will aid these students throughout the rest of their engineering pathway. This also
//aids any students acquiring GEP requirements, by experiencing first hand the use of automation.
*/