Skip to content

Instantly share code, notes, and snippets.

@lapointexavier
Created October 26, 2014 01:30
Show Gist options
  • Save lapointexavier/227e37b0d112234df08f to your computer and use it in GitHub Desktop.
Save lapointexavier/227e37b0d112234df08f to your computer and use it in GitHub Desktop.
Quake Countdown Pumpkin project
#include <Wire.h>
#define BAUD (9600) /* Serial baud define */
#define _7SEG (0x38) /* I2C address for 7-Segment */
#define THERM (0x49) /* I2C address for digital thermometer */
#define EEP (0x50) /* I2C address for EEPROM */
#define RED (3) /* Red color pin of RGB LED */
#define GREEN (5) /* Green color pin of RGB LED */
#define BLUE (6) /* Blue color pin of RGB LED */
#define SPKOUT (9)
// TONES ==========================================
// Start by defining the relationship between
// note, period, & frequency.
//#define c 3830 // 261 Hz
//#define d 3400 // 294 Hz
//#define e 3038 // 329 Hz
//#define f 2864 // 349 Hz
//#define g 2550 // 392 Hz
//#define a 2272 // 440 Hz
//#define b 2028 // 493 Hz
#define C 2700 // 523 Hz
// Define a special note, 'R', to represent a rest
//#define R 0
const byte NumberLookup[16] = {0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,
0x77,0x7C,0x39,0x5E,0x79,0x71};
/* Function prototypes */
void dis7SEG (char*);
void send7SEG (byte, byte);
void updateRGB (long);
// MELODY and TIMING =======================================
// melody[] is an array of notes, accompanied by beats[],
// which sets each note's relative length (higher #, longer note)
int melody[] = {C};
int beats[] = {16};
// Set overall tempo
long tempo = 10000;
// Set length of pause between notes
int pause = 1000;
// Loop variable to increase Rest length
int rest_count = 100; //<-BLETCHEROUS HACK; See NOTES
// Initialize core variables
int tone_ = 0;
int beat = 0;
long duration = 0;
void setup() {
Serial.begin(BAUD);
Wire.begin(); /* Join I2C bus */
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
pinMode(SPKOUT, OUTPUT);
delay(500); /* Allow system to stabilize */
}
/***************************************************************************
Function Name: loop
Purpose:
Run-time forever loop.
****************************************************************************/
void loop()
{
byte Time;
byte counter, counter2;
bool IsPositive;
/* Configure 7-Segment to 12mA segment output current, Dynamic mode,
and Digits 1, 2, 3 AND 4 are NOT blanked */
Wire.beginTransmission(_7SEG);
Wire.write(0);
Wire.write(B01000111);
Wire.endTransmission();
/* Test 7-Segment */
for (counter=0; counter<8; counter++)
{
Wire.beginTransmission(_7SEG);
Wire.write(1);
for (counter2=0; counter2<4; counter2++)
{
Wire.write(1<<counter);
}
Wire.endTransmission();
delay (250);
}
long countdown = 30;
long third = countdown / 3;
while (1 && countdown > 0)
{
updateRGB(countdown, third);
if (countdown <= third) {
triggerTone();
}
char buffer[5] = {0,0,0,0,'\0'};
ltoa(countdown, buffer, 10);
dis7SEG(buffer);
delay (1000); /* Take temperature read every 1 second */
countdown --;
}
}
void integerToBytes(long n, byte buf[4]) {
buf[0] = (byte) n >> 24;
buf[1] = (byte) n >> 16;
buf[2] = (byte) n >> 8;
buf[3] = (byte) n;
}
long bytesToInteger(byte buf[4]) {
return (unsigned long)(buf[3] & 0xff) | (buf[2] & 0xff << 8) | (buf[1] & 0xff << 16) | (buf[0] & 0xff << 24) ;
}
void triggerTone() {
// Set up a counter to pull from melody[] and beats[]
tone_ = melody[0];
beat = beats[0];
duration = beat * tempo; // Set up timing
playTone();
}
// PLAY TONE ==============================================
// Pulse the speaker to play a tone for a particular duration
void playTone() {
long elapsed_time = 0;
if (tone_ > 0) { // if this isn't a Rest beat, while the tone has
// played less long than 'duration', pulse speaker HIGH and LOW
while (elapsed_time < duration) {
digitalWrite(SPKOUT,HIGH);
delayMicroseconds(tone_ / 2);
// DOWN
digitalWrite(SPKOUT, LOW);
delayMicroseconds(tone_ / 2);
// Keep track of how long we pulsed
elapsed_time += (tone_);
}
}
else { // Rest beat; loop times delay
for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
delayMicroseconds(duration);
}
}
}
/***************************************************************************
Function Name: updateRGB
Purpose:
Update RGB LED according to define HOT and COLD temperature.
****************************************************************************/
void updateRGB (long countdown, long third)
{
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW); /* Turn off all LEDs. */
if (countdown >= third * 3)
{
digitalWrite(BLUE, HIGH);
}
else if (countdown <= third * 2)
{
digitalWrite(RED, HIGH);
}
else
{
digitalWrite(GREEN, HIGH);
}
}
/***************************************************************************
Function Name: dis7SEG
Purpose:
Display number on the 7-segment display.
****************************************************************************/
void dis7SEG (char* n)
{
byte Digit = 4; /* Number of 7-Segment digit */
byte High;
byte Number;
char reversed[5];
// for(int y=5; y>1; y--) {
// reversed[y] = n[4-(y-1)];
// }
reversed[0] = n[4];
reversed[1] = n[3];
reversed[2] = n[2];
reversed[3] = n[1];
reversed[4] = '\0';
for(int x=0; x<4; x++) {
char toConvert[2] = {n[x], '\0'};
send7SEG(Digit, NumberLookup[(byte) atol(toConvert) ]);
Digit --;
}
}
/***************************************************************************
Function Name: send7SEG
Purpose:
Send I2C commands to drive 7-segment display.
****************************************************************************/
void send7SEG (byte Digit, byte Number)
{
Wire.beginTransmission(_7SEG);
Wire.write(Digit);
Wire.write(Number);
Wire.endTransmission();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment