I am starting with millis, so I find it still a bit flustering. I have read the guide, but I do stuff wrong haha.
I am working with a flying fader and this piece of code based on this example of Cody Hazelwood, it works briljantly. However, I want to multitask whilst the flying fader is moving to its next position, but the things I have tried make the code dysfunctional. Could someones help me?
Thanks in advance!
void updateFader(int position) {
if (position < analogRead(wiper) - 10 && position > faderMin && !touched) {
digitalWrite(motorDown, HIGH);
digitalWrite(enablePin, HIGH);
while (position < analogRead(wiper) - 10 && !touched) {}; //Loops until motor is done moving
digitalWrite(motorDown, LOW);
digitalWrite(enablePin, HIGH);
delay(1000);
}
else if (position > analogRead(wiper) + 10 && position < faderMax && !touched) {
digitalWrite(motorUp, HIGH);
digitalWrite(enablePin, HIGH);
while (position > analogRead(wiper) + 10 && !touched) {};
digitalWrite(motorUp, LOW);
digitalWrite(enablePin, HIGH);
delay(1000);
}
}
Not without a complete program and a bit more detail about what you mean by multitasking.
And you haven't got very far with millis(). I can't see any in your code fragment but I can see quite a lot of blocking code that would make using millis() pretty pointless.
You have posted the updateFader() function out of context so it is difficult to provide help. Using millis() for timing requires you so do actions in steps based on how much time has passed since something occurred. This allows other things to happen in the slack time between actions.
So, you cannot stay in a function like updateFader() for any appreciable time. Break what the function does into small steps, perhaps each moving the slider a little and do other things between the slider movements. Is the real problem the delay(1000); in the function ? If so then break that down into say 1000 1 millsecond steps and do other things in the slack time.
Here is the entire code, thought it might be a bum to see all. @Steve, I know. I uploaded the working code. This was the latest thing I tried, but it is a mess..... So I was hesitant to upload that
#include <CapacitiveSensor.h> //Library for fader touch sensitivity
#include <Keyboard.h>
//Array to store the random position values
int progress;
long randomVals[3];
//Arduino Pin Assignments
int motorDown = 9; //H-Bridge control to make the motor go down
int motorUp = 8; //H-Bridge control to make the motor go up
int enablePin = 10; //H-Bridge enable to PWM 11 to control speed
//Inputs
int wiper = A0; //Position of fader relative to GND (Analog 1)
//Variables
double faderMax = 0; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
int faderChannel = 1; //Value from 1-8
int value; //To get the random position for the motor
int attempt = 0; //To get the 3 user inputs
int counter = 0; //To differentiate the different touches
//For the pause between the random locations
unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
unsigned long previousPattern = 0;
unsigned long currentPattern = 0;
unsigned long previousTimer = 0;
unsigned long currentTimer = 0;
unsigned long intervalLocation = 3000;
unsigned long intervalPattern = 3000;
//Touchsensor
CapacitiveSensor cs_7_8 = CapacitiveSensor(4, 3);
unsigned long csSum;
volatile bool touched = false; //Is the fader currently being touched?
volatile bool perform = false;
int errorMargin = 50;
//-----------------------------------------------------------------------------------------------------------------------------
void setup() {
pinMode (motorUp, OUTPUT);
pinMode (motorDown, OUTPUT);
pinMode (enablePin, OUTPUT);
randomSeed(analogRead(5));
calibrateFader();
}
//-----------------------------------------------------------------------------------------------------------------------------
void loop() {
checkTouch();
while (perform) {
checkTouch();
showPattern();
}
}
//-----------------------------------------------------------------------------------------------------------------------------
void createValues() {
currentMillis = millis();
for (int i = 0; i < 3; i++) {
if (currentMillis - previousMillis >= intervalLocation && progress == i) {
randomVals[i] = random(1020);
Serial.println(randomVals[i]);
updateFader(randomVals[i]);
previousMillis = millis();
progress++;
}
}
perform = true;
if (progress == 3) {
progress = 0;
}
}
//-----------------------------------------------------------------------------------------------------------------------------
void showPattern() {
currentPattern = millis();
for (int i = 0; i < 3; i++) {
if (currentPattern - previousPattern >= intervalPattern) {
updateFader(randomVals[i]);
previousPattern = millis();
}
}
}
//-----------------------------------------------------------------------------------------------------------------------------
//Calibrates the min and max position of the fader
void calibrateFader() {
//Send fader to the top and read max position
digitalWrite(motorUp, HIGH);
digitalWrite(enablePin, 95);
delay(500);
digitalWrite(motorUp, LOW);
digitalWrite(enablePin, HIGH);
faderMax = analogRead(wiper);
//Send fader to the bottom and read max position
digitalWrite(motorDown, HIGH);
digitalWrite(enablePin, HIGH);
delay(500);
digitalWrite(motorDown, LOW);
digitalWrite(enablePin, HIGH);
faderMin = analogRead(wiper);
}
//-----------------------------------------------------------------------------------------------------------------------------
void updateFader(int position) {
currentTimer = millis();
int currentTimerF = millis();
int previousTimerF = 0;
if (position < analogRead(wiper) - 10 && position > faderMin && !touched && currentTimer - previousTimer <= 1000) {
digitalWrite(motorDown, HIGH);
digitalWrite(enablePin, HIGH);
while (position < analogRead(wiper) - 10 && !touched) {}; //Loops until motor is done moving
digitalWrite(motorDown, LOW);
previousTimer = millis();
}
if (position > analogRead(wiper) + 10 && position < faderMax && !touched && currentTimerF - previousTimerF <= 1000) {
digitalWrite(motorUp, HIGH);
digitalWrite(enablePin, HIGH);
while (position > analogRead(wiper) + 10 && !touched) {};
digitalWrite(motorUp, LOW);
previousTimerF = millis();
}
}
//-----------------------------------------------------------------------------------------------------------------------------
//Check to see if the fader is being touched
void checkTouch() {
long cs = cs_7_8.capacitiveSensor(80); //Sensor resolution is set to 80, for higher sensitivity increase this value (to 2000 approx)
csSum += cs;
if (cs > 100 && csSum >= 3800) { //Arbitrary number
int location = analogRead(A0);
touched = true;
switch (counter) {
case 0: //Show pattern
createValues();
counter++;
break;
case 1: //Read user input
for (int i = 0; i < 3; i++) {
if (touched && location < randomVals[i] + errorMargin && location > randomVals[i] - errorMargin && attempt == i) {
attempt++;
}
}
break;
}
} else {
touched = false;
}
//Reset if attempted
if (attempt == 3) {
Keyboard.begin();
Keyboard.print("YEAH");
attempt = 0;
perform = false;
delay(3000);
counter = 0;
Keyboard.end();
}
}
Oh sorry, and with multitasking I meant: at the moment when you touch the flying fader, it moves to 3 different locations. Because of the delay you can't interrupt that. You have to wait till after the pattern to do the user input. I woul dlike to be able to do the user input at all times.
Read up about state-machines - in short: have one state-machine for the UI, one for the fader action, call them
both every time through loop(), don't use delay() or while/do-while, just use if.