Add a physical button - I just can't do it!

Hi, I have been altering a code I found online which controls a servo motor from a program on the computer, via the cmd´s in the code.

I how ever wan't to add a physical button (on pin 10, without resistor (Internal.Pullup)) but it seems that either way I do it, it just don't recognize the button push or run the servo.write properly - I bet some of you guys can tell me quite quick what my errors are. (possible wrong { } in the code at the wrong place.

/

/*
  Name:       DarkLight_90
  Author:     Nathan Woelfle

  Version: 1.0.0
  
  Description: DarkLight is a full ASCOM supported and compliant
              device for use with ICoverCalibrator driver.
*/

#include <Servo.h>
#include <EEPROMWearLevel.h>

#define EEPROM_LAYOUT_VERSION 1 //EEPROMWearLevel Version
#define AMOUNT_OF_INDEXES 4 //EEPROMWearLevel number of variables to store
#define EEPROM_LENGTH_TOUSE 1023 //EEPROMWearLevel Max EEPROM address usage
#define SAVED_COVER_STATE 0 //EEPROMWearLevel Index
#define SAVED_PANEL_VALUE 1 //EEPROMWearLevel Index
#define SAVED_BROADBAND_VALUE 2 //EEPROMWearLevel Index
#define SAVED_NARROWBAND_VALUE 3 //EEPROMWearLevel Index

Servo myservo; //create servo object to control servo

const byte lightPanel = 3; //assign to pin
const byte motor = 9; //assign to pin
const byte button =10; //assign button to pin
int buttonValue = 0;

//----- USER-DEFINED VARIABLES -----
long serialSpeed = 9600; //values are (default 9600) 19200 38400 57600 115200 230400
boolean lightInstalled = true; //true if using EL Panel
byte maxBrightness = 51; //max brightness level (max:steps between) 17:15, 51:5, 85:3

//adjustable variables
unsigned int openPos = 90; //speed servo opens at
unsigned int closePos = 180; //speed servo closes at
long stabilizeTime; //set delay to give light time to settle
long maxMoveTime = 30000; //30s max time before error reported that panel hasn't completed opening/closing

//flags for receiving commands
boolean closingCover; //if true will monitor closeSensor otherwise will monitor openSensor
byte coverState; //reports # 1:Closed, 2:Moving, 3:Open, 4:Unknown, 5:Error
byte calibratorState = 1; //reports # 0:NotPresent 1:Off, 2:NotReady, 3:Ready, 4:Unknown, 5:Error

//remaining variables
long startTimer; //holds start time
unsigned int stopMotor = 1500; //halt servo
String cmd; //variable to store serial string
boolean autoON; //if true turns panel on after closing
byte previousPanelValue; //holds last ON value
byte broadbandValue; //holds saved EEPROM value
byte narrowbandValue; //holds saved EEPROM value
byte reportingValue; //adjust value sent to user
byte lightValue = 0; //lightValue received and adjusted for Arduino
byte brightnessSteps = 255 / maxBrightness; //set steps size based on maxBrightness


void setup() {
  myservo.attach(motor); //attaches the servo
  myservo.write(closePos); //put motor in stall mode
  pinMode(lightPanel, OUTPUT); //declare lightPanel output
  pinMode (button, INPUT_PULLUP);

  Serial.begin(serialSpeed); //start serial
  Serial.flush();

  EEPROMwl.begin(EEPROM_LAYOUT_VERSION, AMOUNT_OF_INDEXES, EEPROM_LENGTH_TOUSE);
  initializeLocation();
}

void loop(){
  if(Serial.available() > 0){
    cmd = Serial.readStringUntil('#');
    
    //CoverState
    if(cmd == "P"){
      Serial.print(coverState); Serial.print("#");
    }
    
    //OpenCover
    else if(cmd == "O"){
      closingCover = false;
      startTimer = millis();
      if (calibratorState == 3){
        turnPanelOFF();
      }
      myservo.write(openPos);
      coverState = 3; //3:Open
      Serial.print("#");
      saveCoverState();
    }
    
    //CloseCover
    else if(cmd == "C"){
      closingCover = true;
      startTimer = millis();
      myservo.write(closePos);
      coverState = 1; //1:Closed
      Serial.print("#");
      if (autoON == true){
        turnPanelTo();
      }
      saveCoverState();
    }

    // Read the value of the button input. It can either be 1 or 0   
    buttonValue = digitalRead(button);   
    if (buttonValue == LOW);{
      if (coverState = 1);
      closingCover = false;
      startTimer = millis();
      myservo.write(openPos);
      coverState = 0; //1:Closed      
      Serial.print("#");{
    }
      saveCoverState();
    }
    
    //HaltCover
  }    else if(cmd == "H"){
      myservo.writeMicroseconds(stopMotor); Serial.print("#");
    }
    
    //CalibratorState
    else if(cmd == "L"){
      Serial.print(calibratorState); Serial.print("#");
    }
    
    //Brightness
    else if(cmd == "B"){
      reportingValue = lightValue / brightnessSteps;
      Serial.print(reportingValue); Serial.print("#");
    }
    
    //MaxBrightness
    else if (cmd == "M"){
      Serial.print(maxBrightness); Serial.print("#");
    }
    
    //CalibratorOn (turns light on)
    else if (cmd.startsWith("T")){
      cmd.remove(0,1);
      lightValue = cmd.toInt();
      turnPanelTo();
      Serial.print("#");
      startTimer = millis();
    }
    
    //CalibratorOff (turns light off)
    else if (cmd == "F"){
      turnPanelOFF();
      Serial.print("#");
    }

    //autoON(true)
    else if (cmd == "A"){
      autoON = true;
      Serial.print("#");
    }

    //autoON(false)
    else if (cmd == "a"){
      autoON = false;
      Serial.print("#");
    }

    //setStabilizeTime
    else if (cmd.startsWith("S")){
      cmd.remove(0,1);
      stabilizeTime = cmd.toInt();
      Serial.print("#");
    }

    //setBroadband & Narrowband
    else if (cmd.startsWith("D")){
      cmd.remove(0,1);
      if (cmd == "B"){
        broadbandValue = lightValue; //set variable and save
        EEPROMwl.put(SAVED_BROADBAND_VALUE, broadbandValue);
      }
      else{
        narrowbandValue = lightValue; //set variable and save
        EEPROMwl.put(SAVED_NARROWBAND_VALUE, narrowbandValue);
      }
      Serial.print("#");
    }

    //goto Broadband & Narrowband
    else if (cmd.startsWith("G")){
      cmd.remove(0,1);
      calibratorState = 2;
      if (cmd == "B"){
        analogWrite(lightPanel, broadbandValue); //change current panel value to broadband value
        lightValue = broadbandValue;
      }
      else{
        analogWrite(lightPanel, narrowbandValue); //change current panel value to narrowband value
        lightValue = narrowbandValue;
      }
      Serial.print("#");
      startTimer = millis();
      savePanelValue();
    }

    //decrease light value by 1
    else if (cmd == "-"){
      int valueCheck = reportingValue - 1;
      if (valueCheck >= 1){
        calibratorState = 2;
        lightValue = valueCheck * brightnessSteps;
        analogWrite(lightPanel, lightValue);
        startTimer = millis();
        savePanelValue();
      }
      Serial.print("#");
    }

    //increase light value by 1
    else if (cmd == "+"){
      byte valueCheck = reportingValue + 1;
      if (valueCheck <= maxBrightness){
        calibratorState = 2;
        lightValue = valueCheck * brightnessSteps;
        analogWrite(lightPanel, lightValue);
        startTimer = millis();
        savePanelValue();
      }
      Serial.print("#");
       
    
   }
  }//end serial
  
  if (calibratorState == 2){
    if (millis() - startTimer >= stabilizeTime){
      calibratorState = 3;
    }
  }




}//end loop

void initializeLocation(){
  coverState = EEPROMwl.get(SAVED_COVER_STATE, coverState);
  previousPanelValue = EEPROMwl.get(SAVED_PANEL_VALUE, previousPanelValue);
  broadbandValue = EEPROMwl.get(SAVED_BROADBAND_VALUE, broadbandValue);
  narrowbandValue = EEPROMwl.get(SAVED_NARROWBAND_VALUE, narrowbandValue);

  if (coverState <= 0){
    coverState = 1; //1:Closed
  }
  if (previousPanelValue < 0){
    previousPanelValue = 255;
  }
  if (broadbandValue <= 0){
    broadbandValue = 25;
  }
  if (narrowbandValue <= 0){
    narrowbandValue = 255;
  }

  if (lightInstalled == false){
    maxBrightness = 0;
    calibratorState = 0;
  }
}//end initializeLocation

void turnPanelTo(){
  if(lightValue != 0){
    lightValue = lightValue * brightnessSteps;
    analogWrite(lightPanel, lightValue);
  }
  else{
    lightValue = previousPanelValue;
    analogWrite(lightPanel, lightValue);
  }
  savePanelValue();
  calibratorState = 2;
}//end turnPanelON

void saveCoverState(){
  EEPROMwl.put(SAVED_COVER_STATE, coverState);
}//end saveCoverState

void savePanelValue(){
  previousPanelValue = lightValue;
  EEPROMwl.put(SAVED_PANEL_VALUE, previousPanelValue);
}//end savePanelValue

void turnPanelOFF(){
  analogWrite(lightPanel, 0);
  lightValue = 0;
  calibratorState = 1;  //1:Off
}//end turnPanelOFF

Start a separate sketch just to make sure you have the button working.
Follow this guide: Arduino - Button | Arduino Tutorial (arduinogetstarted.com)
Then, when you know the button is working, you can integrate it into your code.

If you try to do both at once and it doesn't work, what is the problem?
Hard to tell. So, do one thing at a time and verify that thing works, then move one. That way when something doesn't work then it's likely the last thing that you changed.

Hello corpzez
You can use the Notepad++ editor to check the correct placement of {} brackets.

Have a nice day and enjoy coding in C++.
Дайте миру шанс!

if (buttonValue == LOW);{

That semicolon should not be there.

if (coverState = 1);

That semicolon should also not be there. Also you have used = when you should have used ==. They are different!

These are the basic errors most people make when they first begin to learn C coding. You are not ready to alter complex code. You need to take tutorials and write some simple code of your own so that you become more familiar with C code and know what errors to avoid.

Problem is the sketch blocks just WAITING for a text command, unable to watch the button as well. Next thing is resort to a pin change interrupt. Last thing is rewrite that sketch to not block.

What @PaulRB said.

If you start scratching your head because you can't find the bug.
It is time to investigate what is

really going on

through adding

serial debug-output

adding the serial debug-output adds a fixed amount of time
trying to modify your code based on guessings can endure infinitely.

To make sure that serial debug-out works at all add a serial.print at the top of function loop and at the bottom of function loop

void loop() {
  dbgi("top of loop loop is looping", 0, 1000);
//.. all your other code
    dbgi("bottom of function loop", 99, 1000);

} // end of loop()

the special kind of debug-out used here prints only once per second to avoid flooding ther serial monitor with always new text

If you see these printings in the serial monitor you

really know

serial output works in principle

if some output does not appear
the code around the serial output is not executed
And this will guide you to what your code is

really doing

instead of going on scratching your head "I don't understand why..."

This special debug-functions offer printing a fixed text a variable-name and the variables value
Which makes it comfortable to add

So here is a code-version with this kind of serial debug-output

#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);

/*
  Name:       DarkLight_90
  Author:     Nathan Woelfle

  Version: 1.0.0

  Description: DarkLight is a full ASCOM supported and compliant
              device for use with ICoverCalibrator driver.
*/

#include <Servo.h>
#include <EEPROMWearLevel.h>

#define EEPROM_LAYOUT_VERSION 1 //EEPROMWearLevel Version
#define AMOUNT_OF_INDEXES 4 //EEPROMWearLevel number of variables to store
#define EEPROM_LENGTH_TOUSE 1023 //EEPROMWearLevel Max EEPROM address usage
#define SAVED_COVER_STATE 0 //EEPROMWearLevel Index
#define SAVED_PANEL_VALUE 1 //EEPROMWearLevel Index
#define SAVED_BROADBAND_VALUE 2 //EEPROMWearLevel Index
#define SAVED_NARROWBAND_VALUE 3 //EEPROMWearLevel Index

Servo myservo; //create servo object to control servo

const byte lightPanel = 3; //assign to pin
const byte motor = 9; //assign to pin
const byte button = 10; //assign button to pin
int buttonValue = 0;

//----- USER-DEFINED VARIABLES -----
long serialSpeed = 9600; //values are (default 9600) 19200 38400 57600 115200 230400
boolean lightInstalled = true; //true if using EL Panel
byte maxBrightness = 51; //max brightness level (max:steps between) 17:15, 51:5, 85:3

//adjustable variables
unsigned int openPos = 90; //speed servo opens at
unsigned int closePos = 180; //speed servo closes at
long stabilizeTime; //set delay to give light time to settle
long maxMoveTime = 30000; //30s max time before error reported that panel hasn't completed opening/closing

//flags for receiving commands
boolean closingCover; //if true will monitor closeSensor otherwise will monitor openSensor
byte coverState; //reports # 1:Closed, 2:Moving, 3:Open, 4:Unknown, 5:Error
byte calibratorState = 1; //reports # 0:NotPresent 1:Off, 2:NotReady, 3:Ready, 4:Unknown, 5:Error

//remaining variables
long startTimer; //holds start time
unsigned int stopMotor = 1500; //halt servo
String cmd; //variable to store serial string
boolean autoON; //if true turns panel on after closing
byte previousPanelValue; //holds last ON value
byte broadbandValue; //holds saved EEPROM value
byte narrowbandValue; //holds saved EEPROM value
byte reportingValue; //adjust value sent to user
byte lightValue = 0; //lightValue received and adjusted for Arduino
byte brightnessSteps = 255 / maxBrightness; //set steps size based on maxBrightness


void setup() {
  myservo.attach(motor); //attaches the servo
  myservo.write(closePos); //put motor in stall mode
  pinMode(lightPanel, OUTPUT); //declare lightPanel output
  pinMode (button, INPUT_PULLUP);

  Serial.begin(serialSpeed); //start serial
  Serial.flush();

  EEPROMwl.begin(EEPROM_LAYOUT_VERSION, AMOUNT_OF_INDEXES, EEPROM_LENGTH_TOUSE);
  initializeLocation();
}

void loop() {
  dbgi("top of loop loop is looping", 0, 1000);

  if (Serial.available() > 0) {
    dbg("if-condition true", Serial.available() );
    cmd = Serial.readStringUntil('#');

    //CoverState
    if (cmd == "P") {
      Serial.print(coverState); Serial.print("#");
    }

    //OpenCover
    else if (cmd == "O") {
      closingCover = false;
      startTimer = millis();
      if (calibratorState == 3) {
        turnPanelOFF();
      }
      myservo.write(openPos);
      coverState = 3; //3:Open
      Serial.print("#");
      saveCoverState();
    }

    //CloseCover
    else if (cmd == "C") {
      closingCover = true;
      startTimer = millis();
      myservo.write(closePos);
      coverState = 1; //1:Closed
      Serial.print("#");
      if (autoON == true) {
        turnPanelTo();
      }
      saveCoverState();
    }

    // Read the value of the button input. It can either be 1 or 0
    dbg("next reading the button", 0);
    buttonValue = digitalRead(button);
    dbg("button read", buttonValue);
    if (buttonValue == LOW) {
      if (coverState = 1) {
        closingCover = false;
        startTimer = millis();
        myservo.write(openPos);
        coverState = 0; //1:Closed
        Serial.print("#");
      }
      saveCoverState();
    }

    //HaltCover
    else if (cmd == "H") {
      myservo.writeMicroseconds(stopMotor); Serial.print("#");
    }

    //CalibratorState
    else if (cmd == "L") {
      Serial.print(calibratorState); Serial.print("#");
    }

    //Brightness
    else if (cmd == "B") {
      reportingValue = lightValue / brightnessSteps;
      Serial.print(reportingValue); Serial.print("#");
    }

    //MaxBrightness
    else if (cmd == "M") {
      Serial.print(maxBrightness); Serial.print("#");
    }

    //CalibratorOn (turns light on)
    else if (cmd.startsWith("T")) {
      cmd.remove(0, 1);
      lightValue = cmd.toInt();
      turnPanelTo();
      Serial.print("#");
      startTimer = millis();
    }

    //CalibratorOff (turns light off)
    else if (cmd == "F") {
      turnPanelOFF();
      Serial.print("#");
    }

    //autoON(true)
    else if (cmd == "A") {
      autoON = true;
      Serial.print("#");
    }

    //autoON(false)
    else if (cmd == "a") {
      autoON = false;
      Serial.print("#");
    }

    //setStabilizeTime
    else if (cmd.startsWith("S")) {
      cmd.remove(0, 1);
      stabilizeTime = cmd.toInt();
      Serial.print("#");
    }

    //setBroadband & Narrowband
    else if (cmd.startsWith("D")) {
      cmd.remove(0, 1);
      if (cmd == "B") {
        broadbandValue = lightValue; //set variable and save
        EEPROMwl.put(SAVED_BROADBAND_VALUE, broadbandValue);
      }
      else {
        narrowbandValue = lightValue; //set variable and save
        EEPROMwl.put(SAVED_NARROWBAND_VALUE, narrowbandValue);
      }
      Serial.print("#");
    }

    //goto Broadband & Narrowband
    else if (cmd.startsWith("G")) {
      cmd.remove(0, 1);
      calibratorState = 2;
      if (cmd == "B") {
        analogWrite(lightPanel, broadbandValue); //change current panel value to broadband value
        lightValue = broadbandValue;
      }
      else {
        analogWrite(lightPanel, narrowbandValue); //change current panel value to narrowband value
        lightValue = narrowbandValue;
      }
      Serial.print("#");
      startTimer = millis();
      savePanelValue();
    }

    //decrease light value by 1
    else if (cmd == " - ") {
      int valueCheck = reportingValue - 1;
      if (valueCheck >= 1) {
        calibratorState = 2;
        lightValue = valueCheck * brightnessSteps;
        analogWrite(lightPanel, lightValue);
        startTimer = millis();
        savePanelValue();
      }
      Serial.print("#");
    }

    //increase light value by 1
    else if (cmd == " + ") {
      byte valueCheck = reportingValue + 1;
      if (valueCheck <= maxBrightness) {
        calibratorState = 2;
        lightValue = valueCheck * brightnessSteps;
        analogWrite(lightPanel, lightValue);
        startTimer = millis();
        savePanelValue();
      }
      Serial.print("#");


    }

    if (calibratorState == 2) {
      if (millis() - startTimer >= stabilizeTime) {
        calibratorState = 3;
      }
    }
  }
  dbgi("bottom of function loop", 99, 1000);

}//end loop

void initializeLocation() {
  coverState = EEPROMwl.get(SAVED_COVER_STATE, coverState);
  previousPanelValue = EEPROMwl.get(SAVED_PANEL_VALUE, previousPanelValue);
  broadbandValue = EEPROMwl.get(SAVED_BROADBAND_VALUE, broadbandValue);
  narrowbandValue = EEPROMwl.get(SAVED_NARROWBAND_VALUE, narrowbandValue);

  if (coverState <= 0) {
    coverState = 1; //1:Closed
  }
  if (previousPanelValue < 0) {
    previousPanelValue = 255;
  }
  if (broadbandValue <= 0) {
    broadbandValue = 25;
  }
  if (narrowbandValue <= 0) {
    narrowbandValue = 255;
  }

  if (lightInstalled == false) {
    maxBrightness = 0;
    calibratorState = 0;
  }
}//end initializeLocation

void turnPanelTo() {
  if (lightValue != 0) {
    lightValue = lightValue * brightnessSteps;
    analogWrite(lightPanel, lightValue);
  }
  else {
    lightValue = previousPanelValue;
    analogWrite(lightPanel, lightValue);
  }
  savePanelValue();
  calibratorState = 2;
}//end turnPanelON

void saveCoverState() {
  EEPROMwl.put(SAVED_COVER_STATE, coverState);
}//end saveCoverState

void savePanelValue() {
  previousPanelValue = lightValue;
  EEPROMwl.put(SAVED_PANEL_VALUE, previousPanelValue);
}//end savePanelValue

void turnPanelOFF() {
  analogWrite(lightPanel, 0);
  lightValue = 0;
  calibratorState = 1;  //1:Off
}//end turnPanelOFF

best regards Stefan

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.