Announcement

Collapse
No announcement yet.

Is it possible....Bosch (BNO055) IMU - to - Diablo display ??

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

  • Is it possible....Bosch (BNO055) IMU - to - Diablo display ??

    New to 4D Systems. Hope this is posting into the correct forum. If not, can a MOD please suggest correct location?

    We are trying to determine if using Bosch IMU to provide input directly to DIABLO or other 4D display is practical. Objective is merely to display output from IMU utilizing a 3-D, 3-axis of freedom, object on the display. We have developed several operational prototypes and now trying to reduce the total board/component count. To date, all work has been thru Arduino or Python. Ultimately, CAP-Touch (for field configuration of certain program variables thru setting menu) is desired but not absolute requirement.

    Attached are two tech. ref's related to the BOSCH IMU.

    Thanks in advance from this 1st-time poster here @ 4D

    Rocky
    Attached Files

  • #2
    Hello,

    Yes it would be easily possible to use the BNO055 IMU, It has successfully been attached directly to a Diablo processor a couple of years ago. The BOSCH sensor because of it's on board processor is not a hard device to code, A calibrartion routine needs to be written for the device to work correctly but if I remember rightly, that was the hardest piece of code to implement.

    If there is any example code for the BNO055 I will share it here but I can't promise that it still exist's as it was quite a while ago.

    I hope this helps

    Best regards

    Paul

    Comment


    • #3
      Hi,

      I have found the code which is part of a larger project so I have taken out the useful I2C functions that were used. I no longer have a BNO055 to test with but I hope this helps.

      Code:
      var device1 := 0x50;
      var WR := 1;
      
      func readcal(var address1)
          I2C2_Start();
          I2C2_Write(device1);
          I2C2_Write(LObyte(0x55));
          I2C2_Start();
          I2C2_Write(device1+WR);
          for(n := 1; n < 23; n++)
          calib[n] := I2C2_Read();
          if(n < 22)
          I2C2_Ack();
      
          endif
          next
          I2C2_Nack();
          I2C2_Stop();
          return r;
      endfunc
      
      func sendcal(var address1, var value)
          I2C2_Start();
          I2C2_Write(device1);
          I2C2_Write(address1);
          I2C2_Write(value);
          I2C2_Stop();
          return r;
      endfunc
      
       func readver()                      // Not Supported
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(4);
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          bnoverl := I2C2_Read();
          I2C2_Ack();
          bnoverh := I2C2_Read();
          I2C2_Nack();
          I2C2_Stop();
          acc1 := ((a2 << 8) + a1) / 4;
          return r;                                       // return the register value
      endfunc
      
      func readacc(var address1)                      // Not Supported
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(address1));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          a1 := I2C2_Read();
          I2C2_Ack();
          a2 := I2C2_Read();
          I2C2_Nack();
          I2C2_Stop();
          acc1 := ((a2 << 8) + a1) / 4;
          return r;                                       // return the register value
      endfunc
      
      func readraw(var address1)                      // Not Supported
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(address1));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          g1 := I2C2_Read();
          I2C2_Ack();
          g2 := I2C2_Read();
          I2C2_Ack();
          g3 := I2C2_Read();
          I2C2_Ack();
          g4 := I2C2_Read();
          I2C2_Nack();
          I2C2_Stop();
          gx := ((g2 << 8) + g1);
          gy := ((g4 << 8) + g3);
          return r;                                       // return the register value
      endfunc
      
      func readcalstat(var address1)                      // Not Supported
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(address1));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          r := I2C2_Read();
      
          I2C2_Nack();
          I2C2_Stop();
      
          return r;                                       // return the register value
      endfunc
      
      func readbmp(var address1)                          // Not Supported
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(address1));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          r := I2C2_Read();
          I2C2_Nack();                                    // finished reading, send Not Ack
          I2C2_Stop();                                    // Send Stop Condition
          return r;                                       // return the register value
      endfunc
      
      func readbearing(var address1)                      // Not Supported
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(address1));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          deglo := I2C2_Read();
          I2C2_Ack();
      
      
          deghi := I2C2_Read();
      
          I2C2_Nack();
          I2C2_Stop();                                    // Send Stop Condition
          return r;                                       // return the register value
      endfunc
      
       func readpitch(var address1)                       // Not Supported
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(address1));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          p1 := I2C2_Read();
          I2C2_Ack();                                     // finished reading, send Not Ack
          p2 := I2C2_Read();
          I2C2_Nack();
          I2C2_Stop();                                    // Send Stop Condition
          pitch := (p2 << 8) + p1;
          return r;
      endfunc
      
      func readroll(var address1)                         // Not Supported
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(address1));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          p1 := I2C2_Read();
          I2C2_Ack();                                     // finished reading, send Not Ack
          p2 := I2C2_Read();
      
          I2C2_Nack();
          I2C2_Stop();                                    // Send Stop Condition
          roll := ((p2 << 8) + p1) / 16;
          return r;
      endfunc
      
      func readeul(var address1)                          // Not Supported
          I2Cbusy := 1;
      
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(0x1a));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);
      
      
          deglo := I2C2_Read();
          I2C2_Ack();                                     // finished reading, send Not Ack
          deghi := I2C2_Read();
          I2C2_Ack();                                     // finished reading, send Not Ack
          p1 := I2C2_Read();
          I2C2_Ack();                                     // finished reading, send Not Ack
          p2 := I2C2_Read();
          roll := ((p2 << 8) + p1)/16;
          I2C2_Ack();                                     // finished reading, send Not Ack
          p1 := I2C2_Read();
          I2C2_Ack();                                     // finished reading, send Not Ack
          p2 := I2C2_Read();
      
      
          I2C2_Nack();
          I2C2_Stop();                                    // Send Stop Condition
          pitch := ((p2 << 8) + p1)/16;
          I2Cbusy := 0;
          return r;
      endfunc
      
      func readacc1(var address1)                          // Not Supported
          I2Cbusy := 1;
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave address
          I2C2_Write(LObyte(address1));
          I2C2_Start();                                   // Generate Restart
          I2C2_Write(device1+WR);                         // send control byte for Read
          a1 := I2C2_Read();
          I2C2_Ack();                                     // finished reading, send Not Ack
          a2 := I2C2_Read();
          I2C2_Ack();                                     // finished reading, send Not Ack
          acc1 := ((a2 << 8) + a1);
      
      
          I2C2_Nack();
          I2C2_Stop();                                    // Send Stop Condition
      
          I2Cbusy := 0;
          return r;
      endfunc
                                                          // send command to barometer - no longer used
      func sendcmd(var address1, var value)
          I2C2_Start();                                   // Generate Start condition
          I2C2_Write(device1);                            // send slave
          I2C2_Write(address1);
          I2C2_Write(value);
          I2C2_Stop();                                    // Send Stop Condition
          return r;                                       // return the register value
      endfunc
      Best regards

      Paul

      Comment


      • #4
        Paul

        Thank you for researching that historical work. At first glance it looks like an elegant solution to be able to use the Bosch IMU directly.

        Now we are experimenting with your graphics software to try to determine exactly how much creative license we have in graphics design for the display of information.

        As an example, we want to be able to display output from the IMU as a set of digits on rotating drums....much like the old mechanical odometer in a vehicle. We want to be able to animate the rotation of digits into and out of view (but the Crux of that is perhaps, for another forum here at 4D).

        Thank you again for the code you posted. It will put us days/weeks ahead.

        Cheers for now.....

        Rocky

        Comment


        • #5
          Hi Rocky,

          You're very welcome. Let me know if you need any more help with the BNO055, in particular the calibration routine. The Barrel meter can be done either by using UserImages or with text but you would get a nicer result with Userimages and a paint package to create the effect of the digits rotating.

          Best regards

          Paul

          Comment


          • #6
            Paul,

            We have your 3.5" capacitive touch display in hand and we are digesting your software application as quickly as possible. Your online application notes are very helpful.

            I already see the advantage however of using images we create externally. Fortunately, I come from a previous job in the graphics industry and use Photoshop and Illustrator (Adobe) extensively.

            As we advance to significant programming (so as not to bombard you with "beginner's" questions, I'm sure we will have questions where your experience would be most appreciated.

            Currently, we are trying to decide what will run onboard the display controller and what will run on the teensy 3.6 that will piggy back the display. Right now we are cleaning up the code for a "single knob" interface via rotary Encoder with momentary p.b. as well as translucent shaft with embedded RGB led to assist with mode enunciation and other status needs.

            Rocky

            PS. Could you investigate on your side regarding my login credentials?. I cannot log into the forum from any other location except this device. I get a username or password invalid. I'm quite sure that my keystrokes are correct on my end.

            Comment


            • #7
              Hi Rocky,

              Your graphics expertise will be really useful in your project. You can off-load most of your design work into image design for some nice animated results.

              I ended up attaching the rotary encoder to the host processor leaving the display just handling graphics and communication.

              I will try to find out why you are having difficulty logging in to the forum.

              Best regards

              Paul

              Comment

              Working...
              X