Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
Hand tools and fabrication machines | ||||||
|
The Story is about a Arduino based SmartWatch Called Solder Time II.
Solder Time II is even more hackable than ever. The on board microcontroller in this model is the very popular ATmega328P used in many of the current versions of Arduino™. In fact, you can reprogram your watch using the same Arduino™ IDE software that you use for a regular Arduino.
If you want you can buy this watch kit from here .
If you already purchased, follow this steps to change the scrolling text of the screen or add more new features to your watch.
STEP 1Solder the Pin Header Strip to the mainboard ( 6 pins you need for this step).
You have to remove alarm buzzer first if you already solder the alarm buzzer to the main board.
Connect the ftdi cable.
Install ftdi cable usb drivers.
you can download the drivers from here
"You can manually install usb cable drivers from windows device manager"
Open the arduino IDE and select the Communication port.
The ST2 sketch uses a library called TimerOne. More information can be found here on the Arduino Playground web pages. The latest version can be download is here, and the version used in the standard production release of the ST2 can be downloaded here;
Download: TimerOne Library
Once downloaded, unzip it and add it to the library folder in your Arduino sketch folder. Quit your Arduino IDE if it is open and relaunch it.
To compile and upload sketches to the ST2 from within the Arduino IDE menu Tools/Board, choose “Arduino Pro or Pro Mini (3.3v 8Mhz) w/ATmega328” as the board type. You must choose this version since the ST2 is using the internal 8mhz oscillator as a processor clock source.
The actual sketch is made up of eight files divided it into parts because it was getting too long to scroll the mouse up and down the list of code as it was being programmed. (The files could be combined back into one file.) “ST_Two_Release” is the file you should open first, the other will appear along the top of the window in tabs.
Download the code : Solder : Time II Sketch v1.1
If you want to change the scrolling message change the "string text" to the yellow line below.
The result:
Hacking and Re-programming: Advanced
TWI - I2C:
Currently the I2C pins are not broken out into a connector, but there is an I2C bus used to communicate with the RTC chip... you could attache your own I2C devices to this bus. For example an EEPROM, temperature sensor, port expander, etc... (I2C pull-up resistors (10k ohm) are already on the ST2 board.)
Analog pins:
The creator used all of the standard Arduino analog pins as digital I/O pins, but on the ATmega328P-AU there are another two analog only pins (ADC6 and ADC7) that are not used on the ST2.
//*******************************************************************************************************************
// Helper - State incrementor
//*******************************************************************************************************************
// Increments the Main state to the next state upto MAXSTATE
// If you add more States increase MAXSTATE to match.
void NextState()
{
STATE = STATE + 1;
SUBSTATE = 0;
NextStateRequest = false;
if(STATE > MAXSTATE)
{
STATE = 0;
SUBSTATE = 0;
}
}
//*******************************************************************************************************************
// Beep the piezo
//*******************************************************************************************************************
// NOTE: the piezo uses the same pin as the SET Button input
// This routine switches the pin to an output during the beeping process
// (There is a current limited resistor on the board to prevent over current if the Set Button is pressed at
// the same time as the pin is driving the piezo.)
void beepsound(int freq, int freqlenght)
{
// freq was 4000
// freqlenght was 100
pinMode(SETBUTTON, OUTPUT);
tone(SETBUTTON,freq,freqlenght);
delay(freqlenght);
noTone(SETBUTTON);
digitalWrite(SETBUTTON, HIGH);
#if ARDUINO >= 101
pinMode(SETBUTTON, INPUT_PULLUP);
// digitalWrite(SETBUTTON, HIGH);
#else
// digitalWrite(SETBUTTON, HIGH);
pinMode(SETBUTTON, INPUT);
#endif
}
//*******************************************************************************************************************
// Display Time Routine
//*******************************************************************************************************************
void DisplayTimeSub()
{
if(NextStateRequest)
{
SUBSTATE =99;
}
if(NextSUBStateRequest)
{
SUBSTATE = SUBSTATE +1;
if(SUBSTATE>4)
{
SUBSTATE =1;
}
NextSUBStateRequest = false;
}
UpdateTime = UpdateTime + 1;
if(UpdateTime > 2000)
{
checktime();
checkDate();
UpdateTime = 0;
}
switch (SUBSTATE)
{
case 0: // Start Display Time
SUBSTATE = 1;
blinkON = true;
blinkFlag = false;
blinkMin = false;
blinkHour = false;
checktime();
checkDate();
if(!JustWokeUpFlag2)
{
displayString("Time");
}
else
{
JustWokeUpFlag2 = false;
}
delay(250);
break;
case 1: // Time
// checktime();
writeTime(HourTens, HourOnes, MinTens, MinOnes);
break;
case 2: // Day
// checkDate();
displayStringDay(Days -1);
break;
case 3: // Month
// checkDate();
displayMonth(MonthCode-1);
break;
case 4: // Date
// checkDate();
displayDate();
delay(100);
break;
case 5: // Year
break;
case 99: // Exit Display Time
NextState();
clearmatrix();
break;
}
}
//*******************************************************************************************************************
// SET Time Routine
//*******************************************************************************************************************
void setTimeSub()
{
switch (SUBSTATE)
{
case 0: // Start SET Time
clearmatrix();
displayString("Set?");
SUBSTATE = 1;
NextSUBStateRequest = false;
break;
case 1: // Ask user if they want to set time
if(NextSUBStateRequest)
{
SUBSTATE = 2;
NextSUBStateRequest = false;
blinkFlag = true;
}
if(NextStateRequest)
{
SUBSTATE =99;
NextStateRequest = false;
}
break;
case 2: // Minute + one
// displayString("----");
blinkMin = true;
writeTime(HourTens, HourOnes, MinTens, MinOnes);
if(NextSUBStateRequest)
{
settimeNEW(1);
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
blinkMin = false;
SUBSTATE =3;
NextStateRequest = false;
}
break;
case 3: // Hours + one
blinkHour = true;
writeTime(HourTens, HourOnes, MinTens, MinOnes);
if(NextSUBStateRequest)
{
settimeNEW(2);
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
blinkHour = false;
SUBSTATE =4;
NextStateRequest = false;
}
break;
case 4: // Day + one
displayStringDay(Days -1);
if(NextSUBStateRequest)
{
settimeNEW(3);
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
SUBSTATE =5;
NextStateRequest = false;
}
break;
case 5: // Month + one
displayMonth(MonthCode-1);
if(NextSUBStateRequest)
{
settimeNEW(4);
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
SUBSTATE =6;
NextStateRequest = false;
}
break;
case 6: // Date + one
displayDate();
if(NextSUBStateRequest)
{
settimeNEW(5);
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
SUBSTATE =8;
NextStateRequest = false;
}
break;
/*
case 7: // Year + one ** NOTE: not used
displayString("Year");
if(NextSUBStateRequest)
{
settimeNEW(6);
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
SUBSTATE =8;
NextStateRequest = false;
}
break;
*/
case 8:
NewTimeFormate = TH_Not24_flag; // Pre-set before toggle
SUBSTATE =9;
break;
case 9: // Select 12 or 24 hour clock
if(NewTimeFormate)
{
displayString("12 h");
}
else
{
displayString("24 h");
}
if(NextSUBStateRequest)
{
NewTimeFormate = !NewTimeFormate;
NextSUBStateRequest = false;
TwelveTwentyFourConvert();
A_TH_Not24_flag = NewTimeFormate;
}
if(NextStateRequest)
{
SUBSTATE =99;
NextStateRequest = false;
}
break;
case 99: // Exit Set Time
blinkFlag = false;
NextState();
clearmatrix();
break;
}
}
//*******************************************************************************************************************
// SET Alarm Routine
//*******************************************************************************************************************
void setAlarmSub()
{
switch (SUBSTATE)
{
case 0: // Start SET Alarm
clearmatrix();
displayString("ALM?");
SUBSTATE = 1;
NextSUBStateRequest = false;
break;
case 1: // Ask user if they want to set Alarm
if(NextSUBStateRequest)
{
// displayString("A ON");
// delay(250);
// ALARMON = true;
SUBSTATE = 2;
NextSUBStateRequest = false;
blinkFlag = true;
}
if(NextStateRequest)
{
// displayString("AOFF");
// delay(500);
// EnableAlarm1(false);
// ALARMON = false;
SUBSTATE =99;
NextStateRequest = false;
}
break;
case 2:
blinkMin = true;
writeTime(AHourTens, AHourOnes, AMinTens, AMinOnes);
if(NextSUBStateRequest)
{
setAlarm(1);
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
blinkMin = false;
SUBSTATE =3;
NextStateRequest = false;
}
break;
case 3:
blinkHour = true;
writeTime(AHourTens, AHourOnes, AMinTens, AMinOnes);
if(NextSUBStateRequest)
{
setAlarm(2);
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
blinkMin = false;
SUBSTATE =4;
NextStateRequest = false;
// EnableAlarm1(true);
}
break;
case 4:
if(ALARMON)
{
// displayString("A ON");
displayGraphic(1,0,5);
displayGraphic(2,5,5);
displayGraphic(0,10,4);
displayGraphic(3,14,5);
}
else
{
// displayString("AOFF");
displayGraphic(1,0,5);
displayGraphic(2,5,5);
displayGraphic(0,10,4);
displayGraphic(4,14,5);
}
if(NextSUBStateRequest)
{
ALARMON = !ALARMON;
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
blinkMin = false;
SUBSTATE =99;
NextStateRequest = false;
if(ALARMON)
{
EnableAlarm1(true);
}
else
{
EnableAlarm1(false);
}
}
break;
case 99: // Exit Set Alarm
blinkFlag = false;
NextState();
clearmatrix();
break;
}
}
//*******************************************************************************************************************
// Stop Watch
//*******************************************************************************************************************
void StopWatch()
{
switch (SUBSTATE)
{
case 0: // Stop Watch Set-up
OldTime = 0;
CurrentTime = 0;
TotalTime = 0;
SWDigit4 = 0;
SWDigit3 = 0;
SWDigit2 = 0;
SWDigit1 = 0;
blinkON = true;
blinkFlag = false;
blinkMin = false;
blinkHour = false;
SUBSTATE = 1;
NextSUBStateRequest = false;
displayString("Stop");
delay(500);
clearmatrix();
writeTime(SWDigit4, SWDigit3, SWDigit2, SWDigit1);
break;
case 1: // Waiting for "Start" button to be pressed
writeTime(SWDigit4, SWDigit3, SWDigit2, SWDigit1);
if(NextSUBStateRequest)
{
SUBSTATE = 2;
NextSUBStateRequest = false;
SleepEnable = false;
currentMillis = millis();
SleepTimer = currentMillis; // Using Long SleepTimer variable for timing not sleep
}
if(NextStateRequest)
{
SUBSTATE =99;
NextStateRequest = false;
}
break;
case 2: // Stop Watch Running
// I2C_RX(RTCDS1337,RTC_SEC);
// CurrentTime =i2cData & B00001111;
currentMillis = millis();
if((currentMillis - SleepTimer) >= 1000)
{
// OldTime = CurrentTime;
SleepTimer = currentMillis;
TotalTime = TotalTime + 1;
if(TotalTime > 5999) // Over 99 minutes can "not" be displayed (60seconds x 99 = 5940)
{
TotalTime = 0;
}
}
// Convert Total Time to digits
SWMINUTES = TotalTime / 60;
SWSECONDS = TotalTime % 60;
SWDigit4 = SWMINUTES / 10;
SWDigit3 = SWMINUTES % 10;
SWDigit2 = SWSECONDS / 10;
SWDigit1 = SWSECONDS % 10;
writeTime(SWDigit4, SWDigit3, SWDigit2, SWDigit1);
if(NextSUBStateRequest)
{
SUBSTATE = 1;
NextSUBStateRequest = false;
SleepEnable = true;
}
if(NextStateRequest)
{
SUBSTATE =99;
NextStateRequest = false;
}
break;
/*
// Not using this RTC version since it seems too power hungery due to constant I2C polling
case 2: // Stop Watch Running
I2C_RX(RTCDS1337,RTC_SEC);
CurrentTime =i2cData & B00001111;
if(CurrentTime != OldTime)
{
OldTime = CurrentTime;
TotalTime = TotalTime + 1;
if(TotalTime > 5940) // Over 99 minutes can "not" be displayed (60seconds x 99 = 5940)
{
TotalTime = 0;
}
}
// Convert Total Time to digits
SWMINUTES = TotalTime / 60;
SWSECONDS = TotalTime % 60;
SWDigit4 = SWMINUTES / 10;
SWDigit3 = SWMINUTES % 10;
SWDigit2 = SWSECONDS / 10;
SWDigit1 = SWSECONDS % 10;
writeTime(SWDigit4, SWDigit3, SWDigit2, SWDigit1);
if(NextSUBStateRequest)
{
SUBSTATE = 1;
NextSUBStateRequest = false;
SleepEnable = true;
}
if(NextStateRequest)
{
SUBSTATE =99;
NextStateRequest = false;
}
break;
*/
case 99: // Exit Stop Watch Function
NextState();
clearmatrix();
SleepEnable = true;
break;
}
}
//*******************************************************************************************************************
// Display Serial Data
//*******************************************************************************************************************
void DisplaySerialData()
{
int temp =0;
switch (SUBSTATE)
{
case 0: // Display Set-up
ResetScrollMessage();
NextSUBStateRequest = false;
NextStateRequest = false;
OptionModeFlag = false;
displayString("Text");
delay(250);
GETFROMEEPROM();
if(IncomingMessIndex == 0 | IncomingMessIndex > 27)
{
MessagePointer = 0;
SUBSTATE =3;
char Str2[] = "put your text here";
for(int i =0; i <= sizeof(Str2); i ++) // Show default Scrolling message
{
IncomingMessage[i] = Str2[i];
IncomingMessIndex = i;
}
}
else
{
MessagePointer= 0;
SUBSTATE = 3;
SleepEnable = true;
}
break;
case 1:
if(NextSUBStateRequest)
{
ResetScrollMessage();
SUBSTATE = 2;
NextSUBStateRequest = false;
power_usart0_enable();
Serial.begin(57600);
SleepEnable = false;
}
if(NextStateRequest)
{
SUBSTATE =99;
NextStateRequest = false;
}
break;
// break;
case 2: // Receive Serial
clearmatrix();
// LED MATRIX
//
// Port C: C0 to C3 set to high. Columns 17 to 20 of LED matrix - Cathode connection
PORTC = (PORTC & B11110000) | B00001111;
// Port B: Unselect the MUX chip
PORTB = (1<<PORTB7);
// Port B: Set all the ROWs to high: High on both cathode and annode = no current ?
PORTB = PORTB | B01111111; // Could be PORTB =B11111111;
Timer1.detachInterrupt();
shortloop:
if(Serial.available()>0)
{
MessageRead = Serial.read();
if(IncomingMessIndex<24)
{
IncomingMessage[IncomingMessIndex] = MessageRead;
// IncomingMessIndex = IncomingMessIndex + 1;
IncomingMessIndex++;
// IncomingMessage[IncomingMessIndex] = '\0';
Serial.print(MessageRead);
}
}
bval = !digitalRead(SETBUTTON);
if(!bval)
{
goto shortloop;
}
else
{
Timer1.attachInterrupt(LEDupdateTWO);
while(bval)
{
bval = !digitalRead(SETBUTTON);
}
delay(100);
}
if(IncomingMessIndex == 0)
{
SUBSTATE = 99;
}
else
{
SUBSTATE = 3;
FILLEEPROM();
OptionModeFlag = false;
}
SleepTimer = millis();
SleepEnable = true;
Serial.end();
power_usart0_disable();
break;
case 3:
for(int i = 0;i<=IncomingMessIndex-1;i ++)
{
TEXT = IncomingMessage[i]-32;
for(int y =0;y<5;y++)
{
Message[MessagePointer] = LETTERS[TEXT][y];
MessagePointer = MessagePointer +1;
}
Message[MessagePointer] = 0; // One space between words
MessagePointer = MessagePointer +1;
IncomingMax = MessagePointer;
}
for(int i = 0;i<20;i ++) // 20 spaces between phrases
{
Message[MessagePointer] = 0;
MessagePointer = MessagePointer +1;
IncomingMax = MessagePointer;
}
SUBSTATE = 4;
ScrollLoops = 3;
SleepEnable = true;
break;
// ==================================================================================================
case 4:
scrollCounter = scrollCounter +1;
if(scrollCounter>scrollSpeed)
{
if(ScrollLoops > 0)
{
SleepTimer = millis();
}
IncomingIndex = StartWindow;
for(int i=0;i<20;i++)
{
LEDMAT[i] = Message[IncomingIndex];
IncomingIndex = IncomingIndex + 1;
if(IncomingIndex>IncomingMax)
{
IncomingIndex = 0; // Rolled over end of message
// ScrollLoops = ScrollLoops - 1; // Used to extend number of messages to scroll before sleep mode reqctivated
}
}
StartWindow = StartWindow + 1;
if(StartWindow>IncomingMax)
{
StartWindow = 0;
ScrollLoops = ScrollLoops - 1; // Used to extend number of messages to scroll before sleep mode reqctivated
}
scrollCounter= 0;
}
if(NextSUBStateRequest)
{
scrollSpeed = scrollSpeed + 50;
if(scrollSpeed>400)
{
scrollSpeed = 100;
}
scrollCounter= 0;
NextSUBStateRequest = false;
}
if(NextStateRequest)
{
SUBSTATE =99;
NextStateRequest = false;
}
if(OptionModeFlag)
{
SUBSTATE =1;
displayString("NEW?");
delay(250);
}
break;
case 99: // Exit Stop Watch Function
Serial.end();
power_usart0_disable();
NextState();
clearmatrix();
SleepEnable = true;
break;
}
}
void ResetScrollMessage()
{
IncomingIndex = 0;
IncomingMax = 0;
MessagePointer = 0;
IncomingMessIndex =0;
StartWindow = 0;
IncomingLoaded = 0;
scrollCounter = 0;
for(int i =0;i<275;i++)
{
Message[i] = 0;
}
for(int i =0;i<24;i++)
{
IncomingMessage[i] = 0;
}
}
//*******************************************************************************************************************
// Graphic Animation
//*******************************************************************************************************************
void graphican()
{
int temp =0;
// int rand = 0;
switch (SUBSTATE)
{
case 0:
SUBSTATE =1;
scrollCounter = 0;
scrollSpeed = 200;
// soundeffect = false;
y = 3;
target = 1;
targdist = 0;
displayString("Worm");
delay(250);
break;
case 1:
if(scrollCounter>scrollSpeed)
{
c= c +1;
if(c>19)
{
c = 0;
}
// --
if(NextSUBStateRequest)
{
target = target +1;
if(target> 3)
{
target = 0;
// targdir = false;
targdist = 0;
}
NextSUBStateRequest = false;
}
if(targdir)
{ // Going up
if(targdist == target)
{
targdir = !targdir;
targdist = - target;
if(soundeffect)
{
beepsound(4000,10);
}
}
else
{
targdist = targdist +1;
y = 3 - targdist;
}
}
else
{ // Going Down
if(targdist == target)
{
targdir = !targdir;
targdist = - target;
if(soundeffect)
{
beepsound(5000,10);
}
}
else
{
targdist = targdist +1;
y = 3 + targdist;
}
}
bitSet(temp, y);
// --
LEDMAT[c] = temp;
if((c-wormlenght)<0)
{
LEDMAT[19-((wormlenght-1)-c)] = 0;
}
else
{
LEDMAT[c-wormlenght] = 0;
}
scrollCounter = 0;
}
if(NextStateRequest)
{
SUBSTATE =99;
NextStateRequest = false;
}
if(OptionModeFlag)
{
soundeffect = !soundeffect;
}
scrollCounter = scrollCounter +1;
break;
case 99: // Exit Graphic Function
NextState();
clearmatrix();
break;
}
}
//*******************************************************************************************************************
// LED tester
//*******************************************************************************************************************
void lamptest()
{
int lamptestspeed = 250;
clearmatrix();
bval = !digitalRead(SETBUTTON);
if(bval)
{
do
{
// clearmatrix();
for(int i = 0; i<20;i++)
{
for(int y = 0; y<8;y++)
{
bitSet(LEDMAT[i],y);
delay(lamptestspeed / 10);
bval = !digitalRead(SETBUTTON);
if(bval)
{
lamptestspeed = lamptestspeed -1;
if(lamptestspeed== 0)
...
This file has been truncated, please download it to see its full contents.
Comments