You are browsing as a guest. Sign up (or log in) to start making projects!

FlashPoint

  • 9 Devlogs
  • 35 Total hours

My fork of CrossInk, adds flashcard support to the XTeink X4

Open comments for this post

6h 14m 11s logged

Split app into distinct parts

I have split the app into four parts - decks, review, sync, settings.

Decks

Currently just shows an ‘open’ button to review cards. Will eventually show a navigable deck tree.

Review

For reviewing due cards.

Sync

Syncs with Anki desktop.

Settings

Settings and stuff… (haven’t decided yet)

0
0
1
Open comments for this post

55m 45s logged

Basic anki sync achieved!

Cards are now downloaded from Anki on my laptop when the app is opened
and loaded into memory for review.

How I achieved this

I am running an anki plugin on my laptop called anki-connect which provides a REST API for interacting with cards, decks, notes etc…

The process looks like this:

  • Retrieve deck names
  • For each deck, retrieve card IDs
  • Retrieve each card by ID

Attached is a video showing 3 cards being synced.

Issues to be addressed in future

Each card is retrieved with an independent API request even though its possible to retrieve them in bulk

Why: My current implementation loads the entire response body into
memory at once then deserialises it. Each card in the response is
roughly 1KB, so loading many at once would require more memory than the
ESP32 has.

Fix: Implement a streaming approach instead where cards are saved to the
SD card as they are received, reducing memory usage.

Cards are lost when the app is exited

Why: I wanted a quick CardStore implementation to test the sync with so
cards are only stored in memory.

Fix: Implement a CardStore which saves them to the SD Card

0
0
2
Open comments for this post

9h 21m logged

Trying to get anki integration working

Currently trying to get the XTeink to load cards from my laptop through the anki-connect plugin’s api. Here’s a screenshot of the log from it attempting to load the decks and cards. Sadly it crashed right after so I’m still working on that.

After I get this working I can start working on storing the cards so they can be reviewed offline.

0
0
1
Open comments for this post

2h 14m 17s logged

Purged SQLite from the code and implemented an in-memory store instead

I’ve made an interface called CardStore so I can implement multiple ways of storing cards. In future, I might use this to benchmark and compare different methods but for now I’m using an in-memory store so I can quickly test things out.

I’ve made a plan for the persistent card storage, but I’ll get to that later.

For now I’m going to work on the initial sync with Anki. This will be much easier than the partial sync (where cards have been added, edited, removed, and reviewed).

0
0
3
Open comments for this post

52m 37s logged

My 4 yr old brother helped design a new logo

I was trying to design an icon for the flashcard app when he came over and asked if he could help. He says it’s a ‘super cool rocket block smiley face’.

0
0
5
Open comments for this post

10h 5m 51s logged

Went on a massive detour trying to get SQLite onto the ESP32

Anki allows you to export all your cards into a single .apkg file, which is essentially a zip file containing media files along with Anki’s SQLite database. I want it to be possible to import apkg files directly into flashpoint so I figured if I could get SQLite working on the XTeink X4 directly then this would be easy.

Issue #1 - I have no idea what I’m doing

I have never used PlatformIO before, so I wasn’t sure how to actually include libraries. Initially, I tried just adding #include <sqlite.h> where I needed it, but this failed to build so I installed SQLite onto my laptop which didn’t work either. I discovered that since the XTeink X4 uses an ESP32 I needed specific libraries for it — I found siara-cc/Sqlite3Esp32 and added it to the dependencies section in platformio.ini (PlatformIO’s config file). This brings us to Issue #2.

Issue #2 - The ESP32 is so small!

The ESP32 only has 16MiB of flash memory. This is enough to store around 48 novels, 4 photos, or 1/20th of a YouTube video*. This memory is typically used to store configuration, assets, and firmware. Here is the partition scheme used in CrossInk (the project I forked).

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     0x9000,  0x5000,   #    20KiB - For settings, like the WiFi password
otadata,  data, ota,     0xe000,  0x2000,   #     8KiB - Tracks OTA update progress
app0,     app,  ota_0,   0x10000, 0x640000, #  6.25MiB - First firmware partition
app1,     app,  ota_1,   0x650000,0x640000, #  6.25MiB - Second firmware partition
spiffs,   data, spiffs,  0xc90000,0x360000, # 3.375MiB - Filesystem for assets, such as those in the webserver
coredump, data, coredump,0xFF0000,0x10000,  #    64KiB - Crash reports for debugging

Overall, this reduces the space actually available for the firmware down to 6.25MiB. SQLite adds roughly 470KiB to the firmware image, bringing it beyond the 6.25MiB partition limit. To solve this I shrunk the spiffs partition, which allowed me to expand app0 and app1 to 7MiB and build an image with SQLite. However, I realised that I still couldn’t use SQLite yet.

Issue #3 - SQLite doesn’t understand the filesystem I’m using

Under many abstractions, it seems that CrossInk uses SdFat to manage the filesystem, rather than the simpler SD library. As I understand it, this means that files cannot be accessed using stdio.h commands like fopen() and instead must be accessed through the SdFat library. This means that for SQLite to work I would need to write a sort of ‘translation’ class which maps SQLite’s desired filesystem actions onto SdFat methods. This is called a VFS (Virtual File System), and looks very tedious to implement. In a last ditch effort, I tried to use the SD library and SdFat library simultaneously, which resulted in the whole device crashing whenever I opened my flashcards (pictured below) - this is not very useful. I’m sure I’m misunderstanding something and there’s probably an easier solution which works, but I’ve decided to try a different approach instead.

A different Approach

CrossInk already persists structured data in many places. For example, bookmarks appear to be stored in a binary file format using some sort of serialisation utility. I’ll look into this and probably implement my own storage solution which only stores the data I need rather than using an entire SQLite database.

In hindsight, SQLite was probably the wrong decision, but it led me to better understand PlatformIO, ESP32 partition tables, and CrossInk’s storage architecture.

Notes

Rough calculations:

  • 75,000 word novels, 4.7 characters per word, one-byte characters
  • 4MiB photos
  • 10-minute 720p video, which is around 332MB according to this website
0
0
5
Open comments for this post

2h 49m 12s logged

Created a card review screen

You can now review cards!

Well, technically there’s only one to review, but it’s a great card.

0
0
5
Open comments for this post

1h 2m 44s logged

We have a menu button!

I figured out how to add a button to the main menu (I designed a little icon for it too). Next, I’m going to make it do something.

I’m new to embedded development so I’m still trying to get my head around the build process as well as how CrossPoint is structured

0
0
6

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…