Hi Guys,
I have set up a small system to count how many times I could activate a push button on a panel before it collapsed.
The button is guaranteed to 500K activations, but we experienced some collapsing long before that.
Thus I made a test
I used the following:
Arduino Uno
Adafruit Motor Shield
12DC motor with a short (3cm) metal arm
The pushbutton to be tested ( connected to pin 4)
12V 5A external power supply for the motor
The idea is to Start the Uno and loop through the following:
Set the motor running forward and forcing the mounted arm to hit the button on the table
When the button is activated, the motor stops and reverses
After 250 milliseconds , the motor stops and goes forward again
The loop is wrapped round a "watchdog" that stops the UNO when the button eventually breaks and saves to count to EEProm
Progress is showed on a LCD
The test has worked fine and we even counted more than 2 million activations before the button broke.
Success - and all is fine from that point of view.
But I am pussled by the behavior of the motor because the cycle is as follows:
Turn clockwise( forward) and hit the button
Turn counterclockwise approx 45 degrees
Turn clockwise( forward) and hit the button
Turn counterclockwise approx 45 degrees
Turn clockwise( forward) and hit the button
Turn counterclockwise approx 120 degrees
This cycle continues until the button breaks, i.e. 2 short burst and a long burst.
Why is the cycle uneven?
Is my code "uneven" or is it perhaps a hardware issue?
It has made no difference if I have had the Uno powered by USB, separate 12V, or 12V from the Motor shield
And here is the code
#include <Wire.h>
#include <EEPROM.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(2);
#include <SoftwareSerial.h>
// Create a software serial port!
SoftwareSerial lcd = SoftwareSerial(0,2);
long Watchdog =millis();
long cycletime=millis();
long counter=0;
int fspeed=55;
int rspeed=55;
int run=4; // name of button to be tested on touchpad
boolean reversing=false;
const int MaxTimeWatchDog =700;
const int MaxCycletime=250;
void setup()
{
counter= EEPROMReadlong(0);
AFMS.begin(); // create with the default frequency 1.6KHz
//AFMS.begin(1000); // OR with a different frequency, say 1KHz
myMotor->setSpeed(fspeed);
pinMode(run,INPUT_PULLUP);
lcd.begin(9600);
// Set up LCD
lcd.write(0xFE);
lcd.write(0xD1);
lcd.write(16); // 16 columns
lcd.write(2); // 2 rows
delay(10);
// set the contrast,
lcd.write(0xFE);
lcd.write(0x50);
lcd.write(200);
delay(10);
// set the brightness -
lcd.write(0xFE);
lcd.write(0x99);
lcd.write(255);
delay(10);
// turn off cursors
lcd.write(0xFE);
lcd.write(0x4B);
lcd.write(0xFE);
lcd.write(0x54);
// Clear screen
lcd.write(0xFE);
lcd.write(0x01);
delay(10);
// lcd.print(" ButtonBounce");
// delay(1000);
// lcd.print(" Idle ");
delay(30);
}
void loop()
{
while ((millis()-Watchdog) < (MaxTimeWatchDog))
{
if( millis()-cycletime>MaxCycletime)
{
// lcd.println ("now in loop");
// lcd.println(cycletime);
myMotor->run(RELEASE);
delay(50);
myMotor->run(FORWARD);
cycletime=millis();
}
if(digitalRead(run)==LOW & !reversing)
{
myMotor->run(RELEASE);
delay(50);
myMotor->run(BACKWARD);
reversing=true;
counter++;
Watchdog=millis();
// Clear screen
lcd.write(0xFE);
lcd.write(0x01);
delay(10);
lcd.write(1);
delay(10);
lcd.print("Cnt: ");
lcd.print(counter);
// updatelcd;
}
if(digitalRead(run)==HIGH)
{
reversing=false;
}
}
// Clear screen
// If we get to here we are out of the while loop and have timed out
EEPROMWritelong(0,counter);
lcd.write(0xFE);
lcd.write(0x01);
delay(10);
lcd.write(1);
delay(10);
lcd.print(" Cnt: ");
lcd.print(counter);
lcd.print(" Stopped");
myMotor->run(RELEASE);
// updatelcd;
}
// Functions to read & write values to EEprom
void EEPROMWritelong(int address, long value)
{
//Decomposition from a long to 4 bytes by using bitshift.
//One = Most significant -> Four = Least significant byte
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
//Write the 4 bytes into the eeprom memory.
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}
//This function will return a 4 byte (32bit) long from the eeprom
//at the specified address to address + 3.
long EEPROMReadlong(long address)
{
//Read the 4 bytes from the eeprom memory.
long four = EEPROM.read(address);
long three = EEPROM.read(address + 1);
long two = EEPROM.read(address + 2);
long one = EEPROM.read(address + 3);
//Return the recomposed long by using bitshift.
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}