People holding hands to trigger audio file

Hello Arduino Forum. I'm new in here.
I am musician who have got little experience with arduino.
I have a project I would like to do and was wandering what are my option for doing so.

My project should do the following:
When two people are holding hands it should play an audio file. when the people are releasing their hands the audio file is paused. If they are holding again then the audio file is resume. If they are holding more than a certain time (let's say 1 minute) the audio file will play until the end even if they already release their hands.

My first question:

  1. Can I do the above considerably easy without need to use external software such as max/MSP?
  2. how can I detect when two people are holding hands with arduino? any further reading regarding it?
  3. Can I create a fade time for the track to start and/or pause?
  4. how can I send the audio out from the DFPlayer mini (is it a good choice for that project?) to four or more speakers?

Thanks!

You could detect a completed, high resistance, circuit, only if you can get them to hold a metal contact with their other hand. But I don't know how you would tell if the contact was actually hand-to-hand. Could be any other contact points.
Any image analysis software would be quite expensive and involved and WAY beyond the Arduino.

So I encounter that topic: Human chain - body conductivity - #7 by wvmarle
and I create that configuration in order to read the value from the analog pin A0:

R1 is pull A0 to 5V . why using such an high value (10M) is necessary? Can I use much lower value (10k) so the pull up will be stronger or is better leaving 10M?
shall I also add a resistor between wire1 to ground?

here is code for the moment:

int pin_touch = A0;
uint16_t reading;
uint16_t lastreading;
unsigned long previousMillis = 0;
const long interval = 100; 

void setup() {
Serial.begin(9600);
lastreading = reading;

}

void loop() {
  if(millis() - previousMillis >= interval) 
  {
    previousMillis = millis();
    reading = analogRead(pin_touch);
  if(lastreading != reading)
  {
  Serial.print("rgeadin: ");
  Serial.println(reading);
  lastreading = reading;
}
  }
}

I try to filter-out repeating numbers. Am I doing it the right way?

thanks

You can do anything you want, but you STILL have not shown how to connect the wires to TWO different people!

my mistake.
person 1 will hold one wire with his one hand while person 2 will hold the other wire with is one hand.
When the two persons will also hold their seconds hands together they will close the circuit between A0 and GND .
I checked that with my father and it is working.
when no one is holding the wires I read around 1023 from A0. when we hold our hands together while each of us holding one of the wires with is spare hand the value I am reading is drop to around 50 - 200 .

That works, but have person 1 touch person 2 some place other than hand, perhaps neck, and see what you get.

I see. they will be limited to only touching hands.
What about the value of R1 ? choosing lower value could be dangerous in any way?
adding a resistor between wire 1 to GND could benefit in any way? (I guess not because the body itself acting like a resistor to ground(?))

Ok, you will be in charge of touching!
What voltage are you working with? Looks to be 5 volts. Can you feel 5 volts with your fingers? likely not. Then include a 10 meg resistor and the feel will not even notice the 5 volts at almost NO current. Just use the circuit as you showed it.
Good luck,
Paul

1 Like

Shall I use separate power supply? one for the DFPlayer and another for the arduino?

here is my code for the moment:

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

int pin_touch = A0;
uint16_t reading;
uint16_t lastreading;
unsigned long previousMillis = 0;
const uint16_t interval = 20; 
const uint16_t threshold = 350;




void setup() {
 mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  Serial.println();
  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));
  
  myDFPlayer.setTimeOut(500); //Set serial communictaion time out 500ms
  
  //----Set volume----
  myDFPlayer.volume(20);  //Set volume value (0~30).
  myDFPlayer.volumeUp(); //Volume Up
  myDFPlayer.volumeDown(); //Volume Down
  lastreading = reading;
  myDFPlayer.play(1);

}

void loop() {
  if(reading > threshold)
  {
    myDFPlayer.pause();
  }
  else
   myDFPlayer.start();
  if(millis() - previousMillis >= interval) 
  {
    previousMillis = millis();
    reading = analogRead(pin_touch);
  if(lastreading != reading)
  {
  Serial.println(reading);
  lastreading = reading;
}
  }
}

how can I improve my loop section?

void loop() {
  if(reading > threshold)
  {
    myDFPlayer.pause();
  }
  else
   myDFPlayer.start();
  if(millis() - previousMillis >= interval) 
  {
    previousMillis = millis();
    reading = analogRead(pin_touch);
  if(lastreading != reading)
  {
  Serial.println(reading);
  lastreading = reading;
}
  }
}

every time the reading is less then the threshold the line: "myDFPlayer.start();" is executed.
I am having lots of clicks in the audio file playing. I'm assuming is because that line that get executed over and over again?
how can I prevent that?

edit: I'll try to be more precise:

My needs from that project are:

A - while two persons are holding hands the DFPlayer will play an audio file.

B - when the two person stops holding hands the DFPlayer will pause.

C- When holding again the DFPlayer will resume.

D - If the two persons are holding their hands more than one minute - the audio file will play until the end regardless if the two persons are still holding or not.

in order to decide if the persons are holding hands I'm using two piece of wire between A0 and ground. A0 is pull up to +5V.

when the two person are holding one wire that is connected to A0 and the other that is connected to ground, the moment they holds their two others hands together they will close the circuit and the value at A0 will fall below a certain threshold that indicates hands holding.

I have the following code:

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini player;

//input pin//
int pin_touch = A0;

//reading from input pin//
uint16_t reading;
uint16_t lastreading;

unsigned long previousMillis = 0;

const uint16_t interval = 100; 

const uint16_t threshold = 500;


enum DeviceState {INITIALISING, HOLD, RELEASE};
DeviceState deviceState = DeviceState::INITIALISING;



void setup() {
 mySoftwareSerial.begin(9600);
  Serial.begin(115200);
  Serial.println();
  if (!player.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));
  
  player.setTimeOut(500); //Set serial communictaion time out 500ms
  
  //----Set volume----
  player.volume(20);  //Set volume value (0~30).
  lastreading = reading;
  deviceState = DeviceState::HOLD;
  for(int i = 0; i < 20; i++)
  {
    analogRead(pin_touch);
    delay(50);
  }
 
}

void loop() {
  
  //printing the value from A0 in intervals//
  uint16_t reading = analogRead(pin_touch);
  if(millis() - previousMillis >= interval) 
  {
    previousMillis = millis();
    reading = analogRead(pin_touch);
  if(lastreading != reading)
  {
    Serial.print("Reading: ");
    Serial.println(reading);
    lastreading = reading;
  }
  }

  switch (deviceState) {
    case DeviceState::INITIALISING:
      break;
    case DeviceState::HOLD:
    
    //holding hands//
      if(reading < threshold)
      {
       player.start();
       deviceState = DeviceState::RELEASE;
      }
      break;
    case DeviceState::RELEASE:
    
    //not holding hands//
    if(reading > threshold)
    {
      player.pause();
      deviceState = DeviceState::HOLD;
    }
    break;
  }  
}

the above code working fine for the following:

It start and play the audio file while holding hands.

It pause the audio file when no hands are held.

Two things I would like to solve with no success:

  1. when the hands are release there is a state of bouncing so the audio is pause start and pause again creating noise. A solution I think of: when detecting hand release - first fade volume to 0 and only then pause the audio file.
  2. I can't make point D from the top of the post.

Any help with those two?

Thanks!

No, touching contact with any part of the body will trigger it.

I would advise that the two wires that have to be touched are metal rods placed so far apart so that one person can’t touch them both.

You could address that by maybe reducing the value of the pull up resistor to say 510K. The other way would be to use a small delay after you have paused the music before the next analogue reading.

When you detect the first hold, make a note of the value of the millis counter in a variable. Then at the end of the loop test to see if the current millis time minus this variable is greater than a minute. Note this is all done in milliseconds and the variables involved should be of the unsigned long type. To make a number into this variable type put UL immediately after the number, that is no space. This would then set a Boolean variable that would stop any new reading that would otherwise detect a break.
Then reset this Boolean variable when the track ends.

Is it for safety measurement or something else?

Is there any other way I could to detect two persons holding one each other hand without the need to hold another piece of wire with their second hand?

I presume this is some sort of art exhibition and if one person could hold both rods then that would not be so good. So it is purely how I perceive the aesthetic.
I had done a lot of exhibitions and one very large scale installation.

I can only think of some sort of computer vision setup, but that is way out of the Arduino league and more of the Raspberry Pi 4 project. Even then it would require quite a bit of experiment and writing code that I think you could not cope with. Given you said in your first post

ok, so it is only aesthetic concern, no safety. Yes, you are right, it is a part of an art installation.
I'm thinking of using Arduino only for sensing the input from the persons holding hands. For the moment I'm afraid it be much easier for me using max MSP for the system itself.

The arduino might need to be place far away from the area the persons will be and made the contact.
what is the max length the rods can be? is 15 meter long should be fine as well?

By rods I had envisage a 20cm metal rod about 1cm in diameter connected by wires to the Arduino.
If they were 15 meters long then are you thinking about a sort of corridor that they walk along? It would block free movement round the exhibition hall, wouldn't it?

I'm thinking about a place in the middle of a room to place a small open box so people can hold their hands inside it and from the outside of the box will be the two rods in order to close the circuit with the other hands.thosw two wires will be placed across the floor room to a point at the corner which there a the arduino will be.
I'm not sure yet if this is how it will be done - I just ask in general if it can arise a problem when using such a long cable (15m or so) ?

Well having a wire that long could act as a pick-up for any interference knocking about from light fittings, especially if they are dimmed. But as they are only connected to the ground and 5V it should not be much of an issue. I would however put a series resistor of about 100 ohms at the Arduino end in case these were ever shorted out with say a metallic trolly. This will prevent you having a short circuit on the Arduino power supply.

like that? (R2 and R3 )