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


              • #8
                Paul
                We have each of 8 Arduino code "modules" complete and working well standalone. We received the uLCD-35DCT-CLB Dev kit over a week ago. Yes, I know agree with you after using Workshop 4 software for a week....we will be able to accomplish much more by creating user images externally in Adobe for use in Workshop.

                However, for this past week-plus, we have simply been unable to get the display to communicate with out host. We have been trying to be resourceful on our own grinding through your manuals and even searching other site postings regarding comm difficulties.

                We cannot find any detailed information on the OPTIONS Section of Workshop, especially in regards to comm's. Quite frankly, what little info there is in the App Notes as well as some notes about bad rates in the various options tabs, is quite ambiguous.

                This is frustrating. My teammates and I are not new to industrial controls and comm links. It should not be this hard.

                Before I get into specifics, is there a link to a guide that you could provide that could shed light?

                We are using a Teensy 3.6 as the host. We have one other device assigned at TX/RX-2. We are trying to assign your display as TX/RX-1 on our host. There are 4 other devices using I2C. Except for your display, all devices are live simultaneously and posting status to the serial monitor for debugging purposes.

                I hope you can provide some insight. We are out of ideas (and combinations to try setting in Workshop 4).

                Thanks,

                Rocky

                Comment


                • #9
                  Hi Rocky,

                  Yes we should be able to get this communicating over Serial. I have a Teensy 3.6 here, can you let me know how you have the Teensy connected to the display and any snippets of code you have for communicating over Serial between the display and the Teensy and I will replicate it here.

                  As you are using Visi, all config and options for serial are made in code so there isn't anything really to set in Workshop 4

                  Best regards

                  Paul

                  Comment


                  • #10
                    Hi Paul...

                    Thanks for your prompt reply.

                    Our comm issue seems to be even more fundamental than you expect. So far, we have utilized App Note 116 (ok that's really basic intro into stand-alone programming of display). Then we moved to App Note 17. We have experimented solely with VisiGenie to date to try to understand it's limits. We will upgrade to workshop 4 Pro, after we solve this bloody comm problem because we will need the extended functionality of 4 Pro.

                    We are not implementing any of our code yet....just using your examples from GitHub (including the required Arduino libraries and the sketch for this app note). So our code is not even in play yet. It's is a fundamental comm connection or configuration issue.

                    We have tried using the gen4-PA and the STD. 5 way connection. We have tried reassigning Tx/Rx to other pins on the PA board in the OPTIONS section of Workshop 4.

                    We are aware of the comm conflict with USB programming while USB is connected to Teensy 3.6. we just can't get your examples to function.

                    Currently...

                    ~ We have no devices connected to Teensy except the gen4-PA.
                    ~ We want to use Tx/Rx on pins 0,1 of Teensy.
                    ~ Reset on pin 4 (we have inverted pin code Hi-Lo in your sketch for reset to function properly).
                    ~ we have changed serial.begin of your GenieArduino_Demo to serial1.begin (as well as in genie.Begin line)
                    ~ We are using a common ground on display power to the "PA"....the same ground as connected to pin 0 of the Teensy 3.6 host.
                    ~ We have even tried running only on battery to eliminate noise from power supply as a contributor to this problem.....no change.

                    We are all chuckling at ourselves in disbelief that we have this deep of a knowledge pool and cannot make that damn slider on the display example talk to the teensy :-)

                    It simply must be something in mismatched settings but we can't find it.

                    Rocky

                    ​​​​​​(And Ross, Stephen, Tammy, Amir, and Ken)

                    Comment


                    • #11
                      Hi Rocky & Team,

                      You seem to have done a lot of the things I would have suggested. You could go back to using TX & RX on the display via the gen4-IB if you have one, if not you have done the correct thing in moving Serial over to other pins on the gen4-PA to avoid conflict with the USB to Serial converter. When using the gen4-PA make sure that the 'PA' pin matches to the right GPIO pin on the PA as in this image

                      Click image for larger version

Name:	PAPinout.png
Views:	1
Size:	273.4 KB
ID:	64181

                      Comment


                      • #12
                        Also, check that the baud rate under the Project Tab matches the baud rate on the Teensy.

                        Best regards

                        Paul

                        Comment


                        • #13
                          Great news.

                          When I got to the office (unfortunately we work 7 days a week) Ross was already working on this. Yes, we have already seen the tech notes about the Gen4-PA GPIO pin numbers as they relate to Diablo and Picaso. Good there.

                          What Ross did was completely uninstall, reboot and reinstall all software and driver's driver's related to this project. That didn't fix the comm problem. Next he found a very brief thread on the web related to native comm port issues with Arduino directly. A post stated that an AutoDesk process running in the background was silently hijacking comm port settings. Guess what. We make extensive use of Autodesk products... particularly AutoCAD and INVENTOR.

                          Ross opened the process explorer, killed two Autodek processes. Then he re- uploaded to the display and to the host and SHABAM, the display is talking to the host via TxRx-1 and ALSO Ross is using the stock, 5-way connection.

                          All smiles on this end. Time to really dig into productive coding now.

                          Yes, we try to solve problems on our own. We learn better lessons that way. We do not like to be bothersome to tech support staff. But you have been awesome so far with quick responses. We will sing your praises whenever we can to whomever we can.

                          We will continue to try not to be a bother, but with the real work with your display ahead of us, we will likely ask for some assistance.

                          Cheers for now,

                          Rocky

                          PS, our first order for dispays would likely be 100 units but we will need a brighter display. I believe you have a Super Bright series.

                          Comment


                          • #14
                            Hi Rocky,

                            That is great news and nice work Ross finding the comm port hijacking.

                            We are always here if you need any help and we are always happy to help so don't worry about bothering us, it's no bother at all.

                            Good luck with the rest of your project

                            Best regards

                            Paul

                            Comment


                            • #15
                              Mornin' Paul...(well, at least on this side of our little planet it's still early morning)

                              So, I'm going to send you our first module of code to look over. It looked easy through our eyes, but after struggling with the "comm fiasco" for almost 10 days, we've decided to asked for help (perhaps jump starting our efforts in getting our arduino information flowing to the display).

                              > Physical Components: (we will build on this list as we go).
                              - Teensy 3.6
                              - 4D uLCD-35DCT-CLB
                              - Battery "State of Charge" module (Maxim Integrated Circuits #17043)
                              ~ this device is permanently attached to the LiPo cell supply power
                              ~ is provides 2 data elements on the I2C bus.....Voltage and % of Charge remaining

                              > Process Flow:
                              - read the two data sets continuously (update rate does not have to be fast; even as slowly as once every 10 seconds)
                              - push the data from the Maxim device up to two LEDDIGITS fields

                              > Current Sketch:

                              just noticed (just before clicking send now) the first occurrence of serial.Begin about 5 lines into void setup....could that be the problem? could it need to be changed to serial2.begin? there are no other devices with the same address to be unilized in our project. Each device using I2C luckily has an individual address. no need for serial multiplexing in the case of this project.

                              also as a late thought, I can send you the original sketch that was working without trying to incorporate 4D syntax and structure into it.\

                              Our sincerest "Thanks" in advance

                              Rocky
                              =======================================================================================

                              /*First execution of sending numeric data from Teensy 3.6 to 4D Display
                              code segement BB_rev 0.31
                              6-25-18 (BY: Rocky & Ross)
                              LiPo battery to Battery Monitor
                              Batt. Mon. Voltage out to Teensy 3.6 Vcc IN
                              Batt. Mon. I2C out to Pins 18/19
                              4D LedDigits0 = Batt. Voltage 3 digits (x.xx)V
                              4D LedDigits1 = Batt. Percentage 4 digits (xxx.x)%
                              */

                              // 4d Declarations..................................
                              #include <genieArduino.h>
                              Genie genie;
                              #define RESETLINE 4 // Pin 4 D-Write transition Lo-Hi-Lo to reset

                              // Battery Monitor Declarations.....................
                              #include "MAX17043.h" // supplied by vendor for Batt. State Monitor
                              MAX17043 batteryMonitor; // this device comm's with arduino via I2C in realtime

                              #define CellVoltage //=batteryMonitor.getVCell(); // ?? define CellVoltage as data holder
                              #define StateofCharge //=batteryMonitor.getSoC(); // ?? define StateofCharge as data holder

                              #include "Wire.h" // used only for debug on serial monitor
                              // all lines related to serial monitor are for initial
                              // programming and debug only. The serial monitor
                              // functionality will not be included in the v 1.0
                              // production release code (and can be rem'd out).

                              #define CellVoltage = genie.GetEventData(&Event);

                              void setup() {

                              //---Batt Monitor Code Begins Here.....................
                              Wire.begin(); // for serial monitor
                              Serial.begin(200000); // MAXIM factory setting was (115200)
                              batteryMonitor.reset();
                              batteryMonitor.quickStart();
                              delay(1000);

                              //---4D SETUP Code Begins Here.....................
                              // NOTE, Use Serial Begin w/ serial port of choice.
                              // Use the genie.Begin function to send it to the Genie library
                              // 200K Baud is good for most Arduinos.
                              Serial1.begin(200000); // Serial1 @ 200000 (200K) Baud
                              genie.Begin(Serial1); // Use Serial1 for comms to the Genie Library, and to 4D display

                              // the next line was rem'd out by Rocky due to error compliling
                              //genie.AttachEventHandler(myGenieEventHandler); // Attach the user function Event Handler for processing events
                              // need to learn about Event Handler

                              // Reset the Display
                              // If wired direct to 4D display, digitalWrites must be reversed
                              // as Display Reset is Active Low. The 4D Arduino Adaptors
                              // invert this signal so must be Active High.
                              pinMode(RESETLINE, OUTPUT); // Set Pin4 on Arduino to D-Output
                              digitalWrite(RESETLINE, 0); // Reset the Display via D4_write LO (inverted from 4D default)[by:Rocky]
                              delay(100);
                              digitalWrite(RESETLINE, 1); // unReset the Display via D4_write HI (inverted from 4D default)[by:Rocky]

                              delay (3500); // let the display start up after the reset (This is important)

                              //---4D Brightness Code Starts Here............................
                              // Set the brightness/Contrast of the Display
                              // Range 0 to 15 (0=OFF, 15=MAX Bright)
                              genie.WriteContrast(15);

                              }

                              void loop() {
                              // next line was rem'd out for non-declaration at this time of compiling...
                              // Rocky needs to learn more about do events
                              // genie.DoEvents(); // This calls the library each loop to process the queued responses from the display
                              // at present, we have no need of response from display. We want display to update
                              // in realtime as values change in the defined variable in the Teesny [voltage and Percentage].

                              float CellVoltage = batteryMonitor.getVCell();
                              Serial.print("Voltage:\t\t"); // print to serial monitor for debugging
                              Serial.print(CellVoltage, 2); // print value to 2 dec. places X.XX
                              Serial.println(" V");

                              float StateofCharge = batteryMonitor.getSoC();
                              Serial.print("State of charge:\t"); // print to serial monitor for debugging
                              Serial.print(StateofCharge); // prints numeric value
                              Serial.println(" %"); // as a percentage
                              Serial.println(" "); // line break - formatting to serial monitor for readability
                              Serial.println(" "); // line break - formatting to serial monitor for readability

                              delay(1000); // delay repeat to serial monitor for readability


                              CellVoltage = genie.GetEventData(&Event); // ?? is this correct usage of 'aquiring' value of declared variable ??
                              genie.WriteObject(GENIE_OBJ_LEDDIGITS, 0, CellVoltage); // ?? is this correct syntx to send value to genie_Obj ??

                              StateofCharge = genie.GetEventData(&Event); // ?? same question
                              genie.WriteObject(GENIE_OBJ_LEDDIGITS, 1, StateofCharge); // ?? same question
                              }

                              Comment

                              Working...
                              X