有没有办法在 Nodemcu ESP8266 上提高 LUA 中 SD 卡的写入速度?

如何解决有没有办法在 Nodemcu ESP8266 上提高 LUA 中 SD 卡的写入速度?

我能达到的最大写入速度是 2.4 KB/s。有没有办法增加这个?

在 NodeMCU ESP8266 和 User_Modules.h 中的 SPI 模块上使用 LUA。 #define BUILD_FATFS 也在 user_config.h 中启用。

我有一个数据记录器,每次采样 920SPS 或 ~1.1ms/Sample 10 小时。 1.1 毫秒应该是很多时间将两个字节写入 SD 卡或样本之间的 xxx 字节缓冲区,但是我看到的最大写入速度是 498 毫秒写入 1200 字节或 7 毫秒写入 3 字节。这与 12.5MB/s 的 SD class 0 标准相差甚远。当我将 1200 B 转储到卡中时,记录器最终丢失了大约 450 个样本。


local adc1 = nil
local t_tbl={}
local n=1

function adcReady(_,_,c)
    
    _,adctbl[n],_ = adc1:read()
    n=n+1
    if n>400 then
    
        t_tbl[1]=tmr.now()
        
        file.open("/SD0/sddata.txt","a")
        for k,v in ipairs(adctbl) do 
            file.write(v..",")
            adctbl[k]=nil
        end
        file.close()
        
        t_tbl[2]=tmr.now()
        
        print(t_tbl[2] - t_tbl[1])
        n=1
        
    end
end

do
    local adc = {
        ADC1_ID             =   0,ADC1_ADDRESS        =   ads1115.ADDR_GND,GAIN                =   ads1115.GAIN_4_096V,SAMPLES             =   ads1115.DR_920SPS,CHANNEL             =   ads1115.SINGLE_0,MODE                =   ads1115.CONTINUOUS,CONV_READY          =   ads1115.CONV_RDY_1,}
    i2c.setup(i2c0.id,i2c0.sda,i2c0.scl,i2c0.speed)
    ads1115.reset()
    adc1 = ads1115.ads1015(adc.ADC1_ID,adc.ADC1_ADDRESS)   
    adc1:setting(adc.GAIN,adc.SAMPLES,adc.CHANNEL,adc.MODE,adc.CONV_READY)  
    
    spi.setup(1,spi.MASTER,spi.CPOL_LOW,spi.CPHA_LOW,8,2,spi.HALFDUPLEX)
    vol = file.mount("/SD0",8)   -- 2nd parameter is optional for non-standard SS/CS pin
    file.open("/SD0/sddata.txt","w+")
    file.close()
    
    tmr.create():alarm(1000,tmr.ALARM_SINGLE,function()
        gpio.mode(i2c0.conv_rdy,gpio.INT) 
        gpio.trig(i2c0.conv_rdy,'up',adcReady) --enable interrupt,active low rising edge==conv ready  
    end)
end

解决方法

您可以通过准备 2KB 对齐的文本块来加速文件写入。
将您的 adcReady 替换为:

local log_text = ""
local chunk_size = 2*1024

function adcReady(_,_,c)
   _,adctbl[n],_ = adc1:read()
   n = n + 1
   if n > 400 then
   
      t_tbl[1] = tmr.now()
      
      log_text = log_text..table.concat(adctbl,",1,n-1)..","
      local size = #log_text - #log_text % chunk_size
      local log_text_to_save = log_text:sub(1,size)
      log_text = log_text:sub(size + 1)
      
      t_tbl[2] = tmr.now()
      
      if size ~= 0 then 
         file.open("/SD0/sddata.txt","a")
         file.write(log_text_to_save)
         file.close()
      end
      
      t_tbl[3] = tmr.now()
      
      print(t_tbl[2] - t_tbl[1],t_tbl[3] - t_tbl[2])  -- for strings and GC,for File operations
      n = 1
      
   end
end

是否快于 498 毫秒?


更新:

带有缓存 tostring() 的新版本

local num2str = {}

function adcReady(_,_ = adc1:read()
   n = n + 1
   if n > 400 then

      t_tbl[1] = tmr.now()

      for i = 1,n - 1 do
         local v = adctbl[i]
         local s = num2str[v]
         if not s then
            s = v..","
            num2str[v] = s
         end
         adctbl[i] = s
      end
      local log_text_to_save = table.concat(adctbl,"",n-1)

      t_tbl[2] = tmr.now()

      file.open("/SD0/sddata.txt","a")
      file.write(log_text_to_save)
      file.close()

      t_tbl[3] = tmr.now()

      print(t_tbl[2] - t_tbl[1],for File operations
      n = 1

   end
end

它比以前的版本快吗?


更新 2:

local chr = string.char

function adcReady(_,n - 1 do
         local v = adctbl[i]
         -- 0<=v<=4095
         local s
         if v < 10 then
            s = chr(v + 48,44)
         else
            local m10 = v % 10
            if v < 100 then
               s = chr((v - m10)/10 + 48,m10 + 48,44)
            else
               local m100 = v % 100
               if v < 1000 then
                  s = chr((v - m100)/10 + 48,(m100 - m10)/10 + 48,44)
               else
                  local m1000 = v % 1000
                  s = chr((v - m1000)/1000 + 48,(m1000 - m100)/100 + 48,44)
               end
            end
         end
         adctbl[i] = s
      end
      local log_text_to_save = table.concat(adctbl,for File operations
      n = 1

   end
end

更新 3:

对于 Lua 5.3 和日志中的十六进制数字:

-- log output is in hex
local high = {} -- [1] = "",[2] = "1",...,[256] = "FF"
local low = {}  -- [1] = "0,[2] = "1,[16] = "F,"
for x = 0,255 do  -- replace 255 with 127 (to save memory) if ADC generates only positive values 0x0000-0x7FF0
   high[x+1] = string.format("%X",x*16):sub(1,-2)
   if x < 16 then
      low[x+1] = string.format("%X,x)
   end
end

-- in case of out-of-memory error reduce measures count (400) to 256
local measures = 400   -- recommended values are powers of 2
local measures_2 = measures*2

-- adctbl[] is not used anymore,text_buffer[] is used instead
local text_buffer = {}  -- array of (2*measures) elements
for x = 1,measures_2 do
   text_buffer[x] = ""
end

function adcReady(_,c)
   local _,v = adc1:read()
   -- 0x0000<=v<=0xFFF0
   text_buffer[n] = high[(v>>8)+1]
   text_buffer[n+1] = low[((v>>4)&15)+1]
   n = n + 2
   if n > measures_2 then

      t_tbl[1] = tmr.now()

      local log_text_to_save = table.concat(text_buffer,for File operations
      n = 1

   end
end

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res