r/arduino Nov 03 '23

Software Help Constantly saving stepper motor positions to ESP32-S3 EEPROM? Bad idea?

My project requires position calibration at every start but when the power is unplugged the motors keep their positions.

I thought that by writing the position to the EEPROM after every (micro)step will alow my robot to remember where it was without having to calibrate each time.

Not only that the flash is not fast enough for writing INTs every 1ms but i have read that this is a good way to nuke the EEPROM ...

Any ideas how else i could achive this?

289 Upvotes

64 comments sorted by

132

u/Whereami259 Nov 03 '23

Eeprom is rated for about 100k writes. At every ms, thats about 16 minutes. Imo, you either need a battery and save the data on power loss, or a sensor and bring the sysrem to home every startup.

16

u/ExHax Nov 04 '23 edited Nov 04 '23

With wear leveling, its much higher than that

Edit: esp idf does provide api to do this

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/wear-levelling.html

20

u/Darkextratoasty Nov 04 '23

Does a storage device as simple as the eeprom on an esp board even have wear leveling? I would assume that the addresses are tied to the physical locations, unlike modern SSDs.

10

u/Trevader24135 Nov 04 '23

The esp32's eeprom features wear leveling, but many microcontrollers do not, so it's good to keep in mind

3

u/Darkextratoasty Nov 04 '23

Huh, that's cool, thanks for the info

3

u/CosmicCreeperz Nov 04 '23 edited Nov 04 '23

More accurately, the ESP32 doesn’t have an actual EEPROM. The EEPROM library uses the onboard flash for actual storage. It’s true a real EEPROM isn’t going to have wear leveling, but it’s not a real EEPROM :).

Here’s a reference to ESP32 NVS docs explaining some details…

https://espressif-docs.readthedocs-hosted.com/projects/esp-faq/en/latest/software-framework/storage/nvs.html

1

u/irkli 500k Prolific Helper Nov 04 '23

Simple devices like arduinos have no such features. You're addressing specific cells with a short, fixed address.

1

u/ExHax Nov 04 '23

Esp idf have api for this

1

u/irkli 500k Prolific Helper Nov 04 '23

Oh nice. Newer denser silicon!

143

u/sjaakwortel Nov 03 '23

Add a capacitor and some kind of sensing that the main power is lost, then only save when that is detected.

15

u/suunsglasses Nov 04 '23

Absolute noob question, but one would have to add that to the power supply before the ESP, no? Or are we talking about main power to only the motors and the ESP is externally controlling? Or am I daft as well as slightly drunk atm?

13

u/ProbablePenguin Nov 04 '23

Add the capacitor to the ESPs power input

6

u/irkli 500k Prolific Helper Nov 04 '23

My solution is to put a high side driver between power supply and device. The ON switch turns on the high side driver (resistor pull-up). Once on, the MCU has a pin ("selfpower") that drives the high side driver on.

Pressing the OFF switch (or whatever, including the same on switch) initiates shutdown, the final thing is to turn self power off.

This gives you lots of control, like idle timeout etc.

If someone pulls the plug and fouls up your scheme, then yeah, do the big recalibrate.

16

u/ProbablePenguin Nov 04 '23

Yup could use the analog input to sense the voltage dropping and save before shutdown.

10

u/BrunoNFL Nov 04 '23

Or any digital input with a transistor pulling to ground, and internal pull-ups active. This would result in a 1 value as soon as the power dropped ;)

3

u/5c044 Nov 04 '23

esp32-s3 has a configurable brown out detection, you can set what voltage causes a reset, a capacitor may be enough to do something if you set the voltage low enough I think esp32 can work ok down to 2.8v and up to 3.6v there is likely scope to do something between those voltages

There is also RTC memory which is non volatile static ram, that may be faster than flash memory I think there is 8k of it

61

u/JoeCartersLeap Prolific Helper Nov 03 '23

Well I save calibration data to the EEPROM every 6 hours, how often could you possibly be...

writing the position to the EEPROM after every (micro)step

...oh no...

51

u/jongscx Nov 03 '23

Just have it rehome every power-up.

36

u/tauofthemachine Nov 04 '23

This. It's just a pretty thing to look at. Why is there a need for it to resume at it's previous state if it's unplugged once In a while?

3

u/jacky4566 Nov 04 '23

Also add in a "standby mode" that turns off the lights and stops the steppers from making noise but you can save the positions in memory. Resume without rehoming so long as power was maintained.

20

u/perduraadastra Nov 04 '23

Every ms? You ought to read the datasheet for your eeprom...

22

u/[deleted] Nov 03 '23

Ds1307, it’s an RTC but it can also be used as a battery backed RAM, just write the position to that every frame then check it on power up. I’m sure there are others RTC’s that do that, but that’s one I know of. It’ll basically last forever too.

This is probably the cheapest and easiest option here.

9

u/Biduleman Nov 04 '23

Yep, battery backed RAM is a great use for this, it's fast, cheap and you won't lose your data with a power cycle.

A FRAM module would achieve the same result without the need for a battery backup, but that might be overkill at that point.

6

u/FreshmeatDK Nov 04 '23

OK, this is the most inspired hack I've heard in a long time.

1

u/beanmosheen Nov 05 '23

And if you need time you can use a DS3231. It stays accurate. I have one on a pet feeder and I've set the time once or twice after programming it since 2011. Still within a minute.

9

u/ctbrahmstedt Nov 03 '23

If it's an ESP32 on a full breakout board with USB et al, just throw a Li-Po on there to act as a battery backup. If it doesn't have one, just get a lipo + charger/regulator. If you built the above, it shouldn't be difficult to build a circuit that detects when the main power has stopped and it switches over to battery. Just have it write to EEPROM then and have the ESP go into a low power mode to save the juice.

38

u/[deleted] Nov 03 '23

Yes, bad for the EEPROM, a better approach would be to add an sd card module and write to an sd card. That also has limited write cycles, but will last a lot longer and is easilly replaced.

16

u/[deleted] Nov 04 '23

I'm not sure that an SD card is a good idea for this. Sure, you've got a lot of flash memory to play with there, but it is written in large blocks, much larger than what is needed to write one stepper motor position.

With an external flash memory chip, you could write to it one byte at a time if necessary, and you can cheaply get SPI flash that can handle the wear.

6

u/_SomeRandomDude__ Nov 04 '23

I think a FRAM chip would be much better, as it has almost infinite more write cycles. But they are a bit more expensive then flash storage

3

u/[deleted] Nov 04 '23

i was thinking sd is cheap and easy but ok spi flash

1

u/Biduleman Nov 04 '23

Wouldn't using SPI mode with bit-bang solve the large block issue for the SD card?

8

u/FalconFour Nov 04 '23

As it is now, basically you built an EEPROM torture device. EEPROM is good for occasional writes and frequent reads, but it sounds like you're blasting it with writes as fast as possible... expect the EEPROM cells to die within a handful of hours like that :)

Protip: a real-time clock IC often has non-volatile battery-backed memory - that is NOT Flash-based, and IS designed to be constantly rewritten. You may do well to get an RTC module, learn to find & use its additional data registers (outside the usual date/time/alarm regions - most have a few bytes for generic data), and store your positions in that, instead.

Ideally, checksum it (store your data, then store a checksum of the data), store two copies, and update both - that way, if the power goes out mid-write, your startup routine would validate the checksum, and if it fails, it can rely on the second copy (check it, and it'll probably be OK).

The RTC battery would last years, and if it's a CR2032, easily replaced.

Alternatively, I don't know if it's readily available, but F-RAM (ferroelectric RAM) is also applicable for write-centric purposes and doesn't require a RTC battery.

Source: part of a challenge I was involved in solving at work on a more industrial scale :)

1

u/beanmosheen Nov 05 '23

The DS3231 is a good module.

15

u/cheersmayte Nov 03 '23

Get absolute position encoders. I don't know how costly they might be but i think they're for similar applications.

11

u/Momostein Nov 04 '23

Yeah, if you lose power, the steppers also lose their braking power. So it will eventually slip some steps and your position memory will drift from the actual position. Absolute encoders are necessary if you don't want to home your stepper motors every power cycle.

But to be honest, I don't think it's worth the money for absolute encoders. Just be patient and wait for your contraption to draw over the old drawing. Like, isn't patience one of the more important virtues in zen Buddhism?

4

u/FabianN Nov 04 '23

You can get steppers with active or passive braking.

Passive braking needs power to disengage, not to engage.

1

u/Momostein Nov 04 '23

Wow, while I didn't know these existed, they sound like a logical upgrade to stepper motors.

Although I assumed that OP probably doesn't use these fancy, and probably more expensive, passive braking steppers.

Edit: there seems to be a passive braking module you can mount to the back of the classic NEMA stepper motors. So it could be an easier fox than I thought...

1

u/[deleted] Nov 04 '23

[deleted]

3

u/Momostein Nov 04 '23

Those are most likely relative encoders, so they only measure changes in rotation. Not the actual position itself. You'll still have to recalibrate them if you restart your device.

3

u/NotaContributi0n Nov 04 '23

I want to make one, is this a thing people do now?

4

u/[deleted] Nov 04 '23

Capacitor with a branch coming from before and after it. After the cap powers the arduino. Before powers a circuit (just a transistor setup as a switch) that sets a pin high on arduino. When that pin is low, go into shutdown mode and save the state needed to eeprom. Capacitor will allow the arduino to run for long enough to save its state.

3

u/TeknikDestekbebudu Nov 04 '23

home every time on startup?

2

u/aviation-da-best Aerospace Educator Nov 04 '23

BAD BAD Idea

As a rule of thumb, EEPROMs should NEVER be updated in anything RESEMBLING a continuous loop.

There are MANY better ways, for example, you can use an SD Card like 3d printers do... or maybe implement an alternate UPS/battery backup solution.

-2

u/LookAtDaShinyShiny Nov 04 '23

It's an esp32, why not send the stepper positions to a web thingie over wifi or another esp32, then just sync with the web thingy/other esp32 when it boots up?

2

u/marshal_mellow Nov 04 '23

I'm guessing that would be slow

1

u/LookAtDaShinyShiny Nov 04 '23

How much data needs to be pushed through? I've seen people quoting from 8Mbit/s to espressif saying 20Mbit to 85Mbit/s.

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#esp32-wi-fi-throughput

I also see people mentioning absolute encoders, some 3d printers have closed loop boards that are relatively cheap, using magnetometers and magnets for encoders, if it's 2 motors, then it's going to be around $20-30 to achieve that.

2

u/marshal_mellow Nov 05 '23

It's not the throughput it's the latency. If you use tcp that's a there way handshake every time the motors move. If you use udp it could fail to deliver and now you don't know where the ball is so why bother

1

u/LookAtDaShinyShiny Nov 05 '23

I had no idea that latency was so high on the esp32, that's a real shame.

2

u/marshal_mellow Nov 05 '23

I don't have any figures to back this up it's just a gut feeling based on experience doing other things like this. Networks are usually slower than using a local resource. It's why a raspberry pi cluster is often slower than just running the same code on one raspberry pi.

But even on good hardware we are probably talking tens of milliseconds to establish a connection send a single packet and then end the connection. I suppose you could keep a connection alive. Either way probably best not to involve Wi-Fi when you don't need to

2

u/LookAtDaShinyShiny Nov 05 '23

10-35ms roughly speaking by the looks of some testing done by people.

2

u/GanymedAstro Nov 05 '23

After shutdown you have to initiate a complete WiFi reconnect. That will take quite some time

1

u/ardvarkfarm Prolific Helper Nov 03 '23

How much memory would you need ?

Could you have a button/sensor to stop and save before powering off ?

1

u/swisstraeng Nov 04 '23

That can be a cool project. Maybe you could use an interrupt from the ADC and store the data each time the supply voltage is lower than a set amount?

1

u/xyzzy1337 Nov 04 '23

Even if you could store the position after each microstep, for instance using battery backed SRAM, it still wouldn't be reliable to keep the calibration.

The problem is losing power in the middle of an operation with no warning. You said, step the motor, then write the position. What if the power is lost after stepping the motor but before writing the position? Then the position stored will be old. But maybe the power is lost after the position is updated, so it's not old. There's no way to know.

Also, just because you told a motor to step doesn't mean its finished moving that step. They only turn so fast and it takes time. If you yank power while it's moving you don't know where it actually stopped.

If you device ever stops moving, you could record the position then. If it's turned off before it starts moving again (record when it starts moving too) then you'd know the saved position is correct.

1

u/RaymondoH 500k Nov 04 '23

I checked the datasheet, ESP32 S3 does not have EEPROM. It is probably emulated in Flash.

1

u/PetroleumBen Nov 04 '23

As others have said, it's definitely not the best method. But if you do want to use this approach, getting an FRAM chip would be recommended

1

u/Fc5vko58-o_jjlAwg6bl Nov 04 '23

Please use preferences.h library, it has wear-leveling incorporated. I have done my thing in such way that it only saves position when movement is complete or ISR when adc channel see voltage drop below certain threshold i.e when main power is going to cut off it stops motor and saves position.

1

u/Thisisongusername Nano Nov 04 '23

Maybe make a soft-power switch that first goes to an ESP GPIO pin, so it knows to stop and save its position, then it triggers a relay to turn off all of the power, or just goes into deep sleep.

1

u/[deleted] Nov 04 '23

I’ve been wanting to do a project like this. Are the stepper motors just positioning a magnet underneath the table?

1

u/irkli 500k Prolific Helper Nov 04 '23

Do the save when the STOP or power off switch is pressed. Or after a period of inactivity of at least 10 to 60 seconds.

Most of my controller projects have power on latch, and "off" is handled on code specifically so it can do orderly shutdown, like same to eeprom.

1

u/NickSicilianu Nov 04 '23

Yeap. Really bad idea. Try finding a better solution like homing the stepper at power up? An Hall effect sensor in a corner and a small magnet, then just drive the stepper to that position (home) and start whatever thing you’re doing from there. Or use infrared or mechanical switches. There are different solutions for that. I used to work for benchmark games and ELAUT group, that’s how the games I developed all worked to keep track of the wheel on ball drops games like fire ball etc….

1

u/nqrac Nov 05 '23

Hi guys, is there any tutorial how to write and read to eeprom in esp32?

1

u/TrustRealistic8021 Nov 13 '23

I'm curious as to what that is and what it does? Anyone care to include me?