View previous topic :: View next topic |
Author |
Message |
solidust
Joined: 08 Mar 2010 Posts: 13
|
Need Help Fuzz-C Code |
Posted: Thu Jul 01, 2010 2:00 pm |
|
|
Code
Last edited by solidust on Sun Aug 01, 2010 11:57 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 01, 2010 2:43 pm |
|
|
I suggest that you get rid of the Fuzzy stuff. Look how simple it is
to do this in normal C code. I used a PicDem2-Plus board, which
has a trimpot on pin AN0 so I used that pin for the analog input.
It has an LED on pin B0, so I used it to indicate if the input voltage
is above or below the threshold voltages.
Code: |
#include <16F877.H>
#device adc=8
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define LED_PIN PIN_B0
#define LOWER_LIMIT ((1.2/5) * 255)
#define UPPER_LIMIT ((2.0/5) * 255)
//==========================================
void main()
{
int8 adc_result;
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
output_low(LED_PIN); // Set LED to Off
while(1)
{
adc_result = read_adc();
if(adc_result < LOWER_LIMIT)
output_low(LED_PIN); // LED Off
if(adc_result > UPPER_LIMIT)
output_high(LED_PIN); // LED On
}
} |
|
|
|
solidust
Joined: 08 Mar 2010 Posts: 13
|
|
Posted: Thu Jul 01, 2010 2:58 pm |
|
|
Yeah thats alot simpler but my overall objective is a FUZZY controller to control pH. I already have the Fuzzy design its just to get on PIC now. Once I could get this simple Fuzzy 1 input 1 output to work I can work with my pH project (3 inputs about 50 rules and 5 outputs).
Thanks anyways man. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19540
|
|
Posted: Thu Jul 01, 2010 3:14 pm |
|
|
The first obvious thing 'wrong' with the Fuzzy code, is 'types'. Values are being passed as integers, then compared with floating point number like '1.2'. Won't give sensible answers in _any_ 'C'....
Inside at least one routine, you have an int being multiplied by '255'. An int in CCS C, is 255 _max_. Again wrong type.
Early on on the code flow, the adc value is being tested for being 'true'. Since the only way to get 'false', would be for the ADC to return '0', implying the incoming line is clamped to the 0v line, this doesn't make much sense either.
Remember the value from the ADC, is an integer count from 0 to 255, _not_ a voltage value. You need to convert first.
The code itself is 'fuzzy' in more ways than one.
Best Wishes |
|
|
solidust
Joined: 08 Mar 2010 Posts: 13
|
|
Posted: Tue Jul 06, 2010 3:28 pm |
|
|
Update
Last edited by solidust on Sun Aug 01, 2010 11:58 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
solidust
Joined: 08 Mar 2010 Posts: 13
|
|
Posted: Fri Jul 23, 2010 2:26 pm |
|
|
Ok I made some progress however I need to know the simplest way I can scale an input range say 0 -100 to 0-255 so that the PIC will read 100% of the input.
Please Help |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 23, 2010 3:02 pm |
|
|
Where does this input range come from ? Is it from the A/D ?
If so, what's the voltage range of your input A/D signal ? |
|
|
solidust
Joined: 08 Mar 2010 Posts: 13
|
|
Posted: Fri Jul 23, 2010 5:38 pm |
|
|
The design itself has two inputs.
1 pH 0- 14
2 Level 0-100%
I am using two 10K pots for both inputs. However the code uses these stated values as the actual values for computing. So the input voltage will be 0-5V.
For example the range for Level being xlow is 0-25% with the value for xlow being ideally <=5%. Meaning with a level of <=5% it is completely (1 on y axis) xlow. After 5% the 'trueness' of level being xlow diminishes until it reaches 25%. At 25% the level is not xlow (0 on y axis) at all.
Code: |
int Level ;
/* MEMBER xlow { 0,0,5,25 } */
/*
1-| ...
| . .
| . .
| . .
0-| . .........................
----------------------------------
0 25 50 75 100
*/
char Level_xlow (int __CRISP)
{
{
if (__CRISP <= 5) return(255);
else
{
if (__CRISP <= 25)
return((( + 25 - __CRISP) * 12) + 7);
else
return(0);
|
Hope this is clear, if not plz let me know which part isn't. Thanks alot. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 23, 2010 9:48 pm |
|
|
Quote: | I am using two 10K pots for both inputs. However the code uses these
stated values as the actual values for computing. So the input voltage will
be 0-5V. |
I don't know what you want. What do you want from the read_adc()
statement ? Your posted code shows that you have '#device adc=8'.
If you truly have an input range from 0 to 5 volts, then you will get
a value from read_adc() from 0 to 255. That's what you said you want.
So I don't see the problem.
Quote: |
For example the range for Level being xlow is 0-25% with the value for
xlow being ideally <=5%. Meaning with a level of <=5% it is completely
(1 on y axis) xlow. After 5% the 'trueness' of level being xlow diminishes
until it reaches 25%. At 25% the level is not xlow (0 on y axis) at all. |
I don't want to consider fuzzy logic itself. I just want to answer questions
about CCS functions or hardware or low level stuff like that. If you can
put your question in those terms, I can you help you perhaps. |
|
|
solidust
Joined: 08 Mar 2010 Posts: 13
|
|
Posted: Fri Jul 23, 2010 10:22 pm |
|
|
Kool. Thanks anyways man, i guess its the fuzzy part i need to sort out, n for now i'll have the inputs range from 0-255 what is it exactly.
Will figure out sumthin. If i need help will check you for sure. |
|
|
solidust
Joined: 08 Mar 2010 Posts: 13
|
|
Posted: Sun Aug 01, 2010 11:56 pm |
|
|
How can I make this code smaller? Somebody Anybody?
Basically is a statement monitoring 3 inputs PH, Level and Temperature. Based on the readings outputs to 3 on/off devices. Drain valve, Recirculation valve and a start pump function.
Code: |
/*IF PH IS Good AND Level IS xlow AND Temperature IS Good THEN DrainValve IS close AND RecircValve IS close AND StartPump IS off */
__IDOM[1] = PH_Good(PH) ;
__IDOM[0] = Level_xlow(Level) ;
__IDOM[0] = F_AND(__IDOM[1],__IDOM[0]);
__IDOM[1] = Temperature_Good(Temperature) ;
__IDOM[1] = F_AND(__IDOM[0],__IDOM[1]);
__IDOM[0] = __IDOM[1];
DrainValve_close( __IDOM[0] );
RecircValve_close( __IDOM[0] );
StartPump_off( __IDOM[0] );
|
Any possible way to condense this?? I have over 100 lines of this code. Too large for compiler, out of ROM.
Please Help. |
|
|
|