Save to eeprom, while loop, Monotonic

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
rubble
 
Posts: 29
Joined: Fri Mar 14, 2014 5:46 am

Save to eeprom, while loop, Monotonic

Post by rubble »

I have built a LED light with a rotary encoder to change the colours. The colour change is working well but I want to save the last colour so when the light is turned off and back on the colour will be the last colour set.
I obviously don't want to write to the eeprom every time through the loop. I first tried with a counter but could never get it to work as the counter kept getting overwritten and other problems.
I am now using time.monotonic which is working except the rotary encoder stops working after the save. I am not sure the write to eeprom code is correct.
Please can somebody let me know what my problem is.

Tinket MO with external Adafruit eeprom module

After the write I am getting this error:
Traceback (most recent call last):
File "code.py", line 82, in <module>
File "adafruit_24lc32.py", line 142, in __setitem__
RuntimeError: EEPROM currently write protected.

Code: Select all

import board
import neopixel
import time
import adafruit_24lc32
from time import sleep

i2c = board.I2C()
countEnd = 33
ORDER = neopixel.GRB
pixel_pin = board.D1
num_pixels = 33

eeprom = adafruit_24lc32.EEPROM_I2C(i2c)
encoder = rotaryio.IncrementalEncoder(board.D3, board.D4)
eeprom_position = int.from_bytes(eeprom[0], (b"\x02\x00\x10\x00"))
encoder.position = 0
print("Value from eeprom")
print(eeprom_position)

PURPLE1 = (155, 48, 255)
SPRINGGREEN = (0, 255, 127)
SEAGREEN1 = (0, 255, 127)
CYAN = (0, 255, 255)
LIGHTGOLDENROD1 = (255, 236, 139)
AQUAMARINE = (127, 255, 212)
WHITE = (255, 255, 255)
DARKSALMON = (233, 150, 122)
LIGHTPINK = (255, 182, 193)
PALEVIOLETRED = (219, 112, 147)
LIGHTCORAL = (240, 128, 128)
MELON = (227, 168, 105)
chocolate1 = (255, 127, 36)
DarkOrange = (255, 140, 0)
DeepPink = (255, 20, 147)
DarkOrchid = (153, 50, 204)
RED = (255, 0, 0)

colours = [
    WHITE,
    LIGHTGOLDENROD1,
    RED,
    LIGHTPINK,
    DeepPink,
    DARKSALMON,
    PALEVIOLETRED,
    LIGHTCORAL,
    DarkOrchid,
    chocolate1,
    DarkOrange,
    SPRINGGREEN,
    SEAGREEN1,
    PURPLE1,
    CYAN,
    AQUAMARINE,
    MELON
]

pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
                           brightness=0.1, auto_write=False, pixel_order=ORDER)

last_position = None
count = 0
save_delay = 15
initial_time = time.monotonic()

while True:
    position = (encoder.position + eeprom_position) % len(colours)

    print("Value from encoder")
    print(encoder.position)
    print("Value from eeprom_position")
    print(eeprom_position)
    print("position")
    print(position)

    if last_position is None or position != last_position:
        print("Value from loop")
        print(eeprom_position)

        last_position = position
        eeprom[0] = position
        
        if type(colours[position]) is tuple:
            pixels.fill(colours[position])
        pixels.show()
        sleep(0.05)
# WORKS PROPELY DOWN TO HERE
# THIS IS THE WRITE TO EEPROM
        current_time = time.monotonic()
        if current_time - initial_time > save_delay:
            eeprom[0] = position
            eeprom.write_protected = False
            print(eeprom.write_protected)
            print(eeprom[0])
            eeprom.write_protected = True
            print(eeprom.write_protected)

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: Save to eeprom, while loop, Monotonic

Post by mikeysklar »

Are you able to run the eeprom simpletest example code? I'd like to confirm this works before going into your custom lighting code.

Code: Select all

import board
import adafruit_24lc32

i2c = board.I2C()
eeprom = adafruit_24lc32.EEPROM_I2C(i2c)

print("length: {}".format(len(eeprom)))

eeprom[0] = 4
print(eeprom[0])

while True:
    pass

User avatar
rubble
 
Posts: 29
Joined: Fri Mar 14, 2014 5:46 am

Re: Save to eeprom, while loop, Monotonic

Post by rubble »

I have uploaded the code and get this as a serial output:
Code stopped by auto-reload.
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
length: 4096
bytearray(b'\x04')

User avatar
rubble
 
Posts: 29
Joined: Fri Mar 14, 2014 5:46 am

Re: Save to eeprom, while loop, Monotonic

Post by rubble »

Easier code to work with?

Code: Select all

import board
import neopixel
import time
import adafruit_24lc32
from time import sleep

i2c = board.I2C()
countEnd = 33
ORDER = neopixel.GRB
pixel_pin = board.D1
num_pixels = 33

eeprom = adafruit_24lc32.EEPROM_I2C(i2c)
eeprom_position = int.from_bytes(eeprom[0], (b"\x02\x00\x10\x00"))
last_position = 0
position = 0

save_delay = 15
initial_time = time.monotonic()

while True:
    if last_position is None or position != last_position:
        current_time = time.monotonic()
        if current_time - initial_time > save_delay:
            eeprom[0] = position
            eeprom.write_protected = False
            print(eeprom.write_protected)
            print(eeprom[0])
            eeprom.write_protected = True
            print(eeprom.write_protected)
    position = 1

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: Save to eeprom, while loop, Monotonic

Post by mikeysklar »

Thank you for trying the example code. It is good to see that works.

Now what happens when you try to write a manual example of position data using the same example code.

The original code that you shared is failing on this line probably due to position being uninitialized or maybe due the format. You had indicated in the comments that the code was getting furhter to the current_time = time.monotonic(), but it is failing at the first eeprom[0] setting (line: 82):

Code: Select all

        last_position = position
        eeprom[0] = position

User avatar
rubble
 
Posts: 29
Joined: Fri Mar 14, 2014 5:46 am

Re: Save to eeprom, while loop, Monotonic

Post by rubble »

I tried changing line 82 to eeprom[0] = 6 and the program froze. It didn't freeze by putting it into the monotonic section but went very slowly and threw the same error.

I don't know what has gone wrong now but I will have to get back to where it dosen't freeze or go slowly.

Out of interest this code ( from a post above ):

Code: Select all

while True:
    if last_position is None or position != last_position:
        current_time = time.monotonic()
        if current_time - initial_time > save_delay:
            eeprom[0] = 1
            eeprom.write_protected = False
            print(eeprom.write_protected)
            print(eeprom[0])
            eeprom.write_protected = True
            print(eeprom.write_protected)
    position = 1
Output:
False
bytearray(b'\x01')
True
Traceback (most recent call last):
File "code.py", line 25, in <module>
File "adafruit_24lc32.py", line 142, in __setitem__
RuntimeError: EEPROM currently write protected.

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: Save to eeprom, while loop, Monotonic

Post by mikeysklar »

Since the demo program is successfully writing to the EEPROM. I would try creating a new file slowly bring different elements of your position program to the demo code to determine what combination is causing the eeprom to not be writable or hang the program.

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

Re: Save to eeprom, while loop, Monotonic

Post by neradoc »

rubble wrote: Out of interest this code ( from a post above ):

Code: Select all

while True:
    if last_position is None or position != last_position:
        current_time = time.monotonic()
        if current_time - initial_time > save_delay:
            eeprom[0] = 1
            eeprom.write_protected = False
            print(eeprom.write_protected)
            print(eeprom[0])
            eeprom.write_protected = True
            print(eeprom.write_protected)
    position = 1
Output:
False
bytearray(b'\x01')
True
Traceback (most recent call last):
File "code.py", line 25, in <module>
File "adafruit_24lc32.py", line 142, in __setitem__
RuntimeError: EEPROM currently write protected.
You try to write before disabling the write protection.
You have to do eeprom.write_protected = False before eeprom[0] = 1.
More precisely, the first time the loop runs, as you can see by the printout:
- eeprom[0] = 1 works because the EEPROM is not write protected.
- then you set the write protection mode to False. Prints: False.
- then you set it back to True. Prints: True.
- then you leave it in the write-protected state.
So the second time the loop runs, eeprom[0] = 1 fails.
Likewise in your original code, eeprom[0] = position line 82 will fail for the same reason.

You could also not use write_protected, it doesn't bring much to the table.

You have another major issue, your if current_time - initial_time > save_delay: test is not gonna do what you want. And you are going to write to the EEPROM every time the encoder position changes, because you don't change the value of "initial_time" in the loop, so basically once true, the test is always true.
You need to set initial_time = current_time.

Also eeprom_position = int.from_bytes(eeprom[0], (b"\x02\x00\x10\x00")) is incorrect, the second argument to from_bytes is the byte order: "big" or "little". Other values default to big (it probably shouldn't, but that's less code).

Here is a version that includes those fixes:
rotary_encoder_eeprom_v1.py
(1.97 KiB) Downloaded 7 times

User avatar
rubble
 
Posts: 29
Joined: Fri Mar 14, 2014 5:46 am

Re: Save to eeprom, while loop, Monotonic

Post by rubble »

Thank you both for the help and yes the code now works @neradoc

There seems to be something strange with the save but I will try and see what is happening as it is hard to see/explain.

I had/have problems finding information on the write to eeprom and went with the only example I found and assumed I needed to write protect. Out of interest is it writting to the same part of the eeprom every time?

Thank you for explaining what the problems were @neradoc
Working light
Working light
th__MG_2659.jpg (347.44 KiB) Viewed 78 times

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

Return to “Adafruit CircuitPython”