noobie completely stuck!

Hi all! I’m a first time poster, and I’ve been immersing myself in arduino for a whole 2 weeks now! I have a project I’d like to finish but considering my lack of knowledge in any kind of programming, I’ve found myself completely stuck and unsure of how to proceed. Everything I’ve tried has so far either caused confusion in the board or simply hasn’t worked, so now I’ve decided to ask the experts.

The project is this, I’ve built a light source in which I’ve put an 8 segment colour wheel, with this wheel I’m using an Uno with 16x2 LCD, a voltage control box and a 12v 50:1 stepper motor with 7.5 degree steps for colour selection. I’m wanting to oscillate between adjacent segments 8/1 and then oscillate between segments 1 through to 8.

Now, I have all of the above fully working with no problems. The only problem I have is getting the wheel turning to ‘home’ and then actually trying to reach “home” upon power on or reset. I use a magnetic reed switch and a magnet on a particular segment to specify “home” on the wheel.

Here is the code I have so far and you can see at the end of the loop() I have the part for the reed switch which doesn’t interrupt the motor ‘homing’.

I can’t seem to get the motor turning from initial switch on either.

Any tips/advice is greatly appreciated and please go gentle as I really have no idea about programming to be honest.

#include <Stepper.h>

#include <LiquidCrystal.h>

/*-----( Declare Constants, Pin Numbers )-----*/
//---( Number of steps per revolution of INTERNAL motor in 4-step mode )---
#define STEPS_PER_MOTOR_REVOLUTION 24

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//---( Steps per OUTPUT SHAFT of gear reduction )---
#define STEPS_PER_OUTPUT_REVOLUTION 48 * 50  //2400 

/*-----( Declare objects )-----*/
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to

//The pin connections need to be 4 pins connected
// to Motor Driver In1, In2, In3, In4  and then the pins entered
// here in the sequence 1-3-2-4 for proper sequencing
Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 7);

/*-----( Declare Variables )-----*/

int Steps2Take;
int a=0;
int switchPin1 = 6;
int switchState = 0;
int val = 0;

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0,1);
  lcd.clear();
  lcd.print("Initializing");
  delay(5000);
  pinMode(A5, INPUT_PULLUP); // sets analog pin for input 
  pinMode(6, INPUT);   //sets reed switch to input

  
} 
  
int readButtons(int pin)
// returns the button number pressed, or zero for none pressed 
// int pin is the analog pin number to read 
{
  int b,c = 0;
  c=analogRead(pin); // get the analog value  
  if (c>990)
  {
    b=0; // buttons have not been pressed
  }   
else
  if (c>445 && c<455)
  {
    b=1;
   {osc1();} // button 1 pressed
  }     
  else
    if (c>355 && c<365)
    {
      b=2;
     {osc2();} // button 2 pressed
    }       
    else
      if (c>220 && c<240)
      {
        b=3; // button 3 pressed
      }         
      else
        if (c>10 && c<20)
        {
          b=4; // button 4 pressed
        }           
        else
          if (c<10)
          {
            b=5; // button 5 pressed
          }
return b;
}

void loop()
{
  a=readButtons(5);
  lcd.clear();
  if (a==0) // no buttons pressed
  {
    lcd.setCursor(0,1);
    lcd.print("Press a button");
  }   
  else
    if (a>0) // someone pressed a button!
    {
      lcd.setCursor(0,2);
      lcd.print("Pressed button ");
      lcd.print(a);
    }
  delay(2000); // give time to read LCD

val=digitalRead(6);
if(val == HIGH)    //   if switch is open then
  {
  Steps2Take  =  STEPS_PER_OUTPUT_REVOLUTION ; 
  small_stepper.setSpeed(0);   
  small_stepper.step(0);
  delay(500);
  }
   }
void osc1()
{
  Steps2Take  =  STEPS_PER_OUTPUT_REVOLUTION / 8;  // Rotate CW 1/8 turn
  small_stepper.setSpeed(500);   
  small_stepper.step(Steps2Take);
  delay(1000);
  
  Steps2Take  =  - STEPS_PER_OUTPUT_REVOLUTION / 8;  // Rotate CCW 1/8 turn  
  small_stepper.setSpeed(500);  // 500 a good max speed??
  small_stepper.step(Steps2Take);
  delay(1000);
}
void osc2()
{
Steps2Take  =  - STEPS_PER_OUTPUT_REVOLUTION + 300;
  small_stepper.setSpeed(500);
  small_stepper.step(Steps2Take);
  delay(1000);
  
  Steps2Take  =  STEPS_PER_OUTPUT_REVOLUTION - 300;
  small_stepper.setSpeed(500);
  small_stepper.step(Steps2Take);
  delay(1000);
}

I can't figure from your code what is connected to what. Rather than using (for example)

val=digitalRead(6);

it would make the code easier for you and for us if you use

val=digitalRead(reedSwitchPin);

or whatever it is actually connected to.

Generally speaking the way to move to the HOME position is to

  move one step, 
   check the switch
      repeat as needed

...R Stepper Motor Basics

Hi, thanks for your reply, OK so i have made the changes as you suggested which does simplify things, and your explanation makes perfect sense.

When I try to implement it in the main loop() like this

  small_stepper.setSpeed(500);
  Steps2Take = 10;
  small_stepper.step(Steps2Take);
  int val = digitalRead(reed);
  if (reed == HIGH)
 {
    small_stepper.setSpeed(0);
    Steps2Take = 0;
    small_stepper.step(Steps2Take);
    lcd.print("wheel homed");
}

obviously it just keeps on looping, so after the wheel has reached the reed switch it continues and doesn't actually stop at all, what am I missing here?

fatmanchris: When I try to implement it in the main loop() like this

Please post the whole program. Snippets are no use.

...R

OK sorry, so here is the full sketch, I have // a part I’ve been playing with so it has no effect in the main loop to which I referred to in my previous post about the motor continually stepping. And I have been playing with switch statements which to me seem to be ok but still do nothing.

// Example 25.3
/*-----( Import needed libraries )-----*/
#include <Stepper.h>

#include <LiquidCrystal.h>

/*-----( Declare Constants, Pin Numbers )-----*/
//---( Number of steps per revolution of INTERNAL motor in 4-step mode )---
#define STEPS_PER_MOTOR_REVOLUTION 24

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//---( Steps per OUTPUT SHAFT of gear reduction )---
#define STEPS_PER_OUTPUT_REVOLUTION 48 * 50  //2400 

/*-----( Declare objects )-----*/
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to

//The pin connections need to be 4 pins connected
// to Motor Driver In1, In2, In3, In4  and then the pins entered
// here in the sequence 1-3-2-4 for proper sequencing
Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 7);

/*-----( Declare Variables )-----*/

int Steps2Take;
int a=0;
int reed = 6;
int switchState = 0;
int val = 0;

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0,1);
  lcd.clear();
  lcd.print("Initializing");
  Serial.println("initializing");
  delay(5000);
  pinMode(A5, INPUT_PULLUP); // sets analog pin for input 
  pinMode(6, INPUT);   //sets reed switch to input

  
} 
  
int readButtons(int pin)
// returns the button number pressed, or zero for none pressed 
// int pin is the analog pin number to read 
{
  int b,c = 0;
  c=analogRead(pin); // get the analog value  
  if (c>990)
  {
    b=0; // buttons have not been pressed
  }   
else
  if (c>445 && c<455)
  {
    b=1;
   {osc1();} // button 1 pressed
  }     
  else
    if (c>355 && c<365)
    {
      b=2;
     {osc2();} // button 2 pressed
    }       
    else
      if (c>220 && c<240)
      {
        b=3; // button 3 pressed
      }         
      else
        if (c>10 && c<20)
        {
          b=4; // button 4 pressed
        }           
        else
          if (c<10)
          {
            b=5; // button 5 pressed
          }
return b;

delay(1000);
Serial.println("homing Wheel");
delay(1000);
  switch (val = digitalRead(reed)) 
  {
  //val = digitalRead(reed);
  if (val = LOW)
    small_stepper.setSpeed(500);
  Steps2Take = 10;
  small_stepper.step(Steps2Take);
  break;
  
  switch (digitalRead(reed) == HIGH)
  case 2:
  small_stepper.setSpeed(0);
  Steps2Take = (0);
  small_stepper.step(Steps2Take);
   break;
  }
  
  }

void loop()
{
  
  
  //Serial.println(val);
  //if (reed == HIGH)
  //{
    //Serial.println(val);
    //delay(10);
    //small_stepper.setSpeed(0);
    //Steps2Take = 0;
    //small_stepper.step(Steps2Take);
    //Serial.println("reed activated, wheel Homed");
    //lcd.print("wheel homed");
    //delay(1000);
    
{
  a=readButtons(5);
  lcd.clear();
  if (a==0) // no buttons pressed
  {
    lcd.setCursor(0,1);
    lcd.print("Press a button");
  }   
  else
    if (a>0) // someone pressed a button!
    {
      lcd.setCursor(0,2);
      lcd.print("Pressed button ");
      lcd.print(a);
    }
  delay(2000); // give time to read LCD
}
}
void osc1()
{
  Steps2Take  =  STEPS_PER_OUTPUT_REVOLUTION / 8;  // Rotate CW 1/2 turn
  small_stepper.setSpeed(500);   
  small_stepper.step(Steps2Take);
  delay(1000);
  
  Steps2Take  =  - STEPS_PER_OUTPUT_REVOLUTION / 8;  // Rotate CCW 1/2 turn  
  small_stepper.setSpeed(500);  // 500 a good max speed??
  small_stepper.step(Steps2Take);
  delay(2000);
}
void osc2()
{
Steps2Take  =  - STEPS_PER_OUTPUT_REVOLUTION + 300;
  small_stepper.setSpeed(500);
  small_stepper.step(Steps2Take);
  delay(1000);
  
  Steps2Take  =  STEPS_PER_OUTPUT_REVOLUTION - 300;
  small_stepper.setSpeed(500);
  small_stepper.step(Steps2Take);
  delay(1000);
}

The switch statements essentially have no effect whatsoever, even though the compiler has no errors. The buttons connected in series through A0 still perform their functions.

return b;

delay(1000);

That's an interesting twist on avoiding the use of "delay()"

I don't want to code to run too fast so I cannot see what's happening, I take it that it shouldn't be there then? Please remember that I really have very little idea over syntax and command structuring in regards to this language. I've tried to read and understand as best I can but with no tutor and only a handful of books to guide me, it's tricky to say the least. I cut and paste some code from here and there but only after I think I understand the function.

When you execute a return, you exit the function at that point, so anything following can never be executed; it may as well not be there

Ok that explains that then...

So is there anything else I am missing that would explain why what I have tried isn't working how I hoped it would?

If that delay after a return is the only fault in my sketch I don't think it's too bad?

I've no idea - stuff like that might as well be written in highlighter to me - it leaps off the page at me, and makes the rest hard to read.

OK can you point me to something that doesn’t look like something someone has written with a highlighter so that I can understand what it is a master of programming finds suitable to read and comprehend?

Fix the stuff that's already been pointed out, check it compiles, use the IDE's auto-format tool (ctrl-t), and repost.

I'm sorry, I don't know any masters of programming.

Hi, How have you got the reed switch wired and if it pulls the pin high, have you got a pull low resistor, 10K to pull the pin low when it is open? Or if the reed pulls low, then turn on the pull up resistor for that pin as well.

Tom...... :)

Your first answer has just sunk in, after re-reading my sketch I've noticed that I put the switch after return b; and after you explained that anything after a return is ignored in that scope it explains why it compiles OK and auto format is fine but when executing the sketch nothing happens in regards to the switch statements and operation of my motor. Thank you for the roundabout answer to my question.

I'm now at home eating a steak so I cannot try out either putting the switch statement before the return executable or in the main loop itself, can switch statements be outside of the main loop?

So now I'm going through it to make it more comprehensible to the experienced among us.

Hi Tom, yes I have a 10k ohm resistor on a breadboard wired for the reed to be normally closed 0v and when activated it gives 5v.

never seen a switch used this way. It could be done with a switch using case 0: and case 1: (0 and 1 being logic for low and high) just looks wrong. Im not good at programming so maybe theres something I don’t understand so maybe some one else can weigh in on it.

  switch (val = digitalRead(reed)) 
  {
  //val = digitalRead(reed);
  if (val = LOW)
    small_stepper.setSpeed(500);
  Steps2Take = 10;
  small_stepper.step(Steps2Take);
  break;
  
  switch (digitalRead(reed) == HIGH)
  case 2:
  small_stepper.setSpeed(0);
  Steps2Take = (0);
  small_stepper.step(Steps2Take);
   break;
  }

this would be the way I thought a switch would be used.

  val = digitalRead(reed)
  switch (val) {
 case 0://digitalRead = LOW
    small_stepper.setSpeed(500);
  Steps2Take = 10;
  small_stepper.step(Steps2Take);
  break;
  
  case 1://digitalRead = HIGH
  small_stepper.setSpeed(0);
  Steps2Take = (0);
  small_stepper.step(Steps2Take);
   break;
  }

Hi gpop1 your absolutely right, I don’t know how it got so muddled, but I have an inkling one of my colleagues messed around with it. Just before your posted again I was going through the code and noticed it wasn’t right also, here is my revised switch statement.

Serial.println("homing Wheel");
  delay(1000);
  switch (val = digitalRead(reed)) 
  {
    case 1:
    val = digitalRead(reed);
    if (val == LOW)
      small_stepper.setSpeed(500);
    Steps2Take = 10;
    small_stepper.step(Steps2Take);
    break;

    case 2:
    val= digitalRead(reed);
    if (val == HIGH)
    small_stepper.setSpeed(0);
    Steps2Take = (0);
    small_stepper.step(Steps2Take);
    break;
  }

It looks identical to how you posted, now I just need to figure out if this can be used in setup or in the main loop for it to be effective. Thank you.

switch (val = digitalRead(reed))

the brackets after the switch is the link to the case

so how do you get (val = digitalRead(reed) to equal 2?

I like using switchs but in this example a "if" looks like a better solution

Serial.println("homing Wheel");
delay(1000);
val = digitalRead(reed);
if (val == LOW) {
  small_stepper.setSpeed(500);
  Steps2Take = 10;
  small_stepper.step(Steps2Take);
}
else {
  small_stepper.setSpeed(0);
  Steps2Take = (0);
  small_stepper.step(Steps2Take);
}

OK so what I've noticed from your reply is this, first there is no need to read the value twice, as this is now stored in memory correct? second there is no need for an if statement as well because the switch is doing the comparison for me correct? The equalling of case 2 will be when the reed switch has a contact to pull it HIGH making the change from the original val I've read, thereby stopping the motor in the correct position, correct?

Thank you for helping as well by the way