Правене на променливи постоянни след рестартиране на NodeMCU

Правя интелигентна домашна система с помощта на nodeMCU и трябва да съхранявам и извличам данни от модула. Използвах следната функция.

function save_settings(name,value)
  file.remove(name)
  file.open(name,"w+")
  file.writeline(value)
  file.close()
end

Работи, но е бавен и NodeMCU се срива, ако задействам горната функция бързо... Понякога се изисква FS формат, за да мога да го използвам отново.

Така че въпросът ми е: има ли друг начин да направя променливите постоянни между рестартирането?


person Suraj Bhawal    schedule 16.09.2015    source източник
comment
всяко записване вероятно изисква блок от флаш да бъде изтрит и пренаписан, което по своята същност е бавно. Нямам представа защо ще се срине, но може да е препълване на буфера за запис или опит за изтриване/записване на страница, докато същата операция вече се случва. И в двата случая решението може да бъде да буферирате данните в масив някъде и да пишете по-рядко. Ако това не е достатъчно добро, може да се наложи да пишете на SPI EEPROM или SD карта :(   -  person user1816847    schedule 04.10.2015
comment
@user1816847 Ithx за отговора, но това вече не е опция, защото вече направих специална печатна платка за проекта и в момента го използвам без функцията за запазване... Всичко, което мога да направя сега, е да внедря вкъщи функция за запазване на натоварване само чрез софтуер. .   -  person Suraj Bhawal    schedule 04.10.2015
comment
Бих препоръчал да премахнете file.remove(name), тъй като е излишен с file.open в този случай поради режима w+. Това може също да опрости работата, която FS трябва да върши, тъй като няма промяна във файловата таблица.   -  person Adam B    schedule 30.03.2016


Отговори (2)


Използвам най-новия фърмуер, 0.9.6-dev_20150704, плаващата версия (https://github.com/nodemcu/nodemcu-firmware/releases)

Първоначално завършването на този код отне 62-63 ms и изглежда добавя няколко части от милисекунда с всяко следващо изпълнение на кода, след няколкостотин изпълнения достигна до почти 100 ms. Никога не ми е забивал.

function save_setting(name, value)
  file.open(name, 'w') -- you don't need to do file.remove if you use the 'w' method of writing
  file.writeline(value)
  file.close()
end

function read_setting(name)
  if (file.open(name)~=nil) then
      result = string.sub(file.readline(), 1, -2) -- to remove newline character
      file.close()
      return true, result
  else
      return false, nil
  end
end

startTime = tmr.now()

test1 = 1200
test2 = 15.7
test3 = 75
test4 = 15000001
save_setting('test1', test1)
save_setting('test2', test2)
save_setting('test3', test3)
save_setting('test4', test4)

1exists, test1 = read_setting('test1')
2exists, test2 = read_setting('test2')
3exists, test3 = read_setting('test3')
4exists, test4 = read_setting('test4')

completeTime = (tmr.now()-startTime)/(1000)
print('time to complete (ms):')
print(tostring(completeTime))
person wordsforthewise    schedule 17.10.2015
comment
във функцията read_setting имате file.readline(value) - това вероятно трябва да е само file.readline(), тъй като стойността не трябва да съществува в този контекст. - person askvictor; 07.03.2016
comment
Освен това бих добавил проверка, за да видя дали извикването open() е успешно - ако върне нула, тогава функцията read_setting трябва да върне нула. - person askvictor; 07.03.2016
comment
по-кратка форма за премахване на нов ред е file.readline():match("[^\n]*") - person rodvlopes; 16.09.2017

Ако надстроите до по-нова версия (базирана на SDK 1.4.0), можете да използвате слотовете за памет rtcmem:

local offset = 10
local val = rtcmem.read32(offset, 1)
rtcmem.write32(offset, val + 1)

Документирано е, че този спомен продължава през цикъл на дълбок сън; Открих, че продължава както при нулиране на хардуер, така и при софтуер (но не и при циклично захранване.)

person Mark McGinty    schedule 19.04.2016
comment
Потребителят иска да продължи през цикъл на захранване, затова той пише във файл. - person ambassallo; 29.05.2016