arduino uno as motor throttle controller

Hi, I’m new to arduino, but i’ve spent many hours looking at examples and reading in forums. I have a long history with electronics but with a big gap during the changes from discrete chips to microcomputer controls. I am usingan Arduino Uno, I’m wanting to replace the throttle control on my small generator as the existing one died.
I have the notion that by measuring speed (o/p frequency) of the gen and comparing to a desired frequency to produce a speed hi/low flag then driving the unipolar motor (which is a 28BYJ) CW/CCW i could achieve the result i want. I am able to measure frequency (using a sig generator) and display it on the Uno serial monitor. I am able to drive the stepper both directions using several of the example sketches, and it can operate fast enough to do the job - must be able to as that’s what is on the generator engine.
My problem is that i can’t stitch the two sketches together to drive the stepper up or down as determined by the speed hi/low flag, it just oscillates.
The sketch also slows down enormously once i ‘engage’ the stepper up/down drive code. I am using “If” statements to get ‘increase’ or ‘reduce’ flag in the Uno. I’m driving the sig generator and the uln2003 board from a supply separate from the uno and i am using a common ground.
As I’ve spent many many hours trying to get this to work with no success, I am hoping that I can get a pointer or two from the wiser heads in this forum. I’ve attached the sketch. (I know I’ll need refinements to properly tune the response, its one step at a time for the present).
Thanks in advance for any help offered.

enginethrottlecontrol_MP_rev3-1jun20.ino (2.14 KB)

Search for "generator control" or similiar! This project was asked for not long ago.

mikep32:
I have the notion that by measuring speed (o/p frequency) of the gen and comparing to a desired frequency to produce a speed hi/low flag then driving the unipolar motor (which is a 28BYJ) CW/CCW i could achieve the result i want.

I suspect you will need to apply PID control (read up about it) to ensure a smooth response without over- or under-shooting. There is an Arduini PID library and this link includes a simple PID function.

…R

PS … people will find it much easier to help you if you include short programs in your Post so they don’t have to download them. Use the code button </>. See How to use the forum

Railroader:
Search for "generator control" or similiar! This project was asked for not long ago.

I did inded do that and was unable to find anything that was recent, except for an incomplete project using a servo not a stepper. My code incorporates some of that persons code. Another project from 2012 was for a complete diesel mamagement system so i did not follow it through. I have spent weeks reading, searching for something to help me understand why my code does not work as i expected. Sadly i am also a newby with stepper motors and am finding it difficult to understand why an even number step command will make the motor go one direction and the same command with an odd step number will make it go the opposite. Also hy a full turn command will get a fast response but a looped increment +1 command wil be sooo slow.

mikep32:
Sadly i am also a newby with stepper motors and am finding it difficult to understand why an even number step command will make the motor go one direction and the same command with an odd step number will make it go the opposite.

That seems very strange.

Have you written a short program just to learn how to make the stepper motor move backwards and forwards?

If so, and if it does not work, then please post the program and tell us exactly what happens when you run the program.

...R

Robin2:
That seems very strange.

Have you written a short program just to learn how to make the stepper motor move backwards and forwards?

If so, and if it does not work, then please post the program and tell us exactly what happens when you run the program.

…R

I have used this sample program and played with its parameters to get its fastest rotation speed thinking to use those parameters in my engine control code. The stepper works as expected with the code below.
<
#include <Stepper.h>

const int stepsPerRevolution = 600; // 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);

int stepCount = 0; // number of steps the motor has taken
int jump = 1;
void setup() {
// initialize the serial port:
Serial.begin(9600);
}

void loop() {
// step one step:
myStepper.step(jump);
Serial.print(“steps:”);
Serial.println(stepCount);
stepCount++;
delay(1);
}

You can see that Jump is set to 1 where it runs ok, but if i set jump to 2 the motor jitters and does not really turn, except I just now found that if i rotate the shaft manually it will then rotate on its own. Clearly i don’t understand the operation of stepper motors. One of my problems is that as i am inexperienced with steppers and arduino both, i am unable to really tell where my problem lies.

I have also played with another sample sketch which rotates the servo both CW and CCW, adjusting the step parameter to obtain maximum motor speed. It worksas youd expect
<#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() {
// set the speed at 60 rpm:
myStepper.setSpeed(60);
// initialize the serial port:
Serial.begin(9600);
}

void loop() {
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper.step(stepsPerRevolution);
delay(500);

// step one revolution in the other direction:
Serial.println(“counterclockwise”);
myStepper.step(-stepsPerRevolution);
delay(500);
}

My engine control Problem seems to lie in getting the stepper to move in a (say) CW direction until my 'If 'statement remains ‘true’, which again may be an issue with my understanding of steppers? Sorry about the length of the post, I don’t know how to describe the issues any more succinctly. :frowning:

When posting code use the code button </> or put the words [code] code in here  [/code] before and after the code

This is the code from your Original Post presented properly so other people don’t have to download it. I believe people who read the Forum on tablets can’t download code.

/*
 this sketch uses frequencycounter, compares to desired speed,
 increases or decreases unipolar motor position to increase or reduce
 carburettor position to restore engine speed to desired.
 Derived from Frequency counter and
 Stepper Motor Control - one revolution

 This program drives a unipolar or bipolar stepper motor.
 The motor is attached to digital pins 8 - 11 of the Arduino.
 */
 
#include <Stepper.h>
const int stepsPercorrection = 20;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPercorrection, 8, 9, 10, 11);
void setup() 
{   // set the speed at 10 rpm:
    myStepper.setSpeed(10);
    //Initialize serial and wait for port to open:
    Serial.begin(9600);
    while (!Serial) 
       {; // wait for serial port to connect. Needed for native USB port only
 
        delay(100);
        }
Serial.println("trying for throttle control");

}
const int pulsePin = 5; // Input signal connected to Pin 8 of Arduino

int pulseHigh; // Integer variable to capture High time of the incoming pulse
int pulseLow; // Integer variable to capture Low time of the incoming pulse
float pulseTotal; // Float variable to capture Total time of the incoming pulse
float frequency; // Calculated Frequency
int countnumber= 0; //times counted
float targetspeed = 200; // define desired engine "speed signal" as 200hZ
int speederror = 0;

void loop()
 
{
   pulseHigh = pulseIn(pulsePin,HIGH);
   pulseLow = pulseIn(pulsePin,LOW);
    
   pulseTotal = pulseHigh + pulseLow; // Time period of the pulse in microseconds
   frequency=1000000/pulseTotal; // Frequency in Hertz (Hz)
   Serial.print("        "), Serial.println(countnumber) ;
   Serial.print(frequency), Serial.print("         "),Serial.println(frequency - targetspeed);
   countnumber = (countnumber + 1);
   
   speederror = (frequency - targetspeed);
   if (speederror>0) 
   {//Serial.print("close throttle");
   myStepper.step(1);
   }
     
    else if (speederror<0)
    {Serial.print("open throttle");
    myStepper.step(-1);  
    }
  delay(10);
}

…R

When you ask the Stepper library to do a single step it can’t use your speed setting. The speed of the motor will be determined by how quickly loop() repeats. If that is too fast the motor will miss steps. Start with a much longer delay() in loop() to give a much longer interval between steps.

Also, you have no hysteresis built into your system so when the speederror is very close to zero the system will hunt between moving forward and backwards. You should have a gap between the value at which it needs to increase and the value at which is needs to decrease. Perhaps like this

    if (speederror > 5) {
       //Serial.print("close throttle");
       myStepper.step(1);
    }
     
   else if (speederror < 5) {
      Serial.print("open throttle");
      myStepper.step(-1);  
   }

If none of that helps please explain in more detail what happens when you run your program

…R

Robin2:
When you ask the Stepper library to do a single step it can’t use your speed setting. The speed of the motor will be determined by how quickly loop() repeats. If that is too fast the motor will miss steps. Start with a much longer delay() in loop() to give a much longer interval between steps.

I did think the speed setting was unused in single step. That portion of code lingered from the sample i cribbed from and has no effect The stepper speed will need to be quite fast to respond to engine speed changes with load. I will have another play with the loop delay. I also thought by stepping say 2 steps rather than 1 i might get a faster response but as i said if i use an odd number the stepper jitters, whereas with an odd number it works ok even with reasonably large - say 41 steps.

I know there is no hysteresis, but since i am simulating an engine frequency with a sig generator that does not come into play as i am setting a simulated engine speed which does not change. Im looking for a servo response to reflect the speed error and its not happeningas the speed error is detected but the servo is not driving. Hysteresis and engine /controller tuning are not my issue at present.
PS
I imagine that the suggested code to introduce hysteresis “else if (speederror < 5)” ought to read “else if (speederror < -5)” ?
Mike
PPS Sorry, but I cannot see a code </> button, I thought using a < before and a > after the code would do it?

Errrm, I see! the quick reply does not have a code button, that only shows up when one replies using "Post reply" :grin:

mikep32:
Errrm, I see! the quick reply does not have a code button,

I believe you can change your Preferences so that it does. It's a PITA that it is not there by default.

...R

One way of several to post code.

Type this:

[code]

Copy 
  and
    paste
      your
        code
          here

Then type this:

[/code]

It will look like:

Copy 
  and
    paste
      your
        code
          here

A reply to OP #3.
This project concists of several parts. One is measuring RPM. One is the control algorithm. One is putting the maths into fysical action and so on. If this uses steppers or servos it is still a part of its own.
My idea was that You would identify those parts and pick up the experiences mad in that other topic.
If You hope a ready made concept for copying, You're wrong.

Robin2:
I believe you can change your Preferences so that it does. It's a PITA that it is not there by default.

...R

Thanks, I'll look for that and set it to show.

JCA34F:
One way of several to post code.

Type this:

Copy 
  and
    paste
      your
        code
          here

Then type this:



It will look like:


Copy
 and
   paste
     your
       code
         here

Thanks, that example makes it clear,

Railroader:
A reply to OP #3.
This project concists of several parts. One is measuring RPM. One is the control algorithm. One is putting the maths into fysical action and so on. If this uses steppers or servos it is still a part of its own.
My idea was that You would identify those parts and pick up the experiences mad in that other topic.
If You hope a ready made concept for copying, You’re wrong.

Not sure what OP #3 means, but I’ll assume you’re talking to me. Yes, the project does comprise of several parts. I have indeed looked for experiences and examples relating to those parts and have, as i have said, adapted and borrowed code from those parts i have been able to find. Hence, i have code to measure frequency from one project, code from examples on driving stepper motors, (and my apologies to the original writers of that code for not giving credit but i have lost track of who’s code i have borrowed) and my own code which you call the control algorithm to produce logic which intends to drive the stepper to correct the engine speed by operation of the throttle. Additionally, i recognise that the control algorithm i have so far is insufficient for complete control and have every intention to add to it to tune engine/ control response. I believe i can do that either by active management of the size of the steps related to the speed error, which would comprise in itself a type of pid control, or by using the pid control library available in the arduino library but which at present i have not looked into. However , as they say, baby steps first, so this latter can wait until i manage to get the basics going. While it would be delightful to find a ready made solution to my engine speed control, and i certainly could learn from that were it available, i do not expect it. I have about 40 years experience in engineering and technical matters as an electrical/ electronic engineer, but the last twenty in administration where i needed an understanding of concepts but not the knowledge for the detailed work so have gotten rusty (very) but not completely ignorant. I did start this project of mine with actual discreet ic components and a breadboard and got to the near-final stage of needing to control a stepper motor then, having already purchased some time ago an arduino with the view of educating myself, I thought, “why not use the arduino for the complete project?”. The application of micro computers has not changed the basic concepts, only the means of application. I hope that gives you a better idea of where i sit technically.

mikep32:
Not sure what OP #3 means,

You are the OP - the Original Poster

And #3 means Reply #3

...R

@mikep32, the text you posted in Reply #15 is essentially unreadable because several different thoughts are all included in a single paragraph. See how some white-space greatly increases readability. A good test of readability is to read your text aloud to yourself.

Not sure what OP #3 means, but I’ll assume you’re talking to me.

Yes, the project does comprise of several parts. I have indeed looked for experiences and examples relating to those parts and have, as i have said, adapted and borrowed code from those parts i have been able to find.

Hence, i have code to measure frequency from one project, code from examples on driving stepper motors, (and my apologies to the original writers of that code for not giving credit but i have lost track of who’s code i have borrowed) and my own code which you call the control algorithm to produce logic which intends to drive the stepper to correct the engine speed by operation of the throttle.

Additionally, i recognise that the control algorithm i have so far is insufficient for complete control and have every intention to add to it to tune engine/ control response. I believe i can do that either by active management of the size of the steps related to the speed error, which would comprise in itself a type of pid control, or by using the pid control library available in the arduino library but which at present i have not looked into.

However , as they say, baby steps first, so this latter can wait until i manage to get the basics going. While it would be delightful to find a ready made solution to my engine speed control, and i certainly could learn from that were it available, i do not expect it.

I have about 40 years experience in engineering and technical matters as an electrical/ electronic engineer, but the last twenty in administration where i needed an understanding of concepts but not the knowledge for the detailed work so have gotten rusty (very) but not completely ignorant.

I did start this project of mine with actual discreet ic components and a breadboard and got to the near-final stage of needing to control a stepper motor then, having already purchased some time ago an arduino with the view of educating myself, I thought, “why not use the arduino for the complete project?”. The application of micro computers has not changed the basic concepts, only the means of application.

I hope that gives you a better idea of where i sit technically.

…R

Robin2:
@mikep32, the text you posted in Reply #15 is essentially unreadable because several different thoughts are all included in a single paragraph. See how some white-space greatly increases readability. A good test of readability is to read your text aloud to yourself.

...R

I stand humbled and corrected. It was rather dense and would have scored a 3/10 from any english teacher. :wink:

In desperation I have gone back to basics, very basic for you I’m sure.
The following code works and my stepper drives in both directions and pauses dependent on the input value from the pot. This will provide the hysteresis mentioned by Railroader. The speed of the stepper is quite good, as fast as it is technically able to be, which i have ascertained by trying lower and lower values of “flash”. Now I will look at stitching this code into my frequency measurement component, and we’ll see what happens…

void setup() 
 { // put your setup code here, to run once:

pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,HIGH);
Serial.begin(9600);
}
int potpin = 0;  // analog pin used to connect the potentiometer
int flash = 3;
int val;    // variable to read the value from the analog pin

void loop() {
  // put your main code here, to run repeatedly:
 val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 15, 240);     // scale it to use it with the servo (value between 0 and 180)
   Serial.println(val);
  //delay(130);                           // waits for the servo to get there

if (val>130)
    {digitalWrite(10,HIGH);
    delay(flash);
    digitalWrite(10,LOW);
    digitalWrite(9,HIGH);
    delay(flash);
    digitalWrite(9,LOW);
    digitalWrite(8,HIGH);
    delay(flash);
    digitalWrite(8,LOW);
    digitalWrite(11,HIGH);
    delay(flash);
    digitalWrite(11,LOW);
    }
else if (val<110)
    {digitalWrite(8,HIGH);
    delay(flash);
    digitalWrite(8,LOW);
    digitalWrite(9,HIGH);
    delay(flash);
    digitalWrite(9,LOW);
    digitalWrite(10,HIGH);
    delay(flash);
    digitalWrite(10,LOW);
    digitalWrite(11,HIGH);
    delay(flash);
    digitalWrite(11,LOW);
    }
    
}
[code/]

Did I manage to get the "code" format OK this time?  :)