Hello all
I have what I thought was a basic project that has ballooned beyond my very basic coding skills. I could use a second set of eyes and some pointers.
I have the code working for all but one task, the stepper motor. Here’s the complete timeline of what I would like to happen.
- Arduino Uno lies in wait until a button is pushed
- Arduino triggers relays to supply 12v to various things
- LED light countdown with MP3 Beeps. This works even though I used Delay, cant’ get Millis to work.
- After the LED function ends I need the Arduino to fire up the 12v motor on an L289n controller. This works.
- Now it monitors an input to count the laps (reed switch under track) and shuts off after 4 laps. this works.
Here’s the kicker. The 12v motor needs 1 second to spin up and gain momentum before a car can go through. So, I have a stepper motor on an arm that can push the car forward into the rollers. I can make the stepper move but not how I want. I also have a limiting switch on the stepper, but can’t make that work either.
Ideally, the 12v motor would spin up for a second, then the stepper would do one full 360 and end back where it started. This may or may not need that limiting switch as I only added it in case, but if it’s just doing a full 350 every time maybe not. I figured since I’m counting the laps already I could just say “if # of laps = zero then rotate the stepper, if more than 0 don’t” but it still constantly spins.
After I trigger 4 laps the code does a little cleanup and resets everything for the next time the button is pressed. I just cant figure out how to control the stepper and time it correctly with the firing off of the 12v motor. Any tips? Here’s my horrid code:
//=======
// -----LIBRARIES
#include <SoftwareSerial.h>
#include <Stepper.h>
// ----CONSTANTS (won't change)
const int RLED = 8; //map pins
const int YLED1 = 10;
const int YLED2 = 7;
const int GLED = 9;
const int BUTTON = 4;
const int STEPSW = 13;
const int LANE1PWM = 5; //motors
const int LANE11 = A3;
const int LANE12 = A2;
const int LANE1SW = A4;
const int RELAY1 = 2;
const int RELAY2 = 3;
const int Lapinterval = 300; // number of millisecs between button readings
// Number of steps per internal motor revolution
const float STEPS_PER_REV = 32;
// Amount of Gear Reduction
const float GEAR_RED = 64;
// Number of steps per geared output rotation
const float STEPS_PER_OUT_REV = STEPS_PER_REV * GEAR_RED;
// Number of Steps Require
unsigned long previousMillis = 0;
// Create Instance of Stepper Class
// Specify Pins used for motor coils
// Connected to ULN2003 Motor Driver In1, In2, In3, In4
// Pins entered in sequence 1-3-2-4 for proper step sequencing
Stepper steppermotor(STEPS_PER_REV, 6, A0, A1, A5);
//------- VARIABLES (will change)
boolean LEDOFF = false;
boolean LANE1OFF = false;
int StepperSwitch = HIGH;
int MainButtonState = HIGH;
int LastMainButtonState = HIGH;
int buttonPushCounter1 = 0; // counter for the number of reed 1 presses
int buttonState1 = HIGH; // current state of reed 1
int lastButtonState1 = LOW; // previous state of reed 1
int CurrentStep = 0;
int PrevStep = 0;
int Car1Running = 0;
int SPEED = 100; // ADJUST SPEED HERE
//MP3 Stuff ======================================================================================
#define ARDUINO_RX 12 //should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 11 //connect to RX of the module
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);//init the serial protocol, tell to myserial which pins are TX and RX
///////////////////////////////////////////////////////////////////////////////////
//all the commands needed in the datasheet(http://geekmatic.in.ua/pdf/Catalex_MP3_board.pdf)
static int8_t Send_buf[8] = {0} ;//The MP3 player undestands orders in a 8 int string
//0X7E FF 06 command 00 00 00 EF;(if command =01 next song order)
#define NEXT_SONG 0X01
#define PREV_SONG 0X02
#define CMD_PLAY_W_INDEX 0X03 //DATA IS REQUIRED (number of song)
#define VOLUME_UP_ONE 0X04
#define VOLUME_DOWN_ONE 0X05
#define CMD_SET_VOLUME 0X06//DATA IS REQUIRED (number of volume from 0 up to 30(0x1E))
#define SET_DAC 0X17
#define CMD_PLAY_WITH_VOL 0X22 //data is needed 0x7E 06 22 00 xx yy EF;(xx volume)(yy number of song)
#define CMD_SEL_DEV 0X09 //SELECT STORAGE DEVICE, DATA IS REQUIRED
#define DEV_TF 0X02 //HELLO,IM THE DATA REQUIRED
#define SLEEP_MODE_START 0X0A
#define SLEEP_MODE_WAKEUP 0X0B
#define CMD_RESET 0X0C//CHIP RESET
#define CMD_PLAY 0X0D //RESUME PLAYBACK
#define CMD_PAUSE 0X0E //PLAYBACK IS PAUSED
#define CMD_PLAY_WITHFOLDER 0X0F//DATA IS NEEDED, 0x7E 06 0F 00 01 02 EF;(play the song with the directory \01\002xxxxxx.mp3
#define STOP_PLAY 0X16
#define PLAY_FOLDER 0X17// data is needed 0x7E 06 17 00 01 XX EF;(play the 01 folder)(value xx we dont care)
#define SET_CYCLEPLAY 0X19//data is needed 00 start; 01 close
#define SET_DAC 0X17//data is needed 00 start DAC OUTPUT;01 DAC no output
////////////////////////////////////////////////////////////////////////////////////
void setup() { //==========================================================================================
Serial.begin(9600);
mySerial.begin(9600);//Start our Serial coms for our serial monitor!
Serial.println("Starting Routine"); // so we know what sketch is running
pinMode(BUTTON, INPUT_PULLUP); // set the button pin as input with a pullup resistor to ensure it defaults to HIGH
// set the Led pins as output:
pinMode(STEPSW, INPUT_PULLUP);
pinMode(GLED, OUTPUT);
pinMode(RLED, OUTPUT);
pinMode(YLED1, OUTPUT);
pinMode(YLED2, OUTPUT);
//set motors as outputs
pinMode(LANE11, OUTPUT);
pinMode(LANE12, OUTPUT);
pinMode(LANE1PWM, OUTPUT);
pinMode(LANE1SW, INPUT_PULLUP);
pinMode (RELAY1, OUTPUT);
pinMode (RELAY2, OUTPUT);
//set motor controller pins
digitalWrite(LANE11, HIGH);
digitalWrite(LANE12, LOW);
sendCommand(CMD_SEL_DEV, DEV_TF);//select the TF card
delay(200);
}
//=============================================================================================
// MP3
void sendCommand(int8_t command, int16_t dat)
{
delay(20);
Send_buf[0] = 0x7e; //starting byte
Send_buf[1] = 0xff; //version
Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
Send_buf[3] = command; //
Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
Send_buf[5] = (int8_t)(dat >> 8);//datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //ending byte
for(uint8_t i=0; i<8; i++)//
{
mySerial.write(Send_buf[i]) ;
}
}
//LEDS==============================================================================================
void updateLED_State() {
int LEDDELAY = 1000;
//(beep)
digitalWrite(RLED, HIGH);
sendCommand(CMD_PLAY_WITH_VOL, 0X1E03);
delay(LEDDELAY); // wait for a second
//(beep)
digitalWrite(YLED1, HIGH);
sendCommand(CMD_PLAY_WITH_VOL, 0X1E03);
delay(LEDDELAY); // wait for a second
//(beep)
digitalWrite(YLED2, HIGH);
sendCommand(CMD_PLAY_WITH_VOL, 0X1E03);
delay(LEDDELAY); // wait for a second
//(beep)
digitalWrite(GLED, HIGH);
sendCommand(CMD_PLAY_WITH_VOL, 0X1E01);
delay(500); // wait for a second
//(beep)
sendCommand(CMD_PLAY_WITH_VOL, 0X3202);
digitalWrite(RLED, LOW); // turn the LED off
digitalWrite(YLED1, LOW); // turn the LED off
digitalWrite(YLED2, LOW); // turn the LED off
Serial.println("Initial LED done");
LEDOFF = true;
}
//Ending MP3 Sounds ================================================================================
void ShutDown() {
sendCommand(STOP_PLAY, 02); //ending celebration
delay (200);
sendCommand(CMD_PLAY_WITH_VOL, 0X1E04);
delay (3000);
sendCommand(STOP_PLAY, 04);
delay (200);
}
// Stepper Motor ==================================================================================
void StepSwing() {
if (CurrentStep <= STEPS_PER_OUT_REV) {
Serial.println("Stepping");
steppermotor.setSpeed(800);
steppermotor.step(-CurrentStep);
CurrentStep = (CurrentStep + 1);
}
}
//LANE 1 =======================================================================================
void LANE1CONT() {
if (buttonPushCounter1 = 0) StepSwing();
while(buttonPushCounter1 < 4) {
buttonState1 = digitalRead(LANE1SW); //counting laps
// Delay a little bit to avoid bouncing
delay(30);
if (buttonState1 != lastButtonState1) {
if (buttonState1 == LOW)
buttonPushCounter1++; }
lastButtonState1 = buttonState1; // save the current state as the last state, for next time through the loop
//if (buttonPushCounter1 < 3) {
analogWrite(LANE1PWM, SPEED);
Serial.print("number of laps lane 1: ");
Serial.println(buttonPushCounter1);
}
if (buttonPushCounter1 >= 4) { //number of laps
analogWrite(LANE1PWM, 0);
LANE1OFF = true; // main loop needs this to trigger shutdown
}
}
//=======
// MAIN LOOP
void loop() {
Serial.println("Ready");
MainButtonState = digitalRead(BUTTON);
// Delay a little bit to avoid bouncing
delay(30);
// compare the buttonState to its previous state
if (MainButtonState != LastMainButtonState) { // if the state has changed, increment the counter
if (MainButtonState == LOW) {
Serial.println("Button Pressed");
digitalWrite (RELAY1, LOW);
digitalWrite (RELAY2, LOW);
updateLED_State();
do {
//call functions that do work
Serial.println("inner loop");
LANE1CONT();
}
while(LANE1OFF = false);
if (LANE1OFF = true) ShutDown();
}
LastMainButtonState = MainButtonState;
}
Serial.println("Outter Main Loop");
buttonPushCounter1 = 0;
CurrentStep = 0;
LEDOFF = false;
LANE1OFF = false;
digitalWrite (RELAY1, HIGH);
digitalWrite (RELAY2, HIGH);
digitalWrite(GLED, LOW);
}
//=====END