线性时钟源程序

发光二极管

13人已加入

描述

线性时钟源程序:
/*
Linear Clock driver
Written by Sandy Noble (sandy.noble@gmail.com)
This version 8th Jan 2011

This uses the AFMotor library from Adafruit, because I used an Adafruit
Motorshield, and I think Adafruit are the bomb.  Make sure you use a version
of the libraries from after 7th Jan 2011, because there's a little fix in 
them that is important to this code.

This should be fairly simple self-explanatory code.

*/

#include 
#include 

// These set up the motors.  The values here depend on how they've been wired up.
AF_Stepper minuteHand(20, 1); // minutes
int const minutesIncrement = BACKWARD;
int const minutesDecrement = FORWARD;

AF_Stepper hourHand(20, 2); // hours
int const hoursIncrement = FORWARD;
int const hoursDecrement = BACKWARD;

int const stepType = DOUBLE;
int const motorRPM = 150;

int second=0, minute=0, hour=0; // declare time variables

// Minutes setup
int startMinutePos = 0;
// current minute position.  This gets updated all the time.
float currentMinutePos = startMinutePos;
// the current position of the indicators.  This only gets updated when the hands move
int displayMinutePos = startMinutePos;

// Hours setup
int startHourPos = 0;
float currentHourPos = startHourPos;
int displayHourPos = startHourPos;

// These are the actual time, in seconds minutes and hours.  
// doTick() writes these values, and renderTime() reads them.
int currentSeconds = 0;
int currentMinutes = 50;
int currentHours = 11;

int const millisPerSecond = 200;

int const stepsPerClock = 592;

float const stepsPerMinute = stepsPerClock/60.0;
float const stepsPerHourMinute = stepsPerClock/720.0;
float const stepsPerHour = stepsPerClock/12.0;


void setup() 
{

  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("LINEAR CLOCK!");

  hourHand.setSpeed(motorRPM);  // 10 rpm  
  minuteHand.setSpeed(motorRPM);  // 10 rpm   

}

void loop() 
{

  static unsigned long lastTick = 0; // set up a local variable to hold the last time we moved forward one second
  // (static variables are initialized once and keep their values between function calls)

  // move forward one second every 1000 milliseconds
  unsigned long time = millis();
  unsigned long sinceLastTick = time - lastTick;
  
  if (sinceLastTick >=millisPerSecond)
  {
    unsigned int secondsMissed = sinceLastTick / millisPerSecond;
    
    lastTick = millis();

    for (int i = 0; i < secondsMissed; i++)
    {
      doTick();
    }
  }
  renderTime();
}

void doTick()
{
  currentSeconds++;
  if (currentSeconds > 59)
  {
    currentSeconds = 0;
    currentMinutes++;
    if (currentMinutes > 59)
    {
      currentMinutes = 0;
      currentHours++;
      if (currentHours > 11)
      {
        currentHours = 0;
      }
    }
  }
  Serial.print(millis());
  Serial.print(" - tick!");
  Serial.print(currentHours);
  Serial.print(":");
  Serial.print(currentMinutes);
  Serial.print(":");
  Serial.println(currentSeconds);
}

void renderTime()
{
  setTime(currentHours, currentMinutes);
}

void setTime(int hour, int minute)
{
  setHour(hour, minute);
  setMinute(minute);
}

void setHour(int hour, int minute)
{
  // work out the new position and set it globally eg time 4:25.
  // first hours
  // eg 0.2055 * 4 * 60 = 49.333
  float justHours = stepsPerHourMinute * hour * 60;
  // eg 0.2055 * 25 = 5.13888
  float justMinutes = stepsPerHourMinute * minute;
  
  // stick em together: position is 54.472 (4:25)
  currentHourPos = justHours + justMinutes;

  // round to integer
  // eg 54
  int newPos = currentHourPos;

  // save the previous actual position so we can check if the hands need moving
  // eg 52
  int lastPos = displayHourPos;
  
  // now see if the hand position needs to change
  // eg 54 - 52 = 2
  int stepsToChange = newPos - lastPos;
  if (stepsToChange != 0)
  {
    Serial.print("sethour:");
    Serial.println(hour);
    // update the global variable
    displayHourPos = newPos;
    changeHours(stepsToChange);
  }
  
}

void changeHours(int steps)
{
  Serial.print("Incrementing hours position:");
  Serial.println(steps);
  
  // make it positive
  int absSteps = abs(steps);
  
  if (steps < 0)
  {
    // if it's negative, then DECREMENT
    if (absSteps >= 1)
    {
      // only step if it's a full step
      hourHand.step(absSteps, hoursDecrement, stepType);
    }
  }
  else if (steps > 0)
  {
    // if it's positive then INCREMENT
    if (absSteps >= 1)
    {
      // only step if it's a full step
      hourHand.step(absSteps, hoursIncrement, stepType);
    }
  }
  
  Serial.print("Actual current hour position:");
  Serial.println(displayHourPos);
  
  hourHand.release();
}

void setMinute(int minute)
{
  // work out the new position and set it globally
  // eg 2.467 * 25 = 61.675
  currentMinutePos = stepsPerMinute * minute;

  // round to integer
  // eg 61
  int newPos = currentMinutePos;

  // save the previous actual position so we can check if the hands need moving
  // eg 59
  int lastPos = displayMinutePos;
  
  // now see if the hand position needs to change
  // eg 61 - 59 = 2
  int stepsToChange = newPos - lastPos;
  if (stepsToChange != 0)
  {
    Serial.print("setmin:");
    Serial.println(minute);
    // update the global variable
    displayMinutePos = newPos;
    changeMinutes(stepsToChange);
  }
}

void changeMinutes(int steps)
{
  Serial.print("Incrementing minutes position:");
  Serial.println(steps);
  
  // make it positive
  int absSteps = abs(steps);
  
  if (steps < 0)
  {
    // if it's negative, then DECREMENT
    if (absSteps >= 1)
    {
      // only step if it's a full step
      minuteHand.step(absSteps, minutesDecrement, stepType);
    }
  }
  else if (steps > 0)
  {
    // if it's positive then INCREMENT
    if (absSteps >= 1)
    {
      // only step if it's a full step
      minuteHand.step(absSteps, minutesIncrement, stepType);
    }
  }
  
  Serial.print("Actual current minute position:");
  Serial.println(displayMinutePos);
  
  minuteHand.release();
}



#p#副程序2e#程序2:
/*
Linear Clock driver
Written by Sandy Noble (sandy.noble@gmail.com)
This version 8th Jan 2011

This uses the AFMotor library from Adafruit, because I used an Adafruit
Motorshield, and I think Adafruit are the bomb.  Make sure you use a version
of the libraries from after 7th Jan 2011, because there's a little fix in 
them that is important to this code.

This should be fairly simple self-explanatory code.

*/

#include 
#include 
#include 

// These set up the motors.  The values here depend on how they've been wired up.
AF_Stepper minuteHand(20, 1); // minutes
int const minutesIncrement = BACKWARD;
int const minutesDecrement = FORWARD;

AF_Stepper hourHand(20, 2); // hours
int const hoursIncrement = FORWARD;
int const hoursDecrement = BACKWARD;

int const stepType = DOUBLE;
int const motorRPM = 150;

int second=0, minute=0, hour=0; // declare time variables

// Minutes setup
int startMinutePos = 0;
// current minute position.  This gets updated all the time.
float currentMinutePos = startMinutePos;
// the current position of the indicators.  This only gets updated when the hands move
int displayMinutePos = startMinutePos;

// Hours setup
int startHourPos = 0;
float currentHourPos = startHourPos;
int displayHourPos = startHourPos;

// These are the actual time, in seconds minutes and hours.  
// doTick() writes these values, and renderTime() reads them.
int currentSeconds = 0;
int currentMinutes = 0;
int currentHours = 0;

int const millisPerSecond = 1000;

int const stepsPerClock = 592;

float const stepsPerMinute = stepsPerClock/60.0;
float const stepsPerHourMinute = stepsPerClock/720.0;
float const stepsPerHour = stepsPerClock/12.0;

boolean currentlyRunning = false;

Button hourSetButton = Button(9, PULLUP);
Button minuteSetButton = Button(10, PULLUP);
Button modeToggleButton = Button(2, PULLUP);

const int modeIndicatorPin = 13;



void setup() 
{

  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("LINEAR CLOCK!");

  hourHand.setSpeed(motorRPM);  // rpm  
  minuteHand.setSpeed(motorRPM);  // rpm   
  
  pinMode(13, OUTPUT);
  

}

void loop() 
{
  // check if the clock is paused or is running
  if (inRunMode())
  {
    // here we count the seconds and things
    static unsigned long lastTick = 0; // set up a local variable to hold the last time we moved forward one second
    // (static variables are initialized once and keep their values between function calls)
  
    // move forward one second every 1000 milliseconds
    unsigned long time = millis();
    unsigned long sinceLastTick = time - lastTick;
    
    if (sinceLastTick >=millisPerSecond)
    {
      unsigned int secondsMissed = sinceLastTick / millisPerSecond;
      
      lastTick = millis();
  
      for (int i = 0; i < secondsMissed; i++)
      {
        doTick();
      }
    }
  }
  else
  {
    // not in Run mode, so we aren't automatically counting time.  
    // instead we're anticipating getting some button pushes to increment the time.
    if (hourSetTriggered())
    {
      if (currentHours == 11)
        currentHours = 0;
      else
        currentHours ++;
    }
    else if (minuteSetTriggered())
    {
      if (currentMinutes == 59)
        currentMinutes = 0;
      else
        currentMinutes ++;
    }
  }
  renderTime();
}

void doTick()
{
  currentSeconds++;
  if (currentSeconds > 59)
  {
    currentSeconds = 0;
    currentMinutes++;
    if (currentMinutes > 59)
    {
      currentMinutes = 0;
      currentHours++;
      if (currentHours > 11)
      {
        currentHours = 0;
      }
    }
  }
  Serial.print(millis());
  Serial.print(" - tick!");
  Serial.print(currentHours);
  Serial.print(":");
  Serial.print(currentMinutes);
  Serial.print(":");
  Serial.println(currentSeconds);
}

void renderTime()
{
  setTime(currentHours, currentMinutes);
}

void setTime(int hour, int minute)
{
  setHour(hour, minute);
  setMinute(minute);
}

void setHour(int hour, int minute)
{
  // work out the new position and set it globally eg time 4:25.
  // first hours
  // eg 0.2055 * 4 * 60 = 49.333
  float justHours = stepsPerHourMinute * hour * 60;
  // eg 0.2055 * 25 = 5.13888
  float justMinutes = stepsPerHourMinute * minute;
  
  // stick em together: position is 54.472 (4:25)
  currentHourPos = justHours + justMinutes;

  // round to integer
  // eg 54
  int newPos = currentHourPos;

  // save the previous actual position so we can check if the hands need moving
  // eg 52
  int lastPos = displayHourPos;
  
  // now see if the hand position needs to change
  // eg 54 - 52 = 2
  int stepsToChange = newPos - lastPos;
  if (stepsToChange != 0)
  {
    Serial.print("sethour:");
    Serial.println(hour);
    // update the global variable
    displayHourPos = newPos;
    changeHours(stepsToChange);
  }
  
}

void changeHours(int steps)
{
  Serial.print("Incrementing hours position:");
  Serial.println(steps);
  
  // make it positive
  int absSteps = abs(steps);
  
  if (steps < 0)
  {
    // if it's negative, then DECREMENT
    if (absSteps >= 1)
    {
      // only step if it's a full step
      hourHand.step(absSteps, hoursDecrement, stepType);
    }
  }
  else if (steps > 0)
  {
    // if it's positive then INCREMENT
    if (absSteps >= 1)
    {
      // only step if it's a full step
      hourHand.step(absSteps, hoursIncrement, stepType);
    }
  }
  
  Serial.print("Actual current hour position:");
  Serial.println(displayHourPos);
  
  hourHand.release();
}

void setMinute(int minute)
{
  // work out the new position and set it globally
  // eg 2.467 * 25 = 61.675
  currentMinutePos = stepsPerMinute * minute;

  // round to integer
  // eg 61
  int newPos = currentMinutePos;

  // save the previous actual position so we can check if the hands need moving
  // eg 59
  int lastPos = displayMinutePos;
  
  // now see if the hand position needs to change
  // eg 61 - 59 = 2
  int stepsToChange = newPos - lastPos;
  if (stepsToChange != 0)
  {
    Serial.print("setmin:");
    Serial.println(minute);
    // update the global variable
    displayMinutePos = newPos;
    changeMinutes(stepsToChange);
  }
}

void changeMinutes(int steps)
{
  Serial.print("Incrementing minutes position:");
  Serial.println(steps);
  
  // make it positive
  int absSteps = abs(steps);
  
  if (steps < 0)
  {
    // if it's negative, then DECREMENT
    if (absSteps >= 1)
    {
      // only step if it's a full step
      minuteHand.step(absSteps, minutesDecrement, stepType);
    }
  }
  else if (steps > 0)
  {
    // if it's positive then INCREMENT
    if (absSteps >= 1)
    {
      // only step if it's a full step
      minuteHand.step(absSteps, minutesIncrement, stepType);
    }
  }
  
  Serial.print("Actual current minute position:");
  Serial.println(displayMinutePos);
  
  minuteHand.release();
}

boolean inRunMode()
{
  // observe the buttons
  modeToggleButton.isPressed();
  if (modeToggleButton.stateChanged())
  {
    if (modeToggleButton.wasPressed())
    {
      // a previously HIGH button has gone low (been released)
      // so flip modes
      
      if (currentlyRunning)
      {
        Serial.println("CLOCK PAUSED");
        currentlyRunning = false;
      }
      else
      {
        Serial.println("CLOCK RUNNING");
        currentlyRunning = true;
      }
    }
  }
  
  if (currentlyRunning)
    digitalWrite(modeIndicatorPin, LOW);
  else
    digitalWrite(modeIndicatorPin, HIGH);
  
  return currentlyRunning;
}

boolean hourSetTriggered()
{
  hourSetButton.isPressed();
  if (hourSetButton.stateChanged() && hourSetButton.wasPressed())
  {
    Serial.println("Hour set button.");
    return true;
  }
  else
    return false;
}
boolean minuteSetTriggered()
{
  minuteSetButton.isPressed();
  if (minuteSetButton.stateChanged() && minuteSetButton.wasPressed())
  {
    Serial.println("Minute set button.");
    return true;
  }
  else 
    return false;
}
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分