Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 45 of 45

Thread: Teensy Backpacks

  1. #26
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    528
    Quote Originally Posted by mjs513 View Post
    A while ago you asked me if had any ideas for mounting a t3.6 to the backpack. One possibility is just to lengthen the backpack to fit the T3.6 and extend the headers so that you can get access to the additional pins. It could also give you the ability to make additional backpacks using the other pins as well.

    Regards
    Mike
    Hi Mike, do you mean as a separate product line (i.e. a line of backpacks designed for Teensy 3.0/1/2 and Teensy LC and then a separate product line for Teensy 3.5/6)?

    Brian

  2. #27
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,505
    do you mean as a separate product line
    Just a redesigned backpack. Just make the current backpack longer to fit the T3.5/6 and extend the headers to match the T3.5/3.6 mounting backpack. If i get some time i can probably sketch it up for you.

    Mike

  3. #28
    Junior Member
    Join Date
    Dec 2018
    Posts
    3
    @Brian,

    I have purchased a few of your backpack pieces, and I am impressed! I was wondering if you might have some code to make your Motion-Backpack output work as a "Tilt-Compensated Compass"? This may known as using "Sensor Fusion" but, I am struggling to find a code that I can convert to use with your Backpack.

    I would like the compass to output a value of (0 to 359/360) so that I can use it for North, South Etc. I am replacing an Adafruit 9 Dof found here: https://www.adafruit.com/product/1714. Here is their example code that I have not been able to convert: https://learn.adafruit.com/adafruit-9-dof-imu-breakout

    My project is for a GPS guided RC Truck and my current code works well with the Compass outputting degrees from North.

    I really like your small, clean Backpack designs and I hope you can help me, even though this may require some code to be written.

    Thanks for your Backpack designs and any help you can give,
    Mark M.


    The Backpack that I am referring to:
    Quote Originally Posted by brtaylor View Post
    Motion Backpack
    Integrating an MPU-9250 inertial measurement unit and a BME-280 environmental sensor, this backpack enables you to easily measure your project's motion and altitude. You'll get 3 axis accelerometer, 3 axis gyro, and 3 axis magnetometer data along with pressure, temperature and humidity. Both sensors communicate over I2C, have integrated pullups, and you can select the I2C address for each sensor.

  4. #29
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    528
    Hi Mark,

    Thanks! I'm glad you like the backpack designs. I'm planning on writing a series of tutorials around the Motion Backpack and GNSS Backpack in the next few months. In the meantime, here is what you'll need for a tilt compass, please let me know if you have any questions or run into issues.

    There are two files attached, Mag_Cal.ino and Tilt_Compass.ino. You need to run Mag_Cal.ino only once; this calibrates the magnetometer on the MPU-9250 by estimating the hard and soft iron corrections. It's absolutely necessary to estimate these before doing any heading estimation, these corrections can be very large. There are instructions displayed to the serial terminal when you run the code - basically you'll slowly move the board in a figure 8 motion until the program is complete. Hard and soft iron corrections will be estimated and saved to the Teensy EEPROM. You should run Mag_Cal.ino any time the magnetic environment of the sensor changes, so if you moved its location within the vehicle, you would likely want to re-calibrate the sensor.

    Next, is the Tilt_Compass.ino. This uses the accelerometers to estimate the pitch and roll angles of the sensor, which are used to project the magnetometer data onto a horizontal plane and estimate the yaw angle. Yaw angle is then transformed from a -180 to +180 result to a 0 - 360 result. Finally, because the magnetometer can be pretty noisy, I filter the result as well. All five of these values are available: pitch, roll, yaw (+/- 180), heading (0 - 360), and filtered heading. The +X axis direction is depicted on the Motion Backpack and I use a right handed axis system as depicted here:
    https://github.com/bolderflight/MPU9...or-orientation

    Best,
    Brian
    Attached Files Attached Files

  5. #30
    Junior Member
    Join Date
    Dec 2018
    Posts
    3
    Brian,

    Thank you for your quick reply! I will try your provided sketches right away!

    Thanks for the help,
    Mark

  6. #31
    Junior Member
    Join Date
    Dec 2018
    Posts
    3
    Brian,

    I tested your provided sketches and I am very happy with the results! I have the output I want and without asking you, you also fixed a problem that I had with my previous compass!

    My previous problem was that the compass had random noise in it that would cause the output to jump around 10 or 12 degrees in random directions. Your filter looks like it will smooth the noise and make it a much smaller issue. That is awesome!

    Thanks for the help!
    Mark

  7. #32
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    528
    Quote Originally Posted by CycleGadget View Post
    Brian,

    I tested your provided sketches and I am very happy with the results! I have the output I want and without asking you, you also fixed a problem that I had with my previous compass!

    My previous problem was that the compass had random noise in it that would cause the output to jump around 10 or 12 degrees in random directions. Your filter looks like it will smooth the noise and make it a much smaller issue. That is awesome!

    Thanks for the help!
    Mark
    Awesome! You can adjust the filter by changing window_size; larger values will reduce the noise at the expense of slower filter response. For example a value of 100 would have even less noise, but when the car turns, it would take longer for that turn to show up in the filtered data. A value of 1 would provide no filtering. The filter I used is called a first order IIR filter, it's the easiest filter to implement on a microcontroller since it only requires knowledge of its previous output.

    Best,
    Brian

  8. #33
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,505
    Hi Brian
    Got my GNSS board a couple of weeks ago but got sidetracked with another one of my projects. I finally had a chance to try it out. Was a little disappointed in its performance (acquiring a lock and # sats available). Think the patch antenna is a little to small to get a descent lock unless you are under open skies. I did my tests at my desk by the window and tried a couple of different GPS antennas on Neo-8m boards. Finally hooked up a Beiitian BN-280 (it has pps signal broken out) and it worked without any major issue. I used Chris O's modified library and was able to change the PPS rate as well.

    Just wanted to let you know for future designs. It has a patch antenna as well but its about twice as large as the one on yours.

    Mike

  9. #34
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    528
    Thanks for the feedback! Too bad that you're not getting good satellite performance, let me know if you would like a refund. Works great in my workshop and yard, which is definitely not clear sky, but GNSS receivers are funny that way.

    I'm planning on a board (probably a couple of different boards) and at least one would have external antenna. But I don't have a good ETA on it, waiting to get my hands on the uBlox 9 series and get some of these other projects done.

  10. #35
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,505
    Not a problem Brian. Have a whole collection - like you said GPS receivers are funny especially when you use patch antennas I found.

  11. #36
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,505
    Hi Brian
    Playing around again with the MPU stuff. Just gave your Tilt_compass.ino file a try and never any angles between 0-90 or 0-90. What should be about 0 reads 90 degrees.

    Mike

  12. #37
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    528
    Quote Originally Posted by mjs513 View Post
    Hi Brian
    Playing around again with the MPU stuff. Just gave your Tilt_compass.ino file a try and never any angles between 0-90 or 0-90. What should be about 0 reads 90 degrees.

    Mike
    Hi Mike, which axis?

  13. #38
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,505
    Oops - yaw - the problem child axis

  14. #39
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    528
    How is your calibration? That could be causing it.

  15. #40
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,505
    I used the full calibration sketch and just ran the unavAHRS sketch which seemed to have yaw ok. Was curious how close the two would correspond. I can always redo it and double check.

  16. #41
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,505
    Ok - That was it - was the calibration - redid it and now its working. THanks - was just strange.

  17. #42
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    528
    Quote Originally Posted by mjs513 View Post
    Ok - That was it - was the calibration - redid it and now its working. THanks - was just strange.
    Awesome! That's great to hear.

  18. #43
    Junior Member
    Join Date
    May 2019
    Posts
    1

    Flash Backpack basics using SerialFlash Library

    Hi,
    Started using the backpacks. Started with the flash storage one. Following is a basic initialize and test that may be helpful to other first time users. SerialFlash library has examples but tend to be a little complicated and of course are generic and not setup specifically for the bolder backpack. Key concept I missed at first is that this is really two different SPI devices so you need set the CS pin of the chip you are not accessing to INPUT_PULLUP. This code does the following on each chip, does a full erase, creates a file named test, writes data, reads data, checks for file existing, erases file if exists, writes data, reads data.

    Code:
    #include <SerialFlash.h>
    
    int FlashChipSelect = 16;
    
    bool eraseAllFirst;
    
    int size;
    
    unsigned char id[256];
    
    SerialFlashFile file;
    
    const unsigned long testIncrement = 4096;
    float eraseBytesPerSecond(const unsigned char *id) {
      if (id[0] == 0x20) return 152000.0; // Micron
      if (id[0] == 0x01) return 500000.0; // Spansion
      if (id[0] == 0xEF) return 419430.0; // Winbond
      if (id[0] == 0xC2) return 279620.0; // Macronix
      return 320000.0; // guess?
    }
    
    
    const char * id2chip(const unsigned char *id)
    {
      if (id[0] == 0xEF) {
        // Winbond
        if (id[1] == 0x40) {
          if (id[2] == 0x14) return "W25Q80BV";
          if (id[2] == 0x15) return "W25Q16DV";
          if (id[2] == 0x17) return "W25Q64FV";
          if (id[2] == 0x18) return "W25Q128FV";
          if (id[2] == 0x19) return "W25Q256FV";
        }
      }
      if (id[0] == 0x01) {
        // Spansion
        if (id[1] == 0x02) {
          if (id[2] == 0x16) return "S25FL064A";
          if (id[2] == 0x19) return "S25FL256S";
          if (id[2] == 0x20) return "S25FL512S";
        }
        if (id[1] == 0x20) {
          if (id[2] == 0x18) return "S25FL127S";
        }
      }
      if (id[0] == 0xC2) {
        // Macronix
        if (id[1] == 0x20) {
          if (id[2] == 0x18) return "MX25L12805D";
        }
      }
      if (id[0] == 0x20) {
        // Micron
        if (id[1] == 0xBA) {
          if (id[2] == 0x20) return "N25Q512A";
          if (id[2] == 0x21) return "N25Q00AA";
        }
        if (id[1] == 0xBB) {
          if (id[2] == 0x22) return "MT25QL02GC";
        }
      }
      if (id[0] == 0xBF) {
        // SST
        if (id[1] == 0x25) {
          if (id[2] == 0x02) return "SST25WF010";
          if (id[2] == 0x03) return "SST25WF020";
          if (id[2] == 0x04) return "SST25WF040";
          if (id[2] == 0x41) return "SST25VF016B";
          if (id[2] == 0x4A) return "SST25VF032";
        }
        if (id[1] == 0x25) {
          if (id[2] == 0x01) return "SST26VF016";
          if (id[2] == 0x02) return "SST26VF032";
          if (id[2] == 0x43) return "SST26VF064";
        }
      }
      return "(unknown chip)";
    }
    
    void InitializeSerialFlash(int CSPin)
    {
      if ( FlashChipSelect == 16)
      {
        pinMode(15, INPUT_PULLUP);
        pinMode(16, INPUT);
      }
      else
      {
        pinMode(16, INPUT_PULLUP);
        pinMode(15, INPUT);
      }
      Serial.print("Initializing SerialFlash on CS number:");
      Serial.println(CSPin);
      Serial.println();
      if (!SerialFlash.begin(CSPin)) {
        while (1) {
          Serial.println("Unable to access SPI Flash chip");
          delay(1000);
        }
      }
    }
    
    void PrintChipInfo()
    {
      SerialFlash.readID(id);
      Serial.print("  JEDEC ID:     ");
      Serial.print(id[0], HEX);
      Serial.print(" ");
      Serial.print(id[1], HEX);
      Serial.print(" ");
      Serial.println(id[2], HEX);
      Serial.print("  Part Nummber: ");
      Serial.println(id2chip(id));
      size = SerialFlash.capacity(id);
      Serial.print("Total Size:");
      Serial.println(size);
      Serial.println();
    
    }
    
    void FullErase()
    {
      unsigned long startMillis = millis();
      Serial.print("Flash Memory has ");
      Serial.print(size);
      Serial.println(" bytes.");
      Serial.println("Erasing ALL Flash Memory:");
      // Estimate the (lengthy) wait time.
      Serial.print("  estimated wait: ");
      int seconds = (float)size / eraseBytesPerSecond(id) + 0.5;
      Serial.print(seconds);
      Serial.println(" seconds.");
      Serial.println("  Yes, full chip erase is SLOW!");
      SerialFlash.eraseAll();
      unsigned long dotMillis = millis();
      unsigned char dotcount = 0;
      while (SerialFlash.ready() == false) {
        if (millis() - dotMillis > 1000) {
          dotMillis = dotMillis + 1000;
          Serial.print(".");
          dotcount = dotcount + 1;
          if (dotcount >= 60) {
            Serial.println();
            dotcount = 0;
          }
        }
      }
      if (dotcount > 0) Serial.println();
      Serial.println("Erase completed");
      unsigned long elapsed = millis() - startMillis;
      Serial.print("  actual wait: ");
      Serial.print(elapsed / 1000ul);
      Serial.println(" seconds.");
      Serial.println();
    }
    
    void OpenEraseWrite( const char *fileName, char buffer[])
    {
      SerialFlashFile file = SerialFlash.open(fileName);
      Serial.print("Open Result:");
      Serial.println(file);
      Serial.print("Erasing File:");
      Serial.println(fileName);
      file.erase();
      Serial.print("Writing:");
      Serial.println(buffer);
      file.write(buffer, 12);
      Serial.print("Reading:");
      file.seek(0);
      file.read(buffer, 12);
      Serial.println(buffer);
      Serial.println();
    }
    
    void DoFileTest()
    {
      Serial.println("_________________________________");
      Serial.println();
      InitializeSerialFlash(FlashChipSelect);
    
      PrintChipInfo();
    
      if (eraseAllFirst) {
        FullErase();
      }
    
      String stringOne = "Example Data in Flash With CS Pin ";
      stringOne += FlashChipSelect;
      char buffer[stringOne.length() + 1];
      stringOne.toCharArray(buffer, stringOne.length() + 1);
    
      //SerialFlash.remove("test");
    
      if (SerialFlash.exists("test"))
      {
        Serial.println("File named test already exists");
    
        OpenEraseWrite("test", buffer);
      }
      else
      {
        Serial.println("test does not exist...creating");
        bool createResult = SerialFlash.createErasable("test", 60000);
        Serial.println("Result of create erasable file named test");
        Serial.println(createResult);
        OpenEraseWrite("test", buffer);
      }
      Serial.println("_________________________________");
      Serial.println();
      Serial.println();
    }
    
    void setup() {
      Serial.begin(9600);
    
      while (!Serial) ;
      delay(100);
    
      eraseAllFirst = true;
    
      FlashChipSelect = 16;
    
      DoFileTest();
    
      FlashChipSelect = 15;
    
      DoFileTest();
    
      eraseAllFirst = false;
    
      FlashChipSelect = 16;
    
      DoFileTest();
    
      FlashChipSelect = 15;
    
      DoFileTest();
    }
    
    void loop() {
      // do nothing after the test
    }
    Serial Output should be as follows:
    _________________________________

    Initializing SerialFlash on CS number:16

    JEDEC ID: 1 2 20
    Part Nummber: S25FL512S
    Total Size:67108864

    Flash Memory has 67108864 bytes.
    Erasing ALL Flash Memory:
    estimated wait: 134 seconds.
    Yes, full chip erase is SLOW!
    .................................................. ..........
    ...............................................
    Erase completed
    actual wait: 107 seconds.

    test does not exist...creating
    Result of create erasable file named test
    1
    Open Result:1
    Erasing File:test
    Writing:Example Data in Flash With CS Pin 16
    Reading:Example Data in Flash With CS Pin 16

    _________________________________


    _________________________________

    Initializing SerialFlash on CS number:15

    JEDEC ID: 1 2 20
    Part Nummber: S25FL512S
    Total Size:67108864

    Flash Memory has 67108864 bytes.
    Erasing ALL Flash Memory:
    estimated wait: 134 seconds.
    Yes, full chip erase is SLOW!
    .................................................. ..........
    .................................................. ..........
    .
    Erase completed
    actual wait: 121 seconds.

    test does not exist...creating
    Result of create erasable file named test
    1
    Open Result:1
    Erasing File:test
    Writing:Example Data in Flash With CS Pin 15
    Reading:Example Data in Flash With CS Pin 15

    _________________________________


    _________________________________

    Initializing SerialFlash on CS number:16

    JEDEC ID: 1 2 20
    Part Nummber: S25FL512S
    Total Size:67108864

    File named test already exists
    Open Result:1
    Erasing File:test
    Writing:Example Data in Flash With CS Pin 16
    Reading:Example Data in Flash With CS Pin 16

    _________________________________


    _________________________________

    Initializing SerialFlash on CS number:15

    JEDEC ID: 1 2 20
    Part Nummber: S25FL512S
    Total Size:67108864

    File named test already exists
    Open Result:1
    Erasing File:test
    Writing:Example Data in Flash With CS Pin 15
    Reading:Example Data in Flash With CS Pin 15

    _________________________________
    Last edited by delateurj; 05-14-2019 at 06:20 PM. Reason: Adding output

  19. #44
    How do you access the pins on your dual backpack ?

    Have you thought of a screw shield

    Might be an idea to sell on tindie

  20. #45
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    528
    Quote Originally Posted by Gadget999 View Post
    How do you access the pins on your dual backpack ?

    Have you thought of a screw shield

    Might be an idea to sell on tindie
    The backpacks are meant to work with each other. So, on the dual backpack you could have an SBUS Backpack next to a GNSS Backpack, for example, and have the total stack height less than using the Solo Backpack.

    The screw shield is a good idea, thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •