so in my last attempt to pivot this project into something usable, can anybody point me in the direction to where I should implement a toggle switch?
I tried to use a bool to activate either the bar, school, etc.
the bluetooth is used to set the profiles by clicking the respective buttons and storing the values then after storing those values i want to use pysical buttons that toggle or 'hold' the buttons state for each situation.
Any help again, would be incredibly appreciated
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 12
#define NUMPIXELS 4
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int delayval = 500; // delay for half a second
#include <string.h>
#include <Arduino.h>
#include <SPI.h>
#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_)
#include <SoftwareSerial.h>
#endif
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#include "BluefruitConfig.h"
#define FACTORYRESET_ENABLE 0
#define MINIMUM_FIRMWARE_VERSION "0.6.6"
#define MODE_LED_BEHAVIOUR "MODE"
Adafruit_BluefruitLE_UART ble(Serial1, BLUEFRUIT_UART_MODE_PIN);
/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
void error(const __FlashStringHelper*err) {
Serial.println(err);
while (1);
}
// function prototypes over in packetparser.cpp
uint8_t readPacket(Adafruit_BLE *ble, uint16_t timeout);
float parsefloat(uint8_t *buffer);
void printHex(const uint8_t * data, const uint32_t numBytes);
// the packet buffer
extern uint8_t packetbuffer[];
int bar[1]; //single v in a relationship
int school[1]; //undergrad v graduate
int work[1]; //staff v management
int store[1]; //help me
int custom[1];
const int buttonPin1 = 6;
const int buttonPin2 = 9;
const int buttonPin3 = 10;
const int buttonPin4 = 3;
const int buttonPin5 = 2;
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;
void setup(void)
{
pinMode(buttonPin1, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
pinMode(buttonPin4, INPUT_PULLUP);
pinMode(buttonPin5, INPUT_PULLUP);
pixels.begin();
while (!Serial); // required for Flora & Micro
delay(500);
Serial.begin(115200);
Serial.println(F("Adafruit Bluefruit App Controller Example"));
Serial.println(F("-----------------------------------------"));
/* Initialise the module */
Serial.print(F("Initialising the Bluefruit LE module: "));
if ( !ble.begin(VERBOSE_MODE) )
{
error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
}
Serial.println( F("OK!") );
if ( FACTORYRESET_ENABLE )
{
/* Perform a factory reset to make sure everything is in a known state */
Serial.println(F("Performing a factory reset: "));
if ( ! ble.factoryReset() ) {
error(F("Couldn't factory reset"));
}
}
/* Disable command echo from Bluefruit */
ble.echo(false);
Serial.println("Requesting Bluefruit info:");
/* Print Bluefruit information */
ble.info();
Serial.println(F("Please use Adafruit Bluefruit LE app to connect in Controller mode"));
Serial.println(F("Then activate/use the sensors, color picker, game controller, etc!"));
Serial.println();
ble.verbose(false); // debug info is a little annoying after this point!
/* Wait for connection */
while (! ble.isConnected()) {
delay(500);
}
Serial.println(F("******************************"));
// LED Activity command is only supported from 0.6.6
if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
{
// Change Mode LED Activity
Serial.println(F("Change LED activity to " MODE_LED_BEHAVIOUR));
ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);
}
// Set Bluefruit to DATA mode
Serial.println( F("Switching to DATA mode!") );
ble.setMode(BLUEFRUIT_MODE_DATA);
Serial.println(F("******************************"));
}
void loop(void)
{
int red = 0;
int green = 0;
int blue = 0;
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
buttonState4 = digitalRead(buttonPin4);
buttonState5 = digitalRead(buttonPin5);
if (buttonState1 == LOW) {
Serial.println("Button 1 Pressed"); // sets pixel to BAR color scheme. replace with RFID UID
//bar
if (bar[0] == 22) {
red = 255; //pink single
green = 0;
blue = 154;
}
if (bar[0] == 33) {
red = 0; //blue relationship
green = 154, blue = 255;
}
}
if (buttonState2 == LOW) {
Serial.println("Button 2 Pressed"); // sets pixel to SCHOOL color scheme. replace with RFID UID
//school
if (school[0] == 44) {
red = 239; //yellow undergrad
green = 255;
blue = 0;
}
if (school[0] == 55) {
red = 230; //purple grad
green = 0;
blue = 255;
}
}
if (buttonState3 == LOW) {
Serial.println("Button 3 Pressed"); // sets pixel to WORK color scheme. replace with RFID UID
//work
if (work[0] == 66) {
red = 201; //gray staff
green = 0;
blue = 0;
}
if (work[0] == 77) {
red = 236; //gold management
green = 236;
blue = 0;
}
}
if (buttonState4 == LOW) {
Serial.println("Button 4 Pressed"); // sets pixel to WORK color scheme. replace with RFID UID
//store
if (store[0] == 11) {
red = 255; //Help Me
green = 0;
blue = 0;
}
if (store[0] == 12) {
red = 255; //Leave me alone
green = 255;
blue = 255;
}
}
if (buttonState5 == LOW) {
Serial.println("Button 5 Pressed"); // sets pixel to WORK color scheme. replace with RFID UID
red = 255; green = 255; blue = 255;
} //Custom color
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(red, green, blue)); pixels.show();
} //show pixels and update color
uint8_t len = readPacket(&ble, BLE_READPACKET_TIMEOUT);
if (len == 0) return;
// Buttons from App for profile
if (packetbuffer[1] == 'B') {
uint8_t buttnum = packetbuffer[2] - '0'; //buttnum reads button number on controller app
boolean pressed = packetbuffer[3] - '0';
// Serial.print ("Button ");
if (buttnum == 5) {
bar[0] = 22; //single
}
if (buttnum == 8) {
bar[0] = 33; //taken
}
if (buttnum == 6) {
school[0] = 44; //undergrad
}
if (buttnum == 7) {
school[0] = 55; //grad
}
if (buttnum == 1) {
work[0] = 66; //staff
}
if (buttnum == 2) {
work[0] = 77; //management
}
if (buttnum == 3) {
store[0] = 11; //I require assistance
}
if (buttnum == 4) {
store[0] = 12; //leave me alone store
}
if (buttonState5 == LOW) {
custom[0] = 13; //custom
}
//check values of arrays
if (bar[0] == 22) {
Serial.println("Single");
}
if (bar[0] == 33) {
Serial.println("In a Relationship");
}
if (school[0] == 44) {
Serial.println("Undergraduate");
}
if (school[0] == 55) {
Serial.println("Graduate");
}
if (work[0] == 66) {
Serial.println("Staff");
}
if (work[0] == 77) {
Serial.println("Management");
}
if (store[0] == 11) {
Serial.println("Help Me");
}
if (store[0] == 12) {
Serial.println("I Require Assistance");
}
if (custom[0] == 13) {
Serial.println("Don't Dim My Sparkle");
}
}
}
why go through all of the array machinations for single element arrays?
int bar[1]; //single v in a relationship
int school[1]; //undergrad v graduate
int work[1]; //staff v management
int store[1]; //help me
int custom[1];
all of your comparisons appear... arbitrary:
if (school[0] == 44) {
red = 239; //yellow undergrad
green = 255;
blue = 0;
}
if (school[0] == 55) {
red = 230; //purple grad
green = 0;
blue = 255;
}
}
Hello gradientreverb,
from your bit unstructured post, I'm not quite sure what you're really into... but I'd assume you want to have a key pressed, and released again, and then it should toggle something in your device. Not just while the key is pressed,right?
First, I'd restructure the code to make use of such advanced control structures as "loops"
. Then, I'd use arrays in places where they make really sense. Then, you need some routine that controls when a button is pressed, and then released again. Maybe even several of them, and also all at once.
Let me try all these in a first attempt (untested, and for your own corrections of course).
See my comments in the code - I leave your original code largely in place, but commented out, for better comparison.
Sorry, have to split it up in 3 postings for length - this text (Part I) , the main program (Part II) and the
doButtons() routine (Part III).
BR
stargar
Part II - Code main program:
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 12
#define NUMPIXELS 4
//added a define that tells the number of buttons:
#define BUTTONS 5
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int delayval = 500; // delay for half a second
#include <string.h>
#include <Arduino.h>
#include <SPI.h>
#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_)
#include <SoftwareSerial.h>
#endif
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#include "BluefruitConfig.h"
#define FACTORYRESET_ENABLE 0
#define MINIMUM_FIRMWARE_VERSION "0.6.6"
#define MODE_LED_BEHAVIOUR "MODE"
Adafruit_BluefruitLE_UART ble(Serial1, BLUEFRUIT_UART_MODE_PIN);
/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
void error(const __FlashStringHelper*err) {
Serial.println(err);
while (1);
}
// function prototypes over in packetparser.cpp
uint8_t readPacket(Adafruit_BLE *ble, uint16_t timeout);
float parsefloat(uint8_t *buffer);
void printHex(const uint8_t * data, const uint32_t numBytes);
// the packet buffer
extern uint8_t packetbuffer[];
// these arrays make no sense:
/*
int bar[1]; //single v in a relationship
int school[1]; //undergrad v graduate
int work[1]; //staff v management
int store[1]; //help me
int custom[1];
*/
int bar; //single v in a relationship
int school; //undergrad v graduate
int work; //staff v management
int store; //help me
int custom;
// use an array of byte here:
/*
const int buttonPin1 = 6;
const int buttonPin2 = 9;
const int buttonPin3 = 10;
const int buttonPin4 = 3;
const int buttonPin5 = 2;
*/
const byte buttonPin[5]={ 6, 9, 10, 3, 2};
// same here - use an array:
/*
int buttonState1 = 0;
...
int buttonState5 = 0;
*/
byte buttonState[5]= { 0, 0, 0, 0, 0 };
void setup()
{
/*
pinMode(buttonPin1, INPUT_PULLUP);
...
pinMode(buttonPin5, INPUT_PULLUP);
*/
// use a loop here now:
for(byte i=0; i<BUTTONS; i++) {
pinMode(buttonPin[i],INPUT_PULLUP);
}
pixels.begin();
while (!Serial); // required for Flora & Micro
delay(500);
Serial.begin(115200);
Serial.println(F("Adafruit Bluefruit App Controller Example"));
Serial.println(F("-----------------------------------------"));
/* Initialise the module */
Serial.print(F("Initialising the Bluefruit LE module: "));
if ( !ble.begin(VERBOSE_MODE) )
{
error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
}
Serial.println( F("OK!") );
if ( FACTORYRESET_ENABLE )
{
/* Perform a factory reset to make sure everything is in a known state */
Serial.println(F("Performing a factory reset: "));
if ( ! ble.factoryReset() ) {
error(F("Couldn't factory reset"));
}
}
/* Disable command echo from Bluefruit */
ble.echo(false);
Serial.println("Requesting Bluefruit info:");
/* Print Bluefruit information */
ble.info();
Serial.println(F("Please use Adafruit Bluefruit LE app to connect in Controller mode"));
Serial.println(F("Then activate/use the sensors, color picker, game controller, etc!"));
Serial.println();
ble.verbose(false); // debug info is a little annoying after this point!
/* Wait for connection */
while (! ble.isConnected()) {
delay(500);
}
Serial.println(F("******************************"));
// LED Activity command is only supported from 0.6.6
if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
{
// Change Mode LED Activity
Serial.println(F("Change LED activity to " MODE_LED_BEHAVIOUR));
ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);
}
// Set Bluefruit to DATA mode
Serial.println( F("Switching to DATA mode!") );
ble.setMode(BLUEFRUIT_MODE_DATA);
Serial.println(F("******************************"));
}
void loop(void)
{
int red = 0;
int green = 0;
int blue = 0;
/*
buttonState1 = digitalRead(buttonPin1);
...
buttonState5 = digitalRead(buttonPin5);
*/
// we put this into a subroutine called "doButtons()", returning "true" if action must be taken, otherwise skip the subsequent section:
if ( doButtons() ) {
// adapted everything to the new setup:
if (buttonState[0] == 0) {
Serial.println("Button 1 Pressed"); // sets pixel to BAR color scheme. replace with RFID UID
//bar
if (bar == 22) {
red = 255; //pink single
green = 0;
blue = 154;
}
if (bar == 33) {
red = 0; //blue relationship
green = 154, blue = 255;
}
}
if (buttonState[1] == 0) {
Serial.println("Button 2 Pressed"); // sets pixel to SCHOOL color scheme. replace with RFID UID
//school
if (school == 44) {
red = 239; //yellow undergrad
green = 255;
blue = 0;
}
if (school == 55) {
red = 230; //purple grad
green = 0;
blue = 255;
}
}
if (buttonState[2] == 0) {
Serial.println("Button 3 Pressed"); // sets pixel to WORK color scheme. replace with RFID UID
//work
if (work == 66) {
red = 201; //gray staff
green = 0;
blue = 0;
}
if (work == 77) {
red = 236; //gold management
green = 236;
blue = 0;
}
}
if (buttonState[3] == 0) {
Serial.println("Button 4 Pressed"); // sets pixel to WORK color scheme. replace with RFID UID
//store
if (store == 11) {
red = 255; //Help Me
green = 0;
blue = 0;
}
if (store == 12) {
red = 255; //Leave me alone
green = 255;
blue = 255;
}
}
if (buttonState[4] == 0) {
Serial.println("Button 5 Pressed"); // sets pixel to WORK color scheme. replace with RFID UID
red = 255; green = 255; blue = 255;
} //Custom color
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(red, green, blue)); pixels.show();
} //show pixels and update color
uint8_t len = readPacket(&ble, BLE_READPACKET_TIMEOUT);
if (len == 0) return;
// Buttons from App for profile
if (packetbuffer[1] == 'B') {
uint8_t buttnum = packetbuffer[2] - '0'; //buttnum reads button number on controller app
boolean pressed = packetbuffer[3] - '0';
// Serial.print ("Button ");
/*
if (buttnum == 5) {
bar[0] = 22; //single
}
if (buttnum == 8) {
bar[0] = 33; //taken
}
if (buttnum == 6) {
school[0] = 44; //undergrad
}
if (buttnum == 7) {
school[0] = 55; //grad
}
if (buttnum == 1) {
work[0] = 66; //staff
}
if (buttnum == 2) {
work[0] = 77; //management
}
if (buttnum == 3) {
store[0] = 11; //I require assistance
}
if (buttnum == 4) {
store[0] = 12; //leave me alone store
}
*/
// Recommended to use "switch" construction here!
switch(buttnum) {
case 1:
work = 66; //staff
break;
case 2:
work = 77; //management
break;
case 3:
store = 11; //I require assistance
break;
case 4:
store = 12; //leave me alone store
break;
case 5:
bar = 22; //single
break;
case 6:
school = 44; //undergrad
break;
case 7:
school = 55; //grad
break;
case 8:
bar = 33; //taken
break;
default:
delay(1); // dummy instruction, add something here?
break;
}
if (buttonState[4] == 0) {
custom = 13; //custom
}
//check values
if (bar == 22) {
Serial.println("Single");
}
if (bar == 33) {
Serial.println("In a Relationship");
}
if (school == 44) {
Serial.println("Undergraduate");
}
if (school == 55) {
Serial.println("Graduate");
}
if (work == 66) {
Serial.println("Staff");
}
if (work == 77) {
Serial.println("Management");
}
if (store == 11) {
Serial.println("Help Me");
}
if (store == 12) {
Serial.println("I Require Assistance");
}
if (custom == 13) {
Serial.println("Don't Dim My Sparkle");
}
}
}
}
Part III - Code doButtons() :
bool doButtons() {
// for return value:
bool ret=false;
// this array must persist its values across subsequent calls:
static bool once[BUTTONS];
// another static boolean flag, for first-run initialization of "once[]" array at runtime:
static bool firstrun=true;
// some more variables:
byte i;
// only if you decide to use the optional part in the end, uncomment this too:
// byte pressed=0;
// dynamic initialize once[] - only on very first run:
if (firstrun) {
for(i=0; i<BUTTONS; i++) {
once[i]=false;
}
firstrun=false;
}
for(i=0; i<BUTTONS; i++) {
buttonState[i] = digitalRead(buttonPin[i]);
// when pressed, it is assumed to be "0":
if (buttonState[i] == 0) {
// if currently selected button is pressed, ...
if ( !(once[i]) ) {
// ... then this is a NEW keypress not seen earlier - return "true" to handle it:
ret=true;
}
}
else {
// key unpressed - we must "recharge" the adjacent "once" variable for next keypress:
once[i]=false;
}
}
// debounce - you will need that; adjust length as required:
delay(100);
/*
// optionally:
// wait until ALL keys are released;
// side effect would be that action is only starting when all keys are released:
if (ret) {
// at least one key still pressed:
do {
pressed=0;
for (i=0; i<BUTTONS; i++) {
// sum up all digital inputs:
pressed += digitalRead(buttonPin[i]);
// only leave loop when all inputs read a "1" again:
} while (pressed != BUTTONS);
}
*/
// ... DONE - return result:
return(ret);
}
BR
stargar
stargar:
Hello gradientreverb,
from your bit unstructured post, I'm not quite sure what you're really into... but I'd assume you want to have a key pressed, and released again, and then it should toggle something in your device. Not just while the key is pressed,right?
First, thank you for the reply and help! also, sorry for my convoluted attempt at trying to explain what im trying to do.
These arrays are storing a profile with buttons on the adafruit iOS app, that is the controller buttons in the app
allows me to punch in whether im single or in a relationship, an undergrad or grad etc. These aren't physical buttons.
Once you enter your profile in the adafruit bluetooth app, its stores whatever number so when I press PHYSICAL buttons i can switch on the lights depending on the environment. ie. Classroom for undergrad/grad/teacher.
My issue is that once I set the profile in the application on my phone(bluetooth app) I want to press a physical button thats connected to the arduino to activate the respective profile. Prior to this the activation mechanism was an RFID tag on doors to each environment, but im trying to figure out this first with a physcial button as a proof of concept.
int bar[1]; //single v in a relationship
int school[1]; //undergrad v graduate
int work[1]; //staff v management
int store[1]; //help me
int custom[1];
*/
gradientreverb:
First, thank you for the reply and help! also, sorry for my convoluted attempt at trying to explain what im trying to do.
These arrays are storing a profile with buttons on the adafruit iOS app, that is the controller buttons in the app
allows me to punch in whether im single or in a relationship, an undergrad or grad etc. These aren't physical buttons.
Once you enter your profile in the adafruit bluetooth app, its stores whatever number so when I press PHYSICAL buttons i can switch on the lights depending on the environment. ie. Classroom for undergrad/grad/teacher.
My issue is that once I set the profile in the application on my phone(bluetooth app) I want to press a physical button thats connected to the arduino to activate the respective profile. Prior to this the activation mechanism was an RFID tag on doors to each environment, but im trying to figure out this first with a physcial button as a proof of concept.
int bar[1]; //single v in a relationship
int school[1]; //undergrad v graduate
int work[1]; //staff v management
int store[1]; //help me
int custom[1];
*/
Hello,
still it doesn't matter where the numbers (integers) for switching actually stem from.
Be it from keypresses, a RFID tag, or an upstream BT device.
And no, you still don't need these variables to be single-member arrays! Omit the [1] at the end, and you're equally fine. Try my code, after having copied the parts together into ONE sketch (I had to split it because of maximum length), and get the logic behind it. (Disclaimer: It is untested so not proven to be error-free, but I've checked it at the best of my knowledge.)
You should possibly get the logical idea behind the "once" variables I used.
Try it and tell your findings.
BR
stargar