CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

float variable problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Milentije89



Joined: 07 Apr 2017
Posts: 31

View user's profile Send private message

float variable problem
PostPosted: Fri Feb 04, 2022 1:17 pm     Reply with quote

Hi to everyone!

I have a really strange problem. It took me 2 days to find out what is happening, but I still don't know why.

MCU: 18F87J11
Compiler version: 5.075

This works.

Code:

#include <18F87J11.h>
#device  PASS_STRINGS = IN_RAM
#device ADC=10


#fuses INTRC_IO, NOWDT, NOPROTECT, NOFCMEN

#use delay (clock = 4000000)
#use rs232 (baud = 9600, xmit = PIN_C6, rcv = PIN_C7, ENABLE = PIN_C2, TIMEOUT = 100, ERRORS)
#use i2c (MASTER, SCL = PIN_C3, SDA = PIN_C4, FAST, FORCE_HW)


#include <MCP9600.c>
#include "Drivers\input_no_echo.c"
#include "Drivers\74595.c"
#include "Drivers\string.h"
#include "Drivers\stdlib.h"

#define MCP9600_addr 0x67

//#define CONST1 3300.00/1024
//#define CONST2 1/320.00

char string[] = "";

float temp1 = 0;
float P_bar = 0;

unsigned int16 pressure1 = 0;

unsigned int8  status = 0;
unsigned int1  data_ready = 0;
unsigned int1  ad_done = 0;
unsigned int1  flame = 1;
unsigned int1  new_string = 0;
unsigned int1  print_enable = 1;

unsigned int16 current_state = 0;

float c1 = 3300.00/1024;
float c2 = 1/320.00;

unsigned int8   releji[2]; // Broj upotrijebljenih 74HC595 za kontrolu releja

unsigned int16   relej[10] = {0b0000000000000000,
                     0b0000000000000001,
                     0b0000000000000010,
                     0b0000000000000100,
                     0b0000000000001000,
                     0b0000000000010000,
                     0b0000000000100000,
                     0b0000000001000000,
                     0b0000000010000000,
                     0b0000000100000000};


void odabir_releja(int16 relej)
{
   releji[0] = relej;
   relej = relej >> 8;
   releji[1] = relej;
   write_expanded_outputs(releji);
}

void open_main_valve()
{
   odabir_releja(1);
}

#int_rda
void rda_isr()
{
   string = "";
   get_string(string, 100);
   new_string = 1;
}

void main()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);
   
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(sAN2, VSS_VDD);
   set_adc_channel(2);
   
   MCP96_set_shutdown_mode(MCP9600_addr, 0);
   MCP96_set_burst_mode(MCP9600_addr, 3);
   MCP96_set_CJ_resolution(MCP9600_addr, 1);
   MCP96_set_ADC_resolution(MCP9600_addr, 0);
   MCP96_set_TC_type(MCP9600_addr, 'K');
   MCP96_set_filter_coefficient(MCP9600_addr, 0);
   
   odabir_releja(relej[0]);
   
   while(TRUE)
   {     
      if(new_string == 1)
      {
         if(!strncmp(string, "open_x_", 7))
         {
            unsigned int8 numberx = 0;
            numberx = string[7]-48;
            odabir_releja(relej[numberx]);
         }
         else if(!strncmp(string, "open_mv", 7))
         {
            odabir_releja(relej[1]);
         }
         else if(!strncmp(string, "cs", 4))
         {
            odabir_releja(relej[0]);
         }
         else if(!strncmp(string, "close", 4))
         {
            current_state = 0;
            odabir_releja(current_state);
         }
         else if(!strncmp(string, "pe", 2))
         {
            print_enable = 1;
         }
         else if(!strncmp(string, "pd", 2))
         {
            print_enable = 0;
         }
         else if(!strncmp(string, "reboot", 6))
         {
            reset_cpu();
         }
         
         string = "";
         new_string = 0;
      }
     
      temp1 = MCP96_get_Th(MCP9600_addr);
     
      status = MCP96_get_status(MCP9600_addr);
      data_ready = MCP96_get_data_Ready(MCP9600_addr);
     
      MCP96_reset_data_ready(MCP9600_addr);
     
      status = MCP96_get_status(MCP9600_addr);
      data_ready = MCP96_get_data_Ready(MCP9600_addr);
     
      read_adc(ADC_START_ONLY);
      while(!ad_done)
      { 
         ad_done = adc_done();
      }
      ad_done = 0;
      pressure1 = read_adc(ADC_READ_ONLY);
      P_bar = ((((float)pressure1 * c1) - 400) * c2);
     
      flame = input(PIN_G1);
     
      if(print_enable == 1)
      {
         printf("%f, %3.2f, %ld, %d, %5.4f, %5.4f\r", temp1, P_bar, pressure1, !flame, c1, c2);
      }
      delay_ms(100);
   }
}



This doesn't work.

Code:

#include <18F87J11.h>
#device  PASS_STRINGS = IN_RAM
#device ADC=10


#fuses INTRC_IO, NOWDT, NOPROTECT, NOFCMEN

#use delay (clock = 4000000)
#use rs232 (baud = 9600, xmit = PIN_C6, rcv = PIN_C7, ENABLE = PIN_C2, TIMEOUT = 100, ERRORS)
#use i2c (MASTER, SCL = PIN_C3, SDA = PIN_C4, FAST, FORCE_HW)


#include <MCP9600.c>
#include "Drivers\input_no_echo.c"
#include "Drivers\74595.c"
#include "Drivers\string.h"
#include "Drivers\stdlib.h"

#define MCP9600_addr 0x67

//#define CONST1 3300.00/1024
//#define CONST2 1/320.00

char string[] = "";

float temp1 = 0;
float c1 = 3300.00/1024;
float c2 = 1/320.00;
float P_bar = 0;

unsigned int16 pressure1 = 0;

unsigned int8  status = 0;
unsigned int1  data_ready = 0;
unsigned int1  ad_done = 0;
unsigned int1  flame = 1;
unsigned int1  new_string = 0;
unsigned int1  print_enable = 1;

unsigned int16 current_state = 0;

unsigned int8   releji[2]; // Broj upotrijebljenih 74HC595 za kontrolu releja

unsigned int16   relej[10] = {0b0000000000000000,
                     0b0000000000000001,
                     0b0000000000000010,
                     0b0000000000000100,
                     0b0000000000001000,
                     0b0000000000010000,
                     0b0000000000100000,
                     0b0000000001000000,
                     0b0000000010000000,
                     0b0000000100000000};


void odabir_releja(int16 relej)
{
   releji[0] = relej;
   relej = relej >> 8;
   releji[1] = relej;
   write_expanded_outputs(releji);
}

void open_main_valve()
{
   odabir_releja(1);
}

#int_rda
void rda_isr()
{
   string = "";
   get_string(string, 100);
   new_string = 1;
}

void main()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);
   
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(sAN2, VSS_VDD);
   set_adc_channel(2);
   
   MCP96_set_shutdown_mode(MCP9600_addr, 0);
   MCP96_set_burst_mode(MCP9600_addr, 3);
   MCP96_set_CJ_resolution(MCP9600_addr, 1);
   MCP96_set_ADC_resolution(MCP9600_addr, 0);
   MCP96_set_TC_type(MCP9600_addr, 'K');
   MCP96_set_filter_coefficient(MCP9600_addr, 0);
   
   odabir_releja(relej[0]);
   
   while(TRUE)
   {     
      if(new_string == 1)
      {
         if(!strncmp(string, "open_x_", 7))
         {
            unsigned int8 numberx = 0;
            numberx = string[7]-48;
            odabir_releja(relej[numberx]);
         }
         else if(!strncmp(string, "open_mv", 7))
         {
            odabir_releja(relej[1]);
         }
         else if(!strncmp(string, "cs", 4))
         {
            odabir_releja(relej[0]);
         }
         else if(!strncmp(string, "close", 4))
         {
            current_state = 0;
            odabir_releja(current_state);
         }
         else if(!strncmp(string, "pe", 2))
         {
            print_enable = 1;
         }
         else if(!strncmp(string, "pd", 2))
         {
            print_enable = 0;
         }
         else if(!strncmp(string, "reboot", 6))
         {
            reset_cpu();
         }
         
         string = "";
         new_string = 0;
      }
     
      temp1 = MCP96_get_Th(MCP9600_addr);
     
      status = MCP96_get_status(MCP9600_addr);
      data_ready = MCP96_get_data_Ready(MCP9600_addr);
     
      MCP96_reset_data_ready(MCP9600_addr);
     
      status = MCP96_get_status(MCP9600_addr);
      data_ready = MCP96_get_data_Ready(MCP9600_addr);
     
      read_adc(ADC_START_ONLY);
      while(!ad_done)
      { 
         ad_done = adc_done();
      }
      ad_done = 0;
      pressure1 = read_adc(ADC_READ_ONLY);
      P_bar = ((((float)pressure1 * c1) - 400) * c2);
     
      flame = input(PIN_G1);
     
      if(print_enable == 1)
      {
         printf("%f, %3.2f, %ld, %d, %5.4f, %5.4f\r", temp1, P_bar, pressure1, !flame, c1, c2);
      }
      delay_ms(100);
   }
}


This code list is full of garbage that I used in past 2 days, trying to find what is wrong. So excuse me for that.

If you look closely, you will see that only difference is where float c1 and c2 are placed within the list.

In case when it doesn't work it behaves like this:
When device is turned on I am getting normal reading of c1 and c2 (expected values). After I send new data to 74HC595 (2 of them cascaded) c1 value changes to 0.0136. After I send next data set to 74HC595 c1 value changes to 0.0000. Then I send first set of data to 74HC595 and c1 value changes again to 0.00136. After that I send second set of data to 74HC595 and value of c1 changes to 0.0000.

Then, I just change the order of declarations in code (first declare c2 and then c1) and I get the same problem but with c2 variable.

WTF???

After that I move declaration of c1 and c2 somewhere else in the code (just under declaration of print_enable). And then I get c1 and c2 values as they should be, but then print_enable variable is changed when one data set is sent to 74HC595. print_enable variable got set and reset.

WTF again???

After that I move declaration of c1 and c2 again in the code (you can see its final destination in code list above). This time everything that I can see works fine, but I am afraid of what I can not see, and when this problem is going to hit me again with some other variable.

Functions that are sending 2 different data sets to 74HC595 do not have anything with c1 and c2 variables. So I really don't know why is this happening.

As you can see from commented parts of code I tried #define for c1 and c2 (constants) and it works.

If I try to use const (in combination with #device const) I am getting the same problem when I set it READ_ONLY.
When I set it to ROM I do not have problems, but programming time is significantly longer (using PicKit 2).

Can somebody explain me why is this happening?
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 2:09 pm     Reply with quote

Quote:
This code list is full of garbage that I used in past 2 days, trying to find what is wrong. So excuse me for that.


yeah, really, you need to post a SMALL program, that shows the problem code. Narrow it down to JUST the problem 'area'. It'll make our lives easier to figure out what's going on....

also what's the purpose of the '595 chips ?A brief but good description of the overall project (what/how it's supposed to work ) might shed light on it. I don't know why /how values are changing, good or bad. There's not many comments at the end of the lines of code to figure out why you coded as you did.
Milentije89



Joined: 07 Apr 2017
Posts: 31

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 2:29 pm     Reply with quote

595s are used to control 16 relays (via ULN2803). Nothing special. Have some 1 I2C sensor, one 4-20 mA sensor and one IR sensor (digital output).

Nothing complex.

Root of the problem is that it makes a difference where I declare float variables. Two of them.

Code:

bla bla code...

int x
int y

float a
float b

int q
int w

main()
{
bla bla code...
}


and

Code:

bla bla code...

int x
int y

int q
int w

float a
float b

main()
{
bla bla code...
}


Those two are giving different results...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 2:34 pm     Reply with quote

Look at the symbol table. (it's in the .SYM file in your project folder)
Notice that 'string' has only 1 byte of memory assigned to it.
So when you write to 'string', it's over-writing variables that come
after it, such as c1 and c2. The C language lets you do this.
Quote:
01C rs232_errors
01D-01E strtok.save
01F-022 _Randseed
023 string
024-027 temp1
028-02B c1
02C-02F c2
030-033 P_bar
034-035 pressure1
036 status

Let's assign some storage to 'string':
Code:
char string[105] = "";

Re-compile and look at the .SYM file below. Now it has storage
assigned to it. You can write to 'string' and it won't over-write
the variables after it. (Unless you write more than it's length).
Quote:
01C rs232_errors
01D-01E strtok.save
01F-022 _Randseed
023-08B string
08C-08F temp1
090-093 c1
094-097 c2
098-09B P_bar
09C-09D pressure1
09E status
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 2:36 pm     Reply with quote

maybe increase stack size ?
are variable by default 8 bit or 16? for that PIC/compiler version ??
heck I can't PRINT from my Win10 machine since the router was replaced(says prt 'offline') thought my W7 -->ptr is OK
I'm getting too old for this 'stuff'.
Milentije89



Joined: 07 Apr 2017
Posts: 31

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 2:50 pm     Reply with quote

PCM programmer wrote:
Look at the symbol table. (it's in the .SYM file in your project folder)
Notice that 'string' has only 1 byte of memory assigned to it.
So when you write to 'string', it's over-writing variables that come
after it, such as c1 and c2. The C language lets you do this.
Quote:
01C rs232_errors
01D-01E strtok.save
01F-022 _Randseed
023 string
024-027 temp1
028-02B c1
02C-02F c2
030-033 P_bar
034-035 pressure1
036 status

Let's assign some storage to 'string':
Code:
char string[105] = "";

Re-compile and look at the .SYM file below. Now it has storage
assigned to it. You can write to 'string' and it won't over-write
the variables after it. (Unless you write more than it's length).
Quote:
01C rs232_errors
01D-01E strtok.save
01F-022 _Randseed
023-08B string
08C-08F temp1
090-093 c1
094-097 c2
098-09B P_bar
09C-09D pressure1
09E status


Jesus!

I didn't see I left that bracket empty. Mad Mad

Thank you very much!

temtronic wrote:
maybe increase stack size ?
are variable by default 8 bit or 16? for that PIC/compiler version ??


By default int is 8 bit. But this was not a problem in my case.
I missed to reserve enough space for string...
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 3:05 pm     Reply with quote

just wait until you're 68 , eyes go 'south' on you......
THEN you'll really start to have 'fun'.
sigh....
I'm glad YOUR problem got fixed though !!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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