0

I have my Arduino Yun set up with a web server. The webpage has a series of buttons on it, which control the buzzer playing various sounds, and a button to control a stepper motor. I'm using the code linked which uses the AccelStepper library.

The button works fine for the buzzer, I click it and it plays the sound. For the motor however, I click the button, and the LED lights up on the driver board for a second after the button is clicked but that's it.

I suspect that the motor, unlike the buzzer, needs the command to be true all the time while it moves to it's position, otherwise it stops. So the button on the webpage needs to act more like a switch - click to come on and stay on, click again to go off and stay off. But I'm unsure how to do this.

Or else, perhaps anyone has experience with this stepper motor and knows how to use it without accelstepper. (All i'm trying to do is get the motor to turn to a given position.)

I hope this isn't too confused. I'm so close, yet this motor is causing me a massive pain. Many thanks!

The sketch code:

    //Bridge Setup
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

YunServer server;
String readString;

//Motor Setup
#include <AccelStepper.h>
#define HALFSTEP 8

// Motor pin definitions
#define motorPin1  3     // IN1 on the ULN2003 driver 1
#define motorPin2  4     // IN2 on the ULN2003 driver 1
#define motorPin3  5     // IN3 on the ULN2003 driver 1
#define motorPin4  6     // IN4 on the ULN2003 driver 1

// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
//////////////
//const int thereader = 8; 
int Buzzer1 = 9;
//int readerstate = 0; 


void setup() {
stepper1.setMaxSpeed(1000.0);
stepper1.setAcceleration(100.0);
stepper1.setSpeed(200);
stepper1.moveTo(20000);

pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(9, OUTPUT);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(9, LOW);

Bridge.begin();
//digitalWrite(13, HIGH);



  // Listen for incoming connection only from localhost
  // (no one from the external network could connect)
  server.listenOnLocalhost();
  server.begin();


  ////////////
  //pinMode(Buzzer1, OUTPUT);  
  // initialize the pushbutton pin as an input:
  //pinMode(thereader, INPUT);

}//--(end setup )---

void loop() {

 YunClient client = server.accept();

 // There is a new client?
 if (client) {
  // read the command
 String command = client.readString();
 command.trim();        //kill whitespace
 Serial.println(command);



   if (command == "rolloutcarpet") {
   stepper1.run();
   //delay(2000);
   //stepper1.moveTo(-stepper1.currentPosition());

  }

 if (command == "playfanfare") {
  tone(Buzzer1,400,200);
  delay(500);
  tone(Buzzer1,400,200);
  delay(500);
  tone(Buzzer1,450,225);
  delay(300);
  tone(Buzzer1,450,225);
  delay(500);
  tone(Buzzer1,400,200);
  delay(500);
  tone(Buzzer1,450,200);
  delay(300);
  tone(Buzzer1,600,300);
  delay(3000);

}

else if (command == "stopfanfare") {
   delay(10000);
}
  client.stop();
}

delay(50);

}

HTML code:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="zepto.min.js"></script>

<script type="text/javascript">
function rolloutcarpet()
{
$('#content').load('/arduino/rolloutcarpet');
}

function playfanfare()
{
$('#content').load('/arduino/playfanfare');
}

function stopfanfare()
{
$('#content').load('/arduino/stopfanfare');
}
</script>



 </head>
 <body onload="setInterval(refresh, 500);">
    <span id="content"></span>
   <button onclick="rolloutcarpet()">Roll Out the Carpet</button> 
    &nbsp;&nbsp;&nbsp;&nbsp;  <button onclick="ledoff()">LED BLUE OFF</button>
<br><br><br>
   <button onclick="playfanfare()">PLAY FANFARE</button> 
  &nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <button onclick="stopfanfare()">STOP FANFARE</button>
<img src="yun.png" align="right">

   </body>

</html>
peyroux
  • 35
  • 1
  • 1
  • 4
  • *"I suspect that the motor, unlike the buzzer, needs the command to be true all the time while it moves to it's position, otherwise it stops."* Wouldn't it be a good idea to test that theory offline with a simple Arduino Sketch? – GolezTrol Aug 30 '14 at 12:27
  • @GolezTrol Well I tried the motor with a physical pushbutton, and it had to be pressed all the time for the motor to turn. But I'm unsure how to replicate that using a digital button and the commands shown above. any help would be greatly appreciated. – peyroux Aug 30 '14 at 12:29
  • Ok. So it seems the theory is right. Now maybe, it's also easier to use the physical button to program your goal. Just read the button value and if it is down, set a flag and rotate the stepper while it is up. All you need to know is how long to keep the flag up. Once this works, switching from a physical button to a web button should be trivial. The flag can also be a counter (to remember how many steps you've done). – GolezTrol Aug 30 '14 at 12:40
  • You can do it with the web interface as well, but in my experience it's tricky to debug a 'larger' system like that. But since the buzzer already works, you're less likely have a fault in that part anyway. – GolezTrol Aug 30 '14 at 12:41
  • ps Have you seen arduino.stackexchange.com? – GolezTrol Aug 30 '14 at 12:56
  • @GolezTrol This is presumably possible with physical buttons using Button State Change Detection. But I'm not sure how to do this with the digital commands shown as I can't check the 'lastcommandstate'. Or if I can, I'm unsure how to. Any help/links greatly appreciated. – peyroux Aug 30 '14 at 12:57

1 Answers1

1

The .run() method needs to be called repeatedly to make more than a single step.

Note that each call to run() will make at most one step, and then only when a step is due, based on the current speed and the time since the last step. reference

So either call .run() in a loop:

if (command == "rolloutcarpet") {
    while (stepper1.distanceToGo() != 0) {
        stepper1.run();
    }
}

Otherwise use .runToPosition(), which does the same as the above loop anyway, but blocks and doesn't return until it's made it to it's new position.

if (command == "rolloutcarpet") {
    stepper1.runToPosition();
}

If you want to skip acceleration, make sure you set the speed you want after you set the target position, and you can use runSpeedToPosition():

if (command == "rolloutcarpet") {
    stepper1.moveTo(200);
    stepper1.setSpeed(200);
    stepper1.runSpeedToPosition();
}
Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
snoble
  • 38
  • 3