main
Norman Köhring 4 months ago
commit e6e0d5e633

@ -0,0 +1,13 @@
# Info Display
This Deno application transforms (resizes and dithers) and image and sends the image to Waveshare's E-Paper ESP32 driver board. For it to work, you need the original wifi example code to be loaded on the board. The code is derived from the wifi example web app, but specialized for the Waveshare 7.5 V2 monochrome display.
## Usage
```sh
# just send the image to the display
deno --allow-read --allow-net main.ts /path/to/original/image
# store dithered image on disk, before sending
deno --allow-read --allow-write --allow-net main.ts /path/to/original/image /path/to/output.image
```

@ -0,0 +1,5 @@
{
"tasks": {
"dev": "deno run --watch main.ts"
}
}

@ -0,0 +1,583 @@
{
"version": "2",
"remote": {
"https://deno.land/std@0.176.0/fmt/colors.ts": "938c5d44d889fb82eff6c358bea8baa7e85950a16c9f6dae3ec3a7a729164471",
"https://deno.land/std@0.176.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea",
"https://deno.land/std@0.176.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7",
"https://deno.land/std@0.176.0/testing/asserts.ts": "984ab0bfb3faeed92ffaa3a6b06536c66811185328c5dd146257c702c41b01ab"
},
"npm": {
"specifiers": {
"jimp@0.22.8": "jimp@0.22.8_@jimp+custom@0.22.8"
},
"packages": {
"@jimp/bmp@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-JEMKgM1AEvvWfn9ZCHn62nK+QCE3Pb/ZhPdL3NF0ZgKNww6pqOmo6KqXzqY18JLB7c0epuTp4GPDPDhOh/ou1g==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8",
"bmp-js": "bmp-js@0.1.0"
}
},
"@jimp/core@0.22.8": {
"integrity": "sha512-vkN28aFikzQieA6bGxN+qe20pseCAemCyUI0YmRkJIArlb6OujtAwWAKyokv2lylV56bq8EQGIz+Y30OXUnRqg==",
"dependencies": {
"@jimp/utils": "@jimp/utils@0.22.8",
"any-base": "any-base@1.1.0",
"buffer": "buffer@5.7.1",
"exif-parser": "exif-parser@0.1.12",
"file-type": "file-type@16.5.4",
"isomorphic-fetch": "isomorphic-fetch@3.0.0",
"mkdirp": "mkdirp@2.1.6",
"pixelmatch": "pixelmatch@4.0.2",
"tinycolor2": "tinycolor2@1.6.0"
}
},
"@jimp/custom@0.22.8": {
"integrity": "sha512-u6lP9x/HNeGHB0Oojv4c2mhuDvn7G0ikzYbK4IKLsH4HzHxt62faMjBzQMcFhKJhR6UiiKE/jiHrhGvBT/fMkw==",
"dependencies": {
"@jimp/core": "@jimp/core@0.22.8"
}
},
"@jimp/gif@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-I0l6koS67IPU40RPxCJTD1NvePEd8vUIHTejx1ly0jrjGnumbqdarAlBUkDrKfPPc+Fnqp84hBbSN1w5hNPT6w==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8",
"gifwrap": "gifwrap@0.9.4",
"omggif": "omggif@1.0.10"
}
},
"@jimp/jpeg@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-hLXrQ7/0QiUhAVAF10dfGCSq3hvyqjKltlpu/87b3wqMDKe9KdvhX1AJHiUUrAbJv1fAcnOmQGTyXGuySa1D6A==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8",
"jpeg-js": "jpeg-js@0.4.4"
}
},
"@jimp/plugin-blit@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-rQ19txVCKIwo74HtgFodFt4//0ATPCJK+f24riqzb+nx+1JaOo1xRvpJqg4moirHwKR2fhwdDxmY7KX20kCeYA==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-blur@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-GWbNK3YW6k2EKiGJdpAFEr0jezPBtiVxj2wG/lCPuWJz7KmzSSN99hQjIy73xQxoBCRdALfJlkhe3leFNRueSQ==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-circle@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-qPCw8XFW8opT89ciFDuvs+eB3EB1mZIJWVajD2qAlprHiE7YGr34TkM7N5MNr3qZ1pJgkYdW6+HbBrJwBaonqw==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-color@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-ogkbg6rpDVH/mMLgAQKg17z3oZE0VN7ZWxNoH12fUHchqKz1I57zpa65fxZe2I8T5Xz97HR3x+7V7oI8qQGdSA==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8",
"tinycolor2": "tinycolor2@1.6.0"
}
},
"@jimp/plugin-contain@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-scale@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8": {
"integrity": "sha512-oiaPLdJt9Dk+XEEhM/OU3lFemM51mA9NgMCAdburSCjDzKacJYBGFSHjTOhXzcxOie/ZDpOYN/UzFGKy8Dgl9A==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-blit": "@jimp/plugin-blit@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-resize": "@jimp/plugin-resize@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-scale": "@jimp/plugin-scale@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-cover@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-scale@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8": {
"integrity": "sha512-mO68w1m/LhfuHU8LKHY05a4/hhWnY4t+T+8JCw9t+5yfzA4+LofBZZKtFtWgwf/QGe1y3X2rtUU/avAzDUKyyA==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-crop": "@jimp/plugin-crop@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-resize": "@jimp/plugin-resize@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-scale": "@jimp/plugin-scale@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-crop@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-ns4oH0h0gezYsbuH8RThcMLY5uTLk/vnqOVjWCehMHEzxi0DHMWCmpcb6bC//vJ+XFNhtVGn1ALN7+ROmPrj+A==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-displace@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-Cj8nHYgsdFynOIx3dbbiVwRuZn3xO+RVfwkTRy0JBye+K2AU8SQJS+hSFNMQFTZt5djivh6kh0TzvR/6LkOd1w==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-dither@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-oE0Us/6bEgrgEg56plU3jSBzvB9iGhweKUHmxYMWnQbFCHP4mNCtPAs8+Fmq6c+m98ZgBgRcrJTnC7lphHkGyw==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-fisheye@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-bWvYY/nfMcKclWEaRyAir+YsT6C5St823HUQAsewZowTrJmme+w4U2a6InsryTHUL01BBcV5BLH0aDHuV3StvA==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-flip@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-rotate@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-blit@0.22.8___@jimp+custom@0.22.8__@jimp+plugin-crop@0.22.8___@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8": {
"integrity": "sha512-0NFTNzjsdmOQkaIkNjZqO3/yU4SQb9nnWQXsLS1fFo+9QrIL5v8vVkXpk/rhiND6PyTj2mMTNjOa76GuZcC+iQ==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-rotate": "@jimp/plugin-rotate@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-gaussian@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-E/f14aLzCS50QAM7K+InI9V61KVy/Zx52vy7Jjfo1h7qKhQHss3PYaydaH0N6qlXRNeXgh+4/32P9JfieLMcdw==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-invert@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-UauP39FF2cwbA5VU+Tz9VlNa9rtULPSHZb0Huwcjqjm9/G/xVN69VJ8+RKiFC4zM1/kYAUp/6IRwPa6qdKJpSw==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-mask@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-bhg5+3i8x1CmYj6cjvPBQZLwZEI3iK3gJWF25ZHF+12d3cqDuJngtr8oRQOQLlAgvKmrj9FXIiEPDczUI9cnWQ==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-normalize@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-Yg5nreAR1JYuSObu3ExlgaLxVeW6VvjVL5qFwiPFxSNlG8JIwL1Ir3K3ChSnnvymyZvJMHb6YKTYNfXKw5Da6g==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-print@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8": {
"integrity": "sha512-86O5ejCDi543IYl0TykSmNWErzAjEYhiAxNQb2F7rFRT38WJYNVsvJ6QhxhDQHKxSmF5iwmqbk0jYk5Wp2Z1kw==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-blit": "@jimp/plugin-blit@0.22.8_@jimp+custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8",
"load-bmfont": "load-bmfont@1.4.1"
}
},
"@jimp/plugin-resize@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-kg8ArQRPqv/iU3DWNXCa8kcVIhoq64Ze0aGCAeFLKlAq/59f5pzAci6m6vV4L/uOVdYmUa9/kYwIFY6RWKpfzQ==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-rotate@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8": {
"integrity": "sha512-9a+VPZWMN/Cks76wf8LjM5RVA3ntP9+NAdsS1SZhhXel7U3Re/dWMouIEbo3QTt6K+igRo4txUCdZiw4ZucvkQ==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-blit": "@jimp/plugin-blit@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-crop": "@jimp/plugin-crop@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-resize": "@jimp/plugin-resize@0.22.8_@jimp+custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-scale@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8": {
"integrity": "sha512-dQS4pG6DX6endu8zUpvBBOEtGC+ljDDDNw0scSXY71TxyQdNo5Ro0apfsppjmuAr8rNotRkfyxbITKkXQDRUDQ==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-resize": "@jimp/plugin-resize@0.22.8_@jimp+custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-shadow@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blur@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8": {
"integrity": "sha512-HyAhr7OblTQh+BoKHQg4qbS9MweNlH77yfpBqUEyDtfyjI5r06+5chf1ZdLRIPEWv/BdCfdI/g81Wv69muCMwA==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-blur": "@jimp/plugin-blur@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-resize": "@jimp/plugin-resize@0.22.8_@jimp+custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugin-threshold@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-color@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8": {
"integrity": "sha512-ZmkfH0PtjvF1UcKsjw0H7V6r+LC0yKzEfg76Jhs2nIqIgsxsSOVfHwS7z0/1IWnyXxSw36m+NjCAotNHRILGmA==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-color": "@jimp/plugin-color@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-resize": "@jimp/plugin-resize@0.22.8_@jimp+custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8"
}
},
"@jimp/plugins@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-scale@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-rotate@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-blit@0.22.8___@jimp+custom@0.22.8__@jimp+plugin-crop@0.22.8___@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8_@jimp+plugin-blur@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-color@0.22.8__@jimp+custom@0.22.8": {
"integrity": "sha512-ieI2+kCpmIfjwVlT7B67ULCzxMizfj7LspJh9HnIZCDXQB9GBOZ9KImLYc75Krae0dP/3FR7FglLiSI7fkOHbw==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugin-blit": "@jimp/plugin-blit@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-blur": "@jimp/plugin-blur@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-circle": "@jimp/plugin-circle@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-color": "@jimp/plugin-color@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-contain": "@jimp/plugin-contain@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-scale@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8",
"@jimp/plugin-cover": "@jimp/plugin-cover@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-scale@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8",
"@jimp/plugin-crop": "@jimp/plugin-crop@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-displace": "@jimp/plugin-displace@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-dither": "@jimp/plugin-dither@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-fisheye": "@jimp/plugin-fisheye@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-flip": "@jimp/plugin-flip@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-rotate@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-blit@0.22.8___@jimp+custom@0.22.8__@jimp+plugin-crop@0.22.8___@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8",
"@jimp/plugin-gaussian": "@jimp/plugin-gaussian@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-invert": "@jimp/plugin-invert@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-mask": "@jimp/plugin-mask@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-normalize": "@jimp/plugin-normalize@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-print": "@jimp/plugin-print@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8",
"@jimp/plugin-resize": "@jimp/plugin-resize@0.22.8_@jimp+custom@0.22.8",
"@jimp/plugin-rotate": "@jimp/plugin-rotate@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8",
"@jimp/plugin-scale": "@jimp/plugin-scale@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8",
"@jimp/plugin-shadow": "@jimp/plugin-shadow@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blur@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8",
"@jimp/plugin-threshold": "@jimp/plugin-threshold@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-color@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8",
"timm": "timm@1.7.1"
}
},
"@jimp/png@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-XOj11kcCr8zKg24QSwlRfH9k4hbV6rkMGUVxMS3puRzzB0FBSQy42NBYEfYf2XlY2QJSAByPl4AYerOtKb805w==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/utils": "@jimp/utils@0.22.8",
"pngjs": "pngjs@6.0.0"
}
},
"@jimp/tiff@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-K0hYUVW5MLgwq3jiHVHa6LvP05J1rXOlRCC+5dMTUnAXVwi45+MKsqA/8lzzwhHYJ65CNhZwy6D3+ZNzM9SIBQ==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"utif2": "utif2@4.1.0"
}
},
"@jimp/types@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-9+xc+mzuYwu0i+6dsnhXiUgfcS+Ktqn5q2jczoKyyBT0cOKgsk+57EIeFLgpTfVGRKRR0y/UIdHByeCzGguF3A==",
"dependencies": {
"@jimp/bmp": "@jimp/bmp@0.22.8_@jimp+custom@0.22.8",
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/gif": "@jimp/gif@0.22.8_@jimp+custom@0.22.8",
"@jimp/jpeg": "@jimp/jpeg@0.22.8_@jimp+custom@0.22.8",
"@jimp/png": "@jimp/png@0.22.8_@jimp+custom@0.22.8",
"@jimp/tiff": "@jimp/tiff@0.22.8_@jimp+custom@0.22.8",
"timm": "timm@1.7.1"
}
},
"@jimp/utils@0.22.8": {
"integrity": "sha512-AaqjfqDeLzSFzrbGRKHMXg/ntiWKvoG9tpVgWzgOx5/gPWj/IyGfztojLTTvY8HqZCr25z8z91u2lAQD2v46Jw==",
"dependencies": {
"regenerator-runtime": "regenerator-runtime@0.13.11"
}
},
"@tokenizer/token@0.3.0": {
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
"dependencies": {}
},
"@types/node@16.9.1": {
"integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==",
"dependencies": {}
},
"any-base@1.1.0": {
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==",
"dependencies": {}
},
"base64-js@1.5.1": {
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dependencies": {}
},
"bmp-js@0.1.0": {
"integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==",
"dependencies": {}
},
"buffer-equal@0.0.1": {
"integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==",
"dependencies": {}
},
"buffer@5.7.1": {
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dependencies": {
"base64-js": "base64-js@1.5.1",
"ieee754": "ieee754@1.2.1"
}
},
"dom-walk@0.1.2": {
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
"dependencies": {}
},
"exif-parser@0.1.12": {
"integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==",
"dependencies": {}
},
"file-type@16.5.4": {
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
"dependencies": {
"readable-web-to-node-stream": "readable-web-to-node-stream@3.0.2",
"strtok3": "strtok3@6.3.0",
"token-types": "token-types@4.2.1"
}
},
"gifwrap@0.9.4": {
"integrity": "sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==",
"dependencies": {
"image-q": "image-q@4.0.0",
"omggif": "omggif@1.0.10"
}
},
"global@4.4.0": {
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"dependencies": {
"min-document": "min-document@2.19.0",
"process": "process@0.11.10"
}
},
"ieee754@1.2.1": {
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dependencies": {}
},
"image-q@4.0.0": {
"integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==",
"dependencies": {
"@types/node": "@types/node@16.9.1"
}
},
"inherits@2.0.4": {
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dependencies": {}
},
"is-function@1.0.2": {
"integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==",
"dependencies": {}
},
"isomorphic-fetch@3.0.0": {
"integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
"dependencies": {
"node-fetch": "node-fetch@2.6.11",
"whatwg-fetch": "whatwg-fetch@3.6.2"
}
},
"jimp@0.22.8_@jimp+custom@0.22.8": {
"integrity": "sha512-pBbrooJMX7795sDcxx1XpwNZC8B/ITyDV+JK2/1qNbQl/1UWqWeh5Dq7qQpMZl5jLdcFDv5IVTM+OhpafSqSFA==",
"dependencies": {
"@jimp/custom": "@jimp/custom@0.22.8",
"@jimp/plugins": "@jimp/plugins@0.22.8_@jimp+custom@0.22.8_@jimp+plugin-blit@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-resize@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-scale@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8_@jimp+plugin-crop@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-rotate@0.22.8__@jimp+custom@0.22.8__@jimp+plugin-blit@0.22.8___@jimp+custom@0.22.8__@jimp+plugin-crop@0.22.8___@jimp+custom@0.22.8__@jimp+plugin-resize@0.22.8___@jimp+custom@0.22.8_@jimp+plugin-blur@0.22.8__@jimp+custom@0.22.8_@jimp+plugin-color@0.22.8__@jimp+custom@0.22.8",
"@jimp/types": "@jimp/types@0.22.8_@jimp+custom@0.22.8",
"regenerator-runtime": "regenerator-runtime@0.13.11"
}
},
"jpeg-js@0.4.4": {
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==",
"dependencies": {}
},
"load-bmfont@1.4.1": {
"integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==",
"dependencies": {
"buffer-equal": "buffer-equal@0.0.1",
"mime": "mime@1.6.0",
"parse-bmfont-ascii": "parse-bmfont-ascii@1.0.6",
"parse-bmfont-binary": "parse-bmfont-binary@1.0.6",
"parse-bmfont-xml": "parse-bmfont-xml@1.1.4",
"phin": "phin@2.9.3",
"xhr": "xhr@2.6.0",
"xtend": "xtend@4.0.2"
}
},
"mime@1.6.0": {
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"dependencies": {}
},
"min-document@2.19.0": {
"integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
"dependencies": {
"dom-walk": "dom-walk@0.1.2"
}
},
"mkdirp@2.1.6": {
"integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==",
"dependencies": {}
},
"node-fetch@2.6.11": {
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
"dependencies": {
"whatwg-url": "whatwg-url@5.0.0"
}
},
"omggif@1.0.10": {
"integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==",
"dependencies": {}
},
"pako@1.0.11": {
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"dependencies": {}
},
"parse-bmfont-ascii@1.0.6": {
"integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==",
"dependencies": {}
},
"parse-bmfont-binary@1.0.6": {
"integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==",
"dependencies": {}
},
"parse-bmfont-xml@1.1.4": {
"integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==",
"dependencies": {
"xml-parse-from-string": "xml-parse-from-string@1.0.1",
"xml2js": "xml2js@0.4.23"
}
},
"parse-headers@2.0.5": {
"integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==",
"dependencies": {}
},
"peek-readable@4.1.0": {
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
"dependencies": {}
},
"phin@2.9.3": {
"integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==",
"dependencies": {}
},
"pixelmatch@4.0.2": {
"integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==",
"dependencies": {
"pngjs": "pngjs@3.4.0"
}
},
"pngjs@3.4.0": {
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==",
"dependencies": {}
},
"pngjs@6.0.0": {
"integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==",
"dependencies": {}
},
"process@0.11.10": {
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"dependencies": {}
},
"readable-stream@3.6.2": {
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dependencies": {
"inherits": "inherits@2.0.4",
"string_decoder": "string_decoder@1.3.0",
"util-deprecate": "util-deprecate@1.0.2"
}
},
"readable-web-to-node-stream@3.0.2": {
"integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==",
"dependencies": {
"readable-stream": "readable-stream@3.6.2"
}
},
"regenerator-runtime@0.13.11": {
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
"dependencies": {}
},
"safe-buffer@5.2.1": {
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dependencies": {}
},
"sax@1.2.4": {
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dependencies": {}
},
"string_decoder@1.3.0": {
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dependencies": {
"safe-buffer": "safe-buffer@5.2.1"
}
},
"strtok3@6.3.0": {
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
"dependencies": {
"@tokenizer/token": "@tokenizer/token@0.3.0",
"peek-readable": "peek-readable@4.1.0"
}
},
"timm@1.7.1": {
"integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==",
"dependencies": {}
},
"tinycolor2@1.6.0": {
"integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
"dependencies": {}
},
"token-types@4.2.1": {
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
"dependencies": {
"@tokenizer/token": "@tokenizer/token@0.3.0",
"ieee754": "ieee754@1.2.1"
}
},
"tr46@0.0.3": {
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dependencies": {}
},
"utif2@4.1.0": {
"integrity": "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==",
"dependencies": {
"pako": "pako@1.0.11"
}
},
"util-deprecate@1.0.2": {
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dependencies": {}
},
"webidl-conversions@3.0.1": {
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dependencies": {}
},
"whatwg-fetch@3.6.2": {
"integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==",
"dependencies": {}
},
"whatwg-url@5.0.0": {
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "tr46@0.0.3",
"webidl-conversions": "webidl-conversions@3.0.1"
}
},
"xhr@2.6.0": {
"integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==",
"dependencies": {
"global": "global@4.4.0",
"is-function": "is-function@1.0.2",
"parse-headers": "parse-headers@2.0.5",
"xtend": "xtend@4.0.2"
}
},
"xml-parse-from-string@1.0.1": {
"integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==",
"dependencies": {}
},
"xml2js@0.4.23": {
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"dependencies": {
"sax": "sax@1.2.4",
"xmlbuilder": "xmlbuilder@11.0.1"
}
},
"xmlbuilder@11.0.1": {
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"dependencies": {}
},
"xtend@4.0.2": {
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"dependencies": {}
}
}
}
}

@ -0,0 +1,70 @@
import Jimp from 'npm:jimp@0.22.8'
function floydSteinberg (data: Buffer, w: number, h: number) {
const errorMultiplier = .6 // 1 is normal, 0.5 is "reduced color bleeding"
const filter = [
[0, 0, 0, 7 / 48, 5 / 48],
[3 / 48, 5 / 48, 7 / 48, 5 / 48, 3 / 48],
[1 / 48, 3 / 48, 5 / 48, 3 / 48, 1 / 48]
]
const error = Array(h)
let r: number
let g: number
let b: number
for (let y = 0; y < h; y++) error[y] = new Float32Array(w)
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const id = ((y * w) + x) * 4
r = data[id]
g = data[id + 1]
b = data[id + 2]
let avg = (r + g + b) / 3
avg -= error[y][x] * errorMultiplier
let e = 0
if (avg < 128) {
e = -avg
avg = 0
} else {
e = 255 - avg
avg = 255
}
data[id] = data[id + 1] = data[id + 2] = avg
data[id + 3] = 255
for (let yy = 0; yy < 3; yy++) {
for (let xx = -2; xx <= 2; xx++) {
if (y + yy < 0 || h <= y + yy || x + xx < 0 || w <= x + xx) continue
error[y + yy][x + xx] += e * filter[yy][xx + 2]
}
}
}
}
return data
}
export default async function process (source: string, destinationWidth?: number, destinationHeight?: number, storeAs?: string): Uint8ClampedArray | null {
try {
const image = await Jimp.read(source)
const width = destinationWidth ?? image.bitmap.width
const height = destinationHeight ?? image.bitmap.height
image.grayscale().cover(width, height)
const data = floydSteinberg(image.bitmap.data, width, height)
if (storeAs) {
new Jimp({data, width, height }, (err, image) => image.write(storeAs))
}
return new Uint8ClampedArray(data)
} catch (error) {
console.error('failed to process image', error)
return null
}
}

@ -0,0 +1,20 @@
import dither from './dither.ts'
import initTransmitter from './transmit.ts'
const ADDRESS = '192.168.178.200'
const DISPLAY_SIZE = [800, 480]
const imgSrcPath = Deno.args[0]
const imgDstPath = Deno.args[1]
// Learn more at https://deno.land/manual/examples/module_metadata#concepts
if (import.meta.main) {
if (!imgSrcPath) {
console.error('Usage: deno main.ts <input-path> [output-path]')
} else {
const [w, h] = DISPLAY_SIZE
const transmit = initTransmitter(ADDRESS)
const imageData = await dither(imgSrcPath, w, h, imgDstPath)
transmit(imageData, w, h)
}
}

@ -0,0 +1,61 @@
import { assertEquals } from "https://deno.land/std@0.176.0/testing/asserts.ts";
import { byteToStr, wordToStr, DisplayCode, getPixelValue } from './transmit.ts'
function orig_byteToStr(v: number) {
return String.fromCharCode((v & 0xF) + 97, ((v >> 4) & 0xF) + 97);
}
function orig_wordToStr(v: number) {
return byteToStr(v & 0xFF) + byteToStr((v >> 8) & 0xFF);
}
function orig_displayCode(epdInd = 22) {
return "EPD" + String.fromCharCode(epdInd + 97) + "_"
}
function orig_getVal(p: { data: Uint8ClampedArray }, i: number) {
if ((p.data[i]==0x00) && (p.data[i+1]==0x00)) return 0
if ((p.data[i]==0xFF) && (p.data[i+1]==0xFF)) return 1
if ((p.data[i]==0x7F) && (p.data[i+1]==0x7F)) return 2
return 3
}
Deno.test(function test_byteToStr() {
const testValues = [0,1,2,23,42,255]
const results = testValues.map(v => byteToStr(v))
const expected = testValues.map(v => orig_byteToStr(v))
assertEquals(results, expected)
})
Deno.test(function test_wordToStr() {
const testValues = [0,1,2,23,42,384]
const results = testValues.map(v => wordToStr(v))
const expected = testValues.map(v => orig_wordToStr(v))
assertEquals(results, expected)
})
Deno.test(function test_displayCode() {
assertEquals(orig_displayCode(), DisplayCode)
})
Deno.test(function test_getPixelValue() {
// 4 pixels: white, black, black, white
const data = new Uint8ClampedArray([
255, 255, 255, 255,
0, 0, 0, 255,
0, 0, 0, 255,
255, 255, 255, 255,
])
const results = [
getPixelValue(data, 0 << 2),
getPixelValue(data, 1 << 2),
getPixelValue(data, 2 << 2),
getPixelValue(data, 3 << 2),
]
const expected = [
orig_getVal({ data }, 0 << 2),
orig_getVal({ data }, 1 << 2),
orig_getVal({ data }, 2 << 2),
orig_getVal({ data }, 3 << 2),
]
assertEquals(results, expected)
})

@ -0,0 +1,39 @@
/**
******************************************************************************
@file Loader.h
@author Waveshare Team
@version V2.0.0
@date 10-August-2018
@brief The main file.
This file provides firmware functions:
+ Initialization of Serial Port, SPI pins and server
+ Main loop
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "srvr.h" // Server functions
/* Entry point ----------------------------------------------------------------*/
void setup()
{
// Serial port initialization
Serial.begin(115200);
delay(10);
// Bluetooth initialization
Srvr__btSetup();
// SPI initialization
EPD_initSPI();
// Initialization is complete
Serial.print("\r\nOk!\r\n");
}
/* The main loop -------------------------------------------------------------*/
void loop()
{
Srvr__loop();
}

@ -0,0 +1,56 @@
/**
******************************************************************************
* @file buff.h
* @author Waveshare Team
* @version V1.0.0
* @date 23-January-2018
* @brief ESP8266 WiFi server.
* This file provides firmware functions:
* + Sending web page of the tool to a client's browser
* + Uploading images from client part by part
*
******************************************************************************
*/
/* Size, current position index and byte array of the buffer -----------------*/
#define Buff__SIZE 2050
int Buff__bufInd;
char Buff__bufArr[Buff__SIZE];
/* Reads a word from the buffer at specified position ------------------------*/
int Buff__getByte(int index)
{
return Buff__bufArr[index];
}
/* Reads a byte from the buffer at specified position ------------------------*/
int Buff__getWord(int index)
{
if (index + 1 >= Buff__SIZE) return -1;
return Buff__bufArr[index] + (Buff__bufArr[index + 1] << 8);
}
/* Reads a byte from the buffer at specified position ------------------------*/
int Buff__getN3(int index)
{
return (index + 3 > Buff__SIZE) ? 0 :
(Buff__bufArr[index ] ) +
(Buff__bufArr[index + 1] << 8) +
(Buff__bufArr[index + 2] << 16);
}
/* Checks if the buffer's data ends with specified string --------------------*/
int Buff__signature(int index, char*str)
{
// characters of the string to the end of the string
while (*str != 0)
{
// If the correspondent character in the buffer isn't equal
// to the string's character, return false
if (Buff__bufArr[index++] != *str) return false;
str++;
}
// Otherwise return true
return true;
}

@ -0,0 +1,597 @@
/**
******************************************************************************
* @file epd.h
* @author Waveshare Team
* @version V1.0.0
* @date 23-January-2018
* @brief This file provides e-Paper driver functions
* void EPD_SendCommand(byte command);
* void EPD_SendData(byte data);
* void EPD_WaitUntilIdle();
* void EPD_Send_1(byte c, byte v1);
* void EPD_Send_2(byte c, byte v1, byte v2);
* void EPD_Send_3(byte c, byte v1, byte v2, byte v3);
* void EPD_Send_4(byte c, byte v1, byte v2, byte v3, byte v4);
* void EPD_Send_5(byte c, byte v1, byte v2, byte v3, byte v4, byte v5);
* void EPD_Reset();
* void EPD_dispInit();
*
* varualbes:
* EPD_dispLoad; - pointer on current loading function
* EPD_dispIndex; - index of current e-Paper
* EPD_dispInfo EPD_dispMass[]; - array of e-Paper properties
*
******************************************************************************
*/
/* SPI pin definition --------------------------------------------------------*/
#define PIN_SPI_SCK 13
#define PIN_SPI_DIN 14
#define PIN_SPI_CS 15
#define PIN_SPI_BUSY 25//19
#define PIN_SPI_RST 26//21
#define PIN_SPI_DC 27//22
/* Pin level definition ------------------------------------------------------*/
#define LOW 0
#define HIGH 1
#define GPIO_PIN_SET 1
#define GPIO_PIN_RESET 0
#define UBYTE uint8_t
#define UWORD uint16_t
#define UDOUBLE uint32_t
void EPD_initSPI()
{
//Serial.println(SPI._spi_num);
//Serial.println(SPI.get);
pinMode(PIN_SPI_BUSY, INPUT);
pinMode(PIN_SPI_RST , OUTPUT);
pinMode(PIN_SPI_DC , OUTPUT);
pinMode(PIN_SPI_SCK, OUTPUT);
pinMode(PIN_SPI_DIN, OUTPUT);
pinMode(PIN_SPI_CS , OUTPUT);
digitalWrite(PIN_SPI_CS , HIGH);
digitalWrite(PIN_SPI_SCK, LOW);
//SPI.begin();
}
/* Lut mono ------------------------------------------------------------------*/
byte lut_full_mono[] =
{
0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22,
0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88,
0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51,
0x35, 0x51, 0x51, 0x19, 0x01, 0x00
};
byte lut_partial_mono[] =
{
0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* The procedure of sending a byte to e-Paper by SPI -------------------------*/
void EpdSpiTransferCallback(byte data)
{
//SPI.beginTransaction(spi_settings);
digitalWrite(PIN_SPI_CS, GPIO_PIN_RESET);
for (int i = 0; i < 8; i++)
{
if ((data & 0x80) == 0) digitalWrite(PIN_SPI_DIN, GPIO_PIN_RESET);
else digitalWrite(PIN_SPI_DIN, GPIO_PIN_SET);
data <<= 1;
digitalWrite(PIN_SPI_SCK, GPIO_PIN_SET);
digitalWrite(PIN_SPI_SCK, GPIO_PIN_RESET);
}
//SPI.transfer(data);
digitalWrite(PIN_SPI_CS, GPIO_PIN_SET);
//SPI.endTransaction();
}
byte lut_vcom0[] = { 15, 0x0E, 0x14, 0x01, 0x0A, 0x06, 0x04, 0x0A, 0x0A, 0x0F, 0x03, 0x03, 0x0C, 0x06, 0x0A, 0x00 };
byte lut_w [] = { 15, 0x0E, 0x14, 0x01, 0x0A, 0x46, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x86, 0x0A, 0x04 };
byte lut_b [] = { 15, 0x0E, 0x14, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x4A, 0x04 };
byte lut_g1 [] = { 15, 0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04 };
byte lut_g2 [] = { 15, 0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04 };
byte lut_vcom1[] = { 15, 0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte lut_red0 [] = { 15, 0x83, 0x5D, 0x01, 0x81, 0x48, 0x23, 0x77, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
byte lut_red1 [] = { 15, 0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/* Sending a byte as a command -----------------------------------------------*/
void EPD_SendCommand(byte command)
{
digitalWrite(PIN_SPI_DC, LOW);
EpdSpiTransferCallback(command);
}
/* Sending a byte as a data --------------------------------------------------*/
void EPD_SendData(byte data)
{
digitalWrite(PIN_SPI_DC, HIGH);
EpdSpiTransferCallback(data);
}
/* Waiting the e-Paper is ready for further instructions ---------------------*/
void EPD_WaitUntilIdle()
{
//0: busy, 1: idle
while(digitalRead(PIN_SPI_BUSY) == 0) delay(100);
}
/* Waiting the e-Paper is ready for further instructions ---------------------*/
void EPD_WaitUntilIdle_high()
{
//1: busy, 0: idle
while(digitalRead(PIN_SPI_BUSY) == 1) delay(100);
}
/* Send a one-argument command -----------------------------------------------*/
void EPD_Send_1(byte c, byte v1)
{
EPD_SendCommand(c);
EPD_SendData(v1);
}
/* Send a two-arguments command ----------------------------------------------*/
void EPD_Send_2(byte c, byte v1, byte v2)
{
EPD_SendCommand(c);
EPD_SendData(v1);
EPD_SendData(v2);
}
/* Send a three-arguments command --------------------------------------------*/
void EPD_Send_3(byte c, byte v1, byte v2, byte v3)
{
EPD_SendCommand(c);
EPD_SendData(v1);
EPD_SendData(v2);
EPD_SendData(v3);
}
/* Send a four-arguments command ---------------------------------------------*/
void EPD_Send_4(byte c, byte v1, byte v2, byte v3, byte v4)
{
EPD_SendCommand(c);
EPD_SendData(v1);
EPD_SendData(v2);
EPD_SendData(v3);
EPD_SendData(v4);
}
/* Send a five-arguments command ---------------------------------------------*/
void EPD_Send_5(byte c, byte v1, byte v2, byte v3, byte v4, byte v5)
{
EPD_SendCommand(c);
EPD_SendData(v1);
EPD_SendData(v2);
EPD_SendData(v3);
EPD_SendData(v4);
EPD_SendData(v5);
}
/* Writting lut-data into the e-Paper ----------------------------------------*/
void EPD_lut(byte c, byte l, byte*p)
{
// lut-data writting initialization
EPD_SendCommand(c);
// lut-data writting doing
for (int i = 0; i < l; i++, p++) EPD_SendData(*p);
}
/* Writting lut-data of the black-white channel ------------------------------*/
void EPD_SetLutBw(byte*c20, byte*c21, byte*c22, byte*c23, byte*c24)
{
EPD_lut(0x20, *c20, c20 + 1);//g vcom
EPD_lut(0x21, *c21, c21 + 1);//g ww --
EPD_lut(0x22, *c22, c22 + 1);//g bw r
EPD_lut(0x23, *c23, c23 + 1);//g wb w
EPD_lut(0x24, *c24, c24 + 1);//g bb b
}
/* Writting lut-data of the red channel --------------------------------------*/
void EPD_SetLutRed(byte*c25, byte*c26, byte*c27)
{
EPD_lut(0x25, *c25, c25 + 1);
EPD_lut(0x26, *c26, c26 + 1);
EPD_lut(0x27, *c27, c27 + 1);
}
/* This function is used to 'wake up" the e-Paper from the deep sleep mode ---*/
void EPD_Reset()
{
digitalWrite(PIN_SPI_RST, HIGH);
delay(200);
digitalWrite(PIN_SPI_RST, LOW);
delay(200);
digitalWrite(PIN_SPI_RST, HIGH);
delay(200);
}
/* e-Paper initialization functions ------------------------------------------*/
#include "epd1in54.h"
#include "epd2in13.h"
#include "epd2in9.h"
#include "epd2in7.h"
#include "epd2in66.h"
#include "epd3in7.h"
#include "epd3in52.h"
#include "epd4in01f.h"
#include "epd4in2.h"
#include "epd5in83.h"
#include "epd5in65f.h"
#include "epd7in5.h"
#include "epd7in5_HD.h"
bool EPD_invert; // If true, then image data bits must be inverted
int EPD_dispIndex; // The index of the e-Paper's type
int EPD_dispX, EPD_dispY; // Current pixel's coordinates (for 2.13 only)
void(*EPD_dispLoad)(); // Pointer on a image data writting function
/* Image data loading function for a-type e-Paper ----------------------------*/
void EPD_loadA()
{
// Get the index of the image data begin
int pos = 6;
// Enumerate all of image data bytes
while (pos < Buff__bufInd)
{
// Get current byte
int value = Buff__getByte(pos);
// Invert byte's bits in case of '2.7' e-Paper
if (EPD_invert) value = ~value;
// Write the byte into e-Paper's memory
EPD_SendData((byte)value);
// Increment the current byte index on 2 characters
pos++;
}
}
void EPD_loadAFilp()
{
// Get the index of the image data begin
int pos = 6;
// Enumerate all of image data bytes
while (pos < Buff__bufInd)
{
// Get current byte
int value = Buff__getByte(pos);
// Invert byte's bits in case of '2.7' e-Paper
if (EPD_invert) value = ~value;
// Write the byte into e-Paper's memory
EPD_SendData(~(byte)value);
// Increment the current byte index on 2 characters
pos++;
}
}
/* Image data loading function for b-type e-Paper ----------------------------*/
void EPD_loadB()
{
// Get the index of the image data begin
int pos = 6;
// Enumerate all of image data bytes
while (pos < Buff__bufInd)
{
// Get current word from obtained image data
int valueA = (int)Buff__getWord(pos);
// Clean current word of processed image data
int valueB = 0;
// Enumerate next 8 pixels
for (int p = 0; p < 8; p++)
{
// Current obtained pixel data
int pixInd = valueA & 3;
// Remove the obtained pixel data from 'valueA' word
valueA = valueA >> 2;
// Processing of 8 2-bit pixels to 8 2-bit pixels:
// black(value 0) to bits 00, white(value 1) to bits 11, gray(otherwise) to bits 10
valueB = (valueB << 2) + (pixInd == 1 ? 3 : (pixInd == 0 ? 0 : 2));
}
// Write the word into e-Paper's memory
EPD_SendData((byte)(valueB >> 8));
EPD_SendData((byte)valueB);
// Increment the current byte index on 2 characters
pos += 2;
}
}
/* Image data loading function for 2.13 e-Paper ------------------------------*/
void EPD_loadC()
{
// Get the index of the image data begin
int pos = 6;
EPD_Send_2(0x44, 0, 15); //SET_RAM_X_ADDRESS_START_END_POSITION LO(x >> 3), LO((w - 1) >> 3)
EPD_Send_4(0x45, 0, 0, 249, 0); //SET_RAM_Y_ADDRESS_START_END_POSITION LO(y), HI(y), LO(h - 1), HI(h - 1)
// Enumerate all of image data bytes
while (pos < Buff__bufInd)
{
// Before write a line of image data
// 2.13 e-Paper requires to set the address counter
// Every line has 15*8-6 pixels + 6 empty bits, totally 15*8 bits
if (EPD_dispX == 0)
{
EPD_Send_1(0x4E, 0 );//SET_RAM_X_ADDRESS_COUNTER: LO(x >> 3)
EPD_Send_2(0x4F, EPD_dispY, 0);//SET_RAM_Y_ADDRESS_COUNTER: LO(y), HI(y)
EPD_SendCommand(0x24);//WRITE_RAM
}
// Write the byte into e-Paper's memory
EPD_SendData((byte)Buff__getByte(pos));
// Increment the current byte index on 2 characters
pos++;
// EPD_dispX and EPD_dispY increments
if (++EPD_dispX > 15)
{
EPD_dispX = 0;
// If the client's browser sends more bits, than it needs, then exit the function
if (++EPD_dispY > 250) return;
}
}
}
/* Image data loading function for 7.5 e-Paper -------------------------------*/
void EPD_loadD()
{
// Get the index of the image data begin
int pos = 6;
// Enumerate all of image data bytes
while (pos < Buff__bufInd)
{
// Get current byte from obtained image data
int valueA = Buff__getByte(pos);
// Processing of 4 1-bit pixels to 4 4-bit pixels:
// black(value 0) to bits 0000, white(value 1) to bits 0011
EPD_SendData((byte)((valueA & 0x80) ? 0x30 : 0x00) + ((valueA & 0x40) ? 0x03 : 0x00));
EPD_SendData((byte)((valueA & 0x20) ? 0x30 : 0x00) + ((valueA & 0x10) ? 0x03 : 0x00));
EPD_SendData((byte)((valueA & 0x08) ? 0x30 : 0x00) + ((valueA & 0x04) ? 0x03 : 0x00));
EPD_SendData((byte)((valueA & 0x02) ? 0x30 : 0x00) + ((valueA & 0x01) ? 0x03 : 0x00));
// Increment the current byte index on 2 characters
pos++;
}
}
/* Image data loading function for 7.5b e-Paper ------------------------------*/
void EPD_loadE()
{
// Get the index of the image data begin
int pos = 6;
// Enumerate all of image data bytes
while (pos < Buff__bufInd)
{
// Get current byte from obtained image data
int value = Buff__getByte(pos);
// Processing of 4 1-bit pixels to 4 4-bit pixels:
// red(value 1) to bits 0011, white(value 3) to bits 0100
int A = (value ) & 3;if (A == 3) A = 4;if (A == 1) A = 3;
int B = (value >> 2) & 3;if (B == 3) B = 4;if (B == 1) B = 3;
int C = (value >> 4) & 3;if (C == 3) C = 4;if (C == 1) C = 3;
int D = (value >> 6) & 3;if (D == 3) D = 4;if (D == 1) D = 3;
// Write the word into e-Paper's memory
EPD_SendData((A << 4) + B);
EPD_SendData((C << 4) + D);
// Increment the current byte index on 2 characters
pos++;
}
}
/* Image data loading function for 5.65f e-Paper -----------------------------*/
void EPD_loadG()
{
// Come back to the image data end
int pos = 6;
// Enumerate all of image data bytes
while (pos < Buff__bufInd)
{
// Get current byte from obtained image data
int value = Buff__getByte(pos);
// Switch the positions of the two 4-bits pixels
// Black:0b000;White:0b001;Green:0b010;Blue:0b011;Red:0b100;Yellow:0b101;Orange:0b110;
int A = (value ) & 0x07;
int B = (value >> 4) & 0x07;
// Write the data into e-Paper's memory
EPD_SendData((byte)(A << 4) + B);
// Increment the current byte index on 2 characters
pos ++;
}
}
/* Show image and turn to deep sleep mode (a-type, 4.2 and 2.7 e-Paper) ------*/
void EPD_showA()
{
// Refresh
EPD_Send_1(0x22, 0xC4);//DISPLAY_UPDATE_CONTROL_2
EPD_SendCommand(0x20);//MASTER_ACTIVATION
EPD_SendCommand(0xFF);//TERMINATE_FRAME_READ_WRITE
EPD_WaitUntilIdle();
// Sleep
EPD_SendCommand(0x10);//DEEP_SLEEP_MODE
EPD_WaitUntilIdle();
}
/* Show image and turn to deep sleep mode (b-type, e-Paper) ------------------*/
void EPD_showB()
{
// Refresh
EPD_SendCommand(0x12);//DISPLAY_REFRESH
delay(100);
EPD_WaitUntilIdle();
// Sleep
EPD_Send_1(0x50, 0x17);//VCOM_AND_DATA_INTERVAL_SETTING
EPD_Send_1(0x82, 0x00);//VCM_DC_SETTING_REGISTER, to solve Vcom drop
EPD_Send_4(0x01, 0x02, 0x00, 0x00, 0x00);//POWER_SETTING
EPD_WaitUntilIdle();
EPD_SendCommand(0x02);//POWER_OFF
}
/* Show image and turn to deep sleep mode (7.5 and 7.5b e-Paper) -------------*/
void EPD_showC()
{
// Refresh
EPD_SendCommand(0x12);//DISPLAY_REFRESH
delay(100);
EPD_WaitUntilIdle();
// Sleep
EPD_SendCommand(0x02);// POWER_OFF
EPD_WaitUntilIdle();
EPD_Send_1(0x07, 0xA5);// DEEP_SLEEP
}
/* Show image and turn to deep sleep mode (2.13 e-Paper) ---------------------*/
void EPD_showD()
{
// VCOM AND DATA INTERVAL SETTING
// WBmode:VBDF 17, D7 VBDW 97, VBDB 57
// WBRmode:VBDF F7, VBDW 77, VBDB 37, VBDR B7
EPD_Send_1(0x50, 0x97);
EPD_SendCommand(0x20);
for(int count=0; count<44; count++) EPD_SendData(lut_vcomDC_2in13d[count]);
EPD_SendCommand(0x21);
for(int count=0; count<42; count++) EPD_SendData(lut_ww_2in13d[count]);
EPD_SendCommand(0x22);
for(int count=0; count<42; count++) EPD_SendData(lut_bw_2in13d[count]);
EPD_SendCommand(0x23);
for(int count=0; count<42; count++) EPD_SendData(lut_wb_2in13d[count]);
EPD_SendCommand(0x24);
for(int count=0; count<42; count++) EPD_SendData(lut_bb_2in13d[count]);
delay(10);
EPD_SendCommand(0x12);//DISPLAY REFRESH
delay(100); //!!!The delay here is necessary, 200uS at least!!!
EPD_WaitUntilIdle();
EPD_Send_1(0x50, 0xf7);
EPD_SendCommand( 0x02);//POWER_OFF
EPD_Send_1(0x07, 0xA5);//DEEP_SLEEP
}
/* The set of pointers on 'init', 'load' and 'show' functions, title and code */
struct EPD_dispInfo
{
int(*init)(); // Initialization
void(*chBk)();// Black channel loading
int next; // Change channel code
void(*chRd)();// Red channel loading
void(*show)();// Show and sleep
char*title; // Title of an e-Paper
};
/* Array of sets describing the usage of e-Papers ----------------------------*/
EPD_dispInfo EPD_dispMass[] =
{
{ EPD_Init_1in54 , EPD_loadA, -1 , 0, EPD_showA, "1.54 inch" },// a 0
{ EPD_Init_1in54b, EPD_loadB, 0x13, EPD_loadA, EPD_showB, "1.54 inch b" },// b 1
{ EPD_Init_1in54c, EPD_loadA, 0x13, EPD_loadA, EPD_showB, "1.54 inch c" },// c 2
{ EPD_Init_2in13 , EPD_loadC, -1 , 0, EPD_showA, "2.13 inch" },// d 3
{ EPD_Init_2in13b, EPD_loadA, 0x13, EPD_loadA, EPD_showB, "2.13 inch b" },// e 4
{ EPD_Init_2in13b, EPD_loadA, 0x13, EPD_loadA, EPD_showB, "2.13 inch c" },// f 5
{ EPD_Init_2in13d, EPD_loadA, -1 , 0, EPD_showD, "2.13 inch d" },// g 6
{ EPD_Init_2in7 , EPD_loadA, -1 , 0, EPD_showB, "2.7 inch" },// h 7
{ EPD_Init_2in7b , EPD_loadA, 0x13, EPD_loadA, EPD_showB, "2.7 inch b" },// i 8
{ EPD_Init_2in9 , EPD_loadA, -1 , 0, EPD_showA, "2.9 inch" },// j 9
{ EPD_Init_2in9b , EPD_loadA, 0x13, EPD_loadA, EPD_showB, "2.9 inch b" },// k 10
{ EPD_Init_2in9b , EPD_loadA, 0x13, EPD_loadA, EPD_showB, "2.9 inch c" },// l 11
{ EPD_Init_2in9d , EPD_loadA, -1 , 0, EPD_2IN9D_Show, "2.9 inch d" },// M 12
{ EPD_Init_4in2 , EPD_loadA, -1 , 0, EPD_showB, "4.2 inch" },// m 12
{ EPD_Init_4in2b , EPD_loadA, 0x13, EPD_loadA, EPD_showB, "4.2 inch b" },// n 13
{ EPD_Init_4in2b , EPD_loadA, 0x13, EPD_loadA, EPD_showB, "4.2 inch c" },// o 14
{ EPD_Init_5in83 , EPD_loadD, -1 , 0, EPD_showC, "5.83 inch" },// p 15
{ EPD_Init_5in83b, EPD_loadE, -1 , 0, EPD_showC, "5.83 inch b" },// q 16
{ EPD_Init_5in83b, EPD_loadE, -1 , 0, EPD_showC, "5.83 inch c" },// r 17
{ EPD_Init_7in5 , EPD_loadD, -1 , 0, EPD_showC, "7.5 inch" },// s 18
{ EPD_Init_7in5 , EPD_loadE, -1 , 0, EPD_showC, "7.5 inch b" },// t 19
{ EPD_Init_7in5 , EPD_loadE, -1 , 0, EPD_showC, "7.5 inch c" }, // u 20
{ EPD_7in5_V2_init , EPD_loadAFilp, -1 , 0, EPD_7IN5_V2_Show, "7.5 inch V2" },// w 22
{ EPD_7in5B_V2_Init , EPD_loadA, 0x13 , EPD_loadAFilp, EPD_7IN5_V2_Show, "7.5 inch B V2 "},// x 23
{ EPD_7IN5B_HD_init , EPD_loadA, 0x26 , EPD_loadAFilp, EPD_7IN5B_HD_Show, "7.5 inch B HD "},// x 24
{ EPD_5IN65F_init, EPD_loadG, -1 , 0, EPD_5IN65F_Show, "5.65 inch F " },// z 25
{ EPD_7IN5_HD_init, EPD_loadA, -1, 0, EPD_7IN5_HD_Show, "7.5 inch HD" },// 26
{ EPD_3IN7_1Gray_Init, EPD_loadA, -1 , 0, EPD_3IN7_1Gray_Show,"3.7 inch" },// 27
{ EPD_2IN66_Init, EPD_loadA, -1 , 0, EPD_2IN66_Show, "2.66 inch" },// 28
{ EPD_5in83b_V2_init, EPD_loadA, 0x13, EPD_loadAFilp, EPD_showC, "5.83 inch B V2"},// 29
{ EPD_Init_2in9b_V3, EPD_loadA, 0x13, EPD_loadA, EPD_showC, "2.9 inch B V3" },// 30
{ EPD_1IN54B_V2_Init, EPD_loadA, 0x26, EPD_loadAFilp, EPD_1IN54B_V2_Show, "1.54 inch B V2"},// 31
{ EPD_2IN13B_V3_Init, EPD_loadA, 0x13, EPD_loadA, EPD_2IN13B_V3_Show, "2.13 inch B V3"},// 32
{ EPD_Init_2in9_V2, EPD_loadA, -1, 0, EPD_2IN9_V2_Show, "2.9 inch V2" },// 33
{ EPD_Init_4in2b_V2, EPD_loadA, 0x13, EPD_loadA, EPD_4IN2B_V2_Show, "4.2 inch B V2" },// 34
{ EPD_2IN66B_Init, EPD_loadA, 0x26, EPD_loadAFilp, EPD_2IN66_Show, "2.66 inch B" },// 35
{ EPD_Init_5in83_V2, EPD_loadAFilp, -1, 0, EPD_showC, "5.83 inch V2" },// 36
{ EPD_4IN01F_init, EPD_loadG, -1, 0, EPD_4IN01F_Show, "4.01 inch F" },// 37
{ EPD_Init_2in7b_V2, EPD_loadA, 0x26, EPD_loadAFilp, EPD_2in7b_V2_Show, "2.7 inch B V2" },// 38
{ EPD_Init_2in13_V3, EPD_loadC, -1, 0, EPD_2IN13_V3_Show, "2.13 inch V3" },// 39
{ EPD_2IN13B_V4_Init, EPD_loadA, 0x26, EPD_loadA, EPD_2IN13B_V4_Show, "2.13 inch B V4"},// 40
{ EPD_3IN52_Init, EPD_loadA, -1, 0, EPD_3IN52_Show, "3.52 inch" },// 41
{ EPD_2IN7_V2_Init, EPD_loadA, -1 , 0, EPD_2IN7_V2_Show, "2.7 inch V2" },// 42
};
/* Initialization of an e-Paper ----------------------------------------------*/
void EPD_dispInit()
{
// Call initialization function
EPD_dispMass[EPD_dispIndex].init();
// Set loading function for black channel
EPD_dispLoad = EPD_dispMass[EPD_dispIndex].chBk;
// Set initial coordinates
EPD_dispX = 0;
EPD_dispY = 0;
// The inversion of image data bits isn't needed by default
EPD_invert = false;
}

@ -0,0 +1,168 @@
/**
******************************************************************************
* @file edp1in54.h
* @author Waveshare Team
* @version V1.0.0
* @date 23-January-2018
* @brief This file describes initialisation of 1.54 and 1.54b e-Papers
*
******************************************************************************
*/
int EPD_Init_1in54()
{
int EPD1in54 = 2;
if(EPD1in54 == 1) {
Serial.print("\r\nEPD1in54 V1");
EPD_Reset();
EPD_Send_3(0x01, 199, 0, 00);//DRIVER_OUTPUT_CONTROL: LO(EPD_HEIGHT-1), HI(EPD_HEIGHT-1). GD = 0; SM = 0; TB = 0;
EPD_Send_3(0x0C, 0xD7, 0xD6, 0x9D);//BOOSTER_SOFT_START_CONTROL
EPD_Send_1(0x2C, 0xA8);//WRITE_VCOM_REGISTER: VCOM 7C
EPD_Send_1(0x3A, 0x1A);//SET_DUMMY_LINE_PERIOD: 4 dummy lines per gate
EPD_Send_1(0x3B, 0x08);//SET_GATE_TIME: 2us per line
EPD_Send_1(0x11, 0x03);//DATA_ENTRY_MODE_SETTING: X increment; Y increment
EPD_lut(0x32, 30, &lut_full_mono[0]);
EPD_Send_2(0x44, 0, 24);//SET_RAM_X_ADDRESS_START_END_POSITION: LO(x >> 3), LO((w-1) >> 3)
EPD_Send_4(0x45, 0, 0, 200, 0);//SET_RAM_Y_ADDRESS_START_END_POSITION: LO(y), HI(y), LO(h - 1), HI(h - 1)
EPD_Send_1(0x4E, 0);//LO(x >> 3)
EPD_Send_2(0x4F, 0, 0);//LO(y), HI(y >> 8)
EPD_SendCommand(0x24);//WRITE_RAM
delay(2);
} else {
Serial.print("\r\nEPD1in54 V2");
EPD_Reset();
while (digitalRead(PIN_SPI_BUSY) == 1) delay(100);
EPD_SendCommand(0x12); //SWRESET
while (digitalRead(PIN_SPI_BUSY) == 1) delay(100);
EPD_SendCommand(0x01); //Driver output control
EPD_SendData(0xC7);
EPD_SendData(0x00);
EPD_SendData(0x01);
EPD_SendCommand(0x11); //data entry mode
EPD_SendData(0x01);
EPD_SendCommand(0x44); //set Ram-X address start/end position
EPD_SendData(0x00);
EPD_SendData(0x18); //0x0C-->(18+1)*8=200
EPD_SendCommand(0x45); //set Ram-Y address start/end position
EPD_SendData(0xC7); //0xC7-->(199+1)=200
EPD_SendData(0x00);
EPD_SendData(0x00);
EPD_SendData(0x00);
EPD_SendCommand(0x3C); //BorderWavefrom
EPD_SendData(0x01);
EPD_SendCommand(0x18);
EPD_SendData(0x80);
EPD_SendCommand(0x22); // //Load Temperature and waveform setting.
EPD_SendData(0XB1);
EPD_SendCommand(0x20);
EPD_SendCommand(0x4E); // set RAM x address count to 0;
EPD_SendData(0x00);
EPD_SendCommand(0x4F); // set RAM y address count to 0X199;
EPD_SendData(0xC7);
EPD_SendData(0x00);
while (digitalRead(PIN_SPI_BUSY) == 1) delay(100);
Serial.print("\r\n init over");
EPD_SendCommand(0x24);//DATA_START_TRANSMISSION_1
}
return 0;
}
int EPD_Init_1in54b()
{
EPD_Reset(