Hi guys and gals, Its been a long time since I done much programming. I have however cobbled together some code trying to use the state principle. As you can see my code is version 1.97 as I couldnt post it up till I knew it worked. Well it almost works properly.
The concept was to use the basic DC motor control circuit and use a sine wave pattern to drive it allowing the user to pick betweeen 1 and 100 cycles in a minute. After validating the selection the motor cycle value the motor would run for 1 minute and then stop. The user would then be able to select another value and it would run again for a minute.
Issues I have had were intiger, unsigned long and float variables. Initialy the motor didnt run in a sine wave pattern because of trying to use to long a command Line 93 used to be FloatStepcount = float(StepCount/1000); this didnt work it only transposed the integer part of the equation so it was mostly 0.00 or 1.00 etc. I'd set a variable up as an integer instead of an unsigned long so my timer reset didnt used to work.
Here is my finished code, could you good people please peruse it and offer constructive critisism as to improvements.
//Sine wave motor driver ver 1.97
//J.Anslow 02/02/17
//setup variables
const int motorPin = 3; //pin to connect motor control to
int TimeDelay = 0; // time delay between each motor speed increase
int Amplitude = 1; // allow for strength alteration later version
int IntSinWave = 0;
int MotorChangeTime = 10;// for upddating motor speed every 10th of a second
int StepCount = 0;
int MappedChange = 0;
boolean DisplayMessageOnce = false; //for use in SetTimeDelay() to print message only once
boolean TimeDelaySet = false; //set to true to run SetTimeDelay() only once
boolean HasTimePassed = false; //for use in ResetTimer()
boolean DoOnce = false;
unsigned long CurrentMillis = 0;
unsigned long PreviousMotorMillis = 0;
unsigned long SetStartTimer = 0; //for use in ResetTimer()
const float Pi = 3.142;
float FreqPerMin = 6; //set manually for now will allow for change in further version
float Omega = 0.00; //part of the sine wave formula
float FloatSinWave = 0.00;
float FloatStepCount = 0;
void setup()
{
pinMode(motorPin, OUTPUT); //activate pin as an output
Serial.begin(9600); //activate serial monitor control for help debugging
}
void loop()
{
if (TimeDelaySet) //if the time delay value has not been set the main body of the program will not run. SetTimeDelay() runs instead
{
//in this version we will attempt to run the motor from 20%(lowest value to start motor) to 100% using a sign wave pattern
// this will run for 1 minute before stopping and resetting to initial state
CurrentMillis = millis(); // sets a constant value to use in any further functions
ResetTimer();
if (DisplayMessageOnce && TimeDelaySet)
{
MotorSpeedChange();
}
}
else
{
SetTimeDelay();
PreviousMotorMillis = millis();
}
}
void ResetTimer()
{
if (SetStartTimer == 0)
{
SetStartTimer = millis();
}
else
{
if ((millis() - SetStartTimer) >= 60000)
{
SetStartTimer = 0;
analogWrite(motorPin, 0);
DisplayMessageOnce = false;
TimeDelaySet = false;
DoOnce = false;
StepCount = 0;
Serial.println("1 minute elapsed");
}
}
}
void MotorSpeedChange()
{
if (!DoOnce)
{
float FreqPerSec = 0;
FreqPerMin = float(TimeDelay);
FreqPerSec = 1 / (60 / FreqPerMin);
Serial.println(FreqPerSec);
Omega = (2 * Pi) * FreqPerSec;
DoOnce = true;
}
if (CurrentMillis - PreviousMotorMillis >= MotorChangeTime)
{
PreviousMotorMillis += MotorChangeTime;
StepCount += MotorChangeTime;
FloatStepCount = float(StepCount); //had to change the int to a float first
FloatStepCount = FloatStepCount / 1000; //then divide by the 1000 before it becomes an actual floating value
FloatSinWave = Amplitude * sin(Omega * FloatStepCount);
IntSinWave = int(FloatSinWave * 1000);
MappedChange = map(IntSinWave, -1000, 1000, 50, 255);
analogWrite(motorPin, MappedChange);
}
}
void SetTimeDelay()
{
if (!DisplayMessageOnce) // this checks to see if message has been printed
{
Serial.println("Input motor cycles: 1 to 100");
DisplayMessageOnce = true; //this change ensures if statement does not run again
}
if (!TimeDelaySet) //checking for valid input
{
if (Serial.available()) //check to see if there has been an input
{
TimeDelay = Serial.parseInt(); //ensures only numerical values are passed
if (TimeDelay >= 1 && TimeDelay <= 100) // validates input
{
TimeDelaySet = true; // setting to true stops SetTimeDelay() from being run again
Serial.print(TimeDelay);
Serial.print(" ");
Serial.println("thank you for valid input");
}
}
}
}
Also is there a some way I can check my variables and flow of my program other than putting Serial.print commands everywhere. would be nice and probably save me a lot of time.
I also noticed a small problem when running the motor over a 1 cycle per minute it did not seem to follow the sine curve properly seemed to have a couple of blips.
One last thing I used the power supply to plug into my breadboard. I didnt realise the jumpers altered the voltage a 3.3v and a 5v I was running my motor on the 3.3v side and i wondered why it was so slow :o
I was also going to add a picture of my board set up but I couldnt figure out how to do this .
Sorry if Ive been slightly long winded.