Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by KnightRiderGuy · Nov 23, 2015 at 05:21 PM · arraylightingtriggerarduinoaudio.playoneshot

Arduino LDR Sensor to Play Audio Clip At A Certain Level

I am trying to get information from a simple LDR light sensitive Resistor to trigger an audio clip in Unity 3D. I can get the clip to play but it overlaps and repeats the audio. What I want it to do is activate an audio clip from a random array of audio clips. How can I do this? This is the code I have.

 using UnityEngine;
 using System.Collections;
 using System.IO.Ports;
 using System.Threading;
 
 public class Sending : MonoBehaviour {
 
     //Random Clips
     public AudioClip[] voices;
     public GameObject worldLight;
     public static Sending sending;
 
     //public static SerialPort sp = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
     public static SerialPort sp = new SerialPort("/dev/cu.wchusbserial1420", 115200);
 
     public string message2;
 
 
 
     void Awake () {
         if (sending == null) {
             DontDestroyOnLoad (gameObject);
             sending = this;
         } else if (sending != this) {
             Destroy (gameObject);
         }
         
     }
 
 
     float timePassed = 0.0f;
     // Use this for initialization
     void Start () {
         OpenConnection();
     }
     
     // Update is called once per frame
     void Update () {
         //timePassed+=Time.deltaTime;
         //if(timePassed>=0.2f){
 
             //print("BytesToRead" +sp.BytesToRead);
             message2 = sp.ReadLine();
             print(message2);
         //    timePassed = 0.0f;
         //}
 
         if (message2!="") {
             print("called");
             lightMeUp(message2);
         }
     }
 
     public void OpenConnection() 
     {
        if (sp != null) 
        {
          if (sp.IsOpen) 
          {
           sp.Close();
           print("Closing port, because it was already open!");
          }
          else 
          {
           sp.Open();  // opens the connection
           sp.ReadTimeout = 16;  // sets the timeout value before reporting error
           print("Port Opened!");
         //        message = "Port Opened!";
          }
        }
        else 
        {
          if (sp.IsOpen)
          {
           print("Port is already open");
          }
          else 
          {
           print("Port == null");
          }
        }
     }
 
     void OnApplicationQuit() 
     {
        sp.Close();
     }
 
     public static void sendYellow(){
         sp.Write("y");
     }
 
     public static void sendGreen(){
         sp.Write("g");
         //sp.Write("\n");
     }
     
 
     public static void sendRed(){
         sp.Write("r");
     }
 
 
     public static void sendBlue(){
         sp.Write("b");
     }
 
     public static void sendBlue2(){
         sp.Write("1");
     }
 
     public static void sendPulse1(){
         sp.Write("p");
     }
 
     public static void sendPulse2(){
         sp.Write("q");
     }
 
     void lightMeUp(string message){
         print (message);
         float fl = float.Parse (message) / 100.0f;
         fl = 1.0f - fl;
 
 
             //Do Something
             GetComponent<AudioSource> ().PlayOneShot (voices [Random.Range (0, voices.Length)]);
 
     }
 
 }
 
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Thomas-Mountainborn · Nov 23, 2015 at 08:05 PM

The fact that it's overlapping is undoubtedly because your Arduino is repeatedly sending out the message that the light sensor threshold has been breached. Since Update() is called every frame, and therefore lightMeUp(), and your Arduino sends out its message every frame as well as long as the sensor value is valid, a sound will be triggered every frame, resulting in a cacophonous mess worthy of any middle school music class.

You need a "flag", a boolean field in your MonoBehaviour, that is set to true when a sound is played, and set to false when the sound finishes playing. Then, in lightMeUp(), you only allow a new sound to play if the boolean is set to false.

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image KnightRiderGuy · Nov 23, 2015 at 08:28 PM 0
Share

Thanks $$anonymous$$, I'm not really great at booleans can you help me with how I would do that? I did try altering the data on the Arduino code so that it read something like this:

 void loop()
 { 
   //Light Sensor
     if((lightInt - analogRead(lightPin)) > 50 || (lightInt - analogRead(lightPin)) < -50){
       lightInt = analogRead(lightPin);
       Serial.println(lightInt);
     }

That way I thought perhaps it might not send information as much. Basically I'm looking for a way to have the voice clips activate when it's around dusk or just getting dark out.

avatar image Thomas-Mountainborn KnightRiderGuy · Nov 23, 2015 at 09:15 PM 1
Share

Booleans are real easy.

 //Random Clips
 public AudioClip[] voices;
 ...
 //_isPlayingSound is true when a sound is currently playing - just as the name suggests.
 private bool _isPlayingSound;
 
 ...
 
 void light$$anonymous$$eUp(string message)
 {
     //If there is a sound currently playing, return immediately so we don't play another sound simultaneously.
     //if(_isPlayingSound) is shorthand for if(_isPlayingSound == true), in case you where wondering.
     if (_isPlayingSound)
         return;
 
     print(message);
     float fl = float.Parse(message) / 100.0f;
     fl = 1.0f - fl;
 
 
     //Pick a random sound.
     AudioClip randomClip = voices[UnityEngine.Random.Range(0, voices.Length)];
     //Play that sound.
     GetComponent<AudioSource>().PlayOneShot(randomClip);
     //Flag that we are currently playing a sound.
     _isPlayingSound = true;
     //Start a coroutine that will set the flag to false once the sound stops playing, so we can start playing a new sound.
     StartCoroutine(RunResetIsPlayingSoundFlag(randomClip.length));
 }
 
 private IEnumerator RunResetIsPlayingSoundFlag(float soundDuration)
 {
     //Wait until the sound finishes playing.
     yield return new WaitForSeconds(soundDuration);
     //Disable the _isPlayingSound flag, so we can play a new sound since this one is over.
     _isPlayingSound = false;
 }
avatar image KnightRiderGuy Thomas-Mountainborn · Nov 23, 2015 at 09:30 PM 0
Share

Ah ok, thanks $$anonymous$$, That fixed the overlapping and repeating audio issue but I'm not sure how to make it so that it only plays when the light level is either near dark or near light?

Show more comments
avatar image KnightRiderGuy · Nov 23, 2015 at 09:01 PM 0
Share

I also tried doing something like this but I did not get the results I was looking for: void light$$anonymous$$eUp(string message){ print (message); float fl = float.Parse (message) / 100.0f; fl = 1.0f - fl;

         //worldLight.GetComponent<Light>().intensity = fl;
         //Do Something
         GetComponent<AudioSource> ().PlayOneShot (voices [Random.Range (0, voices.Length)]);
         if (GetComponent<AudioSource> ().isPlaying) {
             GetComponent<AudioSource> ().Stop ();
         } else {
             GetComponent<AudioSource> ().Play ();
         }
     }    
avatar image
0

Answer by KnightRiderGuy · Nov 23, 2015 at 09:54 PM

lol ok I changed my arduino code to this and now the audio repeat over and over again randomly, ??

 int lightPin = 0; //Define Pin For Photoresistor
 //int lightInt = 0;
 int lightLevel = analogRead(0);
 int threshold = 250;
 int range = 1000;
 
 const byte rLed = 12; //Sets Pin number LED is conneted too
 const byte yLed = 11;
 const byte gLed = 10;
 const byte bLed = 9;
 const byte bLed2 = 8;
 char myChar;         //changed the name of this variable because they are not all colurs now
 const byte pulsePins[] = {13, 7};  //pins for a pulse output
 char pulseTriggers[] = {'p', 'q'};
 const int NUMBER_OF_PULSE_PINS = sizeof(pulsePins);
 unsigned long pulseStarts[NUMBER_OF_PULSE_PINS];
 unsigned long pulseLength = 500;
 
 void setup()
 {
   //Serial.begin (9600);
   Serial.begin (115200);
   Serial.setTimeout(13); //Added today Sun Nov 22
   pinMode(rLed, OUTPUT);
   pinMode(yLed, OUTPUT);
   pinMode(gLed, OUTPUT);
   pinMode(bLed, OUTPUT);
   pinMode(bLed2, OUTPUT);
   digitalWrite(rLed, LOW);
   digitalWrite(yLed, LOW);
   digitalWrite(gLed, LOW);
   digitalWrite(bLed, LOW);
   digitalWrite(bLed2, LOW);
   for (int p = 0; p < NUMBER_OF_PULSE_PINS; p++)
   {
     pinMode(pulsePins[p], OUTPUT);
     digitalWrite(pulsePins[p], LOW);
   }
 }
 
 void loop()
 { 
   //Light Sensor
     /*if((lightInt - analogRead(lightPin)) > 50 || (lightInt - analogRead(lightPin)) < -50){
       lightInt = analogRead(lightPin);
       Serial.println(lightInt);
     }*/
 
     if(lightLevel > threshold - range && lightLevel < threshold + range)
     Serial.println(lightLevel);
     
   if (Serial.available())              //if serial data is available
   {
     
     int lf = 10;
 
     myChar = Serial.read();             //read one character from serial
     if (myChar == 'r')                  //if it is an r
     {
       digitalWrite(rLed, !digitalRead(rLed));  //change the state of the r LED
     }
     if (myChar == 'b')
     {
       digitalWrite(bLed, !digitalRead(bLed));
     }
 
     if (myChar == 'y')
     {
       digitalWrite(yLed, !digitalRead(yLed));
     }
 
     if (myChar == 'g')
     {
       digitalWrite(gLed, !digitalRead(gLed));
     }
 
     if (myChar == '1')
     {
       digitalWrite(bLed2, !digitalRead(bLed2));
     }
 
     for (int p = 0; p < NUMBER_OF_PULSE_PINS; p++)
     {
       if (myChar == pulseTriggers[p])
       {
         pulseStarts[p] = millis();  //save the time of receipt
         digitalWrite(pulsePins[p], HIGH);
       }
     }
   }
 
   //the following code runs each time through loop()
   for (int p = 0; p < NUMBER_OF_PULSE_PINS; p++)
   {
     if (millis() - pulseStarts[p] >= pulseLength)  //has the pin been HIGH long enough ?
     {
       digitalWrite(pulsePins[p], LOW);   //take the pulse pin LOW
     }
   }
 }
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Thomas-Mountainborn · Nov 23, 2015 at 09:57 PM 0
Share

Well yeah, you set the "range" variable to 1000. The analogRead() value can only be between 0 and 1023. " if(lightLevel > threshold - range && lightLevel < threshold + range)" will therefore always be true.

$$anonymous$$ake the range value smaller - somewhere around 50, maybe. Also, you need to analogRead() in loop(), or else you will only read the value once on startup, and never again afterwards.

avatar image KnightRiderGuy Thomas-Mountainborn · Nov 23, 2015 at 10:13 PM 0
Share

Sorry for my stupidity but not really sure I follow.? I think I am also missing something on the unity side as I have the same code in that read as a string?

avatar image Thomas-Mountainborn KnightRiderGuy · Nov 24, 2015 at 05:48 AM 0
Share
 int lightPin = 0; //Define Pin For Photoresistor
 
 int threshold = 250;
 //The range value should not be very high, because analogRead() can only return values between 0 and 1023. It is necessary because if you were to use a single value (i.e. lightLevel == threshold), it would be impossible that you stay on that value for a sustained period of time. Using the "range" variable, you check if the lightLevel is between 200 and 300, for instance.
 int range = 50; 
 
 
 ...
 
 
 void loop()
 {
     //Read the current light level.
     int lightLevel = analogRead(lightPin);
     //If the light level is within our desired range, send it to Unity.
     if (lightLevel > threshold - range && lightLevel < threshold + range)
         Serial.println(lightLevel);
 
     ....
 }
 
 ...
Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

38 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Populate an array of GameObjects with collision? 1 Answer

Triggering candle lights on with Colliders 1 Answer

Triggering a specific sound in an Array - syntax help likely... 1 Answer

Make an array/list of objects in enemy sight trigger 1 Answer

How to add colliders to an array, and pick the oldest one? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges