[Interactive Serious Game] Seeking help with implementing sensors

Hi there :slight_smile: , I am working on a group project for an Interactive Serious Game for children but I need some advice for the implementation in practice.

I will do my best to explain everything. If anything is still unclear, check out my Flowcharts, images and my Electrical diagrams or feel free to ask me anything you want. I appreciate it.

I am using an Arduino Uno R3 and 4x HC-SRO4 sensors.

In this topic I will focus on the Arduino side of the project but I will give a general idea about the whole project.

The goal is for children to stand on the tile with the right answer in a 2x2 grid. The goal is: Learning children something and to let them stay in motion.

C# part:
-A beamer will be hung upside down with it’s lens facing the ground and
you will see a C# application being reflected on the ground.
-A random addition will be performed with numbers and the calculation will be shown on the ground.
-A 2x2 grid will be filled up randomly with numbers including the answer.
-The C# application will read the responses from the Arduino.
-The children need to choose a right answer in a certain interval.

Now comes the Arduino part.
-A HC-SRO4 ultrasound sensor is hung above each tile (upside down with the sensor facing the ground) to represent an answer.
-A player stands on a specific tile representing a specific answer and a change in distance will be measured by a certain sensor and the Arduino will send a response to the C# part of the game.

It want to make this project reliable in every situation.

First problem: I tested my ultrasound sensors in a room with a ceiling height of 2.5m(≈98.43Inches). But the ceiling can be up to 10m(≈393.70Inches) high when I am going to present my project. That is out of reach for my sensors and too high for me to hang up sensors.

Second problem:
During my testing, I realized that sudden movements and curves can result in inaccurate readings because the sound waves are not bouncing back correctly.

Third problem:
It is possible that the ultrasound sensors will interfere with each other after a great distance. The more distance the sound waves travel, the more they scatter out. And they may collide with each other and result in inaccurate readings. It is also possible that the readings won’t be accurate in a noisy environment.

Fourth problem:
The sensors are not reading the distance simultaneously, so the delay in the game is too big.

Maybe my way of approaching this project is a bit too complicated. There might be simpler solutions to solve my problems.

I did some research and these may be possible solutions?
-Using a weight sensor that is capable of holding a weigh between 20~100kg.
(Don’t have these sensors currently.)
-Using IR sensors instead of Ultrasound sensors.
(Don’t have these sensors currently.)
-Using an I2C controller.
(Don’t have this currently and no experience with it.)
-Using an array to execute the code faster.

My code:

const int trigPin = 6;
const int echoPin = 7;

const int trigPin2 = 8;
const int echoPin2 = 9;

const int trigPin3 = 10;
const int echoPin3 = 11;

const int trigPin4 = 12;
const int echoPin4 = 13;

void setup() {
  Serial.begin (9600);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(triggerPin2, OUTPUT);
  pinMode(echoPin2, INPUT);

  pinMode(triggerPin3, OUTPUT);
  pinMode(echoPin3, INPUT);

  pinMode(triggerPin4, OUTPUT);
  pinMode(echoPin4, INPUT);
}

void loop() {
  long duration1, distance1;
  digitalWrite(trigPin1, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin1, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin1, LOW);
  duration1 = pulseIn(echoPin1, HIGH);
  distance1 = (duration1 / 2) * 0.0343;

  if (distance1 >= 450 || distance1 <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print ( "Sensor1  ");
    Serial.print ( distance1);
    Serial.println("cm");
  }
  delay(2000);
  long duration2, distance2;
  digitalWrite(trigPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin2, LOW);
  duration2 = pulseIn(echoPin2, HIGH);
  distance2 = (duration2 / 2) * 0.0343;

  if (distance2 >= 450 || distance2 <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print("Sensor2  ");
    Serial.print(distance2);
    Serial.println("cm");
  }

  delay(2000);
  long duration3, distance3;
  digitalWrite(trigPin3, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin3, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin3, LOW);
  duration3 = pulseIn(echoPin3, HIGH);
  distance3 = (duration3 / 2) * 0.0343;

  if (distance3 >= 450 || distance3 <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print("Sensor3  ");
    Serial.print(distance3);
    Serial.println("cm");
  }

    delay(2000);
  long duration4, distance4;
  digitalWrite(trigPin4, LOW);  
  delayMicroseconds(2); 
  digitalWrite(trigPin4, HIGH);
  delayMicroseconds(10); 
  digitalWrite(trigPin4, LOW);
  duration4 = pulseIn(echoPin4, HIGH);
  distance4 = (duration4 / 2) * 0.0343;

  if (distance4 >= 450 || distance4 <= 0) {
    Serial.println("Out of range");
  }
  else {
    Serial.print("Sensor4 ");
    Serial.print(distance4);
    Serial.println("cm");
  }
}

Hi TonyCoding, I have never attempted something like this before, but if I were you, I would use a simple pressure plate switch similar to something like this: https://www.youtube.com/watch?v=c6RXu0pYUVI, to detect a human presence on a tile. I doubt ultrasonic sensors would be as reliable or easy to implement for such a task as you've already discovered. The solution above should work for your project and should be really easy to implement and customize (it can be made out of cardboard and tinfoil)! Hope that helps, John Wolf Progetto Company

You could also look into capacitive sensing,

https://playground.arduino.cc/Main/CapacitiveSensor/

Thank you for the reply. I think a pressure plate would be way easier to implement and also more reliable.

The code would work similar to a button. Because a pressure plate is literally a big button.

Would it be something like this?

 //Pressure plate
const int pressurePlatePins[] = {12, 11, 10, 9};
int pressurePlateStates[] = {0, 0, 0, 0};

//LEDs
const int ledPins[] = {8, 7, 6, 5};

void setup() {
  for (int i = 0; i < 4; i++) {
    pinMode(pressurePlatePins[i], INPUT);
    pinMode(ledPins[i], INPUT);
    digitalWrite(ledPins[i], LOW);
  }
}

void loop() {
   for (int i = 0; i < 4; i++) {
    pressurePlateStates[i] = digitalRead(pressurePlatePins[i]);
  }
  if (pressurePlates[i] == HIGH) {
    /*Giving a response to the C# application.
      The C# Application is connected to the same USB port and
      the variable will be saved as a String in the C# code.*/
    if (i == 0) {
      Serial.println('1');
    }
    else if (i == 1) {
      Serial.println('2');
    }
    else if (i == 2) {
      Serial.println('3');
    }
    else if (i == 3) {
      Serial.println('4');
    }
  }
}
  • literally

Pressure plate codes the same as a contact switch?