LED driver

Go To Last Post
29 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello

I'm working on a speedometer for my old motorcycle but I cannot find any example/tutorial for the SCT2210CSTG led driver. Because my uC(Atmega 8, 4mhz external clock) doesn't have enough outputs for drive direcly the LED + the current flow on one LED is around ~17mA at 5V "¦ so what I need was an led driver and only this model of driver I can get it easily . The speedometer will have 32 LED(2 led drivers).
My concern is how to use this led driver? I haven't work with any type of LED driver or serial driven equipment.

http://www.starchips.com.tw/pdf/sct2210/

I've been looking on the data-sheet but for me it is a nightmare.could somebody give me an example of code how for this led driver?

ps. because is a smd type IC at this moment I cannot test, I need to make the final PCB with all the peripheral on it.
Here is the connection diagram:

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pseudocode

Quote:

arrange for LED data to be in four elements of an array
repeat 4 times
fetch data from array (use loop counter for index)
repeat 8 times
output bit
clock bit
latch drivers

Charles Darwin, Lord Kelvin & Murphy are always lurking about!
Lee -.-
Riddle me this...How did the serpent move around before the fall?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You do not need resistors in series with LED's. Just set the current via resistor on pin Rext.
Merge LDEVRIES code with timing diagram on page 3. In other words - push a sequence of output data to SDI, clocked by CLK; latch by /LA at the end of sequence, and enable outputs via /OE. Connect drivers in series as per page 9 diagram (except dynamic MOSFET driver).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks guys.it is possible to give me an code example? I'm beginner and I haven't work with serial peripherals.
@Kas do you think it is better to use Rext for the current limiting? I have chosen this method because the power dissipation will be on each resistors and the IC doesn't need to control the current flow.
Iout = 30(630/Rext) => 30(630/1.2k) = 15,75mA
Ok I limit the current to 15mA but the output voltage will be the same and the LED's can handle only 2V.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You should not care about LED voltage - just set the current limit and it's OK. The LED's forward voltage will be around 2V, the rest will fall onto driver.
For coding, the ball is in Your hands:
choose a language
start coding or pick up something alike for modification.
BascomAVR, for instance, has few useful examples. GCC too, for sure.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sorry i forgot to mention that i'm writing in C(Avr Studio).Now i will start to draw the PCB and i hope tomorrow i can finish it for testing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I agree about not needing all those resistors ( read your datasheet about Rext ). You're wasting your time/money using those resistors when the chip's designed to save you BOTH. Read Atmel's A.N., AVR151, about using SPI, it's a simple interface to setup and use. I could give you example code, but you wouldn't understand it. So it's better if you study and implement it ( it really won't take you long, about 1-2 hrs ( not inc. the time to read the AN ), esp. if you include googling something like "avr spi" ). You'll learn more and get more confidence doing it this way. If your code doesn't work though, post it here and we'll help you with it.

According to your diagram, you'll have to do a software spi. WHY would you do THAT ?! Just use the builtin spi and simplify your life. You must tie ALL three SPI lines of both drivers to the AVR spi. Then 2 control lines / driver ( LA and OE ). You must tie ALL three SPI lines of both drivers to the AVR spi. Whether it's s.ware or h.ware spi. Then 2 control lines / driver ( LA and OE ), so 4 ttl. but maybe you can share one of those between the 2 chips and end up with 3 ttl.

I suggest you write the LED driver ONLY for now in your main(), until you get its basic coding I/F down.

SPI_init(void);
SPI_write(value_for_LEDs);
SPI_read(some_dummy_value);

These 3 are all you need to do SPI work and they're each very short.

Make your ground trace as fat as you can wherever you can.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi and thanks for everything.

I had manage to make the PCB(i used Sprint Layout 5 and I haven't ssop24 IC library so I done one).
Now is the connection questions.
Rext is reference resistance or shunt resistance?
How can I protect the programmer(USBASP) outputs if I use the same ports of uC like the LED driver? (MOSI,MISO,SCK).I seen in one of AVR A.N. The ISP connection was in series with a resistance but it haven't specify the value.
And at the last how can I connect the led driver to uC?
uC 3 SPI lines:

MOSI - sdi
MISO - ?
SCK – sck

and the other OE, LA where are connected?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rext I guess you can think of as a ref. since it sets the current to a constant. See my last post about SPI and LA / OE pins ( any GP I/O as output pins can be used to connect these controls lines ). If you don't need MISO, you don't have to connect them.

You might as well use the MCU /SS pin as 1 of the 2 needed "chip selects". Your MCU datasheet should be all you need to write the SPI()s, but do read AVR151 also for your own good ( when you get the free time -- just a suggestion of course ). :)

You could connect the 2 according to pg. 9 of the driver datasheet and it'll save MCU pins. But then you'd always have to write to both drivers. Connecting their SPI pins separately to MCU lets you write to either at any time. Probably best for you, noobie ! You can repost the new schematic after you're done, for us to check it before coding if you want.

Protection resistors are used if a device on the SPI tries to drive any lines ( AVR042 ). Vdrive / Rspi = current into programmer--- So use this to make sure that the programmer's Imax isn't exceeded. I don't know that you're at risk of an LED driver chip doing that. My LED driver chip, MAX6971, hasn't given me any problems yet in my programming cycles ( I don't have the ISP resistors ).

I also have an MP3 design that has a decoder chip and an SD card on the SPI bus and no problems. It's up to you, though.

I suggest only connecting 1 of the drivers and get it working, then do the other one. The SPI_read is just the SPI_write() and you do a return( SPDR ) as last step. You may not want / need to read from the driver , then don't worry about writing an SPI_read() !

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

Last Edited: Tue. May 3, 2011 - 01:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

here it is the schematic of what i've thought.
The SDI, LA, SCK lines are connected together on both LED drivers and only the OE pins are connected separate to the MCU.unfortunately i'm not glad to use this type of connection because the no. of MCU used pins so maybe i will chose another MCU(Atmega16).
It is good this connection(with OE to select the driver) or i will need to use separate pins for LA as well?
question: can i use MISO pin for output, when SPI is activated? for example to drive LA or other propose?

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
question: can i use MISO pin for output, when SPI is activated? for example to drive LA or other propose?
No, MISO is a shift register output and you can only tie it to a S.R. input.

/LA --Latches (stores ) data to the driver.

/OE -- Turns output ON/OFF.

From the datasheet, it looks like MAYBE LA's can be tied together BUT both chips will show the same LED pattern, if that's what you want otherwise they have to be separate.

Vdd connect for the drivers doesn't look right to me.

Vcc
|
|
R
|--> driver
|
C
|--> ground, seems right. But it already has builtin POR, so only a decoupling cap. from Vdd --Gnd is needed.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

if both driver will show the same that's isn't good for me, so i think i will 'sacrifice' another pin to drive LA independent for both chips.

and about the supply connection i've used the connection from the datasheet page:10

ps. what clock frequency i should use to drive the SCK line? on datasheet is specify that accept max 25Mhz serial transfer rate ... which is too high, compared with my MCU clock 4Mhz.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mzchristensen Pg. 10 and mine are the same, your's is NOT ( check it again and see ). :wink:

SPImax = CPU / 2, so any speed you want that's <= 2 MHz ( try prescaler of /8 for now, until you get it working ). Once it's working you can max. it out if you want.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sorry, you had right, i've corrected the schematic.

I've connected only the first LED driver:

LA1 - PC3
OE1 - PD7
SDI - MOSI PB3
CLK - SCK PB5
PB2 - PWM out

void SPI_MasterTransmit(char cData)

{

/* Start transmission */

 PORTD &= ~(1 << 7); // pull low the OE line

SPDR = cData;

/* Wait for transmission complete */

while(!(SPSR & (1<<SPIF)));

PORTD |= (1 << 7); // pull high the OE line

}

void SPI_MasterInit(void)

{

// port direction
DDRB |= (1 << 2) | (1 << 3) | (1 << 5); // Set PB2,PB3,PB5 as output
DDRD |= (1 << 7); // Set PD7 as output
DDRC |= (1 << 3); // Set PC3 as output

// SPI setup
// clock rate fck/8 = 500Khz
SPCR |= (1 << SPIE) | (1 << SPE) | (1 << DORD) | (1 << MSTR) | (1 << SPR0);  

/*
Whant should i selet for DORD:
DORD=1, LSB will be transmitted first.
DORD=0, MSB will be transmitted first.

I don't know how to setup the CPOL and the CPHA.

*/

SPSR |= (1 << SPI2X);

}


int main(void) {

SPI_MasterInit();

SPI_MasterTransmit('???'); 

   while(1)

 {

 }

}

I don't know if OE is correct controlled and what to do with LA.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I don't know if OE is correct controlled and what to do with LA.

Good work, you're almost there !

You have to think about EVERY config. bit that you need to set for any peripheral and since you don't use an SPI_ISR() don't set SPIE.

Quote:
What should i select for DORD:

Ref. driver D.S. pg. 3 ( timing diagrams read left to right ): This shows MSBit (OUT15) is sent on 1st clk, so DORD = 0 . It also means that the driver's SDI is internally connected to the LSbit of its 16 bit serial-to-// shift register. 0xA0(MSB) and 0x03(LSB) are being sent, overall.

Quote:
I don't know how to setup the CPOL and the CPHA.
pg. 3 shows the clk idles, or starts out, low and d.s. states chip samples on rising edge ( both facts are shown in the diagram and it's what the up arrow means on clk ( sampling ) ). Look at the m8 SPI diagrams for those 2 signals and see that CPOL = 0 makes it idle low and CPHA = 0 to sample on rising. The rest of your SPI_INIT() is right . :D

static inline void SPI_MasterInit(void) 

would save some bytes ( See "minimizing functions" tutorial in that forum when you get time after this pjt. to see why. Don't worry about it now ).

For your transmit, look at pg. 3 again and see that your code doesn't follow the timing. It's showing you that the 2 bytes are sent out, MISO doesn't output MSBit until the 16th clk and the control signals are disabled. When 2nd byte sent, THEN raise and lower /LA, THEN lower and raise /OE. See my previous post about these 2 signals functions and think about it as you study the diagram.

So do this :

void SPI_MasterTransmit(char cData)

{

/* Start transmission */

SPDR = cData;

/* Wait for transmission complete */

while(!(SPSR & (1<<SPIF)));

}

I would do this for the control lines:

#define   SET_LA      PORTC |= (1 << 3); 
#define   CLR_LA      PORTC &= ~(1 << 3);

same for /OE, makes it easier to see what's goin' on in the code, especially when you come back to it months / years later .

main(void){
.
.
.
   SET_OE; //Initialize these...
   CLR_LA; //... 2 lines.

   SPI_MasterTransmit(0xA0); // Send MSB
   SPI_MasterTransmit(0x03); // Send LSB


   SET_LA;
   CLR_LA;

   CLR_OE; // pull low the OE line
   SET_OE; // pull high the OE line

   while(1);

} // End main()

So your biggest lesson learned is for you to see that your SPI config., and the transmit() [ and any read() ] can be coded for based on a good enough timing diagram in a datasheet even if it's a new chip for you ( it was for me ), and knowing the basics of SPI. D.S.'s not as big a nightmare as you thought, right ?

Your PWM FET is hooked up like a BJT with those 2 resistors, I don't know if it'll work like a switch or not. See the driver d.s. PWM FET. You can tie PWM_signal to /OE1 and skip the FET. Keep /OE1 high when sending data if you do, though. You only do PWM if you want to vary the brightness of the LEDs.

PC3 may not work right since some AVRs need the AVCC connected for the port to work right ( even though the ADC isn't used ).

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for all you help.
I've manage to connect the driver and test the code it is working properly ( conform the datasheet page 3 the 15,13,1 and 0 outputs are enabled)
but i have some questions about the SDI line.
From where is the value of MSB and LBS? the A0=160 in decimal and for me doesn't mean anything.

SPI_MasterTransmit(0xA0); // Send MSB
   SPI_MasterTransmit(0x03); // Send LSB 

i've try to send to thr driver anther value like: 0x01=output0, 0x02=output1, 0x03 = 0,1 outputs, 0x04=output2 ... there aren't a 'logic' value for the result, or maybe my approach for this driver isn't good.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mzchristensen, congratulations you did very good work ! I'll bet you feel better about learning SPI this way than someone just giving you the code. :D

OP wrote:
From where is the value of MSB and LBS?
Do you mean how did I get those 2 values for sending to the driver ? I don't really get your question.

OP wrote:
i've try to send to the driver another value like: 0x01=output0, 0x02=output1, 0x03 = 0,1 outputs, 0x04=output2 ... there aren't a 'logic' value for the result, or maybe my approach for this driver isn't good.
Are you saying you tried sending the above values and it DIDN'T work ? If that's what you mean, show us the code for how you sent any one of the values that didn't work.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Do you mean how did I get those 2 values for sending to the driver ?

Yes
Quote:

Are you saying you tried sending the above values and it DIDN'T work ? If that's what you mean, show us the code for how you sent any one of the values that didn't work.

Yes, it works but i don't get the logic about how i get the correct value to the desired output.
ex. i want to enable the 5th output how i do that?
Here is my code:

/*
LA1 - PC3
OE1 - PD7
SDI - MOSI PB3
CLK - SCK PB5
PB2 - PWM out 
*/

#include 

#define   SET_LA      PORTC |= (1 << 3); // pull high the LA line
#define   CLR_LA      PORTC &= ~(1 << 3); //pull low the LA line

#define    CLR_OE 	PORTD &= ~(1 << 7); // pull low the OE line
#define    SET_OE 	 PORTD |= (1 << 7);// pull high the OE line

void SPI_MasterTransmit(char cData)

{

/* Start transmission */
SPDR = cData;

/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));
} 

void SPI_MasterInit(void) 
{
// port direction
DDRB |= (1 << 2) |  (1 << 3) | (1 << 5); // Set PB2,PB3,PB5 as output
DDRD |= (1 << 7); // Set PD7 as output
DDRC |= (1 << 3); // Set PC3 as output 

// SPI setup
// clock rate fck/8 = 500Khz
SPCR |=  (1 << SPE)| (1 << MSTR) | (1 << SPR0); 
SPSR |= (1 << SPI2X); 
}

int main(void){

SPI_MasterInit(); 

 SET_OE; // pull high the OE line
CLR_LA; //pull low the LA line
   while(1)
   {
     
    SPI_MasterTransmit(0x01); // Send MSB
  //SPI_MasterTransmit(0x03); // Send LSB

 SET_LA; //pull high the LA line
CLR_LA; //pull low the LA line

   CLR_OE; // pull low the OE line
 SET_OE; // pull high the OE line
   }
} 

and another thing i've noticed, when i want to drive 2 outputs, output 0 and 1 the correct value for them is 0x01 and 0x02

SPI_MasterTransmit(0x01); // Send LSB
SPI_MasterTransmit(0x02); // Send MSB

only the output 1 is enabled.
to enable both outputs i need to send 0x03 and then there are 3 enabled outputs but i want only 2 (0,1 and the 9th) to disable the 9th output i needed to send 0x00 at the beginning:

SPI_MasterTransmit(0x00); // disable the 9th output 
SPI_MasterTransmit(0x03); // enable the 0 and 1 output
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Those 2 values are from the datasheet, pg 3. Whenever SDI = '1'( binary ) when there's a clk means that bit value SENT was '1' for the corresponding position. You must ALWAYS send MSByte 1st since DORD = 0.

MSByte = out15 - out8( pins ), so if you wanted out15 = '1' and out13 = '1' and the rest to be '0', then binary: 1010 0000 = 0xA0 hex. Same for LSByte and you get 0x03. So decide which outs you want 'ON' and work it out 1 byte at a time, just as I've done in this example and use binary FIRST, then convert to hex.

Quote:
ex. i want to enable the 5th output how i do that?
That's out4, so I assume you mean ALL other outs = zero. Then, by my method we know right away that MSB = 0x00 and LSB = 0001 0000 = 0x10. So send those two bytes, MSB, then LSB.

SPI_MasterTransmit(0x01); // Send MSB
  //SPI_MasterTransmit(0x03); // Send LSB 

You CANNOT comment out either of those 2 lines ! You must send 2 bytes even if you desire only ONE LED on ! :cry: The driver expects 2 bytes every time.

SPI_MasterTransmit(0x01); // Send LSB
SPI_MasterTransmit(0x02); // Send MSB

You interchanged the ( MSB, LSB )order of these and that's also something you CANNOT do.

Quote:
and another thing i've noticed, when i want to drive 2 outputs, output 0 and 1 the correct value for them is 0x01 and 0x02
True, individually those are the values for those outputs, but always remember you're sending bytes, not bits. So referencing my method above, MSB = 0x00( all 8 outs OFF ), LSB = 0000 0011 = 0x03. Which is what you have in your last example.

I should have given you an even better way for the #defines:

Style 1:

#define   SET_LA_1      PORTC |= (1 << PC3); // pull high the LA_1 line

#define    CLR_OE_1    PORTD &= ~(1 << PD7); // pull low the OE_1 line 

OR
Style 2:

#define   LA_1  PC3
#define   SET_LA_1    PORTC |= (1 << LA_1); // pull high the LA_1 line

#define    OE_1    PD7
#define    CLR_OE_1    PORTD &= ~(1 << OE_1); // pull low the OE_1 line

Style #2 is more self-documenting and easier on my debugging eyes when I use it !

Also OE must be low for as long as you want to have the LEDs ON. Your structure up to this point should be:

.
.
. 
  SET_OE; // pull high the OE line
  CLR_LA; //pull low the LA line  
 
  SPI_MasterTransmit(0x00); // Send MSB
  SPI_MasterTransmit(0x03); // Send LSB

  SET_LA; //pull high the LA line
  CLR_LA; //pull low the LA line

  CLR_OE; // pull low the OE line
  
  while(1);
.
.
.

Finally, since you'll be writing to the drivers many times what's best is to make a function:

void   driver_1( uint8_t MSB, uint8_t LSB ){

  SET_OE_1;  // pull high the OE line
  CLR_LA_1; //pull low the LA line  

  SPI_MasterTransmit( MSB ); // Send MSB First
  SPI_MasterTransmit( LSB ); // Send LSB

  SET_LA_1; //pull high the LA line
  CLR_LA_1; //pull low the LA line

  CLR_OE_1; // pull low the OE line

}

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

:D thank you very ... very much :D
now i it is clear for me.
always i need to send 2 bytes.
MSB and LSB have each 8 bytes which define the outputs 15 to 8 and 7 to 0.
Before it was sooo hard to understand, always i've searched for the meaning of sent bytes value and it was so simple ... binary ... dam how stupid i'm!
Now again a question(at this moment i don't have connected the hardware and before i do some stupid things is good to know how can i drive in series 2(or more) led drivers SDI => SDO).
In this case i will send 4 bites?

Thanks again mr. indianajones11 ... all my respect!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It took me a while to not fret about the inefficiency of wasted computer cycles. You keep clevering the algorithm up until its fast enough, then start shipping.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
...so simple ... binary ... dam how stupid i'm!
No, you just have to LEARN when to switch up your thinking ( for number representations ) !
Quote:
Thanks again mr. indianajones11 ... all my respect!
I'll take it where I can get it ! You're welcome .
Quote:
...is good to know how can i drive in series 2(or more) led drivers SDI => SDO
No, do SDO-->SDI. So SDO the first 1 (#1) to SDI of the 2nd (#2). It takes 2 bytes / driver chip, so yeah 4 bytes total for that connect. But for that connect you will only toggle BOTH chips' control lines after the 2nd SPI write ( and you can tie the LA and OE of each chip together, so you only need TWO control pins from MCU ).You'd use the driver_1() twice, but the 3 toggles at the end of that function you would take out and put where... ?

Think about it if you don't get that and review shift registers if needed. Series or // connection, think about what should happen and when ( "BE the circuit" ). You've been a good student and a quick study.:D

Now you should copy those SPI functions to their own file spi.c and folder ( "SPI" ) outside of ALL your apps ( and add more functions later ). This way when you have future SPI applications, you can just go to your SPI folder and COPY the spi.c file to the pjt. folder and you KNOW they work, so you're done ! If you do this you'll have to take out

DDRD |= (1 << 7); // Set PD7 as output
DDRC |= (1 << 3); // Set PC3 as output 

from SPI_MasterInit(), since those are specific to this application.

I have a spi.h file too and to give you an idea of SOME of the stuff I put there:

#include   

#define   SS     PB4    // For mega644
#define   MOSI   PB5
#define   MISO   PB6
#define   SCK    PB7

#define   MODE0	 0 << 2
#define   MODE1  1 << 2
#define   MODE2  2 << 2
#define   MODE3  3 << 2

#define   SPI_DIV_2     0x04
#define   SPI_DIV_4     0x00
#define   SPI_DIV_8     0x05
#define   SPI_DIV_16    0x01
#define   SPI_DIV_32    0x06
#define	  SPI_DIV_64    0x02
#define   SPI_DIV_128   0x03

Then with the right functions in my 2 spi files I can just do this for example, in some app. main():

set_spi_clk_mode( SPI_DIV_4, MODE0 );

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

Last Edited: Thu. Aug 22, 2013 - 04:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nice :) thanks
I've connect both drivers and are working properly.
Now i have a question about optimize the code for drivers:
Every 5km/h will be displayed on the speedo and i have 24LED to display the speed and 3 leds for: turn light, low beam and high beam which are connected to the others LEDs from the first driver.
Here in this example i've measured the revolution/minute and only one dashboard light is connected 'OUT 9' but in this time the RPM outputs should work also.
When sw_on is active than the output 9 is on.

void LED_driver(void)
{
if (rpm < 1000)
{
if (sw_on)
{
driver_1( 0x00, 0x00 ); // second driver
driver_1( 0x02, 0x00 ); // first driver
}
else 
{
driver_1( 0x00, 0x00 );
driver_1( 0x00, 0x00 );
}
}
 else if ((rpm >= 1000) && (rpm < 1250))
 {
 if (sw_on)
 {
 driver_1( 0x00, 0x00 );
 driver_1( 0x06, 0x00 ); // out9 and out10 on
 }
 else 
 {
  driver_1( 0x00, 0x00 );
 driver_1( 0x04, 0x00 ); // out10 ON
 }
}
 else if ((rpm >= 1250) && (rpm < 1500))
 {
  if (sw_on)
 {
 driver_1( 0x00, 0x00 );
 driver_1( 0x0E, 0x00 ); // out9,10,11 ON
 }
else
{
 driver_1( 0x00, 0x00 );
 driver_1( 0x0C, 0x00 ); // out10,11 ON
 }
CLR_OE; // pull low the OE line
} 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First, you MUST indent code, it's TOO much work trying to find out which if or else goes with what. Compare my rewrite to yours , which is easier to follow. You should go back and edit code above for indenting, and you ought to comment it in key places so that you will know its purpose for all time because you will forget ! For example, out_9 and out_10 being ON means...what ( you know NOW, but what about in a year? ) ?

void LED_driver(void)
{

   if (rpm < 1000){

      if (sw_on)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver
      }
      else 
      {
         driver_1( 0x00, 0x00 );
         driver_1( 0x00, 0x00 );
      }
  } // End if (rpm < 1000)
.
.
.

What do you want to optimize in this code ? 1 thing I see is that

CLR_OE;

is part of your last else if, so for all other conditions it won't hit that line.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

with CLR_OE; i've make like this, only the wrong part i've post before.

void LED_driver(void)
{

   if (rpm < 1000){

      if (sw_on)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver
CLR_OE; 
      }
      else
      {
         driver_1( 0x00, 0x00 );
         driver_1( 0x00, 0x00 );
CLR_OE; 
      }
  } // End if (rpm < 1000) 

or i can put it like this:

void LED_driver(void)
{
   if (rpm < 1000)
{
      if (sw_on)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver
      }
      else
      {
         driver_1( 0x00, 0x00 );
         driver_1( 0x00, 0x00 );
      }
  } // End if (rpm < 1000)
CLR_OE; 
}

i was thinking to other solution because for 3 inputs which drives 3 outputs will need to write a lot and all this will be a big source of mistake.
for ex:

void LED_driver(void)
{
   if (rpm < 1000){

      if ((sw_on) && (sw_off2) && (sw_off3))
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver
CLR_OE;
      }
       else if ((sw_on2) && (sw_off) && (sw_off3)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver
CLR_OE;
      }
       else if ((sw_on3)&& (sw_off2) && (sw_off)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver
CLR_OE;
      }
       else if ((sw_on)&& (sw_on2) && (sw_on3)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver
CLR_OE;
      }
      else
      {
         driver_1( 0x00, 0x00 );
         driver_1( 0x00, 0x00 );
CLR_OE;
      }
  } // End if (rpm < 1000)
.
.
. 

the sent value is only an example.at this moment cannot test all rev range because i'm limit to the electrical engine which i use to simulate the wheel rotation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HI mzchristensen ! When you have to send ALL 0s you should keep the drivers OE HIGH, since all LEDs are off and it saves a bit of current on the bike's battery. The driver I use keeps my LEDs off when its OE is HIGH. If your's doesn't do that, then have it low for the all zeros state, and put the one OE_1 line at the end of the nest .

void LED_driver(void)
{
uint8_t   flag = 0;

   if (rpm < 1000){

      if ((sw_on) && (sw_off2) && (sw_off3))
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver

      }
       else if ((sw_on2) && (sw_off) && (sw_off3)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver

      }
       else if ((sw_on3)&& (sw_off2) && (sw_off)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver

      }
       else if ((sw_on)&& (sw_on2) && (sw_on3)
      {
         driver_1( 0x00, 0x00 ); // second driver
         driver_1( 0x02, 0x00 ); // first driver

      }
      else
      {
         driver_1( 0x00, 0x00 );
         driver_1( 0x00, 0x00 );
         flag = 1;
      }

   if ( flag == 0 ) CLR_OE; // Turn outputs ON only if there's something to show.

  } // End if (rpm < 1000)
.
.
.

You test for many switch combinations, but always send the same LED pattern, so you ought to really think about what combos REALLY need to be tested. Time for a Karnaugh map. :D But you did say this is just an example ( but if real code ends up sending same patterns for some tests, then using a K-map will help ).

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all!

To transform output pins in binary or hex, i use the software from below. it was a big help for me because i haven't connect the driver in output order.
for example: 10km.....33km = out 10 .... out15 and 105km ... 140km => out 0 .... out 5.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So this part of your design works now ? Time to pop some wheelies, motorcycle mama !

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yep it's working, thanks to you!It is not finish, as you see in the other topic i have problems with the signal when the wheel is not moving and the engine still running.