{"id":15672373,"url":"https://github.com/tomarrell/rasp-ws2812b","last_synced_at":"2025-05-06T21:10:48.434Z","repository":{"id":82076827,"uuid":"143305836","full_name":"tomarrell/rasp-ws2812b","owner":"tomarrell","description":"Controlling WS2812b LED's using Rust on the Raspberry Pi","archived":false,"fork":false,"pushed_at":"2019-07-15T22:10:28.000Z","size":317,"stargazers_count":18,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-31T03:01:42.926Z","etag":null,"topics":["embedded","leds","mario","pwm","raspberry-pi","rust","spi"],"latest_commit_sha":null,"homepage":"https://blog.tomarrell.com/post/rust_and_leds","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomarrell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-02T14:30:01.000Z","updated_at":"2024-10-22T00:21:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"d4243cef-39d5-42d6-98d0-59c2f0f7b480","html_url":"https://github.com/tomarrell/rasp-ws2812b","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomarrell%2Frasp-ws2812b","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomarrell%2Frasp-ws2812b/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomarrell%2Frasp-ws2812b/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomarrell%2Frasp-ws2812b/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomarrell","download_url":"https://codeload.github.com/tomarrell/rasp-ws2812b/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252769425,"owners_count":21801378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["embedded","leds","mario","pwm","raspberry-pi","rust","spi"],"created_at":"2024-10-03T15:24:59.288Z","updated_at":"2025-05-06T21:10:48.415Z","avatar_url":"https://github.com/tomarrell.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"**NB: This was an experiment, and should not actually be used as a method to communicate with the WS2812b**\n\n# Rasp-WS2812b\nPower WS2812b LEDs from your Raspberry Pi over SPI.\n\n[Blogpost](https://blog.tomarrell.com/post/rust_and_leds)\n\n## How it works?\nThe LEDs run with a scan frequency of no less than `400Hz`, with a data transfer rate of `800kbps`.\n\nThe traditional method of communication with the WS2812b is usually PWM. The duty cycle to send a single bit is:\n\n| Bit | Time High | Time Low | Duty % |\n|-----|-----------|----------|--------|\n| 0   | 0.4us     | 0.85us   | 32%    |\n| 1   | 0.8us     | 0.45us   | 64%    |\n\nA visual of the protocol is below.\n\n```\nPWM LED (0): where\n    on time  = 0.4us +/-150ns\n    off time = 0.85us +/-150ns\n    \nVolts\n    |    START                      END\n    |    v                          v\n    |    ----------\n    |    |        |\n    |    |        |\n    |    |        |\n    | ----        -------------------\n    *-------------------------------- Time\n    \nPWM LED (1): where\n   on time  = 0.8us +/-150ns\n   off time = 0.45us +/-150ns\n   \nVolts\n    |    START                      END\n    |    v                          v\n    |    ------------------\n    |    |                |\n    |    |                |\n    |    |                |\n    | ----                -----------\n    *-------------------------------- Time\n```\n\nLooking at the above duty cycle lengths, we can approximate each time slice into another 3 periods, each **33%** of the original wavelength in order to have constant high/low runs for the given period. This will allow us to continue using SPI, using a clock speed of approximately `3Mhz`.\n\nTo interact over SPI, each traditional LED sequence (3 bytes, 8 bits per colour channel) needs to be converted to a 9 byte sequence (72 bits per colour channel) before being shifted over SPI. Each traditional PWM 'bit' gets turned into an equivalent 3 SPI bits, and the clock speed of the SPI interface set to achieve within the `+/-150ns` error margins.\n\nWith the traditional period broken into 3 time sections, each can be pulled high or low individually. We can therefore represent what would have been a PWM (1) with an SPI `110`. And on the contrary, represent a PWM (0) with an SPI `100`.\n\n## Example\nAn example of a Raspberry Pi controlling a flexible panel of WS2812b's:\n\n(Mario)\n![Image of Pixel Mario](./assets/mario.jpg)\n\n## License\nLicensed under the GNU GPLv3.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomarrell%2Frasp-ws2812b","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomarrell%2Frasp-ws2812b","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomarrell%2Frasp-ws2812b/lists"}