Hey guys
I hope you are doing well? I might need some help in coding
Intro:
I designed in CAD and built with my 3D printer a pretty cool Nerf Sentry. Since I'm a mechanical engineer the mechanical and also the electrical design of the thing was "easy" but now with the coding of the Arduino I'm a bit confused and clueless, since it is my first big Arduino project.
Here are some pictures and Hardware setup
*Since new in this forum, I'm allowed to post only one picture *
Hardware Setup:
The Hardware itself functions as it should. With Arduino example sketches I can move all the motors, steppers and Servos.
The only thing there is, that once I'm not working with MICROSTEP
the Steppers are rattling quiet loud.
Questions & UPDATE: See Reply: Things work now
This code was snipped together from different sources and example sketches. II tried to format and comment it very clearly. I hope you get my attempt of using millis() and calling the functions for simultaneous operation. My biggest problem right now is that I'm confused using steppers with this motorshield and how I implemented them with AccelStepper.h:
-->See Code with function description in the beginning
- So in Function
void shoot ()
the Stepper1 should move a determined amount of steps forward... but rightnow nothing happens.
1.1) Also thisdelay()
should not be used in the code.
So what can I use to get this behavior:
- Once the Joystick Button is pushed, the DC Motors are powered on, the StepperMotor (Stepper1) moves X steps and the DC Motors are powered off again. (Repeat this once the button is pushed again after a determined break time)
-
In function
void moveXSentry()
the Stepper (Stepper2) should move according to the Joystick input in a defined space. Rightnow nothing happens again
How can I set this function right? -
The
void idle()
function is not done jet: Basically the turret should stop moving once all darts are fired. How can I setup something like this?
Is there a possibility to actually switch to an Input from lets say a 2nd jostick?
Well that's it for the beginning. I think it's not a big issue, just dump code I copied together.
Let me know I I can provide more information.
Cheers NTC
Code
Here is my code with a functional description in the beginning:
// V3.0 Sentry Code
// this sketch does the following:
// 1) Function: void shoot()
// When Jostick Button is pushed;
// - it turns on two DC Motors by switching on a NO relais module for a short time (<1s)
// - it simoultaneously moves a Stepper motor (STM1) a determined amount of steps FORWARD
// - it counts down the amount of darts left (18 darts in total)
// --> A spring which is tensioned by the STM1 pushes a FoamDart into the two DC Motors and shoots out
// --> The Jostick button has a delay (buttonInterval) so that it is not possible to shoot rappidly
// 2) Function: void moveYSentry ()
// - it detects Y Input of a jostick on A2
// - it controls the position of SERVO01 and so the pitch axis of the sentry
// --> If jostick is neutral the sentry moves back on 90° Position (0-180°)
//
// 3) Function: void moveXSentry ()
// - it detects X Input of a jostick on A1
// - it controls a Stepper Motor (STM2) and so the yaw axis of the sentry
// --> The sentry should not be allowed to turn 360° since cabling issues
// --> Amount of RotarySteps should define movement boundaries (f.e. (MaxLeft 0 ... 2500 middle...5000 MaxRight)
//
// 4) Function: void idle ()
// - Once all darts ar fired the sentry should not mover or shoot anymore
//
// --> For simultaneous operation of all the functions millis(); is used
//========================================
// ----------LIBRARIES--------------
#include <Wire.h>
#include <Servo.h>
#include <Adafruit_MotorShield.h>
#include <AccelStepper.h>
#include <utility/Adafruit_MS_PWMServoDriver.h>
// --------CONNECTIONS---------------
const int MotorPin = 7; // Motor Relais Pin
const int SERVO1Pin = 9; // Pitch Servo2 slot Pin 10
const int JoyStick_B = 3; // D3 Joystick Button Pin
const int JoyStick_X = 1; // A1 Jostick Input - pitch Axis = Up (0) - Center (507..08) - Down (1023)
const int JoyStick_Y = 2; // A2 Jostick Input - Yaw Axis = Left (1023) - Center (508..509) - Right (0)
// --------CONSTANTS---------------
const int buttonInterval = 500; // number of millisecs between button readings
const int JostickSignalDelay = 150; // Delay in ms for stability (needed?)
const int servoPositionS1 = 90; // the current angle of the servo - starting at 90.
//------------ VARIABLES---------------------
int x_NS;
int y_NS;
int stateB_NS = 0; // State Yostick Button
int rotarysteps = 2500; //Amonunt of steps for Yaw-Axis
int ammunition = 18; // Total of 18 darts
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousButtonMillis = 0; // time when button press last checked
unsigned long previousServoMillis = 0; // the time when the servo was last moved
unsigned long previousJoystickMillis = 0; // the time when the Joystick move was last checked
//------------ OBJECTS---------------------
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); // Create the motor shield object with the default I2C address
Servo SERVO1; // Pitch Servo created
//------------ STEPPER SETUP---------------
// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #1 (M1 and M2) or #2 (M3 and M4)
Adafruit_StepperMotor *STM1 = AFMS.getStepper(200, 1); // MagazineMover
Adafruit_StepperMotor *STM2 = AFMS.getStepper(200, 2); // Turn Sentry
// wrappers for the first motor
void forwardstep1() {
STM1->onestep(FORWARD, MICROSTEP);
}
void backwardstep1() {
STM1->onestep(BACKWARD, MICROSTEP);
}
// wrappers for the second motor
void forwardstep2() {
STM2->onestep(FORWARD, MICROSTEP);
}
void backwardstep2() {
STM2->onestep(BACKWARD, MICROSTEP);
}
// Now we'll wrap the 2 steppers in an AccelStepper object
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);
//========================================
//------------ VOID SETUP ---------------------------------------------------------
void setup() {
Serial.begin(9600);
Serial.println("Starting V3_NerfSentry_1.ino");
SERVO1.attach(SERVO1Pin);
SERVO1.write(servoPositionS1); // sets the initial position
AFMS.begin();
//Magazine Mover
stepper1.setMaxSpeed(2000.0);
stepper1.setSpeed(500.0);
//Turred Mover
stepper2.setMaxSpeed(3000.0);
stepper2.setAcceleration(750.0);
pinMode(MotorPin, OUTPUT); // Set Pinmode for Relais Pin 9
digitalWrite(MotorPin, LOW); // Turns DC-Motors off in the beginning
}
//------------ VOID LOOP ---------------------------------------------------
void loop() {
// Notice that none of the action happens in loop() apart from reading millis()
// it just calls the functions that have the action code
currentMillis = millis(); // capture the latest value of millis()
// this is equivalent to noting the time from a clock
// use the same time for all LED flashes to keep them synchronized
readJoystick();
moveXSentry();
moveYSentry();
shoot();
idle();
}
//------------FUNCTIONS---------------------------------------------------------
void readJoystick() {
if (currentMillis - previousJoystickMillis >= JostickSignalDelay) {
x_NS = analogRead(JoyStick_X);
y_NS = analogRead(JoyStick_Y);
stateB_NS = digitalRead(JoyStick_B);
Serial.print(x_NS , DEC);
Serial.print(",");
Serial.print(y_NS , DEC);
Serial.print(",");
Serial.println(stateB_NS , DEC);
previousJoystickMillis += JostickSignalDelay;
}
}
//========================================
// - Move ROTATION Sentry function
void moveXSentry() {
if (analogRead(JoyStick_X) >= 550 && rotarysteps == 5000) { // If Jostick is moved left
stepper2.setSpeed(50);
stepper2.runSpeed();
rotarysteps++;
}
if (analogRead(JoyStick_X) <= 500 && rotarysteps == 0) { // If Jostick is moved lef
stepper2.setSpeed(-50);
stepper2.runSpeed();
rotarysteps--;
}
}
//========================================
// - Move Pitch Sentry function
void moveYSentry() {
y_NS = analogRead(JoyStick_Y); // UP-Down reads the value of the potentiometer (value between 0 and 1023)
y_NS = map(y_NS, 0, 1023, 180, 0); // scale it to use it with the servo (value between 0 and 180)
SERVO1.write(y_NS); // sets the servo position according to the scaled value
}
//========================================
// - Shoot function
void shoot() {
// this only reads the button state after the button interval has elapsed
// this avoids multiple shots if the button bounces
stateB_NS = digitalRead(JoyStick_B);
if (millis() - previousButtonMillis >= buttonInterval) {
if (stateB_NS == HIGH) {
digitalWrite(MotorPin, HIGH);
stepper1.setCurrentPosition((long) 500) //Amount of steps the motor needs to move forward
delay (1000);
digitalWrite(MotorPin, LOW);
ammunition--;
}
previousButtonMillis += buttonInterval;
}
}
//========================================
// - EmptyMagazine function
void idle() {
if (ammunition == 0) { // If no darts left,
// Jostick not operating anymore
}
}
//========================================END===============================