/*
jjn timer
20161022
*/
#include <Wire.h> // Include the Arduino SPI library
bool showColon=0;
/*start encoders*/
int val;
int encoder0PinA = 2;
int encoder0PinB = 3;
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int encoder1PinA = 7;
int encoder1PinB = 8;
int encoder1Pos = 0;
int encoder1PinALast = LOW;
int n = LOW;
bool startup = true;
bool doBeeper=false;
int mins=0;
int secs=0;
/*end encoders*/
/*beep*/
int SPKR=9;
/*end beep*/
/*toggle button*/
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 5; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = HIGH; // the current state of the output pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
/*end toggle button*/
// Here we'll define the I2C address of our S7S. By default it
// should be 0x71. This can be changed, though.
const byte s7sAddress = 0x71;
unsigned int counter = 0; // This variable will count up to 65k
char tempString[10]; // Will be used with sprintf to create strings
int scan=1;
bool doCountdown=true;
void setup(){
Serial.begin(9600);
Wire.begin(); // Initialize hardware I2C pins
/*start encoder pins*/
pinMode (encoder0PinA,INPUT);
pinMode (encoder0PinB,INPUT);
pinMode (encoder1PinA,INPUT);
pinMode (encoder1PinB,INPUT);
/*end encoder pins*/
// Clear the display, and then turn on all segments and decimals
clearDisplayI2C(); // Clears display, resets cursor
// Custom function to send four bytes via I2C
// The I2C.write function only allows sending of a single
// byte at a time.
//s7sSendStringI2C("TIMR");
//setDecimalsI2C(0b111111); // Turn on all decimals, colon, apos
// Flash brightness values at the beginning
//setBrightnessI2C(0); // Lowest brightness
//delay(130);
setBrightnessI2C(255); // High brightness
// setBrightnessI2C(105); // med brightness
//delay(150);
//s7sSendStringI2C("TIMR");
//delay(150);
// Clear the display before jumping into loop
//clearDisplayI2C();
/*toggle button*/
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
//pinMode (SPKR,OUTPUT);
// set initial LED state
//digitalWrite(ledPin, ledState);
/*end toggle button*/
}
void loop(){
/*read encoders*/
int delta=0;
n = digitalRead(encoder0PinA);
if ((encoder0PinALast == LOW) && (n == HIGH)) {
if (digitalRead(encoder0PinB) == LOW) {
encoder0Pos++;
delta=1;
} else {
encoder0Pos--;
delta=-1;
}
Serial.print ("B");
Serial.print (encoder0Pos);
Serial.print ("/");
}
if(encoder0PinALast != n) {
StopBeeperAndCountdown();
mins+=delta;//=encoder0Pos;
}
encoder0PinALast = n;
n = digitalRead(encoder1PinA);
if ((encoder1PinALast == LOW) && (n == HIGH)) {
if (digitalRead(encoder1PinB) == LOW) {
encoder1Pos++;
delta = 5;
} else {
encoder1Pos--;
delta = -5;
}
Serial.print ("A");
Serial.print (encoder1Pos);
Serial.print ("/");
}
if(encoder1PinALast != n){
StopBeeperAndCountdown();
secs+=delta;//encoder1Pos*5;
}
encoder1PinALast = n;
if(mins>99)mins=0; //mins
if(mins<0)mins=99;
if(secs>59)secs=0; //secs
if(secs<0)secs=55;
/*read encoders end*/
if(startup){
startup = false;
encoder0Pos = 0;
encoder1Pos = 0;
mins = 0;
secs = 0;
}
// Magical sprintf creates a string for us to send to the s7s.
// The %4d option creates a 4-digit integer.
//sprintf(tempString, "%4d", counter);
//sprintf(tempString, "%s%2d%s%2d",(mins<10)?"":"0", mins,(secs<10)?"":"0",secs);
if(mins>9&&secs>9)sprintf(tempString, "%2d%2d", mins,secs);
if(mins<=9&&secs>9)sprintf(tempString, "0%d%2d", mins,secs);
if(mins>9&&secs<=9)sprintf(tempString, "%2d0%d", mins,secs);
if(mins<9&&secs<=9)sprintf(tempString, "%02d0%d", mins,secs);
if(scan%1000==0){ //only update every so many cycles
// This will output the tempString to the S7S
s7sSendStringI2C(tempString);
}
// Print the decimal at the proper spot
/*
setDecimalsI2C(0b00000100); // Sets digit 3 decimal on
*/
//delay(50); // This will make the display update at 10Hz.*/
scan++;
if(scan > 60000){scan=0;}
if(doCountdown){
if(scan % 5000==0 && !doBeeper){
if(secs >= 0)secs--;
if(secs < 0){
secs = 59;
mins--;
}
if(mins < 0){
secs = 0;
mins = 0;
doCountdown = false;
doBeeper = true;
}
}
}
if(scan % 3000 == 0){
showColon=!showColon;
// [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
if(doCountdown && showColon){//showColon
setDecimalsI2C(0b010000); // Turn on colon
}else{
setDecimalsI2C(0b000000); // hide colon
}
if(doBeeper){
alarm();
}
}
CheckToggleButton();
}
void CheckToggleButton(){
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// 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 (reading != buttonState) {
snick();
if(doCountdown&&doBeeper)StopBeeperAndCountdown();
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
//ledState = !ledState;
doCountdown=!doCountdown;
}
}
}
// set the LED:
//digitalWrite(ledPin, ledState);
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonState = reading;
}
// This custom function works somewhat like a serial.print.
// You can send it an array of chars (string) and it'll print
// the first 4 characters in the array.
void s7sSendStringI2C(String toSend){
Wire.beginTransmission(s7sAddress);
for (int i=0; i<4; i++)
{
Wire.write(toSend[i]);
}
Wire.endTransmission();
}
// Send the clear display command (0x76)
// This will clear the display and reset the cursor
void clearDisplayI2C(){
Wire.beginTransmission(s7sAddress);
Wire.write(0x76); // Clear display command
Wire.endTransmission();
}
// Set the displays brightness. Should receive byte with the value
// to set the brightness to
// dimmest------------->brightest
// 0--------127--------255
void setBrightnessI2C(byte value){
Wire.beginTransmission(s7sAddress);
Wire.write(0x7A); // Set brightness command byte
Wire.write(value); // brightness data byte
Wire.endTransmission();
}
// Turn on any, none, or all of the decimals.
// The six lowest bits in the decimals parameter sets a decimal
// (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
// [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
void setDecimalsI2C(byte decimals){
Wire.beginTransmission(s7sAddress);
Wire.write(0x77);
Wire.write(decimals);
Wire.endTransmission();
}
void snick(){
// put your setup code here, to run once:
pinMode (SPKR,OUTPUT);
for (int i=0; i<300; i++) { // generate a 1KHz tone for 1/2 second
digitalWrite(SPKR, HIGH);
delayMicroseconds(100);
digitalWrite(SPKR, LOW);
delayMicroseconds(100);
}
pinMode (SPKR,INPUT);
//delay(1000);
}
void alarm(){
//return;
// put your setup code here, to run once:
pinMode (SPKR,OUTPUT);
for (int i=0; i<350; i++) {
digitalWrite(SPKR, HIGH);
delayMicroseconds(120);
digitalWrite(SPKR, LOW);
delayMicroseconds(50);
digitalWrite(SPKR, HIGH);
delayMicroseconds(60);
}
pinMode (SPKR,INPUT);
//delay(1000);
}
void StopBeeperAndCountdown(){
doBeeper=false;
doCountdown=false;
//secs=30;
//mins=encoder1Pos*5;
//secs=encoder0Pos*5;
}
Comments