Maker Pro
Maker Pro

Arduino Project for ACC box

justin_gerber360

Sep 23, 2021
4
Joined
Sep 23, 2021
Messages
4
My wife is in grad school studying to be a Speech Language Pathologist (SLP). She does many assessments with patients and does exercises to help patients grow in their deficiencies. Since SLPs sometimes interact with patients that have low fine motor skills, there are large button switches that can be added to toys so kids who have motor issues can still play with toys at the press of a button. Example:


In this case my wife and her supervisor would like me to create a wooden box that opens at the press of this button and then closes at the press of the button. I did a year of robotics in high school which prompted them to assign me to this project but I am finding that this is way over my head. Would someone be able to guide me in how I can do this? At this point I have most of the hardware I think I need and I am working on the coding. I will get to the engineering later. I am using an Arduino Nano and a servo motor with this button to make the whole thing work powered by a 9V. I know I have not shared all the information needed to help me but I am just wondering if anyone wants and is able to help me. Thanks in advance.

Attached is my current circuit using SimulIDE and also the box I am using.

circuit.png

box.jpg
 

Bluejets

Oct 5, 2014
6,901
Joined
Oct 5, 2014
Messages
6,901
Show your code.
By 9V I am assuming a smoke alarm battery.....bad move.
As is driving a servo off the 5v regulator in the Arduino board.
Code would be much easier for you with 2 buttons.
It's normal to go to an Arduino forum for Arduino projects.
However, the web is chocka-block full of examples as is the Arduino IDE.
 

justin_gerber360

Sep 23, 2021
4
Joined
Sep 23, 2021
Messages
4
Yes my current plan was a 9V as you describe. What battery should I use?

My current code is limited as I am still trying to implement the push button as a toggle switch but this is what I have tried. You mentioning 2 buttons would be easier though so thank you for that suggestion. Would you recommend I go to an Arduino forum to get specialized help?

Code:
int LEDState=0;
int LEDPin=13;
int buttonPin=8;
int buttonNew;
int buttonOld=1;
int dt=250;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDPin, OUTPUT);
pinMode(buttonPin, INPUT);

}

void loop() {
buttonNew=digitalRead(buttonPin);
if(buttonOld==0 && buttonNew==1) {
  if (LEDState==0){
    digitalWrite(LEDPin, HIGH);
    LEDState=1;
  }
  else{
    digitalWrite(LEDPin, LOW);
    LEDState=0;
  }
}
buttonOld=buttonNew;
delay (dt);

}

Moderators note : used code tags for pieces of code
 
Last edited by a moderator:

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,700
Joined
Nov 17, 2011
Messages
13,700
A few issues:
No. 1:
Your button is connected from GND to pin 8 of the Arduino. But your definition says only
Code:
pinMode(buttonPin, INPUT);
In this case when the button is not pressed the input floats (input voltage arbitrarily somewhere between 0 V and 5 V). This is an undefined state. Use
Code:
pinMode(buttonPin, INPUT_PULLUP);
instead. This will connect an internal Pull-Up resistor from pin 8 to Vcc, thus ensuring logic high when the button is not pressed (see this reference).

No. 2:
Your button is not debounced. Bouncing happens when a mechanical switch is opened or closed and can lead to seemingly multiple actications of the button, as if the button where pressed in rapid sequence. Add code to debounce the button to avoid this. See this reference.

No. 3:
Your code checks the state of the button, but ignores the current state of the toy (toy on or toy off). To do this, you need a very simple form of a state machine, see this reference. Sounds more complicated than it is. Assuming you have a function that returns a debounced button (see above), it goes like this:
Code:
void setup() {
Toy_on = 0; // Toy is off. Set Toy_on = 1 for toy is on
// rest of setup code...
}

int button_pressed() {
// returns 1 if button is pressed (after debouncing)
// returns 0 if button is not pressed (after debouncing)
// your code for debouncing goes here...
}

void loop() {
  if (button_pressed() == 1) { // button has been pressed to turn the toy on or off
    if (Toy_on == 0) {       // toy is currently off
      Toy_on = 1;
      // your code for activating the toy goes here...
      while (button_pressed() == 1) { // wait until button is released
      }
    else {
      Toy_on = 0;
      // your code for de-activating the toy goes here...
      while (button_pressed() == 1) { // wait until button is released
      }
   }
 }
}

Cheers,

Harald
 

justin_gerber360

Sep 23, 2021
4
Joined
Sep 23, 2021
Messages
4
Thank you so much for the help!

I did some work last night and made a lot of progress. Here is my code with deboucning but it did not seems to make much difference than without the debouncing code. One thing that is interesting is that if I press the button quickly then the servo does not move but if I hold the button for a short time, then on the release the servo moves to the correct position. Is this an issue with the program or just a glitch with the program that I am using? Thanks.

Code:
const int    ledPin=13;              //declare servo, light, and button pins
const int buttonPin=8;
const int  servoPin=9;

const int DEBOUNCE_DELAY = 50;         //debounce setup
int lastSteadyState = LOW;            //the previous steady state from the input pin
int lastFlickerableState = LOW;      //the previous flickerable state from the input pin
int currentState;                   //the current reading from the input pin

int lastState=HIGH;                 //create other variables
int ledState;
int servoState;
                                       //the following variables are unsigned longs because the time, measured in
                                      //milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  //the last time the output pin was toggled

#include <Servo.h>                   //include the Servo library
Servo Servo1;                       //create a servo object

int dt=500;                         //extras

void setup() {
  Serial.begin(9600);
  pinMode(ledPin,OUTPUT);
  pinMode(buttonPin,INPUT_PULLUP);
  Servo1.attach(servoPin);
  pinMode(servoPin,OUTPUT);
}

void loop() {
  // If the switch/button changed, due to noise or pressing:
  if (currentState != lastFlickerableState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
    // save the the last flickerable state
    lastFlickerableState = currentState;
  }

  if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if(lastSteadyState == HIGH && currentState == LOW)
      Serial.println("The button is pressed");
    else if(lastSteadyState == LOW && currentState == HIGH)
      Serial.println("The button is released");

    // save the the last steady state
    lastSteadyState = currentState;
 
  currentState=digitalRead(buttonPin);
    if(lastState == LOW && currentState == HIGH) {
      if (servoState == 0){
        Servo1.write(90);
        servoState=1;
        }
      else{
        Servo1.write(0);
        servoState=0;
        }
  }
 }

lastState=currentState;
delay (dt);

}
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,700
Joined
Nov 17, 2011
Messages
13,700
This is not what I'd expect. You have 4 state variables:
  • currentState (this one is missing an initialization, btw,)
  • lastState
  • lastFlickerableState
  • lastSteadyState
Where you need only one: State = on or State = off

Also your code is a tad confusing as you mingle the debouncing into the main code section (loop()). I strongly recommend you put it into a separate routine as indicated in my code snippet. Of course that is not mandatory but imho makes the code better readable.

In this section
Code:
    // if the button state has changed:
    if(lastSteadyState == HIGH && currentState == LOW)
      Serial.println("The button is pressed");
    else if(lastSteadyState == LOW && currentState == HIGH)
      Serial.println("The button is released");
you evaluate the button press and send a message via the serial line. But you do not the information about the button state present at this point to initiate any action. Instead you use a separate code section to control the servo.
I'm afraid I lack the time to completely follow your thought structure through your code :(

May I suggest you forget the code you have for the moment being and start from scratch by drawing a flow diagram to visualize what the code is going to do. You may even ignore debouncing at this time. You can always replace reading the button state by a call to a deboucing routine later in the project. Simplify as much as possible. Things will become complicated almost by themselves with time :)
 

Bluejets

Oct 5, 2014
6,901
Joined
Oct 5, 2014
Messages
6,901
Simple enough debounce with minimal hardware (small capacitor) to get you going.
 

justin_gerber360

Sep 23, 2021
4
Joined
Sep 23, 2021
Messages
4
Here is where I have gotten to since last posting:

Code:
const int    ledPin=13;              //declare servo, light, and button pins
const int  buttonPin=8;
const int   servoPin=9;

#include <Servo.h>
Servo Servo1;

int lastState=1;                 //create other variables
int ledState;
int currentState;
int servoState;
int buttonRead;                   

int dt=500;                         //extras

void setup() {
  Serial.begin(9600);
  pinMode(ledPin,OUTPUT);
  pinMode(buttonPin,INPUT_PULLUP);
  Servo1.attach(servoPin);
  pinMode(servoPin,OUTPUT);
}

void loop() {
currentState=digitalRead(buttonPin);
if(lastState == 0 && currentState == 1){
  if (servoState == 0){
     Servo1.write(90);
     servoState=1;
   }
   else{
     Servo1.write(0);
     servoState=0;
    }
}
    
lastState=currentState;
delay (dt);
}

I did not create a flowchart but have made this code work on my simulated circuit that is shown above. I am still using SimulIDE. When I upload this program to the simulation my code works. After I release the button the servo moves 90 degrees. Then I press it again and it moves back 90 degrees. My issue now is that when I upload this to my hardware, nothing happens when I press my button in real life. I was able to modify this program to make a LED turn on and off at the press of one button. This also works in my simulation and it half works on the hardware. When uploaded to the hardware the button does nothing still, but when I unplug the button from the aux port then the light turns on. When I plug the cable back in nothing happens but then I unplug it again and the light turns off again. Is there an issue with my wiring or my program? Thanks!
 

Bluejets

Oct 5, 2014
6,901
Joined
Oct 5, 2014
Messages
6,901
Place some serial prints in your code and see where you are going astray.
 
Top