Thursday, December 31

George Lucas criticizes “retro” feel of new Star Wars, describes “breakup”

Is George Lucas having regrets about selling his Force-filled empire to Disney? He says no, but the Star Wars creator seemed slightly bitter about his space opera in an interview with Charlie Rose at the Skywalker Ranch that aired over Christmas but is just starting to make its way around the Internet. In the interview, Lucas called the first six episodes his "children" and referred to his separation from the Star Wars franchise as a "breakup."

He also didn't seem entirely pleased with the new film, Episode VII: The Force Awakens, which borrowed plot points—and brought back original characters—from his films.

“The first three movies had all kinds of issues," he told Rose. "[Disney] looked at the stories, and they said, we want to make something for the fans. I said, all I wanted to do is tell a story of what happened, it started here and went here... it’s a family soap opera, ultimately. We call it a space opera, but people don’t realize it’s actually a soap opera, and it’s all about family problems. It’s not about spaceships.”

Read 9 remaining paragraphs | Comments

Oculus announces “Touch” VR controller delay to second half of 2016

Oculus' latest Touch controller image doesn't look much different than the model we tried out in June. (credit: Oculus)

Want to simulate waving your hands around in virtual space? 2016 should be a very good year for you, with burgeoning VR hardware makers HTC, Oculus, and Sony all gearing up to launch motion-tracked VR options by way of handheld controllers. However, in the case of Oculus, their offering received a delay on Thursday, just before this year's New Year's Eve ball drop.

The Oculus Touch system, which will add two handheld controllers and an additional motion-tracking camera to the upcoming Oculus VR headset, will now launch in "the second half of 2016," according to an official announcement. This news pushes back the controllers' originally announced—and equally vague—window of 2016's "first half."

Oculus' announcement says the delay will enable "advances in ergonomics" and "improved hand-pose recognition." Ars got the chance to try out an early Touch controller demo in June, which showed off the system's ability to notice whether our fingers within the controller were extended or clenched, enabling poses such as fists and finger points, but the recognition did feel somewhat wonky in the system's early state.

Read 1 remaining paragraphs | Comments

32C3: So You Want to Build a Satellite?

[INCO] gave this extremely informative talk on building a CubeSat. CubeSats are small satellites that piggyback on the launches of larger satellites, and although getting a 10 cm3 brick into orbit is cheap, making it functional takes an amazing attention to detail and redundant design.

[INCO] somehow talks through the entire hour-long presentation at a tremendous speed, all the while remaining intelligible. At the end of the talk, you’ve got a good appreciation for the myriad pitfalls that go along with designing a satellite, and a lot of this material is relevant, although often in a simpler form, for high altitude balloon experiments.

satellite_2-shot0002CubeSats must be powered down during launch, with no radio emissions or anything else that might interfere with the rocket that’s carrying them. The satellites are then packed into a box with a spring, and you never see or hear from them again until the hatch is opened and they’re pushed out into space.

[INCO] said that 50% of CubeSats fail on deployment, and to avoid being one of the statistics, you need to thoroughly test your deployment mechanisms. Test after shaking, being heated and cooled, subject to low battery levels, and in a vacuum. Communication with the satellite is of course crucial, and [INCO] suggests sending out a beacon shortly after launch to help you locate the satellite at all.

satellite_2-shot0003Because your satellite is floating out in space, even tiny little forces can throw it off course. Examples include radiation pressure from the sun, and anything magnetic in your satellite that will create a torque with respect to the Earth’s magnetic field. And of course, the deployment itself may leave your satellite tumbling slightly, so you’re going to need to control your satellite’s attitude.

Power is of course crucial, and in space that means solar cells. Managing solar cells, charging lithium batteries, and smoothing out the power cycles as the satellite enters the earth’s shadow or tumbles around out of control in space. Frequent charging and discharging of the battery is tough on it, so you’ll want to keep your charge/discharge cycles under 20% of the battery’s nominal capacity.

mpv-shot0001In outer space, your satellite will be bombarded by heavy ions that can short-circuit the transistors inside any IC. Sometimes, these transistors get stuck shorted, and the only way to fix the latch-up condition is to kill power for a little bit. For that reason, you’ll want to include latch-up detectors in the power supply to reset the satellite automatically when this happens. But this means that your code needs to expect occasional unscheduled resets, which in turn means that you need to think about how to save state and re-synchronize your timing, etc.

In short, there are a ridiculous amount of details that you have to attend to and think through before building your own CubeSat. We’ve just scratched the surface of [INCO]’s advice, but if we had to put the talk in a Tweet, we’d write “test everything, and have a plan B whenever possible”. This is, after all, rocket science.


Filed under: robots hacks, solar hacks, wireless hacks

Code Craft-Embedding C++: Hacking the Arduino Software Environment

The Arduino software environment, including the IDE, libraries, and general approach, are geared toward education. It’s meant as a way to introduce embedded development to newbies. This is a great concept but it falls short when more serious development or more advanced education is required. I keep wrestling with how to address this. One way is by using Eclipse with the Arduino Plug-in. That provides a professional development environment, at least.

The code base for the Arduino is another frustration. Bluntly, the use of setup() and loop() with main() being hidden really bugs me. The mixture of C and C++ in libraries and examples is another irritation. There is enough C++ being used that it makes sense it should be the standard. Plus a good portion of the library code could be a lot better. At this point fixing this would be a monumental task requiring many dedicated developers to do the rewrite. But there are a some things that can be done so let’s see a couple possibilities and how they would be used.

The Main Hack

As mentioned, hiding main() bugs me. It’s an inherent part of C++ which makes it an important to learning the language. Up until now I’d not considered how to address this. I knew that an Arduino main() existed from poking around in the code base – it had to be there because it is required by the C++ standard. The light dawned on me to try copying the code in the file main.cpp into my own code. It built, but how could I be sure that it was using my code and not the original from the Arduino libraries? I commented out setup() and it still built, so it had to be using my version otherwise there’d be an error about setup() being missing. You may wonder why it used my version.

When you build a program… Yes, it’s a “program” not a “sketch”, a “daughter board” not a “shield”, and a “linker” not a “combiner”! Why is everyone trying to change the language used for software development?

When you build a C++ program there are two main stages. You compile the code using the compiler. That generates a number of object files — one for each source file. The linker then combines the compiled objects to create an executable. The linker starts by looking for the C run time code (CRTC). This is the code that does some setup prior to main() being called. In the CRTC there will be external symbols, main() being one, whose code exists in other files.

The linker is going to look in two places for those missing symbols. First, it loads all the object files, sorts out the symbols from them, and builds a list of what is missing. Second, it looks through any included libraries of pre-compiled objects for the remaining symbols. If any symbols are still missing, it emits an error message.

If you look in the Arduino files you’ll find a main.cpp file that contains a main() function. That ends up in the library. When the linker starts, my version of main() is in a newly created object file. Since object files are processed first the linker uses my version of main(). The library version is ignored.

There is still something unusual about main(). Here’s the infinite for loop in main():

        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }

The call to loop() is as expected but why is there an if statement and serialEventRun? The function checks if serial input data is available. The if relies on a trick of the tool chain, not C++, which checks the existence of the symbol serialEventRun. When the symbol does not exist the if and its code are omitted.

Zapping setup() and loop()

Now that I have control over main() I can address my other pet peeve, the setup() and loop() functions. I can eliminate these two function by creating my own version of main(). I’m not saying the use of setup() and loop() were wrong, especially in light of the educational goal of Arduino. Using them makes it clear how to organize an embedded system. This is the same concept behind C++ constructors and member functions. Get the initialization done at the right time and place and a good chunk of software problems evaporate. But since C++ offers this automatically with classes, the next step is to utilize C++’s capabilities.

Global Instantiation

One issue with C++ is the cost of initialization of global, or file, scope class instances. There is some additional code executed before main() to handle this as we saw in the article that introduced classes. I think this overhead is small enough that it’s not a problem.

An issue that may be a problem is the order of initialization. The order is defined within a compilation unit (usually a file) from the first declaration to the last. But across compilation units the ordering is undefined. One time all the globals in file A may be initialized first and the next time those in file B might come first. The order is important when one class depends on another being initialized first. If they are in different compilation units this is impossible to ensure. One solution is to put all the globals in a single compilation unit. This may not work if a library contains global instances.

A related issue occurs on large embedded computer systems, such as a Raspberry Pi running Linux, when arguments from the command line are passed to main(). Environment variables are also a problem since they may not be available until main() executes. Global instance won’t have access to this information so cannot use it during their initialization. I ran into this problem with my robots whose control computer was a PC. I was using the robot’s network name to determine their initial behaviors. It wasn’t available until main() was entered, so it couldn’t be used to initialize global instances.

This is an issue with smaller embedded systems that don’t pass arguments or have environment values but I don’t want to focus only on them. I’m looking to address the general situation that would include larger systems so we’ll assume we don’t want global instances.

Program Class

The approach I’m taking and sharing with you is an experiment. I have done something similar in the past with a robotics project but the approach was not thoroughly analyzed. As often happens, I ran out of time so I implemented this as a quick solution. Whether this is useful in the long run we’ll have to see. If nothing else it will show you more about working with C++.

My approach is to create a Program class with a member run() function. The setup for the entire program occurs in the class constructor and the run() function handles all the processing. What would normally be global variables are data members.

Here is the declaration of a skeleton Program class and the implementation of run():

class Program {
public:
        void run();
        static Program& makeProgram() {
                static Program p;
                return p;
        }

private:
        Program() { }
        void checkSerialInput();
};

void Program::run() {
        for (;;) {
                // program code here
                checkSerialInput();
        }
}

We only want one instance of Program to exist so I’ve assured this by making the constructor private and providing the static makeProgram() function to return the static instance created the first time makeProgram() is called. The Program member function checkSerialInput() handles checking for the serial input as discussed above. In checkSerialInput() I introduced an #if block to eliminate the actual code if the program is not using serial input.

Here is how Program is used in main.cpp:


void arduino_init() {
        init();
        initVariant();
}

int main(void) {
        arduino_init();
        Program& p = Program::makeProgram();
        p.run();
        return 0;
}

The function initArduino() is inlined and handles the two initialization routines required to setup the Arduino environment.

One of the techniques for good software development is to hide complexity and provide a descriptive name for what it does. These functions hide not only the code but, in one case, the conditional compilation.

Redbot Line Follower Project

redbotThis code experiment uses a Sparkfun Redbot setup for line following. This is a two wheeled robot with 3 optical sensors to detect the line and an I2C accelerometer to sense bumping into objects. The computer is a Sparkfun Redbot Mainboard which is compatible with the Arduino Uno but provides a much different layout and includes a motor driver IC.

This robot is simple enough to make a manageable project but sufficiently complex to serve as a good test, especially when the project gets to the control system software. The basic code for handling these motors and sensors comes from Sparkfun and uses only the basic pin-level Arduino routines. I can’t possibly hack the entire Arduino code but using the Sparkfun code provides a manageable subset for experimenting.

For this article we’ll just look at the controlling the motors. Let’s start with the declaration of the Program class for testing the motor routines:

class Program {
public:
        void run();
        static Program& makeProgram() {
                static Program p;
                return p;
        }

private:
        Program() { }
        static constexpr int delay_time { 2000 };

        rm::Motor l_motor { l_motor_forward, l_motor_reverse, l_motor_pwm };
        rm::Motor r_motor { r_motor_forward, r_motor_reverse, r_motor_pwm };
        rm::Wheels wheels { l_motor, r_motor };

        void checkSerialInput();
};

There is a namespace rm enclosing the classes I’ve defined for the project, hence the rm:: prefacing the class names. On line 11 is something you may not have seen, a constexpr which is new in C++ 11 and expanded in C++14. It declares that delay_time is a true constant used during compilation and will not be allocated storage at run-time. There is a lot more to constexpr and we’ll see it more in the future. One other place I used it for this project is to define what pins to use. Here’s a sample:

constexpr int l_motor_forward = 2;
constexpr int l_motor_reverse = 4;
constexpr int l_motor_pwm = 5;
constexpr int r_motor_pwm = 6;
constexpr int r_motor_forward = 7;
constexpr int r_motor_reverse = 8;

The Motor class controls a motor. It requires two pins to control the direction and one pulse width modulation (PWM) pin to control the speed. The pins are passed via constructor and the names should be self-explanatory. The Wheels class provides coordinated movement of the robot using the Motor instances. The Motor instances are passed as references for the use of Wheels. Here are the two class declarations:

class Motor : public Device {
public:
        Motor(const int forward, const int reverse, const int pwm);

        void coast();
        void drive(const int speed);

        int speed() const {
                return mSpeed;
        }

private:
        void speed(const int speed);

        PinOut mForward;
        PinOut mReverse;
        PinOut mPwm;
        int mSpeed { };
};


class Wheels {
public:
        Wheels(Motor& left, Motor& right) :
                        mLeft(left), mRight(right) {
        }

        void move(const int speed) {
                drive(speed, speed);
        }
        void pivot(const int speed) {
                drive(speed, -speed);
        }
        void stop() {
                mLeft.coast();
                mRight.coast();
        }

        void drive(const int left, const int right) {
                mLeft.drive(left);
                mRight.drive(right);
        }

private:
        Motor& mLeft;
        Motor& mRight;
};

The workhorse of Wheels is the function drive() which just calls the Motor drive() functions for each motor. Except for stop(), the other Wheels functions are utilities that use drive() and just make things easier for the developer. The compiler should convert those to a direct call to driver() since they are inline by being inside the class declaration. This is one of the interesting ways of using inline functions to enhance the utility of a class without incurring any cost in code or time.

The run() method in Program tests the motors by pivot()ing first in one direction and then the other at different speeds. A pivot() rotates the robot in place. Once the speed is set it continues until changed so the delay functions simply provide a little time for the robot to turn. Here’s the code:

void Program::run() {
        for (;;) {
                wheels.pivot(50);
                delay (delay_time);

                wheels.pivot(-100);
                delay(delay_time);

                checkSerialInput();
                if (serialEventRun) {
                }
        }
}

Wrap Up

The Redbot project is an interesting vehicle for demonstrating code techniques. The current test of the motor routines demonstrates how to override the existing Arduino main(). Even if you don’t like my approach with Program, the flexibility of using your own main() may come in handy for your own projects. The next article is going to revisit this program using templates.

THE EMBEDDING C++ PROJECT

Over at Hackaday.io, I’ve created an Embedding C++ project. The project will maintain a list of these articles in the project description as a form of Table of Contents. Each article will have a project log entry for additional discussion. Those interested can delve deeper into the topics, raise questions, and share additional findings.

The project also will serve as a place for supplementary material from myself or collaborators. For instance, someone might want to take the code and report the results for other Arduino boards or even other embedded systems. Stop by and see what’s happening.


Filed under: Arduino Hacks, Hackaday Columns, Software Development, software hacks

The Top Ten Most Popular Make: Posts for 2015

sliding-bookcase-doorFind out what the top ten most popular articles where on the site this year

Read more on MAKE

The post The Top Ten Most Popular Make: Posts for 2015 appeared first on Make: DIY Projects, How-Tos, Electronics, Crafts and Ideas for Makers.

32C3: Running Linux On The PS4

At the 2010 Chaos Computer Congress, fail0verflow (that’s a zero, not the letter O) demonstrated their jailbreak of the PS3. At the 2013 CCC, fail0verflow demonstrated console hacking on the Wii U. In the last two years, this has led to an active homebrew scene on the Wii U, and the world is a better place. A few weeks ago, fail0verflow teased something concerning the Playstation 4. While this year’s announcement is just a demonstration of running Linux on the PS4, root0verflow can again claim their title as the best console hackers on the planet.

Despite being able to run Linux, there are still a few things the PS4 can’t do yet. The current hack does not have 3D acceleration enabled; you won’t be playing video games under Linux with a PS4 any time soon. USB doesn’t work yet, and that means the HDD on the PS4 doesn’t work either. That said, everything to turn the PS4 into a basic computer running Linux – serial port, framebuffer, HDMI encoder, Ethernet, WiFi, Bluetooth, and the PS4 blinkenlights – is working.

Although the five-minute lightning talk didn’t go into much detail, there is enough information on their slides to show what a monumental task this was. root0verflow changed 7443 lines in the kernel, and discovered the engineers responsible for the southbridge in the PS4 were ‘smoking some real good stuff’.

This is only root0verflow’s announcement that Linux on the PS4 works, and the patches and bootstrap code are ‘coming soon’. Once this information is released, you’ll need to ‘Bring Your Own Exploit™’ to actually install Linux.

Video of the demo below.


Filed under: cons, playstation hacks

Gene editing tech named Science magazine’s Breakthrough of the Year

3d render of DNA spirals.

CRISPR, a genome-editing technology that has been progressing rapidly in the last three years, has just been named Science’s Breakthrough of the Year. CRISPR is a futuristic technique that can be used to edit and manipulate the DNA of any organism—crops, livestock, and even humans. It can allow scientists to control gene expression and selectively turn genes on or off.

In 2015, two significant advances contributed to CRISPR’s status as this year’s Breakthrough technique. The first was the engineering of a “gene drive” in insects that could benefit human health by eliminating pests and the diseases they carry. The second was gene editing performed in human embryos, a process that sounds like something out of a science fiction novel and raises a host of legal and ethical questions about the manipulation of human DNA to create customized offspring.

CRISPR is not only remarkable for its ability to manipulate the DNA of a targeted organism, it is also remarkable because it is an extremely inexpensive and relatively easy technique to use. In terms of the resources it requires, it could be implemented in almost any microbiology lab worldwide.

Read 9 remaining paragraphs | Comments

In 2015, promising surveillance cases ran into legal brick walls

(credit: Gage Skidmore)

Today, the first Snowden disclosures in 2013 feel like a distant memory. The public perception of surveillance has changed dramatically since and, likewise, the battle to shape the legality and logistics of such snooping is continually evolving.

To us, 2015 appeared to be the year where major change would happen whether pro- or anti-surveillance. Experts felt a shift was equally imminent. "I think it's impossible to tell which case will be the one that does it, but I believe that, ultimately, the Supreme Court will have to step in and decide the constitutionality of some of the NSA's practices," Mark Rumold, an attorney with the Electronic Frontier Foundation, told Ars last year.

The presumed movement would all start with a lawsuit filed by veteran conservative activist Larry Klayman. Filed the day after the initial Snowden disclosures, his lawsuit would essentially put a stop to unchecked NSA surveillance. In January 2015, he remained the only plaintiff whose case had won when fighting for privacy against the newly understood government monitoring. (Of course, it was a victory in name only—the judicial order in Klayman was stayed pending the government’s appeal at the time).

Read 34 remaining paragraphs | Comments

2015: As the Hardware World Turns

Space for Europe and for all humankind: A brief history of the ESA

In November 2014, a strange-looking little spider of a spacecraft caught the world's attention. It may have been one of the oddest-looking pioneers of all time, resembling a mini-refrigerator attached to an insect's legs. The spacecraft, christened Philae, electrified both die-hard space fans and casual observers despite its alien appearance. It made the first-ever soft landing on the face of a comet.

Philae actually made soft landings, as it “bounced” twice on the comet's surface after its landing harpoons did not deploy as planned. Eventually it settled down in its final resting spot, a craggy, dark region called Abydos. Here it delivered another surprise when it “reawakened” seven months after a lack of solar power put it into hibernation.

For some, one of the largest surprises was the identity of people who built Philae and the Rosetta orbiter that delivered it to the comet. While those casually in touch with space news focused on the mission's dramatic twists and turns, dedicated space-watchers recognized it as a historic mission for one oft-overlooked group—the European Space Agency (ESA).

Read 32 remaining paragraphs | Comments

Ars’ favorite science images of 2015

Science is an inherently visual activity. Yes, we can know about all sorts of things in the abstract and try to envision them in our minds. But it's one thing to hear a description of the developing brain, and another thing entirely to see one as it's developing. In some cases, images tell us things that it was simply impossible to know otherwise.

2015's science came with its own host of images, some of them taken by the scientists and engineers involved, others we managed to take ourselves. So, we put together a gallery of some of our favorites from this past year; what follows is a little bit on why we liked them.

New worlds: Pluto is too small to have much heat left over from its formation, so the expectations were that we'd see little more than a crater-ridden landscape. Pluto is anything but, and the images have left scientists scrambling to explain a landscape with complex geology. Similar things are true about another dwarf planet, the largest object in the asteroid belt, Ceres. Here, the surface was a crater-scarred landscape, but it contained enigmatic bright spots that continued to grab everyone's attention as the Dawn probe moved closer.

Read 7 remaining paragraphs | Comments

Break Your Wrist? Twitter-Enable That Plaster Cast

Plaster casts are blank canvases for friends and family to post their get well messages. But if it’s holiday season, adding blinky LED lights to them is called for. When [Dr Lucy Rogers] hurt her hand, she put a twitter enabled LED Christmas tree on her cast.

The hardware is plain simple – some RGB LEDs, an Arduino, a blue tooth module and a battery. The LEDs and wires formed the tree, and all the parts were attached to the plaster cast using Velcro. This allowed the electronics to be removed during future X-ray scans. The fun part was in connecting the LEDs to the #CheerLights project. CheerLights is an “Internet of Things” project that allows people’s lights all across the world to synchronize to one color set by a Tweet. To program the Arduino, she used code written by [James Macfarlane] which allowed the LED color to be set to any Cheerlights color seen in blue tooth UART data.

Connectivity is coordinated using MQTT — lightweight standard popular with connected devices. By connecting the MQTT feed to the cheerlights topic from [Andy Stanford-Clark’s] MQTT feed (mqtt://iot.eclipse.org with the topic cheerlights) the lights respond to tweets (Tweet #cheerlights and a color). The LED colors can also be selected via the phone from the color picker tool in the controller, or directly via the UART. If the Bluetooth connection is lost, the LEDs change colors randomly. Obviously, delegates had great fun when she brought her Twitter enabled LED blinky lights plaster cast arm to a conference. It’s not as fun unless you share your accomplishments with others!


Filed under: Holiday Hacks

32C3: Dieselgate — Inside the VW’s ECU

[Daniel Lange] and [Felix Domke] gave a great talk about the Volkswagen emissions scandal at this year’s Chaos Communication Congress (32C3). [Lange] previously worked as Chief architect of process chain electronics for BMW, so he certainly knows the car industry, and [Domke] did a superb job reverse-engineering his own VW car. Combining these two in one talk definitely helps clear some of the smog around the VW affair.

[Lange]’s portion of the talk basically concerns the competitive and regulatory environments that could have influenced the decisions behind the folks at VW who made the wrong choices. [Lange] demonstrates how “cheating” Europe’s lax testing regime is fairly widespread, mostly because the tests don’t mimic real driving conditions. But we’re not sure who’s to blame here. If the tests better reflected reality, gaming the tests would be the same as improving emissions in the real world.

As interesting as the politics is, we’re here for the technical details, and the reverse-engineering portion of the talk begins around 40 minutes in but you’ll definitely want to hear [Lange]’s summary of the engine control unit (ECU) starting around the 38 minute mark.

[Domke] starts off with a recurring theme in our lives, and the 32C3 talks: when you want to reverse-engineer some hardware, you don’t just pull the ECU out of your own car — you go buy another one for cheap online! [Domke] then plugged the ECU up to a 12V power supply on his bench, hooked it up, presumably to JTAG, and found a bug in the firmware that enabled him to dump the entire 2MB of flash ROM into a disassembler. Respect! His discussion of how the ECU works is a must. (Did you know that the ECU reports a constant 780 RPM on the tacho when the engine’s idling, regardless of the actual engine speed? [Domke] has proof in the reverse-engineered code!)

The ECU basically takes in data from all of the car’s sensors, and based on a number of fixed data parameters that physically model the engine, decides on outputs for all of the car’s controls. Different car manufacturers don’t have to re-write the ECU code, but simply change the engine model. So [Domke] took off digging through the engine model’s data.

Long story short, the driving parameters that trigger an emissions reduction exactly match those that result from the EU’s standardized driving schedule that they use during testing — they’re gaming the emissions tests something fierce. You’ve really got to watch the presentation, though. It’s great, and we just scratched the surface.

And if you’re interested in our other coverage of the Congress, we have quite a collection going already.


Filed under: news, security hacks, transportation hacks

Magic Mirror on the Wall, “Is Pi or ESP, Fairest of All?”

“What’s the weather like, honey?” “I don’t know. Let me check the mirror.”  The mirror?

Both [Dylan Pierce] and [Dani Eichorn] have mirror projects that display the weather. They took two different approaches which makes for an interesting comparison. [Dylan] uses a Rapsberry Pi with an actual monitor behind the mirror. [Dani] puts an OLED behind the mirror driven by a ESP8266.  It appears there is more than one way to hack a mirror, or anything, which is what makes hacking fun.

Raspberry Pi Booting Framing Mirror and Monitor

[Dani] started with a picture frame, adding tinting film to the glass so it would reflect. A small section of tint was removed to allow the OLED to be seen. The ESP8266 software connects to the Weather Underground to get the latest information.

The Raspberry Pi version by [Dylan] puts a 27″ monitor behind the mirror. That is either terribly impressive or way over the top but seeing Linux boot behind the mirror makes it worth the effort. The Pi generates a web page which makes this adaptable as a general purpose kiosk.

A video of [Dani’s] mirror in operation, after the break.

 


Filed under: misc hacks, Raspberry Pi, software hacks

Must-Have Overkill Christmas Tree Lights

The yuletide fire is out, so we’re starting to receive this year’s Christmas hacks. [Chris] sent us his awesome video-mapped tree lighting hack. His project made clever use of a bunch of cool tools, so even if you’re not thinking forward to next December, it’s worth a look. Still images don’t do it justice; check out the video below the break.

The end result is an addressable string of WS2812B LEDs connected up to a Raspberry Pi Zero that can display a video image even though it’s wrapped around a roughly cone-shaped (pine) object. But this is actually more impressive than you’d think at first; how would you map a flat image to a string of LEDs wrapped around a tree?

[Chris]’s solution was to write a routine that lit up the LEDs in a unique pattern and then detected them using OpenCV and a webcam, making the mapping directly. He then samples images from a video at exactly the points where the pixels are located on the tree, and sends this data out to the LEDs.

The basic framework here should transform fairly easily into a generic image-mapping procedure with randomly located LEDs, so we think it’s a hack that’ll outlast the season. And because it runs on the Pi Zero, everything is in Python so it’d be a good project for beginners to replicate. However, the code section on the project page still lists it as coming soon. We hope so!



Filed under: Holiday Hacks, led hacks, video hacks