Multifunction LED Matrix Display

This is my first post, so hi everyone! I'm just here to show off a display I've been working on. The LED matrices are two Sure 0832's and the microcontroller is a Duemilanove. There's also a wall-wart to power the display. I used this: http://milesburton.com/index.php/Arduino_&_the_Sure_2416_Information_Display library to communicate with the display. I expanded the font set using this excel spreadsheet: http://www.instructables.com/id/LED-Scolling-Dot-Matrix-Font-Graphics-Generator-/step6/Predefined-5x8-Font-Data-and-Awesome-Patterns/. Messages are sent to the Arduino from my Slackware Linux Server through USB Serial. I wrote a Java app on the Linux box to gather the data to be displayed and pass it along to the Arduino. The app is configured by a web interface I wrote in php. The code is a mess (like my workbench and my desk). If there is demand for the source I'll try to clean it up and release it. Here are some pics (the ones that look sloppy are just scrolling. An issue with the camera): New mail from multiple accounts, and current time (default mode, not scrolling)

Current weather conditions (scrolling "65F Mostly Sunny")

Weather forecast for the (rest of the) day.

Stock ticker gets info from Yahoo finance.

User-programmable scrolling message.

Web configuration. The 5 to 9 under weather is when the weather is displayed (like when I get up in the morning so I know what to wear.)

I'm looking forward to chaining more displays and adding more functions such as a sports ticker. Hope you like it, and feel free to make suggestions!

Good job, and welcome! :)

This is my first post, so hi everyone!

Well now that's a lie :p

Looks nice. I was going to look into chaining those displays but never got round to it...

Mowcius

Very cool, well done.

Could you go into a more detail about how your web interface works?

Could you go into a more detail about how your web interface works?

The linux box that does the communication with the Arduino has an Apache web server with PHP support. The web interface is a PHP generated html form. The PHP reads and modifies a config file on the computer. When the page loads, the file is read and the form is populated with the config info. When I change something on the web interface and hit "Submit," the php script updates the config file to reflect the changes.

The java app periodically reads this config file, and uses these settings to determine what should be sent to the Arduino, to be shown on the display.

Thanks for explaining.

Have you thought about using an ethernet shield so it wouldn't need to be tethered to your PC? You could have your web server open a socket to the arduino and send instructions that way.

I'd love an Ethernet shield in general. In this case, however, the pc is always on as I use it for a media/web/email/etc server. It doesn't matter to me whether it's tethered to the server or a switch. I like finding new uses for the server anyway, since it has a lot of idle cycles. If the shield had power-over-ethernet that allowed me to eliminate the wall wart, I'd have to consider it though. I guess I'd then have to buy the shield and a PoE switch. I'm sorta broke.

Fair enough.

It's a shame POE isn't more common.

Cool! And very well done!

Good work, you are welcome. Here is the link to our work: php form.

Good work, you are welcome. Here is the link to our work: php form.

Funny spam?

Related? No...

Mowcius

where can I buy some of those displays?

That’s really a greeat project.

where can I buy some of those displays?

A simple search may have helped…

http://business.shop.ebay.com/Business-Industrial-/12576/i.html?_nkw=0832&_catref=1&_fln=1&_sc=1&_sop=15&_sticky=1&_trksid=p3286.c0.m282

Any chance of some code? Those Displays are wonderfully cheap, and I’d definitely pull the trigger on a few if I knew how to work with the darned things.

I see the library, but that seems to be for setting individual pixels, and I have no idea of a quick method for writing text/scrolling/anything else.

So again, do you have any basic code for writing text / scrolling?

Thanks :slight_smile:

Any chance of some code? Those Displays are wonderfully cheap, and I'd definitely pull the trigger on a few if I knew how to work with the darned things.

I see the library, but that seems to be for setting individual pixels, and I have no idea of a quick method for writing text/scrolling/anything else.

So again, do you have any basic code for writing text / scrolling?

Thanks

Well now you see, I can tell you to search!

There is a many page thread on controlling them. I think you should find it if you search for sure electronics matrix although the thread does not include that in the name. Shouldn't take too long to find the thread though.

Mowcius

I spent about 1.5 hours sifting through various threads, blogs, and datasheets last night looking for some code that writes text or scrolls (I even looked through the WiseClock's code!) but couldn't find any.

Maybe my searching skills are lacking. I'll do a bit more later haha :P.

[edit]Hmm I seem to have overlooked this big thread. I'm currently looking through it, hoping to find some code for the 0832 rather than the 1624. I see some text generation for the 1624, but I have no clue if it'd work for the 0832..[/edit]

[edit]WestfW had included a ZIP file that had what looks like everything I needed, but it was hosted on Geocities (which ceased to exist) and is now gone. Anyone have a copy? :([/edit]

[edit]More progress! I've found Florinc's code for scrolling text on the 0832, but I can't seem to find the ever elusive ht1632.h that's needed to run the program :([/edit]

[edit]AHA! I've found it: http://homepage.mac.com/westfw/.Public/demo16x24.zip :)[/edit]

Well, even after all that, I'd still love to see the OP's code. I'd be interested to see his adaptations and simplifications, etc.

A simple search may have helped..

for some reason altavista did not turn up any useful results :'(

I see Sure sells these as kits that work with LCD smartie, does anyone know/have the code to make these work with LCD smartie? I think I see another little control board in the photo on eBay, but I believe that’s just a microcontroller to handle the USB comms etc.

I linked to the library on the first post of the thread. There is example code on that page, but the code that actually came packaged with the lib seemed better. The example code will work if you hook up the display properly. It can scroll text, draw lines, etc..

This is what I run on the Arduino. Some of it’s a bit sloppy.

#include "MatrixDisplay.h"
#include "DisplayToolbox.h"
#include "betterfont.h"

const byte pinCS1 = 10;
const byte pinCS2 = 9;
const byte pinWR = 11;
const byte pinData = 12;
const byte nDisplays = 2;

char command = 'm';
char param[2];
char env[1] = {7};

// Macro to make it the initDisplay function a little easier to understand
#define setMaster(dispNum, CSPin) initDisplay(dispNum,CSPin, true)
#define setSlave(dispNum, CSPin) initDisplay(dispNum,CSPin,false)

// Init Matrix
MatrixDisplay disp(nDisplays,pinWR,pinData, true);
// Pass a copy of the display into the toolbox
DisplayToolbox toolbox(&disp);

// Prepare boundaries
uint8_t X_MAX = 0;
uint8_t Y_MAX = 0;

const int maxString = 1000;
char banner[maxString];

long lastUpdate = 0;

const int timeout = 5000; //ms

void setup() {
  Serial.begin(9600);
  
  // Fetch bounds (dynamically work out how large this display is)
  X_MAX = disp.getDisplayCount() * (disp.getDisplayWidth()-1)+1;
  Y_MAX = disp.getDisplayHeight();

  // Prepare displays
  disp.setMaster(0,pinCS1);
  disp.setSlave(1,pinCS2);
  
//  banner[0] = 'k';
//  banner[1] = '\0';
//  scrollText();
//  disp.syncDisplays();
}



void loop() {
  getSerial();
  
  while(banner[0] == '/' && banner[1] == '/'){
    command = banner[2];
    param[0] = banner[3];
    param[1] = banner[4];
    for (int i = 0; i < maxString - 5; i++){
        banner[i] = banner[i + 5];
    }
    
    if(command == 'b'){
      toolbox.setBrightness((param[0] - 48) * 10 + (param[1] - 48));
    }
    
    //stationary text
    else if(command == 's'){
      disp.clear();
      drawString(2, 0, env);
      drawString(15, 0, banner);
      disp.syncDisplays();
    }
  }
  
  if (command == 'm'){
    scrollText();
  }
}

/*
 * 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 setPixel() to draw each dot.
 */
void drawChar(uint8_t x, uint8_t y, int c)
{
  uint8_t dots;
  
  // just draw visible chars
  if(c >= ' ' && c <= '~' + 2){
    c -= 32;
  }
  
  for (char col=0; col< 5; col++) {
    dots = pgm_read_byte_near(&myfont[c][col]);
    for (char row=0; row < 8; row++) {
      if (dots & (128>>row))              // 128 for 8 rows.
        toolbox.setPixel(x+col, y+row, 1);
//      else 
//        toolbox.setPixel(x+col, y+row, 0);
    }
  }
}


// Write out an entire string (Null terminated)
void drawString(int x, int y, char* c)
{
  for(char i=0; i< strlen(c); i++)
    {  
      if(x > -6 && x < X_MAX)
        if(c[i] == 7){
          drawChar(x, y, '~' + 1);
          x+=5;
          drawChar(x, y, '~' + 2);
          x+=8;
        }
        else{
          drawChar(x, y, c[i]);
          x+=6; // Width of each glyph
        }
    }
}

void scrollText(){
  int x = X_MAX;
  int charsFinished = 0;
  char visible[11];
  int i = 0;
  
  for (int n = 0; n < 11; n++){
    visible[n] = banner[n];
  }
  
  while(charsFinished < strlen(banner)){
    if(millis() - lastUpdate > 25){
      lastUpdate = millis();
      drawString(x, 0, visible);
      disp.syncDisplays();
        
      x--;
        
      if (x <= -6){
        charsFinished++;
        x = 0;
        
        i = 0;
        while(i < 11 && banner[i + charsFinished] != '\0'){
            visible[i] = banner[i + charsFinished];
            i++;
        }
        visible[i] = banner[i + charsFinished];
      }
      
      disp.clear();
    }
  }
}

void getSerial(){
  boolean finished = false;
  long tLast = millis();
  int iChar = 0;
  
  if (Serial.available()){
    while(!finished){
      for (int i = 0; i < 126;){
        if(Serial.available()){
          banner[iChar] = Serial.read();
          tLast = millis();
          iChar++;
          i++;
          
          //if we get the terminating char or we get too big of a string
          if(banner[iChar - 1] == 13 || iChar == 1000){
            finished = true;
            break;
          }
        }
      }
      
      if (!finished){
        toolbox.setPixel(1, 1, 1);
        disp.syncDisplays();
        
        Serial.print("ready.");
        long tSend = millis();
        tLast = millis();
        
        while(!Serial.available()){
          if(millis() - tSend > 500){
            Serial.print("ready.");
            tSend = millis();
          }
        toolbox.setPixel(1, 1, 0);
        disp.syncDisplays();
        }// while(!Serial.available())
      }// if not finished
    }// while(!finished)
    banner[iChar - 1] = '\0';
  }
  
  //if we haven't received anything, let the control box know the buffer is clear
  //and arduino is ready
  else
    Serial.print("ready.");
}