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.
Help My Project(12CH LED Driver)??
Re: Help My Project(12CH LED Driver)??
Hi...Neo and Friends,
I solved problem using Rksk's code.
I replaced small piece of flowing code.
What are different between this two code line?
This,
AND,
Another,My PIC cant do that?(=PIC16F877A)
Thanks
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);
}
This,
Code: Select all
val=pow(2,j) + pow(2,11-i);
Code: Select all
VAL=pow(2,j) +(2048/pow(2,j);
Thanks
Re: Help My Project(12CH LED Driver)??
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)
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)
Re: Help My Project(12CH LED Driver)??
Both are same. I think you tried to remember (2048/pow(2,j));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);.
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)).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)
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));
Re: Help My Project(12CH LED Driver)??
Nandika:
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.
Rksk:Another,My PIC cant do that?(=PIC16F877A)
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.val=pow(2,j) + pow(2,11-i);
val=pow(2,j) +(2048/pow(2,j));
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.
Re: Help My Project(12CH LED Driver)??
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,
Now i want to light up LED from beside to center.(right and left to center.)
I used flowing function,
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?
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.
}
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);
}
}
}
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?
Re: Help My Project(12CH LED Driver)??
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
.....
.....
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
.....
.....
Re: Help My Project(12CH LED Driver)??
Thank you Neo..
It's work without including math.h.
It's a nice code.What is the meaning of?
Please explain or give some links for understand code?
It's work without including math.h.
It's a nice code.What is the meaning of
Code: Select all
1L
Please explain or give some links for understand code?
Re: Help My Project(12CH LED Driver)??
I understood something...if I incorrect ,please give answer abode question ..
This is shifting.
As your Example....
See = 4
= 8
....
....
In my coding... = 2^ i
=2^(11-i)
adding this tow values ,correctly light up my LED driver ...
But,
What is meaning of?? What is this L?
It also worked without L.
thank u
This is shifting.
As your Example....
See
Code: Select all
1<<2
Code: Select all
1<<3
....
....
In my coding...
Code: Select all
1<i
Code: Select all
1<<(11-i)
adding this tow values ,correctly light up my LED driver ...
But,
What is meaning of
Code: Select all
1L
It also worked without L.
thank u
Re: Help My Project(12CH LED Driver)??
First have a look at the part "long-suffix: one of " in C++ Integer Constants.?? What is this L?
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.