Italia’s Status Report for 4/25/2026

This week, I was able to finish all animations and create an animation system for the character’s different idle/sad animations. The settings menu and home screen can now seamlessly transition between one another without lag or menu skips. While displaying different graphics, I did, however, notice some color display issues, so I will be working on using more saturated colors so they appear properly on the screen. I also encountered issues with the battery icon and health bar displaying incorrectly. For the health bar, the current image being displayed is fine, but for the battery, I will be changing the symbol and logic behind battery symbols (instead of battery level display, there will be a warning for low battery and a charging icon).

The plan for next week is to polish up the graphics for the final demo and ensure any changing icons have a seamless state transition.

Currently, I am on schedule for the MVP for the final demo coming up.

 

Delaynie’s Status Report for 04/25/2026

PCB Version 2

Bugs:

  • LED control should not have gone on GPIO46. It’s a bootloader pin, and it doesn’t reliably work as a digital output. There are a couple of other unused pins nearby that can be used instead.
  • The LED control pin also needs a pull-up resistor because it is active-low. This means that when the ESP32 goes to sleep, the screen will still be on, blank white.
  • Green LEDs are way too bright (I see spots in my vision after looking at them). They also get a bit warm. These LEDs are just for debugging.
    • Yellow LEDs could also be a bit brighter.

Things that work:

  • The ESD protection diodes on the USB didn’t break it!
  • The buzzer works now that a pmos is being used.
  • The screen and stuff works after I rewired it.

Pictures of PCB rewire:

Button Debounce Requirements

  • Surprisingly, the buttons we are using aren’t that bouncy. After looking at the waveform, it doesn’t ring for more than 10 ms.

Team Status Report for 04/25/2026

The most significant risk to this team’s success is getting the firmware done in time for the demo. This risk is managed by the fact that we are planning to spend the bulk of our time this week on Capstone. Contingency plan is to get as much work done by the end of Thursday, and decide what to include in the demo on Friday after that.

Progress is behind schedule, but since there are no classes this week, we have extra time to spend on integrating all of the firmware and testing it before the demo.

There are a couple of small design changes we decided to make this week, such as only including battery statuses instead of fine percentage levels. This is due to the variability, and therefore unreliability, in voltage as Remigotchi is being used.

Below is a state diagram of our firmware.

Unit Tests

  • GNSS test: Ran firmware on Remigotchi to interface with its GNSS module. Measured how long it typically takes to get a verified time. We found that we could only reliably get a verified time when outside, or sometimes by a window.
  • RTC test: Synchronized the RTC with the GNSS time once, put the ESP32 to sleep, woke it up several hours later and measured the time difference. We found that over the course of roughly 8 hours, the ESP32’s internal RTC was roughly 2 min, 15 sec ahead. Given this, we are considering synchronizing to GNSS time more frequently than once a week.
  • Power tests: Enabled/disabled various combinations of peripherals connected to the ESP32 and measure how much power the device draws overall. We found that having the GNSS module in use vs not in use didn’t have much of an impact. However, the module itself is embedded onto the board, and its power lines are hard-wired to the board’s main power. This means that even if the GNSS module is not in use, it still does have some amount of power going to it. Should this project be worked on in the future, we would likely have some sort of way to dynamically control access to power for various devices.
  • ADC battery monitor: Read out millivolts measured on the ESP32’s ADC pin, and compared it to what I measured with a multimeter. It was accurate to about 0.01 volts. However, we concluded that voltage is not typically a good indicator of overall battery charge level due to the fact that voltage varies a bit during usage, and the lipo discharge curve is very non-linear. Therefore, we decided to not include a precise battery percentage readout visible to users, but instead, opt for battery indicators when the device needs to be charged or when it is fully charged.
  • Bluetooth connection time: We measured how long it took for the desktop app to connect to Remigotchi at varying distances between the two devices. Average is around 2 seconds.
  • Bluetooth data upload time: We measured how long it took to send a user’s schedule from the desktop app to Remigotchi, once it’s connected. Typical schedule sizes (under 10 reminders/week) result in send times of less than 1 second.

Felipe Status report for 4/25/2026

This week saw me finish work on the desktop app prior to the demo.  I added additional notifications and a way to modify what pet the user displays on the Remigotchi device, while providing a preview of what that pet looks like.  This also led me to conducting additional tests on the Bluetooth capabilities, which confirmed that I was sending data in the correct manner.  Future changes to the app will likely be limited to minor bug fixes prior to the demo.

Deliverables for the coming week are the final deliverables of the project, those being the poster and the video.  The poster I will be working on today and will likely be ready for team review by Monday, with the video following in short order.   I will also be responding to teammates requests for aid in their areas.

Overall I am excited for the demo this week and feel that we are in a good position for a final push to completion.

Italia’s Status Report 04/4/2026

This week, I was able to get the graphics I designed to display on the screen and move like animations. Previously, I was struggling to get any animations to play on the screen at all, which is not ideal since our device needs to have animated details. I looked into animation libraries for Arduino and found Animated GIF, which I used to animate the character. While I was able to get the character animation to work, I am still trying to figure out animating other objects on the screen while the character animation is playing.

I was also able to test the button functionality on the PCB board. However, I am experiencing issues with getting the screen to work when connected to the PCB, so I was only able to test the buttons by printing out a message to the serial monitor.

In the upcoming week, I will work on having multiple graphical assets on the screen at a time and figuring out what may be causing the screen to not work with the PCB. Currently, I am off schedule due to TFT library issues on the screen and PCB issues, so I will work to resolve them promptly to ensure I can move on to full firmware coding.

Delaynie’s Status Report for 04/18/2026

GNSS Time Acquisition Testing

  • Indoors, and even outdoors, it takes a while (more than a few seconds) for the time to resolve itself.
  • When to call the time and date “good”:
    • When gnss.getTimeValid() and gnss.getDateValid() return true, then the time and dates provided can be trusted for our purposes. The only major thing to be aware of is that it doesn’t guarantee leap seconds are correct (which means you have a +/- 1 second uncertainty).
    • Even when this happens, the number of satellites reported seen might be zero.
    • When inside the W3VC radio club near the window, it takes 1-2 minutes on average for the time and date to validate from a cold start. (This is different from simply resetting the MCU/code. When simply resetting code, time and date validation takes less time.)
  • A note about “valid” and “confirmed”:
    • There are four functions available: gnss.getTimeValid() , gnss.getDateValid() , gnss.getTimeConfirmed() , and gnss.getDateConfirmed() .
    • “Confirmed” is a more strict check than “valid”.
  • See GitHub repo for modifications on custom library this week.

BLE Schedule Uploading

  • Define a struct for each event to be sent from the desktop app to Remigotchi
#include <stdint.h>

typedef struct {
    // 32 bytes
    char name[32];
    // 2 bytes
    uint16_t period;
    uint16_t start_time;
    uint16_t end_time;
    // 1 byte
    uint8_t days_of_week;
    uint8_t padding[1];
} event_t;
  • Rewrote BLE Serial testbench, there were some bugs with the code blocking until a total of 4 bytes were sent. Now, it doesn’t block, but continuously polls the serial buffer.

Battery Monitor

  • I finally got around to testing the battery monitor, which is a 100 kOhm and 270 kOhm voltage divider connected to one of the ESP32’s GPIO pins.
  • Luckily, the Arduino framework provides a function analogReadMillivolts(), which does in fact work. So all I have to do is call that.
  • I confirmed with a Fluke 233 multimeter that values read by the aforementioned function are accurate.

New Tools and Knowledge

I needed to learn a bit more about how the SPI peripherals on the ESP32-S3 were set up. The main strategies I used were forums about ESP32 SPI usage, as well as ESP’s official documentation page and chip datasheets.

I also learned a bit about communicating with the GNSS module on the board. I learned how to use it by first looking up popular, well-tested libraries, and decided on the SparkFun GNSS V3 library. From there, I learned how to extract the time from the device by reading the library’s docs as well as the device’s datasheet.

Below is a photo of the LCD screen connected to a Remigotchi PCB used for field-testing the GNSS connectivity.

Italia’s Status Report for 4/18/2026

This week, I had to troubleshoot many issues I was experiencing with the firmware and graphics. There were two main issues I ran into: the screen not RemiGotchi screen not showing anything, and graphics glitches. The first issue was solved after figuring out the correct ESP32-S3 board. The two issues were, however, a lot more complicated, as it was a multitude of issues, such as library function compatibility and mismatched data sizes for pushing graphics.

After solving these issues, the buttons and screen can now interact properly: Menu Toggling

Due to these issues, I am off schedule by quite a bit. I plan to work on the project on the firmware and have it completed by this coming Wednesday. After that, I will have other people test it for a few days to fix any issues.

 

Unit Tests and System Tests

To monitor user input to device reaction time, I booted up the RemiGotchi device and tested the device reaction time from pressing the buttons ten times in a row. I also performed this same test after the device had been sitting for a while. The results from both these tests yielded approximately the same reaction time of 72 milliseconds, which is almost half of our anticipated reaction time. When this same test was performed with long button presses instead, the reaction time was 77 milliseconds, despite the button press performing a much more strenuous task ( switching from a PNG image to a multi-part graphical interface).

When trying to decide on animation libraries, I tested out 3 graphic libraries: eSPI TFT, Animated GIF, and the LVGL library. Initially, the Animated GIF library looked promising as it was able to quickly render animated characters, but it was extremely difficult to use, with drawing static assets on the screen. Static assets often ended up as corrupted files on the screen, and hid parts of the character animation from view.  I did some research into other animation libraries and found the LVGL library. There, however, was not enough documentation for me to feel comfortable using this library. As a result of my difficulties with the other libraries, I decided to use the library for the TFT screen, as it had the most documentation and included multiple ways to parse data into an animation-style format.

Team status report 4/18/2026

This week saw the testing portion of our capstone take off.  Felipe started talking to other students to review the UI of the desktop app, Delaynie tested the functionality of the gps portion of the device and timed how long it took to start connecting to satellites, and Italia continued testing out different graphic libraries to find out which one works best for our use case.  Such testing will be incorporated into our final presentation which will be happening this week.

 

In terms of what we have left before the final demo, integration between the board and the companion app has been nearly completed, as Felipe and Delaynie were able to establish what a sent schedule looks like and how a schedule is turned into a stream of bytes to send, and have confirmed that the bytes can be sent within and acceptable range of time (around 1-1.5 seconds).

 

In terms of changes there are very few.  Felipe has really nailed down what the UI is looking like and while Italia has made some changes to the colors of some graphics, the core look remains the same.

 

Overall we are excited to finish the semester strong and are looking forward to showing off our hard work in the coming weeks.

Felipe Status Report for 4/18/26

This week saw me finalizing the desktop app, as well as beginning some testing on it.

Below are some updated screenshots of both the schedule creation screen and the bluetooth screen:

This also saw me responding to advice given by my peers in regards to what should be included to make sure the desktop app is easy to use and understand.  Results from this advice centered on increased notification as to when tasks like saving schedules are completed.  The biggest thing added this week would be toast notifications that alert the user before fading automatically, allowing for easy notification that is hard to ignore yet also doesn’t require undue effort to react to.  I also made changes to certain portions of the color scheme, but had to consider the visually impaired in what colors were selected.  I defaulted to soft greens for most selected options, and am awaiting feedback on whether the color is distinct enough without causing eye strain.

Overall I feel that the app is almost complete, and only requires a couple more quality of life changes before the demo in 1.5 weeks, which gives me time to aid teammates in integration so the demo goes well.

 

In terms of new knowledge I required to finish this project, I found myself reviewing and reflecting on work I had done during a prior internship that was also centered on desktop application UI design.  I had to learn to put myself in the mind of the user when designing the app, since they would know less about the project and thus would require more aid in tips when using the app.  This then led to me trying to find a balance between making the app easy to understand and clean to look at, as drowning the user un additional messages seems like poor design.  Learning good UI design involved me navigating common websites (google, canvas, discord) and taking note of the UI choices made there.  What colors worked well together, how often were error messages displayed and in what format, what was the user informed about and what was relegated to the backend.  All of the observations informed my decisions regarding the desktop app.

In addition to UI design, I also had to learn how to use new libraries and language, especially in regards to how to connect to bluetooth devices.  While flutter/dart is similar enough to kotlin as both use the google material library that learning the language was not needlessly complex, I had never had to deal with bluetooth before, so learning how to use the flutter_blue_plus library was fun.  In terms of how I learned to use the library, it generally involved reading official documentation and parsing example code that could be adapted to serve my purposes.  In addition, forum posts like those from stackOverflow were helpful in identifying bugs, as most common bugs I ran into were not exclusive to my project.

 

Delaynie’s Status Report for 4/4/2026

GPS

  • Copilot was able to do a lot in this area. Most of my work involved finding the right library to use, finding the right version of that library, and making sure it was properly installed.
  • There were some comments in the library source code explaining some nuance to the order in which functions should be called, so I had to refactor to touch that up a bit.
  • But for filling in functions like estimating UTC offset or calculating the day of the week, Copilot was quite helpful. It’s most useful when I already have the structure and clear inputs and outputs defined.
  • I tested the code by running the code, printing out the number of satellites in view, and printing the time and date received.
  • After I verified the ability to receive time of day from the satellites, I worked on integrating that functionality with the use of the ESP32’s RTC peripheral, and building that into a custom library that will provide the caller with the most accurate time possible.

SPI Issues with the LCD Screen

<aside> ✅

Fix: In the User_Setup.h file in the library source code (terrible architecture by the way) make sure #define USE_HSPI_PORT is uncommented.

</aside>

  • Recall that we are using an external library for driving our LCD screen via SPI. That library is TFT_eSPI.
  • Simply changing the SPI pins between the breadboard version of the code and the version for the PCB did not work.
  • The board would completely crash somewhere within in the tft.init() function call. (To be clear, this is a function provided by TFT_eSPI).
  • So, I went back to the basics and ran the SPI testbench code from last week where it would simply send an incrementing byte across the line.
  • Both SPI buses simply sending an incrementing/decrementing value separately does work. Code is below.

SPI Sanity Check

#include <Arduino.h>

// #include <TFT_eSPI.h>      // Include the graphics library
// TFT_eSPI tft = TFT_eSPI(); // Create object "tft"

#include <SPI.h>
#define SPI2 FSPI
#define SPI3 HSPI

#define LCD_CIPO 13
#define LCD_COPI 11
#define LCD_SCLK 12
#define LCD_CS 10 // Chip select control pin
#define LCD_DC 9  // Data Command control pin
#define LCD_RST 3 // Reset pin (could connect to RST pin)

#define SHARED_COPI 38
#define SHARED_CIPO 39
#define SHARED_SCLK 40

#define SD_CS 41
#define RFID_CS 42

SPIClass lcd_SPI(SPI2);

SPIClass shared_SPI(SPI3);

#define BUTTON_1 14

void setup(void)
{
  pinMode(BUTTON_1, INPUT_PULLDOWN);
  while (!digitalRead(BUTTON_1))
  {
  }

  Serial.begin(115200);
  Serial.println("begin");

  pinMode(LCD_CS, OUTPUT);
  pinMode(SD_CS, OUTPUT);
  pinMode(RFID_CS, OUTPUT);
  digitalWrite(LCD_CS, HIGH);
  digitalWrite(SD_CS, HIGH);
  digitalWrite(RFID_CS, HIGH);

  lcd_SPI.begin(LCD_SCLK, LCD_CIPO, LCD_COPI, LCD_CS);
  shared_SPI.begin(SHARED_SCLK, SHARED_CIPO, SHARED_COPI, -1);

  // tft.init();
  // Serial.println("tft init");

  // tft.setRotation(1);
  // tft.fillScreen(TFT_DARKGREY);
  // tft.setTextFont(2);
}

uint8_t l = 0x00;
uint8_t s = 0x00;
void loop()
{
  Serial.printf("lcd spi = %x shared spi = %x\\n", l, s);

  lcd_SPI.transfer(l++);
  shared_SPI.transfer(s--);

  delay(250);

  // tft.fillRectHGradient(0, 0, 160, 50, TFT_MAGENTA, TFT_BLUE);
  // tft.setCursor(10, 10);
  // tft.print("Horizontal gradient");

  // tft.fillRectVGradient(0, 60, 160, 50, TFT_ORANGE, TFT_RED);
  // tft.setCursor(10, 70);
  // tft.print("Vertical gradient");
}
  • I went back and tried to make it not crash during tft.init() again.
  • What ultimately fixed it was simply configuring the library to use the HSPI port. It’s a line in the User_Setup.h file that you uncomment. I’m attaching a full copy of the User_Setup.h file to this web page for reference.
    • Interestingly and frustratingly, the ESP32-S3 doesn’t necessarily have FSPI, HSPI, and VSPI ports anymore. Instead it has two SPI peripherals, SPI2 and SPI3. However, the old terminology appears to have stuck around for backwards compatibility reasons. ChatGPT explains it some more at the beginning of this conversation here (scroll up all the way to the top).
  • Lastly, I added some SD card code from last week into this project, and I’ve verified that at the very least, I can display a static picture on the LCD screen and then

RFID Scanner

  • I first encountered an issue where the RFID scanner would not communicate back to the ESP32.
  • After looking at it with an oscilloscope, the SCLK and COPI lines looked normal. However, the COPI waveform looked incredibly weak.
  • I eventually realized that I did not have CS connected to the RFID scanner itself.
    • Part of this oversight was due to the fact that on the module’s silkscreen, there is no “CS” pin labeled. It’s just that the pin labeled “SDA” also doubles as the CS pin while being used for SPI 💀
  • After connecting a CS pin, the RFID scanner functioned just fine, and I was able to read the UID from an RFID tag.
  • Next, I need to verify that the RFID, SD card reader, and LCD screen all work in conjunction with each other.

PCB Work

  • Now that most of the elements on the PCB have been validated, and not to mention the deadline is drawing near, I went back to making edits to the schematic and redoing the layout.
  • I decided to completely redo the layout because I added a few things to the schematic, I got rid of all jumper bridges (we’re not in prototype mode anymore), and I wanted to prioritize a compact and smooth form factor.

Photos

Current layout and 3d model (components not yet routed):

What happens when you forget to include a CS line on your SPI-connected device: