• Home
  • Exercises 06
  • MCU & Power Boards Test
  • MCU & Power Boards Test

    The questions below are due on Thursday March 23, 2023; 10:00:00 AM.
     
    You are not logged in.

    Please Log In for full access to the web site.
    Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.

    Board assembly and test will occur over two psets (EX06 and EX07). The first part (assembly) is due in EX06, and the second part in EX07 (though we aim to release the testing early in case you want to do it early). You'll need to do the board assembly in EDS where you have access to the soldering tools.

    These exercises will be completed as a team. The main tasks are to

    • Assemble and test the MCU boards
    • Assemble and test the power management boards

    Due for Ex06:

    • Your team should assemble N power boards
    • Your team should assemble N MCU boards

    Due for Ex07:

    • Your team should test N power boards
    • Your team should test N MCU boards

    Where N is the number of people on your team so that everyone will have a working mcu/powerboard combo.

    The testing is due with EX07 after spring break, though you are welcome (and encouraged!) to do it earlier.
    Just to reiterate, this isn't due until after spring break with exercise 7, so you don't need to test all of your boards until then. We're only putting this out with Ex06 as a helpful reference for testing.

    Testing

    Just like for the sensor boards, we need to test the assembled boards to make sure the design, layout, and assembly are correct. The test procedure differs for each board.

    MCU board

    Test 1: Power

    Before powering up your MCU board, use a multimeter to double check that there aren't any shorts between 3.3V and GND. If there are, you'll need to double check your soldering and potentially your PCB layout and schematic.

    If all seems well, power up your MCU board by connecting the JST connector to 3.3V and ground. You can get 3.3V from your XIAO ESP32-C3 dev board, from a power supply, whatever.

    If the power status LED lights up, go on to the next step. If it doesn't, you'll need to debug.

    Test 2: MCU programming and I2C

    Next we'll test the MCU: is it powered up, able to be programmed, and connect to sensors via I2C?

    Take a known good SHTC3/SGP41 sensor board -- ideally your board, but if that one is problematic, assemble/test a staff design or a team member's known-good board.

    Connect that board to your MCU board. Download the sensor code below (this is the one we used in Lab05). Make sure you can see sensor readings from both sensors on the serial port.

    You'll need to install the SGP41 library if you haven't already. You can find it [here](https://github.com/sensirion/arduino-i2c-sgp41).
    #include <Arduino.h>
    #include <SensirionI2CSgp41.h>    // link to the library: https://github.com/sensirion/arduino-i2c-sgp41
    #include <SparkFun_SHTC3.h>       // link to the library: https://github.com/sparkfun/SparkFun_SHTC3_Arduino_Library
    #include <Wire.h>
    
    SHTC3 shtc3;              // Declare an instance of the SHTC3 class
    SensirionI2CSgp41 sgp41;
    
    #define I2C_SDA 4
    #define I2C_SCL 5
    
    // time in seconds needed for NOx conditioning
    uint16_t conditioning_s = 10;
    
    void setup() {
    
        Serial.begin(115200);
        while (!Serial) {
            delay(100);
        }
    
        Wire.begin(I2C_SDA, I2C_SCL);
    
        uint16_t error;
        char errorMessage[256];
    
        errorDecoder(shtc3.begin());
    
        sgp41.begin(Wire);
    
        uint16_t serialNumber[3];
        uint8_t serialNumberSize = 3;
    
        error = sgp41.getSerialNumber(serialNumber, serialNumberSize);
    
        if (error) {
            Serial.print("Error trying to execute getSerialNumber(): ");
            errorToString(error, errorMessage, 256);
            Serial.println(errorMessage);
        } else {
            Serial.print("SerialNumber:");
            Serial.print("0x");
            for (size_t i = 0; i < serialNumberSize; i++) {
                uint16_t value = serialNumber[i];
                Serial.print(value < 4096 ? "0" : "");
                Serial.print(value < 256 ? "0" : "");
                Serial.print(value < 16 ? "0" : "");
                Serial.print(value, HEX);
            }
            Serial.println();
        }
    
        uint16_t testResult;
        error = sgp41.executeSelfTest(testResult);
        if (error) {
            Serial.print("Error trying to execute executeSelfTest(): ");
            errorToString(error, errorMessage, 256);
            Serial.println(errorMessage);
        } else if (testResult != 0xD400) {
            Serial.print("executeSelfTest failed with error: ");
            Serial.println(testResult);
        }
    }
    
    void loop() {
        uint16_t error;
        char errorMessage[256];
        uint16_t defaultRh = 0x8000;
        uint16_t defaultT = 0x6666;
        uint16_t srawVoc = 0;
        uint16_t srawNox = 0;
    
        delay(1000);
    
        SHTC3_Status_TypeDef result = shtc3.update();             // Call "update()" to command a measurement, wait for measurement to complete, and update the RH and T members of the object
        printInfo();                                                // This function is used to print a nice little line of info to the serial port
    
        if (conditioning_s > 0) {
            // During NOx conditioning (10s) SRAW NOx will remain 0
            error = sgp41.executeConditioning(defaultRh, defaultT, srawVoc);
            conditioning_s--;
        } else {
            // Read Measurement
            error = sgp41.measureRawSignals(defaultRh, defaultT, srawVoc, srawNox);
        }
    
        if (error) {
            Serial.print("Error trying to execute measureRawSignals(): ");
            errorToString(error, errorMessage, 256);
            Serial.println(errorMessage);
        } else {
            Serial.print("SRAW_VOC:");
            Serial.print(srawVoc);
            Serial.print("\t");
            Serial.print("SRAW_NOx:");
            Serial.println(srawNox);
        }
    }
    
    
    
    /////////////////////////////
    // SHTC3 Utility Functions //
    /////////////////////////////
    void printInfo()
    {
      if(shtc3.lastStatus == SHTC3_Status_Nominal)              // You can also assess the status of the last command by checking the ".lastStatus" member of the object
      {
        Serial.print("RH = "); 
        Serial.print(shtc3.toPercent());                        // "toPercent" returns the percent humidity as a floating point number
        Serial.print("%, T = "); 
        Serial.print(shtc3.toDegF());                           // "toDegF" and "toDegC" return the temperature as a flaoting point number in deg F and deg C respectively 
        Serial.println(" deg F"); 
      }
      else
      {
        Serial.print("Update failed, error: "); 
        errorDecoder(shtc3.lastStatus);
        Serial.println();
      }
    }
    
    void errorDecoder(SHTC3_Status_TypeDef message)                             // The errorDecoder function prints "SHTC3_Status_TypeDef" resultsin a human-friendly way
    {
      switch(message)
      {
        case SHTC3_Status_Nominal : Serial.print("Nominal"); break;
        case SHTC3_Status_Error : Serial.print("Error"); break;
        case SHTC3_Status_CRC_Fail : Serial.print("CRC Fail"); break;
        default : Serial.print("Unknown return code"); break;
      }
    }
    

    If that all works, you're almost finished.

    If that doesn't work, then you'll need to debug: you'll want to check if the MCU is getting power (and gnd), if the USB interface is connected, if you can download code to the board, and if the I2C pins from the board are connected.

    Test 3: Check reset button

    Once the code is working and you are seeing readings, hit the reset button on your MCU board. The board should reset and start up again.

    Test 4: Check boot button

    Pressing the boot button should put your ESP32 into "download mode" where it's waiting for new code to be flashed. Try pressing your boot button and you should see your ESP32 stop printing sensor readings to the serial monitor and instead print some text indicating it has entered download mode and is waiting for new code.

    Test 5: Posting

    Finally, adapt your code from EX05 that posted RH/T data to your database, so that it now sends and logs VOC and NOx readings as well. Upload a brief video of this working and you are all set!

    Insert the URL below:

    MCU testing video URL:

    Power board

    Test 1: Some checks before powering up

    The power board is less tolerant of wiring mistakes than other boards. So our first test will be to make sure there is no short between power and ground. Use a multimeter to check the resistance between 5V power pin on the MCP73871 and ground pins -- hopefully you have test points that make this easy to check.

    Test 2: Check USB power functionality

    One use case of the power board is that when it is connected to USB input (5V), the MCP73871 chip sends that 5V to the AP7361C regulator, and the regulator outputs 3.3V.

    Connect your power board to USB power. Check voltages on certain pins/traces:

    • MCP73871 pin 18/19 (IN) should be ~5 V
    • MCP73871 pin 1/20 (OUT) should be ~5 V
    • AP7361C pin 5 (OUT) should be 3.3 V
    • The power status LED (if you have one) should turn on

    Test 3: Delivering power

    Next, we will want to see whether the power board can power an ESP32C3. We'll give instructions for how to do this with the XIAO ESP32C3 board, but similar procedure will work with your own ESP32C3 board.

    First, download code on the ESP32 XIAO board that will connect to WiFi and post to your flask server. We do this because we want to stress test the power board, and the highest peak power draw occurs when the ESP32 is posting to WiFi. Start by powering th XIAO board from USB to make sure that code is working and posting.

    Next disconnect the XIAO board from USB input (because the USB input is also providing power). Power up the XIAO board from the 3.3V and GND pins on your power board.

    Make sure the MCU power status LED lights up, and then check to ensure that you are logging data to the server. If so, you are delivering power!

    Test 4: Charge the battery

    The next functionality of the power board is that it should be able to charge a LiPo battery.

    Obtain a LiPo battery. The batteries come partially charged.

    Disconnect the power board from the XIAO board.

    Connect the power board to USB, attach the battery. Check your status LEDs. The PG LED should light up, as should the STAT1 LED (see Table 5-1 in the MCP718731 datasheet).

    Now, while keeping the system connected to USB power, carefully place the battery and board in a pouch. The pouches are for safety in case anything goes wrong!

    Come back after 2 hours. Once the battery stops charging, the status LEDs should change. Check Table 5-1 to see what they should be, and make sure you observe that!

    Test 5: Run off battery

    The final functionality is that the power board should be able to run the rest of the system from battery power alone.

    With the battery charged, disconnect the battery. Connect up your ESB32C3 XIAO board. Reconnect the battery. If everything works well, you should be posting to the server off battery power!

    Power board testing video URL: