📜 ⬆️ ⬇️

Driving LED strip with Raspberry Pi and Android

Hello, frequenter and guest Habra.

I have been reading Habr for a long time, but there was still no reason to write an article until I was once again not reminded of the existence of the Raspberry Pi and of such a thing as the WS2801 LED Strip. They have already written about this once, but to contact Arduina to get an Embileyt, so I decided to take a chance and write my article with Lego and Kitties .

The article will have few pictures, several videos, a lot of text, including lyrical digressions not by sabzh and very little code, but at the very end there will be links to the project on Gitkhab. And now about everything in order:

It all started with the fact that I learned that one colleague regularly carries Raspberry Patties and sells them with a minimum of markups, especially to his colleagues. Once again, I heard about the pies, I could not resist and bought it from him. What it is and what you can do with it, I will not tell, and so everyone knows, and who does not know, they can search for articles full. I myself played with him for a week or two, set it up for what I needed and calmed down.


But here the same colleague threw an interesting info: you can order a controlled (“address”) “ garland ” from Ibei (+ power supply , connectors and connecting wiring to your taste and color) and the simplest way to get DYI Ambilight as described, for example, here . Or, you can just play with this garland as you please: in theory, it allowed at any time to light any of the lamps with any RGB color, and after all I had dreamed of owning such a thing for several years!
')
Without hesitation, I ordered the necessary parts on Ibei. The estimated delivery time was about 3 weeks, so there was still time to be distracted by preparations for the trip to Sweden for a week. Upon returning, there was still a week at home, trying to find in advance as much information as possible about how the garland would need to be plugged in, looking for various scripts and libraries to write my own control algorithms. There was not a lot of sensible, one Habra article , though it’s about a link with Arduina and several links led to this Python project. Since I didn’t have any tasks to embed, I don’t have a soul for Python (I love Java + Android), I didn’t find much useful information for myself. There was no free time, the garland did not come at all, I decided to roll on Android a simple garland simulator application and write a couple of control algorithms of the latter. The application was so simple and not less crooked that it didn’t even show anyone.

Last weekend I was brought back from Novosibirsk a long-awaited box of Lego 42009, which temporarily eclipsed my thoughts about garland.

Lego assembly plans were scheduled for next weekend, when, roughly, the arrival of a parcel from China was expected. I thought for a long time what more I was waiting for - the grand opening of the Lego box and the assembly of the top one at the moment of Lego Technic set or the game with the dream of the past few years. The package arrived on Friday evening, and on Saturday morning it was planned to begin assembling the constructor and removing the Time-Lapse assembly process.
Of course, I could not resist on Friday evening and tried to connect the garland to the Patty, but due to the lack of the necessary wiring, it was difficult to connect to the RPIO ports of the RPi. Having found some old postings, having disassembled the old mouse, having read articles on the Internet, I tried to connect a garland at least somehow and run test scripts. But all was in vain. When power was connected to the garland, the first light was turned on with white light and that was it, there were no reactions, regardless of what I started on Pirog. Having suffered badly, I decided to postpone the matter until the morning.

In the morning a friend-photographer came to help with the assembly and filming of Lego, along with him they also unsuccessfully tried to connect a garland to Pirog. An hour later, they abandoned this business and went to prepare the environment of the apartment for the assembly of the Mobile Crane.
[lyrical digression]
The assembly went off with a bang, the crane met all expectations, turned out to be even more than I thought, the assembly process itself was not simple and fascinating. Time-lapse video assembly can be viewed here .
[/lyrical digression]

Since they started later than planned, finished even later, they did not return to the garland anymore. But on the afternoon of the next day, another friend came, who was already a specialist - a piece of iron, and at the same time brought very necessary wiring of different lengths and connectors for connecting the wreath to the Cake. Sat down with him poking around. Spent 5 hours, probably and seemingly unsuccessfully. At first, the garland did not react to external stimuli, that is, us, in any way. Then sometimes the first few lights began to flash when the connectors connected to the cake were touched. An hour later, we found out that if we short-circuit the wires that should go to the Cake with our fingers, the first few lights of the garland would light up or go out. Hence, it is still working, it remains to understand why the scripts do not work. A cursory analysis of the Python script showed that the /dev/spidev0.0 device is /dev/spidev0.0 , and I actually had it on the system. In parallel, I tried to google the problem, found something, applied what they would say, but without success.

By the end of the day, completely exhausted, the guest left me, and while he was driving home, I decided to wander into the Pie config
raspi-config
and discover the main epic fail of the last couple of days, namely that SPI was turned off ...
Turned on. The script worked, it was possible to turn on and off all the diodes in white and run two infinite actions - fade (gradual appearance and extinction with random colors), or chase - a consistent light running from beginning to end.

Happiness knew no bounds. I even made a couple of photos of the built Lego-crane in the light of a garland:
Lego 42009

Lego 42009

The scarce capabilities of the script quickly got bored, but I was quite problematic to write something of my own on Python. Therefore, it was decided to write a simple Java application for Raspberry and start it tomorrow. But "tomorrow" - it was Monday. It was on this Monday that I did not want to go to work more than on all other Mondays earlier. Having survived Monday, running away from work early, hanging a garland under the ceiling, on the top edge of the carpet that hangs and covers a large hole in the wallpaper in my apartment, I sat down at the code, but then another trick was waiting for me, however, the expected one.
Having installed all the necessary java-packages I decided to write Hello World, compile and run right on the cake. Compiling even such a simple application on Rapsberry Pi took a few seconds, about 5, what can we say about the following code? This was quite inconvenient, as well as the lack of a normal IDE. Therefore, it was decided to write code on a large PC, fill-in compiled classes with ftp on the cake and run them there. Later, when the project has grown to a large number of files began to collect immediately in jar-s. Went to the most interesting. The main question was: how to make the garland light up using Java. Google search didn’t give anything, the C sources were located using libraries and a couple of scripts on Python. At the last it looked like this:

 spidev = file("/dev/spidev0.0", "wb") spidev.write(pixels) time.sleep(refresh_rate/1000) 

where pixels is an array of bytes, 3 times larger than the number of light bulbs in the garland. Every three elements in the array are the values ​​for the RGB channels for each light bulb. Suppose we have a garland of 50 light bulbs; in order to light it all up, we need to write to the /dev/spidev0.0 file /dev/spidev0.0 array of the form {R0, G0, B0, R1, G1, B1, ... R49, G49, B49} . No headers, just an array of bytes and flush after.
The main idea was that at any given time you need to write the entire array to the file, even if you want to light one light bulb. The time delay is needed in order to see all the changes on the tape, however, it can be varied as you like.



Returning to Java, there the code for writing to the file looks almost the same ( try-catch omitted):

 FileOutputStream spidev = new FileOutputStream(new File("/dev/spidev0.0")); spidev.write(bytes); spidev.flush(); Thread.sleep(); 

Actually, having written a simple class of working with the device, I wrote a couple more wrapper classes for various simple actions, such as lighting a certain lightbulb with a given color, lighting the whole garland with the desired color, the same chase and fade. A day later, I screwed in a visualization of the stack and something else.



But again, to run these "algorithms" is not enough interest and it is also quickly tired. I wanted direct control. It was decided to write a simple server, again on Java, which would receive string data, parse them and interact with the garland on the basis of sent “commands”. For convenience, it was done so that the port, the number of lights in the garland and the device ( /dev/spidev0.0 ) were set using the parameters at server startup.
The client, in turn, on Android. In the first version of the client, there was a minimal functionality — turn on / off, set the color using the RGB sliders, and “move” the light with one more slider. In spite of my dislike “from childhood” on client-server code, the written code worked and even correctly.
I quickly realized that 50 bulbs would not be enough for me and I ordered as many more in terms of the fact that later they could be folded into a 10x10 square, and this is a new field of imagination, you can make at least a classic snake.
A little later, a student friend of mine helped rewrite the client-server code for a more correct architecture, now the client communicated with the server using a predetermined set of commands, and an Object type parameter served as data for each command, therefore, there could be anything. Also, to protect against “unauthorized access”, a password field was added to the server, and sent it by the first command on the client. If it did not fit, the server disconnected the client. This was done in case someone knows by what name / aypishnik and port my pie is available so that he cannot try to play with a garland.
Having reworked the code for a new architecture, I began to increase the functionality in breadth: I added new interface elements and new light control algorithms.
Android Client
Added and flickering RGB-colors and random and a rainbow, including moving. Even NFC was bolted to turn on / off the bulbs when reading any label (removed from the final version). It is worth mentioning that the SpeechRecognizer Google was bolted, which was configured to perceive literally 5 teams: “red”, “green”, “blue”, "Yellow" and "rainbow". And, in my opinion, the most interesting functionality is the use of the entire length of the garland as ... equalizer, probably more correctly to say: the number of consecutively lit lamps depended on the volume of the sound perceived by the microphone of the smartphone. Especially impressive is the example of the track Caspa - Sir Rock A Lot :


General overview of the functionality of the application:


After that, I pampered a little more with a couple of algorithms, rules, found bugs on the server and client, and also slightly refactored the code. Now the main control screen looks like this:
All code is laid out on Gitkhab ( library , server and client ) for those who are not indifferent. I would be glad if he will help you with anything. I myself have plans to fork in version 2.0, the functionality of which I haven’t yet defined for myself, but I’m planning something like this:
  1. Control screen selection: straight tape, rectangle or square.
  2. Expansion of current functionality for a tape stretched into one straight line.
  3. Writing a packet of algorithms for the variant, when the tape is folded into a square and a rectangle:
    • Light bulb control
    • Equalizer from the center of the square
    • Static text / Running line
    • Snake
    • anything else. If you have ideas, write, I will gladly discuss and take note.

From the little things that I forgot to write in time:

1. It may be necessary to adjust the color of each diode before writing to the file because the light turns out to be “cold” and gives up in blue at values ​​of 255-255-255. In the Python script, which I found, this is how it is done:

 def correct_pixel_brightness(pixel): corrected_pixel = bytearray(3) corrected_pixel[0] = int(pixel[0] / 1.1) corrected_pixel[1] = int(pixel[1] / 1.1) corrected_pixel[2] = int(pixel[2] / 1.3) return corrected_pixel 

2. The icon was drawn to me by the same person who helped to record the time-lapse built by Lego. It is based on a photo of my cat. proprietary
protracted cat

3. The described actions with the /dev/spidev0.0 file work only for tapes with a WS2801 controller. Last weekend, they gave the DR to a friend ( necrys ) just a ribbon, and not a garland (this time just for the embailite), very much hoping that there was also WS2801. There was no time to order from China, they bought from us in the city, the seller claimed that the controller was the same, although there were no inscriptions on the packaging and the tape itself. In the midst of the birthday celebration they decided to try to connect. Having unsuccessfully spent a few hours, it would seem that, knowing all the pitfalls, they could not turn it on until they accidentally tried to change the protocol to SM16716, after which it lit the tape and even worked chase, but still did not want to fade. Writing a simple c-program did not solve the problem, an attempt to write an array of 3 bytes lit such sections of the tape that we could not understand the logic of work that day. After the experiments, by the middle of the next day, the new owner of the tape managed to lighten up and understand the algorithm of working with the tape: you need to write an array of 4 bytes per file to the luminous unit, where the first byte should always be 0xFF and the rest is RGB. Changing the value of the first byte leads to the behavior of the tape, the meaning of which has not yet been understood. It is in mind of the difference of the controller, the assembly and patching of boblight, which would work with it correctly and it took several days to connect it to xbmc. But after the result was achieved:

For the code, please do not kick much, unfortunately, I don’t have any experience of writing large projects, and when I started writing code, I didn’t think that it would grow to this. And this is the first experience with Git and laying out his code in Open-Source.

Thank you, I hope it was interesting.

Source: https://habr.com/ru/post/203532/


All Articles