Can Arduino Due act as a Mass Storage Device (MSD)?

I would like to collect data from my Nibe F370 heat pump. First I looked at a solution to "decrypt" the modbus protocol they use to communicate add-on modules (like an expensive SMS module). Secondly I saw that I could connect a Mass Storage Device to a USB port on the pump and the data was written in clear text to the device. The problem with this solution is that I want the data in "real time" (I don't want to collect the data manually anyways).

My dream solution would be to emulate the MSD interface and parse the raw data and send it to a server that could store it. (note that the pump writes a line with a hundred characters every minute to the device)

So to my questions:

  • I have a Due board that I could use for this, is there a library that I can use to emulate the MSD interface?
  • During my searches I stumble upon LUFA. It is written for AVRs but is there a port for the Due board going on?
  • Is there any other hardware that could do this easier? (The heat pump is quite tricky, for instance you cannot use a newer MSD devices, so the infinitec solution is a no go for me)

I know that lots of people want to log data from their heat pumps and often newer pumps have such usb-memory-output and therefor a solution like this could be useful. Just as a note; some pumps seems to aggressively buffer the data before writing to the device so this won't be a "real time" monitor but just to get the data without the manual pain is a great gain.

My dream solution would be to emulate the MSD interface and parse the raw data and send it to a server that could store it. (note that the pump writes a line with a hundred characters every minute to the device)

I started work towards this on Teensy 2.0. Honestly, this is still a work-in-progress. It's more difficult than I had originally thought. There are 3 rather difficult problems:

1: Caching - the PC writes quickly to minimize the chance of data loss if you unplug the USB device unexpectedly, but it maintains a cache of almost everything for reading. You can't simply change the data and expect your PC to be aware of the changes. Worse, if you change the FAT tables in conflict with writes the PC does later, you can ruin the filesystem.

2: SCSI sense timing - To work around #1, I added (as yet undocumented) functions Disk.claim() and Disk.release(). When you claim the disk, the media is taken away from the PC, and when you release it, it's given back. Perhaps these names aren't intuitive... I might change them later (when/if I ever get this stuff working reasonably well). The trouble I experienced involves timing. Just because you've claimed the disk doesn't mean the PC has updated. I wrote some complex code to track what status updates and scsi sense codes have been reported, and I tested on Windows, Mac and Linux... but it's far from perfectly refined. In theory, one error code and one scsi sense ought to be enough, but in practice Windows seems to second guess the card at times. I still haven't learned exactly what its doing, so I have not found a way to know exactly when it the PC is no longer expecting the media. The problem mostly manifests as the PC not "forgetting" the cached data. Adding many seconds of delay in your program is a workaround, but the caveat is this issue is still not fully understood (by me, anyway) so any workaround is more guesswork than reliable engineering (and the failure mode is a badly corrupted filesystem on the SD card).

3: SD card sharing - Sharing the SD card between the interrupt-driven USB code and a user level (polling-only) library like SD or SdFat is tricky. This is actually many problems. First, if an interrupt occurs while SdFat is using the SPI port, a conflict occurs at that level. Second, even if the SPI port isn't in use (the CS signal isn't asserted), the SdFat library may be in the middle of a sequence of operations where the card must not be accessed. Third, even if you never use SdFat while you haven't claimed the disk (a wise move), when switching between the 2, the card can be left in a state where the other can't recover. I added some mutex functionality (also undocumented) for testing, but so far I've never dug deeply into the underlying issues of how Bill's code leaves the card configured and how my code would need to use to interoperate nicely.

If you've installed Teensyduino, it appears in the Tools > USB Type menu. It mainly lets you access the card from your PC, but sharing between the PC and your own code really isn't well supported. While it sort-of works, there are still a lot of rough edges (which it why it's not yet documented...)

My dream solution is to someday make this work so easily and flawlessly that anyone could quickly build data logging applications like you've described. If you want to dig into extremely messy low-level USB and SD card protocol details, my code is probably the closest that exists today (the Teensyduino installer puts it into hardware/teensy/cores/usb_disk). But these issues are quite difficult.... which is why I haven't perfected this to the point it's even worth documenting.

Paul,

Any upate on this?

Thanks!

No, no update from me and I have not done any more digging.

Still interested if I could emulate an MSD using duo.

Atmel studio 7 has an example of this.

av8or1:
Any upate on this?

Recent progress on MTP.