/**
Copyright (C) 2018, Uri Shaked
Licensed under the MIT License.
*/
#include <Arduino.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <TinyDebug.h>
#include "pitches.h"
const int totalSwitches = 3;
byte buttonPins[] = {1, 2, 3};
int switchVal = 0;
/* Constants - define pin numbers for leds, buttons and speaker, and also the game tones */
// byte buttonPins[] = {1, 2, 3, 4};
int gameTones[] = { NOTE_G3, NOTE_C4, NOTE_E4, NOTE_G5};
#define SPEAKER_PIN 0
/**
Set up the GPIO pins
*/
ISR(PCINT0_vect) {
GIMSK &= ~0b00100000; // Turn off pin change interrupts
sleep_disable();
}
// Alternate sleep function
// void sleep() {
// sleep_enable();
// noInterrupts();
// GIMSK |= 0b00100000; // Turn on pin change interrupts
// PCMSK = 0; // Clear all pin change interrupts
// // Enable pin change interrupts for button pins (assuming pins are within PCINT0-7 group)
// for (byte i = 0; i < totalSwitches; i++) {
// PCMSK |= (1 << buttonPins[i]);
// }
// interrupts();
// sleep_cpu();
// }
void sleep() {
Debug.println("-- ENTERING SLEEP MODE --");
sleep_enable();
noInterrupts();
GIMSK |= 0b00100000; // Turn on pin change interrupts
// check if disabling more buttons saves power verify totalbuttons
for (byte i = 0; i < totalSwitches; i++) {
PCMSK |= 1 << buttonPins[i];
}
interrupts();
sleep_cpu();
}
// The sound-producing function
void beep (unsigned char speakerPin, int frequencyInHertz, long timeInMilliseconds)
{ // http://web.media.mit.edu/~leah/LilyPad/07_sound_code.html
int x;
long delayAmount = (long)(1000000 / frequencyInHertz);
long loopTime = (long)((timeInMilliseconds * 1000) / (delayAmount * 2));
pinMode(speakerPin, OUTPUT);
for (x = 0; x < loopTime; x++) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(delayAmount);
digitalWrite(speakerPin, LOW);
delayMicroseconds(delayAmount);
}
pinMode(speakerPin, INPUT);
}
void playButtonTone(byte buttonIndex) {
beep(SPEAKER_PIN, gameTones[buttonIndex], 150);
// Wait until button is released.
while (digitalRead(buttonPins[buttonIndex]) == LOW);
delay(50);
}
int readSwitch() {
for (;;) {
int switchState = 0;
for (int i = 0; i < totalSwitches; i++) {
byte buttonPin = buttonPins[i];
if (digitalRead(buttonPin) == LOW) {
switchState |= (1 << i);
}
}
if (switchState != 0) {
return switchState;
}
else if (switchState == 0) { // if all buttons are high, return 0
return 0;
}
sleep();
}
}
/*
int readSwitch() {
for (;;) {
int switchState = 0;
for (int i = 0; i < totalSwitches; i++) {
// Debug.print(digitalRead(buttonPins[i]));
byte buttonPin = buttonPins[i];
if (digitalRead(buttonPin) == LOW) {
switchState |= (1 << i);
// Debug.println(switchState |= (1 << i), HEX);
}
}
// Debug.println("");
if (switchState != 0) {
return switchState;
}
sleep();
}
}
*/
void decodeSwitch(int switchValue) {
// Add different modes depending on the switchValue
switch (switchValue) {
case 01: // Mode 1
Debug.println("1");
break;
case 10: // Mode 2
Debug.println("2"); // Code for mode 2
break;
case 00: // Mode 3
Debug.println("3"); // Code for mode 3
break;
case 11: // Mode 3
Debug.println("11"); // Code for mode 3
break;
// Add more cases for different modes
default:
Debug.println("default");
// Code for invalid mode or no mode selected
break;
}
}
void setup()
{
Debug.begin();
for (int i = 0; i < totalSwitches; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
}
void loop()
{
// Read the switch values
switchVal = readSwitch();
Debug.println(switchVal);
// Decode and perform actions based on the switch values
// decodeSwitch(switchVal);
// beep(SPEAKER_PIN, gameTones[], 300);
// Debug.print(digitalRead(switchPin1));
// Debug.println(digitalRead(switchPin2));
sleep();
delay(50);
}
/*
The switchState |= (1 << i); line of code combines the current switchState with
the value obtained from shifting the number 1 left by i positions using a bitwise OR operation.
Let's break it down:
1 << i: This operation is a bitwise left shift. It takes the binary representation of
the number 1 (which is 00000001 in 8-bit representation) and shifts it left by i positions.
For example, if i = 2, the result would be 00000100.
switchState |= ...: This operation is a bitwise OR assignment.
It takes the current value of switchState, performs a bitwise OR with the value obtained in step 1,
and assigns the result back to switchState.
00000100
00000010
00000110
*/