Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

6 Digits 7-segment display

Status
Not open for further replies.
There should be no limit to the number you use, it just gets slower to load all the bits to the one at the end of the chain

Something about working with 8 but not 9 makes me think the limit might be 256 clock pulses rather than the number of digits. Are you by chance using a 'char' or a byte in your software as the clock counter? If you are, try changing to a bigger variable type ('int' for example) so it can handle the bigger count number or try arranging the software to avoid sending all the bits/clocks in one go.

Brian.
 
Thank you,

Dear betwixt please see the code I paste defined in LedControl.C file.

Please see the blue lines it cannot take more than 8 devices so what would I do?

Code:
LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
    SPI_MOSI=dataPin;
    SPI_CLK=clkPin;
    SPI_CS=csPin;
    [COLOR="#0000FF"]if(numDevices<=0 || numDevices>8 )
        numDevices=8;[/COLOR]
    maxDevices=numDevices;
    pinMode(SPI_MOSI,OUTPUT);
    pinMode(SPI_CLK,OUTPUT);
    pinMode(SPI_CS,OUTPUT);
    digitalWrite(SPI_CS,HIGH);
    SPI_MOSI=dataPin;
    for(int i=0;i<64;i++) 
        status[i]=0x00;
    for(int i=0;i<maxDevices;i++) {
        spiTransfer(i,OP_DISPLAYTEST,0);
        //scanlimit is set to max on startup
        setScanLimit(i,7);
        //decode is done in source
        spiTransfer(i,OP_DECODEMODE,0);
        clearDisplay(i);
        //we go into shutdown-mode on startup
        shutdown(i,true);
    }
}
 

I think you can ignore the MOSI pin unless you want to read back the end of the chain to confirm data is passing all the way through.

I am not familiar with the version of 'C' running on Arduino so maybe it imposes a limit on the range of numbers you can use in "spiTransfer()". Everythig else looks good in the code you show.

Personally, I would write the SPI routine in my own code. All you have to do is make Enable low, set the data line for the 1/0 you want to send, make the clock low, make it high again and repeat until all the bits are sent. Finally, make Enable high again to terminate the process. It's just a simple software loop.

Brian.
 
Dear betwixt,

I am not familiar with the version of 'C' running on Arduino so maybe it imposes a limit on the range of numbers you can use in "spiTransfer()"

Please define above quote ,I did not make spiTransfer() function it is pre-build arduino function use LedControl Library.
 

I do not have an Arduino or any software for one so I was just guessing that the library function had a limit built in to it.

SPI is probably the easiest protocol to write yourself so I suggest you forget the library and use your own function instead. Refer to the timing diagram (Figure 1 in the Maxim data sheet) and write code like this:

1. Initialize with the LOAD (-CS) signal high and CLK signal low. This makes sure the ICs are ready to receive data but still dormant.
2. Prepare the 16 bits for the IC most distant from the Arduino
3. Make LOAD low, this enables all the ICs
4. Put the most significant bit (D15) on the DIN connection
5. Make CLK high, this shifts the bit into the first IC
6. Make CLK low
7. Shift the next bit to the DIN connection
8. go back to step 5 until all the bits have been shifted
9. Prepare the data for the next IC
10. go back to step 4 and repeat until all the ICs have their data
11. Make LOAD high. This will make all the displays update with their new digits simultaneuously.

In real C code it is only a few lines.

Brian.
 
Dear betwixt,

In library this function is defined

Code:
void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
    //Create an array with the data to shift out
    int offset=addr*2;
    int maxbytes=maxDevices*2;

    for(int i=0;i<maxbytes;i++)
        spidata[i]=(byte)0;
    //put our device data into the array
    spidata[offset+1]=opcode;
    spidata[offset]=data;
    //enable the line 
    digitalWrite(SPI_CS,LOW);
    //Now shift out the data 
    for(int i=maxbytes;i>0;i--)
        shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]);
    //latch the data onto the display
    digitalWrite(SPI_CS,HIGH);
}
 

You can see that follows the same path as the code I suggested but note that it expects all the data to be in an array of size "maxbytes", that's why it stops working for you when you add more devices. You are running out of array space to hold the data. You can try finding where "maxDevices" is defined and increase the number but there may be a reason why a limit was set by the library creator. I will return later with a code suggestion that overcomes the limit.

Brian.
 
Thank you,

There are some code for SPI, I googled.

FOR MASTER:
Code:
void spi_init_master (void)
{
    DDRB = (1<<5)|(1<<3);              //Set MOSI, SCK as Output
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //Enable SPI, Set as Master
                                       //Prescaler: Fosc/16, Enable Interrupts
}
 
//Function to send and receive data
unsigned char spi_tranceiver (unsigned char data)
{
    SPDR = data;                       //Load data into the buffer
    while(!(SPSR & (1<<SPIF) ));       //Wait until transmission complete
    return(SPDR);                      //Return received data
}

and FOR SLAVE:
Code:
void spi_init_slave (void)
{
    DDRB=(1<<6);                                  //MISO as OUTPUT
    SPCR=(1<<SPE);                                //Enable SPI
}
 
//Function to send and receive data
unsigned char spi_tranceiver (unsigned char data)
{
    SPDR = data;                                  //Load data into buffer
    while(!(SPSR & (1<<SPIF) ));                  //Wait until transmission complete
    return(SPDR);                                 //Return received data
}

- - - Updated - - -

Dear betwixt,

maxDevices is used in header file of library and it is not array it took int type,below

Code:
class LedControl {
    private :
        /* The array for shifting the data to the devices */
        byte spidata[16];
        /* Send out a single command to the device */
        void spiTransfer(int addr, byte opcode, byte data);

        /* We keep track of the led-status for all 8 devices in this array */
        byte status[64];
        /* Data is shifted out of this pin*/
        int SPI_MOSI;
        /* The clock is signaled on this pin */
        int SPI_CLK;
        /* This one is driven LOW for chip selectzion */
        int SPI_CS;
        [COLOR="#0000FF"]/* The maximum number of devices we use */
        int maxDevices;[/COLOR]

Another function is used in library "int getDeviceCount();"

I am searching where it is situated.
 

Dear betwixt,

I changed the following buffer size and loop condition as you described in post 27 and it works for 9 as well as 10 devices and so on.

Thank you very^3 much for your co-operation.

Code:
LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
    SPI_MOSI=dataPin;
    SPI_CLK=clkPin;
    SPI_CS=csPin;
    if(numDevices<=0 || numDevices>8 )
        numDevices=8;
    maxDevices=numDevices;
    pinMode(SPI_MOSI,OUTPUT);
    pinMode(SPI_CLK,OUTPUT);
    pinMode(SPI_CS,OUTPUT);
    digitalWrite(SPI_CS,HIGH);
    SPI_MOSI=dataPin;
    [COLOR="#0000FF"]for(int i=0;i<64;i++) i<72 for 9 devices  and  i<100 for 10 devices [/COLOR]
        status[i]=0x00;
    for(int i=0;i<maxDevices;i++) {
        spiTransfer(i,OP_DISPLAYTEST,0);
        //scanlimit is set to max on startup
        setScanLimit(i,7);
        //decode is done in source
        spiTransfer(i,OP_DECODEMODE,0);
        clearDisplay(i);
        //we go into shutdown-mode on startup
        shutdown(i,true);
    }
}

class LedControl {
    private :
        /* The array for shifting the data to the devices */
        [COLOR="#0000FF"]byte spidata[16]; 18 for 9 devices and 20 for 10 devices[/COLOR]
        /* Send out a single command to the device */
        void spiTransfer(int addr, byte opcode, byte data);

        /* We keep track of the led-status for all 8 devices in this array */
        [COLOR="#0000FF"]byte status[72]; 72 for 9 devices  and  100 for 10 devices[/COLOR] 
        /* Data is shifted out of this pin*/
        int SPI_MOSI;
        /* The clock is signaled on this pin */
        int SPI_CLK;
        /* This one is driven LOW for chip selectzion */
        int SPI_CS;
        /* The maximum number of devices we use */
        int maxDevices;
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top