Homing 28BYJ-48 ULN2003 + AccelStepper + Hall Effect A3144 issue

Hi,

I'm new to this forum and after having searched on the internet I come to ask an answer to my problem.
I found on this forum someone who had exactly the same needs as me but he had no answer .. This topic dating back to 2012 I opened a new one.

My project is a wheel that rotates 360 °. It is controlled by Ascom driver windows (VBA) that it is controlled by a video capture software.

So: Arduino Nano --> Ascom Driver VBA --> Windows software

I have a sketch (I did not create because I do not know much coding) that positions the wheel in 5 precise positions.
FILTER1
FILTER2
.....

#include <AccelStepper.h>

#define HALFSTEP 8 // Nécessaire au bon fonctionnement du moteur
#define LEDoccupe A3
#define LEDok A1
int CurrentFilter = 0;
int homepin = A2; 

// Motor pin definitions
#define motorPin1  8       // IN1 on UL2003
#define motorPin2  9       // IN2 on UL2003
#define motorPin3  10      // IN3 on UL2003
#define motorPin4  11      // IN4 on UL2003
// Initialisation de la sequence des pins IN1-IN3-IN2-IN4 
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);


void setup() {
  stepper1.setAcceleration(3000.0);// Acceleration Max du moteur A PARAMETRER
  stepper1.setMaxSpeed(5000.0); // Vitesse Max du moteur A PARAMETRER
   stepper1.setCurrentPosition(0);
  Serial.flush();
  Serial.begin(9600);  //  Doit correspondre à votre driver ASCOM A PARAMETRER
  pinMode(homepin, INPUT);
  analogWrite(LEDok,1023);  
  analogWrite(LEDoccupe,1023);
  delay(500);
  analogWrite(LEDok,0);  
  analogWrite(LEDoccupe,0);  

}


void loop() {
  String cmd;
  if (Serial.available() >0) {
    cmd = Serial.readStringUntil('#');  
    if (cmd=="GETFILTER") {
      Serial.print(CurrentFilter); Serial.println("#"); 
    }

    else if (cmd=="FILTER0") MoveFilter(0);
    else if (cmd=="FILTER1") MoveFilter(1);
    else if (cmd=="FILTER2") MoveFilter(2);
    else if (cmd=="FILTER3") MoveFilter(3);
    else if (cmd=="FILTER4") MoveFilter(4);
    else if (cmd=="FILTER5") MoveFilter(5);
  }
}

void MoteurOFF() {
  digitalWrite(8,LOW);
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);
  digitalWrite(11,LOW);
  
}

void MoveFilter(int pos) 
{
  CurrentFilter = pos;   
       switch (CurrentFilter) 
       {
        
     case 0:                    // DEPLACEMENT FILTER 1
       analogWrite(LEDok,0);  
       analogWrite(LEDoccupe,1023);
       stepper1.run();
       stepper1.runToNewPosition(CurrentFilter * 6250);   // 6250= Distance entre chaque FILTER en nbre pas 360°/5 A PARAMETRER
       Serial.print(CurrentFilter); Serial.println("#");
       MoteurOFF();
       analogWrite(LEDoccupe,0);
       delay(750);
       analogWrite(LEDok,1023);
       MoteurOFF();       
       break;
       
     case 1:                  // DEPLACEMENT FILTER 2
       analogWrite(LEDok,0);  
       analogWrite(LEDoccupe,1023);
       stepper1.run();
       stepper1.runToNewPosition(CurrentFilter * 6250); // 6250= Distance entre chaque FILTER en nbre pas 360°/5 A PARAMETRER
       Serial.print(CurrentFilter); Serial.println("#");
       MoteurOFF();
       analogWrite(LEDoccupe,0);
       delay(750);
       analogWrite(LEDok,1023);     
       break;
       
     case 2:                  // DEPLACEMENT FILTER 3
       analogWrite(LEDok,0);  
       analogWrite(LEDoccupe,1023);
       stepper1.run();
       stepper1.runToNewPosition(CurrentFilter * 6250); // 6250= Distance entre chaque FILTER en nbre pas 360°/5 A PARAMETRER
       Serial.print(CurrentFilter); Serial.println("#");
       MoteurOFF();
       analogWrite(LEDoccupe,0);
       delay(750);
       analogWrite(LEDok,1023);    
       break;
       
     case 3:                    // // DEPLACEMENT FILTER 4
       analogWrite(LEDok,0);  
       analogWrite(LEDoccupe,1023);
       stepper1.run();
       stepper1.runToNewPosition(CurrentFilter * 6250); // 6250= Distance entre chaque FILTER en nbre pas 360°/5 A PARAMETRER
       Serial.print(CurrentFilter); Serial.println("#");
       MoteurOFF();
       analogWrite(LEDoccupe,0);
       delay(750);
       analogWrite(LEDok,1023);    
       break;
       
     case 4:                     // DEPLACEMENT FILTER 5
       analogWrite(LEDok,0);  
       analogWrite(LEDoccupe,1023);
       stepper1.run();
       stepper1.runToNewPosition(CurrentFilter * 6250); // 6250= Distance entre chaque FILTER en nbre pas 360°/5 A PARAMETRER
       Serial.print(CurrentFilter); Serial.println("#");
       MoteurOFF();
       analogWrite(LEDoccupe,0);
       delay(750);
       analogWrite(LEDok,1023);    
       break;
       
       }
       }
}

With the serial monitor I can control the wheel as well that from my software when I icons that correspond to different positions.

I bought a Hall sensor to try to create a home point for the wheel but I can not control it in the sketch. I tried several things found here and there on the forums but nothing functional.
What I would like is to add a position in void MoveFilter(int pos) that rotates the wheel until detect the sensor and the magnet at this time, puts the original position.

I thought then add this position in the setup function by calling MoveFilter(5) for example.

you can find the change that I have tried to do in CASE 5 and who does not work. When I call GETFILTER5 wheel moves only one position. She does not go to the sensor

case 5:                     // DEPLACEMENT FILTER 5
       pinMode(homepin, INPUT); 
       analogWrite(LEDok,0);  
       analogWrite(LEDoccupe,1023);
         while(digitalRead(homepin) == HIGH){ // switch not yet triggered/home
       stepper1.run();
      // stepper1.runToNewPosition(CurrentFilter * 6250); // 6250= Distance entre chaque FILTER en nbre pas 360°/5 A PARAMETRER
       Serial.print(CurrentFilter); Serial.println("#");
       MoteurOFF();
       analogWrite(LEDoccupe,0);
       delay(750);
       analogWrite(LEDok,1023);    
       break;

If anyone can give me a solution that would be great appreciated.

Here the guy from the video link that creates the code where it explains the operation.

thank you

  Serial.flush();
  Serial.begin(9600);  //  Doit correspondre à votre driver ASCOM A PARAMETRER

It is absolutely pointless to block, waiting for all pending outgoing serial data to be sent BEFORE you open the serial port.

Lose the stupid flush() call.

       stepper1.run();
       stepper1.runToNewPosition(CurrentFilter * 6250);

You don't have a clue what run() does, do you?

       MoteurOFF();
       analogWrite(LEDoccupe,0);
       delay(750);
       analogWrite(LEDok,1023);
       MoteurOFF();

If you don't trust the pins to stay off, don't assign them to the AccelStepper instance, or call the function more often. Maybe a couple of million times more.

The stepper motor will stop, without your "help" when it gets to the commanded position.

I bought a Hall sensor to try to create a home point for the wheel but I can not control it in the sketch. I tried several things found here and there on the forums but nothing functional.

Where is the code that is supposed to do that? Pretend that you are the Arduino AND that you are the stepper motor AND that you are the hall effect sensor.

Outline EXACTLY what needs to happen (Are we there yet? No? OK take another step and start over) and EXACTLY how to make that happen and EXACTLY how to determine if appropriate things have happened. Turning that into code will be trivial.

As @PaulS has said you need to study the documentation for the AccelStepper library. Spend a few hours looking at the examples that come with it.

You should have stepper1.run() in loop() and not within a function or within a CASE block. You should arrange for loop() to repeat hundreds or thousands of times per second.

Then if you want the motor to move you just give AccelStepper the new destination and it will look after everything in the background.

To move a stepper to a HOME or ZERO position you need to

check if you are already at the position
    if not
    move one step
    repeat

...R

Hello,

My wheel is drill with 5 holes. In each hole i have a colored filter. At startup of the Arduno, I've to place manualy the first filter (curentposition=0)

       stepper1.runToNewPosition(CurrentFilter * 6250);

=360°/5 so 72°

Then, when i use the serial monitor or my astronomical software i can call each filter i want.

cmd FILTER0 = movetofilter(0) = filter 1 = red color
cmd FILTER1 = movetofilter(1) = Filter 2 = green color

......

It work like a charm, no problem with this.

       MoteurOFF();
       analogWrite(LEDoccupe,0);
       delay(750);
       analogWrite(LEDok,1023);
       MoteurOFF();

my moteurOFF function is not to stop rotating the motor.
This is intended to disable the electrical supply to the motor as I send him 12v and is functioning nominally 5V

It's a coil power off option.

I have not attached the code for the homing stance because I never managed to make it work. And like I said I've never coded in my life but I understand soon enough.

I was thinking that he should not be difficult to create a new CASE and tell the motor to go for the Hall sensor.
As a filter,

cmd FILTERX= movetofilterX = move to hall effect sensort = homing

I've try to do this but with no luck.......

I am sure that the sensor works because I tried the sketch of the hall effect and led and it works.

thank's a lot

@seriousmath, I can see nothing in Reply #3 to suggest that you have considered and taken account of the Replies you have already received.

...R

Hello,

it's not that I did not take into account your remarks, it's more that I have a way English and I never programmed.
I understand what the sketch do but I not able to code it myself. Is it possible to tell me if it is possible to create a CASE for homing or the method is not good.

thank a lot

SWITCH/CASE is just a way of making decisions - for some situations it can be simpler then IF/ELSE

You should create a function containing the code to make your stepper move to the home position and then you can call that function from anywhere in your code that it is required - including as a result of a CASE.

Write a short program that does nothing except move the motor to the home position. Then you can put the code from that program into a function and use it in your larger program.

Planning and Implementing a Program illustrates the use of functions.

For the future please acknowledge replies and tell us whether they are relevant and let us know if you don't understand them. That will make it much easier and quicker to give you useful advice.

...R

Thank's Robin !

I very well understand what you mean. I tried to create two versions of code for homing, but I did not test at the moment.

Do you think I'm on the right track?

while (homepin = HIGH){
   stepper1.move(-1);
   stepper1.setSpeed(3000);
   stepper1.runSpeedToPosition();
 if (digitalRead(homepin == HIGH)){
 stepper1.move(-1);
 stepper1.runSpeedToPosition(); 
 //stepper1.run();
  }
else{
digitalWrite(LEDok, HIGH);
stepper1.setCurrentPosition(0);
  }

I think you need a combination of your two snippets.

The first snippet does not test the homePin and the second snippet does not repeat.

For the future please test your code before asking the next question - it may save you the trouble of asking it and save us the trouble of answering it.

...R

Sorry for no have test my code before asking the next question !!!!!

Well I advance in the right direction with this sensor, I created a home function probably "dirty" but it works and I call in my SETUP as I want or nearby.

So early sketch I defined this:
const byte homepin = A2;
byte hBval;

and then the function I integrates SETUP

void Home() {
analogWrite(LEDok,0);  
analogWrite(LEDoccupe,1023);
stepper1.run();  
stepper1.runToNewPosition(6250);  
hBval = digitalRead(homepin);  
while (hBval == HIGH){
stepper1.moveTo(-30000);
stepper1.run();
digitalWrite(LEDok, LOW);
hBval = digitalRead(homepin);}
digitalWrite(LEDok, HIGH); 
stepper1.setCurrentPosition(0);
MoteurOFF();
analogWrite(LEDoccupe,0);
delay(750);
analogWrite(LEDok,1023);  
Serial.print(CurrentFilter); Serial.println("#");
MoveFilter(6);
MoveFilter(0);
}

So immediately it "works" even if I would have to improve that.
and especially the wheel stop too soon, the field of the magnet is too big, I'll try to break a tiny bit to see or backward sensor.

But surely it would be better able to control for sensor voltage.

thank's

What about something simple (not tested)

void Home() {
    hBval = digitalRead(homepin); 
    while (hBval == HIGH){
        stepper1.move(-1);
        stepper1.runSpeedToPosition();
        hBval = digitalRead(homepin);
    }
    stepper1.setCurrentPosition(0);
}

But surely it would be better able to control for sensor voltage.

I don't understand.

analogWrite() takes values from 0-255

...R

Hi,

I tried your function to the home but nothing happens, the engine does not start.
Should I give the values for acceleration and speed somewhere?

To read the Hall sensor I connected on pin A2 of the nano, I used a sketch to send me the value read by the sensor is the result in binary form it seems.
I have 2 or 1023 no other value.

I think my sensor is not good because there are two type of Hall sensor.
A type 0/1 and the other type that can read a range of current value.
Maybe I say a stupidity ....

day by day, I began to understand a little more what I do by coding.

I went to find out about the library Accelstepper which allowed me to replace my function to coil power off

void MoteurOFF() {
  digitalWrite(8,LOW);
  digitalWrite(9,LOW);
  digitalWrite(10,LOW);
  digitalWrite(11,LOW);
}

using:
stepper1.disableOutputs();

seriousmath:
Should I give the values for acceleration and speed somewhere?

Of course.

I had assumed you would do that in setup() - but if you need special values for the homing function you can include them in it. My suggestion uses runSpeedToPosition() which does not use acceleration. Acceleration seems irrelevant if you are just moving a single step.

...R