Using one button for many things

Hello. I am controlling an arduino via serial port to turn on/off various sensors. I want to have a “manual mode” that simply turns on the sensor (and keeps it on while the button is depressed). One button connected to Digital Pin 11 controls any sensor depending on the selection in the GUI which is then specified via serial with the command for manual mode.

I can turn on manual mode, but if I try to incorporate a way to kill manual mode via a serial command, it will stop manual mode but will not regain serial control. It seems like simple code to me, but it just doesn’t work.

I have attached the sketch. Ignore Case 4 for now. That is my ultimate objective (to have it count the seconds the sensor is on) but case 5 is the basis for it and is not yet working.

  case 5: // Enter manual mode and turn on sensor while button is depressed
    {
      pMode = true;
      getSerial();
      pinNumber = serialdata;
      Serial.begin(9600);                 //clear serial to see if buffer is interfering with future commands
      pinMode(pinNumber, OUTPUT);
      while (pMode == true){
        Serial.println("1");              //this prints repeatedly so everything is working so far
        if (digitalRead(buttonPin) == HIGH){
          digitalWrite(pinNumber, HIGH);
          //buttonPressed = true;
        }
        //wait until button is released, then set sensor to LOW
        //while (digitalRead(buttonPin) == HIGH){}
        // digitalWrite(pinNumber, LOW);            // if I use this loop instead of the next three lines, button works but inconsistently. Arduino quirk?
        if (digitalRead(buttonPin) == LOW){
          digitalWrite(pinNumber, LOW);
        }
        serialdata = Serial.read() - '0';
        if (serialdata == 5){
          Serial.println(serialdata);          //does not print anything but somehow sending 5 to the arduino breaks the loop (pMode false)
          pMode = false;
        }
      }
    serialdata = 0;
    pinNumber = 0;
    break;
    }

SerialCode.ino.ino (5.91 KB)

You need to post a complete program - not just a snippet.

From what I can see of the snippet the code is a complete bird’s nest or bowl of spaghetti.

Have a look at Planning and Implementing a Program

…R

  case 5: // Enter manual mode and turn on sensor while button is depressed
    {
      pMode = true;
      getSerial();
      pinNumber = serialdata;
      Serial.begin(9600);                 //clear serial to see if buffer is interfering with future commands
      pinMode(pinNumber, OUTPUT);

What last comment is horsepoop. That is NOT what that function does. How do you expect to read serial data in other places if you don't start Serial until you get to here?

What does getSerial() do if you enter "Hi, there"? Certainly NOT what you want. What happens if the line ending is not nothing?

Why does the function return a global variable?

        serialdata = Serial.read() - '0';

When there is no serial data to read, you look rather stupid trying to read it.

          Serial.println(Serial.read());          //does not print anything but somehow sending 5 to the arduino breaks the loop (pMode false)
          pMode = false;

If, by some miracle, there was a '5' to read, read and print another character that is likely to not exist, and then, regardless of whether there was anything to read, or what it was, set pMode to false.

Robin2 was being kind in describing your code.

I did post the file with the full code and the snippet only to focus the discussion. Serial was already initialized, I put that serial.begin later on to reset the serial to see if it was being affected by data in the buffer or something. Please look at the file with the full code. Thank you.

CyborgDroid: I did post the file with the full code and the snippet only to focus the discussion. Serial was already initialized, I put that serial.begin later on to reset the serial to see if it was being affected by data in the buffer or something. Please look at the file with the full code. Thank you.

Please post the entire sketch inside code tags, in accordance with the forum protocol as described in the sticky posts: How to use this forum - please read. and Read this before posting a programming question ... It is not large enough to justify being an attachment.

I had not noticed the attachment. I agree completely with Reply #4 but I am feeling generous (rare!) so here is the code.

/*

1 = Write:
      1 = digital:
          "pin number" Avoid 0 & 1
              "1 for LOW"
              "2 for HIGH"
                  #deciseconds to turn sensor on for
      2 = analog:
          "pin number"
              "frequency (0-255)"
                  #deciseconds to turn sensor on for
2 = Read:
    1 = digital:
        "pin number"
    2 = analog:
        "pin number"

3 = Ping: respond with "Arduino"

4 = Calibrate sensor manually, respond with timing.
    "digital pin"

5 = Simple sensor manual control
    "digital pin"

Examples: 
1/1/2/2/20/     Write, Digital, Pin#2, HIGH, 2 seconds
                Plain English: turn digital pin 2 ON for 2 seconds. 
1/2/2/200/      Write, Analog, Pin#2, at 150 (0-255)
                English: turn analog pin 2 ON at medium power
3/              Ping

5/2/            Manual mode, button controls Digital Pin 2
5               stop manual mode

*/

const int buttonPin = 11; 

boolean buttonPressed;
boolean cMode;
boolean pMode;
unsigned long stopMillis;
unsigned long startCalibration;
unsigned long calibrationTime;
unsigned long serialdata;
int inbyte;
int digitalState;
int pinNumber;
int analogRate;
int sensorVal;


void setup()
{
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
}

void loop()
{
  
  getSerial();
  switch(serialdata)
  {
  
  case 1: //WRITE
    {
      getSerial();
      switch (serialdata)
      {
      case 1:
        {
          //analog write
          getSerial();
          pinNumber = serialdata;
          getSerial();
          analogRate = serialdata;
          pinMode(pinNumber, OUTPUT);
          analogWrite(pinNumber, analogRate);
          if(analogRate > 0){
            getSerial();
            if (serialdata > 0){
              delay(serialdata*100);
              digitalWrite(pinNumber,LOW);
            }
          }
          pinNumber = 0;
          analogRate = 0;
          break;
        }
      case 2:
        {
          //digital write
          getSerial();
          pinNumber = serialdata;
          getSerial();
          digitalState = serialdata;
          pinMode(pinNumber, OUTPUT);
          if (digitalState == 1){digitalWrite(pinNumber, LOW);}
          if (digitalState == 2)
          {
            digitalWrite(pinNumber, HIGH);
            getSerial();
            if (serialdata > 0){
              delay(serialdata*100);
              digitalWrite(pinNumber,LOW);
            }
          }
          pinNumber = 0;
          digitalState = 0;
          break;
         
        }
     }
     break; 
    }
    case 2: // READ
    {
      getSerial();
      switch (serialdata)
      {
      case 1:
        {
          //analog read
          getSerial();
          pinNumber = serialdata;
          pinMode(pinNumber, INPUT);
          sensorVal = analogRead(pinNumber);
          //Serial.println(sensorVal);
          sensorVal = 0;
          pinNumber = 0;
          break;
        } 
      case 2:
        {
          //digital read
          getSerial();
          pinNumber = serialdata;
          pinMode(pinNumber, INPUT);
          sensorVal = digitalRead(pinNumber);
          //Serial.println(sensorVal);
          sensorVal = 0;
          pinNumber = 0;
          break;
        }
      }
      break;
    }
  case 3: // Respond to ping for Auto-connect
    {
      Serial.println("A");
      break;
    }
  case 4: // enter manual mode and record time button is depressed while in manual mode.
    {
      cMode = true;
      getSerial();
      pinNumber = serialdata;
      pinMode(pinNumber, OUTPUT);
      calibrationTime = 0;
      Serial.println("C1");
      while (cMode == true) { 
        Serial.println("c");
        startCalibration = 0;
        //Check if button is depressed and turn sensor on
        if (digitalRead(buttonPin) == HIGH){
          digitalWrite(pinNumber, HIGH);
          startCalibration = millis();
          Serial.println("S");
          //Wait until button is released
          while (digitalRead(buttonPin) == HIGH) {}
        }
        //Turn off sensor if button was pressed and released
        if (startCalibration > 0){
          digitalWrite(pinNumber, LOW);
          calibrationTime = calibrationTime + startCalibration - millis();
          //send current calibration time
          Serial.println("P");
          Serial.println(calibrationTime);
        }
        //Check to see if calibration mode is turned off
        getSerial();
        if (serialdata == 4){
          Serial.println("E");
          getSerial();
          cMode = false;
        }
      }
      pinNumber = 0;
      break;
    }
  case 5: // Enter manual mode and turn on sensor while button is depressed
    {
      pMode = true;
      getSerial();
      pinNumber = serialdata;
      Serial.begin(9600);                 //clear serial to see if buffer is interfering with future commands
      pinMode(pinNumber, OUTPUT);
      while (pMode == true){
        Serial.println("1");              //this prints repeatedly so everything is working so far
        if (digitalRead(buttonPin) == HIGH){
          digitalWrite(pinNumber, HIGH);
          //buttonPressed = true;
        }
        //wait until button is released
        //while (digitalRead(buttonPin) == HIGH){}
        // digitalWrite(pinNumber, LOW);            // if I use this loop instead of the next three lines, button works but inconsistently.
        if (digitalRead(buttonPin) == LOW){
          digitalWrite(pinNumber, LOW);
        }
        serialdata = Serial.read() - '0';
        if (serialdata == 5){
          Serial.println(Serial.read());          //does not print anything but somehow sending 5 to the arduino breaks the loop (pMode false)
          pMode = false;
        }
      }
    serialdata = 0;
    pinNumber = 0;
    break;
    }
  }
}

long getSerial()
{
  serialdata = 0;
  while (inbyte != '/')
  {
    inbyte = Serial.read(); 
    if (inbyte > 0 && inbyte != '/')
    {
     
      serialdata = serialdata * 10 + inbyte - '0';
    }

  }
  inbyte = 0;
  return serialdata;
}

It is still a dog's breakfast. Study the link I gave in Reply #1.

...R