Pages: [1]   Go Down
Author Topic: DateTime library  (Read 719 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've been working on a program that displays the current time and date on a Sure Electronics 24x16 display. The day of week, month, date, and year are display are constantly scrolling across the top of the display while the time is displayed on the bottom. When I start it up and sync it with the current PC time everything goes great. I can connect it to a battery of wall wort and let it do its thing.  After about five minutes it will go blank or the time will be reset.  The same thing happens when I leave it connected usb to the PC.  Can anyone tell me whats going on?  I feel the way I'm running the code interferes with the clock code going on in the background.  Can anyone give me any advice?  Ill post my code below...

Code:
/***********************************************************************
 * demo16x24.c - Arduino demo program for Holtek HT1632 LED driver chip,
 *            As implemented on the Sure Electronics DE-DP016 display board
 *            (16*24 dot matrix LED module.)
 * Nov, 2008 by Bill Westfield ("WestfW")
 *   Copyrighted and distributed under the terms of the Berkely license
 *   (copy freely, but include this notice of original author.)
 ***********************************************************************/
#include <DateTime.h>
#include <DateTimeStrings.h>
#include <WString.h>                // include the String library
#include "ht1632.h"
#include <avr/pgmspace.h>
#include "font.h"

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  255

#define maxLength 40
#define X_MAX 23
#define Y_MAX 15

#define ASSERT(condition) //nothing

/*
 * Set these constants to the values of the pins connected to the SureElectronics Module
 */
static const byte ht1632_data = 10;  // Data pin (pin 7)
static const byte ht1632_wrclk = 11; // Write clock pin (pin 5)
static const byte ht1632_cs = 12;    // Chip Select (1, 2, 3, or 4)

// There should also be a common GND.
// The module with all LEDs like draws about 200mA,
//  which makes it PROBABLY powerable via Arduino +5V


#define DEMOTIME 10000  // 30 seconds max on each demo is enough.
#define DISPDELAY 40    // Each "display" lasts this long
#define LONGDELAY 1000  // This delay BETWEEN demos
String inString = String(maxLength);       // allocate a new String


/***********************************************************************
 * ht1632_chipselect / ht1632_chipfree
 * Select or de-select a particular ht1632 chip.
 * De-selecting a chip ends the commands being sent to a chip.
 * CD pins are active-low; writing 0 to the pin selects the chip.
 ***********************************************************************/

void ht1632_chipselect(byte chipno)
{
  DEBUGPRINT("\nHT1632(%d) ", chipno);
  digitalWrite(chipno, 0);
}

void ht1632_chipfree(byte chipno)
{
  DEBUGPRINT(" [done %d]", chipno);
  digitalWrite(chipno, 1);
}


/*
 * ht1632_writebits
 * Write bits (up to 8) to h1632 on pins ht1632_data, ht1632_wrclk
 * Chip is assumed to already be chip-selected
 * Bits are shifted out from MSB to LSB, with the first bit sent
 * being (bits & firstbit), shifted till firsbit is zero.
 */
void ht1632_writebits (byte bits, byte firstbit)
{
  DEBUGPRINT(" ");
  while (firstbit) {
    DEBUGPRINT((bits&firstbit ? "1" : "0"));
    digitalWrite(ht1632_wrclk, LOW);
    if (bits & firstbit) {
      digitalWrite(ht1632_data, HIGH);
    }
    else {
      digitalWrite(ht1632_data, LOW);
    }
    digitalWrite(ht1632_wrclk, HIGH);
    firstbit >>= 1;
  }
}

/*
 * ht1632_sendcmd
 * Send a command to the ht1632 chip.
 * A command consists of a 3-bit "CMD" ID, an 8bit command, and
 * one "don't care bit".
 *   Select 1 0 0 c7 c6 c5 c4 c3 c2 c1 c0 xx Free
 */
static void ht1632_sendcmd (byte command)
{
  ht1632_chipselect(ht1632_cs);  // Select chip
  ht1632_writebits(HT1632_ID_CMD, 1<<2);  // send 3 bits of id: COMMMAND
  ht1632_writebits(command, 1<<7);  // send the actual command
  ht1632_writebits(0, 1);       /* one extra dont-care bit in commands. */
  ht1632_chipfree(ht1632_cs); //done
}

/*
 * ht1632_senddata
 * send a nibble (4 bits) of data to a particular memory location of the
 * ht1632.  The command has 3 bit ID, 7 bits of address, and 4 bits of data.
 *    Select 1 0 1 A6 A5 A4 A3 A2 A1 A0 D0 D1 D2 D3 Free
 * Note that the address is sent MSB first, while the data is sent LSB first!
 * This means that somewhere a bit reversal will have to be done to get
 * zero-based addressing of words and dots within words.
 */
static void ht1632_senddata (byte address, byte data)
{
  ht1632_chipselect(ht1632_cs);  // Select chip
  ht1632_writebits(HT1632_ID_WR, 1<<2);  // send ID: WRITE to RAM
  ht1632_writebits(address, 1<<6); // Send address
  ht1632_writebits(data, 1<<3); // send 4 bits of data
  ht1632_chipfree(ht1632_cs); // done
}

void ht1632_setup()
{
  pinMode(ht1632_cs, OUTPUT);
  digitalWrite(ht1632_cs, HIGH);       /* unselect (active low) */
  pinMode(ht1632_wrclk, OUTPUT);
  pinMode(ht1632_data, OUTPUT);
  ht1632_sendcmd(HT1632_CMD_SYSDIS);  // Disable system
  ht1632_sendcmd(HT1632_CMD_COMS11);  // 16*32, PMOS drivers
  ht1632_sendcmd(HT1632_CMD_MSTMD);       /* Master Mode */
  ht1632_sendcmd(HT1632_CMD_SYSON);       /* System on */
  ht1632_sendcmd(HT1632_CMD_LEDON);       /* LEDs on */
  for (byte i=0; i<96; i++)
    ht1632_senddata(i, 0);  // clear the display!
  delay(LONGDELAY);
}

/*
 * we keep a copy of the display controller contents so that we can
 * know which bits are on without having to (slowly) read the device.
 * Note that we only use the low four bits of the shadow ram, since
 * we're shadowing 4-bit memory.  This makes things faster, and we
 * use the other half for a "snapshot" when we want to plot new data
 * based on older data...
 */
byte ht1632_shadowram[96];  // our copy of the display's RAM

/*
 * plot a point on the display, with the upper left hand corner
 * being (0,0), and the lower right hand corner being (23, 15).
 * Note that Y increases going "downward" in contrast with most
 * mathematical coordiate systems, but in common with many displays
 * No error checking; bad things may happen if arguments are out of
 * bounds!  (The ASSERTS compile to nothing by default
 */
void ht1632_plot (char x, char y, char val)
{
  char addr, bitval;

  ASSERT(x >= 0);
  ASSERT(x <= X_MAX);
  ASSERT(y >= 0);
  ASSERT(y <= y_MAX);
  if(y < 0 || y > Y_MAX || x < 0 || x > X_MAX){
    return;
  }

  /*
   * The 4 bits in a single memory word go DOWN, with the LSB
   * (first transmitted) bit being on top.  However, writebits()
   * sends the MSB first, so we have to do a sort of bit-reversal
   * somewhere.  Here, this is done by shifting the single bit in
   * the opposite direction from what you might expect.
   */
  bitval = 8>>(y&3);  // compute which bit will need set
  addr = (x<<2) + (y>>2);  // compute which memory word this is in
  if (val) {  // Modify the shadow memory
    ht1632_shadowram[addr] |= bitval;
  }
  else {
    ht1632_shadowram[addr] &= ~bitval;
  }
  // Now copy the new memory value to the display
  ht1632_senddata(addr, ht1632_shadowram[addr]);
}

/*
 * get_shadowram
 * return the value of a pixel from the shadow ram.
 */
byte get_shadowram(byte x, byte y)
{
  byte addr, bitval;

  bitval = 8>>(y&3);  // compute which bit will need set
  addr = (x<<2) + (y>>2);  // compute which memory word this is in
  return (0 != (ht1632_shadowram[addr] & bitval));
}


/*
 * snapshot_shadowram
 * Copy the shadow ram into the snapshot ram (the upper bits)
 * This gives us a separate copy so we can plot new data while
 * still having a copy of the old data.  snapshotram is NOT
 * updated by the plot functions (except "clear")
 */
void snapshot_shadowram()
{
  for (char i=0; i< sizeof ht1632_shadowram; i++) {
    ht1632_shadowram[i] = (ht1632_shadowram[i] & 0x0F) | ht1632_shadowram[i] << 4;  // Use the upper bits
  }
}

/*
 * get_snapshotram
 * get a pixel value from the snapshot ram (instead of
 * the actual displayed (shadow) memory
 */
byte get_snapshotram(byte x, byte y)
{
  byte addr, bitval;

  bitval = 128>>(y&3);  // user upper bits!
  addr = (x<<2) + (y>>2);  // compute which memory word this is in
  if (ht1632_shadowram[addr] & bitval)
    return 1;
  return 0;
}

/*
 * ht1632_clear
 * clear the display, and the shadow memory, and the snapshot
 * memory.  This uses the "write multiple words" capability of
 * the chipset by writing all 96 words of memory without raising
 * the chipselect signal.
 */
void ht1632_clear()
{
  char i;

  ht1632_chipselect(ht1632_cs);  // Select chip
  ht1632_writebits(HT1632_ID_WR, 1<<2);  // send ID: WRITE to RAM
  ht1632_writebits(0, 1<<6); // Send address
  for (i = 0; i < 96/2; i++) // Clear entire display
    ht1632_writebits(0, 1<<7); // send 8 bits of data
  ht1632_chipfree(ht1632_cs); // done
  for (i=0; i < 96; i++)
    ht1632_shadowram[i] = 0;
}

/***********************************************************************
 * plotting routines built on top of "dot" capabiliy of ht1632_plot().
 * Code past here is not particularly dependent on the underlying
 * graphics hardware
 ***********************************************************************/

#define plot(x,y,v)  ht1632_plot(x,y,v)
#define cls          ht1632_clear

// End part One
« Last Edit: October 21, 2009, 07:18:17 pm by spam21 » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is part two.

Code:
Begin Part Two
/*
 * Draw a line between two points using the bresenham algorithm.
 * This particular bit of code is copied nearly verbatim from
 *   http://www.gamedev.net/reference/articles/article1275.asp
 * I don't like it much (too many local variables!), but it works,
 * and is fully explained at the site, so...
 */
void bres_line(byte x1, byte y1,   byte x2, byte y2,  byte val )
{
  char deltax = abs(x2 - x1);        // The difference between the x's
  char deltay = abs(y2 - y1);        // The difference between the y's
  char x = x1;                       // Start x off at the first pixel
  char y = y1;                       // Start y off at the first pixel
  char xinc1, xinc2, yinc1, yinc2, den, num, numadd, numpixels, curpixel;

  if (x2 >= x1) {                // The x-values are increasing
    xinc1 = 1;
    xinc2 = 1;
  }  
  else {                          // The x-values are decreasing
    xinc1 = -1;
    xinc2 = -1;
  }

  if (y2 >= y1)                 // The y-values are increasing
  {
    yinc1 = 1;
    yinc2 = 1;
  }
  else                          // The y-values are decreasing
  {
    yinc1 = -1;
    yinc2 = -1;
  }

  if (deltax >= deltay)         // There is at least one x-value for every y-value
  {
    xinc1 = 0;                  // Don't change the x when numerator >= denominator
    yinc2 = 0;                  // Don't change the y for every iteration
    den = deltax;
    num = deltax / 2;
    numadd = deltay;
    numpixels = deltax;         // There are more x-values than y-values
  }
  else                          // There is at least one y-value for every x-value
  {
    xinc2 = 0;                  // Don't change the x for every iteration
    yinc1 = 0;                  // Don't change the y when numerator >= denominator
    den = deltay;
    num = deltay / 2;
    numadd = deltax;
    numpixels = deltay;         // There are more y-values than x-values
  }

  for (curpixel = 0; curpixel <= numpixels; curpixel++)
  {
    plot(x, y, val);             // Draw the current pixel
    num += numadd;              // Increase the numerator by the top of the fraction
    if (num >= den)             // Check if numerator >= denominator
    {
      num -= den;               // Calculate the new numerator value
      x += xinc1;               // Change the x as appropriate
      y += yinc1;               // Change the y as appropriate
    }
    x += xinc2;                 // Change the x as appropriate
    y += yinc2;                 // Change the y as appropriate
  }
}


/*
 * Copy a character glyph from the myfont data structure to
 * display memory, with its upper left at the given coordinate
 * This is unoptimized and simply uses plot() to draw each dot.
 */
void ht1632_putchar(byte x, byte y, char c)
{
  byte dots;
  if (c >= 'A' && c <= 'Z' ||
    (c >= 'a' && c <= 'z') ) {
    c &= 0x1F;   // A-Z maps to 1-26
  }
  else if (c >= '0' && c <= '9') {
    c = (c - '0') + 27;
  }
  else if (c == ' ') {
    c = 0; // space
  }
  else if (c == '#') {
    c = 47;
  }
  else if (c == '.') {
    c = 0;
  }
  else if (c == ':') {
    c = 48;
  }
  for (char col=0; col< 5; col++) {
    dots = pgm_read_byte_near(&myfont[c][col]);
    for (char row=0; row < 7; row++) {
      if (dots & (64>>row))              // only 7 rows.
        plot(x+col, y+row, 1);
      else
        plot(x+col, y+row, 0);
    }
  }
}

boolean getPCtime() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    if( Serial.read() == TIME_HEADER ) {        
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){  
        char c= Serial.read();          
        if( c >= '0' && c <= '9'){  
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }  
      DateTime.sync(pctime);   // Sync Arduino clock to the time received on the serial port
      return true;   // return true if time message received on the serial port
    }  
  }
  return false;  //if no message return false
}

void scrollText(char message[], int length, int yPos)
{
      for(int p = (X_MAX+2); p > (-1* (length * 6)); p--){
        for(int i = 0; i < length; i = i++){
          int scrollPos = i * 6 + p;
          if( message[i] == '.'){
            break;
          }
          ht1632_putchar(scrollPos, yPos, message[i]);
          bres_line( (scrollPos+5), 0, (scrollPos+5), 7, 0);
          if(Serial.available() > 0){
            ht1632_clear();
            break;
          }
      }
  }
}

void displayTime(){  // Display current time and date
  String dateString = String(30);
  String timeString = String(6);
  int year = ((DateTime.Year,DEC) + 1999);
  dateString.append(DateTimeStrings.dayStr(DateTime.DayofWeek));
  dateString.append(' ');
  dateString.append(DateTimeStrings.monthStr(DateTime.Month));
  dateString.append(' ');
  dateString.append(DateTime.Day,DEC);
  dateString.append(' ');
  dateString.append(year);
  dateString.append(' ');
  
  scrollText(dateString, 30, 1);  // Scroll date
 
  timeString.append(DateTime.Hour);
  timeString.append(DateTime.Minute);
  
  for(int i = 0; i < 7; i++){
    int scrollPos = i * 6;
    ht1632_putchar(scrollPos, 9, timeString[i]);
  }
}

/***********************************************************************
 * traditional Arduino sketch functions: setup and loop.
 ***********************************************************************/

void setup ()
{
  ht1632_setup();
  Serial.begin(19200);
}

void loop ()
{
  unsigned long  prevtime;
  if( getPCtime()) {  // try to get time sync from pc
    Serial.print("Clock synced at: ");
    Serial.println(DateTime.now(),DEC);
  }
    DateTime.available(); //refresh the Date and time properties
    displayTime(); // Scroll Time and Date on LED display
    delay(100);
}

  
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

TANKS A LOT.
IS POSSIBLE TO RECIEVE THE SCHAMATICS?
Logged

Pages: [1]   Go Up
Jump to: