Having difficulties with noTone()

Hi,

I'm developing a printing system for my final year project, using a Mega2560 and RAMPS 1.4 shield to control some stepper motors and an inkjet printhead.

I have successfully got the stepper motors to move in the desired fashion - they rotate a belt which is attached to a platform, causing the platform to move - using the code below. The basic idea is that the platform moves in parallel lines, with a small perpendicular movement at the end of the line. When a certain number of lines have been printed, the motors all stop. Eventually this will be positioned beneath a stream of ink droplets so that the ink prints a square shape.

#include <AccelStepper.h>

#define X_STEP_PIN 54
#define X_DIR_PIN 55
#define X_ENABLE_PIN 38
#define Y_STEP_PIN 60
#define Y_DIR_PIN 61
#define Y_ENABLE_PIN 56
#define Y_MIN_PIN 14
#define Y_MAX_PIN 15

AccelStepper Xaxis(1, X_STEP_PIN, X_DIR_PIN);
AccelStepper Yaxis(1, Y_STEP_PIN, Y_DIR_PIN);

void setup() {
  Xaxis.setMaxSpeed(1000);
  Xaxis.setAcceleration(10000);
  Xaxis.moveTo(660);
  Xaxis.setEnablePin(X_ENABLE_PIN);
  Xaxis.setPinsInverted(false,false,true);
  Xaxis.enableOutputs();
  Yaxis.setMaxSpeed(10000);
  Yaxis.setAcceleration(10000);
  Yaxis.setEnablePin(Y_ENABLE_PIN);
  Yaxis.setPinsInverted(false,false,true);
  Yaxis.enableOutputs();
}

void loop() {
  while (Yaxis.currentPosition() == 660)
  Yaxis.stop();
  while (Yaxis.currentPosition() == 660)
  Xaxis.stop();
  if (Xaxis.distanceToGo() == 0)
  Yaxis.move(66);
  if (Xaxis.distanceToGo() == 0)
  Xaxis.moveTo(-Xaxis.currentPosition());
  Xaxis.run();
  Yaxis.run();
}

My next challenge is to send a signal from another pin to cause actuation of the printhead. This has to be synchronised with the movement of the stepper motors - so that it starts printing when the platform starts moving, and stops printing when the platform stops moving. Otherwise there will just be a big mess of ink on one spot!

I've used the tone() function to send a square wave from a pin, which will be able to actuate the printhead. As I'm not connected to the printhead just yet, I have an LED and resistor connected to the pin to check if it's working.

I tried to add another bit into the loop so that noTone() is called once the stepper motors have reached the desired position - this is the same strategy I have used to get the stepper motors to stop. However the signal keeps on firing.

void loop() {
  while (Yaxis.currentPosition() == 660)
  Yaxis.stop();
  while (Yaxis.currentPosition() == 660)
  Xaxis.stop();
  while (Yaxis.currentPosition() == 660)
  noTone(Trigger_PIN);
  if (Xaxis.distanceToGo() == 0)
  Yaxis.move(1);
  if (Xaxis.distanceToGo() == 0)
  Xaxis.moveTo(-Xaxis.currentPosition());
  Xaxis.run();
  Yaxis.run();
  tone(Trigger_PIN, 31);
}

Can anyone suggest how I can get noTone to stop the signal from firing once the stage reaches the desired position (660 steps) and stops?

That seems like an awful lot of explanation for such a simple problem - you can probably tell I've never done any coding before let alone used an Arduino!

Thanks in advance,

Michael

  while (Yaxis.currentPosition() == 660)
  Yaxis.stop();
  while (Yaxis.currentPosition() == 660)
  Xaxis.stop();
  while (Yaxis.currentPosition() == 660)
  noTone(Trigger_PIN);

This seems to be a very odd use of the while command. Would it not be better to use an if command and why check 3 times for the same value ? Why not check once and execute 3 commands ?

I'm sure you're right, and I'm probably missing something, but I couldn't get it to work when just using the 'while' command once.

So if I change the 'while' for an 'if' and just use it once, would you expect it to work?

mcaley:
So if I change the 'while' for an 'if' and just use it once, would you expect it to work?

I don't know, but I suggest that you tidy up the code and make it more standard in any case.

In my experience, problems with if and while are usually caused by the values being tested not being what is expected so you will probably need to add some Serial.print()s to output the value of pertinent variables at relevant stages in the program so that you can track what is going on. When you do don't forget to add some text lables so that you know what you are seeing.

Followed your advice - to be honest I had no idea that what I had done wasn't 'standard' - and it works as I want it to. Thanks for your help.