arduino based cable asm tester

All arduino users unite! Howdy.
I had an idea to use an arduino uno for a test rig. I’ve got a cable assembly I want to test and cycle/bend with a stepper motor, and count the # cycles/time.
I’ve got the mechanical layout ready. I need to wire up the arduino. It’ll have to do the following:

  1. drive a stepper motor with an adafruit motor shield
  2. monitor 5 circuits for continuity
  3. record elapsed time

Do you guys know if the uno is capable to do all this? My plan is to connect the circuits to resistors, and run small current, so once a circuit I broken current will not run. Then feed this data into the arduino some ways, so it monitors the current flow in each circuit separately. Once any of the 5 circuits is broken it’ll record the elapsed time, once all circuits are broken it’ll stop the stepper motor.

Any ideas/help is appreciated,

Thank you!

Yes, that can be done. How much knowledge do you have on coding?

dibloff:
Once any of the 5 circuits is broken it’ll record the elapsed time, once all circuits are broken it’ll stop the stepper motor.

How long do you expect before the first and last breaks? If you are thinking in terms of days you might want to use a Real Time Clock (RTC) because the Arduino's millis() function does not keep accurate time over long periods.

There are example programs with the Arduino IDE that show how to use sevos and switch buttons. You could treat the continuity circuits as switches that are normally closed and the break would open the switch.

...R

I’m not much worrying about the programming, but the hardware and layout.
The stepper motor test code is available from adafruit with the shield. I can modify it to fit my needs.
I’ll need to put a loop in the code that detects the wire(s) fault(s) and records the time stamp.
The arduino uno has 6 analog channels (A0-A5) and I can use these to sense a voltage high/low
I think I was missing an overall picture, to see if this all could be done on the UNO

Robin2. Thanks for the idea about the RTC clock. I don’t know how long the test will run, but there is a good chance it could be days. I did some research into the switch button options. It looks to be an easy solution for my problem.

dibloff:
The arduino uno has 6 analog channels (A0-A5) and I can use these to sense a voltage high/low

You don't need to use analog inputs to check for a broken connection. Just use the digital I/O pins with
pinMode(pin, INPUT_PULLUP); and use the wire under test to connect that pin to ground. While the wire is intact digitalRead(pin); will return LOW. If the wire breaks it will return HIGH because there will no longer be an earth connection.

I think code like this should work with three simple functions

void loop() {
   moveServo();
   checkConnections();
   recordTimeIfConnectionBroken();
}

...R

Hi all. Thanks for all the input. I’ve finished the mechanical part of the tester, and the motor/cable shield for the arduino. Here is my schematic:

I’ve got a stepper motor, and I’m using an SD8825 driver for the motor. It works well.
I have 6 “switches”. 5 of them are the cables I’m trying to test, #6 is an end switch.
Here is how it should work.
When I turn on the arduino the motor should go in one direction (max one span length) ontil #6 end switch (ES) is activated. Then the motor should go back to mid span, and start to cycle. While cycling the 1-2-3-4-5 channels should be monitored for continuity (HIGH – LOW). In the meantime # cycles (or elapsed time) needs to be recorded. When any of the channels are open the time stamp should be recorded for that channel. Preferably when the arduino is switched off the recorded data should be maintained so I can download it to the computer. While it’s cycling no computer is attached. The Arduino must perform on it’s own. I’ve got a viki lcd viki lcd 3d printer control interface that has an sd card socket, so I could use it to write the result file in there. A bonus would be to have all the data (open/closed channels, number of completed cycles) displayed on the viki display).

So this is how far I have gotten. I tested the motor and it works fine. I tested the channels 1-6 and they all work with the http://arduino.cc/en/Tutorial/ButtonStateChange push button tester. There is no way i'll be able to finish the code, so I'm asking for help. Not sure how many hours of coding it would require. I can pay for the help off course. Please pm if you can help. thank you!

I’ve got a quick question. How can I leave (quit) the InitialSteps void once my if statement is satisfied? I tried using buttonstate == HIGH or LOW and I tried to use return and break too. if I comment out the //return my stepper will slowly advance (since it’s executing the if statement in every for loop) and if I activate the switch I’ll see 1’s insted of 0’s on the serial port. If I leave everything in the current state I’ll hear the first step being done by the stepper, and then nothing happens. Please advise. thank you.

void InitialSteps(float length, float RPM, int Dir)
{
  float MS = 16; //Stepper Driver Microstepping microsteps/step
  float RE = 200; //Stepper Motor Resolution steps/revolution
  float del = 3E7/(RPM * MS * RE);
  float steps;
  steps = (length * MS * RE) / ( mxl * z);
  digitalWrite(10, Dir);
  
  for(int i=0; i < steps; i++){ 
    digitalWrite(9, HIGH);
    delayMicroseconds(del);          
    digitalWrite(9, LOW); 
    delayMicroseconds(del);  
    Serial.println(ButtonState);
    ButtonState = digitalRead(buttonPin); // read the pushbutton input pin:
    
          if (ButtonState == 1);
          return;
  }
}

return is the normal way to exit from a function.

I suspect your problem is (alas) poorly organized code.

You probably need to organize your code like this

void loop() {
readButtons();
moveMotorOneMoreStep();
}

Your code seems to try to do all the moves in one block which means there is no scope to read the buttons until the moves have finished. You have tried to remedy this by reading the button during the moves - but then you are not able to deal with the button without screwing up the stepper movement.

The demo several things at a time shows how code can be organized so different activities don't block each other. You can use the same timing technique with micros() to regulate the stepper moves.

I suspect you could rewrite your steps like this

     digitalWrite(9, HIGH);
    
    digitalWrite(9, LOW); 
    delayMicroseconds(del * 2);

The point about this is that concentrating all the time into one place will make it easier to manage the time using micros() rather than delay().

...R

          if (ButtonState == 1);

If the state is 1, do nothing (;). Otherwise, do nothing. Why bother?

thanks for the comments.
there are several subroutines. The InitialSteps will move the carriage towards the end stop while checking is the end stop is activated. Once it's activated it'll quit the subroutine and go for the next task. the if statement would check if the switch is HIGH/LOW and stop the stepper movement.

dibloff:
there are several subroutines.

It would still be best (and simplest to understand and maintain) if the switches are only read within a special function for that purpose.

Each subroutine should be restricted to one simple actvity.

...R

thanks for the comments.
there are several subroutines. The InitialSteps will move the carriage towards the end stop while checking is the end stop is activated. Once it's activated it'll quit the subroutine and go for the next task. the if statement would check if the switch is HIGH/LOW and stop the stepper movement.

What you say you want, and what that code actually does, are two different things. Loose the ; on the end of the if statement, and they'd be the same thing.

Here is how far I have gotten. The motor homing works, then it’ll run to mid position and start cycling. In the meantime it monitors the channels and gives a printout about their health (on/off).
I calculated the required RPM for a 200 (mm) run (100 mm left and 100 mm right) and it came out to be 328 RPM (with 200 step motor @ 16 microsteps/step, mxl belt = 2.032 mm pitch and 18 teeth pulley). Well I counted 20 cycles and the system is not delivering the 1 sec cycle time, therefore I included a calculation in the sketch for the cycleLength right now it’s spitting out 0.00 and sometimes an 1.00 and 2.00. I’ll probably figure this out by tomorrow, but now it’s 11 pm again.
I also tried to write the number of cycles to the EEPROM. Read about it for 2 weeks now, still hesitant. Don’t want to burn it out in case I screw up something in the code. I anticipate the cable(s) being broken in a day or two so the # of cycles can go up as high (86400 cycles/day) so int will not work, I have to use long or float. There are many sketches for writing int into EEPROM which will only take 2 bytes but long and float will take 4 bytes and will need a “special” algorithm.
Well. Here’s I am now. As always any comments are appreciated. Thank you!

#include <EEPROM.h>
  const int  buttonPin = 7;    // the pin that the pushbutton is attached to
  int ButtonState = 0;         // current state of the button
  int span = 200;              // carriage run length
  float mxl = 2.032;           // mxl belt pitch
  int z = 18;                  // stepper motor pulley number of teeth
  long cycles = 0;                 //number of cycles
  int channel[5];
  long startTime ;                    // start time for stop watch
  long elapsedTime ;                  // elapsed time for stop watch
  float cycleLength;                  // lenght of 1 cycle
  
void RotateSteps(float length, float RPM, int Dir, int checkSwitch)
{
  float MS = 16; //Stepper Driver Microstepping microsteps/step
  float RE = 200; //Stepper Motor Resolution steps/revolution
  float del = 3E7/(RPM * MS * RE); //delay between stepper on/off signal to get the proper speed
  float steps;
  steps = (length * MS * RE) / ( mxl * z); // number of steps to achive the required travel lenght 
  digitalWrite(10, Dir);
  
  for(int i=0; i < steps; i++){ 
    digitalWrite(9, HIGH);
    delayMicroseconds(del);          
    digitalWrite(9, LOW); 
    delayMicroseconds(del);  
  
    if (checkSwitch == 1)
      {
          if (digitalRead(buttonPin) == 1){
          return;}
      }
  }
} 

void setup() 
  {                
  pinMode(10, OUTPUT);     
  pinMode(9, OUTPUT);
  pinMode(buttonPin, INPUT);    // initialize the button pin as a input:
  EEPROM.write(0, 10);
  
  Serial.begin(9600);  // initialize serial communication:
  RotateSteps(250, 350, LOW, 1);
  RotateSteps(170, 350, HIGH, 0);
  startTime = millis();                                   // store the start time
  
  for (int i=0;i<5;i++){
    channel[i]=digitalRead(i+2);
  }
  }

void loop() { 
    
    RotateSteps(100, 350, LOW, 0);
    RotateSteps(100, 350, HIGH, 0);
    cycles = cycles + 1;  
    elapsedTime =   millis() - startTime;              // store elapsed time
    cycleLength = cycles / ((int)(elapsedTime % 1000L));
    //EEPROM.write(0,cycles);
    //EEPROM.read(0);
    //Serial.println(EEPROM.read(0));
    Serial.println(cycleLength, 2);
    for (int i=0; i<5;i++)
      {
        int temp;

        temp = digitalRead(i+2);
        if ((temp==0) && (temp != channel[i]))
          {
           temp = i+2; 
           Serial.print("Error! Channel: ");
           Serial.print(temp);
           Serial.print(" , Cycle#: ");
           Serial.println(cycles);
//EEPROM.write((i+1)*50,cycles);
           channel[i]=0;
          }
      }
    
}

dibloff:
Don’t want to burn it out in case I screw up something in the code. I anticipate the cable(s) being broken in a day or two so the # of cycles can go up as high (86400 cycles/day) so int will not work,

There is no point writing data to the EEPROM if nothing happens. Just write data when a break is detected and also save the cycle number at which it happened. There will be more data to write on any one occasion but the total number of writes will only be the same as the number of cables.

I haven’t looked for your maths problem. I am lazy and I have every confidence in your ability to figure it out.

…R