sakis Kountourgiotis
Published

Hacking Your Arduino mini Pro SmartWatch

Following this steps you can reprogram your watch using the Arduino™ IDE software.

BeginnerFull instructions provided2 hours925
Hacking Your Arduino mini Pro SmartWatch

Things used in this project

Hardware components

Solder Time II Watch kit
×1
Wilderness Labs Pin Header 1x40 Male Right Angle
×1
FTDI Cable 5V VCC-3.3V
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

ST2Schematic

Code

ST2_Routines

Arduino
//*******************************************************************************************************************
// 								                        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.

Credits

sakis Kountourgiotis

sakis Kountourgiotis

1 project • 3 followers
More than 13 years experience in programming and application development.

Comments