Loading...
Logo
Processing Forum
Hi there,
I'm trying to control a LED indicator board via Processing. Opening a connection and sending text works perfectly. But the board is also capable of displaying simple graphic data.

This is the board I'm working on: LED board and here's a link to the data sheet

If I'm sending simple text to the board, everything displays nicely. But if I'm trying to send graphic data, the board turns black and a few LEDs light up randomly for maybe a second. The previous contents seem to be replaced, but the replacement seems to contain incorrect data.

A working text message looks like this:
Copy code
  1. <ID01><L1><PA><FE><MA><WA><FE><AA><N00>My text goes here2E<E>
<ID01> specifies the ID of the LED board, all other <> tags specify pre-set effects (like animation-in, animation-out, etc.). The 2E is the checksum of the text, <E> is the end tag.

The data sheet (p. 13-14) says, that a graphic block basically is build the same way.
Copy code
  1. <Gxn>..Graphic data
e.g.
Copy code
  1. <GA1> Graphic data
So I thought a successful data package should look something like this:
Copy code
  1. <ID01<GA1>10000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000010000000035<E>
  2. <ID01><BE><L1><PA><FA><MA><WA><FA><GA1>46<E>
The LED board came with a little helper tool called "NewSign 03127 or 03128". I logged communcations between the tool and the LED board using a USB port monitor. This is an excerpt how the data of a Graphic block looks like then:
Copy code
  1. <ID01><GA1>¨ ¨*(((*(*        ¨ª¨ª  ª ª ª BD<E>
Does anyone have a clue how the message has to be built? What am I doing wrong? Any hints are highly appreciated!

Replies(7)

Quote from the datasheet (page 14):

Four Pixel is represented by 1 Byte. 

What you are doing is sending the individual 1s and 0s as an ASCII character each. So before sending out you have to pack your information into individual bytes.


Here is a dirty example on how you would convert a string of eight 1s and 0s to a byte that you can send over the Serial connection.


              
Copy code
  1. int number = 0;
  2. String text = "10000100";

  3. for(int i = 0; i < 8; i++) {
  4.   number = number << 1; // Left shift. See the processing reference for meaning of the bitwise operators
  5.   
  6.   if( text.charAt(i) == '1' ) {
  7.        number = number + 1; 
  8.   }  
  9. }


  10. byte sendByte = (byte)number;

  11. println( "Our byte value (signed) is: " + sendByte );
allesblinkt, you're the man! Awesome, the conversion did the trick! Thank you so much!

Just because I'm curious. Why would you call your presented conversion method "dirty"?
Glad it worked for you. Normally one wouldn't construct a String of 1s and 0s and then convert it to a binary, but rather do it directly. But it's easier to understand that way...
Ah I see, thanks for the clarification!

As I am planning to build a matrix using PGraphics and "translate" the matrix to the LED screen, I reckon I won't need the conversion.

Sorry if that's a stupid question - how would I do that without the conversion detour?
I would loop through the pixels ( by using the pixels array or get() ) of the PGraphics in the order your display expects them. While doing this you can construct a byte for every four pixels. So for every pixel of the matrix you have to shift your byte twice. and in between the shifts you have to decide if you add a 1 to turn on the red or green... 

Once you have filled one byte, store it in an array. So when sending you can just send the array of bytes. I think the Serial. write function supports that.

The bitwise operators are difficult to grasp at first, but they are not black magic... 
Great thanks allesblinkt, that's about the way I was thinking too (theoretically..)! My board only supports red LEDs, so I'll just have to differentiate between LED on / LED off (whew).

I'm still struggling with the concept of bytes and shifting. After more research and reading I get the basic idea of leftshifting. I just don't understand how I get from the value from pixels[] to my constructed byte. I want to construct a variable with datatype byte. But the shift operation just works on int variables!?

In my case, pixels[] contains the color datatype. Can I do something as simple as
Copy code
  1. if(pixels[i] == red)
  2.       value_for_LED_on
I couldn't figure out how to build the byte correctly. Would something like this be the right way to go (just the basic idea)?
Copy code
  1. byte fourleds;
  2. if(pixels[0] == red)
  3.       fourleds << 2;
  4. if(pixels[1] == red)
  5.       fourleds << 2;
  6. ...
You have to shift on every step.... Then you have to decide wether to set the bit to one or not.
You can just use an integer and convert it (cast) to a byte when actually sending it.
              
Copy code
  1. int fourleds = 0;

  2. for(int i = 0; i < 4; i++) {

  3.   fourleds = fourleds << 1; // Shift one time

  4.   if( red(pixels[i]) > 127) { // more than 50% red?
  5.     fourleds = fourleds + 1;  // Set the rightmost bit to one
  6.   }
  7.   
  8.   fourleds = fourleds << 1; // Shift another time
  9. }


  10. println( (byte)fourleds );