Add A Start Off State for Switch Case Scenario
I have some switch cases set up from reading that are sent through the Serial port from the Arduino into Unity. A Button Pressed state and Un pressed state. These states are then read by unity in order to trigger some animation on another canvas panel. What happens is that although the initial button functions are working just fine (See Video Demo) Because it starts off at a "case 0" for button up or un pressed my animation sounder gets activated. like this:
void DirectionArrow(int buttonStatus)
//void DirectionArrow(int Direction)
{
switch (buttonStatus)
{
//OFF Buttons States
case 0:
//deactivate Left Direction Arrow
SystemGuidanceManagerScript WAO = FindObjectOfType<SystemGuidanceManagerScript>();
WAO.WestArrowOff ();
SystemGuidanceManagerScript EAO = FindObjectOfType<SystemGuidanceManagerScript>();
EAO.EastArrowOff();
SystemGuidanceManagerScript SFXOff = FindObjectOfType<SystemGuidanceManagerScript>();
SFXOff.TopIndicatorOff();
SystemGuidanceManagerScript BGSOff = FindObjectOfType<SystemGuidanceManagerScript>();
BGSOff.BarLEDsSounderOff();
break;
//LEFT BUTTON ON STATE
case 4:
//Activate Left Direction Arrow Indicator
SystemGuidanceManagerScript WA = FindObjectOfType<SystemGuidanceManagerScript>();
WA.WestArrow();
SystemGuidanceManagerScript WBSOn = FindObjectOfType<SystemGuidanceManagerScript>();
WBSOn.BarLEDsSounderOn();
break;
//RIGHT BUTTON ON STATE
case 5:
//Activate Right Direction Arrow Indicator
SystemGuidanceManagerScript EA = FindObjectOfType<SystemGuidanceManagerScript>();
EA.EastArrow();
SystemGuidanceManagerScript EBSOn = FindObjectOfType<SystemGuidanceManagerScript>();
EBSOn.BarLEDsSounderOn();
break;
}
}
I was wondering if there is a way to add some sort of "Start Off" case where nothing happens until the buttons are pressed.?
what do you mean by "where nothing happens"?
you could add a default
state to handle some case not explicitly handled by 0-5... for clarity, you might consider assigning some names to those too - use an enum
and pass that as the button state or cast it to the enum
you can get rid of a lot of that code too - the object you're getting with every FindObjectOfType
appears to be the same every time, so just get the reference before your switch
statement...
edit: btw - looks like an interesting project ;)
@gif, Thanks man, I'm all for cleaning up unnecessary confusing code, can you direct me more with what needs to stay and what can go?
P.S. I posted more information down below with updated codes.
Answer by NoseKills · Dec 28, 2015 at 11:46 AM
I'm not sure if I understand your problem right but in general I'd say that a switch case works as it works and there's no changing it:
You have your individual "cases" and the "default" that happens when no other case happens. But you can change what values you feed into it and change behavior that way.
If I understood correctly, the device outputs "0" all the time if no buttons are pressed and you'd like your code to only perform the "case 0:" when the button is released after pressing ? In that case you need to use other variables to control what goes into the switch-case
private int lastbuttonStatus = 0;
void DirectionArrow(int buttonStatus)
{
if (buttonStatus != lastbuttonStatus) {
lastbuttonStatus = buttonStatus;
switch (buttonStatus)
{
//OFF Buttons States
case 0:
//deactivate Left Direction Arrow
break;
//LEFT BUTTON ON STATE
case 4:
//Activate Left Direction Arrow Indicator
break;
//RIGHT BUTTON ON STATE
case 5:
//Activate Right Direction Arrow Indicator
break;
}
}
}
Thanks @Nose$$anonymous$$ills, I posted some more information in an answer below, I changed the Arduino code so that the "0" is not being sent constantly, it's fixed part of the problem. I put a video link near the bottom too to demo what I mean better.
Answer by KnightRiderGuy · Dec 28, 2015 at 01:01 PM
@gif thanks. I should point out that code is not really my strong suit but I kinda have no choice on this project ;) Glad you like the project, if I can ever get it done it should make a nice compliment to the knight Rider dash I have.... takes me all day to figure out nit picky stuff that some one who is way more code savvy would whip through in a matter of minutes... It's the biggest frustrating part about this project is the code stuff. ;)
I was on the Arduino forums and managed to change my Arduino code to this:
int lightSensorPin = A0; //Define the Light Sensor Pin
int lightSensorValue = 0;
//int lightLevel = analogRead(0);
//int threshold = 250;
//int range = 50;
//Defines Our Button Pins
const int buttonRight = A1;
const int buttonLeft = A2;
// Variable to hold the state of the buttons
int bRS, bLS; //ButtonRight and ButtonLeft states status holders
//Sets Pin number LED is conneted too
const byte rLed = 12;
const byte rLed2 = 1;
const byte yLed = 11;
const byte gLed = 10;
const byte gLed2 = 5;
const byte gLed3 = 4;
const byte wLed = 3;
const byte bLed = 2;
const byte bLed2 = 13;
char myChar; //changed the name of this variable because they are not all colurs now
const byte pulsePins[] = {6, 7, 8, 9}; //pins for a pulse output
char pulseTriggers[] = {'p', 'q','R','L'};
const int NUMBER_OF_PULSE_PINS = sizeof(pulsePins);
unsigned long pulseStarts[NUMBER_OF_PULSE_PINS];
unsigned long pulseLength = 500;
int buttonStateR = 0; //Current State of the R button
int lastButtonStateR = 0; //Previous State of the R button
int buttonStateL = 0; //Current State of the L button
int lastButtonStateL = 0; //Previous State of the L button
int buttonPushCounter = 0; //Counter for number of button presses
void setup()
{
//Serial.begin (9600);
Serial.begin (115200);
Serial.setTimeout(13); //Added today Sun Nov 22 ( not sure if this is needed? )
pinMode(buttonRight, INPUT); //Defines Pin Mode
pinMode(buttonLeft, INPUT);
digitalWrite(buttonRight, HIGH);
digitalWrite(buttonLeft, HIGH);
pinMode(wLed, OUTPUT);
pinMode(rLed, OUTPUT);
pinMode(rLed2, OUTPUT);
pinMode(yLed, OUTPUT);
pinMode(gLed, OUTPUT);
pinMode(gLed2, OUTPUT);
pinMode(gLed3, OUTPUT);
pinMode(bLed, OUTPUT);
pinMode(bLed2, OUTPUT);
digitalWrite(wLed, LOW);
digitalWrite(rLed, LOW);
digitalWrite(rLed2, LOW);
digitalWrite(yLed, LOW);
digitalWrite(gLed, LOW);
digitalWrite(gLed2, LOW);
digitalWrite(gLed3, 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()
{
// read the new light value (in range 0..1023):
int sensorValue = analogRead(lightSensorPin);
// if the value changed by 10
if(lightSensorValue - sensorValue > 10 || sensorValue - lightSensorValue > 10){
lightSensorValue = sensorValue; // save the new value
float p = lightSensorValue * (100.0 / 1023.0); // make the value to range 0..100
// the Parentheses may be for compiler optimization idk
Serial.println(p); // send it to unity
}
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)); //Oil Slick Toggle
}
if (myChar == 'b')
{
digitalWrite(bLed, !digitalRead(bLed)); //Surveillance Mode Toggle
}
if (myChar == 'y')
{
digitalWrite(yLed, !digitalRead(yLed)); //Movie Player Toggle
}
if (myChar == 'g')
{
digitalWrite(gLed, !digitalRead(gLed)); //Auto Phone Toggle
}
if (myChar == 's')
{
digitalWrite(bLed2, !digitalRead(bLed2)); //Scanner Toggle
}
if (myChar == 'f')
{
digitalWrite(gLed2, !digitalRead(gLed2)); //Fog Lights Toggle
}
if (myChar == 'h')
{
digitalWrite(gLed3, !digitalRead(gLed3)); //Head Lights Toggle
}
if (myChar == 'H')
{
digitalWrite(wLed, !digitalRead(wLed)); //High Beams Toggle
}
//Rear Hatch Popper
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);
}
}
//Grappling Hook Launch
for (int q = 0; q < NUMBER_OF_PULSE_PINS; q++)
{
if (myChar == pulseTriggers[q])
{
pulseStarts[q] = millis(); //save the time of receipt
digitalWrite(pulsePins[q], HIGH);
}
}
//Auto Doors Right Pulse
for (int R = 0; R < NUMBER_OF_PULSE_PINS; R++)
{
if (myChar == pulseTriggers[R])
{
pulseStarts[R] = millis(); //save the time of receipt
digitalWrite(pulsePins[R], HIGH);
}
}
//Auto Doors Left Pulse
for (int L = 0; L < NUMBER_OF_PULSE_PINS; L++)
{
if (myChar == pulseTriggers[L])
{
pulseStarts[L] = millis(); //save the time of receipt
digitalWrite(pulsePins[L], 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
}
}
for (int q = 0; q < NUMBER_OF_PULSE_PINS; q++)
{
if (millis() - pulseStarts[q] >= pulseLength) //has the pin been HIGH long enough ?
{
digitalWrite(pulsePins[q], LOW); //take the pulse pin LOW
}
}
// read the pushbutton input pin
buttonStateR = digitalRead(buttonRight);
//compare the buttonState to its previous state
if (buttonStateR != lastButtonStateR){
// if the state has changed, increment the counter
if (buttonStateR == LOW){
// if the current state is HIGH then the button went from off to on
buttonPushCounter++;
Serial.println(1);
//Serial.print("number of button pushes: ");
//Serial.println(buttonPushCounter);
}else{
// if the current state is LOW then the button went from on to off
Serial.println(0);
}
// Delay little bit to avoid bouncing
delay(20);
}
// save the current state as the last state for the next time through loop
lastButtonStateR = buttonStateR;
// read the pushbutton input pin
buttonStateL = digitalRead(buttonLeft);
//compare the buttonState to its previous state
if (buttonStateL != lastButtonStateL){
// if the state has changed, increment the counter
if (buttonStateL == LOW){
// if the current state is HIGH then the button went from off to on
buttonPushCounter++;
Serial.println(2);
//Serial.print("number of button pushes: ");
//Serial.println(buttonPushCounter);
}else{
// if the current state is LOW then the button went from on to off
Serial.println(0);
}
// Delay little bit to avoid bouncing
delay(20);
}
// save the current state as the last state for the next time through loop
lastButtonStateL = buttonStateL;
}
UNITY Code: I changed my unity code to this:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.IO.Ports;
using System.Threading;
public class Sending : MonoBehaviour {
//int sysHour = System.DateTime.Now.Hour;
//Random Clips
public AudioClip[] BrightnessAudioClips;
public AudioClip[] DarknessAudioClips;
public AudioClip[] AnnoyedAudioClips;
//DTMF Tones
public AudioClip DTMFtone01;
public AudioClip DTMFtone02;
public AudioClip DTMFtone06;
public AudioClip DTMFtone08;
public AudioSource source;
//UI Text Reference
//public Text MessageCentreText;
//_isPlayingSound is true when a sound is currently playing - just as the name suggests.
private bool _isPlayingSound;
const float sliderChangeVelocity = 0.5f;
private float desiredSliderValue;
public GameObject LightSlider;
public Slider slider;
Slider lightSlider;
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, Parity.None, 8, StopBits.One); //115200
public string message2;
//Button States
bool button01State = false;
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 () {
StartCoroutine(OpenConnection());
lightSlider = GetComponent<Slider> ();
if(slider == null) slider = GetComponent<Slider>(); // search slider in this object if its not set in unity inspector
if(source == null) source = GetComponent<AudioSource>(); // search audiosource in this object if its not set in unity inspector
}
// Update is called once per frame
void Update () {
/*string dataFromArduinoString = sp.ReadLine ();
int dFAI = int.Parse (dataFromArduinoString);
print (dFAI);
DirectionArrow (dFAI);*/
try
{
//DirectionArrow(sp.ReadByte());
//print(sp.ReadByte());
string dataFromArduinoString = sp.ReadLine ();
int dFAI = int.Parse (dataFromArduinoString);
print (dFAI);
DirectionArrow (dFAI);
}
catch (System.Exception) {
}
//print("BytesToRead" +sp.BytesToRead);
message2 = sp.ReadLine();
string message = sp.ReadLine(); //get the message...
if(message == "") return; //if its empty stop right here
// parse the input to a float and normalize it (range 0..1) (we could do this already in the Arduino)
float input = 1 - float.Parse (message) / 100f;
// set the slider to the value
float oldValue = slider.value; // -------- this is new
slider.value = input;
// after the slider is updated, we can check for the other things for example play sounds:
if (source.isPlaying) return; // if we are playing a sound stop here
// else check if we need to play a sound and do it
if (slider.value > 0.9f && oldValue <= 0.9f) // ---------this has changed
source.PlayOneShot (BrightnessAudioClips [Random.Range (0, BrightnessAudioClips.Length)]);
else if (slider.value < 0.15f && oldValue >= 0.15f) //----------this has changed
source.PlayOneShot (DarknessAudioClips [Random.Range (0, DarknessAudioClips.Length)]);
}
//public void OpenConnection() {
IEnumerator OpenConnection(){
yield return new WaitForSeconds(1.9f); // wait time
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();
}
//Movie Player Toggle
public static void sendYellow(){
sp.Write("y");
}
//Analyzer Toggle
public static void sendYellow2(){
sp.Write("A");
}
//Pod 7DLA Toggle
public static void sendYellow3(){
sp.Write("D");
}
//Pod PENG Toggle
public static void sendYellow4(){
sp.Write("P");
}
//Pod 6RM Toggle
public static void sendYellow5(){
sp.Write("6");
}
//Pod Laser Toggle
public static void sendYellow6(){
sp.Write("Z");
}
//Auto Phone Toggle
public static void sendGreen(){
sp.Write("g");
//sp.Write("\n");
}
//Oil Slick Toggle
public static void sendRed(){
sp.Write("r");
}
//Surveillance Mode Toggle
public static void sendBlue(){
sp.Write("b");
}
//Scanner Toggle
public static void sendRed2(){
sp.Write("s");
}
//Fog Lights Toggle
public static void sendGreen2(){
sp.Write("f");
}
//Head Lights Toggle
public static void sendGreen3(){
sp.Write("h");
}
//Hight Beams Toggle
public static void sendWhite(){
sp.Write("H");
}
//Rear Hatch Popper
public static void sendPulse1(){
sp.Write("p");
}
//Grappling Hook Launch
public static void sendPulse2(){
sp.Write("q");
}
//Auto Doors Right Pulse
public static void sendPulse3(){
sp.Write("R");
}
//Auto Doors Left Pulse
public static void sendPulse4(){
sp.Write("L");
}
//Startup and Shutdown Pulse
public static void sendPulse5(){
sp.Write("S");
}
//System Guidance Close Button
public void GoDTMFtone02(){
StartCoroutine(LoadT4());
GetComponent<AudioSource>().PlayOneShot(DTMFtone02);
}
IEnumerator LoadT4(){
yield return new WaitForSeconds(0.0f); // wait time
CameraSwitcher cs1 = FindObjectOfType<CameraSwitcher>();
cs1.EnableCamera1();
}
void DirectionArrow(int buttonStatus)
//void DirectionArrow(int Direction)
{
switch (buttonStatus)
{
//OFF Buttons States
case 0:
//deactivate Left Direction Arrow
SystemGuidanceManagerScript WAOff = FindObjectOfType<SystemGuidanceManagerScript>();
WAOff.WestArrowOff ();
SystemGuidanceManagerScript EAOff = FindObjectOfType<SystemGuidanceManagerScript>();
EAOff.EastArrowOff();
SystemGuidanceManagerScript SFXOff = FindObjectOfType<SystemGuidanceManagerScript>();
SFXOff.TopIndicatorOff();
SystemGuidanceManagerScript BGSOff = FindObjectOfType<SystemGuidanceManagerScript>();
BGSOff.BarLEDsSounderOff();
break;
//LEFT BUTTON ON STATE
case 1:
//Activate Left Direction Arrow Indicator
SystemGuidanceManagerScript WAOn = FindObjectOfType<SystemGuidanceManagerScript>();
WAOn.WestArrow();
SystemGuidanceManagerScript WBSOn = FindObjectOfType<SystemGuidanceManagerScript>();
WBSOn.BarLEDsSounderOn();
break;
//RIGHT BUTTON ON STATE
case 2:
//Activate Right Direction Arrow Indicator
SystemGuidanceManagerScript EAOn = FindObjectOfType<SystemGuidanceManagerScript> ();
EAOn.EastArrow ();
SystemGuidanceManagerScript EBSOn = FindObjectOfType<SystemGuidanceManagerScript>();
EBSOn.BarLEDsSounderOn();
break;
}
}
}
I think part of the problem now might be That because the Buttons read into Unity as 0, 1 & 2 that perhaps these values conflict with values of the LDR sensor. Someone on the Arduino forums suggested that I should try and call the button inputs or LDR reading inputs before each other in the Update.
Here is a vide link of how it's working with these updated codes. As you will see the LDR seems to work fine for the most part although right away on sat up the light sensor slider will often shoot right up to it's brightest level and the buttons for the turn signal indicators will often "Miss fire" for lack of a better word.
Video Link Demo Video Link
Your answer
Follow this Question
Related Questions
How Do I Activate The Switch Statement 1 Answer
Get Temperature Value and Prompt an Action 0 Answers
Convert an Int to a String 0 Answers
App - device connection in Android 0 Answers
Need Help With Arduino Code to Unity 0 Answers