View previous topic :: View next topic |
Author |
Message |
MAKInnovation
Joined: 16 Nov 2010 Posts: 61
|
Saving float value on DS1302 |
Posted: Sat Feb 23, 2013 4:04 am |
|
|
Dear All;
How can i save a float32 value on DS1302 memory
would i convert float into some other type for saving data on memory locations.
Ashraf |
|
|
hellopic
Joined: 21 Feb 2013 Posts: 8
|
|
Posted: Sat Feb 23, 2013 4:10 am |
|
|
Assuming you have enough space ...
uint8 array[sizeof(float)];
memcpy(array,&float_variable,sizeof(float));
Now your float_variable's data is in array, just save that. Cheers. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Feb 23, 2013 4:45 am |
|
|
Downside is that you are moving data around unnecessarily. This is where a union comes in:
Code: |
union {
uint8 bytes[4];
float fval;
} val;
//val.fval is a floating point variable that you can use like any other.
//val.bytes[0] to val.bytes[3] are the individual bytes
|
Best Wishes |
|
|
hellopic
Joined: 21 Feb 2013 Posts: 8
|
|
Posted: Sat Feb 23, 2013 11:02 am |
|
|
I've never used unions but this looks useful, thanks. Can I ask - what other situations would they come in handy?
We can also just access the bytes from the float_value as *((uint8*)&float_value)[0] through *((uint8*)&float_value)[3] but the union thing looks cleaner. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Feb 23, 2013 12:05 pm |
|
|
Anywhere you want to access a value in two (or more) different ways.
Key is of course that the float is accessed just like any other float (no overhead on space or speed), and the same is true of the bytes. If you use fixed indexes (val.byte[0] for example), on most processors it codes as a single instruction.
It is supported in all C's, but (obviously) things like the byte order are processor specific. Pointer accesses tend to take more space (though the optimiser should sort this out).
However your version wouldn't work. You need to increment the pointer after the cast:
*(((uint8 *)&float_value)+3)
To get the third byte.
Best Wishes |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Sat Feb 23, 2013 4:48 pm |
|
|
One instance I often find using unions useful in is message parsing. By creating a struct type that mimics the message and placing it in a union with a byte array, I have an easy means of converting a byte stream directly to a struct, though you have to be careful to make sure the message lines up correctly within the byte array (we use sync bytes to help make this easier). |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sun Feb 24, 2013 9:38 pm |
|
|
Any time I've needed to save a config,
I build my struct with all my elements and then just rattle through the address of the struct and save it to NV Storage.
Saving it out and then pulling it back in the same order keeps the array intact just fine.
Code: |
for ( i=0 ; i < sizeof(config) ; i++ ) {
switch (rw) {
case load : *(((int8 *)&config) + i) = read_eeprom(i);
break;
case save : write_eeprom( i, *(((int8 *)&config) + i) );
break;
}
}
|
Any amount/type of elements can be added to the struct.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
MAKInnovation
Joined: 16 Nov 2010 Posts: 61
|
|
Posted: Sat Mar 09, 2013 2:04 am |
|
|
Thank you Ttelmah;
I use Union code for saving float data on DS1302 and it is working fine.
Now, i want to send my ccs float value over serial line in IEEE 754 float format.
So need a simple conversion routine.
Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Mar 09, 2013 2:10 am |
|
|
Doesn't anyone look in the supplied CCS code, before asking?.
ieeefloat.c, contains routines to go both ways. Funny thing is it uses a union....
Best Wishes |
|
|
MAKInnovation
Joined: 16 Nov 2010 Posts: 61
|
|
Posted: Sat Mar 09, 2013 2:15 am |
|
|
thank you
I will go through the examples
Ashraf |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sun Mar 10, 2013 5:03 pm |
|
|
Ttelmah wrote: | Doesn't anyone look in the supplied CCS code, before asking?.
|
That's a rhetorical question, right?
_________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
MAKInnovation
Joined: 16 Nov 2010 Posts: 61
|
|
Posted: Wed Mar 13, 2013 2:09 am |
|
|
Yes it is and thanks to Ttelmah for emphasizing me to read examples first before asking a question.
Apart from above discussion, i would like to ask modbus related question now.
I have checked with the modbus_slave.c file first this time
and connect 18F452 microcontroller with the PC.
I receive the data on my software with illegal address which is shown below
Tx:01 03 00 00 00 0A C5 CD
Rx:F7 83 02 20 C3
what could be the reason?
I did not change any thing in the example except the following:
Uncheck this line : #define USE_WITH_PC 1
connect these data pins
Code: |
#define MODBUS_SERIAL_TX_PIN PIN_C6 // Data transmit pin
#define MODBUS_SERIAL_RX_PIN PIN_C7 // Data receive pin
|
and made changes in this line
Code: | if((modbus_rx.address == MODBUS_ADDRESS) || modbus_rx.address == 1) // here address change from 0 to 1
|
Ashraf |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Mar 13, 2013 3:25 am |
|
|
MAKInnovation wrote: | Yes it is and thanks to Ttelmah for emphasizing me to read examples first before asking a question. |
Interesting...
Quote: |
I have checked with the modbus_slave.c file first this time
and connect 18F452 microcontroller with the PC.
I receive the data on my software with illegal address which is shown below
Tx:01 03 00 00 00 0A C5 CD
Rx:F7 83 02 20 C3
what could be the reason?
|
Your addressing is the problem.
Modbus_slave.c implements just eight of each datatype: eight coils, eight input and eight holding registers. Any attempt to read a register outside of these will, correctly and in compliance with the Modbus standard, generate an addressing error. This should be obvious, and was for me when I read it carefully enough, from reading the example code.
You are attempting to read coil 10, i.e. 0X000A, but that doesn't "exist" in the slave. So it returns a Modbus address error exception. The example is, in fact, working correctly.
Extending the addressing range of the example is not as simple as it looks. There are "gotchas", so take care. |
|
|
MAKInnovation
Joined: 16 Nov 2010 Posts: 61
|
|
Posted: Wed Mar 13, 2013 4:04 am |
|
|
Thanks RF_Developer:
Example is working within 8 numbers but the address should be 01 when reading the receiving frame instead of F7.
Tx: 01 03 00 00 00 06 C5 C8
Rx: F7 03 0C 00 88 00 77 00 66 00 55 00 44 00 33 2F 6C |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed Mar 13, 2013 4:17 am |
|
|
Whoa.
That line _must_ end if zero.
There are two things here. The first part:
modbus_rx.address == MODBUS_ADDRESS
Tests if the address byte received matches your system's modbus address.
The second:
|| modbus_rx.address == 0
Tests if instead it matches the modbus _broadcast_ address (0).
This is part of the modbus spec, and _must not_ be changed.
Your system _must_ receive broadcast messages. If you change the value to 1, it won't......
The address you are to listen for 'other than this', is defined by 'MODBUS_ADDRESS'. This is the one you can change.
Best Wishes |
|
|
|