trying to build a sort of flip clock but...

38 views
Skip to first unread message

Matthijs Muller

unread,
Sep 12, 2022, 7:08:09 PM9/12/22
to accelstepper
I call for a help here.

I am building an Artwork that comprises of a sort of "flip clock", with 6 "digits" (secs, 10secs, min, 10 mins, hrs, 10hrs) run with steppers.
I integrated an RTC and I managed to make the individual digits run on time.
But I also want to make the digits run "crazy" every once in a while.
And that is where the problems start.
I wrote several different variations which, when run individually, work.
I wrote a random selector (with switch case) and with timers, which works.
But once I start putting things together the problems start.
Some variations suddenly won't work, or inherit positions (or other settings) from previous variations, etc.

In the beginning things were going terrible, but after I studied the accelstepper library through the very helpfull "missing manual", things started to work a bit better.
Nevertheless now I am on a point where I manage to have two variations running (more or less), but several of them not. And I don't see why.
In the current building phase I write for 1 or at the most 3 steppers. Once I have that running I expand with the other ones.
The whole should run on a Mega board. For now I test on an Uno.
I use stepperdrivers with microstepping 3200stp/evo.

I am able to program on a very basic level so this project is pushing me at (or rather over) the boundaries of my abilities.
I would be extremely gratefull when some of you might be able to help me on track again.

The code has become fairly long so what I can do here, for a start, is publish some relevant parts, to show my (simplistic) approach.
Many thanks in advance to all who take their time to give it a look!
Matthijs

// DECLARATIONS==================================
// TIME =========================================
#include <virtuabotixRTC.h> //Library used  (pins 2,4,5)
virtuabotixRTC myRTC(5,4,2); //Clk,Dat,Rst
#include <elapsedMillis.h>

byte lastSecRead = 0;   // get hold of last reading to see how much time past since
byte last10SecRead = 0;
byte lastMinRead = 0;
// ETC.

byte secDiff = 0;    // track/calculate  difference between the actual time and the lastRead
byte sec10Diff = 0;  
byte minDiff = 0;
// ETC.

elapsedMillis writeTime;      // for debugging
elapsedMillis startTime;      // for startdelay in slowSwing
elapsedMillis onClockTimer1;  // timers for the selection clock or variation
elapsedMillis offClockTimer1;
//ETC

int maxOnClockT1 = ((random (10,60)*1000*7); //setting max to ClockasAClock runs
int maxOffClockT1 = ((random (5,50)*1000);   // setting the max for the variations (10-50secs)
bool onClockEnabled1 = true;  // flag if random variation has finished, so clock can restart.
//ETC

bool offClockAll;             // keeps track of the amount of steppers that do NOT run the clock
int countOffClockAll;         // add all offClockAll true together      

long ranMov1;                 // the randomMovement var    
bool ranNeed1 = 1;            // check if a new random is needed to avoid a stream of randoms
//ETC

//STEPPER========================================================================
  #define FuRo 3200.0   // one Full Rotation set in the hardware at the driver!!!
//====================  // the number is according to the hardwaresettings
//====================  // Positions, (max)Speed, (max)Accel are related to
// the driversetting. By changing the setting in the driverhardware you only
// have to change the "FuRo" here and all should run well...

#include <AccelStepper.h>

const int stepPin1 = 8;
const int dirPin1 = 9;
const int enablePin1 = 12;  
//the enablePin I will use differently, within a variation, outside the stepperdriver.                      
//stepper1.setPinsInverted (false, false, true); //(directionPin, stepPin, enablePin);
// ETC.



AccelStepper stepper1(AccelStepper::DRIVER, stepPin1, dirPin1, enablePin1);          
// ETC.

bool isRunning;
bool runAllowed1 = false; // the main GO flag for the run routine
//ETC

//STEPPER POSITIONS ==============================

//// ABSOLUTE //// new position is hard-coded
int absTen[] = {FuRo,((FuRo/10)*1),((FuRo/10)*2),((FuRo/10)*3),((FuRo/10)*4),
                    ((FuRo/10)*5),((FuRo/10)*6),((FuRo/10)*7),((FuRo/10)*8),((FuRo/10)*9)};
int absSix[] = {((FuRo/1)*1), ((FuRo/6)*1),((FuRo/6)*2),((FuRo/6)*3), ((FuRo/6)*4),((FuRo/6)*5)};
int absThree[] = {((FuRo/1)*1), ((FuRo/3)*1), ((FuRo/3)*2)};

//// RELATIVE //// new position is the many steps from current position
int relTen = absTen[1];  // the relative position-goal derides from the absolute position and from FuRo
int relSix = absSix[1];  
int relThree = absThree[1];

// these are the vars for the switch-cases, which I will use extensively
byte swVar1 = 1;   // var for switch of variations (only 1: 1 runs at a time)
//ETC

bool varDone = true; // the flag used to signal a variation is done(instead of a clock deciding to return)
int vibMax = 5; // max amount of vibrations

//=================================================
//NEW VARS DEVELOPED DURING TRIALS

int ranDintm1;  // the intermediate random needed to create the randDirX
int ranDirX1;   // the random that works like a "multiplier" for the direction - or +

//====================
// END OF DECLARATIONS
//=================================================
// SETUP
//=================================================

void setup() {
      Serial.begin(9600);
      randomSeed(analogRead(A0));

      myRTC.updateTime();               // First: Read the clock    
      // print Time as a check if clock-module is still running fine
      Serial.print("   Hour =     "); Serial.print(myRTC.hours);Serial.print(":");
            Serial.print (myRTC.minutes); Serial.print(":");Serial.println(myRTC.seconds);
   
      ReadNewSec();     // initiate the calculations by once running them all to 0.
      ReadNew10Sec();
      ReadNewMin();
      // ETC.

      stepper1.setMaxSpeed(FuRo *4);      // the maximum without load was more than 15000 for
      stepper1.setAcceleration(FuRo *4);  // both speed and acceleration at 3200 > (FuRo *5)
      //stepper1.setMinPulseWidth(10);      // the 6600 seems to work more reliable with 15 setting
      // ETC.                             // be careful with this setting though    
      }    

//====================
// END OF SETUP
//=================================================
// LOOP
//=================================================
   updateTimeReadings();
   selectAndRun();
   runTheSteppers();

//====================
// END of LOOP
//================================================
// SELECTING THE VARIATION (or run the clock)
//================================================

void selectAndRun1()               // the condition of maxOffClock motors has to be added
{  
          if (( onClockTimer1 < maxOnClockT1) || (varDone == false)){
                               // as long as maxOnClockTime isn't reached or a variation didn't say ready
          runAllowed = true;
          ranNeed1 = true;                        //flag the random in Need
          randm1();                               //(keep) running the randomizer for future random
          calcRanDir();                           // (keep) random seek for direction
          ranMovPar();                            // keep random seek for randomMovement Parameters
          justJump();              // The Clock
          offClockTimer1 = 0;                     // reset the offClockTimer for a future fresh start
          }                                      
     
     
          else {
               ranNeed1 = false;
               switch (ranMov1) {
     
               case 1:                            
               if (offClockTimer1 > maxOffClockT1){    // when the timer is reached
               offClockAll = false;                    // keep track of nr of off Clock motors
               onClockEnabled1 = true;
               onClockTimer1 = 0;                      // reset onClockTimer (so Clock restarts)
               }                                      
               else {                                  // as long as the maxOffClockTime is NOT met
               runAllowed1 = true;
               secSwing();             // The variation
               offClockAll = true;                     // keep track of nr of off Clock motors
               onClockEnabled1 = false;
               }                                      
               break;

               case 2:
               if ((offClockTimer1 > maxOffClockT1)){  
               offClockAll = false;                        
               onClockEnabled1 = true;                    
               onClockTimer1 = 0;                          
               }                                      
               else {
               runAllowed1 = true;
               secSwing();            // Another variation
               offClockAll = true;
               onClockEnabled1 = false;  
               }                                      
               break;

               case 3:                              
               if (offClockTimer1 > maxOffClockT1){  
               offClockAll = false;                    
               onClockEnabled1 = true;
               onClockTimer1 = 0;                      
               }                                        
               else {                                  
               runAllowed1 = true;
               moveRandom();          // Another variation
               offClockAll = true;
               onClockEnabled1 = false;
               }                                      
               break;
               }                                                          
          }                                            
      }


//=================================================
// FUNCTIONS TIME
//=================================================

void updateTimeReadings()  {
     myRTC.updateTime();                             // Read the clock    
     secDiff = (myRTC.seconds - lastSecRead);        // Difference @secs between a certain moment and now
     sec10Diff = (myRTC.seconds /10)- last10SecRead; // Difference @10secs
     minDiff = (myRTC.minutes - lastMinRead);        // Difference @mins
     // ETC.
}


//=================================================
// FUNCTIONS MOVEMENT VARIATIONS
//=================================================

// JUMP 1/10th or 1/6th or 1/3rd evolution at a time
//==================================================

void justJump()   // works!    // each sec/min/etc the digit "jumps" to its new position
    {                          // sec, min, hrs > rotation/10  10sec,10min > rotation/6
                               // 10hrs > rotation / 3.
   
      if ((secDiff < 1)  &&  (lastSecRead - myRTC.seconds != 59) )
      { }  // as long as one second isn't passed, do nothing & and a rollover so 60>0          
      else{                                                                    
          Reset();
          runAllowed1 = true;
          varDone = false;
          stepper1.move(relTen);
          stepper1.setMaxSpeed(FuRo*2);  //The speed has to be defined AFTER move(To)
          stepper1.setAcceleration(FuRo*1.5);
          varDone = true;
          ReadNewSec();                                                                    
      }
    }


//RUN SECS IN GENTLE SWING
//==========================================================                          
// First the motor is switched off 1,5 second, so all is hanging down
// (this isn't programmed yet. But I expand the cases for that.)
// Then the motor gently starts swinging 1/10FuRo left, 1/10 right


void secSwing()  // works within the selector, but with restrictions
    {
   
    switch (swVar1)                 //
    {                  // without a Reset it takes over settings from the previous
    Reset();           // but with the Reset I loose track of my positions
    varDone = false;   // flag the variation in action
   
    case 1:
         // enablePin() = high;      // or switch this with the funktion direct?
         runAllowed1 = false;
         if (startTime > 1500){       // timecondition for the start
         runAllowed1 = true;
          //enablePin() = low;       // enablePin low = motor switched ON
          //swVar1 = 2;              // move to next case
         }                           // without a break it automatically moves on
   
    case 2:                               // this makes the first push > astable
        runAllowed1 = true;      
        stepper1.setMaxSpeed(FuRo);
        stepper1.setAcceleration(FuRo/10);  
        stepper1.moveTo(FuRo/10);  
        swVar1  = 3;
    break;
   
    case 3:                               // this starts an occilation
      if (stepper1.distanceToGo() == 0){
      stepper1.setMaxSpeed(FuRo);
      stepper1.setAcceleration(FuRo/10);
      stepper1.moveTo(-stepper1.currentPosition());
      }
      //if ( h == vibMax){    // I want to have the variation say: done
      //  varDone = true;     // and then return to the selectionprogram/clock
      //  runAllowed1 = false; // but that doesn't work (yet). Switched back by the clock
      //}                     // of the selector, makes me also lose track of the position.
    break;
    }}


// RANDOM MOVEMENT Variation
//=========================================

// RANDOM (random, steps, direction, acceleration, speed)

void moveRandom()  // doesn't work within the selector
{
     varDone = false;   //flag the variation is running
     Reset();           //without the reset it inherits settings
     runAllowed = true;
     stepper1.setMaxSpeed((rand() % 1500) + 1);
     stepper1.setAcceleration((rand() % 500) + 1);
     stepper1.moveTo((rand() % 32000) * ranDirX1);  
     varDone = true;    
             
     //         if (stepper1.distanceToGo() ==  0 ){              //again: trying to let the variation
     //         varDone = true;    //flag the variation is ready  //decide when to return to the selector
     //         }                                                 //this doesn't work ...
}  

//=========================================
// RANDOMS CALCULATED
//=========================================
// ranNeed, a boolean that flags the need for a new random variation selection (rename in randSwNeed?)
// ranMov, the Switch-variable that defines which case is selected: resulting in random Movement.

void randm1(){                      // calculate a random Movement (switch-case)
  if ( ranNeed1 == true) {          // to avoid repeated randoms  
     ranMov1 = random (1,4);        // 1st nr is the minimum, 2nd nr is the "smaller than"!!!
     }                              // else if
}                                   // end
//ETC

//=========================================
// RANDOMIZING THE DIRECTION ==============
// ranDintm is an intermediate var needed to calculate a random direction
// randDirX is the random Directory + or - (Multiplier) that defines the direction

void calcRanDir1(){         // create a positive and negative random direction
  ranDintm1 = random(0,2);  // randomize between 0 and 1 // interim Var to aqquire randDirX
  if (ranDintm > 0){        // if 1 > +1
    ranDirX1 = 1;}          // CW or CCW depending on wiring
  else {                    // else  -1
    ranDirX1 = -1;          // CCW or CW depending on wiring
    }
}
//ETC

//=====================================================================
// RANDOMISED VARIATION

void ranMovPar(){
move2 = (random( FuRo * 2));
sMaxS = (random( FuRo * 2)+1);
aCell = (random( FuRo * 2)+1);
 
}


//==========================================
// RESET
//==========================================

void Reset() // created to avoid the variations inherit settings from each other
{            // but doing so I lose track of my position which is annoying but not impossible
             //  and still: inheriting occurs at some occasions

             runAllowed1 = false;            //running disabled
             stepper1.disableOutputs();      //disable power
             stepper1.setAcceleration(0);
             stepper1.setMaxSpeed(0);
             stepper1.setCurrentPosition(0); //Reset current position. "new home"
             stepper1.enableOutputs();
             runAllowed1 = true;
}

//=================================================
// RUN
//=================================================

void runTheSteppers()
  {
    if (runAllowed1 == true)
      {
      stepper1.enableOutputs();    //enable pins
      stepper1.run();              //step the motor (this will step the motor by 1 step at each loop)
      }
    else                           //if the runallowed is FALSE, don't do anything
      {
      stepper1.disableOutputs();   //disable outputs
      }
  }
//ETC

Jim Larson

unread,
Sep 12, 2022, 11:23:07 PM9/12/22
to accelstepper
This is an amazing project! Hopefully, you will post a link to a video when it is all working.

The first thing I notice is that using an int to hold a number that can be as large as 420,000 is going to cause problems. Ints on the Mega and Uno can only be 32,000 or so.
int maxOnClockT1 = ((random (10,60)*1000*7); //setting max to ClockasAClock runs

The next question I have is why are you using 32000 steps per rotation? That's fine if you want to do that, but the maximum speed you can run a stepper at with an Uno or Mega is about 1000 steps per second - especially if you are running multiple motors. I suggest slowing your step rate to maybe 200 steps per rotation - you can try speeding it up if everything works.

I don't think you really need to use stepper1.enableOutputs() before every call to run(). This is not necessary and just wastes time - unless you have specific evidence to the contrary. Same with calls to setSpeed() - not needed if you're using run().

I'll continue looking at your code and see if I can offer more suggestions.

Perhaps you can provide a complete program that just uses one motor? Then we could see a version that we could try out.

              -jim

Matthijs Muller

unread,
Sep 13, 2022, 9:29:02 AM9/13/22
to accelstepper

Hello Jim,

thank you so much for your time and effort.
Of course I will post (links to) imagery when all is working. And to give you some idea of what it is going to look like: the flips aren't flips with numbers but fly swats. The whole thing will be quite ironical (with a serious undertone).

The maxOnClockT1 integer didn't cause me problems yet, because for testing I put in a much smaller static number (10.000 milliseconds). But it is very helpful to know this in advance!
Your next question, about the 32000 steps per rotation is confusing me a little. I wrote 3200.0 where the xxx.0 is meant to be a decimal. (I did so because I often divide this number). I am afraid that the difference in the use of points and comma's, between Europe and the US confuses me here. But: I use 3200 steps per rotation and that is how the system at the moment reacts with one motor.
I was aware of the possible impact of 6 motors running with that amount of steps(=data). That is why I used the "define FuRo" and tried as much as I could to connect all related values to it, so it would be easy to change, not only on the hardware, but also in the software. Once all is running I can adjust that according to my needs (as smooth as possible) and the abilities of the Mega.
I was wondering myself if the enableOutputs would be needed each run, so: good to know, I will change that (later), same to the setSpeed()s.

I hereby post the whole prog, so far, filtered out everything but the first stepper (seconds).
I already took out some of the errors you pointed at, but didn't take out the enableOutputs and SetSpeed jitter yet.
That code is now underneath your reaction.

Matthijs

Op 13.09.2022 om 05:23 schreef Jim Larson:
This is an amazing project! Hopefully, you will post a link to a video when it is all working.

The first thing I notice is that using an int to hold a number that can be as large as 420,000 is going to cause problems. Ints on the Mega and Uno can only be 32,000 or so.
int maxOnClockT1 = ((random (10,60)*1000*7); //setting max to ClockasAClock runs

The next question I have is why are you using 32000 steps per rotation? That's fine if you want to do that, but the maximum speed you can run a stepper at with an Uno or Mega is about 1000 steps per second - especially if you are running multiple motors. I suggest slowing your step rate to maybe 200 steps per rotation - you can try speeding it up if everything works.

I don't think you really need to use stepper1.enableOutputs() before every call to run(). This is not necessary and just wastes time - unless you have specific evidence to the contrary. Same with calls to setSpeed() - not needed if you're using run().

I'll continue looking at your code and see if I can offer more suggestions.

Perhaps you can provide a complete program that just uses one motor? Then we could see a version that we could try out.

              -jim

-----------------------------------------------------------------------------------------


// DECLARATIONS==================================
// TIME =========================================
#include <virtuabotixRTC.h> //Library used  (pins 2,4,5)
virtuabotixRTC myRTC(5,4,2); //Clk,Dat,Rst
#include <elapsedMillis.h>

byte lastSecRead = 0;   // get hold of last reading to see how much time past since
byte last10SecRead = 0;
byte lastMinRead = 0;
// ETC.

byte secDiff = 0;    // track/calculate  difference between the actual time and the lastRead
byte sec10Diff = 0;  
byte minDiff = 0;
// ETC.

elapsedMillis writeTime;      // for debugging
elapsedMillis startTime;      // for startdelay in slowSwing
elapsedMillis onClockTimer1;  // timers for the selection clock or variation
elapsedMillis offClockTimer1;
//ETC

long maxOnClockT1 = ((random (10,60)*1000*7); //setting max to ClockasAClock runs
long maxOffClockT1 = ((random (5,50)*1000);   // setting the max for the variations (10-50secs)

bool onClockEnabled1 = true;  // flag if random variation has finished, so clock can restart.
//ETC

bool offClockAll;             // keeps track of the amount of steppers that do NOT run the clock
int countOffClockAll;         // add all offClockAll true together      

int ranMov1;                 // the randomMovement var    

bool ranNeed1 = 1;            // check if a new random is needed to avoid a stream of randoms
//ETC

//STEPPER========================================================================
  #define FuRo 3200     // one Full Rotation set in the hardware at the driver!!!
//================================================
// INITIALIZING THE STEPPERS
//
// INIT ALL ======================================
// check if all wheels  are turning well
// let them make 2 rounds...

void initAll()
    {
        if (startTime > 1000) {
        stepper1.setAcceleration(FuRo/10);
        stepper1.moveTo(FuRo*2);  

        //ETC

        startTime = 0;    
}}}}


// SET TO START POSITION =========================
// to set the wheel to the ready to go position
// ready to go means: with a next 1/10 rotation one flip is done.

void setToStartAll()  
    {
        if (startTime > 1000) {
        stepper1.setAcceleration(FuRo/10);
        stepper1.moveTo(FuRo/4);  

        //ETC   
      
        startTime = 0;
          stepper1.move(relTen);         //to relative Position 1/10th FuRo

          stepper1.setMaxSpeed(FuRo*2);  //The speed has to be defined AFTER move(To)
          stepper1.setAcceleration(FuRo*1.5);
          varDone = true;
          ReadNewSec();                                                                    
      }
    }


//SECS JUMP
//=====================================================================
// The difference between secJumpRun and justJump is that in secJumpRun
// the program starts with a routine to adjust the flap to the actual time.
// after that it moves to the relative defined positions each second.
// make the motor jump 1/10th of a full rotation each second
// Jump means accelerate run decelerate stop each second.
// first: start to find the right place for the next second
// this is done with the moveTo command (absolute position)
// then: jumpspeed each second with the move command.
//
// The first part tries to adjust the flaps to the actual time
// as if the flaps have numbers and the clock shows the actual time.

void secJumpRun() // is running too fast, the hardware cannot cope
   {
    
    switch (swVar1)
    {
    case 1:
    runAllowed = true;
    stepper1.moveTo(absTen[(myRTC.seconds-((myRTC.seconds/10)*10))]);
    stepper1.setMaxSpeed(FuRo);  //The speed has to be defined AFTER move(To)
    stepper1.setAcceleration(FuRo);
        if (stepper1.distanceToGo() <= (FuRo/1000))  //isRunning())
        {                           // when les then 0,1% from goal
        swVar1  = 2;}
        break;
    
    case 2:
    runAllowed = true;
    stepper1.move(relTen);
    stepper1.setMaxSpeed(FuRo);  //The speed has to be defined AFTER move(To)
    stepper1.setAcceleration(FuRo);
    break;
// FAST SWING
//=========================================
// the fastSwing uses runSpeed so doesn't have acceleration
// so be careful with the settings.

void secFastSwing()
    {
    Reset();
    switch (swVar1)
    {
    case 1:  
        stepper1.moveTo(FuRo/25);
        stepper1.runSpeedToPosition();
        stepper1.setSpeed(FuRo/160);
        swVar1  = 2;
        break;
    
    case 2:
      if (stepper1.distanceToGo() == 0){
      stepper1.moveTo((-stepper1.currentPosition()));
      stepper1.runSpeedToPosition();
      stepper1.setSpeed(FuRo/160);
      }
    break;
    }}


//VIBRATE
//=================================================================
// vibrate so the flaps are vibrating
// this setting uses runSpeed which means that
// there is no acceleration.

void vibrate()
    {
    
    switch (swVar1)
    {
    Reset();

    case 1:                   // move to new position
        runAllowed = true;  
        stepper1.moveTo(4);                
        stepper1.runSpeedToPosition();
        stepper1.setSpeed(90);  
        swVar1  = 2;  
        break;
    
    case 2:                  // occilate between new and former position
      if (stepper1.distanceToGo() == 0){
      runAllowed = true;
      stepper1.moveTo((-stepper1.currentPosition()));
      stepper1.runSpeedToPosition();
      stepper1.setSpeed(90);
      }
    break;
    }}


//RUN SECS IN CONSTANT SPEED
//==========================================================                  
// first the motor moves to the correct position according to the actual time
// make the motor turn in constant speed for seconds =3200/10 steps per sec
// Set the speed in steps per second: by 3200 full rotation > 320 stps/sec
// check this with the final driver!! 365 somehow seems better than the 320 it schould be.
// Step the motor with a constant speed as set by setSpeed():


void secConsSpeed()
    {
    Reset();
    switch (swVar1)
    {
    case 1:
    stepper1.moveTo(absTen[(myRTC.seconds-((myRTC.seconds/10)*10))]);
        if (stepper1.distanceToGo() <= (FuRo/1000))  //isRunning())  
             // define an argument to stop the search for the right position
        {
        swVar1  = 2;
        }
        break;
    
    case 2:
    stepper1.setSpeed(FuRo/8); // tweak this setting theory: FuRo/10
    stepper1.runSpeed();          // praxis: FuRo/8 comes closer !!!

    break;
    }}                    


// RANDOM MOVEMENT Variation
//=========================================
// randomMovement (random, steps, direction, acceleration, speed)


void moveRandom()  // doesn't work within the selector
{
     varDone = false;   //flag the variation is running
     Reset();           //without the reset it inherits settings
     runAllowed = true;
     stepper1.setMaxSpeed((rand() % 1500) + 1);    //must be FuRo here
     stepper1.setAcceleration((rand() % 500) + 1); //must be FuRo here
     stepper1.moveTo((rand() % 32000) * ranDirX1); //must be FuRo here
     varDone = true;    
             
     //         if (stepper1.distanceToGo() ==  0 ){              //again: trying to let the variation
     //         varDone = true;    //flag the variation is ready  //decide when to return to the selector
     //         }                                                 //this doesn't work ...
}  

//=========================================
// RANDOMS CALCULATED
//=========================================
// ranNeed, a boolean that flags the need for a new random variation selection (rename in randSwNeed?)
// ranMov, the Switch-variable that defines which case is selected: resulting in random Movement.

void randm1(){                      // calculate a random Movement (switch-case)
  if ( ranNeed1 == true) {          // to avoid repeated randoms  
     ranMov1 = random (1,4);        // 1st nr is the minimum, 2nd nr is the "smaller than"!!!
     }                              // else if
}                                   // end
//ETC


// RANDOMIZING THE DIRECTION
//=========================================

// ranDintm is an intermediate var needed to calculate a random direction
// randDirX is the random Directory + or - (Multiplier) that defines the direction

void calcRanDir1(){         // create a positive and negative random direction
  ranDintm1 = random(0,2);  // randomize between 0 and 1 // interim Var to aqquire randDirX
  if (ranDintm > 0){        // if 1 > +1
    ranDirX1 = 1;}          // CW or CCW depending on wiring
  else {                    // else  -1
    ranDirX1 = -1;          // CCW or CW depending on wiring
    }
}
//ETC


// RANDOMISED VARIATION
//=========================================
void ranMovPar(){
move2 = (random (FuRo * 2)* ranDirX1);    // create random position(*ran +/-)
sMaxS = (random (FuRo * 2)+1);            // create random speed
aCell = (random (FuRo * 2)+1);            // create random acceleration
}


// COUNT OFF-CLOCK STEPPERS  in concept
//=========================================
// make it possible to avoid the case all motors run off-clock variations at the same time
// this feature is not tested yet! I test with one first.

void countOffClock () {
  if ( offClockAll == true){
    countOffClockAll +1;
    }
    if (offClockAll == false){
    countOffClockAll -1;

    }
}


//==========================================
// RESET
//==========================================

void Reset() // created to avoid the variations inherit settings from each other
{            // but doing so I lose track of my position which is annoying but not impossible
             //  and still: inheriting occurs at some occasions

             runAllowed1 = false;            //running disabled
             stepper1.disableOutputs();      //disable power
             stepper1.setAcceleration(0);
             stepper1.setMaxSpeed(0);
             stepper1.setCurrentPosition(0); //Reset current position. "new home"
             stepper1.enableOutputs();
             runAllowed1 = true;
}

//==========================================
// RUN
//==========================================


void runTheSteppers()
  {
    if (runAllowed1 == true)
      {
      stepper1.enableOutputs();    //enable pins
      stepper1.run();              //step the motor (this will step the motor by 1 step at each loop)
      }
    else                           //if the runallowed is FALSE, don't do anything
      {
      stepper1.disableOutputs();   //disable outputs
      }
  }
//ETC


//================================================
// VARIOUS DEBUG OPTIONS
//================================================
// DIRECT with SERIAL PRINT (to be listed in LOOP)
// ===============================================

void writeClockAction(){

      if ((secDiff < 1)  &&  (lastSecRead - myRTC.seconds != 59) ){     
      }       
      
      else {    //to avoid a large stream, write only every second
      Serial.print("Mot1 pos: "); Serial.print((myRTC.seconds-((myRTC.seconds/10)*10)));
        Serial.print("  = >"); Serial.print(stepper1.distanceToGo());
           Serial.print("  ");Serial.println(stepper1.currentPosition());        
      Serial.println (onClockTimer1);
      Serial.println (offClockTimer1);
      Serial.println (onClockEnabled1);
      Serial.println (countOffClockAll);
}}

//=================================================================

void writeClockSmall(){
      if (writeTime > 1000)   //===== to avoid a large stream, write only every second
      {
      Serial.print("Mot1 pos: "); Serial.print((myRTC.seconds-((myRTC.seconds/10)*10)));
        Serial.print("  = >"); Serial.print(stepper1.distanceToGo());
          Serial.print("  ");Serial.println(stepper1.currentPosition());
      Serial.println(ranMov1);
      writeTime = 0;
}}


//==============================================================================
// OR WITH MACROS (to be placed in Declarations) I use tabs in IDE, one for this
//==============================================================================

// DEBUGGING ===================================================================
//
// DEBUG#1a
// Simple General purpose
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//use DEBUG_PRINT or DEBUG_PRINTLN in place of Serial.print and Serial.println.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// in LOOP the different uses can be commented in or out.

#define DEBUG // for unspecified use (the old DEBUGs) // comment-out to set off

#ifndef DEBUGUTILS_H
#define DEBUGUTILS_H

#ifdef DEBUG // the old DEBUG Serial.Print commands
  #define DEBUG_PRINT(...) Serial.print(__VA_ARGS__)
  #define DEBUG_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
  #define DEBUG_PRINT(...)
  #define DEBUG_PRINTLN(...)
#endif
#endif

//===============================================================================
// DEBUG#1b
// Split up to be more specific
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//use DEBvar_PRINT or DEBvar_PRINTLN in place of Serial.print and Serial.println.
//or  DEBfun_PRINT or DEBfun_PRINTLN in place of Serial.print and Serial.println.
//or  DEBtim_PRINT or DEBtim_PRINTLN in place of Serial.print and Serial.println.
//or  DEBpos_PRINT or DEBpos_PRINTLN in place of Serial.print and Serial.println.
//or  DEBxtr_PRINT or DEBxtr_PRINTLN in place of Serial.print and Serial.println.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//#define DEBvar // variables // comment-out to set off
//#define DEBflg // flags     // comment-out to set off
//#define DEBfun // functions // comment-out to set off
//#define DEBtim // time      // comment-out to set off
//#define DEBpos // positions // comment-out to set off
//#define DEBxtr // xtra opt. // comment-out to set off

//=================== Vars (byte, int, long)
#ifndef DEBUGUTILS_V
#define DEBUGUTILS_V

#ifdef DEBvar  // for Variables
  #define DEBvar_PRINT(...) Serial.print(__VA_ARGS__)
  #define DEBvar_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
  #define DEBvar_PRINT(...)
  #define DEBvar_PRINTLN(...)
#endif
#endif
//=================== Flags (bool)
#ifndef DEBUGUTILS_G
#define DEBUGUTILS_G

#ifdef DEBfun  // for Functions
  #define DEBflg_PRINT(...) Serial.print(__VA_ARGS__)
  #define DEBflg_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
  #define DEBflg_PRINT(...)
  #define DEBflg_PRINTLN(...)
#endif
#endif
//=================== Functions (void, function)
#ifndef DEBUGUTILS_F
#define DEBUGUTILS_F

#ifdef DEBfun  // for Functions
  #define DEBfun_PRINT(...) Serial.print(__VA_ARGS__)
  #define DEBfun_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
  #define DEBfun_PRINT(...)
  #define DEBfun_PRINTLN(...)
#endif
#endif
//=================== Time (millis, elapsedMillis)
#ifndef DEBUGUTILS_T
#define DEBUGUTILS_T

#ifdef DEBtim  // for Time options
  #define DEBtim_PRINT(...) Serial.print(__VA_ARGS__)
  #define DEBtim_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
  #define DEBtim_PRINT(...)
  #define DEBtim_PRINTLN(...)
#endif
#endif
//=================== Positions (current, target )
#ifndef DEBUGUTILS_P
#define DEBUGUTILS_P

#ifdef DEBpos  // for Positions
  #define DEBpos_PRINT(...) Serial.print(__VA_ARGS__)
  #define DEBpos_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
  #define DEBpos_PRINT(...)
  #define DEBpos_PRINTLN(...)
#endif
#endif
//=================== Extra (others)
#ifndef DEBUGUTILS_X
#define DEBUGUTILS_X

#ifdef DEBxtr  // for Xtra options
  #define DEBxtr_PRINT(...) Serial.print(__VA_ARGS__)
  #define DEBxtr_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
  #define DEBxtr_PRINT(...)
  #define DEBxtr_PRINTLN(...)
#endif
#endif


// DEBUG#2 //========================================================
// with proglineNr, function, timestamp
//++++++++++++++++++++++++++++++++++++++++++++++
// use this by adding code like the following:
// DebugPrint("The value of x is:");
// DebugPrintln(x,DEC);
//++++++++++++++++++++++++++++++++++++++++++++++
// disable by setting to 0 and enable to 1
#define SERIAL_DEBUG_ENABLED 0

#define GET_NUM_ARGS(...) GET_NUM_ARGS_ACT(__VA_ARGS__, 5,4,3,2,1)
#define GET_NUM_ARGS_ACT(_1,_2,_3,_4,_5,N,...) N

#define macro_dispatcher(func, ...) \
            macro_dispatcher_(func, GET_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) \
            macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) \
            func ## nargs
            
#ifdef SERIAL_DEBUG_ENABLED
  #define DebugPrint(...)  \
        Serial.print(millis());     \
        Serial.print(": ");    \
        Serial.print(__PRETTY_FUNCTION__); \
        Serial.print(' ');      \
        Serial.print(__LINE__);     \
        Serial.print(' ');      \
        Serial.print(__VA_ARGS__)
  #define DebugPrintln(...)  \
        Serial.print(millis());     \
        Serial.print(": ");    \
        Serial.print(__PRETTY_FUNCTION__); \
        Serial.print(' ');      \
        Serial.print(__LINE__);     \
        Serial.print(' ');      \
        Serial.println(__VA_ARGS__)
#else
  #define DebugPrint(...)
  #define DebugPrintln(...)  
#endif




Op dinsdag 13 september 2022 om 05:23:07 UTC+2 schreef jla...@pacifier.com:

Jim Larson

unread,
Sep 13, 2022, 1:42:05 PM9/13/22
to accelstepper
Yes, I meant 3200, not 32000, as steps per rotation. Sorry for the confusion.

I will study your code more and comment. Thank you for your thorough response.

        -jim

Jim Larson

unread,
Sep 14, 2022, 7:00:18 PM9/14/22
to accelstepper
Hello Matthijs -

After looking over your code, I must conclude that your needs are not as much for AccelStepper help, but for general program design and logic flow. While I will continue to help you privately, this forum isn't the place for further discussion about this. If a problem arises related to AccelStepper, we will of course post it here.

Thanks for understanding!
 
               -jim
Reply all
Reply to author
Forward
0 new messages