Enter code here...#include <AccelStepper.h>
#include <MultiStepper.h>
#include <MP3Trigger.h>
MP3Trigger trigger;#include <SPI.h>
#include <Wire.h>
#include "servoshock.h"#define MS1 4
#define MS2 5
const int domeBaudeRate = 9600; //Set the baude rate for the Kangaroo
const int slaveSelect = SS; //Set the slave select pin for the ServoShock.
//Set jumper JP2 on the Shield to D10 if using digital output 10.
AccelStepper stepper(1,2,3);ServoShock Servoshock1(slaveSelect); //Create instance of ServoShockbyte vol = 20; // 0 = full volume, 255 offboolean isInAutomationMode = false;
unsigned long automateMillis = 0;
byte automateDelay = random(5, 20);
int turnDirection = 20;
byte automateAction = 0;int domeRight = 100;
int domeLeft = -100;
void setup(){ digitalWrite(slaveSelect,HIGH);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV32);
SPI.setBitOrder(MSBFIRST);
SPI.begin(); trigger.setup(&Serial);
trigger.setVolume(vol); //anything with trigger is for the mp3trigger pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
digitalWrite(MS1, LOW);
digitalWrite(MS2, LOW); stepper.setMaxSpeed(1000);
stepper.setAcceleration(1000);
}
void loop(){ Servoshock1.update();
if (Servoshock1.inPacket.psButton){ //Toggle automation mode with the PS Button
if (isInAutomationMode){
isInAutomationMode = false;
automateAction = 0;
trigger.play(1);
} else {
isInAutomationMode = true;
trigger.play(2);
}
}
if (isInAutomationMode){
unsigned long currentMillis = millis(); if (currentMillis - automateMillis > (automateDelay * 1000)){
automateMillis = millis();
automateAction = random(1, 5); if (automateAction > 1){
trigger.play(random(32,52));
}
//=================================================================================
// Below is where is need some help!
//
// The idea here is that the robots head would turn at random at the value of
// turnDirection from one side then stop untill it was ready to turn all the way to
// the other side and stop again.
//
//================================================================================= if (automateAction < 4){
stepper.moveTo(turnDirection); //set the direction of the turn
stepper.setSpeed(500); //speed at which the motor is turning
delay(750);
stepper.moveTo(0); //this is to stop the motor before it makes its next turn
stepper.setCurrentPosition(0);
stepper.setSpeed(0); if (turnDirection > 0){
turnDirection = domeRight;
} else {
turnDirection = domeLeft;
}
}
stepper.run();
automateDelay = random(5,20);
}
}
//============================================================================
//
// Joystick Control
//
//============================================================================
int domeMotor = map(Servoshock1.inPacket.lStickX, 0, 255, 200, -200);
stepper.moveTo(domeMotor);
stepper.setSpeed(800);
stepper.runSpeedToPosition();} if (automateAction < 4){ stepper.moveTo(turnDirection); //set the direction of the turn stepper.setSpeed(500); //speed at which the motor is turning delay(750); stepper.moveTo(0); //this is to stop the motor before it makes its next turn stepper.setCurrentPosition(0); stepper.setSpeed(0); if (currentMillis - automateMillis > (automateDelay * 1000)){ /* */ }
int domeMotor = map(Servoshock1.inPacket.lStickX, 0, 255, 200, -200); stepper.moveTo(domeMotor); stepper.setSpeed(800); stepper.runSpeedToPosition();if (automateAction < 4){
stepper.moveTo(turnDirection); //set the direction of the turn
stepper.setSpeed(500); //speed at which the motor is turning
delay(750);
stepper.moveTo(0); //this is to stop the motor before it makes its next turn
stepper.setCurrentPosition(0);
stepper.setSpeed(0);I have this working with a DC motor but it has no position sensors and just moves the motor from side to side at random and is not that great. This is why I thought a steeper might be better as you can control how far it will move! The code with the DC motor is as follows.
if (Servoshock1.inPacket.psButton){ //Toggle automation mode with the PS Button.
if (isInAutomationMode){
isInAutomationMode = false;
automateAction = 0;
trigger.play(1);
}
else
{
isInAutomationMode = true;
trigger.play(2);
}
}
if (isInAutomationMode){
unsigned long currentMillis = millis(); if (currentMillis - automateMillis > (automateDelay * 1000)){
automateMillis = millis();
automateAction = random(1, 5); if (automateAction > 1){
trigger.play(random(32,52));
}
if (automateAction < 4){
Syren10.motor(1, turnDirection); //This is the speed that the dome will turn at
delay(750); //Longer delay the further dome will travel side to side
Syren10.motor(1, 0); //Turn of dome motor
if (turnDirection > 0){ //Speed of the dome. + and - for CW / CCW rotation
turnDirection = -45;
} else {
turnDirection = 30;
}
}
automateDelay = random(5,20); //Delay between dome movement and sound
}
}
The above code is executed every time the PS Button is pressed and the automation of the dome (R2's head) and sounds start. If the PS button is pressed again this part will not be active as such. I can still make the dome spin via the joystick and that is why that part below is not inside an if block as such.
int domeMotor = map(Servoshock1.inPacket.lStickX, 0, 255, 200, -200); stepper.moveTo(domeMotor); stepper.setSpeed(800); stepper.runSpeedToPosition();if (automateAction < 4){if (turnDirection > 0){ //Speed of the dome. + and - for CW / CCW rotation
turnDirection = -45;
} else {
turnDirection = 30; Hi,Thanks for your reply!Yes it is my code all but the following part where I did copy that from some examples trying to get it working which it does not!if (automateAction < 4){
stepper.moveTo(turnDirection); //set the direction of the turn
stepper.setSpeed(500); //speed at which the motor is turning
delay(750);
stepper.moveTo(0); //this is to stop the motor before it makes its next turn
stepper.setCurrentPosition(0);
stepper.setSpeed(0);
if (isInAutomationMode && ((millis() - lastAutomation) > automationDelay)) {
I can still make the dome spin via the joystick and that is why that part below is not inside an if block as such.int domeMotor = map(Servoshock1.inPacket.lStickX, 0, 255, 200, -200);stepper.moveTo(domeMotor);stepper.setSpeed(800);stepper.runSpeedToPosition();
In the main part of the code after this line:if (automateAction < 4){
This is where I am trying to place some code so that the dome (R2's head) will spin slowly to one side, stop for a given time then move to a new position on the other side. Automate Action is a random number between 1 and 5. if its greater than one R2 will make sounds, but if its less than 4 R2 will turn his head.if (turnDirection > 0){ //Speed of the dome. + and - for CW / CCW rotation
turnDirection = -45;
} else {
turnDirection = 30;
The idea above with turn direction states which side R2's head is going to turn, left or right. So its this part where I need some help as I have no idea what to put there to get this to work. So I am think that because of when this code is executed by pressing the PS button the stepper.run() may have to be inside this and before or just after automateDelay = random(5,20); to kep it within this block of code.So do you have any ideas as to how I might start this code for the automation of the head turning. I have used code from some of the examples including the one from the random example however all that happends is the stepper motor just hum.If you can help that would be great. Hope you can make some understanding of what I have put here. I will attach my full working code with my DC motor so you can have a better understanding of what is going on. Well I hope so!Thanks Greg
void loop(){ //control input goes here Servoshock1.update(); //ServoShock update must be at start of main loop
digitalWrite(OEPIN, HIGH); //Disable power to the Adafruit Servo Driver //more control input...
if (isInAutomationMode && ((millis() - lastAutomation) > automationDelay)) { //setup automatic movement here //...
if (automateAction < 4) { stepper.moveTo(/*target position of choice*/); } }
if (/*override by manual control input*/) { int targetPosition = map(Servoshock1.inPacket.lStickX, 0, 255, 200, -200);
stepper.moveTo(targetPosition); }
stepper.run();}void controlInput() { if (millis() - lastInput > 100) //you usually do not need to evaluate user input in each loop. this limits it to 10 times / second return;
lastInput = millis();
//your control input handling goes here... Servoshock1.update(); //ServoShock update must be at start of main loop
if (Servoshock1.inPacket.psButton) { //Toggle automation mode with the PS Button if (isInAutomationMode) { isInAutomationMode = false; automateAction = 0; trigger.play(1); } else { isInAutomationMode = true; trigger.play(2); } }
//...
if (isInAutomationMode && ((millis() - lastAutomation) > automationDelay)) { //setup automatic movement here //...
if (automateAction < 4) { stepper.moveTo(/*targetPosition of choice*/); // } }
if (/*override by manual control input*/) { int domeMotor = map(Servoshock1.inPacket.lStickX, 0, 255, 200, -200);
stepper.moveTo(domeMotor); }}
void loop(){ controlInput();
//anything else you want to do (sounds, lights, limit switches, ...) //...
stepper.run();}if (Servoshock1.inPacket.psButton){ //Toggle automation mode with the PS Button
if (isInAutomationMode){
isInAutomationMode = false;
automateAction = 0;
trigger.play(1);
} else {
isInAutomationMode = true;
trigger.play(2);
}
}
if (isInAutomationMode){
unsigned long currentMillis = millis();
if (Servoshock1.inPacket.cross){
int targetPosition = map(Servoshock1.inPacket.lStickX, 0, 255, 200, -200);
stepper.moveTo(targetPosition);
}if (isInAutomationMode && ((millis() - lastAutomation) > automationDelay)) {Hi,Wow that's for your help....it's been very kind of you!Well I have changed some of the variable names as you stated and how now got the random movement working.....well sort of! I think I am close but been new to Arduino I am not sure how to go about it. At present I can now turn on and off the automate part of the program however in the code below trigger.play(1) and trigger.play(2) are running over between each random sound play. So I have some questions for you?if (Servoshock1.inPacket.psButton){ //Toggle automation mode with the PS Button
if (isInAutomationMode){
isInAutomationMode = false;
automateAction = 0;
trigger.play(1);
} else {
isInAutomationMode = true;
trigger.play(2);
}
}
Is there a way that once psButton is pressed and that isInAtuomationMode = true that it will stay in that part and not jump out until psButton is pressed again and isInAutomationMode = false. That said the stepper will still have to be turning at random and we have stepper.run() at the end of the if statement.
Now I have tried replacing the if with while in the line of code below however been trying to think of a way to jump out of that while loop and I don't know enough about Arduino as you could say I am still rather green to it lol.
while(someCondition)
{
//do stuff
if (someOtherCondition)
break;
}void controlInput(){ if (millis() - lastInput > 100) //you usually do not need to evaluate user input in each loop. this limits it to 10 times / second return; lastInput = millis(); //your control input handling goes here... Servoshock1.update(); //ServoShock update must be at start of main loop if (Servoshock1.inPacket.psButton) { //Toggle automation mode with the PS Button if (isInAutomationMode) { isInAutomationMode = false; automateAction = 0; trigger.play(1); } else { isInAutomationMode = true; trigger.play(2); } } //... if (isInAutomationMode && ((millis() - lastAutomation) > automationDelay)) { //setup automatic movement here //... if (automateAction < 4) { stepper.moveTo(/*targetPosition of choice*/); // } } if (/*override by manual control input*/) { int domeMotor = map(Servoshock1.inPacket.lStickX, 0, 255, 200, -200); stepper.moveTo(domeMotor); } //ignore other inputs if automatic mode is active if (isInAutomationMode) return; //the rest of the input handling goes here //...}
void loop(){ controlInput(); //anything else you want to do (sounds, lights, limit switches, ...) //... stepper.run();}In the joystick part of the program I have added an if statement that is overriding the automate part for manual stepper movement, however I was hoping that when it was in automation mode that the stepper movement would random. If I pressed the psbutton that wouls end the automation and I would have manual control over the stepper.
In your last post you stated that the line of code below should be placed in an if block to add a timeout to the if condition. Can I ask where in the code should that be placed and what lines of the code would be replaced if that is to be added.if (isInAutomationMode && ((millis() - lastAutomation) > automationDelay)) {
if (isInAutomationMode){ unsigned long currentMillis = millis();