Need Help Adding Conditional Code For Button Presses

Hi! I will try to be as informational and concise as possible so as to respect everyone’s time and knowledge.

I am working on building a robotic security camera prop. I have 2 servos, powered externally, connected to an Arduino Nano. The servos are responsible for up/Down and Left/Right movement. To control the servo movement, I am using a Nintendo Wii Nunchuk and an library to interface it with the Nano.

I have successfully managed to get the servos to move based on the joystick’s position and have also gotten the built-in LED to blink while everything else is running:

#include <Servo.h>
#include <Wire.h>
#include "Nunchuk.h"

const int ledPin =  LED_BUILTIN;

Servo leftright;
Servo updown;

int pos1 = 0;
int pos2 = 0;
int ledState = LOW;

unsigned long interval = 1000;
unsigned long previousMillis = 0;

void setup() {
  Wire.begin();
  nunchuk_init_power();
  nunchuk_init();
  leftright.attach(12);
  updown.attach(8);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (nunchuk_read()) {
    pos1 = map(nunchuk_joystickX(), -98, 102, 0, 180);
    pos2 = map(nunchuk_joystickY(), 94, -109, 180, 0);
    leftright.write(pos1);
    updown.write(pos2);
  }
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (ledState == LOW) {
      ledState = HIGH;
    } 
    else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
  delay(20);
}

Here is what I’m struggling with:
I’d like to press the C button on the Nunchuk and have the LED blink quicker. I’d also like to press the Z button and have the Left/Right servo sweep back and forth from 0-180 degrees. However, the methods I’ve tried to implement this in code have not worked. I need help understanding what I’m doing wrong and how it should be coded.

As far as the library elements go:
nunchuk_buttonZ() and nunchuk_buttonC() return either 0 or 1, depending on if the button is pressed or not.

This is the code that does not work:

#include <Servo.h>
#include <Wire.h>
#include "Nunchuk.h"

const int ledPin =  LED_BUILTIN;

Servo leftright;
Servo updown;

int pos1 = 0;
int pos2 = 0;
int pos3 = 90;
int ledState = LOW;
int z = nunchuk_buttonZ;

unsigned long interval = 1000;
unsigned long previousMillis = 0;

void setup() {
  Wire.begin();
  nunchuk_init_power();
  nunchuk_init();
  leftright.attach(12);
  updown.attach(8);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (nunchuk_read()) {
    if (z == 1){
      for (pos3 = 0; pos3 <= 180; pos3 += 1) {
        leftright.write(pos3);
        delay(15);
        }
      for (pos3 = 180; pos3 >= 0; pos3 -= 1) {
        leftright.write(pos3);
        delay(15);
      }
  }
  else {
    pos1 = map(nunchuk_joystickX(), -98, 102, 0, 180);
    pos2 = map(nunchuk_joystickY(), 94, -109, 180, 0);
    leftright.write(pos1);
    updown.write(pos2);
  }
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (ledState == LOW) {
      ledState = HIGH;
    } 
    else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
  delay(20);
  }
}

As you can see, I tried to insert a statement to check to see if the Z button was pressed and to have the servo sweep if it was. However, when I press the Z button, nothing happens.

What am I doing wrong and how can the code be changed to have the servo sweep when Z is pressed and the LED to blink faster when C is pressed?

What is driving z to change?if (z == 1){...
(did not read further, this feels fishy enough to have your stuff fail)

From the top of the code:

int z = nunchuk_buttonZ;

nunchuk_buttonZ reads as a 0 when the Z button is not pressed, and as a 1 when it is pressed. Physically pressing the button should change the value from 0 to 1.

However, now that you mention it, I think it might need to be

int z = nunchuk_buttonZ();

I will try this change and see what happens.

Do it the same way as getting the other values from the nunchuck. You don't need a variable z. The nunchuk_buttonZ() function call should be in the if statement where you want to use the value.

Steve

Ok, both of your comments were very helpful. Changing nunchuk_buttonZ to nunchuk_buttonZ() allowed the program to recognize the function, and moving it straight to the if statement helped simplify things a bit. Thanks for that!

I also found a great tutorial by Adafruit that addressed part of my question, and have successfully added code to keep the LED bblinking while the servo sweeps when Z is pressed.

Here’s the issue I’m facing now: I’d like to press the C button and have the LED blink quicker. I tried putting in

if (nunchuk_buttonC() == 1){
      interval = 250;
    }

into the nunchuk_read() function, but that ended up making the LED blink fast all the time and made it so the sweep function didn’t work any more. Could you please help me figure out what I’m doing wrong and how/where to put this function to change the LED interval?

Here’s the code that’s working currently:

#include <Servo.h>
#include <Wire.h>
#include "Nunchuk.h"

const int ledPin =  LED_BUILTIN;

Servo leftright;
Servo updown;

int pos1 = 0;
int pos2 = 0;
int pos3 = 0;
int increment = 1;
int servoInterval;
int updateInterval = servoInterval;
int ledState = LOW;

unsigned long interval = 1000;
unsigned long previousMillis = 0;
unsigned long lastUpdate;

void setup() {
  Wire.begin();
  nunchuk_init_power();
  nunchuk_init();
  leftright.attach(12);
  updown.attach(8);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (nunchuk_read()) {
    if (nunchuk_buttonZ() == 1){
      if((millis() - lastUpdate) > updateInterval) {
        lastUpdate = millis();
        pos3 += increment;
        leftright.write(pos3);
        if ((pos3 >= 180) || (pos3 <= 0)) {
        increment = -increment;
      }
    }
  }
  else {
    pos1 = map(nunchuk_joystickX(), -98, 102, 0, 180);
    pos2 = map(nunchuk_joystickY(), 94, -109, 180, 0);
    leftright.write(pos1);
    updown.write(pos2);
  }
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (ledState == LOW) {
      ledState = HIGH;
    } 
    else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
  delay(20);
  }
}

I had a couple of ideas as I was drifting off to bed last night, so I played around with the code some more today and: Eureka! I figured out how to make it work!

Instead of trying to change the interval every time I pushed the C button, I just inserted a copy of the blink code with a modification to the interval via basic subtraction. That way when the C button is pressed it will blink in the same way as it normally does, just with a faster interval. I’m so happy it works!

I also added a line to the Z button sweep that writes a position to the Up/Down servo, so the camera’s head stays in a steady position while it sweeps back and forth.

Thank you J-M-L and slipstick for helping me brainstorm this coding challenge!

Here’s my final code, if anyone is interested:

#include <Servo.h>
#include <Wire.h>
#include "Nunchuk.h"

const int ledPin = 4;

Servo leftright;
Servo updown;

int pos1 = 0;
int pos2 = 0;
int pos3 = 0;
int increment = 1;
int servoInterval;
int updateInterval = servoInterval;
int ledState = LOW;

unsigned long interval = 1750;
unsigned long previousMillis = 0;
unsigned long lastUpdate;

void setup() {
  Wire.begin();
  nunchuk_init_power();
  nunchuk_init();
  leftright.attach(12);
  updown.attach(8);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (nunchuk_read()) {
    if (nunchuk_buttonC() == 1){
      if (currentMillis - previousMillis >= (interval - 1625)){
      previousMillis = currentMillis;

       if (ledState == LOW) {
        ledState = HIGH;
        } 
      else {
        ledState = LOW;
        }
        digitalWrite(ledPin, ledState);
        }
    }
    if (nunchuk_buttonZ() == 1){
      if((millis() - lastUpdate) > updateInterval) {
        lastUpdate = millis();
        pos3 += increment;
        leftright.write(pos3);
        if ((pos3 >= 180) || (pos3 <= 0)) {
        increment = -increment;
      }
    }
    updown.write(94);
  }
  else {
    pos1 = map(nunchuk_joystickX(), -98, 102, 0, 180);
    pos2 = map(nunchuk_joystickY(), 94, -109, 180, 0);
    leftright.write(pos1);
    updown.write(pos2);
  }
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (ledState == LOW) {
      ledState = HIGH;
    } 
    else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
  delay(20);
  }
}

Also, here’s the link to the Wii Nunchuk Library I’m using, just in case anyone wants to use this code in the future.