Show Posts
Pages: [1]
1  Community / Exhibition / Gallery / Re: Fatduino v2.0 = Analog monosynth/sequencer conrolled by Arduino on: October 25, 2011, 03:24:37 pm
Nice work! Do you read parameters from the knobs into the mega or are they for tweaking post-mega?

I've got a twin-t ringing filter-style beatbox from a '70s organ I've been thinking of running from an atmega328p. I figure you can store 8 triggers per quantization step in a byte bitmask but I have to think about the right tradeoff on steps/bar and bars stored.

it looks like from your site you've been documenting this well. You might want to consider putting it on instructables.com, they often have contests with decent prizes.
2  Community / Exhibition / Gallery / Re: Storing Strings in EEPROM from Serial Input Example on: October 25, 2011, 02:54:19 pm
Further thoughts on storing data in EEPROM as a struct...

The example given here: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38417&start=220&postdays=0&postorder=asc&highlight=

is pretty good in that it uses <avr/eeprom.h> and does not require you to reference a memory address when storing/retrieving data. The downside is that you have to copy the whole struct from EEPROM into RAM, which isn't so good for storing and retrieving strings. There must be a way to dereference one value at a time from EEPROM into RAM though.
3  Community / Exhibition / Gallery / Re: Storing Strings in EEPROM from Serial Input Example on: October 24, 2011, 09:11:15 am
Thanks for the reply. I've never used predefines but here's an example:

CPU Type and How to Determine Arduino Bord

According to selected target processor, compiler defined constant by processor name.
Constant    CPU    Board
__AVR_ATmega168__    ATmega 168    Arduino Decimilia and older
__AVR_ATmega328P__    ATmega 328P    Arduino Duemilanove and Uno
__AVR_ATmega1280__    ATmega 1280    Arduino Mega
__AVR_ATmega2560__    ATmega 2560    Arduino Mega 2560

So by testing of these constants you can determine board type. For example:

#if not (defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__))
    #error Sorry dude, this program works only on Arduino Mega
#endif
4  Community / Exhibition / Gallery / Storing Strings in EEPROM from Serial Input Example on: October 23, 2011, 08:04:22 pm
Here is a short example demonstrating taking serial string input and storing and retrieving to and from EEPROM. This is done using EEMEM and <avr.eeprom.h>. I also demonstrate using PSTR-like functionality to keep serial response strings in flash but "print" them to serial directly, without copying them into a temp array using PROGMEM.

For brevity and laziness, I define three separate EEMEM strings and select them via a case statement. I am not sure though EEMEM will handle the pointer to pointer setup you'd need to fetch the start address of the char array inside another array. Anyone try it? Also, I have seen many examples using structs. I should try that too, but held off since I have to look into whether you have to copy the whole thing into RAM or can just copy a specific member of the struct.

Here's the code: (it wouldn't fit here)
https://github.com/quarterturn/serialMultiMessages

I hope this is helpful. Comments are appreciated.
5  Forum 2005-2010 (read only) / Development / brightness control for Noritake LCD-compatible VFD on: September 15, 2010, 07:35:55 pm
Here's a suggestion for an addition to the LiquidCrystal library:

LiquidCrystal.cpp diff:
Code:
255,270d254
< // set dimming on Noritake LCD-compatible VFD
< // dimming levels:
< // 0 = 100%
< // 1 = 75%
< // 2 = 50%
< // 3 = 25%
< void LiquidCrystal::vfdDim(uint8_t dimming) {
<       if ((dimming > -1) && (dimming < 4)) {
<             digitalWrite(_rw_pin, LOW);
<             send(0x28, LOW);
<             digitalWrite(_rw_pin, HIGH);
<             send(dimming, HIGH);
<             digitalWrite(_rw_pin, LOW);
<       }
< }
<

LiquidCrystal.h diff:
Code:
79d78
<   void vfdDim(uint8_t dimming);

Usage example code - alternates between 100% and 25% brightness  every second:
Code:
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 2);
  // Print a message to the LCD.
  lcd.vfdDim(3);
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis()/1000);
  if (((millis()/1000) % 2) == 0)
  {
    lcd.vfdDim(0);
  }
  else
  {
    lcd.vfdDim(3);
  }
}

Tested on a Noritake CU20029ECPB-W1J

VFDs rock!  smiley
6  Forum 2005-2010 (read only) / Exhibition / scrolling data on an LCD on: October 07, 2010, 01:46:40 pm
a function to scroll data across a LiquidCrystal.h compatible display using a sliding buffer on a larger string:

Code:
// function displayMsgScroll()
// scrolls a string from right to left across an LCD
// alternaltes between lines to even wear on a lcd-compatible VFD
// expects a pointer to an array of chars
// returns nothing
void displayMsgScroll(char *currentString)
{
  int strPos,
    bufPos,
    relStrPos,
    strSize,
    bufSize,
    r;
    
  char displayBuffer[21] = "                    ";
    
  bufSize = (strlen(displayBuffer)) - 1;
  strSize = (strlen(currentString)) - 1;
  
  // slide the buffer from the left side of the string all the way
  // over to the right side plus the length of the buffer
  for (strPos = 0; strPos < (strSize + bufSize + 1); strPos++)
  {
    // fill the buffer with spaces to clear it each time for display
    // we are only going to copy data where it exists
    // but only if we aren't past the end of the string
    if (strPos < strSize)
    {
      for (r = 0; r < (strlen(displayBuffer) - 1); r++)
      {
        displayBuffer[r] = ' ';
      }
    }
    // store the current position in the string
    relStrPos = strPos;
    // start from the right side of the buffer
    bufPos = bufSize;
    // loop until we try to copy past the left side of the string
    // or we reach the left side of the buffer
    while ((relStrPos > -1) && (bufPos > -1))
    {
      // only copy if the relative position in the string based on the position in
      // the buffer is not past the right side of the string
      if (relStrPos < (strSize + 1))
      {
        displayBuffer[bufPos] = currentString[relStrPos];
      }
      else
      // if the buffer is past the end of the string insert spaces
      {
        displayBuffer[bufPos] = ' ';
      }
      
      // move left one in the string
      relStrPos--;
      // move left one in the buffer
      bufPos--;
    }
    
    // set the cursor to the start of the row
    lcd.setCursor(0, row);
    
    // send the buffer to the lcd
    lcd.print(displayBuffer);
    
    // loop and check serial for data
    previousMillis = millis();
    while (millis() - previousMillis < INTER_DELAY)
    {
      if (Serial.available() > 0)
      {
        // jump back to main
        // even the wear on the VFD by toggling the row used
        if (row == 0)
        {
          row = 1;
        }
        else
        {
          row = 0;
        }  
        lcd.clear();
        return;
      }
    }
    
  }

Note the check for serial data. In the project this is used, the serial port is used to communicate with the device, so I poll it during my delay loop.

Do you have a better way of doing this? You might be able write blanks to the buffer instead of blanking the buffer beforehand.
7  Forum 2005-2010 (read only) / Exhibition / Re: DL2416 Intelligent LED Display using Arduino on: November 27, 2009, 08:58:28 pm
Datasheet here:
http://www.avagotech.com/docs/5988-3271EN

Looks similar but the pins assignments are moved around a bit. It should be easy to get this working.
8  Forum 2005-2010 (read only) / Exhibition / Re: DL2416 Intelligent LED Display using Arduino on: November 08, 2009, 10:23:18 am
Auugh! The above code does not work, but this does:

Code:
/* ------------------------------------------------------------
   function formatStr
   purpose: formats a string for display on a DL2416T
   expects: a pointer to a string
   returns: nothing
   ------------------------------------------------------------ */

void formatStr(char toDisplay[])
{
  int wStart = 0, // start of word in string
  wEnd = 0; // end of word in string
  int count = 0, // string position counter
  x = 0, // string position counter for word < 5
  n = 0, // display counter for word > 5 mid-word
  wordLen = 0, // length of string
  d = 0, // display counter for word >5 end word
  dLen = 0, // length - 1 for display purposes
  offset = 0; // an offset to center the word on the display
  byte displayNum; // selects display 0 or 1

  byte setChar;
  int segCount = 0;

  // loop until the end of the string

  while (toDisplay[count] != '\0')
  {
    // assume string begins a word and not with a space
    wStart = count;
    wordLen = 0;


    // find the length of the word until we reach a space
    // or the end of the string
    while ((toDisplay[count] != ' ') && (toDisplay[count] != '\0'))
    {
      // set the end to the current location
      // when we drop out of the loop this will be
      // the last character in the word
      wEnd = count;
      // move to the next position in the string
      count++;
      // increment the character count
      wordLen++;
    }
    
    // start with 1st display, displayNum = 0
    displayNum = 0;

    // display directly if it fits on the display
    if (wordLen < 9)
    {
      // write the characters between wStart and wEnd directly
      // to the display

      // back through the buffer array and set one character
      // on the display at a time

      // blank the display
      digitalWrite(8, LOW);
      delay(1);

      // go through the buffer array backwards and write the
      // characters to the display
      segCount = 0;

        // calculate an offset to center the word
        if (wordLen < 2)
        {
          offset = 4;
        }
        if ((wordLen > 1 ) && (wordLen < 4))
        {
          offset = 3;
        }
        if ((wordLen > 3) && (wordLen < 6))
        {
          offset = 2;
        }
        if ((wordLen > 5) && (wordLen < 8))
        {
          offset = 1;
        }
        // apply the offset to the segCount
        segCount = segCount + offset;

      for (n = wEnd; n > (wStart - 1); n--)
      {
          // move to 2nd display if segCount > 3
          // eg. displayNum = 1
          if (segCount > 3)
          {
            displayNum = 1;
          }
        // send the character, display position and display
        displayChar(toDisplay[n], segCount, displayNum);
        segCount++;

      }
      // unblank the display
      digitalWrite(8, HIGH);

      // a pause to read the word
      delay(750);

      // clear the display
      digitalWrite(13, LOW);
      delay(2);
      digitalWrite(13, HIGH);

        // reset offset
        offset = 0;
    }

    // if it is more than eight characters long
    // display using the scrolling method
    if (wordLen > 8)
    {
      dLen = wordLen - 1;

      // write the characters between wStart and wEnd so they
      // appear to scroll from left to right

      // it takes length + 2 iterations to scroll
      // all the way to the last character

      // we will use x to keep track of where we are in the
      // scrolling process
      for (x = 0; x < (wordLen + 7); x++)
      {

        // clear the display
        digitalWrite(13, LOW);
        delay(2);
        digitalWrite(13, HIGH);

        // scroll until the eighth character in the word
        // read the buffer backwards
        if (x < 8) {
            // start with the first display
            displayNum = 0;

          segCount = 0;
          for (d = (wEnd - (dLen - x)); d > (wStart - 1) ; d--)
          {
                // move to 2nd display if segCount > 3
                // eg. displayNum = 1
                if (segCount > 3)
                {
                  displayNum = 1;
                }
                
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount++;
          }
        }
        // after the eighth character scroll on
        // until the end of the word
        if ((x > 7) && (x < wordLen))
        {
          segCount = 0;
            displayNum = 0;

          for (d = wEnd - (dLen - x); d > ((wStart + (x - 7)) - 1); d--)
          {
                // move to 2nd display if segCount > 3
                // eg. displayNum = 1
                if (segCount > 3)
                {
                  displayNum = 1;
                }
                
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount++;
          }
        }

        // once we get to the end of the word
        // scroll off by reading forwards in the array
        // while counting backwards in the display position
        if (x > dLen)
        {
          segCount = 7;
            displayNum = 1;
          for (d = (wStart + (x - 7)); d < (wEnd + 1); d++)
          {
                // move to 1st display if segCount < 4
                // eg. displayNum = 0
                if (segCount < 4)
                {
                  displayNum = 0;
                }
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount--;
          }
        }
      // a small delay between scroll
      delay(200);

      }
      // clear the display
      digitalWrite(13, LOW);
      delay(2);
      digitalWrite(13, HIGH);
    }
    count++;
  }
} // end function formatStr

/* ------------------------------------------------------------
   function displayChar
   purpose: displays a character on a DL2416T
   expects: a character, a position and a display (0,1,2 etc...)
   returns: nothing
   ------------------------------------------------------------ */

void displayChar(char myChar, int myPos, byte myDisp)
{

  /* here's how to set a character:
         1. select an address using a0-a1 which here are arduino pins 9-10
         2. pull WR to LOW to enable loading
         3. send the bit-shifted character to the data lines d0-d6 all at once using PORTD
         4. set the WR pin back to HIGH
         5. repeat for next character

   */

  // enable the correct display
  if (myDisp == 0)
  {
    // enable display 0 by setting C1-C2 LOW
    digitalWrite(11, LOW);
    // disable display 1 by setting C1-C2 HIGH
    digitalWrite(12, HIGH);
    delay(2);

  }
  if (myDisp == 1)
  {
     // enable display 1 by setting C1-C2 LOW
    digitalWrite(12, LOW);
    // disable display 0 by setting C1-C2 HIGH
    digitalWrite(11, HIGH);
    delay(2);
    // convert the 7-0 word frame position to the
    // actual position on display 1
    myPos = myPos - 4;
  }

  // we are going to set the ASCII character all at once on PORTD
  // but we must avoid pin 0, which is serial RX
  // so we will shift one bit to the left
  myChar = myChar << 1;
  // the segment position is the opposite of the array
  // eg. seg0 is array[3]
  // set the character pin state
  // cheap binary conversion of setChar
  switch (myPos)
  {
    case 0:
      digitalWrite(9, LOW);
      digitalWrite(10, LOW);
      break;
    case 1:
      digitalWrite(9, HIGH);
      digitalWrite(10, LOW);
      break;
    case 2:
      digitalWrite(9, LOW);
      digitalWrite(10, HIGH);
      break;
    case 3:
      digitalWrite(9, HIGH);
      digitalWrite(10, HIGH);
      break;
  }

  // set the WR pin LOW to enable loading
  digitalWrite(14, LOW);
  delay(1);

  // set the shifted character to PORTD
  PORTD = myChar;
  delay(1);

  // set WR pin HIGH to finish loading
  digitalWrite(14, HIGH);
  delay(1);
} // end function displayChar
9  Forum 2005-2010 (read only) / Exhibition / Re: DL2416 Intelligent LED Display using Arduino on: November 06, 2009, 10:56:15 pm
Here's an update to the functions to support a second display:

Code:
/* ------------------------------------------------------------
   function formatStr
   purpose: formats a string for display on a DL2416T
   expects: a pointer to a string
   returns: nothing
   ------------------------------------------------------------ */

void formatStr(char toDisplay[])
{
  int wStart = 0, // start of word in string
  wEnd = 0; // end of word in string
  int count = 0, // string position counter
  x = 0, // string position counter for word < 5
  n = 0, // display counter for word > 5 mid-word
  wordLen = 0, // length of string
  d = 0, // display counter for word >5 end word
  dLen = 0, // length - 1 for display purposes
  offset = 0; // an offset to center the word on the display
  byte displayNum; // selects display 0 or 1

  byte setChar;
  int segCount = 0;

  // loop until the end of the string

  while (toDisplay[count] != '\0')
  {
    // assume string begins a word and not with a space
    wStart = count;
    wordLen = 0;


    // find the length of the word until we reach a space
    // or the end of the string
    while ((toDisplay[count] != ' ') && (toDisplay[count] != '\0'))
    {
      // set the end to the current location
      // when we drop out of the loop this will be
      // the last character in the word
      wEnd = count;
      // move to the next position in the string
      count++;
      // increment the character count
      wordLen++;
    }
    
    // start with 1st display, displayNum = 0
    displayNum = 0;

    // display directly if it fits on the display
    if (wordLen < 9)
    {
      // write the characters between wStart and wEnd directly
      // to the display

      // back through the buffer array and set one character
      // on the display at a time

      // blank the display
      digitalWrite(8, LOW);
      delay(1);

      // go through the buffer array backwards and write the
      // characters to the display
      segCount = 0;

        // calculate an offset to center the word
        if ((wordLen > 0 ) && (wordLen < 4))
        {
          offset = 3;
        }
        if ((wordLen > 3) && (wordLen < 6))
        {
          offset = 2;
        }
        if ((wordLen > 5) && (wordLen < 8))
        {
          offset = 1;
        }
        // apply the offset to the segCount
        segCount = segCount + offset;

      for (n = wEnd; n > (wStart - 1); n--)
      {
          // move to 2nd display if segCount > 3
          // eg. displayNum = 1
          if (segCount > 3)
          {
            displayNum = 1;
          }
        // send the character, display position and display
        displayChar(toDisplay[n], segCount, displayNum);
        segCount++;

      }
      // unblank the display
      digitalWrite(8, HIGH);

      // a pause to read the word
      delay(750);

      // clear the display
      digitalWrite(13, LOW);
      delay(2);
      digitalWrite(13, HIGH);
    }

    // if it is more than eight characters long
    // display using the scrolling method
    if (wordLen > 8)
    {
      dLen = wordLen - 1;

      // write the characters between wStart and wEnd so they
      // appear to scroll from left to right

      // it takes length + 2 iterations to scroll
      // all the way to the last character

      // we will use x to keep track of where we are in the
      // scrolling process
      for (x = 0; x < (wordLen + 3); x++)
      {

        // clear the display
        digitalWrite(13, LOW);
        delay(2);
        digitalWrite(13, HIGH);

        // scroll until the eighth character in the word
        // read the buffer backwards
        if (x < 7) {
            
            // start with the first display
            displayNum = 0;

          segCount = 0;
          for (d = (wEnd - (dLen - x)); d > (wStart - 1) ; d--)
          {
                // move to 2nd display if segCount > 3
                // eg. displayNum = 1
                if (segCount > 3)
                {
                  displayNum = 1;
                }
                
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount++;
          }
        }
        // after the eighth character scroll on
        // until the end of the word
        if ((x > 7) && (x < wordLen))
        {
          segCount = 0;
            displayNum = 0;

          for (d = wEnd - (dLen - x); d > ((wStart + (x - 3)) - 1); d--)
          {
                // move to 2nd display if segCount > 3
                // eg. displayNum = 1
                if (segCount > 3)
                {
                  displayNum = 1;
                }
                
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount++;
          }
        }

        // once we get to the end of the word
        // scroll off by reading forwards in the array
        // while counting backwards in the display position
        if (x > dLen)
        {
          segCount = 7;
          for (d = (wStart + (x - 3)); d < (wEnd + 1); d++)
          {
                // move to 1st display if segCount < 4
                // eg. displayNum = 0
                if (segCount < 4)
                {
                  displayNum = 0;
                }
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount--;
          }
        }
      // a small delay between scroll
      delay(200);

      }
      // clear the display
      digitalWrite(13, LOW);
      delay(2);
      digitalWrite(13, HIGH);
    }
    count++;
  }
} // end function formatStr

/* ------------------------------------------------------------
   function displayChar
   purpose: displays a character on a DL2416T
   expects: a character, a position and a display (0,1,2 etc...)
   returns: nothing
   ------------------------------------------------------------ */

void displayChar(char myChar, int myPos, byte myDisp)
{

  /* here's how to set a character:
         1. select an address using a0-a1 which here are arduino pins 9-10
         2. pull WR to LOW to enable loading
         3. send the bit-shifted character to the data lines d0-d6 all at once using PORTD
         4. set the WR pin back to HIGH
         5. repeat for next character

   */

  // enable the correct display
  if (myDisp == 0)
  {
    // enable display 0 by setting C1-C2 LOW
    digitalWrite(11, LOW);
    // disable display 1 by setting C1-C2 HIGH
    digitalWrite(12, HIGH);
    delay(2);

  }
  if (myDisp == 1)
  {
     // enable display 1 by setting C1-C2 LOW
    digitalWrite(12, LOW);
    // disable display 0 by setting C1-C2 HIGH
    digitalWrite(11, HIGH);
    delay(2);
    // convert the 7-0 word frame position to the
    // actual position on display 1
    myPos = myPos - 4;
  }

  // we are going to set the ASCII character all at once on PORTD
  // but we must avoid pin 0, which is serial RX
  // so we will shift one bit to the left
  myChar = myChar << 1;
  // the segment position is the opposite of the array
  // eg. seg0 is array[3]
  // set the character pin state
  // cheap binary conversion of setChar
  switch (myPos)
  {
    case 0:
      digitalWrite(9, LOW);
      digitalWrite(10, LOW);
      break;
    case 1:
      digitalWrite(9, HIGH);
      digitalWrite(10, LOW);
      break;
    case 2:
      digitalWrite(9, LOW);
      digitalWrite(10, HIGH);
      break;
    case 3:
      digitalWrite(9, HIGH);
      digitalWrite(10, HIGH);
      break;
  }

  // set the WR pin LOW to enable loading
  digitalWrite(14, LOW);
  delay(2);

  // set the shifted character to PORTD
  PORTD = myChar;
  delay(2);

  // set WR pin HIGH to finish loading
  digitalWrite(14, HIGH);
  delay(2);
} // end function displayChar

I wanted to have my words centered (more or less). It would not be hard to left-justify instead - just adjust the offset section.

Next stop for this project is to move it beyond the breadboard and add in support for an SD card. The ultimate goal is a handheld speed-reader. Reading one word at a time you can read more than 600 WPM. But I'll need a source for a modern, available display. It'll need to be an OLED or VFD. I don't think an STN LCD will be fast enough.
10  Forum 2005-2010 (read only) / Exhibition / Re: DL2416 Intelligent LED Display using Arduino on: November 04, 2009, 11:28:23 am
I pulled them out of some surplus lab gear I bought for a few dollars. I wouldn't recommend trying to buy them online. They exist, but the prices are outrageous. Too bad, I do like how they look.


11  Forum 2005-2010 (read only) / Exhibition / Re: DL2416 Intelligent LED Display using Arduino on: November 01, 2009, 10:22:02 am
here's the link to the video:


It's a small display, so the code takes an array of strings, breaks them down into words, and then displays them all at once if they fit or scrolls them if they don't. I did it all using just the array index so as to conserve RAM.
12  Forum 2005-2010 (read only) / Exhibition / DL2416 Intelligent LED Display using Arduino on: November 01, 2009, 10:17:03 am
Here's a Siemens DL2416 intelligent LED alphanumeric display being run by a Boarduino:

Code:
/* DL2416T intelligent 16-segment display test

   version: 0.2
   author: Alex Davis
   hardware: Atmega168 or Atmega328 Arduino
  
   Sends text to a directly-connected DL2416T 16-segment
   four-character alphanumeric display.
  
   There are probably enough pins to do four displays
   without external logic. As is the code does just one.
  
   If you debug using Serial you will set d0 high and throw off every other character.
  
*/

#include <avr/pgmspace.h>

// strings to display stored in EEPROM
// don't put spaces at the start - the code assumes there won't be any
// do put a space on the end
prog_char string0[] PROGMEM = "SING WHILE YOU MAY ";
prog_char string1[] PROGMEM = "LIKE A FLY THAT'S TRAPPED ON A WINDOW ";
prog_char string2[] PROGMEM = "SING WHILE YOU MAY ";
prog_char string3[] PROGMEM = "THOUGH THERE'S NOTHING IN THE WORLD ";
prog_char string4[] PROGMEM = "THAT YOU CAN CHANGE ";
prog_char string5[] PROGMEM = "SING WHILE YOU MAY ";
prog_char string6[] PROGMEM = "'CAUSE IT MAY NOT BE VERY LONG ";

#define NUM_STRINGS 7
#define MAX_SIZE 81

// an array of strings
// if you change the number of strings above
// update this as well to match
PROGMEM  const char *stringSet[] = {string0,
string1,
string2,
string3,
string4,
string5,
string6
};

// function prototypes
void formatStr(char []);
void displayChar(char, int, byte);

// set ports and pins
void setup()
{
  
  
  byte pinLoop;
  // set port d to all outputs, except serial in
  // then set them low
  DDRD = B11111110;
  PORTD = B00000000;
  // set pins 8-16 to outputs
  for (pinLoop = 8; pinLoop < 17; pinLoop++) {
    pinMode(pinLoop, OUTPUT);
  }
  // set the pin states
  // use 8 for BL and set to HIGH
  digitalWrite(8, HIGH);
  // use 9 for AO and set to LOW
  digitalWrite(9, LOW);
  // use 10 for A1 and set to LOW
  digitalWrite(10, LOW);
  
  // if you tie C1 and C2 on each display
  // then 11 can be for display0
  // and 12 can be for display1
  
  // use 11 for C1 and set to HIGH
  digitalWrite(11, HIGH);
  // use 12 for C2 and set to HIGH
  digitalWrite(12, HIGH);
  // use 13 for CLR and set to HIGH
  digitalWrite(13, HIGH);
  // use 14 for CU and set to HIGH
  digitalWrite(14, HIGH);
  // use 15 for WR and set to HIGH
  digitalWrite(15, HIGH);
  // use 16 for CUE and set to LOW
  digitalWrite(16, LOW);
  
}

// main
void loop()
{
  byte i;
  // buffer string stored in RAM
  char currentString[MAX_SIZE];
  
  for (i = 0; i < NUM_STRINGS; i++)
  {
    
    // copy a string from the array of strings in the EEPROM
    // to a local buffer string in RAM
    strcpy_P(currentString, (char*)pgm_read_word(&(stringSet[i])));
    
    // parse the string for display
    formatStr(currentString);
    // pause a bit
    delay(1000);
  }
}

/* ------------------------------------------------------------
   function formatStr
   purpose: formats a string for display on a DL2416T
   expects: a pointer to a string
   returns: nothing
   ------------------------------------------------------------ */

void formatStr(char toDisplay[])
{
  int wStart = 0, // start of word in string
  wEnd = 0; // end of word in string
  int count = 0, // string position counter
  x = 0, // string position counter for word < 5
  n = 0, // display counter for word > 5 mid-word
  wordLen = 0, // length of string
  d = 0, // display counter for word >5 end word
  dLen = 0; // length - 1 for display purposes
  byte displayNum = 0; // selects display 0 or 1

  byte setChar;
  int segCount = 0;
  
  // loop until the end of the string
  
  while (toDisplay[count] != '\0')
  {
    // assume string begins a word and not with a space
    wStart = count;
    wordLen = 0;
    
    
    // find the length of the word until we reach a space
    // or the end of the string
    while ((toDisplay[count] != ' ') && (toDisplay[count] != '\0'))
    {
      // set the end to the current location
      // when we drop out of the loop this will be
      // the last character in the word
      wEnd = count;
      // move to the next position in the string
      count++;
      // increment the character count
      wordLen++;
    }
    
    // display directly if it fits on the display
    if (wordLen < 5)
    {
      // write the characters between wStart and wEnd directly
      // to the display
      
      // back through the buffer array and set one character
      // on the display at a time
      
      // blank the display
      digitalWrite(8, LOW);
      delay(1);
      
      // go through the buffer array backwards and write the
      // characters to the display
      segCount = 0;
      
      for (n = wEnd; n > (wStart - 1); n--)
      {
        
        // send the character, display position and display
        displayChar(toDisplay[n], segCount, displayNum);
        segCount++;
        
      }
      // unblank the display
      digitalWrite(8, HIGH);
      
      // a pause to read the word
      delay(750);
      
      // clear the display
      digitalWrite(13, LOW);
      delay(2);
      digitalWrite(13, HIGH);
    }
    
    // if it is more than four characters long
    // display using the scrolling method
    if (wordLen > 4)
    {
      dLen = wordLen - 1;
      
      // write the characters between wStart and wEnd so they
      // appear to scroll from left to right
      
      // it takes length + 2 iterations to scroll
      // all the way to the last character
      
      // we will use x to keep track of where we are in the
      // scrolling process
      for (x = 0; x < (wordLen + 3); x++)
      {
        
        // clear the display
        digitalWrite(13, LOW);
        delay(2);
        digitalWrite(13, HIGH);
        
        // scroll until the fourth character in the word
        // read the buffer backwards
        if (x < 4) {
          
          segCount = 0;
          for (d = (wEnd - (dLen - x)); d > (wStart - 1) ; d--)
          {
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount++;
          }
        }
        // after the fourth character scroll on
        // until the end of the word
        if ((x > 3) && (x < wordLen))
        {
          segCount = 0;
          
          for (d = wEnd - (dLen - x); d > ((wStart + (x - 3)) - 1); d--)
          {
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount++;
          }
        }
        // once we get to the end of the word
        // scroll off by reading forwards in the array
        // while counting backwards in the display position
        if (x > dLen)
      {
          
          segCount = 3;
          for (d = (wStart + (x - 3)); d < (wEnd + 1); d++)
          {
            // send the character, display position and display
            displayChar(toDisplay[d], segCount, displayNum);
            segCount--;
          }  
        }
      // a small delay between scroll  
      delay(200);
      
      }
      // clear the display
      digitalWrite(13, LOW);
      delay(2);
      digitalWrite(13, HIGH);
    }
    count++;
  }
} // end function formatStr

/* ------------------------------------------------------------
   function displayChar
   purpose: displays a character on a DL2416T
   expects: a character, a position and a display (0,1,2 etc...)
   returns: nothing
   ------------------------------------------------------------ */

void displayChar(char myChar, int myPos, byte myDisp)
{
  
  /* here's how to set a character:
         1. select an address using a0-a1 which here are arduino pins 9-10
         2. pull WR to LOW to enable loading
         3. send the bit-shifted character to the data lines d0-d6 all at once using PORTD
         4. set the WR pin back to HIGH
         5. repeat for next character
        
   */
 
  // right now we only do one display
  // but logic for more would be added here
  // using a case if more than one were used
  if (myDisp == 0)
  {
    // enable display 0 by setting C1-C2 LOW
    digitalWrite(11, LOW);
    // disable display 1 by setting C1-C2 HIGH
    digitalWrite(12, HIGH);
    delay(2);
    
  }
  
  // we are going to set the ASCII character all at once on PORTD
  // but we must avoid pin 0, which is serial RX
  // so we will shift one bit to the left
  myChar = myChar << 1;
  // the segment position is the opposite of the array
  // eg. seg0 is array[3]
  // set the character pin state
  // cheap binary conversion of setChar
  switch (myPos)
  {
    case 0:
      digitalWrite(9, LOW);
      digitalWrite(10, LOW);
      break;
    case 1:
      digitalWrite(9, HIGH);
      digitalWrite(10, LOW);
      break;
    case 2:
      digitalWrite(9, LOW);
      digitalWrite(10, HIGH);
      break;
    case 3:
      digitalWrite(9, HIGH);
      digitalWrite(10, HIGH);
      break;
  }
  
  // set the WR pin LOW to enable loading
  digitalWrite(14, LOW);
  delay(2);
  
  // set the shifted character to PORTD
  PORTD = myChar;
  delay(2);
  
  // set WR pin HIGH to finish loading
  digitalWrite(14, HIGH);
  delay(2);
} // end function displayChar


13  Forum 2005-2010 (read only) / Frequently-Asked Questions / Official site archive on DVD? on: June 22, 2010, 10:01:52 pm
Any consideration of an arduino.cc site snapshot on DVD? Be great to have in case of no internet access or internet shutdown/segmentation. Perhaps for free, like erowid.org, or maybe for a fee, like rexresearch.com.
Pages: [1]