DO LOOP Mystery >>SOLVED<<

I hope someone can solve a problem I am having.
The following code works great.

 do{
      StepPinToggle;
      Step_Delay(Pulse_Delay_Val[Mode_X][x][ 1]);
    }while(++count <= 1500);

Then I changed the while statement to:

}while((digitalRead(CW_Home_Pin)) == true);

The stepper motor steps a few steps and then drops out of the do loop like it sees the home sensor.

Here is the complete program

#include "Arduino.h"
#include "PinChangeInterrupt.h"


// Define macros to make the code easer to read and speed up code excution
//  by usng Port Manipulation
#define StepPinToggle       PORTD ^= 0b00000010
#define StepPinFalse        PORTD &= 0b11111101
#define StepPinValue        PORTD &  ((0b00000010) >> 1)
#define Busy_LED_On         PORTC |= 0b10000000
#define Busy_LED_Off        PORTC &= 0b01111111
#define INC_Step_Count(x)   x += ((PORTD & 0b0000010) >> 1)
#define Reset_Step_Count(x) x =  0
#define Read_HomePin(x)     digitalRead(x)  

// The followng define macro checks the delay is greater then the delay 
//    maxi in micro seconds [1500] delay value
#define Step_Delay(x)  if( x > 1500){ delay(int(x / 1000)); delayMicroseconds(int(x % 1000));} else delayMicroseconds(x)
 
// Debuging control
#define DEBUG 1   //Tell compiler to compile debug print statmnets (0 == dont compilen debug print || 1 == include debug print code)

#if DEBUG == 1
  #define debug(x) Serial.print(x)
  #define debugln(x) Serial.println(x)
  #define debugF(x) Serial.print(F(x))
  #define debuglnF(x) Serial.println(F(x))
  #define debug_BIN(x) Serial.print(x, BIN)
  #define debugln_BIN(x) Serial.println(x, BIN)
  #define debug_HEX(x) Serial.print(x, HEX)  
  #define debugln_HEX(x) Serial.println(x, HEX)  
  #define debug_SerialWait while(!Serial)
  #define debug_IF_Delay(x) if(x > 1500){debugF("Delay > 1500 || ");debug(int(x / 1000));debugF("mS /// "); debug(int( x % 1000));debuglnF("uS");} else{ debugF("Delay = ");debug(x);debuglnF("uS");}
  #define debug_Delay(x) delay(x)} 

#else
  #define debug(x)
  #define debugln(x)
  #define debugF(x)
  #define debuglnF(x)
  #define debug_BIN(x)
  #define debugln_BIN(x)
  #define debug_HEX(x)
  #define debugln_HEX(x)
  #define debug_SerialWait
  #define debug_IF_Delay(x)
  #define debug_Delay(x)
#endif

// First defne what are PI signal pins
const byte  Smack_Intensity_Pin_B4 = 18; 
const byte  Smack_Intensity_Pin_B3 = 19;
const byte  Smack_Intensity_Pin_B2 = 20;
const byte  Smack_Intensity_Pin_B1 = 21;
const byte  DIR_IN_Pin        = 22;
const byte  Run_Pin           = 23;
const byte  Busy_Pin          = 13;
const byte  Abort_Pin         = 15;
const byte  ToyType_Pin_MSB   = 16;
const byte  ToyType_Pin_LSB   = 14;

// Now define the outpins that control the DRV8825 stepper motor driver
const byte  Step_Pin        =  2;
const byte  DIR_Out_Pin     =  3;
const byte  CW_Home_Pin     = 12;
const byte  CCW_Home_Pin    = 11;

// Now define the global varables
volatile byte Home_Pin         = CW_Home_Pin;
byte    Toy_Type               = 0;
byte    Smack_Intensity_Value  = 5;
volatile bool Abort_Flag         = false;
uint16_t  Angle_90_Count         = 622;
uint16_t  Angle_180_Count        = 1422;

//Define macro valareables
const bool      CW              = false;
const bool      CCW             = true;


// DM8825 step divide number.. The only alowed Mode numbers are 4, 8, 16 ONLY
const byte    Mode = 8; // Set up step divider
const byte    Mode_Pin_0    = 10;
const byte    Mode_Pin_1    =  9;
const byte    Mode_Pin_2    =  7;
const byte    Angle_90_Count_M2   =  78;
const byte    Angle_180_Count_M2  =  178;

const uint8_t   Angle_90_Count_M4   =   156;
const uint16_t  Angle_180_Count_M4  =  356;

const uint16_t  Angle_90_Count_M8   =  311;
const uint16_t  Angle_180_Count_M8  =  711;

const uint16_t  Angle_90_Count_M16  =  622;
const uint16_t  Angle_180_Count_M16 = 1422;

uint8_t Mode_X = 0;

// Now define an array of the step pulse array
                     
// Decode the Smack_Intensity to stepper motor operations
/*     delay is the number of micro seconds for the require step pluse
       Smack_Bottom(int 90 Degree Step Delay , int 180 Degree Step Delay)

   Stepper Motor step angle is 1.8 degree which is divided by the MODE number 
      Mode  2 = 0.900  Deg/Step
      Mode  4 = 0.450  Deg/Step
      Mode  8 = 0.225  Deg/Step
      Mode 16 = 0.1125 Deg/Step

   Number of steps to the desired Whip-Angle equals ===>> [ (Impact-Angle - Home-Postion) / Sept-Angle ]
      Angle ->   90 || 180
      Mode  2 =  78 || 178
      Mode  4 = 156 || 356
      Mode  8 = 311 || 711
      Mode 16 = 622 ||1422

    Now we know how many steps to the desired angle we can now calculate the stepping rate for each intensity setting.
      Step-Pulse-Width  = (Swing-Time / Step-Count)
      Then we divide by 2 to achive 50% duty cyvle (Step-Pulse on and off time are equal).
*/       
// Step Delay Look Up Table
// Spread Sheet .1 Seconds || 25% Strps
const unsigned long int  Pulse_Delay_Val [10][4][2] =
                {
                  { // Intensity 10% 
                    {   4776 ,2093 },  // Mode 2 >> Angle 90 , Angle 90.
                    {   2358 , 1046 },  // Mode 8 >> Angle 90 , Angle 180
                    {   1198 ,  524 },   // Mode 16 >> Angle 90 , Angle 180
                    {    599 ,  262 }   // Mode 16 >> Angle 90 , Angle 180
                  },                                
                  { // In tensity 20%   
                    {  3821 , 1674 },
                    {  1886 ,  837 },
                    {   958 ,  419 },
                    {   479 ,  210 }
                  },
                  {  // Intensity 30%        
                    {  3057 , 1339 },
                    {  1509 ,  670 },
                    {   767 ,  335 },
                    {   383 ,  168 }
                  },
                  { // Intensity 40% 
                    {  2445 , 1072 },
                    {  1207 ,  536 },
                    {   613 ,  268 },
                    {   307 ,  134 }
                  },
                  { // Intensity 50% 
                    { 1956 ,  857 },
                    {  966 ,  429 },
                    {  491 ,  215 },
                    {  245 ,  107 }
                  },
                  {// Intensity 60% 
                    { 1565 ,  875 },
                    {  773 ,  343 },
                    {  393 ,  172 },
                    {  196 ,   86 }
                  },
                  { // Intensity 70% 
                    { 1252 ,  549 },
                    {  618 ,  274 },
                    {  314 ,  137 },
                    {  157 ,   69 }
                  },
                  { // Intensity 80% 
                    { 1002 ,  439 },
                    {  494 ,  219 },
                    {  251 ,  110 },
                    {  128 ,   55 }
                  },
                  { // Intensity 90% 
                    {  801 ,  351 },
                    {  396 ,  176 },
                    {  201 ,   88 },
                    {  100 ,   441 }
                  },
                  { // Intensity 1Q00% 
                    {  641 ,   281 },
                    {  316 ,   140 },
                    {  161 ,    70 },
                    {   80 ,    35 }
                  }
                };
void setup(){

// Initialize and start UBS for print debug points
  Serial.begin(115200);
  debug_SerialWait;

 // Setup and Initialize the GPIO pins
  pinMode(Smack_Intensity_Pin_B4, INPUT);
  pinMode(Smack_Intensity_Pin_B3, INPUT);
  pinMode(Smack_Intensity_Pin_B2, INPUT);
  pinMode(Smack_Intensity_Pin_B1, INPUT);
  pinMode(Run_Pin,           INPUT);
  pinMode(Abort_Pin,         INPUT);
  pinMode(DIR_IN_Pin,        INPUT);
  pinMode(CW_Home_Pin,       INPUT_PULLUP);
  pinMode(CCW_Home_Pin,      INPUT_PULLUP);
  pinMode(ToyType_Pin_MSB,   INPUT);
  pinMode(ToyType_Pin_LSB,   INPUT); 
  pinMode(Busy_Pin,          OUTPUT);
  pinMode(DIR_Out_Pin,       OUTPUT);
  pinMode(Step_Pin,          OUTPUT);
  pinMode(Mode_Pin_0,        OUTPUT);
  pinMode(Mode_Pin_1,        OUTPUT);
  pinMode(Mode_Pin_2,        OUTPUT);
 

//Set output pins to defult values
  StepPinFalse;
  digitalWrite(DIR_Out_Pin, false);
  Busy_LED_Off;

  // Set the motor driver step divide number
  switch (Mode){
    case 2:
      digitalWrite(Mode_Pin_0 , true);
      digitalWrite(Mode_Pin_1 , false);
      digitalWrite(Mode_Pin_2 , false);
      Angle_90_Count  = Angle_90_Count_M2;
      Angle_180_Count = Angle_180_Count_M2;
      Mode_X = 0;
      break;

    case 4:
      digitalWrite(Mode_Pin_0 , false);
      digitalWrite(Mode_Pin_1 , true );
      digitalWrite(Mode_Pin_2 , false);
      Angle_90_Count  = Angle_90_Count_M4;
      Angle_180_Count = Angle_180_Count_M4;
      Mode_X = 1;
      break;  
         
    case 8:
      digitalWrite(Mode_Pin_0 , true );
      digitalWrite(Mode_Pin_1 , true );
      digitalWrite(Mode_Pin_2 , false);
      Angle_90_Count  = Angle_90_Count_M8;
      Angle_180_Count = Angle_180_Count_M8;
      Mode_X = 2;
      break;
  
    case  16:
      digitalWrite(Mode_Pin_0 , false);
      digitalWrite(Mode_Pin_1 , false);
      digitalWrite(Mode_Pin_2 , true );
      Angle_90_Count  = Angle_90_Count_M16;
      Angle_180_Count = Angle_180_Count_M16;
      Mode_X = 3;
      break;

    default:
      debugF(" Invailed Mode Number [ ");
      debug(Mode);
      debugF(" ]. Vaild Mode numbers are 4, 8 or 16");
      debuglnF(" Please recompile the sketch with a vailed Mode number");  
      do {
      }while (true);
      break;
  }
  debugln();  
  debuglnF(" >> Set Up Complete <<"); 
  debug(F(" Mode Number = "));
  debug(Mode );
  debugF("[ ");  
  debug(digitalRead(Mode_Pin_0));
  debug(digitalRead(Mode_Pin_1));   
  debug(digitalRead(Mode_Pin_2));
  debuglnF(" ]");
  
  debugF("\t Mode_X >> ");
  debug(Mode_X);
  
  debugln();
  debug_SerialWait;
  delay(5000);
}

void loop() {
   
// Sytem test code  
  unsigned long int count = 0;
  uint16_t Dir_Count = 356;
  unsigned long int Delay = 140; // microSecond
  uint8_t  x = 0;
  uint8_t  Home_Pin = CCW_Home_Pin;
  digitalWrite(DIR_Out_Pin, false);

debug_SerialWait;
 Mode_X = 0;
  delay(5000);
//  Mode_X = 0;
  do{
      debug_IF_Delay(Pulse_Delay_Val[Mode_X][x][1]);

    debugF("\tMode_X >> ");
    debugln(Mode_X);
    debugF("\tx >> ");
    debugln(x);
    debuglnF("*****************");
    
    
    Busy_LED_On;
    StepPinFalse;
  if(digitalRead(DIR_Out_Pin) == false){
    for (int StepCount = 0; StepCount<1500; StepCount++) {
      StepPinToggle;
      Step_Delay(Pulse_Delay_Val[Mode_X][x][ 1]);
    }
  }
  else{
    debuglnF("DIR Out Pin = 1"); 
    count = 0;    
    do{
      StepPinToggle;
      Step_Delay(Pulse_Delay_Val[Mode_X][x][ 1]);
//    }while(++count <= 1500);
   }while((digitalRead(CW_Home_Pin)) == true);  << Problem here.
  }

  Busy_LED_Off;

    debugF("Home sensores >> CW = ");
    debug(digitalRead(CW_Home_Pin));
    debugF(" || CCW = ");
    debugln(Read_HomePin(CCW_Home_Pin));
    
    if((x += digitalRead(DIR_Out_Pin)) > 9){ 

      if( ++Mode_X > 2) Mode_X = 2;
      
      x=0;
    }
    digitalWrite(DIR_Out_Pin,!digitalRead(DIR_Out_Pin));

//    digitalWrite(DIR_Out_Pin,!digitalRead(DIR_Out_Pin));

   
    delay(2500);
    debug_SerialWait;

   }while(true);

The conto\toler is ItsyBitsy 32u4 3V and the sensor is a Photo Interrupter Optical Sensor (ITR9608F). I checked the senor uninstalled an it works as expected. Even the controller dected the sensor proprly.

digitalRead returns an int that is either HIGH or LOW.
Now does the statement (partly processed) while ((HIGH) == true) make sense?
BTW, is true and TRUE the same? IDK off the top of my head.

Comparing HIGH == true will yield true most of the time... but no guarantee...

1 Like

Where is this defined?

Not a function either. Your intent was StepPinToggle(); (but there is no function by that name). Missing part of the code?

xfpd:
StepPinToggle is defined as a macro.

#define StepPinToggle       PORTD ^= 0b00000010

You can find all macros in the full code I posted in pervuse post.

1 Like

Just to make your code as hard to debug as possible?
Now I need to lookup if byte 2 of PORTB is the same as your CW_Home_pin...

Lower case true is the accepted form, but HIGH would be better.

However, given the do...while structure @RocketNut is using, I'm thinking that, presuming he's got the right pin, then since it has a pullup the most likely problem is a bad switch/loose wire.

Come on guys. I have been doing electronics for over 20 years.
I have checked to ensure I am using the correct GPIO pin (D12). Yes I am using the GPIO pin's PULL_UP

pinMode(CW_Home_Pin,INPUT_PULLUP);

I check the sensor controller input to ensure the controller reads the sensor correctly.
I also checked the noise with an O-Scope, which is less than 10mV.
The sensor's output is a phototransistor so there is no switch debouncing.
For me, there is a problem with the controller/code.

I am using macros to make the code easier to read and to reduce possible typos with the more complex lines of code. Like the Step_Delay macro:

#define Step_Delay(x)  if( x > 1500){ delay(int(x / 1000)); delayMicroseconds(int(x % 1000));} else delayMicroseconds(x)
 

I looked, nothing obvious with your code, hence my reply. Have you tried an alternate pin? Seriously, that's where snark hunting goes sometimes, when we've eliminated the obvious. (I make no excuses for those who have gone down the rabbit hole on non-essential style concerns, except that it does happen to all of us; don't let it bother you, they are, after all, actually trying to help you...).

And we would know that how? "RocketNut" doesn't really convey much. Besides, the names people choose are sometimes a disguise chosen to hide their complete noobness.
You didn't point us to your CV, after all. Look, we see a huge variety of styles, and a huge variety of abilities. It's incredibly frustrating to 'assume' a skill level and, 47 posts later, find out the noob isn't aware of something utterly basic. Better to assume a lesser skill level until proven different. This is, at least partly, a BEGINNER's forum.

1 Like

Then you have been staring at the same thing all day, and it has not changed itself. Been there. Entertain the "dumb" responses as if you, also, do not know why this is happening.

Try this:

} while(digitalRead(CW_Home_Pin)) { // while not zero

The question isn't about the do/while statement.

The question is why

digitalRead(CW_Home_Pin)

becomes LOW, 0 and false when you weren't expecting it to do.

If you printed the bake in the body of the loop, you would confirm that the statement is operating correctly. I certainly hope.

a7

I think I might have found a clue of what is going on
I change the while loop code to the following

 while(zz){
      StepPinToggle;
      Step_Delay(Pulse_Delay_Val[Mode_X][x][ 1]);
      zz = digitalRead(CCW_Home_Pin);
      debug(digitalRead(CCW_Home_Pin));
      debugF(" || ");
      debugln(zz);
    }

I added print digitalRead(CCW_Home_Pin. Then I printed the zz value. The digitalRead(CCW_Home_Pin prints the correct value of the I/O pin, but the zz reads the I/O pin wrong. Meaning they do not match. digitalRead(CCW_Home_Pin reads 1 but zz value is 0!! Thus the while loop is working correctly.
So why is zz reading the wrong value?

Frankly I doubt zz is wrong. I think your debug trick is biting you. Is it possible this little gem is fooling you? Have you tried that in a little test program, combined with your define, to verify that it works? That's what I'd look at first.

Here is the define code:

#define DEBUG 1   //Tell compiler to compile debug print statmnets (0 == dont compilen debug print || 1 == include debug print code)

#if DEBUG == 1
  #define debug(x) Serial.print(x)
  #define debugln(x) Serial.println(x)
  #define debugF(x) Serial.print(F(x))
  #define debuglnF(x) Serial.println(F(x))
  #define debug_BIN(x) Serial.print(x, BIN)
  #define debugln_BIN(x) Serial.println(x, BIN)
  #define debug_HEX(x) Serial.print(x, HEX)  
  #define debugln_HEX(x) Serial.println(x, HEX)  
  #define debug_SerialWait while(!Serial)
  #define debug_IF_Delay(x) if(x > 1500){debugF("Delay > 1500 || ");debug(int(x / 1000));debugF("mS /// "); debug(int( x % 1000));debuglnF("uS");} else{ debugF("Delay = ");debug(x);debuglnF("uS");}
  #define debug_Delay(x) delay(x)} 

#else
  #define debug(x)
  #define debugln(x)
  #define debugF(x)
  #define debuglnF(x)
  #define debug_BIN(x)
  #define debugln_BIN(x)
  #define debug_HEX(x)
  #define debugln_HEX(x)
  #define debug_SerialWait
  #define debug_IF_Delay(x)
  #define debug_Delay(x)
#endif

They work properly.

The way to tell is to get rid of them and see if the behavior changes. It really doesn't pay to get too cute with preprocessor macros, they will bite you.

2 Likes

Do you see the same behaviour with a stronger external pull up using a lower resistance?

analogRead(1)!!! Where did that come from?

Why is this thread marked "SOLVED"?
What was the solution?