|
|
View previous topic :: View next topic |
Author |
Message |
Milentije89
Joined: 07 Apr 2017 Posts: 31
|
float variable problem |
Posted: Fri Feb 04, 2022 1:17 pm |
|
|
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: 9168 Location: Greensville,Ontario
|
|
Posted: Fri Feb 04, 2022 2:09 pm |
|
|
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
|
|
Posted: Fri Feb 04, 2022 2:29 pm |
|
|
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
|
|
Posted: Fri Feb 04, 2022 2:34 pm |
|
|
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: 9168 Location: Greensville,Ontario
|
|
Posted: Fri Feb 04, 2022 2:36 pm |
|
|
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
|
|
Posted: Fri Feb 04, 2022 2:50 pm |
|
|
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.
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: 9168 Location: Greensville,Ontario
|
|
Posted: Fri Feb 04, 2022 3:05 pm |
|
|
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 !!! |
|
|
|
|
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
|