Timing for Sensor Readings

Hi All

I would like some help if you don't mind. I am new to programming (of any kind). I have been through the basic projects and have successfully written code for things like blinking LEDS and the like.

Now I have ran into my first problem.

I have two sensors - 1. Ultrasonic 2. Temp

I want to take a reading from sensor 1 every 500 ms, and a reading from sensor 2 every 10000 ms.

Its not the code for the individual processes I have an issue with but I cant get them to work together.

Every way I have tried to compile this results in the ultrasonic sensor waiting for the temp sensor to take reading before it will take it second reading.

I understand that arduino cant run multiple simultaneous processes so does this mean i would need to use a separate arduino or is there a way to achieve this

I will include my code because that seems to be the done thing but really I am looking for general information as more sensors will be added later and all will have different timings.

End result wanted is a sensor bot, but at the moment i'm just monitoring readings through serial.

Code for Ultrasonic sensor:

#define trigPin 13
#define echoPin 12
#define led 11
#define led2 10

void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(led, OUTPUT);
pinMode(led2, OUTPUT);
}

void loop() {
long duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
if (distance < 4) {
digitalWrite(led,HIGH);
digitalWrite(led2,LOW);
}
else {
digitalWrite(led,LOW);
digitalWrite(led2,HIGH);
}
if (distance >= 200 || distance <= 0){
Serial.println("Out of range");
}
else {
Serial.print(distance);
Serial.println(" cm");
}
delay(500);
}

Code for Temperature sensor:

float temp;
int tempPin1 = 0;

void setup()
{
Serial.begin(9600);
}

void loop()
{
temp = analogRead(tempPin1);
temp = temp * 0.48828125;
Serial.print("TEMPRATURE 1 = ");
Serial.print(temp);
Serial.print("*C");
Serial.println();
delay(10000);
}

Thanks in advance for any help you can give

You can combine both ultrasonic sensor reading and temperature sensor reading in one loop() function. There is no need for another Arduino and no need to run simultaneous processes.
There are multiple ways to achieve your purpose. You will learn programming techniques along the way, so don't worry.

I added two constants in your sketch, ultrasonicInterval and tempInterval which are intervals in ms for sensor readings. Then there are lastUltrasonicTime and lastTempTime variables which store the last millisecond and keep track of time. We can get rid of delays in this way. You can learn about millis() function in Arduino reference if you haven't already.

Feel free to ask questions. I hope this helps. :slight_smile:

#define trigPin 13
#define echoPin 12
#define led 11
#define led2 10
float temp;
const int tempPin1 = 0;
const int ultrasonicInterval = 500;
const int tempInterval = 10000;
unsigned long lastUltrasonicTime =  0;
unsigned long lastTempTime = 0;

void setup() {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
}

void loop() {
  if (millis() - lastUltrasonicTime >= ultrasonicInterval) {
    //Code for ultrasonic sensor reading
    long duration, distance;
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    distance = (duration / 2) / 29.1;
    if (distance < 4) {
      digitalWrite(led, HIGH);
      digitalWrite(led2, LOW);
    }
    else {
      digitalWrite(led, LOW);
      digitalWrite(led2, HIGH);
    }
    if (distance >= 200 || distance <= 0) {
      Serial.println("Out of range");
    }
    else {
      Serial.print(distance);
      Serial.println(" cm");
    }
    //Ultrasonic sensor reading ends here
    lastUltrasonicTime = millis(); //assigns to new millis()
  }

  if (millis() - lastTempTime >= tempInterval) {
    //Code for temperature sensor reading
    temp = analogRead(tempPin1);
    temp = temp * 0.48828125;
    Serial.print("TEMPRATURE 1 = ");
    Serial.print(temp);
    Serial.print("*C");
    Serial.println();
    //Temperature sensor reading ends here
    lastTempTime = millis(); 
  }
}

I understand that arduino cant run multiple simultaneous processes so does this mean i would need to use a separate arduino or is there a way to achieve this

The Arduino cannot run multiple simultaneous processes but it can run 2 or more so fast in series that it looks like they are running at the same time.

The trick is to remove all the delay()s from your program. Read this thread to see how to do it Doing multiple things at the same time

There are two separate issues - combining the code and eliminating the use of delay() to manage timing.

This demo shows a simple way to merge code and the demo several things at a time shows ho to use millis() to manage timing.

...R

Thanks all for the help everyone.

theinlinaung2010 your code was great, after breaking it down and working out what each line did it makes almost perfect sense.

The part I don't get is that there is only one line of my code that you changed. int tempPin1 = 0; to const int tempPin1 = 0;

I've tried to find a solid reason for this but all I can come up with is lower memory usage, but opinion seems to be divided on that.

Thanks again this info has given me exactly what i needed to continue my project.

Maddmatrix:
The part I don't get is that there is only one line of my code that you changed. int tempPin1 = 0; to const int tempPin1 = 0;

I've tried to find a solid reason for this but all I can come up with is lower memory usage, but opinion seems to be divided on that.

Thanks again this info has given me exactly what i needed to continue my project.

This is just a practice assigning a constant when the value does not change in the code later. It prevents you from accidentally changing it and yes, it lowers the memory (RAM) usage which is a good thing.

Just another example.

//take US readings every half second
unsigned long USInterval=500;
unsigned long lastUSread=0;
//take temperature radings every second
unsigned long tempInterval=1000;
unsigned long lastTempRead=0;
//update display every 1.37 seconds (just to be random :)
unsigned long displayInterval=1370;
unsigned long lastDisplayUpdate=0;

int USreading=0;
int temperature=0;

void setup()
{

}

void loop()
{
  unsigned long t=millis();

  if ((t-lastUSread)> USInterval)
  {
    getUS();
    lastUSread=t;
  }

  if ((t-lastUSread)> USInterval)
  {
    getUS();
    lastUSread=t;
  }


  if ((t-lastTempRead)> tempInterval)
  {
    getTemp();
    lastTempRead=t;
  }

  if ((t-lastDisplayUpdate)> displayInterval)
  {
    updateDisplay();
    lastDisplayUpdate=t;
  } 
}

void updateDisplay()
{
  char buffer[30];
  //replace this junk for your real code here

  sprintf(buffer,"Temperature is %d",temperature);
  Serial.println(buffer);
  sprintf(buffer,"Distance is %d",USreading);
  Serial.println(buffer);

}

void getTemp()
{
  //put your real code here
  temperature = random(37,41);
}


void getUS()
{
  //put your real code here
  USreading = random(45,119);
}