How to write from a file to FRAM with QT PY

CircuitPython on hardware including Adafruit's boards, and CircuitPython libraries using Blinka on host computers.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
Porter84
 
Posts: 2
Joined: Sun May 15, 2022 5:38 pm

How to write from a file to FRAM with QT PY

Post by Porter84 »

There are probably easier setups like using a Pi, but this is what I have. Hopefully this is an acceptable and efficient way to ask for some guidance & pointers to where to find the information I am looking for.

I know nothing of Python and have been going in circles trying to read up on where to start with this little project.

Overview of what I want to do/learn:
  • How can I read a binary file into CircuitPython and write to fram?
    I'm trying to read out a range of bytes into binary files and write other files into those byte ranges within the fram.
My understanding of items to learn/solve to make this happen:
  • Understand how to read a file into Python
    Understand how to write binary data out to a file
    Can I write a binary file directly to fram? akin using dd?
    Understand how to read from & write to fram
    Understand what formatting is happening with the print statements

As a first step/test I followed the example from Adafruit and just tweaked it to write a range of bytes into an array and from that array into fram, then to write directly to fram to verify my understanding of those functions.

Code: Select all

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import board
import busio
import adafruit_fram

i2c = busio.I2C(board.SCL, board.SDA)
fram = adafruit_fram.FRAM_I2C(i2c)

## Method 1 - Assigning values this way results in a readable print

FileBytes1=bytearray(10)
FileBytes1[0] = 0x31
FileBytes1[1] = 0x32
FileBytes1[2] = 0x33
FileBytes1[3] = 0x34
FileBytes1[4] = 0x35
FileBytes1[5] = 0x36
FileBytes1[6] = 0x37
FileBytes1[7] = 0x38
FileBytes1[8] = 0x39
FileBytes1[9] = 0x41

## Method 2 - Assigning values this way results in a different printed format
FileBytes2 = [0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41]

fram[0:9] = FileBytes1
fram[10:19] = FileBytes2

## Setting fram values directly prints the same 

fram[20] = 0x31
fram[21] = 0x32
fram[22] = 0x33
fram[23] = 0x34
fram[24] = 0x35
fram[25] = 0x36
fram[26] = 0x37
fram[27] = 0x38
fram[28] = 0x39
fram[29] = 0x41

fram[30:39] = [0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41]

## taken from example to fill the range with random values.  Range makes sense, but list just pulls sequential numbers? 
## from where and why do they print differently if I print the variable or the Fram after it's copied?
listvalues = list(range(20))
fram[40:59]=listvalues

print("")
print(FileBytes1)
print("Method 1 Var printed")
print("")
print(fram[0:9])
print("Method 1 Var to Fram Printed")
print("")
print(FileBytes2)
print("Method 2 Var printed")
print("")
print(fram[10:19])
print("Method 2 Var to Fram Printed")
print("")
print(fram[20:29])
print("Direct to Fram 1 Printed")
print("")
print(fram[30:39])
print("Direct to Fram 2 Printed")
print("")
print(listvalues)
print("listvalue Var Printed")
print("")
print(fram[40:59])
print("random list in Fram Printed")

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:

bytearray(b'123456789A')
Method 1 Var printed

bytearray(b'123456789')
Method 1 Var to Fram Printed

[49, 50, 51, 52, 53, 54, 55, 56, 57, 65]
Method 2 Var printed

bytearray(b'123456789')
Method 2 Var to Fram Printed

bytearray(b'123456789')
Direct to Fram 1 Printed

bytearray(b'123456789')
Direct to Fram 2 Printed

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
listvalue Var Printed

bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12')
random list in Fram Printed

Code done running.

User avatar
Porter84
 
Posts: 2
Joined: Sun May 15, 2022 5:38 pm

Re: How to write from a file to FRAM with QT PY

Post by Porter84 »

I think a place to read to understand why the print is different in some cases may be explainable with how the Variable is defined/created. I'll Try to do some reading on this soon.

This is just for my understanding, but the hurdle that is holding up any real progress is understanding how to bring in/push out raw data in Hexidecimal (enlighten me if this isn't the best way to describe the way want to handle that data.

User avatar
neradoc
 
Posts: 542
Joined: Wed Apr 27, 2016 2:38 pm

Re: How to write from a file to FRAM with QT PY

Post by neradoc »

Hi, you're correct, a list and a bytearray are not the same data type.

FileBytes1 is a bytearray, which contains bytes (values from 0 to 255).
You can read or assign each index by position, but you can only assign a 0-255 value: FileBytes1[0] = 0x55
FileBytes2 is a list of integers (int), which can take any int value.
You can read and assign any int value.

Here's the python reference to bytes types.
Note that for space reasons Circuitpython doesn't support functions like bytes.fromhex().
It does support int.to_bytes()

The bytearray representation bytearray(b'123456789') uses the bytes string representation.
They are displayed similar to regular strings, where bytes that match a character are shown as a character, and bytes that don't are shown as an escape sequence.

Code: Select all

>>> print(b"\x01\x20\x40\x60")
b'\x01 @`'
You can convert between bytes, bytearrays and lists of ints.
The [a:b] notation is called a slice. You can assign a slice to an iterable of the same length (with a compatible type of content).
Here are a few examples:

Code: Select all

FileBytes1 = bytearray(b"0123456789")
FileBytes1[0:2] = b"AB" # this is a bytes string, the read-only version of the bytearray
FileBytes1[0:2] = bytes([97, 98]) # another way to make a bytes string
FileBytes1[2:4] = bytearray([0x70, 0x72]) # bytearray
FileBytes1[6:8] = [0x65, 0x66] # list of ints, ints must be 0-255
FileBytes1[8:10] = b"ABCDEFGH"[4:6] # slice to slice (same size)
FileBytes1[4:7] = [0x55] * 3 # [0x55] * 3 is [0x55, 0x55, 0x55]
fram is an interface for the I2C communication with the device, but it behaves like a bytearray.

Code: Select all

FileBytes2 = bytes([0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41]) # same as b'123456789A'
fram[0:10] = FileBytes2
Here is a bit of code that reads a binary file and writes it to fram (it doesn't check for size).

Code: Select all

with open("filename.dat", "rb") as file:
    data = file.read()
    fram[0:len(data)] = data

Locked
Please be positive and constructive with your questions and comments.

Return to “Adafruit CircuitPython”