Help My Project(12CH LED Driver)??

Embedded Systems Topics
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: Help My Project(12CH LED Driver)??

Post by Neo » Sun Aug 05, 2012 5:12 pm

Looks like there is a problem in your algorithm. Have a look at one of our previous discussions on this topic.
New Knight rider Flasher
There a several nice codes involved in this one.
User avatar
Nandika
Captain
Captain
Posts: 247
Joined: Sat Oct 15, 2011 11:40 am
Location: Galle-Sri Lanka

Re: Help My Project(12CH LED Driver)??

Post by Nandika » Sun Aug 19, 2012 5:38 pm

Hi...Neo and Friends, :)
I solved problem using Rksk's code.
I replaced small piece of flowing code.

Code: Select all

#include <math.h>
#include <pic.h>
#include "delay.h"
//#include "styles.h"


//this methord used for write to port B and C

void Write(unsigned int val){
	PORTB=val;
	PORTC=(val>>8);//I used shifting methord for get last[MSB] bit4 to PORTC.

}

/*KNIGHT RIDER TO CENTER ALL
n=number of times
del=delay
*/
void NightRiderToCenter(unsigned short n,unsigned int del){
	unsigned short i,j;
	unsigned int val;
	for(i=0;i<n;i++){
		for(j=0;j<6;j++){
			val=pow(2,j) + pow(2,11-i);//REPLASED THIS LINE AS val=pow(2,j) +(2048/pow(2,j);
			Write(val);
			DelayBigMs(del);

		}
	}
}

int main(){
	TRISA=1;//SET AS INUT
	TRISB=0;
	TRISC=0;
	PORTB=0;
	PORTC=0;

	//==================
	NightRiderToCenter(10,500);

}

What are different between this two code line?
This,

Code: Select all

val=pow(2,j) + pow(2,11-i);
AND,

Code: Select all

VAL=pow(2,j) +(2048/pow(2,j);
Another,My PIC cant do that?(=PIC16F877A) :idea: :idea:

Thanks
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: Help My Project(12CH LED Driver)??

Post by Neo » Mon Aug 20, 2012 9:54 pm

I can't compare, val=pow(2,j) + pow(2,11-i); with VAL=pow(2,j) +(2048/pow(2,j);.

But I can compare, val=pow(2,j) + pow(2,11-i); with VAL=pow(2,j) +(2048/pow(2,i);.

Since pow(2,j) is same on both, we need to compare pow(2,11-i) with 2048/pow(2,i).

This can be proved with simply knowledge on Exponentiation where we can write 2048 as 2^11 and 2048 / pow(2,i) as 2^11/2^i = 2^(11-i). So both are same.

2^3 x 2^5 = 2^8 (we add the exponents if we multiply numbers with same base)
2^4 / 2^2 = 2^2 (we subtract exponents if we divide numbers with same base)
User avatar
Rksk
Major
Major
Posts: 730
Joined: Thu Jan 07, 2010 4:19 pm
Location: Rathnapura, Sri Lanka

Re: Help My Project(12CH LED Driver)??

Post by Rksk » Tue Aug 21, 2012 12:10 pm

Neo wrote:I can't compare, val=pow(2,j) + pow(2,11-i); with VAL=pow(2,j) +(2048/pow(2,j);.
But I can compare, val=pow(2,j) + pow(2,11-i); with VAL=pow(2,j) +(2048/pow(2,i);.
Both are same. I think you tried to remember (2048/pow(2,j));


This can be proved with simply knowledge on Exponentiation where we can write 2048 as 2^11 and 2048 / pow(2,i) as 2^11/2^i = 2^(11-i). So both are same.

2^3 x 2^5 = 2^8 (we add the exponents if we multiply numbers with same base)
2^4 / 2^2 = 2^2 (we subtract exponents if we divide numbers with same base)
Yes it is correct mathematically. But when using in C (with Hi-tech compiler), pow(2,11-i) didn't gave same result as (2048/pow(2,j)).

Nandika was telling val=pow(2,j) + pow(2,11-i); doesn't give expected result. So I tried to find the bug, later I found that val=pow(2,j) +(2048/pow(2,j)); gives expected result. But we can't find the reason for that.

val=pow(2,j) + pow(2,11-i);
val=pow(2,j) +(2048/pow(2,j));
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: Help My Project(12CH LED Driver)??

Post by Neo » Tue Aug 21, 2012 12:43 pm

Nandika:
Another,My PIC cant do that?(=PIC16F877A) :idea: :idea:
Rksk:
val=pow(2,j) + pow(2,11-i);
val=pow(2,j) +(2048/pow(2,j));
I guess both questions are associative. If you can run a loop i = 11 to 0 and execute pow(2, 11-i), you will be able to find the issue here. Could be an issue with 8-bit registers.

FYI: pow is not usually used in embedded development. Never on the base of 2 where you can efficiently execute those using shift operations which are usually single cycle on most micros.

You can write val=pow(2,i) +(2048/pow(2,j)); with shift operations as val = (1L << i) + (1L << (11-j));
Notice that I have use 1L instead of just 1 which is mathematically correct to mention that it is a long integer where it doesn't become 0 after shifting over the register size (8-bit). If the registers are 8-bit, if you do 1 << 8, it will return you 0. If you use 1L << 8, it will return you 256. These little gimmicks must be gathered when you do real programming.
User avatar
Nandika
Captain
Captain
Posts: 247
Joined: Sat Oct 15, 2011 11:40 am
Location: Galle-Sri Lanka

Re: Help My Project(12CH LED Driver)??

Post by Nandika » Tue Aug 21, 2012 2:16 pm

Ops...Very Sorry Neo...
I given code is wrong.It's a my typing mistake.

I clearly explain it.

I want to make 12LED driver using PIC16F87A.
I used output pin as all of PORTB and 4pin only PORTC(first 4 pins).
I coded function for write to port as this,

Code: Select all

//this methord used for write to port B and C

void Write(unsigned int val){
	PORTB=val;
	PORTC=(val>>8);//I used shifting methord for get last[MSB] bit4 to PORTC.

}
Now i want to light up LED from beside to center.(right and left to center.)
I used flowing function,

Code: Select all

/*KNIGHT RIDER TO CENTER ALL
n=number of times
del=delay
*/
void NightRiderToCenter(unsigned short n,unsigned int del){
	unsigned short i,j;
	unsigned int val;
	for(i=0;i<n;i++){
		for(j=0;j<6;j++){
			val=pow(2,j) + (pow(2,11-j));//*******THIS IS REPLACED CODE...THIS CODE DID NOT WORK********
			Write(val);
			DelayBigMs(del);

		}
	}
}
But,did not work.only right to center light up.left side no.(last left LED light up always.)

According to Rksk instruction,I replace small piece of my code.
I replaced val=pow(2,j) + (pow(2,11-j)); to val=pow(2,j) + (2048/pow(2,j)); .

But,This both are same val returned.
What is this Problem?
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: Help My Project(12CH LED Driver)??

Post by Neo » Tue Aug 21, 2012 11:46 pm

Can you verify whether you have included math.h header file at the top of this source file? If that is not there, it could be the issue.

I would also like to suggest to replace the line val=pow(2,j) + (pow(2,11-j)); with val = (1L << (11-j)) + (1L << j);
Note that I interchanged the parts in the equation for ease of readability where MSB and LSB are represented correctly. Can you confirm the output of this. If you are not familiar with shift operations, let me give you some quick examples.

2^0 = 1 << 0 = 1
2^1 = 1 << 1 = 2
2^2 = 1 << 2 = 4
2^3 = 1 << 3 = 8
...
...
2^11 = 1L << 11 = 2048
....
....

If I get your program,
j = 0, val = (1L << (11-0)) + (1L << 0) = 0000 1000 0000 0001
j = 1, val = (1L << (11-1)) + (1L << 1) = 0000 0100 0000 0010
j = 2, val = (1L << (11-2)) + (1L << 2) = 0000 0010 0000 0100
.....
.....
User avatar
Nandika
Captain
Captain
Posts: 247
Joined: Sat Oct 15, 2011 11:40 am
Location: Galle-Sri Lanka

Re: Help My Project(12CH LED Driver)??

Post by Nandika » Thu Aug 23, 2012 1:56 pm

Thank you Neo.. :D

:o It's work without including math.h.
It's a nice code.What is the meaning of

Code: Select all

1L
? :o :?: :?: :?: :?: :?: :geek: :geek: :geek: :geek:
Please explain or give some links for understand code?
User avatar
Nandika
Captain
Captain
Posts: 247
Joined: Sat Oct 15, 2011 11:40 am
Location: Galle-Sri Lanka

Re: Help My Project(12CH LED Driver)??

Post by Nandika » Thu Aug 23, 2012 2:10 pm

I understood something...if I incorrect ,please give answer abode question ..

This is shifting.
As your Example....

See

Code: Select all

1<<2
= 4

Code: Select all

1<<3
= 8
....
....
In my coding...

Code: Select all

1<i
= 2^ i

Code: Select all

1<<(11-i)
=2^(11-i)

adding this tow values ,correctly light up my LED driver ... :biggrin:

But,


What is meaning of

Code: Select all

1L
?? What is this L?
It also worked without L.

thank u
User avatar
Neo
Site Admin
Site Admin
Posts: 2642
Joined: Wed Jul 15, 2009 2:07 am
Location: Colombo

Re: Help My Project(12CH LED Driver)??

Post by Neo » Thu Aug 23, 2012 3:10 pm

?? What is this L?
First have a look at the part "long-suffix: one of " in C++ Integer Constants.

I'll give you a little example. Say you are on a 8-bit system. 8-bit system means that all your CPU registers are 8-bit and you compiler's minimum accessible unit is 8-bit.
Now if you define a number within your program as say 8, it stores to a CPU register as below.
0000 0100

If you left shift this by 6, it become 0000 0000. This is not correct.
But you CPU will think that the number you defined as 8 was a 8-bit number, nothing wrong in there right?

Now if you define the same number as 8L, which you asked the compiler to think this number as a long, it will be stored using few registers.
........ 0000 0000 0000 0100
In HI-TECH C, this is 32-bit.

Now, you do the same operation, Shift left by 6.
It will become ......0000 0001 0000 0000 = 256, which is your expected result.

Note that in most cases, compilers think constant numbers are 16-bit (this is where it is called "int" as the standard data type on many systems). That is why your program works even without "L".

But say, if you are left shifting a number which needs more than 16-bit, then again you need to specify them with "L".

See last bit of Why do I get an "Arithmetic overflow" message? of HI-TECH C FAQ.
It says,
If you are working with a compiler that uses 16-bit ints and 32-bit longs,
you need to ensure that long arithmetic is used for the whole expression.
8000000 is by default a long number, but 3200 and 64 aren't, so 64*3200
is evaluated in int length, and overflows. Use an 'L' suffix to force long
arithmetic in an expression, e.g.

#define BEEP_TIME XTAL/(64L*BEEP_FREQ)-1 // = 38.0625

Note the 'L' appended to 64 - this makes it a long number, and the
evaluation of 64L*3200 will be done in 32-bit length.
Post Reply

Return to “Embedded Systems”