So I've been working on this code for a while now and have pretty much gotten everything working the way that I want it to. My only problem is that I cannot figure out how to write in a millis() timer instead of a delay. I am controlling two dc motors with a relay shield with a uno. Any help is greatly appreciated.
Thanks!!
Casey
// variables
byte switch1State = 0; // to store switch reading 0 = off 1 = posA 2 = posB
byte lastSwitch1State = 0; // to check for change
byte switch2State = 2; // to store switch reading 2 = off 3 = posA 2 = posB
byte lastSwitch2State = 2; // to check for change
int relay0 = 8; // Relay 0 connected to pin 8 (left out)
int relay1 = 7; // Relay 1 connected to pin 7 (left in)
int relay2 = 2; // Relay 2 connected to pin 2 (right out)
int relay3 = 4; // Relay 3 connected to pin 4 (right in)
int trimleftPin1 = 5; // Left trim switch in
int trimleftPin2 = 6; // Left trim switch out
int trimrightPin1 = 3; // Right trim switch in
int trimrightPin2 = 10; // Right trim switch out
int gateposPin1 = 11; // Left gate out
int gateposPin2 = 12; // Right gate out
void setup() {
Serial.begin(9600);
pinMode(gateposPin1, INPUT);
digitalWrite(gateposPin1, HIGH); // Activate internal pullup
pinMode(gateposPin2, INPUT);
digitalWrite(gateposPin2, HIGH); // Activate internal pullup
pinMode(relay0, OUTPUT); // sets the digital pin as output
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(trimleftPin1, INPUT);
digitalWrite(trimleftPin1, HIGH); // Activate internal pullup
pinMode(trimleftPin2, INPUT);
digitalWrite(trimleftPin2, HIGH); // Activate internal pullup
pinMode(trimrightPin1, INPUT);
digitalWrite(trimrightPin1, HIGH); // Activate internal pullup
pinMode(trimrightPin2, INPUT);
digitalWrite(trimrightPin2, HIGH); // Activate internal pullup
}
void loop(){
// Read the switch and put the result is switchState
if (digitalRead(gateposPin1) == LOW) switch1State = 1;
else switch1State = 0;
if (digitalRead(gateposPin2) == LOW) switch2State = 3;
else switch2State = 2;
// Only do anything if the state has changed
if (switch1State != lastSwitch1State){
lastSwitch1State = switch1State;
switch(switch1State){
case 1:
digitalWrite(relay0, HIGH); // sets relay 0 on (left out)
delay(5000); // waits for 5 second
digitalWrite(relay0, LOW); // sets relay 0 off
Serial.println("A");
break;
case 0:
digitalWrite(relay1, HIGH); //sets relay 1 on (left in
delay(5000); // waits for 5 second
digitalWrite(relay1, LOW); // sets relay 1 off
Serial.println("Switch A OFF");
break;
}}
// Only do anything if the state has changed
if (switch2State != lastSwitch2State){
lastSwitch2State = switch2State;
switch(switch2State){
case 3:
digitalWrite(relay2, HIGH); // sets relay 0 on (right out)
delay(5000); // waits for 5 second
digitalWrite(relay2, LOW); // sets relay 0 off
Serial.println("B");
break;
case 2:
digitalWrite(relay3, HIGH); //sets relay 1 on (right in)
delay(5000); // waits for 5 second
digitalWrite(relay3, LOW); // sets relay 1 off
Serial.println("Switch B OFF");
break;
}
}
if (digitalRead(trimleftPin1) == LOW && //Left trim in
digitalRead(gateposPin1) == LOW){ //only when left gate is out
digitalWrite(relay1, HIGH);
}
else{
digitalWrite(relay1, LOW);} //Left trim out
if (digitalRead(trimleftPin2) == LOW && //only when left gate is out
digitalRead(gateposPin1) == LOW){
digitalWrite(relay0, HIGH);
}
else{
digitalWrite(relay0, LOW);}
if (digitalRead(trimrightPin1) == LOW && //Right trim in
digitalRead(gateposPin2) == LOW){ //only when right gate is out
digitalWrite(relay3, HIGH);
}
else{
digitalWrite(relay3, LOW);} //Right trim out
if (digitalRead(trimrightPin2) == LOW && //only when right gate is out
digitalRead(gateposPin2) == LOW){
digitalWrite(relay2, HIGH);
}
else{
digitalWrite(relay2, LOW);}
}
Robin2 has a good reference for learning about using a time interval in a program. What follows is a slightly modified version of the Blink Without Delay program that's part of the IDE:
#define LEDPIN 13
int ledState = LOW; // track the ledState
const long interval = 1000UL; // interval to pause (milliseconds)
void setup() {
pinMode(LEDPIN, OUTPUT);
}
void loop()
{
pauseWithoutDelay(interval);
if (ledState == LOW) // Blink the LED
ledState = HIGH;
else
ledState = LOW;
digitalWrite(LEDPIN, ledState);
}
/*****
Purpose: to pause a program for a specific number of milliseconds
Parameter List:
unsigned long howLong the number of milliseconds to delay (1000milli = 1sec)
Return value:
void
*****/
void pauseWithoutDelay(unsigned long howLong)
{
unsigned long currentMillis;
unsigned long previousMillis = millis(); // When LED last changed state
while (true) {
currentMillis = millis();
if (currentMillis - previousMillis >= howLong) {
break;
}
}
}
I know this is super repetitive for most of the more knowledgeable folk on here so I apologize ahead of time. I also want to thank those above who have helped steer me in the right direction. I am still struggling with the concept of timers. The above code works using the delay function. Below is one of my attempts to replace the first delay (in case 1 of switchstate) with a timer function and I cant get it to work. I have also tried using a couple of different timer libraries that are available. Any more help would be greatly appreciated.
Thanks!!
#include <elapsedMillis.h>
// variables
byte switch1State = 0; // to store switch reading 0 = off 1 = posA 2 = posB
byte lastSwitch1State = 0; // to check for change
byte switch2State = 2; // to store switch reading 2 = off 3 = posA 2 = posB
byte lastSwitch2State = 2; // to check for change
int relay0 = 8; // Relay 0 connected to pin 8 (left out)
int relay1 = 7; // Relay 1 connected to pin 7 (left in)
int relay2 = 2; // Relay 2 connected to pin 2 (right out)
int relay3 = 4; // Relay 3 connected to pin 4 (right in)
int trimleftPin1 = 5; // Left trim switch in
int trimleftPin2 = 6; // Left trim switch out
int trimrightPin1 = 3; // Right trim switch in
int trimrightPin2 = 10; // Right trim switch out
int gateposPin1 = 11; // Left gate out
int gateposPin2 = 12; // Right gate out
elapsedMillis timer0;
#define interval 1000
void setup() {
Serial.begin(9600);
pinMode(gateposPin1, INPUT);
digitalWrite(gateposPin1, HIGH); // Activate internal pullup
pinMode(gateposPin2, INPUT);
digitalWrite(gateposPin2, HIGH); // Activate internal pullup
pinMode(relay0, OUTPUT); // sets the digital pin as output
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(trimleftPin1, INPUT);
digitalWrite(trimleftPin1, HIGH); // Activate internal pullup
pinMode(trimleftPin2, INPUT);
digitalWrite(trimleftPin2, HIGH); // Activate internal pullup
pinMode(trimrightPin1, INPUT);
digitalWrite(trimrightPin1, HIGH); // Activate internal pullup
pinMode(trimrightPin2, INPUT);
digitalWrite(trimrightPin2, HIGH); // Activate internal pullup
timer0 = 0;
}
void loop(){
// Read the switch and put the result is switchState
if (digitalRead(gateposPin1) == LOW) switch1State = 1;
else switch1State = 0;
if (digitalRead(gateposPin2) == LOW) switch2State = 3;
else switch2State = 2;
// Only do anything if the state has changed
if (switch1State != lastSwitch1State){
lastSwitch1State = switch1State;
switch(switch1State){
case 1:
digitalWrite(relay0, HIGH); // sets relay 0 on (left out)
if (timer0 > interval) {timer0 -= interval;
int gateposPin1 = digitalRead(relay0);
digitalWrite(relay0, !gateposPin1);
// waits for 5 second
digitalWrite(relay0, LOW); // sets relay 0 off
}
Serial.println("A");
break;
case 0:
digitalWrite(relay1, HIGH); //sets relay 1 on (left in
delay(5000); // waits for 5 second
digitalWrite(relay1, LOW); // sets relay 1 off
Serial.println("Switch A OFF");
break;
}}
if (switch2State != lastSwitch2State){
lastSwitch2State = switch2State;
switch(switch2State){
case 3:
digitalWrite(relay2, HIGH); // sets relay 0 on (right out)
delay(5000); // waits for 5 second
digitalWrite(relay2, LOW); // sets relay 0 off
Serial.println("B");
break;
case 2:
digitalWrite(relay3, HIGH); //sets relay 1 on (right in)
delay(5000); // waits for 5 second
digitalWrite(relay3, LOW); // sets relay 1 off
Serial.println("Switch B OFF");
break;
}
}
if (digitalRead(trimleftPin1) == LOW && //Left trim in
digitalRead(gateposPin1) == LOW){ //only when left gate is out
digitalWrite(relay1, HIGH);
}
else{
digitalWrite(relay1, LOW);} //Left trim out
if (digitalRead(trimleftPin2) == LOW && //only when left gate is out
digitalRead(gateposPin1) == LOW){
digitalWrite(relay0, HIGH);
}
else{
digitalWrite(relay0, LOW);}
if (digitalRead(trimrightPin1) == LOW && //Right trim in
digitalRead(gateposPin2) == LOW){ //only when right gate is out
digitalWrite(relay3, HIGH);
}
else{
digitalWrite(relay3, LOW);} //Right trim out
if (digitalRead(trimrightPin2) == LOW && //only when right gate is out
digitalRead(gateposPin2) == LOW){
digitalWrite(relay2, HIGH);
}
else{
digitalWrite(relay2, LOW);}
}
Thanks for the reply and the willingness to help, there is a lot I don't understand about the several things at at time sketch. Below I have parroted what I feel is necessary into my code to make it run, while removing my delay() functions. It will not compile and I don't know why. Also I do not need a blink duration function although I included it just to see if I could get it to work in my sketch. I hope it is something simple that I have missed, it usually is a bracket or something lame. Let me know what you think. Sorry if it's a mess
// variables
byte switch1State = 0; // to store switch reading 0 = off 1 = posA 2 = posB
byte lastSwitch1State = 0; // to check for change
byte switch2State = 2; // to store switch reading 2 = off 3 = posA 2 = posB
byte lastSwitch2State = 2; // to check for change
int relay0 = 8; // Relay 0 connected to pin 8 (left out)
int relay1 = 7; // Relay 1 connected to pin 7 (left in)
int relay2 = 2; // Relay 2 connected to pin 2 (right out)
int relay3 = 4; // Relay 3 connected to pin 4 (right in)
int trimleftPin1 = 5; // Left trim switch in
int trimleftPin2 = 6; // Left trim switch out
int trimrightPin1 = 3; // Right trim switch in
int trimrightPin2 = 10; // Right trim switch out
int gateposPin1 = 11; // Left gate out
int gateposPin2 = 12; // Right gate out
const int relay0Interval = 5000; // Motor out interval
const int relay1Interval = 7000; // Motor in interval
const int relay2Interval = 5000;
const int relay3Interval = 7000;
const int blinkDuration = 500;
byte relay0State = LOW;
byte relay1State = LOW; // LOW = off
byte relay2State = LOW;
byte relay3State = LOW;
unsigned long currentMillis = 0; //stores the value of millis() in each interation of loop()
unsigned long previousrelay0Millis = 0; //store the last time out was updated
unsigned long previousrelay1Millis = 0; //store the last time in was updated
unsigned long previousrelay2Millis = 0; //store the last time in was updated
unsigned long previousrelay3Millis = 0; //store the last time in was updated
void setup() {
Serial.begin(9600);
pinMode(gateposPin1, INPUT);
digitalWrite(gateposPin1, HIGH); // Activate internal pullup
pinMode(gateposPin2, INPUT);
digitalWrite(gateposPin2, HIGH); // Activate internal pullup
pinMode(relay0, OUTPUT); // sets the digital pin as output
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(trimleftPin1, INPUT);
digitalWrite(trimleftPin1, HIGH); // Activate internal pullup
pinMode(trimleftPin2, INPUT);
digitalWrite(trimleftPin2, HIGH); // Activate internal pullup
pinMode(trimrightPin1, INPUT);
digitalWrite(trimrightPin1, HIGH); // Activate internal pullup
pinMode(trimrightPin2, INPUT);
digitalWrite(trimrightPin2, HIGH); // Activate internal pullup
}
void loop(){
currentMillis = millis(); //capture the latest value of millis()
updaterelay0State();
updaterelay1State();
updaterelay2State();
updaterelay3State();
// Read the switch and put the result is switchState
if (digitalRead(gateposPin1) == LOW) switch1State = 1;
else switch1State = 0;
if (digitalRead(gateposPin2) == LOW) switch2State = 3;
else switch2State = 2;
// Only do anything if the state has changed
if (switch1State != lastSwitch1State){
lastSwitch1State = switch1State;
switch(switch1State){
case 1:
digitalWrite(relay0, HIGH); // sets relay 0 on (left out)
digitalWrite(relay0, LOW); // sets relay 0 off
Serial.println("A");
break;
case 0:
digitalWrite(relay1, HIGH); //sets relay 1 on (left in
digitalWrite(relay1, LOW); // sets relay 1 off
Serial.println("Switch A OFF");
break;
}}
// Only do anything if the state has changed
if (switch2State != lastSwitch2State){
lastSwitch2State = switch2State;
switch(switch2State){
case 3:
digitalWrite(relay2, HIGH); // sets relay 0 on (right out)
digitalWrite(relay2, LOW); // sets relay 0 off
Serial.println("B");
break;
case 2:
digitalWrite(relay3, HIGH); //sets relay 1 on (right in)
digitalWrite(relay3, LOW); // sets relay 1 off
Serial.println("Switch B OFF");
break;
}
}
if (digitalRead(trimleftPin1) == LOW && //Left trim in
digitalRead(gateposPin1) == LOW){ //only when left gate is out
digitalWrite(relay1, HIGH);
}
else{
digitalWrite(relay1, LOW);} //Left trim out
if (digitalRead(trimleftPin2) == LOW && //only when left gate is out
digitalRead(gateposPin1) == LOW){
digitalWrite(relay0, HIGH);
}
else{
digitalWrite(relay0, LOW);}
if (digitalRead(trimrightPin1) == LOW && //Right trim in
digitalRead(gateposPin2) == LOW){ //only when right gate is out
digitalWrite(relay3, HIGH);
}
else{
digitalWrite(relay3, LOW);} //Right trim out
if (digitalRead(trimrightPin2) == LOW && //only when right gate is out
digitalRead(gateposPin2) == LOW){
digitalWrite(relay2, HIGH);
}
else{
digitalWrite(relay2, LOW);}
}
void updaterelay0State() {
if (relay0State == LOW) {
if (currentMillis - previousrelay0Millis >= relay0Interval) {
relay0State = HIGH;
previousrelay0Millis += relay0Interval;
}
}
else {
if (currentMillis - previousrelay0Millis >= blinkDuration {
relay0State = LOW;
previousrelay0Millis += blinkDuration;
}
}
}
void updaterelay1State() {
if (relay1State == LOW) {
if (currentMillis - previousrelay1Millis >= relay1Interval) {
relay1State = HIGH;
previousrelay1Millis += relay1Interval;
}
}
else {
if (currentMillis - previousrelay1Millis >= blinkDuration {
relay1State = LOW;
previousrelay1Millis += blinkDuration;
}
}
}
void updaterelay2State() {
if (relay2State == LOW) {
if (currentMillis - previousrelay2Millis >= relay2Interval) {
relay2State = HIGH;
previousrelay2Millis += relay2Interval;
}
}
else {
if (currentMillis - previousrelay2Millis >= blinkDuration {
relay2State = LOW;
previousrelay2Millis += blinkDuration;
}
}
}
void updaterelay3State() {
if (relay3State == LOW) {
if (currentMillis - previousrelay3Millis >= relay3Interval) {
relay3State = HIGH;
previousrelay3Millis += relay3Interval;
}
}
else {
if (currentMillis - previousrelay3Millis >= blinkDuration {
relay3State = LOW;
previousrelay3Millis += blinkDuration;
}
}
}
Balls! I swear I went over the whole thing about ten times looking for errors and couldn't find anything on the lines it was reporting errors. Sometimes an outside eye is best. Thanks!!
Alright, I'm getting closer. My sketch compiled and loads fine but I'm still having issues with the timing. When I flip the switch I get four quick dim blinks of the LEDs on the shield and the serial monitor outputs "A ON" "A OFF", cycled four times then stops. Flipping the switch off I get a single "A off" and thats it. Any ideas, Thanks again to all for all the help!!
// variables
byte switch1State = 0; // to store switch reading 0 = off 1 = posA 2 = posB
byte lastSwitch1State = 0; // to check for change
byte switch2State = 2; // to store switch reading 2 = off 3 = posA 2 = posB
byte lastSwitch2State = 2; // to check for change
int relay0 = 8; // Relay 0 connected to pin 8 (left out)
int relay1 = 7; // Relay 1 connected to pin 7 (left in)
int relay2 = 2; // Relay 2 connected to pin 2 (right out)
int relay3 = 4; // Relay 3 connected to pin 4 (right in)
int trimleftPin1 = 5; // Left trim switch in
int trimleftPin2 = 6; // Left trim switch out
int trimrightPin1 = 3; // Right trim switch in
int trimrightPin2 = 10; // Right trim switch out
int gateposPin1 = 11; // Left gate out
int gateposPin2 = 12; // Right gate out
const int relay0Interval = 5000; // Motor out interval
const int relay1Interval = 7000; // Motor in interval
const int relay2Interval = 5000;
const int relay3Interval = 7000;
const int blinkDuration = 3000;
byte relay0State = LOW;
byte relay1State = LOW; // LOW = off
byte relay2State = LOW;
byte relay3State = LOW;
unsigned long currentMillis = 0; //stores the value of millis() in each interation of loop()
unsigned long previousrelay0Millis = 0; //store the last time out was updated
unsigned long previousrelay1Millis = 0; //store the last time in was updated
unsigned long previousrelay2Millis = 0; //store the last time in was updated
unsigned long previousrelay3Millis = 0; //store the last time in was updated
void setup() {
Serial.begin(9600);
pinMode(gateposPin1, INPUT);
digitalWrite(gateposPin1, HIGH); // Activate internal pullup
pinMode(gateposPin2, INPUT);
digitalWrite(gateposPin2, HIGH); // Activate internal pullup
pinMode(relay0, OUTPUT); // sets the digital pin as output
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(trimleftPin1, INPUT);
digitalWrite(trimleftPin1, HIGH); // Activate internal pullup
pinMode(trimleftPin2, INPUT);
digitalWrite(trimleftPin2, HIGH); // Activate internal pullup
pinMode(trimrightPin1, INPUT);
digitalWrite(trimrightPin1, HIGH); // Activate internal pullup
pinMode(trimrightPin2, INPUT);
digitalWrite(trimrightPin2, HIGH); // Activate internal pullup
}
void loop(){
currentMillis = millis(); //capture the latest value of millis()
updaterelay0State();
updaterelay1State();
updaterelay2State();
updaterelay3State();
// Read the switch and put the result is switchState
if (digitalRead(gateposPin1) == LOW) switch1State = 1;
else switch1State = 0;
if (digitalRead(gateposPin2) == LOW) switch2State = 3;
else switch2State = 2;
// Only do anything if the state has changed
if (switch1State != lastSwitch1State){
lastSwitch1State = switch1State;
switch(switch1State){
case 1:
digitalWrite(relay0, HIGH); // sets relay 0 on (left out)
//digitalWrite(relay0, LOW); // sets relay 0 off
Serial.println("A ON");
break;
case 0:
digitalWrite(relay1, HIGH); //sets relay 1 on (left in
//digitalWrite(relay1, LOW); // sets relay 1 off
Serial.println("A OFF");
break;
}}
// Only do anything if the state has changed
if (switch2State != lastSwitch2State){
lastSwitch2State = switch2State;
switch(switch2State){
case 3:
digitalWrite(relay2, HIGH); // sets relay 0 on (right out)
//digitalWrite(relay2, LOW); // sets relay 0 off
Serial.println("B ON");
break;
case 2:
digitalWrite(relay3, HIGH); //sets relay 1 on (right in)
//digitalWrite(relay3, LOW); // sets relay 1 off
Serial.println("B OFF");
break;
}
}
if (digitalRead(trimleftPin1) == LOW && //Left trim in
digitalRead(gateposPin1) == LOW){ //only when left gate is out
digitalWrite(relay1, HIGH);
}
else{
digitalWrite(relay1, LOW);} //Left trim out
if (digitalRead(trimleftPin2) == LOW && //only when left gate is out
digitalRead(gateposPin1) == LOW){
digitalWrite(relay0, HIGH);
}
else{
digitalWrite(relay0, LOW);}
if (digitalRead(trimrightPin1) == LOW && //Right trim in
digitalRead(gateposPin2) == LOW){ //only when right gate is out
digitalWrite(relay3, HIGH);
}
else{
digitalWrite(relay3, LOW);} //Right trim out
if (digitalRead(trimrightPin2) == LOW && //only when right gate is out
digitalRead(gateposPin2) == LOW){
digitalWrite(relay2, HIGH);
}
else{
digitalWrite(relay2, LOW);}
}
void updaterelay0State() {
if (relay0State == LOW) {
if (currentMillis - previousrelay0Millis >= relay0Interval) {
relay0State = HIGH;
previousrelay0Millis += relay0Interval;
}
}
else {
if (currentMillis - previousrelay0Millis >= blinkDuration) {
relay0State = LOW;
previousrelay0Millis += blinkDuration;
}
}
}
void updaterelay1State() {
if (relay1State == LOW) {
if (currentMillis - previousrelay1Millis >= relay1Interval) {
relay1State = HIGH;
previousrelay1Millis += relay1Interval;
}
}
else {
if (currentMillis - previousrelay1Millis >= blinkDuration) {
relay1State = LOW;
previousrelay1Millis += blinkDuration;
}
}
}
void updaterelay2State() {
if (relay2State == LOW) {
if (currentMillis - previousrelay2Millis >= relay2Interval) {
relay2State = HIGH;
previousrelay2Millis += relay2Interval;
}
}
else {
if (currentMillis - previousrelay2Millis >= blinkDuration) {
relay2State = LOW;
previousrelay2Millis += blinkDuration;
}
}
}
void updaterelay3State() {
if (relay3State == LOW) {
if (currentMillis - previousrelay3Millis >= relay3Interval) {
relay3State = HIGH;
previousrelay3Millis += relay3Interval;
}
}
else {
if (currentMillis - previousrelay3Millis >= blinkDuration) {
relay3State = LOW ;
previousrelay3Millis += blinkDuration;
}
}
}
I would urge you to use CTRL T on your sketches now and then.
Adding comments in the middle of an if function is not recommended.
For readability, I also recommend this style.
if (x == 12)
{
//blah blah
}