Forum Index > Projects > LED Pegboard and Matrix Projects
 Peggy2LE doesn't like snprintf?
 |  Printable Version
By: adambomb (offline) on Wednesday, May 26 2010 @ 07:55 PM PDT (Read 4022 times)  
adambomb

I've got a peggy2le (v2.31le) that I'm trying to program to dynamically update (twitter feeds, baseball scores, news, etc.), but I've hit some snags. I'm using the Peggy2 and PeggyWriter libraries, downloaded two days ago, from here. Using this library gives me four usable rows for text. I'm displaying static text on the top three rows right now and scrolling text for the bottom row. (This may change later.) Here's what's happening:

1. Somebody needs to update the libraries to use all ASCII characters. Having to work around that is a major pain in the butt.

2. How I assign values to the display strings determines whether or not the string for static display will be displayed. If I use snprintf, either a single line of LEDs lights up or nothing at all on the entire board. No scrolling text either. If I set up my strings like this, everything initially works fine:

PHP Formatted Code

char  textstrHeader[] = "SET NEW MESSAGE";
char  textstrScroller[] = "INITIALIZING 0123456789:;<=>?@ ";

void setup() {
  frame1.HardwareInit();
  myScroller.init(&frame1, &myWriter, 18, textstrScroller);
}
 



But if I do it like this, I get the aforementioned problem:

PHP Formatted Code

char  textstrHeader[BUFFER_SIZE];
char  textstrScroller[BUFFER_SIZE];

void setup() {
  snprintf(textstrHeader, BUFFER_SIZE, "%s", "SET NEW MESSAGE");
  snprintf(textstrScroller, BUFFER_SIZE, "%s", "INITIALIZING 0123456789:;<=>?@ ");

  frame1.HardwareInit();
  myScroller.init(&frame1, &myWriter, 18, textstrScroller);
}
 



Maybe my C-coding skills aren't up to par, or maybe something is genuinely wrong with trying to use snprintf that I don't know about.

3. Finally, what's the best way to completely wipe the display so I can change the text? After the scrolling text is finished, I make a call to a refresh function (that uses snprintf, by the way) that results in the old static text remaining after the new static text is displayed. More frustrating: the scrolling text changes just fine!

Here's all my code for now. I appreciate any help anyone can give. I'm largely happy with the peggy2 and have big plans with this board once I get past these little problems.

PHP Formatted Code

#include <Peggy2.h>
#include <PeggyWriter.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 8192

Peggy2 frame1;    
PeggyWriter myWriter;
PeggyScroller myScroller;

//char  textstrHeader[BUFFER_SIZE];
//char  textstrScroller[BUFFER_SIZE];

char  textstrHeader[] = "SET NEW MESSAGE";
char  textstrScroller[] = "INITIALIZING 0123456789:;<=>?@ ";

void setup() {
//  snprintf(textstrHeader, BUFFER_SIZE, "%s", "SET NEW MESSAGE");
//  snprintf(textstrScroller, BUFFER_SIZE, "%s", "INITIALIZING 0123456789:;<=>?@ ");

  frame1.HardwareInit();
  myScroller.init(&frame1, &myWriter, 18, textstrScroller);
}

void loop() {
  long delayCount = 0;
  char messageFinished;

//  strip_nonvalid_characters(textstrHeader);
//  strip_nonvalid_characters(textstrScroller);
 
  // pull all the "myWriter.drawCharacter calls into a separate function
  writeStaticDisplay(frame1, myWriter, textstrHeader);
  messageFinished = myScroller.scrollLeft();
 
  while (delayCount < 200) {
    frame1.RefreshAll(1);
    delayMicroseconds(50);
    delayCount++;
  }
  delayCount = 0;
 
  if (messageFinished == 0) {
    // refresh so we make another call to reset the messages
    refresh();
  }

}

void refresh() {  
  snprintf(textstrHeader, BUFFER_SIZE, "%s", "BUGGY AS HELL");
  snprintf(textstrScroller, BUFFER_SIZE, "%s", "SETTING NEW MESSAGE ");
 
  // find a way to definitively clear the screen to get around static overlap problem
//  frame1.HardwareInit(); // <- doesn't seem to make a difference on subsequent calls
  myScroller.init(&frame1, &myWriter, 18, textstrScroller);
}

void strip_nonvalid_characters(char *textstr) {
  int    i, j;
  int    textstr_length = strlen(textstr);
  char  temp_textstr[BUFFER_SIZE];
 
  for (i = 0, j = 0; i < textstr_length; i++) {
    if ((textstr[i] > 96) && (textstr[i] < 123)) {
      textstr[i] = textstr[i] - 32;
    }
    // ascii characters between 0 and Z and the space on http://www.asciitable.com/
    if (((textstr[i] > 47) && (textstr[i] < 91)) || (textstr[i] == 32)) {
      temp_textstr[j++] = textstr[i];
    }
    // ascii character for / turns into ;
    if (textstr[i] == 47) {
      temp_textstr[j++] = 59;
    }
    // ascii character for # turns into <
    if (textstr[i] == 35) {
      temp_textstr[j++] = 60;
    }
    // ascii character for . turns into >
    if (textstr[i] == 46) {
      temp_textstr[j++] = 62;
    }
    // ascii characters for ' ` " turns into ;
    if ((textstr[i] == 34) || (textstr[i] == 39) || (textstr[i] == 44)) {
      temp_textstr[j++] = 59;
    }
    // ascii character for ! turns into :
    if (textstr[i] == 33) {
      temp_textstr[j++] = 58;
      temp_textstr[j++] = 58;
    }
  }
  temp_textstr[j] = '\0';
  snprintf(textstr, BUFFER_SIZE, "%s", temp_textstr);
  strncpy(textstr, temp_textstr, strlen(temp_textstr));
}

void writeStaticDisplay(Peggy2 frame, PeggyWriter msg, char *textline) {
  int    x = 0;
  int    y = 0;
  int    count;
 
  for (count = 0; textline[count] != '\0'; count++) {

    if (textline[count] == ' ') {
      if ((x + 1) <= 25) {
        x += 2;
      } else {
        x = 0;
        y += 6;
      }

    } else if ((textline[count] == 'I') || (textline[count] == ':')) {
      if ((x + 1) > 25) {
        x = 0;
        y += 6;
      }
      msg.drawCharacter(textline[count], &frame, x, y);
      x += 2;

    } else if ((textline[count] == 'E') || (textline[count] == 'F') || (textline[count] == 'L') ||
     (textline[count] == 'T') || (textline[count] == 'Z') || (textline[count] == '1') ||
     (textline[count] == '<') || (textline[count] == '>') || (textline[count] == '=') ||
     (textline[count] == ';')) {
      if ((x + 3) > 25) {
        x = 0;
        y += 6;
      }
      msg.drawCharacter(textline[count], &frame, x, y);
      x += 4;

    } else if ((textline[count] == 'M') || (textline[count] == 'N') || (textline[count] == 'V') ||
     (textline[count] == 'W') || (textline[count] == 'X') || (textline[count] == 'Y')) {
      if ((x + 5) > 25) {
        x = 0;
        y += 6;
      }
      msg.drawCharacter(textline[count], &frame, x, y);
      x += 6;

    } else {
      if ((x + 4) > 25) {
        x = 0;
        y += 6;
      }
      msg.drawCharacter(textline[count], &frame, x, y);
      x += 5;
    }
   
  }
}

 



Forum Apprentice
Apprentice

Status: offline

Registered: 05/26/10
Posts: 3

Profile Email    
   
By: adambomb (offline) on Wednesday, May 26 2010 @ 11:20 PM PDT  
adambomb

Okay, I'm a real idiot sometimes. Shouldn't wait until it was so late to work on this. Turns out I should've read this page a bit more carefully. Issuing frame1.Clear() wipes the display clean properly.

Now, if I don't worry about scrubbing the string for "bad" characters, everything works perfectly. But when I do check, the entire LED field is still blank. This function works fine in a regular command-line test program. I have no idea what it's doing to the board.

PHP Formatted Code

void strip_nonvalid_characters(char *textstr) {
  int    i, j;
  int    textstr_length = strlen(textstr);
  char  temp_textstr[BUFFER_SIZE];
 
  for (i = 0, j = 0; i < textstr_length; i++) {
    if ((textstr[i] > 96) && (textstr[i] < 123)) {
      textstr[i] = textstr[i] - 32;
    }
    // ascii characters between 0 and Z and the space on http://www.asciitable.com/
    if (((textstr[i] > 47) && (textstr[i] < 91)) || (textstr[i] == 32)) {
      temp_textstr[j++] = textstr[i];
    }
    // ascii character for / turns into ;
    if (textstr[i] == 47) {
      temp_textstr[j++] = 59;
    }
    // ascii character for # turns into <
    if (textstr[i] == 35) {
      temp_textstr[j++] = 60;
    }
    // ascii character for . turns into >
    if (textstr[i] == 46) {
      temp_textstr[j++] = 62;
    }
    // ascii characters for ' ` " turns into ;
    if ((textstr[i] == 34) || (textstr[i] == 39) || (textstr[i] == 44)) {
      temp_textstr[j++] = 59;
    }
    // ascii character for ! turns into :
    if (textstr[i] == 33) {
      temp_textstr[j++] = 58;
      temp_textstr[j++] = 58;
    }
  }
  temp_textstr[j] = '\0';
  snprintf(textstr, BUFFER_SIZE, "%s", temp_textstr);
//  strncpy(textstr, temp_textstr, strlen(temp_textstr));
}
 


Forum Apprentice
Apprentice

Status: offline

Registered: 05/26/10
Posts: 3

Profile Email    
   
By: Windell (offline) on Wednesday, May 26 2010 @ 11:32 PM PDT  
Windell

1. Somebody needs to update the libraries to use all ASCII characters. Having to work around that is a major pain in the butt.



Can you please say which exact library and files you're referring to, and what it is that you're seeing?



2. How I assign values to the display strings determines whether or not the string for static display will be displayed. If I use snprintf, either a single line of LEDs lights up or nothing at all on the entire board. No scrolling text either. If I set up my strings like this, everything initially works fine:



> But if I do it like this, I get the aforementioned problem:
> [...]
>char textstrHeader[BUFFER_SIZE];
>char textstrScroller[BUFFER_SIZE];


That's obviously not the whole story, because you haven't said what BUFFER_SIZE is. If you still have it assigned as "#define BUFFER_SIZE 8192," then of course it isn't going to work. The ATmega328P has a grand total of 2048 bytes of RAM, including whatever frame buffers and overhead is taken by the Peggy2 and PeggyWriter libraries.


3. Finally, what's the best way to completely wipe the display so I can change the text? After the scrolling text is finished, I make a call to a refresh function (that uses snprintf, by the way) that results in the old static text remaining after the new static text is displayed. More frustrating: the scrolling text changes just fine!



To wipe the display clean, just stop calling the RefreshAll function-- it'll go dark, fast.

I think that what you're really asking about is somewhat different, maybe you mean clearing the frame buffer? Try writing all zeroes to it, or using frame1.Clear();.







Windell H. Oskay
drwho(at)evilmadscientist.com
http://www.evilmadscientist.com/

Forum Evil Scientist
Evil Scientist

Status: offline

Registered: 06/15/06
Posts: 1932
Sunnyvale, CA

Profile Email Website  
   
By: adambomb (offline) on Wednesday, May 26 2010 @ 11:48 PM PDT  
adambomb

Aw, jeez. That did it. Changing my default buffer size down to 256 fixed my string scrubbing. Damn.

Okay, last thing then is just this from the PeggyWriter readme.txt file:


CHARACTERS SUPPORTED

Only a limited subset of ASCII characters are supported. These run from '0' through to 'Z' in the standard ASCII table.

Specifically:
- Numbers '0' up to '9'
- punctuation marks: < > = : ; ? @
- Capital letters: 'A' through to 'Z'
- You can also output spaces

If you tell these functions to output characters outside of this set, the behaviour is undefined, and likely to crash.



Thanks for the help, though. This thing is going to be so sweet when I'm finished.


Forum Apprentice
Apprentice

Status: offline

Registered: 05/26/10
Posts: 3

Profile Email    
   
By: Windell (offline) on Wednesday, May 26 2010 @ 11:54 PM PDT  
Windell

>Okay, last thing then is just this from the PeggyWriter readme.txt file:

Sounds like they just didn't write out the font for more characters than those-- you can almost certainly extend that to more characters, but you'll need to add them one at a time.


Windell H. Oskay
drwho(at)evilmadscientist.com
http://www.evilmadscientist.com/

Forum Evil Scientist
Evil Scientist

Status: offline

Registered: 06/15/06
Posts: 1932
Sunnyvale, CA

Profile Email Website  
   



 All times are PDT. The time is now 10:05 PM.
Normal Topic Normal Topic
Locked Topic Locked Topic
Sticky Topic Sticky Topic
New Post New Post
Sticky Topic W/ New Post Sticky Topic W/ New Post
Locked Topic W/ New Post Locked Topic W/ New Post
View Anonymous Posts 
Able to Post 
Filtered HTML Allowed 
Censored Content 

Evil Mad Scientist Forum Archives — Read only!

Please visit our new forums for new discussions.


DIY Hardware for Electronic Art


The Original Egg-Bot Kit


Octolively
Interactive LED kits


Meggy Jr RGB
LED matrix game
development kit.


Business-card sized
AVR target boards


Peggy 2
LED Pegboard kits

My Account






Lost your password?