Anemometer controlling speed of stepper motor

Hello,

I'm working on a small project where I'm trying to use the data readings from an Anemometer to control the rotation speed of a Nema 17 stepper motor (data sheet).

I have a code to get the data from the Anemometer and I have a code to set the RPM of the stepper motor but I don't know how to write a code in order to change the RPM if the wind speed is at a certain interval.

What I would like the code to do is:

if ((windSpeed>0.0) && (windSpeed<=1.0)) myStepper.setSpeed = 0; //RPM
if ((windSpeed>1.0) && (windSpeed<=2.0)) myStepper.setSpeed = 300; //RPM
if ((windSpeed>2.0) && (windSpeed<=3.0)) myStepper.setSpeed = 600; //RPM
if ((windSpeed>3.0) myStepper.setSpeed = 1000; //RPM

I have attached the wiring diagram and these are the two codes I'm been using so far:



const int sensorPin = A0;

int sensorValue = 0;

float sensorVoltage = 0;

float windSpeed = 0;

float voltageConversionConstant = .004882814;

int sensorDelay = 1000;

float voltageMin = .4;

float windSpeedMin = 0;

float voltageMax = 2.0;

float windSpeedMax = 32;

void setup() { Serial.begin(9600); 
}

void loop() { sensorValue = analogRead(sensorPin);

sensorVoltage = sensorValue * voltageConversionConstant;

if 

(sensorVoltage <= voltageMin) { windSpeed = 0; }

else 

{ windSpeed = (sensorVoltage - voltageMin)

*windSpeedMax/(voltageMax - voltageMin); }

Serial.print("Voltage: ");

Serial.print(sensorVoltage);

Serial.print("\t");

Serial.print("Wind speed: ");

Serial.println(windSpeed);

delay(sensorDelay); }


#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

void setup() {

  Serial.begin(9600);
}

void loop() {

  myStepper.step(stepsPerRevolution);
    // set the speed at x rpm:
    myStepper.setSpeed(300);



}

I'm not an expert in coding at all. So if someone would be so kind to guide me in the right direction and help me develop this code I would be very thankful.

FIRST important point…
You don’t drive or spec steppers by revs/min.
Steppers are positioning accuracy, not speed!

Steppers aren’t particularly fast, and depending on how you’re going to load it, the most appropriate motor might probably be a brushed DC motor, driven with PWM.
They can accelerate and decelerate quickly, but have a much better top speed.

If you need the motor to stop precisely at a specific position, look at an encoder and slightly more sophisticated control of the PWM using
PID to park the motor precisely.

Thank you so much for this information. I will look into using a brushed DC motor instead.

The reason I was planning on using the stepper motor was because it does not make as much noise as other motors, in my experience.

I should also have mentioned that the stop position of the motor does not matter and that it does not have to carry any load.

It seems setSpeed(0) will act like "divide by zero" with the stepper taking zero steps to revolve at zero RPM, only releasing the sketch to move to the next command after one revolution is (never) complete.

WOKWI files:

sketch.ino
// https://forum.arduino.cc/t/anemometer-controlling-speed-of-stepper-motor/1267758

#include <Stepper.h>
const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
const int sensorPin = A0;
int speed = 0;

void setup() {
  Serial.begin(9600);
  Serial.print("Wind Speed:");
}

void loop() {
  int sensorValue = analogRead(sensorPin); // read the sensor
  int mapValue = map (sensorValue, 0, 1023, 0, 4); // map the sensor reading

  Serial.print(mapValue); // sensor reading in MPH

  if (mapValue <= 1)
    // speed = 0; // speed must be greater than zero or the revolution never completes and sketch waits forever
    speed = 10;
  if (mapValue > 1 && mapValue <= 2)
    speed = 300;
  if (mapValue > 2 && mapValue <= 3)
    speed = 600;
  if (mapValue > 3)
    speed = 1000;

  // step the motor
  myStepper.setSpeed(speed);
  delay(500);
  myStepper.step(stepsPerRevolution);
}
diagram.json
{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-nano", "id": "nano", "top": 0, "left": 0, "attrs": {} },
    { "type": "wokwi-potentiometer", "id": "pot1", "top": -10.9, "left": 182.2, "attrs": {} },
    {
      "type": "wokwi-stepper-motor",
      "id": "stepper1",
      "top": -115.21,
      "left": 3.42,
      "attrs": { "size": "8" }
    }
  ],
  "connections": [
    [ "pot1:GND", "nano:GND.1", "black", [ "v28.8", "h-57.6" ] ],
    [ "pot1:SIG", "nano:A0", "green", [ "v38.4", "h-134.8" ] ],
    [ "pot1:VCC", "nano:5V", "red", [ "v48", "h-106.4" ] ],
    [ "nano:11", "stepper1:A-", "green", [ "v0" ] ],
    [ "nano:10", "stepper1:A+", "green", [ "v0" ] ],
    [ "nano:9", "stepper1:B+", "green", [ "v0" ] ],
    [ "nano:8", "stepper1:B-", "green", [ "v0" ] ]
  ],
  "dependencies": {}
}

What wind speed would make the anemometer spin at 1000 RPM?
1000 RPM for a 200 step per rev motor would be 3333 steps per second. Can your motor and drive do that?

Thank you so much for this!

I've tried uploading the code, however the serial monitor is showing 'Wind Speed: 33333...' when there is no wind.
Do you know how to adjust this?

And also, how to stop the motor from rotating if the Wind Speed = 0?

Thank you, your help is really appreciated.

Your sensor is putting out 1023 at zero wind speed... maybe as the speed increases, the value (1023) decreases.

So, change this:

  int mapValue = map (sensorValue, 0, 1023, 0, 4); // map the sensor reading

to this:

  int mapValue = map (sensorValue, 1023, 0, 0, 4); // map the sensor reading
You will need to adjust the values inside the code on the "mapValue" line ``` int sensorValue = analogRead(sensorPin); // read the sensor int mapValue = map (sensorValue, 0, 1023, 0, 4); // map the sensor reading ``` You will need to first read the sensorValue at zero speed and put that as the second parameter (the first "0") in map(x, HERE, x, x, x), leave 1023, leave the second "0" and estimate your maximum wind speed and place that value where the "4" is.

I've changed the values but now the Serial Monitor is showing 'Wind Speed: 0', even if there is wind.

Comment-out the "map" command and read/print the raw value the Arduino sees on the sensor pin.

Would you mind writing the example so I understand how to do that correctly?

Thank you.

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(analogRead(A0));
  delay(500);
}

You need to subtract the "zero wind speed" voltage, 0.4volts or an ADC count of about 82 from the ADC reading before mapping. The reading for 2V will be about 410 so the "span" will be 410 - 82 = 328.
So, after subtracting the ADC value for zero wind speed, map for 0 to 328.
Which motor driver are you using? A4988 will not work properly with <stepper.h>.
What is your ADC value for zero wind speed?
Post your current code.

This is the current code:

// https://forum.arduino.cc/t/anemometer-controlling-speed-of-stepper-motor/1267758

#include <Stepper.h>
const int stepsPerRevolution = 200;
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
const int sensorPin = A0;
int speed = 0;
int sensorValue = 0;
float sensorVoltage = 0;
float windSpeed = 0;
float voltageConversionConstant = .004882814;
int sensorDelay = 1000;
float voltageMin = .4;
float windSpeedMin = 0;
float voltageMax = 2.0;
float windSpeedMax = 32;


void setup() {
  Serial.begin(9600);
  Serial.print("Wind Speed:");
}

void loop() {
  int sensorValue = analogRead(sensorPin); // read the sensor
  int mapValue = map (mapValue, 1023, 0, 0, 4); // map the sensor reading

  Serial.println(analogRead(A0));
  //delay(500);

  //Serial.print(mapValue); // sensor reading in MPH

  if (mapValue <= 1)
    // speed = 0; // speed must be greater than zero or the revolution never completes and sketch waits forever
    speed = 10;
  if (mapValue > 1 && mapValue <= 2)
    speed = 200;
  if (mapValue > 2 && mapValue <= 3)
    speed = 600;
  if (mapValue > 3)
    speed = 1000;


  // step the motor
  myStepper.setSpeed(speed);
  myStepper.step(stepsPerRevolution);
}

The Serial Monitor is now printing out values between 81 - 87 when there is no wind speed as @JCA34F you were saying.

1017 for a 0.4 volt signal? Which Arduino are you using?

Sorry, I've edited the post as that was wrong.

The Serial Monitor is now printing out values between 81 - 87 when no wind speed.

How do you wire your stepper driver? The schematic shows a step/dir driver, that only needs 2 wires. You create the stepper object with 4 pins. The stepper.h library isn't designed for step/dir drivers - even if you use only 2 pins.

I've wired it according to the diagram in post #1

How would you suggest to change it - or which library should I use instead?

Thank you!

If you are using the A4988 stepper driver board, replace Stepper.h with A4988.h and follow the example like BasicStepperDriver.ino

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.