Control system for linear rail testing

Hello everyone!

I am actually not using an Arduino at the moment, I'm using a Controllino Maxi. It uses Arduino software and has almost the same programming except it's more for industrial use.

I was interested in testing a new rail and linear bearing (bearing made of plastic) system I've never seen before, so I wanted to make a little test set-up with the rail and an air cylinder. I have a valve allowing the cylinder to move in or out. I also have a blower set-up which blows fine steel dust into the testing enclosure. These rails would be used in a structural steel fabrication shop, so you get the feel of how dirty the environment can be.

My code works as follows: I control when the cylinder moves using a timer with a random duration (between 2.5 and 9 seconds) mainly so the other guys in the shop don't go nuts from the repetitive constant noise lol. After every stroke, I increment a counter. When the counter reaches a certain number, the blower turns on to give it some more dust/move the dust around inside the enclosure.

Every time the blower turns on (every 500 strokes for example), I increment another counter. From this counter, I convert the integer to a binary and use this binary to illuminate built-in LED's (the built-in LED's are actually digital outputs that also carry an LED to tell you if power is at that pin, I just use that instead of making a separate circuit with LED's). I use outputs 3-10 (which are technically D1-D8... don't ask) and illuminate the LED if the bit is 1. The reason for this is to get an approximation as to how much distance the bearings have covered.

Anyways, below you will find my code. I am posting it in case someone else does something similar. Please don't be afraid to suggest improvements in ways to make my code more efficient or something cooler I could add in! I was thinking of adventuring into the creation of files I could then export to a computer (since my binary LED system only works until 256 iterations).

Thanks for reading!

const int cylinderPin = 13; // Digital Output Pin D11
const int blowerPin = 12;   // Digital Output Pin D10
const int inPin = A0;       // Analog Input Pin A0
const int powerPin = 2;     // Digital Output Pin A0, always on to supply switch with power
const int checkPin = 8;

int cylinderSwitch = HIGH;
int blowerSwitch = HIGH;
int inPinStatus;
unsigned long cylinderTimer = 0;

int counter = 0;
int lifeCounter = 0;
int counterByte;
int bitNumber;
int i = 0;
long cylinderInterval;

long randomNumber;

void setup() 
{
  pinMode(cylinderPin, OUTPUT);
  pinMode(blowerPin, OUTPUT);
  pinMode(inPin, INPUT);
  pinMode(powerPin, OUTPUT);
  digitalWrite(powerPin, HIGH);   // This pin is always on to supply power to the switch
  pinMode(checkPin, OUTPUT);
  
  // Setup pins for binary output of count
  // Binary output must be done while inPinStatus == LOW
  {
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
  }
  

  // generate random seed
  randomSeed(45);
}

void loop() 
{
  inPinStatus = digitalRead(inPin);

  
  if(inPinStatus==LOW)                // Day Mode - Random Irregular Repetitions
  {
    digitalWrite(checkPin, LOW);      // Set the checkPin off, lets you know that the program is running this loop
    cylinderInterval = 2500;          // Minimum value of time between intervals = 2.5s
    randomNumber = random(20)*500;    // assign a random number between 0 and 9 to the variable

    if((millis()-cylinderTimer) >= cylinderInterval)
    {
      cylinderTimer = millis();
      if(cylinderSwitch == LOW)
      {
       cylinderSwitch = HIGH;
       counter++;
      }   
      else
       cylinderSwitch = LOW;
    }
    digitalWrite(cylinderPin, cylinderSwitch); 
    delay(randomNumber);

 
    if(counter==500)  // turn on blower when the cylinder has moved 250 times
    {
     cylinderSwitch = LOW;
     digitalWrite(cylinderPin, cylinderSwitch);
     blowerSwitch = HIGH;
     digitalWrite(blowerPin, blowerSwitch);
     delay(7500);
     blowerSwitch = LOW;
     digitalWrite(blowerPin, blowerSwitch);
     counter = 0; 
     lifeCounter++;   
    }

    /*  Displays the lifeCounter variable in binary by lighting up LED's
     *  One increment of life counter means that the buggy has travelled
     *  back and forth 250 times.
     *  
     *  One counter increment represents a travel of 2 meters. One lifeCounter
     *  increment represents a travel distance of 500 meters.
     *  
     *  The lifeCounter variable is only valid < 256 or approx 64 hours
     *  
     *  If an LED is ON, it means the bit = 1
     *  If an LED is OFF, it means the bit = 0
     *  
     *  NOTE: This has to be done while inPin == LOW since pin 8 is used 
     *  to show if inPin == HIGH for night operation
     */
    counterByte = byte(lifeCounter);      // Convert the life counter to a byte
    for (i=0;i<8;i++)                     // Loop for every bit in the byte
    {
      bitNumber = bitRead(counterByte,(i)); // Get bit i
      if (bitNumber==1)                 
      { 
        digitalWrite(10-i,HIGH);           // If the bit is 1, turn on the LED
      }
      else
      {
        digitalWrite(10-i, LOW);           // If the bit is 0, turn off the LED
      }
    }
    
  }
  
  if(inPinStatus==HIGH)               // Night Mode - Rapid Regular Repetitions
  {
    AllSwitchesOff();                 // Run AllSwitchesOff function
    cylinderInterval = 2250;          // 1.75 seconds between strokes
    digitalWrite(checkPin, HIGH);     // Set the checkPin on, lets you know that the program is running this loop
    
    if((millis()-cylinderTimer) >= cylinderInterval)
    {
      cylinderTimer = millis();
      if(cylinderSwitch == LOW)
      {
       cylinderSwitch = HIGH;
       counter++;
      }   
      else
       cylinderSwitch = LOW;
    }
    digitalWrite(cylinderPin, cylinderSwitch); 
     
    if(counter==500)  // turn on blower when the cylinder has moved 500 times
    {
     cylinderSwitch = LOW;
     digitalWrite(cylinderPin, cylinderSwitch);
     blowerSwitch = HIGH;
     digitalWrite(blowerPin, blowerSwitch);
     delay(2250);
     digitalWrite(cylinderPin, HIGH);
     delay(2250);
     blowerSwitch = LOW;
     digitalWrite(blowerPin, blowerSwitch);
     digitalWrite(cylinderPin, LOW);
     counter = 0;
     lifeCounter++;
    }
  } 
}

void AllSwitchesOff()       // Turns off all binary switches
{
  for(i=0;i<8;i++)
  {
    digitalWrite(i+3,LOW);
  }
  digitalWrite(checkPin, HIGH);  // Except for this one
}

Welcome to the forum.

Why do you have

digitalWrite (powerPin, HIGH)

Wire direct from 5v if it is always on and does not change.

Weedpharma

JohnCharbo:
Hello everyone!
...

Hey John, Sounds like a very interesting project! I want to get what you mean by 'cylinder' and 'rail'. Do you have a video, on you tube or anything?