|
|
View previous topic :: View next topic |
Author |
Message |
temp2290
Joined: 07 Apr 2008 Posts: 9
|
timed pulse code not working |
Posted: Mon Apr 07, 2008 9:53 pm |
|
|
I am doing a project which requires timed pulses that output to four motors, each corresponding to a different color of paint (the pulses will make a linear motor move back and forth to cover and uncover a small hole for paint to flow through). Overall, the goal of the project is to mix small amounts of paint based on inputs from four color switches (red, yellow, blue, and white), a size switch (none, small, medium, and large), and a "make paint" button which initializes things.
Basically, I have made a simplified version of the program to test it out which only uses 1 of the 4 colors corresponding to one motor. So, there are 7 input pins: 2 determine the size (computes a variable T in my program), 4 determine the amount of color (computes r), and 1 which must be on for the code to run (Pin B0).
I am using a PIC16F877A with a 20MHz clock, and MPlab as my IDE.
There is something I am completely missing about this, since it outputs nothing between pins D0 and D1. I am not a very good C programmer so spare me. Here is the code:
Code: |
#include <16F877a.h>
#USE DELAY( CLOCK=20000000 ) //20MHz crystal
#FUSES HS,NOWDT,NOPROTECT, NOLVP
#byte port_a=5
#byte port_b=6
#byte port_c=7
#byte port_d=8
int16 T;
int16 r, y, b, w, size;
float delayred;
int16 binaryToDecimal(int16 vala, int16 valb)
{
int16 returnVal;
// Evaluate four cases
if ( (vala==0) && (valb==0) )
{
returnVal = 0;
}
else if ( (vala==0) && (valb==1) )
{
returnVal= 1;
}
else if ( (vala==1) && (valb==0) )
{
returnVal = 2;
}
else if ( (vala==1) && (valb==1) )
{
returnVal = 3;
}
return (returnVal);
}
void outputcycle()
{
int16 movedelay = 1000;
output_low(PIN_D1);
output_high(PIN_D0);
delay_ms(movedelay);
output_low(PIN_D1);
output_low(PIN_D0);
delay_ms(delayred);
output_high(PIN_D1);
output_low(PIN_D0);
delay_ms(movedelay);
output_low(PIN_D1);
output_low(PIN_D0);
}
void main()
{
set_tris_b(0b01111111);
set_tris_c(0b00000000);
set_tris_d(0b00000000);
port_c = 0;
port_d = 0;
for(;;)
{
if ( INPUT(PIN_B0) == 1 )
{
// Sizes
size = binaryToDecimal( INPUT(PIN_B6),INPUT(PIN_B5) );
if ( size == 0 )
{
T = 0;
}
else if ( size == 1 )
{
T=1000;
}
else if ( size == 2 )
{
T=2000;
}
else if ( size == 3 )
{
T=3000;
}
else {;}
// Colors
if (INPUT(PIN_B1) == 1)
{
r = 0;
}
else if(INPUT(PIN_B2) == 1)
{
r = 1;
}
else if (INPUT(PIN_B3) == 1)
{
r = 2;
}
else if (INPUT(PIN_B4) == 1)
{
r = 3;
}
else{;}
// Nothing should output for 0 size or 0 red
if (r == 0 || size == 0)
{
output_low(PIN_D1);
output_low(PIN_D0);
}
else
{
delayred = (float) T/(1+(w+ y+ b/r));
// Output cycle
outputcycle();
}
}
else {;}
}
}
|
I suspect that it might have something to do with the line:
delayred = (float) T/(1+(w+ y+ b/r));
I'm not sure how it calculates this.
I also think there is something wrong with saying delay_ms(variable) since it works without a variable. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 07, 2008 10:24 pm |
|
|
Quote: | I also think there is something wrong with saying delay_ms(variable) |
It can't accept a floating point value. It must be an integer.
Here's section from the manual:
Quote: |
DELAY_MS( )
Syntax: delay_ms (time)
Parameters: time - a variable 0-65535(int16) or a constant 0-65535 |
http://www.ccsinfo.com/downloads/CReferenceManual.pdf |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Apr 08, 2008 7:28 am |
|
|
Quote: | I suspect that it might have something to do with the line:
delayred = (float) T/(1+(w+ y+ b/r)); | You are not initialising the values of w, y, b, and r at program start so these will have a random value and you get unpredictable results.
Quote: | delayred = (float) T/(1+(w+ y+ b/r));
I'm not sure how it calculates this. | The formula doesn't look right to me, maybe a missing pair of parentheses? Can you explain more about what effect you want to achieve here with some example values?
Code: | set_tris_b(0b01111111);
set_tris_c(0b00000000);
set_tris_d(0b00000000); | Only set the TRIS registers in combination with the compiler directive '#use fast_io' or 'fixed_io'. You didn't specify either of these which means the compiler is using standard_io and overrides your settings at each input/output command. If speed and memory size are not critical in your application than it is best to delete these lines.
The binaryToDecimal function is not very efficient.
- Returning an int16 when the value range is only 0-3 is a waste of resources.
- Same applies to the input variables.
- The combination of binary values can be combined in a shift and AND operation. Code: |
int8 binaryToDecimal(int8 ValA, int8 ValB) // Replaced all int16 by int8 and int1 types.
{
return (ValA << 1) & ValB;
} | In fact the function name is wrong, it is a conversion of bits to binary. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|