delay to milis

hi forum could anyone help me how to convert following code to use millis() as subtitute to delay().
thank you

#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8
int frequency = 0;
void setup() {
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  
  // Setting frequency-scaling to 20%
  digitalWrite(S0,HIGH);
  digitalWrite(S1,LOW);
  
  Serial.begin(9600);
}
void loop() {
  // Setting red filtered photodiodes to be read
  digitalWrite(S2,LOW);
  digitalWrite(S3,LOW);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  // Printing the value on the serial monitor
  Serial.print("R= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.print("  ");
  delay(100);
  // Setting Green filtered photodiodes to be read
  digitalWrite(S2,HIGH);
  digitalWrite(S3,HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  // Printing the value on the serial monitor
  Serial.print("G= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.print("  ");
  delay(100);
  // Setting Blue filtered photodiodes to be read
  digitalWrite(S2,LOW);
  digitalWrite(S3,HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  // Printing the value on the serial monitor
  Serial.print("B= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.println("  ");
  delay(100);
}

What sensor is this?

tcs3200 color sensor

pinMode(sensorOut, INPUT);

Are you sure this is correct?

Oh, it comes out of the sensor and into the arduino. Makes sense :-[

@Metallor yes sure and the code work, but i'am confusing how to change the delay to milis() concept

Do you want to keep the delays between the readings? Does it cause the sensor to act differently? Or do you just want to delay the time between outputting to the serial?

donimart:
hi forum could anyone help me how to convert following code to use millis() as subtitute to delay().
thank you

something like this is what you are looking for?

#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8
#define PERIOD 100
#define Arr_size 3

//array of pointer functions
typedef void (* functionPtrs) (void);
functionPtrs filters[Arr_size] = {&Red, &Green, &Blue};

int frequency = 0;
unsigned long oldtime;
uint8_t i = 0;

void setup() {
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);

  // Setting frequency-scaling to 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);

  Serial.begin(9600);
  oldtime = millis();
}

void loop() {
  if (millis() - oldtime > PERIOD) { //call function every 100ms
    filters[i]();
    Serial.println(frequency);//printing color frequency
    i = (i + 1) % Arr_size; //counter loops 0-2
    oldtime = millis();
  }
}

void Red()
{
  // Setting red filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  // Printing the value on the serial monitor
  Serial.print("R= ");//printing name
}

void Blue()
{
  // Setting Blue filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  // Printing the value on the serial monitor
  Serial.print("B= ");//printing name
}

void Green()
{
  // Setting Green filtered photodiodes to be read
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  // Printing the value on the serial monitor
  Serial.print("G= ");//printing name
}

hi @sherzaad how to slow down the serial print out put on the serial monitor. its run to fast

donimart:
hi @sherzaad how to slow down the serial print out put on the serial monitor. its run to fast

just increase PERIOD!!!! :slight_smile:

Try this

#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define sensorOut 8
int frequency = 0;
const unsigned long printPeriod = 1000;
unsigned long lastPrintedTime;
unsigned long currentTime;

void setup()
{
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  // Setting frequency-scaling to 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  Serial.begin(115200);
}
void loop()
{
  currentTime = millis();
  // Setting red filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Reading the output frequency
  int redFrequency = pulseIn(sensorOut, LOW);
  // Setting Green filtered photodiodes to be read
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  int greenFrequency = pulseIn(sensorOut, LOW);
  // Setting Blue filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  int blueFrequency = pulseIn(sensorOut, LOW);
  if (currentTime - lastPrintedTime >= printPeriod)
  {
    printValues(redFrequency, greenFrequency, blueFrequency);
    lastPrintedTime = currentTime;
  }
}

void printValues(int red, int green, int blue)
{
  // Printing the value on the serial monitor
  Serial.print("R= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.print("  ");
  delay(100);
  // Printing the value on the serial monitor
  Serial.print("G= ");//printing name
  Serial.print(frequency);//printing GREEN color frequency
  Serial.print("  ");
  delay(100);
  // Printing the value on the serial monitor
  Serial.print("B= ");//printing name
  Serial.print(frequency);//printing BLUE color frequency
  Serial.println("  ");  
  delay(100);
}

Note that all of the values are read before any printing
The code could be tidied further using an array and a for loop

@sherzaad yes works thank you indeed. btw if i could share with all of you master. i face nearly three weeks trouble to solve this problem ( the bottomServo of this project (https://howtomechatronics.com/projects/arduino-color-sorter-project/) not working in my case, and also many facing the same as mentioned in the comment of the project).
the code of the project

#include <Servo.h>
#define S0 2
#define S1 3
#define S2 4
#define S3 5
#define sensorOut 6
Servo topServo;
Servo bottomServo;
int frequency = 0;
int color=0;
void setup() {
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  // Setting frequency-scaling to 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  topServo.attach(7);
  bottomServo.attach(8);
  Serial.begin(9600);
}
void loop() {
  topServo.write(165);
  delay(500);
  
  for(int i = 165; i > 107; i--) {
    topServo.write(i);
    delay(2);
  }
  delay(500);
  
  color = readColor();
  delay(10);  
  switch (color) {
    case 1:
    bottomServo.write(50);
    break;
    case 2:
    bottomServo.write(75);
    break;
    case 3:
    bottomServo.write(100);
    break;
    case 4:
    bottomServo.write(125);
    break;
    case 5:
    bottomServo.write(150);
    break;
    case 6:
    bottomServo.write(175);
    break;
    
    case 0:
    break;
  }
  delay(300);
  
  for(int i = 107; i > 70; i--) {
    topServo.write(i);
    delay(2);
  } 
  delay(200);
  
  for(int i = 70; i < 165; i++) {
    topServo.write(i);
    delay(2);
  }
  color=0;
}
// Custom Function - readColor()
int readColor() {
  // Setting red filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  int R = frequency;
  // Printing the value on the serial monitor
  Serial.print("R= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.print("  ");
  delay(50);
  // Setting Green filtered photodiodes to be read
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  int G = frequency;
  // Printing the value on the serial monitor
  Serial.print("G= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.print("  ");
  delay(50);
  // Setting Blue filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  frequency = pulseIn(sensorOut, LOW);
  int B = frequency;
  // Printing the value on the serial monitor
  Serial.print("B= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.println("  ");
  delay(50);
  if(R<45 & R>32 & G<65 & G>55){
    color = 1; // Red
  }
  if(G<55 & G>43 & B<47 &B>35){
    color = 2; // Orange
  }
  if(R<53 & R>40 & G<53 & G>40){
    color = 3; // Green
  }
  if(R<38 & R>24 & G<44 & G>30){
    color = 4; // Yellow
  }
  if(R<56 & R>46 & G<65 & G>55){
    color = 5; // Brown
  }
  if (G<58 & G>45 & B<40 &B>26){
    color = 6; // Blue
  }
  return color;  
}

i already tried to modified the code by change the delay with millis() or state machine concept but so far i only make the topServo with milis() where also i found from this Operating Servo without delay function and using millis - Programming Questions - Arduino Forum by @ardy_guy.
the modified topServo code. will run from pos 165 to 107 to 70 and back to 165

#include<Servo.h>

    Servo topServo;

byte pos = 165;
int servoPause = 1300;
unsigned long previousMillisServo;
unsigned long currentMillis;


    
void setup() {

  topServo.attach(5);
  topServo.write(165)
  Serial.begin(9600);
}

void loop() {

    currentMillis = millis();
        if (currentMillis - previousMillisServo >= servoPause) //time to move the servo
      {
        moveTheServo();
      }
 
}       

void moveTheServo()
{
  bool newMove=true; //otherwise it does all the moves all the time
  if (pos == 165 && newMove)
  {
    pos = 107;
    newMove=false;
  }

  if (pos == 107 && newMove)
  {
    pos = 66;
    newMove=false;
  }
  
   if (pos == 66 && newMove)
  {
    pos = 165;
    newMove=false;
  }
  topServo.write(pos);
  previousMillisServo = currentMillis;
}

also in my modified code above for topServo also i facing difficulties how to stop topServo at certain position at certain time e.g stop at pos = 165 for 500ms or stop at pos = 107 for 500ms.
hope anyone of you master here willing to help me at least suggest me how to combine the code made by @sherzaad and my modified topServo code run in where run millis to be able to solve the problem i'm facing and some people in the project comment. thank you indeed

hi @UKHeliBob could you suggest me how to combine your code with my topServo modifed code (if it's correct programatically) to be something like project mentioned in #10 comment. thank you

donimart:
hi @UKHeliBob could you suggest me how to combine your code with my topServo modifed code (if it's correct programatically) to be something like project mentioned in #10 comment. thank you

The whole point of using millis() for timing is that it does not interfere with other code in loop() so you could just copy the contents of my loop() function to a new function in your program and call it from your loop(). I promise you that my program will not interfere with the timing in yours. However, because your program uses delay() it will interfere with mine. You need to eliminate the use of delay() in your program.

hi @UKHeliBob i just copied your code exactly as written but the serial monitor just outputting R 0, G 0, B 0 your code code is pretty easier for me to diggest but dont know why no result for each colors frequency

Post the complete code that you are testing

@sherzaad how to modified this following 5 line of your code to simple one, i mean make it to be more simple to understand ( i'am sorry i'am beginner)
e.g the uint8_t i = 0; become unsigned integer i = 0;

typedef void (* functionPtrs) (void);

functionPtrs filters[Arr_size] = {&Red, &Green, &Blue};

uint8_t i = 0;

filters*();*
i = (i + 1) % Arr_size; //counter loops 0-2

@UKHeliBob

#define S0 2
#define S1 3
#define S2 4
#define S3 5
#define sensorOut 6
int frequency = 0;
const unsigned long printPeriod = 1000;
unsigned long lastPrintedTime;
unsigned long currentTime;

void setup()
{
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  // Setting frequency-scaling to 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  Serial.begin(115200);
}
void loop()
{
  currentTime = millis();
  // Setting red filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Reading the output frequency
  int redFrequency = pulseIn(sensorOut, LOW);
  // Setting Green filtered photodiodes to be read
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  int greenFrequency = pulseIn(sensorOut, LOW);
  // Setting Blue filtered photodiodes to be read
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  int blueFrequency = pulseIn(sensorOut, LOW);
  if (currentTime - lastPrintedTime >= printPeriod)
  {
    printValues(redFrequency, greenFrequency, blueFrequency);
    lastPrintedTime = currentTime;
  }
}

void printValues(int red, int green, int blue)
{
  // Printing the value on the serial monitor
  Serial.print("R= ");//printing name
  Serial.print(frequency);//printing RED color frequency
  Serial.print("  ");
  delay(100);
  // Printing the value on the serial monitor
  Serial.print("G= ");//printing name
  Serial.print(frequency);//printing GREEN color frequency
  Serial.print("  ");
  delay(100);
  // Printing the value on the serial monitor
  Serial.print("B= ");//printing name
  Serial.print(frequency);//printing BLUE color frequency
  Serial.println("  "); 
  delay(100);

What have you got the baud rate set to in the Serial monitor ?

The program sets it to 115200. Make sure that the Serial monitor and program baud rates are the same

yes i also change the baud rate as the code written 115200 within setup() at the bottom of the serial monitor

OK. Found the problem
Substtute this version for the original printValues() function

void printValues(int red, int green, int blue)
{
  Serial.print("R= ");//printing name
  Serial.print(red);//printing RED color frequency
  Serial.print("  ");
  Serial.print("G= ");//printing name
  Serial.print(green);//printing GREEN color frequency
  Serial.print("  ");
  Serial.print("B= ");//printing name
  Serial.println(blue);//printing BLUE color frequency
}