Please Help. First project.

So I came up with a project and fingered out all the hardware for it. I am good there but when it comes to the code that is where a made the big mistake. I thought I had it all worked out in my head on how the code should go. After putting pen to paper I realized it is not going to be as simple as I thought.

Here is the general hardware, minus the small stuff.

Arduino Uno (clone), LCD screen, 3x 10k pots, 2x motors.

The pots control three basic functions, motor on time (in seconds), motor off time(in minutes), and motor power level(in ten levels, 1-10).

The LCD displays four different pieces of information. the motor on time, motor off time, motor power level, and the number of times it has cycled through on and off.

Once I realized the serval mistakes I made I stopped writing the code and jumped on here to see if I can get some major help.

I have also included a picture I made to help me get the LCD pattern right. The top row and left column are the position numbers when I write the code. The # is where the variable goes to be displayed.

This is my first project so please go easy on me. Thank you in advance.

#include <LiquidCrystal.h> //16x2 LCD libary priveded by LCD manufactor.

//Setup of Pins.
const int timeOn = A1; // 10k pot
const int timeOff = A2; // 10k pot
const int power = A3; // 10k pot
const int motorOne = 9; // output to motor 1
const int motorTwo = 10; // output to motor 2

//setting up variables to hold pot numbers.
int timeOn_var = 0;
int timeOff_var = 0;
int power_var = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() 
{
  pinMode(timeOn, INPUT);
  pinMode(timeOff, INPUT);
  pinMode(power, INPUT);
  pinMode(motorOne, OUTPUT);
  pinMode(motorTwo, OUTPUT);
  lcd.begin(16, 2); 
  lcd.setCursor(0,0);
  lcd.println("OFF-T:");
  lcd.setCursor(0,1);
  lcd.println("ON-T:");
  lcd.setCursor(11,0);
  lcd.println("P:");
  lcd.setCursor(11,1);
  lcd.println("C:");
  
}

void loop() 
{
  map(timeOn_var,0,1024,0,10); //seconds
  map(timeOff_var,0,1024,0,10); //Minutes
  maps(power_var,0,1024,0,255); //power levels
  
  analogWrite(motorOne,power_var);
  analogWrite(motorTwo,power_var);
  delay(timeOn_var);
  analogWrite(motorOne,0);
  analogWrite(motorTwo,0);
  delay(timeOff_var);
}

You should use analogRead() function to read the potentiometer value and that you shoud map between 0-255 and 0-10.
https://www.arduino.cc/en/Reference/AnalogRead?setlang=en
then you should use the mapped values to analogWrite()

int time_on_pot = analogRead(A0);
timeOn_var = map(time_on_pot,0,1023,0,10);
int time_off_pot = analogRead(A1);
timeOn_var = map(time_off_pot,0,1023,0,10);
int power_pot = analogRead(A2);
power_var = map(power_pot,0,1023,0,255);

Updated the code. Thank you anoojgandham.

#include <LiquidCrystal.h> //16x2 LCD libary priveded by LCD manufactor.

//Setup of Pins.
const int timeOn = A1; // 10k pot
const int timeOff = A2; // 10k pot
const int power = A3; // 10k pot
const int motorOne = 9; // output to motor 1
const int motorTwo = 10; // output to motor 2

//setting up variables to hold pot numbers.
int timeOn_var = 0;
int timeOff_var = 0;
int power_var = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() 
{
  pinMode(timeOn, INPUT);
  pinMode(timeOff, INPUT);
  pinMode(power, INPUT);
  pinMode(motorOne, OUTPUT);
  pinMode(motorTwo, OUTPUT);
  lcd.begin(16, 2); 
  lcd.setCursor(0,0);
  lcd.println("OFF-T:");
  lcd.setCursor(0,1);
  lcd.println("ON-T:");
  lcd.setCursor(11,0);
  lcd.println("P:");
  lcd.setCursor(11,1);
  lcd.println("C:");
  
}

void loop() 
{
  timeOn_var = analogRead(timeOn); //read analog pin A1
  timeOff_var = analogRead(timeOff); //read analog pin A2
  power_var = analogRead(power); // Read analog pin A3

  
  timeOn_var = map(timeOn_var,0,1024,0,10); //seconds
  timeOff_var = map(timeOff_var,0,1024,0,10); //Minutes
  power_var = map(power_var,0,1024,0,255); //power levels
  
  analogWrite(motorOne,power_var);
  analogWrite(motorTwo,power_var);
  delay(timeOn_var);
  analogWrite(motorOne,0);
  analogWrite(motorTwo,0);
  delay(timeOff_var);
}

Delay input should be given in microseconds

#include <LiquidCrystal.h> //16x2 LCD libary priveded by LCD manufactor.

//Setup of Pins.
const int timeOn = A1; // 10k pot
const int timeOff = A2; // 10k pot
const int power = A3; // 10k pot
const int motorOne = 9; // output to motor 1
const int motorTwo = 10; // output to motor 2

//setting up variables to hold pot numbers.
int timeOn_var = 0;
int timeOff_var = 0;
int power_var = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() 
{
  pinMode(timeOn, INPUT);
  pinMode(timeOff, INPUT);
  pinMode(power, INPUT);
  pinMode(motorOne, OUTPUT);
  pinMode(motorTwo, OUTPUT);
  lcd.begin(16, 2); 
  lcd.setCursor(0,0);
  lcd.println("OFF-T:");
  lcd.setCursor(0,1);
  lcd.println("ON-T:");
  lcd.setCursor(11,0);
  lcd.println("P:");
  lcd.setCursor(11,1);
  lcd.println("C:");
  
}

void loop() 
{
  timeOn_var = analogRead(timeOn); //read analog pin A1
  timeOff_var = analogRead(timeOff); //read analog pin A2
  power_var = analogRead(power); // Read analog pin A3

  
  timeOn_var = map(timeOn_var,0,1024,0,10); //seconds
  timeOff_var = map(timeOff_var,0,1024,0,10); //Minutes
  power_var = map(power_var,0,1024,0,255); //power levels
  
  analogWrite(motorOne,power_var);
  analogWrite(motorTwo,power_var);
  delay(timeOn_var*1000);//delay takes input as micro seconds
  analogWrite(motorOne,0);
  analogWrite(motorTwo,0);
  delay(timeOff_var*1000);//delay takes input as micro seconds
}

Gidget19893161:
This is my first project so please go easy on me. Thank you in advance.

What exactly is the problem you want help with? What does the program actually do and what do you want it to do that is different.

At the moment your description is like a patient saying to the doctor "I'm sick". We, like the doctor, need a clear description of the symptoms.

I presume you are aware that the delay() function requires a value of milliseconds. For example a 5 second delay() is made with delay(5000);

If all you really want to do is make something start, wait for a time, make it stop, wait some more and the repeat your program is reasonable. Note that the potentiometers will only be read when the second delay() is over. Maybe that is sufficient.

If you want a responsive program in which the potentiometers are checked regularly then you should not used the delay() function. The functions delay() and delayMicroseconds() block the Arduino until they complete.
Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

...R

My best advice is to do a bit at a time - get the three pots working and printing to the serial
Monitor. Then work on the LCD and get that running .
Finally look at your motor control.
There are lots of IDE examples appropriate to each stage

Use added print statements to the serial monitor to check
Things are ruining as you expect ( variable values etc )

Robin2

Robin2:
What exactly is the problem you want help with? What does the program actually do and what do you want it to do that is different.

I am not sure how to answer the first question but I can answer try to give more detail to answer the second one.

Cutting the fat off the ends, I want to control two motors via PWM to control their speed. Add the fat back on the ends. I want to be able to control three different variables. On time of the motors, off time of the motors and how fast they are going. My original why I wanted to do that was with a push button but thought a pot would be easier at least for a first project. The values of; off time, on time, and power would be displayed on the LCD screen. For me to know what they are.

Robin2:
If you want a responsive program in which the potentiometers are checked regularly then you should not used the delay() function. The functions delay() and delayMicroseconds() block the Arduino until they complete.
Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

I did know the "delay" function stopped the program form run however it was a major oversight on my part for not thinking about that when i write the code. I have never played with the "millis()" function so i will have to look into that. Thank you for pointing this out to me. I will have to try and find a video on youtube so i can see how i can adapt it to my code. Hopefully I will be able to work on that tonight after work and tomorrow. Will post new code hopefully tomorrow!

Happy New Years everyone!

hammy:
My best advice is to do a bit at a time - get the three pots working and printing to the serial
Monitor. Then work on the LCD and get that running .
Finally look at your motor control.
There are lots of IDE examples appropriate to each stage

Use added print statements to the serial monitor to check
Things are ruining as you expect ( variable values etc )

Thank you for the advice. I just might have to do just that. Break things down into the little part and get them working before adding it all together. The whole walk before you run concept! I thought I had a handle on this because I have done the basic stuff, print to a serial monitor, print to "Hello world" to an LCD, fade an LED with a pot, etc. But I did not have as much of an understanding as I thought doing this project. I have already invested money into the hardware so I don't want to just walk away from it. Thank you for your input and that is what is probably going to have to happen.

Here is a thread I and others have found useful when learning to write Arduino programs:

Planning and Implementing an Arduino Program

Gidget19893161:

What exactly is the problem you want help with? What does the program actually do and what do you want it to do that is different.

I am not sure how to answer the first question but I can answer try to give more detail to answer the second one.

I did not mean that to be interpreted as two separate questions. I intended the second part to be an expansion of the first.

And, while you described your objective you have not said what the program actually does. If you tell us that it allows us to focus on the part of your code that is relevant for the problem and not waste time trying to figure out other parts.

I agree 100% with what @hammy has said about doing it a bit at a time - although I would leave the LCD stuff until last. All successful programs are developed in small stages. Get all the parts working separately before trying to combine them. Then if you make a change and something stops working properly you can go back to the earlier version and try again

...R

@Robin2

I have been trying to wrap my head around the millis() and can not seem to be able to do it. I have watched videos, read blogs, stared at the "blinkwithutdelay" code provided by the IDE. and while it does make some since I am not sure how to adapt it to my code with there different variables. if it was set times that did not change I think I could get it fairly easily. Can you point me down a path that might help with have multiple variables with millis()?

millis() is like the clock on your wall. The Arduino can execute 16,000 instructions in each millisecond, so a millisecond is a big unit of time. Now those instructions are really small, so "add 2 numbers and save the result" takes 3 or 5 instructions. So think of millis like minutes maybe.

So imagine you have a busy day with lots of tasks. You must bake a cake in the oven for 4 hours, dry the washing on the line for 5 hours and write an email to your friend to tell him what you are doing. You will also answer the doorbell and look at the weather occasionally to see if you have to bring the washing inside.

Is it time to start the cake yet? Yes. So start it and write down the time that you started. Maybe your wall clock says 11:15. Write an email to say this, like Serial.print("Cake started");

Look at the weather, check the door, check the other tasks.

Ok, look at the clock again. It is 11:15 still, so zero hours have passed. The cake is not ready.

Repeat several million times. Now when you look at the clock, you see 3:15. Subtract 11:15 from that and you see that 4 hours has passed. The cake is done, so turn off the oven.

In what mathematics does 3-11=4? The maths world where it wraps around at 12. The Arduino uses unsigned long for milliseconds, which wraps around at 49 days. So long as you keep all time calculation in unsigned long and always use subtraction to compare times, the wraparound is never a problem.

Try this example, based on your original code. NOTE: You've allocated pin 9 twice in here (motor1 control and LCD) so you'll need to address that. I left it as is.

Look at the code; if you have any questions, ask.

Compiled for a Mega2560. Not tried. YMMV

#include <LiquidCrystal.h> //16x2 LCD libary priveded by LCD manufactor.

//Setup of Pins.
const int timeOn = A1; // 10k pot
const int timeOff = A2; // 10k pot
const int power = A3; // 10k pot
const int motorOne = 9; // output to motor 1
const int motorTwo = 10; // output to motor 2

#define MOTOR_OFF_VAL   0
//motor states
#define MOTOR_START     0
#define MOTOR_RUN       1
#define MOTOR_STOP      2
#define MOTOR_OFF       3

byte
    motorState;
int 
    time_on_pot,
    time_off_pot,
    timeOn_var,
    timeOff_var,
    power_pot,
    power_var;
unsigned long
    motorRuntime,
    motorOfftime;
    
//setting up variables to hold pot numbers.
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);    //NOTE: Pin 9 is used above for motorOne above

void setup() 
{
    pinMode(timeOn, INPUT);
    pinMode(timeOff, INPUT);
    pinMode(power, INPUT);
    pinMode(motorOne, OUTPUT);
    pinMode(motorTwo, OUTPUT);
  
    lcd.begin( 16, 2 ); 
    lcd.setCursor(0,0);
    lcd.println("OFF-T:");
    lcd.setCursor(0,1);
    lcd.println("ON-T:");
    lcd.setCursor(11,0);
    lcd.println("P:");
    lcd.setCursor(11,1);
    lcd.println("C:");

}//setup

void loop() 
{
    ProcessMotors();

    //can do lots of stuff in here if you want

}//loop


void ReadPOTs( void )
{  
    //read in state 0 of motor control
    
    time_on_pot = analogRead(timeOn);
    timeOn_var = map(time_on_pot,0,1023,0,10);
    //run time is seconds; multiply by 1K to get mS
    motorRuntime = timeOn_var * 1000L;  //convert to mS
    //
    time_off_pot = analogRead(timeOff);
    timeOff_var = map(time_off_pot,0,1023,0,10);
    //offtime is minutes so multiply by 60x1000 to get mS
    motorOfftime = timeOff_var * 60000L; //convert to mS
    //
    power_pot = analogRead(power);
    power_var = map(power_pot,0,1023,0,255);    
    
}//ReadPOTs

void ProcessMotors( void )
{
    static unsigned long
        motorTimer;
    static byte
        motorState = MOTOR_START;
        
    switch( motorState )
    {
        case    MOTOR_START:
            ReadPOTs();
            analogWrite( motorOne, power_var );
            analogWrite( motorTwo, power_var );
            motorTimer = millis() + motorRuntime;
            motorState = MOTOR_RUN;
        break;
        
        case    MOTOR_RUN:
            if( millis() < motorTimer )
                return;
            motorState = MOTOR_STOP; 
        break;
        
        case    MOTOR_STOP:
            analogWrite( motorOne, MOTOR_OFF_VAL );
            analogWrite( motorTwo, MOTOR_OFF_VAL );
            motorTimer = millis() + motorOfftime;
            motorState = MOTOR_OFF;
        break;
        
        case    MOTOR_OFF:
            if( millis() < motorTimer )
                return;
            motorState = MOTOR_START; 
        break;

        default:
            motorState = MOTOR_OFF;
        break;
    }//switch
        
}//ProcessMotor

Gidget19893161:
I have been trying to wrap my head around the millis() and can not seem to be able to do it.

Perhaps an illustration would help.

millis illustration.PNG

millis illustration.PNG

Gidget19893161:
@Robin2

I have been trying to wrap my head around the millis() ...

Can you please answer the simple question that I am now asking for the 3rd time
What does the program actually do and what do you want it to do that is different.

When we know that it will be much easier to suggest a solution.

...R

Robin2:
Can you please answer the simple question that I am now asking for the 3rd time
What does the program actually do and what do you want it to do that is different.

When we know that it will be much easier to suggest a solution.

...R

I have not uploaded the code to an Uno. The reason is because when I started to write the code I quickly realized I was in over my head. I said that because I thought I could use different things I know and combine them together. But the way I was trying to combine them would not work.