Announcement

Collapse
No announcement yet.

I2C and Float issues.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • I2C and Float issues.

    Hello there, I'm currently working on sending precise values over I2C, from an arduino (Arduino Mega 2560) to a diablo16 display (model Gen4-uLCD-43DCT-CLB), i've managed to send Integers just fine, and thought i'd move on to try and send some float values, however i am having some problems, as the way the 4DGL language handles floats confuse me a great deal.

    I think i understand what is going wrong, however i am unsure what to do about it, i've been trying to convert the float into integers before sending them, however i've had no luck with that as of yet, so i wanted to give converting it on the receiving side a try.

    I've attached both the arduino sketch and 4DGL sketch.
    Attached Files

  • #2
    Hi weirdwolf,

    Good Day.

    From your code:
    Code:
         //print(x);
         print("received: ",floatA[0]);
         print(".",floatA[1]);
         print("\n");
         print(floatA);
         pause(1000);
         gfx_Cls();
    Imagine you are have the float 2.01. Assuming the integer part is at index 0 and the decimal part is in index 1, you will be printing 2.1. Therefore, it would be totally wrong to assume that this is how float works.

    4DGL floats works the same way in other languages. Since var is 16 bits and you are required to have an array of 2 var elements to contain the float value, we can conclude that 4DGL floats are 32bits.

    As you can see here: https://en.wikipedia.org/wiki/Single...g-point_format
    Float values are stored not as you've used it.

    The proper way to print a float is as shown below:
    Code:
        var Float[2];
        flt_VAL(Float, "2.01");
        flt_PRINT(Float, "%f");
    In your case:
    Code:
        floatA[0] := I2C1_Read();
        I2C1_Ack() ;
        floatA[0] := I2C1_Read() << 8;
        I2C1_Ack();
        floatA[1] := I2C1_Read();
        I2C1_Ack();
        floatA[1] := I2C1_Read() << 8;
    
        flt_PRINT(floatA, "%f");
    If this prints a different value, this only means that you've stored the bytes incorrectly.
    4DGL Follows Mid-Little Endian (CDAB), therefore floatA[1] is AB High Word while floatA[0] is CD Low Word.

    If you want to test, try sending 2.01 as float and if you use:

    Code:
    print("\n", [HEX4Z]Float[0], [HEX4Z]Float[1]);
    You should get: A3D74000

    Best Regards,

    Comment


    • #3
      Thank you very much for the answer, i'll try this out next time i get around to it, i ended up working around it by using a "math conversion" on the arduino side.

      continuing with the 2.01 float value example, with 2 integers, X and Y, i set X to the floats value, then subtracted X from the float, and multiplied it with 1000, and then put that into Y, so X was the whole numbers, and Y was the decimals, then sent those over.

      like so:
      Code:
      X = floatVal; // X = 2
      floatVal = (floatVal - X) * 1000; //floatVal = (floatVal - 2) * 1000
      //floatVal = 10.0
      Y = floatVal; // Y = 10

      Comment


      • #4
        Good day,

        Still there seems to be a problem with how you try to handle floats.

        See let's change the example to 2.21

        Code:
        X = floatVal; // X = 2
        floatVal = (floatVal - X) * 1000; // floatVal = (2.21 - 2) * 1000 = 0.21 * 1000 = 210
        // floatVal = 210
        Y = floatVal; // Y = 210
        I didn't quite catch how you think these two separate integers each holding the whole number part and fractional part separately could represent a floating point value properly.

        Anyway, you don't really have to do anything in Arduino float so we can leave that topic aside.

        You simply have to send each 4 bytes of the floating point value then receive and store it in proper order on the display module 4DGL code.

        Regards,

        Comment


        • #5
          The calculation is just meant to give me 2 integers that i can use to display the value i've measured, they're not meant to represent an actual floating point variable, and they don't, as you've pointed out.

          Using the two integers was simply meant as a sort of band-aid solution, as there are multiple problems with that way of handling the values, one of which is that, if you're only going off of the calculation i made, then 2.01 would show up as 2.10, because X is 2 and Y is 10, to get around that i just made a couple of if statements adding zeroes in front based on the value of Y.

          I haven't had the chance to try and implement the code you wrote me yet, but i'll be giving it a try soon enough, Thank you very much for the help.

          Comment


          • #6
            Hi,

            Okay.

            At first, it seemed that you were discussing this as a part of your inquiry. But that is all cleared now.

            I hope you can test it out soon. Let me know if you had any trouble.

            We are always glad to help.

            Regards,
            Ferdinand

            Comment

            Working...
            X