Not quite a dummie

21 Nov 2010

I have been trying to get a user-defined LED display to run on the mbed. I know nothing about anything. And C++ For Dummies has been over my head and not supplying the answers.

What I have today runs nicely, but some light patterns are not being interpretted correctly.

The user writes an array made up of 4-digit values: e.g. 0110 or 1111. A zero represents one of the four LEDs off. A one represents one of the four LEDs on. The digit's position in the number equates to the positon of the LED in the 4-LED display.

Reading other posts this morning, it seems that I need to look into 'parsing' and 'formatting.' Something about '%d."

Any help will be appreciated.

The program is called LED11-Lightshow and a believe it is attached here.

 

 

LED11_Lightshow

21 Nov 2010

I have had a little look at your code, and i assume you want to drive 4 leds, with a pattern (in an array...)

 

the best soution for this is ..

BusOut LedDisplay (LED1, LED2, LED3, LED4);       // assosiate 4 leds with the lower 4 bits of a number..

00006 DigitalOut myledd(LED4);
00007 
00008 int nDisplayTemp;
00009 int i;
00010 int nDisplay[100]={                                                          // set number in array
00011                     1000,0100,0010,0001,1000,0100,0010,0001,1000,0100,      // 1:  0 - 09 light display
00012                     0010,0001,1000,0100,0010,0001,0000,1111,0110,1001,      // 2: 10 - 19 light display

the above data in the array is, for 1111 One Thousand, One Hundred and eleven,
where i assume you want 4 leds on,
you need

in binary:   0b00001111
in HEX: 0x0f
 in decimal: 15.

and you can simpley use

LEDDispal = 0b0000101;

or, using array data ..

LedDisplay = nDisplay [x];




Hope this helps,


 Ceri. 

21 Nov 2010

if your using a pc interface, via the usb cable, look at the serial section in the handbook.

the bus is documented in handbook.

 

one way to format it is to use multidimensional arrays. scary...

int display [20][4];(assignments for this should be documented in C++ for dummies, I've forgotten)

twenty rows, four columns or four rows, twenty columns. doesn't matter. pick a represntation.

display [n][0]; gives the value for led 0(number everything from zero, its easier) likewise display [n][1] for led 1......

you can easily use a for loop, to go through the light display.

set each led to the corresponding section of the array, display [n][0]; n is the counter in the for loop. for ( inital condition; exit condition; operation)

have a wait for whatever length of time you want between changes.

 

works perfectly, assuming you followed it.

however int is a waste of memory, declare

bool display [20][4];

you use 80 bits of memory, and achives the same result. bool stores 0 or 1, led on, led off.

int display [20][4];

uses 80 interger values, depending on hardware used this is 8, 16, 32 or 64 times more space to store 1 or 0. hence when storing a on or off value bool is better.  of course if you need to store an interger value, bool isn't much good.

22 Nov 2010

Thank you very much for trying to be of help.

My specific problem is that my code does not seem to be producing consistent results with the mbed LEDs.

I am trying to get the mbed to accept a simple user-arranged sequential flashing LED pattern. The user is not required to know anything about the equipment. He only needs to know that 1111 means all four LEDs will be on, and 0000 means that all four LEDs will be off. 0100 means that only the second LED will be on.

He can then write a sequence of numbers, e.g. 0110,1001,0100,etc, that will result in the LEDs flashing in the sequence of his choice.

This is my first attempt to use the mbed and is my first attempt to program in C++. I understand that it is basic to the extent of being primitive. But I would like to be able to do some of the fantastic things that I see people doing with the mbed. And so there is much I need to learn.

The problem:

After much work and debugging, my code runs well but only produces the correct LED pattern on 11 number configurations:    0000,1000,0100,0010,0001,1111,0111,0011,1001,0110,1011. These numbers processed by the code will produce the correct pattern of LEDs illuminated.

However, these numbers processed by the same code produce erroneous LED pattern: 1100,1110,1101. These numbers will all produce a pattern of all LEDs on.

So, am I violating some syntax rule of C++ or going about this in the wrong way.
                                               

Here is the code that processes the four digit numbers and determines the resulting LED pattern.

 

int main() {
    while (1){
    for (int i=0; i<40; i++) {                                                 // set i = array number
    if (nDisplay[i]>=1000)                                                   // light no 1 : on or off
    {   myleda = 1;
        nDisplayTemp = nDisplay[i] - 1000;
        }
    else
    {   myleda = 0;
        nDisplayTemp = nDisplay[i];
        }
    if (nDisplayTemp >= 0100)                                               // light no 2 : on or off
    {   myledb = 1;
        nDisplayTemp = nDisplayTemp - 0100;
        }
    else
    {   myledb = 0;
        }
    if (nDisplayTemp >= 0010)                                               // light no 3 : on or off
    {   myledc = 1;
        nDisplayTemp = nDisplayTemp - 0010;
        }
    else
    {   myledc = 0;
        }
     if (nDisplayTemp >= 0001)                                              // light no 4 : on or off
     {  myledd = 1;
        }
     else
     {  myledd = 0;
        }  
 
        wait(0.5);
        myleda = myledb = myledc = myledd = 0;                              // 0.2 sec : all lights off
        wait(0.5);
    }
   }
}

22 Nov 2010

Hi David,

You'll kick yourself, or the people who defined C, or whoever is nearby. But this is one of those that is only obvious *once* you've spotted it, even if you have programmed for years.

In C, a number starting with '0' is interpreted as an Octal (base 8) number!

So that means your numbers are mixing bases :)

1000 is decimal 1000

0100 is decimal 64!

I'll leave it at that for now, but please ask if you'd like any further advice on approaches, and i'm sure people can help you out.

Simon

22 Nov 2010

You nneed to add 0b???? to ALL of your numbers in the array, and in your maths,

I still think using BUSOUT will improve your codes readability.

you should have a look in wickapidia for some info on binar/octal/hex numbering sysetms,

there should be some thing to give you that lightbulb moment ;)

 

Ceri

22 Nov 2010

Hi Ceri,

Just to clarify, "0b" is not actually valid in C. The integer number systems supported in C are:

  • Decimal (e.g. 15)
  • Hexadecimal (0xF)
  • Octal (017)

Binary is (unfortunately) not one of them.

Simon

22 Nov 2010

Simon Ford wrote:

Just to clarify, "0b" is not actually valid in C. The integer number systems supported in C are:

  • Decimal (e.g. 15)
  • Hexadecimal (0xF)
  • Octal (017)

Binary is (unfortunately) not one of them.

This was always something that bugged me. I'm not a programmer by trade (Just a lowly MechE that knows enough to be dangerous in electronics and programming) and so having to convert back and forth from binary for bit masks, to hex for programming drove me nuts. I stumbled across these #define statements that let you use the Ob(x) directive to implement binary values. Thats O as in Ohhh and b (not zero). It works great for setting up #define's for bit masks and all the compiler ever sees is the hex version.

#define Ob(x)  ((unsigned)Ob_(0 ## x ## uL))
#define Ob_(x) (x & 1 | x >> 2 & 2 | x >> 4 & 4 | x >> 6 & 8 |		\
	x >> 8 & 16 | x >> 10 & 32 | x >> 12 & 64 | x >> 14 & 128)

If you add those statements to the top of your code, you can then say things like:

int test Ob(11111111);

or

#define test Ob(11111111)

Hope this helps

Tim

22 Nov 2010

OK, I think I am catching on.

Thank you very much for helping me to see the way over this hurdle.

 

Now on to win the challenge.

Cheers.

23 Nov 2010 . Edited: 23 Nov 2010

I got to admit that I liked the challenge presented here, since I am still playing around with C (I code in assembler most of the time).  Here is working code that makes use of Ceri's suggestion:

 

 

#include "mbed.h"

BusOut LedDisplay (LED1, LED2, LED3, LED4); 

unsigned int i;

int nDisplay[100]={                                                          // set number in array
                    8,4,2,1,8,4,2,1,8,4,      // 1:  0 - 09 light display
                    2,1,8,4,2,1,0,15,6,9,      // 2: 10 - 19 light display
                    6,15,0,1,2,4,8,1,2,4,      // 3: 20 - 29 light display
                    8,1,2,4,8,1,2,4,8,0,      // 4: 30 - 39 light display
                    15,6,9,6,9,6,15,0,8,12,      // 5: 40 - 49 light display
                    14,15,3,3,1,0,1,3,3,15,      // 6: 50 - 59 light display
                    14,12,8,0,15,9,6,9,15,15,      // 7: 60 - 69 light display
                    3,3,1,8,12,14,15,0,14,13,      // 8: 70 - 79 light display
                    11,3,14,12,8,0,15,8,12,14,      // 9: 80 - 89 light display
                    15,3,11,13,14,15,6,13,11,15};     //10: 90 - 99 light display
int main() {

    while (1){
    for (int i=0; i<100; i++) {                                                 // set i = array number
     
     LedDisplay = nDisplay[i];

       wait(0.2);

        LedDisplay = 0;               // 0.2 sec : all lights off
        wait(0.2);
    }
   }
}
23 Nov 2010

Thank you Mitch and Ceri and everyone else.

Your code is beautiful in its brevity and compactness, Mitch.

I am guessing that the array numbers are now the decimal equivalents of what had been binary digits.

I don't understand how 'nDisplay[i]' indicates how many lights should be on or off to the processor.

But I am on my learning journey and will find out eventually.

I have loaded your code and it works great. Now I need to come up with something that translates the original user-understood binary light pattern to decimal numbers. That should be manageable.

Thanks again.