summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2022-05-26 10:18:18 +0200
committerDaniel Friesel <derf@finalrewind.org>2022-05-26 10:18:18 +0200
commit3aabcac3aa26b40b2712928b74e6bbfdf4f3efb4 (patch)
tree9866583efeb5bd7cd543d5efc688ce70322924c1
parent3f09903d71fd2e16d1702e21c1572269c67cb47b (diff)
Verify CRC when reading data
-rw-r--r--README.md1
-rw-r--r--sen5x.lua31
2 files changed, 32 insertions, 0 deletions
diff --git a/README.md b/README.md
index 8b38677..ccfcfed 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@ sen5x.lua has been tested with Lua 5.1 on NodeMCU firmware 3.0.1 (Release
202112300746, integer build). It requires the following modules.
* i2c
+* bit
The MQTT HomeAssistant integration in init.lua additionally needs the following
modules.
diff --git a/sen5x.lua b/sen5x.lua
index afc9970..13bd972 100644
--- a/sen5x.lua
+++ b/sen5x.lua
@@ -48,6 +48,9 @@ function sen5x.read()
end
local data = i2c.read(sen5x.bus_id, 24)
i2c.stop(sen5x.bus_id)
+ if not sen5x.crc_valid(data, 24) then
+ return false
+ end
sen5x.pm1 = sen5x.read_value(data, 1)
sen5x.pm2_5 = sen5x.read_value(data, 4)
sen5x.pm4 = sen5x.read_value(data, 7)
@@ -76,6 +79,9 @@ function sen5x.get_product()
end
local data = i2c.read(sen5x.bus_id, 48)
i2c.stop(sen5x.bus_id)
+ if not sen5x.crc_valid(data, 48) then
+ return false
+ end
local ret = ""
ret = ret .. string.sub(data, 1, 2)
ret = ret .. string.sub(data, 4, 5)
@@ -83,4 +89,29 @@ function sen5x.get_product()
return ret
end
+function sen5x.crc_word(data, index)
+ local crc = 0xff
+ for i = index, index+1 do
+ crc = bit.bxor(crc, string.byte(data, i))
+ for j = 8, 1, -1 do
+ if bit.isset(crc, 7) then
+ crc = bit.bxor(bit.lshift(crc, 1), 0x31)
+ else
+ crc = bit.lshift(crc, 1)
+ end
+ crc = bit.band(crc, 0xff)
+ end
+ end
+ return bit.band(crc, 0xff)
+end
+
+function sen5x.crc_valid(data, length)
+ for i = 1, length, 3 do
+ if sen5x.crc_word(data, i) ~= string.byte(data, i+2) then
+ return false
+ end
+ end
+ return true
+end
+
return sen5x