Pico Mounting SD Card
Re: Pico Mounting SD Card
There was not much to implement, and I tried it out of own interest. And last not least - I have to learn dealing with cmake. And taht was at least a start.
-
- Posts: 5
- Joined: Sun Jan 31, 2021 10:02 pm
Re: Pico Mounting SD Card
The build works like a charm, I can now log data on the built in flash and whenever someone wants to get the data they can press a button and it copies the data to the SD card. I'm doing this as I'm trying to reduce power consumption, and I've read that writing to an SD card has a relatively high power consumption. If anyone happens to know if limiting the SD card usage actually makes a difference to power consumption that would be great, otherwise I'll probably power my data logger on 3 AAs and find out whether logging to the built in memory or the SD card makes any difference to the run time of the device.
Thanks for your help.
Thanks for your help.
Re: Pico Mounting SD Card
Hi,
I'm still struggling with the Pico and an SD card.
Here is what i did in Micropython 1.16
From the previous posts I understood that the problem is a missing FAT support of uos?
Though, if that was true, why do I only get an error when I try to mount the file system?
Roberthh posted a link for Micropython WITH Fat support,
https://github.com/robert-hh/micropython/tree/rp2_fat
but it goes into the void for me.
Could someone share his wisdom with me? I would be very glad to log measuring values on an external medium, as the internal storage is rather limited.
I'm still struggling with the Pico and an SD card.
Here is what i did in Micropython 1.16
Code: Select all
>>> from machine import SPI, Pin
>>> import uos
>>> import sdcard
>>> sd = sdcard.SDCard(SPI(1), Pin(9))
>>> vfs = uos.VfsFat(sd)
>>> uos.mount(vfs, "/sd")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 19] ENODEV
Though, if that was true, why do I only get an error when I try to mount the file system?
Roberthh posted a link for Micropython WITH Fat support,
https://github.com/robert-hh/micropython/tree/rp2_fat
but it goes into the void for me.
Could someone share his wisdom with me? I would be very glad to log measuring values on an external medium, as the internal storage is rather limited.
Re: Pico Mounting SD Card
FAT support is included in v1.16. otherwise VfsFat would not exist. I mounted already SD card on RP2, so it's possible. Error 19 indicates that the file system could not be detected. The SD card must only have a single FAT partition. Sometimes new cards have another small partition as the first one. That confused the driver. And not all cards work. I tested it with Samsung, Sandisk and Transcend cards in to he range of 8 to 64 GB.
Re: Pico Mounting SD Card
Thank you, Robert!
Good news:
Just now I succeeded in mounting another freshly formatted (FAT32) card in a folder "/test" I had created in the internal file system of the Pico.
Here is the code:
The unmount at the end is important, otherwise I get an error when restarting the program, as the card is already mounted.
Good news:
Just now I succeeded in mounting another freshly formatted (FAT32) card in a folder "/test" I had created in the internal file system of the Pico.
Here is the code:
Code: Select all
from machine import SPI, Pin
import uos
import sdcard
import time
sd = sdcard.SDCard(SPI(1), Pin(9))
vfs = uos.VfsFat(sd)
uos.mount(vfs, "/test")
l = uos.listdir("/test")
print(l)
uos.umount("/test")
Re: Pico Mounting SD Card
I have tested several SDcards, 4 out of 9 worked, the other produced errors:
or
in init_card
though the cards worked fine in Linux Mint on my computer, and though they were freshly formatted.
Maybe this is due to a timing problem?
I recall a similar behavior of some cards in Arduino.
Code: Select all
OSError: timeout waiting for v1 card
Code: Select all
OSError: no SD card
though the cards worked fine in Linux Mint on my computer, and though they were freshly formatted.
Maybe this is due to a timing problem?
I recall a similar behavior of some cards in Arduino.
Re: Pico Mounting SD Card
Here is a small test program that works for me:
The test program mounts the card under “/SD” in the Pico file system.
If there is no “/SD” folder, it is created.
After this, it lists the directory on the card, writes a test file and reads it back.
At last the card is unmounted.
Code: Select all
from machine import SPI, Pin
import uos
import sdcard
import time
sdfolder = "/SD"
def readfile(fname):
f = open(fname, 'r')
t = f.read()
f.close()
print(t)
def writefile(fname, text):
f = open(fname, 'w')
f.write(text)
f.close()
def mountsdcard(sdfolder):
create_mountpoint(sdfolder)
sd = sdcard.SDCard(SPI(1), Pin(9))
vfs = uos.VfsFat(sd)
uos.mount(vfs, sdfolder)
def create_mountpoint(sdfolder):
try:
print("Creating SD mountpoint " + sdfolder)
uos.mkdir(sdfolder)
except:
# remove trailing '/' before checking -> sdfolder[1:]
if sdfolder[1:] in uos.listdir("/"):
print ("Mountpoint already there: " + sdfolder)
else:
print("Could not create SD mountpoint + sdfolder")
mountsdcard(sdfolder)
l = uos.listdir(sdfolder)
print(l)
writefile(sdfolder + "/blah.txt", "Blahblah\npi = 3.14")
readfile(sdfolder + "/blah.txt")
uos.umount(sdfolder)
If there is no “/SD” folder, it is created.
After this, it lists the directory on the card, writes a test file and reads it back.
At last the card is unmounted.
Re: Pico Mounting SD Card
I am currently working on a set of tools that makes using an SD card easier.
There is an object defining the SD card with functions to mount, unmount, list files / folders etc.
The usage is like this:
And the class and functions definition is here (not ready, but in part already usable)
Feedback is welcome.
There is an object defining the SD card with functions to mount, unmount, list files / folders etc.
The usage is like this:
Code: Select all
if __name__ == "__main__":
sdfolder = "/SD" # (mountpoint)
SPIselect = 0 # 0/1 for SPI0 or SPI1
SD_CS = 5 # Chip select for SD (may be any GP pin)
sd = SD(SPIselect, SD_CS, sdfolder)
if sd.error:
print(sd.error)
else:
print("SD folder: ", sd.sdfolder)
l = sd.list_all()
print("Files and folders on SD: ", l)
l = sd.listfolders()
print("Folders on SD: ", l)
l = sd.listfiles()
print("Files on SD: ", l)
sd.unmount()
Code: Select all
import uos
import sdcard
from machine import SPI, Pin, UART, I2C
# ------------------------------------------------------------------------
# TOOLS
def is_folder(filename):
# True if folder
if uos.stat(filename)[0] & 0x4000:
return True
else:
return False
def is_file(filename):
# True if file, not folder
if uos.stat(filename)[0] & 0x8000:
return True
else:
return False
def list_folders(folder):
# list subfolders of folder
l = uos.listdir(folder)
folders = []
for f in l:
f = folder + '/' + f
if is_folder(f):
folders.append(f)
##folders = [f for f in l if is_folder(f)] ## this gives error if no folder there
return folders
def list_files(folder):
# list files in folder (subfolders excluded)
l = uos.listdir(folder)
files = []
for f in l:
f = folder + '/' + f
if is_file(f):
files.append(f)
#files = [f for f in l if is_file(f)]
return files
# ------------------------------------------------------------------------
# MAIN SD class, needs sdcard.py (driver)
class SD():
def __init__(self, SPIselect, SD_CS, sdfolder):
print("Defining SD")
self.SPIselect = SPIselect
self.SD_CS = SD_CS
self.sdfolder = sdfolder
self.error = ""
# define SD
try:
self.sd = sdcard.SDCard(SPI(SPIselect), Pin(SD_CS))
except OSError as e:
self.error = (str(e))
self.sd = None
except:
self.error = "SD card ERROR"
self.sd = None
# mount SD
self.mountsdcard()
def mountsdcard(self):
print("Mounting SD")
self._create_mountpoint()
try:
vfs = uos.VfsFat(self.sd)
uos.mount(vfs, self.sdfolder)
self.error = ""
except OSError as e:
if "EPERM" in str(e):
print("SD card already mounted!")
self.error = ""
else:
self.error += '\t' + "MOUNT ERROR"
except Exception:
self.error += '\t' + "MOUNT ERROR"
def _create_mountpoint(self):
# if sdfolder does not exist, create it (to use as mountpoint)
if (self.sdfolder in list_folders('/') == False):
print("Creating SD mountpoint " + sdfolder)
uos.mkdir(self.sdfolder)
def unmount(self):
print("Unmounting SD card")
uos.umount(self.sdfolder)
def list_all(self):
return uos.listdir(self.sdfolder)
def listfolders(self):
return list_folders(self.sdfolder)
def listfiles(self):
return list_files(self.sdfolder)
def readfile(fname):
f = open(fname, 'r')
t = f.read()
f.close()
return t
print(t)
def writefile(fname, text):
f = open( fname, 'a')
f.write(text + '\n')
f.close()
Re: Pico Mounting SD Card
That looks fine and useful. For comparison and ideas, you may also have a look at https://github.com/pfalcon/micropython-lib.git, folder upysh.
Re: Pico Mounting SD Card
Thanks Robert,
I had a look. Must confess that I did not understand everything, but it looks interesting.
Here is my more or less ready version of "filetools.py":
For me sd.print is especially interesting, as I can use it like print to Serial.
Also sd.error is a variable that I can use at any time to see if everything's right, especially if the sd card is mounted correctly.
Maybe sd.error should be updated also in sd.readfile or sd._write2file?
I had a look. Must confess that I did not understand everything, but it looks interesting.
Here is my more or less ready version of "filetools.py":
Code: Select all
''' filetools by jean-claude.feltes@education.lu
for working with SD card'''
import uos
import sdcard
from machine import SPI, Pin
# ------------------------------------------------------------------------
# FILE TOOLS
def is_folder(filename):
# True if folder
if uos.stat(filename)[0] & 0x4000:
return True
else:
return False
def is_file(filename):
# True if file, not folder
if uos.stat(filename)[0] & 0x8000:
return True
else:
return False
def list_folders(folder):
# list subfolders of folder
l = uos.listdir(folder)
folders = []
for f in l:
fi = folder + '/' + f
if is_folder(fi):
folders.append(f)
##folders = [f for f in l if is_folder(f)] ## this gives error if no folder there
return folders
def list_files(folder):
# list files in folder (subfolders excluded)
l = uos.listdir(folder)
files = []
for f in l:
fi = folder + '/' + f
if is_file(fi):
files.append(f)
#files = [f for f in l if is_file(f)]
return files
# ------------------------------------------------------------------------
# SD TOOLS
# MAIN SD class, needs sdcard.py (driver)
class SD():
def __init__(self, SPIselect, SD_CS, sdfolder):
print("Defining SD")
self.SPIselect = SPIselect
self.SD_CS = SD_CS
self.sdfolder = sdfolder
self.error = ""
# define SD
try:
self.sd = sdcard.SDCard(SPI(SPIselect), Pin(SD_CS))
except OSError as e:
self.error = (str(e))
self.sd = None
except:
self.error = "SD card ERROR"
self.sd = None
# mount SD
self.mountsdcard()
def mountsdcard(self):
print("Mounting SD")
self._create_mountpoint()
try:
vfs = uos.VfsFat(self.sd)
uos.mount(vfs, self.sdfolder)
self.error = ""
except OSError as e:
if "EPERM" in str(e):
print("SD card already mounted!")
self.error = ""
else:
self.error += '\t' + "MOUNT ERROR"
except Exception:
self.error += '\t' + "MOUNT ERROR"
def _create_mountpoint(self):
# if sdfolder does not exist, create it (to use as mountpoint)
if (self.sdfolder in list_folders('/') == False):
print("Creating SD mountpoint " + sdfolder)
uos.mkdir(self.sdfolder)
def unmount(self):
print("Unmounting SD card")
uos.umount(self.sdfolder)
def list_all(self):
return uos.listdir(self.sdfolder)
def listfolders(self):
return list_folders(self.sdfolder)
def listfiles(self):
return list_files(self.sdfolder)
def readfile(self, fname):
fname = self.sdfolder + '/' + fname
f = open(fname, 'r')
t = f.read()
f.close()
return t
def _write2file(self, fname, text, mode = 'a', end = '\n'):
# mode = 'a' (append) or 'w' (write)
fname = self.sdfolder + '/' + fname
f = open( fname, mode)
f.write(text + end)
f.close()
def writefile(self, fname, text):
# writes a new file to SD card
self._write2file(fname, text, mode = 'w')
def print(self, fname, text, end = '\n'):
# works like print, but to a file on the SD card
# appends text to file fname with line feed at the end
self._write2file(fname, text, mode = 'a', end = end)
#-----------------------------------------------------------------------------------
if __name__ == "__main__":
sdfolder = "/SD"
SPIselect = 0 # 0/1 for SPI0 or SPI1
SD_CS = 5 # Chip select for SD (may be any GP pin)
sd = SD(SPIselect, SD_CS, sdfolder)
if sd.error:
print(sd.error)
else:
print("SD folder: ", sd.sdfolder)
l = sd.list_all()
print("Files and folders on SD: ", l)
l = sd.listfolders()
print("Folders on SD: ", l)
l = sd.listfiles()
print("Files on SD: ", l)
t = 'Blahblah ghjghg pi'
sd.writefile('blah.txt', t)
t = "This is appended to the file"
sd.print('blah.txt', t)
sd.print('blah.txt', t)
t = sd.readfile('blah.txt')
print(t)
sd.unmount()
Also sd.error is a variable that I can use at any time to see if everything's right, especially if the sd card is mounted correctly.
Maybe sd.error should be updated also in sd.readfile or sd._write2file?