diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..c3d3942 --- /dev/null +++ b/404.html @@ -0,0 +1,1073 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + +This example demonstrates how to use the navigation switch and detect if the SD card is inserted. The !INT pin of the GPIO expander IC (PCA9554) triggers an interrupt any time a button is pressed or an SD card is inserted/removed.
+The code for this example can be found in the Firmware folder of this repository. Alternatively, you can expand the link below and copy and paste the code into a shiny new Arduino sketch:
+/*
+ Read the 5-way switch and card detect on the Portability Shield
+ By: Nathan Seidle
+ SparkFun Electronics
+ Date: November 24th, 2024
+ License: This code is public domain but you buy me a drink if you use this
+ and we meet someday (Drink license).
+ Feel like supporting our work? Buy a board from SparkFun!
+ https://www.sparkfun.com/products/27510
+
+ This example demonstrates how to read the 5-way nav switch and detect if the SD card is inserted.
+ The !INT pin of the GPIO expander IC (PCA9554) triggers an interrupt any time a button is pressed or
+ an SD card is inserted/removed.
+
+ Hardware Connections:
+ Connect the Portability shield to the RTK Postcard or other controller board
+ Open output window at 115200bps
+ Press button on navigation switch
+*/
+
+#include <SparkFun_I2C_Expander_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_I2C_Expander_Arduino_Library
+
+SFE_PCA95XX io(PCA95XX_PCA9554); // Create an instance with the PCA9554 IC
+
+int gpioExpander_up = 0;
+int gpioExpander_down = 1;
+int gpioExpander_right = 2;
+int gpioExpander_left = 3;
+int gpioExpander_center = 4;
+int gpioExpander_cardDetect = 5;
+
+int gpioExpander_interrupt = 14; //INT of PCA9554 is connected to ESP14. Goes low when button is pressed.
+
+bool buttonPressed = false;
+
+void IRAM_ATTR gpioExpanderISR()
+{
+ buttonPressed = true;
+}
+
+void setup()
+{
+ Serial.begin(115200);
+ delay(250);
+ Serial.println("Portability Shield Example");
+
+ Wire.begin(7, 20); //SDA, SCL. I2C0 on Portability Shield
+
+ // Initialize the PCA95xx with its default I2C address
+ if (io.begin() == false)
+ {
+ Serial.println("PCA9554 not detected. Please check wiring. Freezing...");
+ while (1)
+ ;
+ }
+ Serial.println("Portability Shield online!");
+
+ pinMode(gpioExpander_interrupt, INPUT_PULLUP);
+
+ io.pinMode(gpioExpander_up, INPUT);
+ io.pinMode(gpioExpander_down, INPUT);
+ io.pinMode(gpioExpander_left, INPUT);
+ io.pinMode(gpioExpander_right, INPUT);
+ io.pinMode(gpioExpander_center, INPUT);
+ io.pinMode(gpioExpander_cardDetect, INPUT);
+
+ uint8_t currentState = io.getInputRegister() & 0b00111111; //Ignore unconnected GPIO6/7
+ if (currentState & 0b00100000)
+ Serial.println("SD Card detected");
+ else
+ Serial.println("No card detected");
+
+ //Setup interrupt service routine (ISR)
+ attachInterrupt(gpioExpander_interrupt, gpioExpanderISR, CHANGE);
+}
+
+void loop()
+{
+ if (buttonPressed == true)
+ {
+ //Get all the pins in one read
+ uint8_t currentState = io.getInputRegister() & 0b00111111; //Ignore unconnected GPIO6/7
+
+ // Pins are pulled high so when we see low, button is being pressed
+ if ((currentState & (1 << gpioExpander_up)) == 0)
+ Serial.print("Up");
+ if ((currentState & (1 << gpioExpander_down)) == 0)
+ Serial.print("Down");
+ if ((currentState & (1 << gpioExpander_left)) == 0)
+ Serial.print("Left");
+ if ((currentState & (1 << gpioExpander_right)) == 0)
+ Serial.print("Right");
+ if ((currentState & (1 << gpioExpander_center)) == 0)
+ Serial.print("Center");
+
+ Serial.println();
+
+ buttonPressed = false;
+ }
+
+ delay(100);
+}
+
One thing to note is that you will also need to install the SparkFun I2C Expander Arduino Library if you haven't already. You can search the library from within the Arduino Library manager, download the zip from the GitHub Repository and install it manually, or you can click the link from within the code. Clicking the link will show something like the following:
+ +Make sure you've selected the correct board (in this case, you will need to use ESP32 Dev Module from espressif) and port in the Tools menu and then hit the upload button. Once the code has finished uploading, go ahead and open a Serial Monitor. You should see something similar to the following.
+ +This file demonstrates the simple API of the SparkFun MAX17043 Arduino library. Make sure you have a LiPo battery plugged into the JST port.
+The code for this example can be found in the Firmware folder of this repository. Alternatively, you can expand the link below and copy and paste the code into a shiny new Arduino sketch:
+/*
+ Example1_Simple
+ By: Paul Clark
+ Date: October 23rd 2020
+
+ Based extensively on:
+ MAX17043_Simple_Serial.cpp
+ SparkFun MAX17043 Example Code
+ Jim Lindblom @ SparkFun Electronics
+ Original Creation Date: June 22, 2015
+
+ This file demonstrates the simple API of the SparkFun MAX17043 Arduino library.
+
+ This example will print the gauge's voltage and state-of-charge (SOC) readings
+ to Serial (115200 baud)
+
+ This code is released under the MIT license.
+
+ Distributed as-is; no warranty is given.
+*/
+
+#include <Wire.h> // Needed for I2C
+
+#include <SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library
+
+SFE_MAX1704X lipo(MAX1704X_MAX17048); // Create a MAX17048
+
+double voltage = 0; // Variable to keep track of LiPo voltage
+double soc = 0; // Variable to keep track of LiPo state-of-charge (SOC)
+bool alert; // Variable to keep track of whether alert has been triggered
+
+void setup()
+{
+ Serial.begin(115200); // Start serial, to output debug data
+ while (!Serial)
+ ; //Wait for user to open terminal
+ Serial.println(F("MAX17043 Example"));
+
+ Wire.begin(7, 20); //SDA, SCL
+
+ // Set up the fuel gauge:
+ if (lipo.begin() == false)
+ {
+ Serial.println(F("MAX17043 not detected. Please check wiring. Freezing."));
+ while (1)
+ ;
+ }
+
+ // Quick start restarts the MAX17043 in hopes of getting a more accurate
+ // guess for the SOC.
+ lipo.quickStart();
+
+ // We can set an interrupt to alert when the battery SoC gets too low.
+ // We can alert at anywhere between 1% - 32%:
+ lipo.setThreshold(20); // Set alert threshold to 20%.
+}
+
+void loop()
+{
+ // lipo.getVoltage() returns a voltage value (e.g. 3.93)
+ voltage = lipo.getVoltage();
+ // lipo.getSOC() returns the estimated state of charge (e.g. 79%)
+ soc = lipo.getSOC();
+ // lipo.getAlert() returns a 0 or 1 (0=alert not triggered)
+ alert = lipo.getAlert();
+
+ // Print the variables:
+ Serial.print("Voltage: ");
+ Serial.print(voltage); // Print the battery voltage
+ Serial.println(" V");
+
+ Serial.print("Percentage: ");
+ Serial.print(soc); // Print the battery state of charge
+ Serial.println(" %");
+
+ Serial.print("Alert: ");
+ Serial.println(alert);
+ Serial.println();
+
+ delay(500);
+}
+
You will also need to install the SparkFun MAX1704x Fuel Gauge Arduino Library if you haven't already. You can search the library from within the Arduino Library manager, download the zip from the GitHub Repository and install it manually, or you can click the link from within the code. Clicking the link will show something like the following:
+ +Make sure you've selected the correct board and port in the Tools menu and then hit the upload button. Once the code has finished uploading, go ahead and open a Serial Monitor at 115200 baud. You should see the gauge's voltage and state-of-charge (SOC) readings, similar to the following:
+ +This example demonstrates how to display on the 1.3" OLED and read the fuel gauge. You should have the Portability Shield connected to the RTK Postcard or other controller and a LiPo battery plugged into the JST port.
+The code for this example can be found in the Firmware folder of this repository. Alternatively, you can expand the link below and copy and paste the code into a shiny new Arduino sketch:
+/*
+ Display a cube on the OLED at 400kHz. Query the fuel guage periodically.
+ By: Nathan Seidle
+ SparkFun Electronics
+ Date: November 24th, 2024
+ License: This code is public domain but you buy me a drink if you use this
+ and we meet someday (Drink license).
+ Feel like supporting our work? Buy a board from SparkFun!
+ https://www.sparkfun.com/products/27510
+
+ This example demonstrates how to display on the 1.3" OLED and read the fuel gauge.
+
+ Hardware Connections:
+ Connect the Portability shield to the RTK Postcard or other controller board
+ Open output window at 115200bps
+*/
+#include <Wire.h>
+
+#include <SparkFun_Qwiic_OLED.h> //http://librarymanager/All#SparkFun_Qwiic_OLED
+Qwiic1in3OLED myOLED;
+
+int width;
+int height;
+
+// For simple frame rate calculations
+long drawTotalTime = 0;
+int numberOfDraws = 0;
+
+float d = 3;
+float px[] = { -d, d, d, -d, -d, d, d, -d};
+float py[] = { -d, -d, d, d, -d, -d, d, d};
+float pz[] = { -d, -d, -d, -d, d, d, d, d};
+
+float p2x[8] = {0};
+float p2y[8] = {0};
+float r[3] = {0};
+
+#define SHAPE_SIZE 950
+#define ROTATION_SPEED 00
+
+#include <SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library
+SFE_MAX1704X lipo(MAX1704X_MAX17048);
+
+double voltage = 0;
+double soc = 0;
+unsigned long lastLipoCheck;
+
+void setup()
+{
+ Serial.begin(115200);
+ delay(250);
+ Serial.println("OLED + Fuel gauge test");
+
+ Wire.begin(7, 20); //SDA, SCL
+ Wire.setClock(400000); //Go to 400kHz for faster OLED response
+ //Wire.setClock(1000000); //Moar! It's not 1MHz but it does work.
+
+ if (myOLED.begin() == false)
+ {
+ Serial.println("Device begin failed. Freezing...");
+ while (true);
+ }
+
+ if (lipo.begin() == false)
+ {
+ Serial.println("MAX17043 not detected. Please check wiring. Freezing...");
+ while (1);
+ }
+
+ Serial.println("Begin success");
+
+ width = myOLED.getWidth();
+ height = myOLED.getHeight();
+
+ // For frame rate calc
+ drawTotalTime = 0;
+ numberOfDraws = 0;
+}
+
+void loop()
+{
+ drawCube();
+
+ if (millis() - lastLipoCheck > 1000)
+ {
+ lastLipoCheck = millis();
+ voltage = lipo.getVoltage();
+ soc = lipo.getSOC();
+
+ Serial.print("Voltage: ");
+ Serial.print(voltage); // Print the battery voltage
+ Serial.println(" V");
+
+ Serial.print("Percentage: ");
+ Serial.print(soc); // Print the battery state of charge
+ Serial.println(" %");
+
+ Serial.println();
+ }
+}
+
+void drawCube()
+{
+ r[0] = r[0] + PI / 180.0; // Add a degree
+ r[1] = r[1] + PI / 180.0; // Add a degree
+ r[2] = r[2] + PI / 180.0; // Add a degree
+ if (r[0] >= 360.0 * PI / 180.0)
+ r[0] = 0;
+ if (r[1] >= 360.0 * PI / 180.0)
+ r[1] = 0;
+ if (r[2] >= 360.0 * PI / 180.0)
+ r[2] = 0;
+
+ // This routine gets called often, so just make these statics
+ static float px2, py2, pz2, px3, py3, pz3, ax, ay, az;
+
+ for (int i = 0; i < 8; i++)
+ {
+ px2 = px[i];
+ py2 = cos(r[0]) * py[i] - sin(r[0]) * pz[i];
+ pz2 = sin(r[0]) * py[i] + cos(r[0]) * pz[i];
+
+ px3 = cos(r[1]) * px2 + sin(r[1]) * pz2;
+ py3 = py2;
+ pz3 = -sin(r[1]) * px2 + cos(r[1]) * pz2;
+
+ ax = cos(r[2]) * px3 - sin(r[2]) * py3;
+ ay = sin(r[2]) * px3 + cos(r[2]) * py3;
+ az = pz3 - 150;
+
+ p2x[i] = width / 2 + ax * SHAPE_SIZE / az;
+ p2y[i] = height / 2 + ay * SHAPE_SIZE / az;
+ }
+
+ // Calculate draw time
+ uint32_t startTime = millis();
+
+ myOLED.erase();
+ for (int i = 0; i < 3; i++)
+ {
+ myOLED.line(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1]);
+ myOLED.line(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5]);
+ myOLED.line(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4]);
+ }
+
+ myOLED.line(p2x[3], p2y[3], p2x[0], p2y[0]);
+ myOLED.line(p2x[7], p2y[7], p2x[4], p2y[4]);
+ myOLED.line(p2x[3], p2y[3], p2x[7], p2y[7]);
+ myOLED.display();
+
+ // Write out our frame rate
+ drawTotalTime += millis() - startTime;
+ numberOfDraws++;
+
+ // Output framerate once every 120 frames
+ if (numberOfDraws % 120 == 0)
+ {
+ Serial.print("Frame rate: ");
+ Serial.println(numberOfDraws / (float)drawTotalTime * 1000.0);
+
+ numberOfDraws = 0;
+ drawTotalTime = 0;
+ }
+}
+
You will also need both the SparkFun Qwiic OLED Arduino Library as well as the SparkFun MAX1704x Fuel Gauge Arduino Library. If you haven't already installed these, you can search them from within the Arduino Library manager and install them from there. Alternatively, you can download the zips from their respective GitHub Repositories here(Fuel Gauge) and here(Qwiic OLED), and install them manually.
+Make sure you've selected the correct board and port in the Tools menu and then hit the upload button. Once the code has finished uploading, you should see the gauge's voltage and state-of-charge (SOC) readings, similar to the the output for Example 2. +The 1.3" OLED display should show a bouncing box like so:
+ +This example will mount an SD card, analyze the type of card, and output the analysis via the Serial Monitor.
+Go ahead and connect the Portability Shield to the RTK Postcard or other controller board. Insert a microSD card into the socket. Cards up to 512GB should work.
+The code for this example can be found in the Firmware folder of this repository. Alternatively, you can expand the link below and copy and paste the code into a shiny new Arduino sketch:
+/*
+ Attempt to mount an SD card and analyze the type of card
+ By: Nathan Seidle
+ SparkFun Electronics
+ Date: November 24th, 2024
+ License: This code is public domain but you buy me a drink if you use this
+ and we meet someday (Drink license).
+ Feel like supporting our work? Buy a board from SparkFun!
+ https://www.sparkfun.com/products/27510
+
+ Hardware Connections:
+ Connect the Portability shield to the RTK Postcard or other controller board
+ Insert a microSD card into the socket. Cards up to 512GB should work.
+ Open output window at 115200bps
+*/
+#include "SdFat.h" // Click here to get the library: http://librarymanager/All#SdFat_SDXC by Bill Greiman
+#include "sdios.h"
+
+int pin_spiSCK = 32;
+int pin_spiPICO = 26; //microSD SDI
+int pin_spiPOCI = 25; //microSD SDO
+int pin_microSD_CS = 27;
+
+#define SD_CONFIG SdSpiConfig(pin_microSD_CS, SHARED_SPI, SD_SCK_MHZ(16))
+//#define SD_CONFIG SdSpiConfig(pin_microSD_CS, DEDICATED_SPI, SD_SCK_MHZ(16))
+
+const int8_t DISABLE_CS_PIN = -1;
+
+//------------------------------------------------------------------------------
+SdFs sd;
+cid_t cid;
+csd_t csd;
+scr_t scr;
+uint8_t cmd6Data[64];
+uint32_t eraseSize;
+uint32_t ocr;
+static ArduinoOutStream cout(Serial);
+//------------------------------------------------------------------------------
+void cidDmp() {
+ cout << F("\nManufacturer ID: ");
+ cout << uppercase << showbase << hex << int(cid.mid) << dec << endl;
+ cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
+ cout << F("Product: ");
+ for (uint8_t i = 0; i < 5; i++) {
+ cout << cid.pnm[i];
+ }
+ cout << F("\nRevision: ") << cid.prvN() << '.' << cid.prvM() << endl;
+ cout << F("Serial number: ") << hex << cid.psn() << dec << endl;
+ cout << F("Manufacturing date: ");
+ cout << cid.mdtMonth() << '/' << cid.mdtYear() << endl;
+ cout << F("CID HEX: ");
+ hexDmp(&cid, sizeof(cid));
+}
+//------------------------------------------------------------------------------
+void clearSerialInput() {
+ uint32_t m = micros();
+ do {
+ if (Serial.read() >= 0) {
+ m = micros();
+ }
+ } while (micros() - m < 10000);
+}
+//------------------------------------------------------------------------------
+void csdDmp() {
+ eraseSize = csd.eraseSize();
+ cout << F("\ncardSize: ") << 0.000512 * csd.capacity();
+ cout << F(" MB (MB = 1,000,000 bytes)\n");
+
+ cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n");
+ cout << F("eraseSingleBlock: ");
+ if (csd.eraseSingleBlock()) {
+ cout << F("true\n");
+ } else {
+ cout << F("false\n");
+ }
+ cout << F("dataAfterErase: ");
+ if (scr.dataAfterErase()) {
+ cout << F("ones\n");
+ } else {
+ cout << F("zeros\n");
+ }
+ cout << F("CSD HEX: ");
+ hexDmp(&csd, sizeof(csd));
+}
+//------------------------------------------------------------------------------
+void errorPrint() {
+ if (sd.sdErrorCode()) {
+ cout << F("SD errorCode: ") << hex << showbase;
+ printSdErrorSymbol(&Serial, sd.sdErrorCode());
+ cout << F(" = ") << int(sd.sdErrorCode()) << endl;
+ cout << F("SD errorData = ") << int(sd.sdErrorData()) << dec << endl;
+ }
+}
+//------------------------------------------------------------------------------
+void hexDmp(void* reg, uint8_t size) {
+ uint8_t* u8 = reinterpret_cast<uint8_t*>(reg);
+ cout << hex << noshowbase;
+ for (size_t i = 0; i < size; i++) {
+ cout << setw(2) << setfill('0') << int(u8[i]);
+ }
+ cout << dec << endl;
+}
+//------------------------------------------------------------------------------
+bool mbrDmp() {
+ MbrSector_t mbr;
+ bool valid = true;
+ if (!sd.card()->readSector(0, (uint8_t*)&mbr)) {
+ cout << F("\nread MBR failed.\n");
+ errorPrint();
+ return false;
+ }
+ cout << F("\nSD Partition Table\n");
+ cout << F("part,boot,bgnCHS[3],type,endCHS[3],start,length\n");
+ for (uint8_t ip = 1; ip < 5; ip++) {
+ MbrPart_t* pt = &mbr.part[ip - 1];
+ if ((pt->boot != 0 && pt->boot != 0X80) ||
+ getLe32(pt->relativeSectors) > csd.capacity()) {
+ valid = false;
+ }
+ cout << int(ip) << ',' << uppercase << showbase << hex;
+ cout << int(pt->boot) << ',';
+ for (int i = 0; i < 3; i++) {
+ cout << int(pt->beginCHS[i]) << ',';
+ }
+ cout << int(pt->type) << ',';
+ for (int i = 0; i < 3; i++) {
+ cout << int(pt->endCHS[i]) << ',';
+ }
+ cout << dec << getLe32(pt->relativeSectors) << ',';
+ cout << getLe32(pt->totalSectors) << endl;
+ }
+ if (!valid) {
+ cout << F("\nMBR not valid, assuming Super Floppy format.\n");
+ }
+ return true;
+}
+//------------------------------------------------------------------------------
+void dmpVol() {
+ cout << F("\nScanning FAT, please wait.\n");
+ int32_t freeClusterCount = sd.freeClusterCount();
+ if (sd.fatType() <= 32) {
+ cout << F("\nVolume is FAT") << int(sd.fatType()) << endl;
+ } else {
+ cout << F("\nVolume is exFAT\n");
+ }
+ cout << F("sectorsPerCluster: ") << sd.sectorsPerCluster() << endl;
+ cout << F("fatStartSector: ") << sd.fatStartSector() << endl;
+ cout << F("dataStartSector: ") << sd.dataStartSector() << endl;
+ cout << F("clusterCount: ") << sd.clusterCount() << endl;
+ cout << F("freeClusterCount: ");
+ if (freeClusterCount >= 0) {
+ cout << freeClusterCount << endl;
+ } else {
+ cout << F("failed\n");
+ errorPrint();
+ }
+}
+//------------------------------------------------------------------------------
+void printCardType() {
+ cout << F("\nCard type: ");
+
+ switch (sd.card()->type()) {
+ case SD_CARD_TYPE_SD1:
+ cout << F("SD1\n");
+ break;
+
+ case SD_CARD_TYPE_SD2:
+ cout << F("SD2\n");
+ break;
+
+ case SD_CARD_TYPE_SDHC:
+ if (csd.capacity() < 70000000) {
+ cout << F("SDHC\n");
+ } else {
+ cout << F("SDXC\n");
+ }
+ break;
+
+ default:
+ cout << F("Unknown\n");
+ }
+}
+//------------------------------------------------------------------------------
+void printConfig(SdSpiConfig config) {
+ if (DISABLE_CS_PIN < 0) {
+ cout << F(
+ "\nAssuming the SD is the only SPI device.\n"
+ "Edit DISABLE_CS_PIN to disable an SPI device.\n");
+ } else {
+ cout << F("\nDisabling SPI device on pin ");
+ cout << int(DISABLE_CS_PIN) << endl;
+ pinMode(DISABLE_CS_PIN, OUTPUT);
+ digitalWrite(DISABLE_CS_PIN, HIGH);
+ }
+ cout << F("\nAssuming the SD chip select pin is: ") << int(config.csPin);
+ cout << F("\nEdit SD_CS_PIN to change the SD chip select pin.\n");
+}
+//------------------------------------------------------------------------------
+void printConfig(SdioConfig config) {
+ (void)config;
+ cout << F("Assuming an SDIO interface.\n");
+}
+//-----------------------------------------------------------------------------
+void setup() {
+ Serial.begin(115200);
+ delay(250);
+ Serial.println("SPI test");
+
+ SPI.begin(pin_spiSCK, pin_spiPOCI, pin_spiPICO);
+
+ cout << F("SdFat version: ") << SD_FAT_VERSION_STR << endl;
+ printConfig(SD_CONFIG);
+}
+//------------------------------------------------------------------------------
+void loop() {
+ // Read any existing Serial data.
+ clearSerialInput();
+
+ // F stores strings in flash to save RAM
+ cout << F("\ntype any character to start\n");
+ while (!Serial.available()) {
+ yield();
+ }
+ uint32_t t = millis();
+ if (!sd.cardBegin(SD_CONFIG)) {
+ cout << F(
+ "\nSD initialization failed.\n"
+ "Do not reformat the card!\n"
+ "Is the card correctly inserted?\n"
+ "Is there a wiring/soldering problem?\n");
+ if (isSpi(SD_CONFIG)) {
+ cout << F(
+ "Is SD_CS_PIN set to the correct value?\n"
+ "Does another SPI device need to be disabled?\n");
+ }
+ errorPrint();
+ return;
+ }
+ t = millis() - t;
+ cout << F("init time: ") << dec << t << " ms" << endl;
+
+ if (!sd.card()->readCID(&cid) || !sd.card()->readCSD(&csd) ||
+ !sd.card()->readOCR(&ocr) || !sd.card()->readSCR(&scr)) {
+ cout << F("readInfo failed\n");
+ errorPrint();
+ return;
+ }
+ printCardType();
+ cout << F("sdSpecVer: ") << 0.01 * scr.sdSpecVer() << endl;
+ cout << F("HighSpeedMode: ");
+ if (scr.sdSpecVer() > 101 && sd.card()->cardCMD6(0X00FFFFFF, cmd6Data) &&
+ (2 & cmd6Data[13])) {
+ cout << F("true\n");
+ } else {
+ cout << F("false\n");
+ }
+ cidDmp();
+ csdDmp();
+ cout << F("\nOCR: ") << uppercase << showbase;
+ cout << hex << ocr << dec << endl;
+ if (!mbrDmp()) {
+ return;
+ }
+ if (!sd.volumeBegin()) {
+ cout << F("\nvolumeBegin failed. Is the card formatted?\n");
+ errorPrint();
+ return;
+ }
+ dmpVol();
+}
+
You will also need to install the SDFat Arduino Library if you haven't already. You can search the library from within the Arduino Library manager, download the zip from the GitHub Repository and install it manually, or you can click the link from within the code.
+Make sure you've selected the correct board and port in the Tools menu and then hit the upload button. Once the code has finished uploading, go ahead and open a Serial Monitor at 115200 baud. Once you type in any key in the Message Field and send it, the code will analyze the SD card and output something similar to the following:
+ + + + + + + + + + + + + + + + + + + + + + + + + + +0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function K(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function B(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o Spot an improvement opportunity? Feel free to contribute to our open-source design and documentation. All of this documentation can be modified by you! Please help us make it better. All of our designs are open-source! Please help us make it better. If approved, we will flag these changes for our next board revision. Congrats! 🍻 Info Even if your suggestion is accepted, these changes may not be immediately available for purchase. We may have to cycle through our current product inventory first. Let's provide some recognition to the contributors for this project! Spot something wrong? Please let us know. Need Help? If you need technical assistance or more information on a product that is not working as you expected, we recommend heading on over to the SparkFun Technical Assistance page for some initial troubleshooting. This Submit Issues page is not where users should seek assistance. If you can't find what you need there, the SparkFun Forums is a great place to search the product forums and ask questions. Account Registration Required For your first visit to our forum, you'll need to create a Forum Account to post questions. All of our documentation can be modified by you! Please help us make it better. If a section of the documentation is incorrect, please open an issue and let us know. All of our designs are open-source! Please help us make it better. If part of the design is confusing, please open an issue and let us know. If part of the board's functionality is missing, please open an issue and file a feature request. Design Considerations Please keep in mind that we may intentionally exclude certain functions of the board to meet our product design requirements. If approved, we will flag these changes for our next board revision. Congrats! 🍻 Info Even if your suggestion is accepted, these changes may not be immediately available for purchase. We may have to cycle through our current product inventory first. Need to download or print our hookup guide? The Portability Shield has been designed to be usable with any compatible main board. Here we have soldered in headers and it is plugged into the RTK Postcard. Note that there is an antenna attached to the module, as well as a LiPo battery plugged into the JST port. The 1.3" OLED is a small, monochrome, blue on black display with a 128 x 64 dot matrix panel and a 7-bit unshifted I2C address of 0x3D. To change the I2C address to 0x3C, cut the D/C jumper on the back of the board. For more information, refer to the datasheet. The Navigation Switch allows for navigation of the configuration modes and menus related to the RTK or other loaded software. The TCA9554 GPIO Expander is used for I2C interfacing with the Navigation Switch, 1.3" OLED display, the fuel gauge, and the SD Card Detect. Its 7-bit unshifted address is 0x20. Power is provided by either the LiPo Battery or the 5V/GND pins. Maximum input to the board is 5V. There are two plated through holes available on the bottom of the board to measure current if desired. How handy! There is an On/Off switch at the top of the board. The MAX17048 uses the Li+ battery-modeling algorithm ModelGauge™ to track the battery relative state-of-charge (SOC) continuously over widely varying charge and discharge conditions. This eliminates current-sense resistor and battery learn cycles required in traditional fuel gauges and allows for the most accurate battery percentage readings. Its 7-bit unshifted address is 0x36. For more information, you can refer to the datasheet. The charge circuit charges Li+ batteries at 500mA. The equation below shows our calculation for this rate. The microSD Socket Friction Fit slot allows for data logging or easy upload of programming files. Warning Do NOT drive the microSD card pins high if the card is not powered. Damage could occur! The offset PTHs allow for a snug fit when soldering headers to the board. Once male headers are soldered in, the SparkFun Portability Shield can be fit to the main board of choice. If 5V is present, LiPo charging commences. Below 5V, the battery will provide VBATT to the mainboard 3.3V is not provided to mainboard - 5V/VBATT powers local 3.3V_P. CHG:
+ Cutting this jumper will disconnect the power to the CHG LED on the front of the board. PWR:
+ Cutting this jumper will disconnect the power to the PWR LED on the front of the board. D/C:
+ Cutting this jumper will change the I2C address from 0x3D to 0x3C. The board dimensions are illustrated in the drawing below; the listed measurements are in millimeters.
+ SparkFun Portability Shield The SparkFun Portability Shield adds all the user interface bits needed to take a SparkFun dev board into the field. A LiPo battery connector, charger, fuel gauge, and an on/off switch take care of your power needs. A friction-fit microSD connector allow for datalogging. The 1.3" OLED and a 5-way navigation switch allow for an excellent user interface. Locking 0.1" headers along the edge of the shield make it easier to solder male pins in place. I2C is used to interface to the display, fuel gauge, and the 5 way navigation switch (GPIO expander PCA9554), SPI is used to communicate with the microSD card. The power switch uses an ideal diode (LM66200) to disconnect the battery from the system for a sleep current of approximately 4μA. To follow along with this tutorial, you will need the following materials. You may not need everything, depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary. Below are a few tutorials that may help users familiarize themselves with various aspects of the board. For more resources related to the SparkFun Portability Shield, check out the links listed here: This is just a placeholder file for the webpage re-direct. All the content for this section is actually in the This example demonstrates how to use the navigation switch and detect if the SD card is inserted. The !INT pin of the GPIO expander IC (PCA9554) triggers an interrupt any time a button is pressed or an SD card is inserted/removed. The code for this example can be found in the Firmware folder of this repository. Alternatively, you can expand the link below and copy and paste the code into a shiny new Arduino sketch: One thing to note is that you will also need to install the SparkFun I2C Expander Arduino Library if you haven't already. You can search the library from within the Arduino Library manager, download the zip from the GitHub Repository and install it manually, or you can click the link from within the code. Clicking the link will show something like the following: SparkFun I2C Expander Arduino Library Install Make sure you've selected the correct board (in this case, you will need to use ESP32 Dev Module from espressif) and port in the Tools menu and then hit the upload button. Once the code has finished uploading, go ahead and open a Serial Monitor. You should see something similar to the following. Example 1 Output This file demonstrates the simple API of the SparkFun MAX17043 Arduino library. Make sure you have a LiPo battery plugged into the JST port. The code for this example can be found in the Firmware folder of this repository. Alternatively, you can expand the link below and copy and paste the code into a shiny new Arduino sketch: You will also need to install the SparkFun MAX1704x Fuel Gauge Arduino Library if you haven't already. You can search the library from within the Arduino Library manager, download the zip from the GitHub Repository and install it manually, or you can click the link from within the code. Clicking the link will show something like the following: SparkFun MAX1704x Fuel Gauge Arduino Library Install Make sure you've selected the correct board and port in the Tools menu and then hit the upload button. Once the code has finished uploading, go ahead and open a Serial Monitor at 115200 baud. You should see the gauge's voltage and state-of-charge (SOC) readings, similar to the following: Example 2 Output This example demonstrates how to display on the 1.3\" OLED and read the fuel gauge. You should have the Portability Shield connected to the RTK Postcard or other controller and a LiPo battery plugged into the JST port. The code for this example can be found in the Firmware folder of this repository. Alternatively, you can expand the link below and copy and paste the code into a shiny new Arduino sketch: You will also need both the SparkFun Qwiic OLED Arduino Library as well as the SparkFun MAX1704x Fuel Gauge Arduino Library. If you haven't already installed these, you can search them from within the Arduino Library manager and install them from there. Alternatively, you can download the zips from their respective GitHub Repositories here(Fuel Gauge) and here(Qwiic OLED), and install them manually. Make sure you've selected the correct board and port in the Tools menu and then hit the upload button. Once the code has finished uploading, you should see the gauge's voltage and state-of-charge (SOC) readings, similar to the the output for Example 2. The 1.3\" OLED display should show a bouncing box like so: Example 3 This example will mount an SD card, analyze the type of card, and output the analysis via the Serial Monitor. Go ahead and connect the Portability Shield to the RTK Postcard or other controller board. Insert a microSD card into the socket. Cards up to 512GB should work. The code for this example can be found in the Firmware folder of this repository. Alternatively, you can expand the link below and copy and paste the code into a shiny new Arduino sketch: You will also need to install the SDFat Arduino Library if you haven't already. You can search the library from within the Arduino Library manager, download the zip from the GitHub Repository and install it manually, or you can click the link from within the code. Make sure you've selected the correct board and port in the Tools menu and then hit the upload button. Once the code has finished uploading, go ahead and open a Serial Monitor at 115200 baud. Once you type in any key in the Message Field and send it, the code will analyze the SD card and output something similar to the following: Example 4 Output Need to download or print our hookup guide? The Portability Shield has been designed to be usable with any compatible main board. Here we have soldered in headers and it is plugged into the RTK Postcard. Note that there is an antenna attached to the module, as well as a LiPo battery plugged into the JST port. SparkFun Portability Shield and RTK Postcard The 1.3\" OLED is a small, monochrome, blue on black display with a 128 x 64 dot matrix panel and a 7-bit unshifted I2C address of 0x3D. To change the I2C address to 0x3C, cut the D/C jumper on the back of the board. For more information, refer to the datasheet. 1.3\" OLED Screen The Navigation Switch allows for navigation of the configuration modes and menus related to the RTK or other loaded software. Navigation Switch The TCA9554 GPIO Expander is used for I2C interfacing with the Navigation Switch, 1.3\" OLED display, the fuel gauge, and the SD Card Detect. Its 7-bit unshifted address is 0x20. GPIO Expander Power is provided by either the LiPo Battery or the 5V/GND pins. Maximum input to the board is 5V. Battery Connector/Power Pins There are two plated through holes available on the bottom of the board to measure current if desired. Current Measurement PTHs How handy! There is an On/Off switch at the top of the board. On/Off Switch The MAX17048 uses the Li+ battery-modeling algorithm ModelGauge\u2122 to track the battery relative state-of-charge (SOC) continuously over widely varying charge and discharge conditions. This eliminates current-sense resistor and battery learn cycles required in traditional fuel gauges and allows for the most accurate battery percentage readings. Its 7-bit unshifted address is 0x36. For more information, you can refer to the datasheet. Fuel Gauge The charge circuit charges Li+ batteries at 500mA. The equation below shows our calculation for this rate. Charge Circuit The microSD Socket Friction Fit slot allows for data logging or easy upload of programming files. Warning Do NOT drive the microSD card pins high if the card is not powered. Damage could occur! microSD Card Slot The offset PTHs allow for a snug fit when soldering headers to the board. Once male headers are soldered in, the SparkFun Portability Shield can be fit to the main board of choice. If 5V is present, LiPo charging commences. Below 5V, the battery will provide VBATT to the mainboard 3.3V is not provided to mainboard - 5V/VBATT powers local 3.3V_P. Shield Connectors CHG: Cutting this jumper will disconnect the power to the CHG LED on the front of the board. PWR: Cutting this jumper will disconnect the power to the PWR LED on the front of the board. D/C: Cutting this jumper will change the I2C address from 0x3D to 0x3C. Jumpers The board dimensions are illustrated in the drawing below; the listed measurements are in millimeters. SparkFun Portability Shield Board Dimensions SparkFun Portability Shield SKU: DEV-27510 The SparkFun Portability Shield adds all the user interface bits needed to take a SparkFun dev board into the field. A LiPo battery connector, charger, fuel gauge, and an on/off switch take care of your power needs. A friction-fit microSD connector allow for datalogging. The 1.3\" OLED and a 5-way navigation switch allow for an excellent user interface. Locking 0.1\" headers along the edge of the shield make it easier to solder male pins in place. I2C is used to interface to the display, fuel gauge, and the 5 way navigation switch (GPIO expander PCA9554), SPI is used to communicate with the microSD card. The power switch uses an ideal diode (LM66200) to disconnect the battery from the system for a sleep current of approximately 4\u03bcA. Purchase from SparkFun To follow along with this tutorial, you will need the following materials. You may not need everything, depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary. Below are a few tutorials that may help users familiarize themselves with various aspects of the board. For more resources related to the SparkFun Portability Shield, check out the links listed here: SparkFun Portability Shield SKU: DEV-27510 The SparkFun Portability Shield adds all the user interface bits needed to take a SparkFun dev board into the field. A LiPo battery connector, charger, fuel gauge, and an on/off switch take care of your power needs. A friction-fit microSD connector allow for datalogging. The 1.3\" OLED and a 5-way navigation switch allow for an excellent user interface. Locking 0.1\" headers along the edge of the shield make it easier to solder male pins in place. I2C is used to interface to the display, fuel gauge, and the 5 way navigation switch (GPIO expander PCA9554), SPI is used to communicate with the microSD card. The power switch uses an ideal diode (LM66200) to disconnect the battery from the system for a sleep current of approximately 4\u03bcA. Purchase from SparkFun To follow along with this tutorial, you will need the following materials. You may not need everything, depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary. Below are a few tutorials that may help users familiarize themselves with various aspects of the board. The 1.3\" OLED is a small, monochrome, blue on black display with a 128 x 64 dot matrix panel and a 7-bit unshifted I2C address of 0x3D. To change the I2C address to 0x3C, cut the D/C jumper on the back of the board. For more information, refer to the datasheet. 1.3\" OLED Screen The Navigation Switch allows for navigation of the configuration modes and menus related to the RTK or other loaded software. Navigation Switch The TCA9554 GPIO Expander is used for I2C interfacing with the Navigation Switch, 1.3\" OLED display, the fuel gauge, and the SD Card Detect. Its 7-bit unshifted address is 0x20. GPIO Expander Power is provided by either the LiPo Battery or the 5V/GND pins. Maximum input to the board is 5V. Battery Connector/Power Pins There are two plated through holes available on the bottom of the board to measure current if desired. Current Measurement PTHs How handy! There is an On/Off switch at the top of the board. On/Off Switch The MAX17048 uses the Li+ battery-modeling algorithm ModelGauge\u2122 to track the battery relative state-of-charge (SOC) continuously over widely varying charge and discharge conditions. This eliminates current-sense resistor and battery learn cycles required in traditional fuel gauges and allows for the most accurate battery percentage readings. Its 7-bit unshifted address is 0x36. For more information, you can refer to the datasheet. Fuel Gauge The charge circuit charges Li+ batteries at 500mA. The equation below shows our calculation for this rate. Charge Circuit The microSD Socket Friction Fit slot allows for data logging or easy upload of programming files. Warning Do NOT drive the microSD card pins high if the card is not powered. Damage could occur! microSD Card Slot The offset PTHs allow for a snug fit when soldering headers to the board. Once male headers are soldered in, the SparkFun Portability Shield can be fit to the main board of choice. If 5V is present, LiPo charging commences. Below 5V, the battery will provide VBATT to the mainboard 3.3V is not provided to mainboard - 5V/VBATT powers local 3.3V_P. Shield Connectors CHG: Cutting this jumper will disconnect the power to the CHG LED on the front of the board. PWR: Cutting this jumper will disconnect the power to the PWR LED on the front of the board. D/C: Cutting this jumper will change the I2C address from 0x3D to 0x3C. Jumpers The board dimensions are illustrated in the drawing below; the listed measurements are in millimeters. SparkFun Portability Shield Board Dimensions The Portability Shield has been designed to be usable with any compatible main board. Here we have soldered in headers and it is plugged into the RTK Postcard. Note that there is an antenna attached to the module, as well as a LiPo battery plugged into the JST port. SparkFun Portability Shield and RTK Postcard Note Not working as expected and need help? If you need technical assistance and more information on a product that is not working as you expected, we recommend heading on over to the SparkFun Technical Assistance page for some initial troubleshooting. SparkFun Technical Assistance Page If you don't find what you need there, the SparkFun Forums are a great place to find and ask for help. If this is your first visit, you'll need to create a Forum Account to search product forums and post questions. Create New Forum Account Log Into SparkFun Forums For more resources related to the SparkFun Portability Shield, check out the links listed here: Note Not working as expected and need help? If you need technical assistance and more information on a product that is not working as you expected, we recommend heading on over to the SparkFun Technical Assistance page for some initial troubleshooting. SparkFun Technical Assistance Page If you don't find what you need there, the SparkFun Forums are a great place to find and ask for help. If this is your first visit, you'll need to create a Forum Account to search product forums and post questions. Create New Forum Account Log Into SparkFun Forums Spot an improvement opportunity? Feel free to contribute to our open-source design and documentation. All of this documentation can be modified by you! Please help us make it better. All of our designs are open-source! Please help us make it better. If approved, we will flag these changes for our next board revision. Congrats! \ud83c\udf7b Info Even if your suggestion is accepted, these changes may not be immediately available for purchase. We may have to cycle through our current product inventory first. Let's provide some recognition to the contributors for this project! Spot something wrong? Please let us know. Need Help? If you need technical assistance or more information on a product that is not working as you expected, we recommend heading on over to the SparkFun Technical Assistance page for some initial troubleshooting. This Submit Issues page is not where users should seek assistance. SparkFun Technical Assistance Page If you can't find what you need there, the SparkFun Forums is a great place to search the product forums and ask questions. Account Registration Required For your first visit to our forum, you'll need to create a Forum Account to post questions. All of our documentation can be modified by you! Please help us make it better. If a section of the documentation is incorrect, please open an issue and let us know. All of our designs are open-source! Please help us make it better. If part of the design is confusing, please open an issue and let us know. If part of the board's functionality is missing, please open an issue and file a feature request. Design Considerations Please keep in mind that we may intentionally exclude certain functions of the board to meet our product design requirements. If approved, we will flag these changes for our next board revision. Congrats! \ud83c\udf7b Info Even if your suggestion is accepted, these changes may not be immediately available for purchase. We may have to cycle through our current product inventory first.
+ SparkFun Portability Shield The SparkFun Portability Shield adds all the user interface bits needed to take a SparkFun dev board into the field. A LiPo battery connector, charger, fuel gauge, and an on/off switch take care of your power needs. A friction-fit microSD connector allow for datalogging. The 1.3" OLED and a 5-way navigation switch allow for an excellent user interface. Locking 0.1" headers along the edge of the shield make it easier to solder male pins in place. I2C is used to interface to the display, fuel gauge, and the 5 way navigation switch (GPIO expander PCA9554), SPI is used to communicate with the microSD card. The power switch uses an ideal diode (LM66200) to disconnect the battery from the system for a sleep current of approximately 4μA. To follow along with this tutorial, you will need the following materials. You may not need everything, depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary. Below are a few tutorials that may help users familiarize themselves with various aspects of the board. The 1.3" OLED is a small, monochrome, blue on black display with a 128 x 64 dot matrix panel and a 7-bit unshifted I2C address of 0x3D. To change the I2C address to 0x3C, cut the D/C jumper on the back of the board. For more information, refer to the datasheet. The Navigation Switch allows for navigation of the configuration modes and menus related to the RTK or other loaded software. The TCA9554 GPIO Expander is used for I2C interfacing with the Navigation Switch, 1.3" OLED display, the fuel gauge, and the SD Card Detect. Its 7-bit unshifted address is 0x20. Power is provided by either the LiPo Battery or the 5V/GND pins. Maximum input to the board is 5V. There are two plated through holes available on the bottom of the board to measure current if desired. How handy! There is an On/Off switch at the top of the board. The MAX17048 uses the Li+ battery-modeling algorithm ModelGauge™ to track the battery relative state-of-charge (SOC) continuously over widely varying charge and discharge conditions. This eliminates current-sense resistor and battery learn cycles required in traditional fuel gauges and allows for the most accurate battery percentage readings. Its 7-bit unshifted address is 0x36. For more information, you can refer to the datasheet. The charge circuit charges Li+ batteries at 500mA. The equation below shows our calculation for this rate. The microSD Socket Friction Fit slot allows for data logging or easy upload of programming files. Warning Do NOT drive the microSD card pins high if the card is not powered. Damage could occur! The offset PTHs allow for a snug fit when soldering headers to the board. Once male headers are soldered in, the SparkFun Portability Shield can be fit to the main board of choice. If 5V is present, LiPo charging commences. Below 5V, the battery will provide VBATT to the mainboard 3.3V is not provided to mainboard - 5V/VBATT powers local 3.3V_P. CHG:
+ Cutting this jumper will disconnect the power to the CHG LED on the front of the board. PWR:
+ Cutting this jumper will disconnect the power to the PWR LED on the front of the board. D/C:
+ Cutting this jumper will change the I2C address from 0x3D to 0x3C. The board dimensions are illustrated in the drawing below; the listed measurements are in millimeters. The Portability Shield has been designed to be usable with any compatible main board. Here we have soldered in headers and it is plugged into the RTK Postcard. Note that there is an antenna attached to the module, as well as a LiPo battery plugged into the JST port. Note
+ Not working as expected and need help? If you need technical assistance and more information on a product that is not working as you expected, we recommend heading on over to the SparkFun Technical Assistance page for some initial troubleshooting. If you don't find what you need there, the SparkFun Forums are a great place to find and ask for help. If this is your first visit, you'll need to create a Forum Account to search product forums and post questions. For more resources related to the SparkFun Portability Shield, check out the links listed here: Note
+ Not working as expected and need help? If you need technical assistance and more information on a product that is not working as you expected, we recommend heading on over to the SparkFun Technical Assistance page for some initial troubleshooting. If you don't find what you need there, the SparkFun Forums are a great place to find and ask for help. If this is your first visit, you'll need to create a Forum Account to search product forums and post questions.=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}});
\ No newline at end of file
diff --git a/assets/javascripts/lunr/min/lunr.he.min.js b/assets/javascripts/lunr/min/lunr.he.min.js
new file mode 100644
index 0000000..b863d3e
--- /dev/null
+++ b/assets/javascripts/lunr/min/lunr.he.min.js
@@ -0,0 +1 @@
+!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.he=function(){this.pipeline.reset(),this.pipeline.add(e.he.trimmer,e.he.stopWordFilter,e.he.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.he.stemmer))},e.he.wordCharacters="֑-״א-תa-zA-Za-zA-Z0-90-9",e.he.trimmer=e.trimmerSupport.generateTrimmer(e.he.wordCharacters),e.Pipeline.registerFunction(e.he.trimmer,"trimmer-he"),e.he.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ה ו י ת",pre2:"ב כ ל מ ש כש",pre3:"הב הכ הל המ הש בש לכ",pre4:"וב וכ ול ומ וש",pre5:"מה שה כל",pre6:"מב מכ מל ממ מש",pre7:"בה בו בי בת כה כו כי כת לה לו לי לת",pre8:"ובה ובו ובי ובת וכה וכו וכי וכת ולה ולו ולי ולת"},e.suf={suf1:"ך כ ם ן נ",suf2:"ים ות וך וכ ום ון ונ הם הן יכ יך ינ ים",suf3:"תי תך תכ תם תן תנ",suf4:"ותי ותך ותכ ותם ותן ותנ",suf5:"נו כם כן הם הן",suf6:"ונו וכם וכן והם והן",suf7:"תכם תכן תנו תהם תהן",suf8:"הוא היא הם הן אני אתה את אנו אתם אתן",suf9:"ני נו כי כו כם כן תי תך תכ תם תן",suf10:"י ך כ ם ן נ ת"},e.patterns=JSON.parse('{"hebrewPatterns": [{"pt1": [{"c": "ה", "l": 0}]}, {"pt2": [{"c": "ו", "l": 0}]}, {"pt3": [{"c": "י", "l": 0}]}, {"pt4": [{"c": "ת", "l": 0}]}, {"pt5": [{"c": "מ", "l": 0}]}, {"pt6": [{"c": "ל", "l": 0}]}, {"pt7": [{"c": "ב", "l": 0}]}, {"pt8": [{"c": "כ", "l": 0}]}, {"pt9": [{"c": "ש", "l": 0}]}, {"pt10": [{"c": "כש", "l": 0}]}, {"pt11": [{"c": "בה", "l": 0}]}, {"pt12": [{"c": "וב", "l": 0}]}, {"pt13": [{"c": "וכ", "l": 0}]}, {"pt14": [{"c": "ול", "l": 0}]}, {"pt15": [{"c": "ומ", "l": 0}]}, {"pt16": [{"c": "וש", "l": 0}]}, {"pt17": [{"c": "הב", "l": 0}]}, {"pt18": [{"c": "הכ", "l": 0}]}, {"pt19": [{"c": "הל", "l": 0}]}, {"pt20": [{"c": "המ", "l": 0}]}, {"pt21": [{"c": "הש", "l": 0}]}, {"pt22": [{"c": "מה", "l": 0}]}, {"pt23": [{"c": "שה", "l": 0}]}, {"pt24": [{"c": "כל", "l": 0}]}]}'),e.execArray=["cleanWord","removeDiacritics","removeStopWords","normalizeHebrewCharacters"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r
=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}});
\ No newline at end of file
diff --git a/assets/javascripts/lunr/min/lunr.pt.min.js b/assets/javascripts/lunr/min/lunr.pt.min.js
new file mode 100644
index 0000000..6c16996
--- /dev/null
+++ b/assets/javascripts/lunr/min/lunr.pt.min.js
@@ -0,0 +1,18 @@
+/*!
+ * Lunr languages, `Portuguese` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}});
\ No newline at end of file
diff --git a/assets/javascripts/lunr/min/lunr.ro.min.js b/assets/javascripts/lunr/min/lunr.ro.min.js
new file mode 100644
index 0000000..7277140
--- /dev/null
+++ b/assets/javascripts/lunr/min/lunr.ro.min.js
@@ -0,0 +1,18 @@
+/*!
+ * Lunr languages, `Romanian` language
+ * https://github.com/MihaiValentin/lunr-languages
+ *
+ * Copyright 2014, Mihai Valentin
+ * http://www.mozilla.org/MPL/
+ */
+/*!
+ * based on
+ * Snowball JavaScript Library v0.3
+ * http://code.google.com/p/urim/
+ * http://snowball.tartarus.org/
+ *
+ * Copyright 2010, Oleg Mazko
+ * http://www.mozilla.org/MPL/
+ */
+
+!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contribute: Make an Augmentation!
+ Improve our Documentation
+
+
+
+docs
folder of the SparkFun Portability Shield repository.Submit a Correction
+
+
+words worlds world a better place.
+
+ Improve our Hardware Design
+
+
+
+Hardware
folder of the SparkFun Portability Shield repository.Submit a Design Enhancement
+
+
+words worlds world a better place.
+
+Contributors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Did we make a mistake?
+Discrepancies in the Documentation
+
+
+docs
folder of the SparkFun Portability Shield repository.🔍 Spot something wrong?
+Do you have a suggested correction?
+
+
+words worlds world a better place.
+
+Problems in the Hardware Design
+
+
+Hardware
folder of the SparkFun Portability Shield repository.Does something not make sense? 🤔
+Did we forget to include an important function of the board? 🤦
+
+
+Do you wish to contribute directly to improving the board design?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ words worlds world a better place.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hard copy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+*.pdf
file, select the Printer or Destination labeled Save as PDF. (Instructions will vary based on the browser)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hardware Assembly
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hardware Overview
+
+OLED
+Navigation Switch
+GPIO Expander
+Power
+Current Measurement
+On/Off Switch
+Fuel Gauge
+LiPo Charging Circuit
+MicroSD Card
+Shield Connectors
+Jumpers
+
+
+
+
+
+
+ D/C
+
+ I2C Addr
+
+
+
+ 0
+
+ 0x3C
+
+
+
+ 1
+
+ 0x3D (default)
+
+
+
+
+Board Dimensions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Introduction
+
+
+
+
+ SKU: DEV-27510
+
+Required Materials
+
+
+
+
+
+
+
+
+ SparkFun Portability Shield
+
+ DEV-27510
+
+
+
+ SparkFun RTK Postcard
+
+ GPS-26916
+ Suggested Reading
+=m[t]&&t
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Resources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ introduction.md
file./*\n Read the 5-way switch and card detect on the Portability Shield\n By: Nathan Seidle\n SparkFun Electronics\n Date: November 24th, 2024\n License: This code is public domain but you buy me a drink if you use this\n and we meet someday (Drink license).\n Feel like supporting our work? Buy a board from SparkFun!\n https://www.sparkfun.com/products/27510\n\n This example demonstrates how to read the 5-way nav switch and detect if the SD card is inserted.\n The !INT pin of the GPIO expander IC (PCA9554) triggers an interrupt any time a button is pressed or\n an SD card is inserted/removed.\n\n Hardware Connections:\n Connect the Portability shield to the RTK Postcard or other controller board\n Open output window at 115200bps\n Press button on navigation switch\n*/\n\n#include <SparkFun_I2C_Expander_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_I2C_Expander_Arduino_Library\n\nSFE_PCA95XX io(PCA95XX_PCA9554); // Create an instance with the PCA9554 IC\n\nint gpioExpander_up = 0;\nint gpioExpander_down = 1;\nint gpioExpander_right = 2;\nint gpioExpander_left = 3;\nint gpioExpander_center = 4;\nint gpioExpander_cardDetect = 5;\n\nint gpioExpander_interrupt = 14; //INT of PCA9554 is connected to ESP14. Goes low when button is pressed.\n\nbool buttonPressed = false;\n\nvoid IRAM_ATTR gpioExpanderISR()\n{\n buttonPressed = true;\n}\n\nvoid setup()\n{\n Serial.begin(115200);\n delay(250);\n Serial.println(\"Portability Shield Example\");\n\n Wire.begin(7, 20); //SDA, SCL. I2C0 on Portability Shield\n\n // Initialize the PCA95xx with its default I2C address\n if (io.begin() == false)\n {\n Serial.println(\"PCA9554 not detected. Please check wiring. Freezing...\");\n while (1)\n ;\n }\n Serial.println(\"Portability Shield online!\");\n\n pinMode(gpioExpander_interrupt, INPUT_PULLUP);\n\n io.pinMode(gpioExpander_up, INPUT);\n io.pinMode(gpioExpander_down, INPUT);\n io.pinMode(gpioExpander_left, INPUT);\n io.pinMode(gpioExpander_right, INPUT);\n io.pinMode(gpioExpander_center, INPUT);\n io.pinMode(gpioExpander_cardDetect, INPUT);\n\n uint8_t currentState = io.getInputRegister() & 0b00111111; //Ignore unconnected GPIO6/7\n if (currentState & 0b00100000)\n Serial.println(\"SD Card detected\");\n else\n Serial.println(\"No card detected\");\n\n //Setup interrupt service routine (ISR)\n attachInterrupt(gpioExpander_interrupt, gpioExpanderISR, CHANGE);\n}\n\nvoid loop()\n{\n if (buttonPressed == true)\n {\n //Get all the pins in one read\n uint8_t currentState = io.getInputRegister() & 0b00111111; //Ignore unconnected GPIO6/7\n\n // Pins are pulled high so when we see low, button is being pressed\n if ((currentState & (1 << gpioExpander_up)) == 0)\n Serial.print(\"Up\");\n if ((currentState & (1 << gpioExpander_down)) == 0)\n Serial.print(\"Down\");\n if ((currentState & (1 << gpioExpander_left)) == 0)\n Serial.print(\"Left\");\n if ((currentState & (1 << gpioExpander_right)) == 0)\n Serial.print(\"Right\");\n if ((currentState & (1 << gpioExpander_center)) == 0)\n Serial.print(\"Center\");\n\n Serial.println();\n\n buttonPressed = false;\n }\n\n delay(100);\n}\n
/*\n Example1_Simple\n By: Paul Clark\n Date: October 23rd 2020\n\n Based extensively on:\n MAX17043_Simple_Serial.cpp\n SparkFun MAX17043 Example Code\n Jim Lindblom @ SparkFun Electronics\n Original Creation Date: June 22, 2015\n\n This file demonstrates the simple API of the SparkFun MAX17043 Arduino library.\n\n This example will print the gauge's voltage and state-of-charge (SOC) readings\n to Serial (115200 baud)\n\n This code is released under the MIT license.\n\n Distributed as-is; no warranty is given.\n*/\n\n#include <Wire.h> // Needed for I2C\n\n#include <SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library\n\nSFE_MAX1704X lipo(MAX1704X_MAX17048); // Create a MAX17048\n\ndouble voltage = 0; // Variable to keep track of LiPo voltage\ndouble soc = 0; // Variable to keep track of LiPo state-of-charge (SOC)\nbool alert; // Variable to keep track of whether alert has been triggered\n\nvoid setup()\n{\n Serial.begin(115200); // Start serial, to output debug data\n while (!Serial)\n ; //Wait for user to open terminal\n Serial.println(F(\"MAX17043 Example\"));\n\n Wire.begin(7, 20); //SDA, SCL\n\n // Set up the fuel gauge:\n if (lipo.begin() == false)\n {\n Serial.println(F(\"MAX17043 not detected. Please check wiring. Freezing.\"));\n while (1)\n ;\n }\n\n // Quick start restarts the MAX17043 in hopes of getting a more accurate\n // guess for the SOC.\n lipo.quickStart();\n\n // We can set an interrupt to alert when the battery SoC gets too low.\n // We can alert at anywhere between 1% - 32%:\n lipo.setThreshold(20); // Set alert threshold to 20%.\n}\n\nvoid loop()\n{\n // lipo.getVoltage() returns a voltage value (e.g. 3.93)\n voltage = lipo.getVoltage();\n // lipo.getSOC() returns the estimated state of charge (e.g. 79%)\n soc = lipo.getSOC();\n // lipo.getAlert() returns a 0 or 1 (0=alert not triggered)\n alert = lipo.getAlert();\n\n // Print the variables:\n Serial.print(\"Voltage: \");\n Serial.print(voltage); // Print the battery voltage\n Serial.println(\" V\");\n\n Serial.print(\"Percentage: \");\n Serial.print(soc); // Print the battery state of charge\n Serial.println(\" %\");\n\n Serial.print(\"Alert: \");\n Serial.println(alert);\n Serial.println();\n\n delay(500);\n}\n
/*\n Display a cube on the OLED at 400kHz. Query the fuel guage periodically.\n By: Nathan Seidle\n SparkFun Electronics\n Date: November 24th, 2024\n License: This code is public domain but you buy me a drink if you use this\n and we meet someday (Drink license).\n Feel like supporting our work? Buy a board from SparkFun!\n https://www.sparkfun.com/products/27510\n\n This example demonstrates how to display on the 1.3\" OLED and read the fuel gauge.\n\n Hardware Connections:\n Connect the Portability shield to the RTK Postcard or other controller board\n Open output window at 115200bps\n*/\n#include <Wire.h>\n\n#include <SparkFun_Qwiic_OLED.h> //http://librarymanager/All#SparkFun_Qwiic_OLED\nQwiic1in3OLED myOLED;\n\nint width;\nint height;\n\n// For simple frame rate calculations\nlong drawTotalTime = 0;\nint numberOfDraws = 0;\n\nfloat d = 3;\nfloat px[] = { -d, d, d, -d, -d, d, d, -d};\nfloat py[] = { -d, -d, d, d, -d, -d, d, d};\nfloat pz[] = { -d, -d, -d, -d, d, d, d, d};\n\nfloat p2x[8] = {0};\nfloat p2y[8] = {0};\nfloat r[3] = {0};\n\n#define SHAPE_SIZE 950\n#define ROTATION_SPEED 00\n\n#include <SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_MAX1704x_Fuel_Gauge_Arduino_Library\nSFE_MAX1704X lipo(MAX1704X_MAX17048);\n\ndouble voltage = 0;\ndouble soc = 0;\nunsigned long lastLipoCheck;\n\nvoid setup()\n{\n Serial.begin(115200);\n delay(250);\n Serial.println(\"OLED + Fuel gauge test\");\n\n Wire.begin(7, 20); //SDA, SCL\n Wire.setClock(400000); //Go to 400kHz for faster OLED response\n //Wire.setClock(1000000); //Moar! It's not 1MHz but it does work.\n\n if (myOLED.begin() == false)\n {\n Serial.println(\"Device begin failed. Freezing...\");\n while (true);\n }\n\n if (lipo.begin() == false)\n {\n Serial.println(\"MAX17043 not detected. Please check wiring. Freezing...\");\n while (1);\n }\n\n Serial.println(\"Begin success\");\n\n width = myOLED.getWidth();\n height = myOLED.getHeight();\n\n // For frame rate calc\n drawTotalTime = 0;\n numberOfDraws = 0;\n}\n\nvoid loop()\n{\n drawCube();\n\n if (millis() - lastLipoCheck > 1000)\n {\n lastLipoCheck = millis();\n voltage = lipo.getVoltage();\n soc = lipo.getSOC();\n\n Serial.print(\"Voltage: \");\n Serial.print(voltage); // Print the battery voltage\n Serial.println(\" V\");\n\n Serial.print(\"Percentage: \");\n Serial.print(soc); // Print the battery state of charge\n Serial.println(\" %\");\n\n Serial.println();\n }\n}\n\nvoid drawCube()\n{\n r[0] = r[0] + PI / 180.0; // Add a degree\n r[1] = r[1] + PI / 180.0; // Add a degree\n r[2] = r[2] + PI / 180.0; // Add a degree\n if (r[0] >= 360.0 * PI / 180.0)\n r[0] = 0;\n if (r[1] >= 360.0 * PI / 180.0)\n r[1] = 0;\n if (r[2] >= 360.0 * PI / 180.0)\n r[2] = 0;\n\n // This routine gets called often, so just make these statics\n static float px2, py2, pz2, px3, py3, pz3, ax, ay, az;\n\n for (int i = 0; i < 8; i++)\n {\n px2 = px[i];\n py2 = cos(r[0]) * py[i] - sin(r[0]) * pz[i];\n pz2 = sin(r[0]) * py[i] + cos(r[0]) * pz[i];\n\n px3 = cos(r[1]) * px2 + sin(r[1]) * pz2;\n py3 = py2;\n pz3 = -sin(r[1]) * px2 + cos(r[1]) * pz2;\n\n ax = cos(r[2]) * px3 - sin(r[2]) * py3;\n ay = sin(r[2]) * px3 + cos(r[2]) * py3;\n az = pz3 - 150;\n\n p2x[i] = width / 2 + ax * SHAPE_SIZE / az;\n p2y[i] = height / 2 + ay * SHAPE_SIZE / az;\n }\n\n // Calculate draw time\n uint32_t startTime = millis();\n\n myOLED.erase();\n for (int i = 0; i < 3; i++)\n {\n myOLED.line(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1]);\n myOLED.line(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5]);\n myOLED.line(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4]);\n }\n\n myOLED.line(p2x[3], p2y[3], p2x[0], p2y[0]);\n myOLED.line(p2x[7], p2y[7], p2x[4], p2y[4]);\n myOLED.line(p2x[3], p2y[3], p2x[7], p2y[7]);\n myOLED.display();\n\n // Write out our frame rate\n drawTotalTime += millis() - startTime;\n numberOfDraws++;\n\n // Output framerate once every 120 frames\n if (numberOfDraws % 120 == 0)\n {\n Serial.print(\"Frame rate: \");\n Serial.println(numberOfDraws / (float)drawTotalTime * 1000.0);\n\n numberOfDraws = 0;\n drawTotalTime = 0;\n }\n}\n
/*\n Attempt to mount an SD card and analyze the type of card\n By: Nathan Seidle\n SparkFun Electronics\n Date: November 24th, 2024\n License: This code is public domain but you buy me a drink if you use this\n and we meet someday (Drink license).\n Feel like supporting our work? Buy a board from SparkFun!\n https://www.sparkfun.com/products/27510\n\n Hardware Connections:\n Connect the Portability shield to the RTK Postcard or other controller board\n Insert a microSD card into the socket. Cards up to 512GB should work.\n Open output window at 115200bps\n*/\n#include \"SdFat.h\" // Click here to get the library: http://librarymanager/All#SdFat_SDXC by Bill Greiman\n#include \"sdios.h\"\n\nint pin_spiSCK = 32;\nint pin_spiPICO = 26; //microSD SDI\nint pin_spiPOCI = 25; //microSD SDO\nint pin_microSD_CS = 27;\n\n#define SD_CONFIG SdSpiConfig(pin_microSD_CS, SHARED_SPI, SD_SCK_MHZ(16))\n//#define SD_CONFIG SdSpiConfig(pin_microSD_CS, DEDICATED_SPI, SD_SCK_MHZ(16))\n\nconst int8_t DISABLE_CS_PIN = -1;\n\n//------------------------------------------------------------------------------\nSdFs sd;\ncid_t cid;\ncsd_t csd;\nscr_t scr;\nuint8_t cmd6Data[64];\nuint32_t eraseSize;\nuint32_t ocr;\nstatic ArduinoOutStream cout(Serial);\n//------------------------------------------------------------------------------\nvoid cidDmp() {\n cout << F(\"\\nManufacturer ID: \");\n cout << uppercase << showbase << hex << int(cid.mid) << dec << endl;\n cout << F(\"OEM ID: \") << cid.oid[0] << cid.oid[1] << endl;\n cout << F(\"Product: \");\n for (uint8_t i = 0; i < 5; i++) {\n cout << cid.pnm[i];\n }\n cout << F(\"\\nRevision: \") << cid.prvN() << '.' << cid.prvM() << endl;\n cout << F(\"Serial number: \") << hex << cid.psn() << dec << endl;\n cout << F(\"Manufacturing date: \");\n cout << cid.mdtMonth() << '/' << cid.mdtYear() << endl;\n cout << F(\"CID HEX: \");\n hexDmp(&cid, sizeof(cid));\n}\n//------------------------------------------------------------------------------\nvoid clearSerialInput() {\n uint32_t m = micros();\n do {\n if (Serial.read() >= 0) {\n m = micros();\n }\n } while (micros() - m < 10000);\n}\n//------------------------------------------------------------------------------\nvoid csdDmp() {\n eraseSize = csd.eraseSize();\n cout << F(\"\\ncardSize: \") << 0.000512 * csd.capacity();\n cout << F(\" MB (MB = 1,000,000 bytes)\\n\");\n\n cout << F(\"flashEraseSize: \") << int(eraseSize) << F(\" blocks\\n\");\n cout << F(\"eraseSingleBlock: \");\n if (csd.eraseSingleBlock()) {\n cout << F(\"true\\n\");\n } else {\n cout << F(\"false\\n\");\n }\n cout << F(\"dataAfterErase: \");\n if (scr.dataAfterErase()) {\n cout << F(\"ones\\n\");\n } else {\n cout << F(\"zeros\\n\");\n }\n cout << F(\"CSD HEX: \");\n hexDmp(&csd, sizeof(csd));\n}\n//------------------------------------------------------------------------------\nvoid errorPrint() {\n if (sd.sdErrorCode()) {\n cout << F(\"SD errorCode: \") << hex << showbase;\n printSdErrorSymbol(&Serial, sd.sdErrorCode());\n cout << F(\" = \") << int(sd.sdErrorCode()) << endl;\n cout << F(\"SD errorData = \") << int(sd.sdErrorData()) << dec << endl;\n }\n}\n//------------------------------------------------------------------------------\nvoid hexDmp(void* reg, uint8_t size) {\n uint8_t* u8 = reinterpret_cast<uint8_t*>(reg);\n cout << hex << noshowbase;\n for (size_t i = 0; i < size; i++) {\n cout << setw(2) << setfill('0') << int(u8[i]);\n }\n cout << dec << endl;\n}\n//------------------------------------------------------------------------------\nbool mbrDmp() {\n MbrSector_t mbr;\n bool valid = true;\n if (!sd.card()->readSector(0, (uint8_t*)&mbr)) {\n cout << F(\"\\nread MBR failed.\\n\");\n errorPrint();\n return false;\n }\n cout << F(\"\\nSD Partition Table\\n\");\n cout << F(\"part,boot,bgnCHS[3],type,endCHS[3],start,length\\n\");\n for (uint8_t ip = 1; ip < 5; ip++) {\n MbrPart_t* pt = &mbr.part[ip - 1];\n if ((pt->boot != 0 && pt->boot != 0X80) ||\n getLe32(pt->relativeSectors) > csd.capacity()) {\n valid = false;\n }\n cout << int(ip) << ',' << uppercase << showbase << hex;\n cout << int(pt->boot) << ',';\n for (int i = 0; i < 3; i++) {\n cout << int(pt->beginCHS[i]) << ',';\n }\n cout << int(pt->type) << ',';\n for (int i = 0; i < 3; i++) {\n cout << int(pt->endCHS[i]) << ',';\n }\n cout << dec << getLe32(pt->relativeSectors) << ',';\n cout << getLe32(pt->totalSectors) << endl;\n }\n if (!valid) {\n cout << F(\"\\nMBR not valid, assuming Super Floppy format.\\n\");\n }\n return true;\n}\n//------------------------------------------------------------------------------\nvoid dmpVol() {\n cout << F(\"\\nScanning FAT, please wait.\\n\");\n int32_t freeClusterCount = sd.freeClusterCount();\n if (sd.fatType() <= 32) {\n cout << F(\"\\nVolume is FAT\") << int(sd.fatType()) << endl;\n } else {\n cout << F(\"\\nVolume is exFAT\\n\");\n }\n cout << F(\"sectorsPerCluster: \") << sd.sectorsPerCluster() << endl;\n cout << F(\"fatStartSector: \") << sd.fatStartSector() << endl;\n cout << F(\"dataStartSector: \") << sd.dataStartSector() << endl;\n cout << F(\"clusterCount: \") << sd.clusterCount() << endl;\n cout << F(\"freeClusterCount: \");\n if (freeClusterCount >= 0) {\n cout << freeClusterCount << endl;\n } else {\n cout << F(\"failed\\n\");\n errorPrint();\n }\n}\n//------------------------------------------------------------------------------\nvoid printCardType() {\n cout << F(\"\\nCard type: \");\n\n switch (sd.card()->type()) {\n case SD_CARD_TYPE_SD1:\n cout << F(\"SD1\\n\");\n break;\n\n case SD_CARD_TYPE_SD2:\n cout << F(\"SD2\\n\");\n break;\n\n case SD_CARD_TYPE_SDHC:\n if (csd.capacity() < 70000000) {\n cout << F(\"SDHC\\n\");\n } else {\n cout << F(\"SDXC\\n\");\n }\n break;\n\n default:\n cout << F(\"Unknown\\n\");\n }\n}\n//------------------------------------------------------------------------------\nvoid printConfig(SdSpiConfig config) {\n if (DISABLE_CS_PIN < 0) {\n cout << F(\n \"\\nAssuming the SD is the only SPI device.\\n\"\n \"Edit DISABLE_CS_PIN to disable an SPI device.\\n\");\n } else {\n cout << F(\"\\nDisabling SPI device on pin \");\n cout << int(DISABLE_CS_PIN) << endl;\n pinMode(DISABLE_CS_PIN, OUTPUT);\n digitalWrite(DISABLE_CS_PIN, HIGH);\n }\n cout << F(\"\\nAssuming the SD chip select pin is: \") << int(config.csPin);\n cout << F(\"\\nEdit SD_CS_PIN to change the SD chip select pin.\\n\");\n}\n//------------------------------------------------------------------------------\nvoid printConfig(SdioConfig config) {\n (void)config;\n cout << F(\"Assuming an SDIO interface.\\n\");\n}\n//-----------------------------------------------------------------------------\nvoid setup() {\n Serial.begin(115200);\n delay(250);\n Serial.println(\"SPI test\");\n\n SPI.begin(pin_spiSCK, pin_spiPOCI, pin_spiPICO);\n\n cout << F(\"SdFat version: \") << SD_FAT_VERSION_STR << endl;\n printConfig(SD_CONFIG);\n}\n//------------------------------------------------------------------------------\nvoid loop() {\n // Read any existing Serial data.\n clearSerialInput();\n\n // F stores strings in flash to save RAM\n cout << F(\"\\ntype any character to start\\n\");\n while (!Serial.available()) {\n yield();\n }\n uint32_t t = millis();\n if (!sd.cardBegin(SD_CONFIG)) {\n cout << F(\n \"\\nSD initialization failed.\\n\"\n \"Do not reformat the card!\\n\"\n \"Is the card correctly inserted?\\n\"\n \"Is there a wiring/soldering problem?\\n\");\n if (isSpi(SD_CONFIG)) {\n cout << F(\n \"Is SD_CS_PIN set to the correct value?\\n\"\n \"Does another SPI device need to be disabled?\\n\");\n }\n errorPrint();\n return;\n }\n t = millis() - t;\n cout << F(\"init time: \") << dec << t << \" ms\" << endl;\n\n if (!sd.card()->readCID(&cid) || !sd.card()->readCSD(&csd) ||\n !sd.card()->readOCR(&ocr) || !sd.card()->readSCR(&scr)) {\n cout << F(\"readInfo failed\\n\");\n errorPrint();\n return;\n }\n printCardType();\n cout << F(\"sdSpecVer: \") << 0.01 * scr.sdSpecVer() << endl;\n cout << F(\"HighSpeedMode: \");\n if (scr.sdSpecVer() > 101 && sd.card()->cardCMD6(0X00FFFFFF, cmd6Data) &&\n (2 & cmd6Data[13])) {\n cout << F(\"true\\n\");\n } else {\n cout << F(\"false\\n\");\n }\n cidDmp();\n csdDmp();\n cout << F(\"\\nOCR: \") << uppercase << showbase;\n cout << hex << ocr << dec << endl;\n if (!mbrDmp()) {\n return;\n }\n if (!sd.volumeBegin()) {\n cout << F(\"\\nvolumeBegin failed. Is the card formatted?\\n\");\n errorPrint();\n return;\n }\n dmpVol();\n}\n
"},{"location":"hardware_assembly/","title":"Hardware Assembly","text":"
*.pdf
file, select the Printer or Destination labeled Save as PDF. (Instructions will vary based on the browser)
D/C I2C Addr 0 0x3C 1 0x3D (default)
"},{"location":"resources/","title":"Resources","text":"
"},{"location":"single_page/","title":"Single page","text":"
"},{"location":"single_page/#hardware-overview","title":"Hardware Overview","text":""},{"location":"single_page/#oled","title":"OLED","text":"
D/C I2C Addr 0 0x3C 1 0x3D (default)
"},{"location":"troubleshooting/","title":"Troubleshooting","text":"
"},{"location":"github/contribute/#submit-a-correction","title":"Submit a Correction","text":"docs
folder of the SparkFun Portability Shield repository.
"},{"location":"github/contribute/#improve-our-hardware-design","title":"Improve our Hardware Design","text":"
"},{"location":"github/contribute/#submit-a-design-enhancement","title":"Submit a Design Enhancement","text":"Hardware
folder of the SparkFun Portability Shield repository.
"},{"location":"github/contribute/#contributors","title":"Contributors","text":"
"},{"location":"github/file_issue/#spot-something-wrong","title":"\ud83d\udd0d Spot something wrong?","text":"docs
folder of the SparkFun Portability Shield repository.
"},{"location":"github/file_issue/#problems-in-the-hardware-design","title":"Problems in the Hardware Design","text":"
"},{"location":"github/file_issue/#does-something-not-make-sense","title":"Does something not make sense? \ud83e\udd14","text":"Hardware
folder of the SparkFun Portability Shield repository.
"},{"location":"github/file_issue/#do-you-wish-to-contribute-directly-to-improving-the-board-design","title":"Do you wish to contribute directly to improving the board design?","text":"
"}]}
\ No newline at end of file
diff --git a/single_page/index.html b/single_page/index.html
new file mode 100644
index 0000000..1592327
--- /dev/null
+++ b/single_page/index.html
@@ -0,0 +1,1663 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SKU: DEV-27510
+
+Required Materials
+
+
+
+
+
+
+
+
+ SparkFun Portability Shield
+
+ DEV-27510
+
+
+
+ SparkFun RTK Postcard
+
+ GPS-26916
+ Suggested Reading
+Hardware Overview
+OLED
+Navigation Switch
+GPIO Expander
+Power
+Current Measurement
+On/Off Switch
+Fuel Gauge
+LiPo Charging Circuit
+MicroSD Card
+Shield Connectors
+Jumpers
+
+
+
+
+
+
+ D/C
+
+ I2C Addr
+
+
+
+ 0
+
+ 0x3C
+
+
+
+ 1
+
+ 0x3D (default)
+
+
+
+
+Board Dimensions
+Hardware Assembly
+Troubleshooting Tips
+Resources:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Troubleshooting
+
+