2

I'm using the Adafruit I2C FRAM breakout board with my Nano and it works as advertised, but every time I write a variable to this thing I have to use library function calls with addressing. This makes it run slower than I want it to, especially since I'm using the memory to keep camera pixel information and I need to process it quickly.

As user Majenko put it:

A write of a single byte requires 4 bytes in a transaction. That's 4 bytes, 1 start, 4 ack and 1 stop bit. So (4x8)+1+4+1 = 38 bits.

A read of a single byte, with "repeated start", requires 5 bytes per transaction, with 2 start, 4 acks, 1 nack and 1 stop. That's (5*8)+2+4+1+1 = 48 bits.

So for a read and write it's 38+48 = 86 bits.

Therefore you'd require 86*512 I2C clock cycles to transfer all 512 bytes in both directions - that's 44032 clock cycles.

At 400,000 bits per second it is 44032/400000 = 0.11 seconds, or 110ms of the time spend transferring data, not counting the time it takes to actually process and prepare the data, fill registers, look for status flags, etc.

If it is taking half a second then at 400,000 bits per second you have 44032 / (400000/2) * 100 = 22% of the time it's actually transmitting or receiving data over I2C.

It's much faster to write entire arrays at a time, but I need to write the data int-by-int as the data is encountered, since my whole reason for using the breakout board was to avoid needing local buffer space.

So is it possible to somehow configure this so that my I2C bus writes to the FRAM memory autonomously just like it does with the stack/heap in the onboard SRAM memory? Because then I could just declare my arrays as normal and let the processor take care of it, and then I would be so happy.

2
  • Have you looked into FRAM with an SPI interface, which may be capable of higher transfer speeds than I2C? Aug 30, 2017 at 1:07
  • Thanks. Yes I have, but the small difference is only in write and read speed. 75% of the time I'm spending is actually taking care of the bookkeeping. Also, I'm already Using my SPI pins for an LCD screen. Aug 30, 2017 at 1:51

3 Answers 3

2

No, you can't use SPI or I2C memories to store stack or heap data in AVR microcontrollers, as the AVR MCUs do not allow to map memories connected to the SPI or I2C buses. In other words, there is no way to tell the MCU that you connected a SPI or I2C memory, and how to use it, automatically. Therefore you can only use such memories to manually store/read data, by manually issuing all the correct command sequences, which will be very slow (as you wrote you are already doing by calling some libary functions).

Instead, you can use an external PARALLEL memory, connected to the external memory bus, which is present on SOME AVR microcontrollers (unfortunately, the ATMEGA328 has no external memory bus). Still you'll get a much slower performance with respect to the internal memory.

Finally, Arduino is not a good platform to process (or store/read) pixel data from a camera, due to severe computing power and memory limits. Even if there are more powerful Arduino (or Arduino-compatible) boards, which feature much more powerful processors (e.g. Cortex M3 or M4), you would probably need to program them using a very optimized C (and not C++!) code, or even ASM. But at this point, there would no reasons to use an Arduino-compatible platform, instead of an another one, possibly much more powerful or even cheaper.

3
  • There's nothing wrong with using C++ for this application provided the C++ libraries used are non-terrible. Aug 30, 2017 at 16:50
  • @IgnacioVazquez-Abrams for this application, using a powerful MCU with a good amount of RAM, yes. For a "tiny" MCU, you should save as many resources as possible. (besides, many - not all - Arduino C++ libraries are unfortunately terrible..)
    – next-hack
    Aug 30, 2017 at 16:55
  • Thanks, @next-hack. If I really have to, I'll just move up to a Mega and make my device larger (not happy about this). Arduino is fine for this particular camera application, since It's only a monochromatic linear CCD with just 128 pixels. It actually worked pretty great until I added more peripherals and started to run out of volatile memory. Aug 30, 2017 at 20:46
1

Yes it is possible to have c variables use external RAM. The Atmel AVR FAQ discusses this. It's also possible to have the heap and stack (not recommended but possible), use external RAM.

Bear in mind that having this dealt with autonomously is still going to take roughly the same amount of time as it's going to have to execute similar functions to the ones you list above, albeit without having to code the transactions.

Have you considered a mega, and cache 1-6k of data then transfer that all at once. Using SPI would be faster, even more so with 1-6k. You can have an SPI LCD and RAM off the same pins, they just need an additional digital pin for the second device.

2
  • 2
    The "external RAM" discussed in that FAQ requires an actual external memory bus such as found on the ATmega64. There is no chance that it will work with a Nano, and certainly not over I2C. Aug 30, 2017 at 16:49
  • Not even on SPI.
    – next-hack
    Aug 30, 2017 at 17:00
0

I don't have experience with FRAM, but below are some results with SRAM: 23LC1024 (128 KB SRAM with SPI). Tests have been performed with an Arduino Uno.

(I had to use an answer instead of a comment because of the (screenshot) table alignment.

As you can see, write/read of a page (32 bytes) is faster than other types, but it depends on the amount of bytes you have to write to use pages.

(Because I want to use reasonable complex structures, I decided to go for a microcontroller with more RAM because stack and heap space cannot be used from external SRAM).

Speed tests

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.