This script is written in python to perform EXFS corrections of digital photos. This script traverses the specified directory, stores all images, then performs the required transform to make the images display correctly.

#! /usr/bin/python
import time
import os
from random import randint
import pexif
from PIL import Image, ExifTags
photo_list = [] #List of all photo paths traversed by OS.WALK
for root, dirs, files in os.walk(“/yourpath/”):
        for file in files:
                if file.endswith(“.png”) or file.endswith(“.jpeg”) or file.endswith(“.jpg”) $
#                       print(os.path.join(root, file)) #Debug for path checking
                        photo_list.append(os.path.join(root, file)) #Add the current path+ph$
for photo in photo_list:
        #print(“Try this: ” + photo)
        img = pexif.JpegFile.fromFile(photo)
        #print(photo + “<- Path Orient ->   ” + str(img.exif.primary.Orientation[0]))
        try:
                image=Image.open(photo)
                for orientation in ExifTags.TAGS.keys():
                        if ExifTags.TAGS[orientation]==’Orientation’:
                                break
                exif=dict(image._getexif().items())
                if exif[orientation] == 3:
                        image=image.rotate(180, expand=True)
                elif exif[orientation] == 6:
                        image=image.rotate(270, expand=True)
                elif exif[orientation] == 8:
                        image=image.rotate(90, expand=True)
                image.save(photo)
                image.close()
        except (AttributeError, KeyError, IndexError):
        # cases: image don’t have getexif
                print(“broke”)

I was looking for a quick way to scan every photo on my media server, and display them one at a time in a photo slideshow. I wanted a python program to power my digital photo frame using a raspberry pi.

My hardware setup is a file share that is mapped from a Raspberry Pi. The software piece is a simple python script running from my CGI-Bin. The code is pasted below. It is a quick hack that I plan to optimize later, but I hope it helps you if you are in need of a solution.

#! /usr/bin/python
print “Content-type: text/html\n\n”;
#DOCTYPE keeps inducing an error violating the CSS so it is commented out for now
#print(“””<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”
import time
import os
from random import randint
photo_list = [] #List of all photo paths traversed by OS.WALK
display_list = [] #List of photos to be displayed (Currently only using one photo at a time)
for root, dirs, files in os.walk(“/mnt/storage/Pictures/Universal_Trip_2017/”): #Traverse from the listed root directory
        for file in files:
                if file.endswith(“.png”) or file.endswith(“.jpeg”) or file.endswith(“.jpg”) or file.endswith(“.JPG”): #The file types to add to the photo_list
#                       print(os.path.join(root, file)) #Debug for path checking
                        photo_list.append(os.path.join(root, file)) #Add the current path+photo to display_list
count = 0
while count < 1:
        random_pic = randint(0,len(photo_list)-1)
        display_list.append(photo_list[random_pic])
        count = count + 1
#HTML code ot generate the webpage (Edit as needed)
print(“<html>”)
print(“<head>”)
print(“<title>Xile Image Magic</title>”)
print(‘<link rel=”stylesheet” type=”text/css” href=”../im_style.css” />’)
print(‘<meta http-equiv=”refresh” content=”5″ />’)
print(“</head>”)
print(“<body>”)
#Print all images added to the display_list
for photo_path in display_list:
#       print(photo_path[21:])  #Debug
        print(“<div class=\”main\”>”)
        print(“<img src=\”” + “/image_magic/” + photo_path[21:] + “\” alt=\”\” />”)
        print(“</div>”)
#Optional Statement for printing the path of the current displayed photo
print(“<h5>” + display_list[0] + “</h5>”)
print(“</body>”)
print(“</html>”)
I created some CSS to make the displayed page a little easier on the eyes.
body
{
background-color: #123552;
}img
{
margin: 2px;
border: 1px solid #ccc;
border-radius: 8px;
display: block;
margin: auto;
margin-bottom: 2px;
height: 85%;
width: auto;
}div.main img
{
margin: 2px;
border: 1px solid #ccc;
border-radius: 8px;
display: block;
margin: auto;
margin-bottom: 2px;
height: 85%;
width: auto;
}h5, h6
{
display: block;
margin: auto;
border: 1px solid #ccc;
text-align: center;
background-color: #496C89;
color: white;
width:50%;
}
Also, because I am using a NAS, I had to edit my Apache Server to allow me to use an alias to access the server. The snippet from my Apache2 conf is pasted below.
Edit: /etc/apache2/sites-available/000-default.conf
Alias /image_magic/ /your/mount/point/
<Directory “/mnt/storage/Pictures/”>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
#Order allow,deny
#Allow from all
Require all granted
</Directory>
 I hope you find this helpful in your attempt to make your own live photo display.

 

Python Cheat Sheet – Working With Lists

Working with Lists: A quick description of different operations that can be performed on a python list

#Declare a list with 2 initial values
computers = ["ibm", "apple"]

#2 Different ways to add items to my existing list
computers.append ("dell")
computers.insert(0, "gateway")

print("\nA complete list of computers I have worked on")
print(computers)

#Sorted prints the list without changing it, sort modifys the list
print("\nA sorted list of computers I have worked on")
print(sorted(computers))
computers.sort()

print(computers)
print("")

#A loop to print each item in title case
 for computer in computers:
      print(computer.title())

computers.pop()
computers.remove("gateway")
print(computers)

#Slicing
print(computers[0:1])

#Print Last
print(computers[-1])

 

Building A Quadcopter

I have been working on building a custom Quad Copter with parts ordered from Hobby King.

quad 

Materials List:

 

Wiring The Remote

The list below is the current way I have the remote wired to the flight controller.

  • AIL – CH1
  • ELE – CH2
  • THR – CH3
  • RUD – CH4
  • AUX –  CH6

WIRELESS RECEIVER receiver wireing

 

Wiring the Quad

speed controller

 

Remote Configuration

The picture below is how I have the remote configured.

remote KK2 Trim Setting

Learning to Build with Balsa Foam

I am learning how to build models that I can animate with an Arduino. After much exploration, I have decided on Balsa Foam. It is easy to shape, carve and customize. This article will help show you how I learned to build models with Balsa Foam.

 

The pictures below are the tools I have been experimenting with. The wood dowels were hand carved to be different types of brick and stone stamps. I press the sharp edges onto the foam to imprint a design. Traditional wood carving tools and a razor saw are also helpful.

Tools Overview Wood Tools

The pictures below are some examples of my work. The brickwork is a variety of press tools. The vase was created by turning a block in a Dremel like a lathe. I shaped it with sand paper and an Xacto knife.

Example Brick Work Balsa Foam Vase 

More to come later…

 

The Journey to Building Remote Controls

I recently finished a project that involves an Arduino powered remote control. I learned a lot of things along the way about setup and programming that I wanted to share to help others avoid pitfalls.

Xbee Remote 2

Hardware Issues

The Adafruit Xbee breakout board supports directly transmitting analog inputs to a second Xbee receiver. This is great for simple projects, but I was looking for very strict control over the Remote and the Robot. I also had a dream of later using the stick to control an actuator mounted to the robot using the same stick that controls the movement of the robot. This would certainly require a micro-controller on both ends (Or so I thought).

As I look back, I probably didn’t even need an Arduino to handle the Remote Control portion as I could have just handled all the interpolation on the robot side. One unforeseen benefit is that I now have a remote that can be used for virtually any remote project I come up with in the future since all the interpolation has already been programmed.

Software Issues

The library for handling Xbee transmission is fairly easy to use, but I had some issues on the receiver side. I had two major hangups. The first was being able to read the entire string being passed to the receiver.

It took some time to realize that the string was being transmitted character by character. I initially tried the code below but it did not properly read in the entire string.

Receiver Code:
void loop()
{
if (mySerial.available())
{
Serial.println((String)mySerial.read());
}
}

I then tried the code below which was able to read the string, but I could not properly parse the whole string.


Receiver Code:
void loop()
{
if (mySerial.available())
{
Serial.write(mySerial.read());
}
}

Finally, I came to this version of code. It waits for something in the buffer and then reconstructs the string in a loop one character at a time.

while(mySerial.available())
{
character = mySerial.read();
content.concat(character);
}
if (content != “”)
{
content.trim();
Serial.print(content);
}

My last major problem was an issue in the way I was originally transmitting control instructions. I was just waiting for input and then transmitting the input over and over which caused a buffer overload on the receiving side. My code would send the Forward command over and over resulting in the backing up of the receiving buffer. When I then transmitted a stop command, it would often get lost in the flood off control commands.

I remedied this situation by transmitting the control instruction only once and setting a “last sent” flag to check if the command was the same or not. This stopped the flood and only transmitted an instruction via Xbee when it was different that before. This technique can be viewed in the completed code for the Arduino Powered Remote Control Robot project.

Summary

Every project should come with a healthy bit of learning along the way. I learned much more about the hardware and how much of a difference a slight change in code implementation can make to address limitations in the hardware.

Another major learning point of this project was the importance of version control along the way for the purposes of learning. I have always been a back-up advocate, but the evolution of the code is always extremely important. It shows you where you were and where you have come too. Sometimes, it is nothing but a testament to how far you have come, but sometimes it is a road map to help others learn.

Cheers,

Justin

 

A Look Ahead

My first large project How-To has been published and I am already looking at my next project. I will continue to update the Arduino Powered Remote Controlled Robot post to make it more clear and easy to follow. I also plan to post some small troubleshooting tutorials centered around some issues I encountered working on the project.

Next, I have set my sights on a Built-From-Scratch quadcopter. I hope to use the Open Beam system as the rig and some real RC quality motors and flight controllers. I will post updates on that project when it gets underway.

Cheers,

Justin

Arduino Powered Remote Control Robot

I have been working on a Arduino Powered Robot that could be remote controlled. (I will continue to update this with more detail). The video below shows the prototype robot working via the remote control. This article will describe how I built the Robot, the materials used, and the program that controls it.

Materials List

This project was completed with materials ordered entirely from Adafruit.com. If your not familiar with them, check out their excellent tutorials and supplies for makers.

 

The Remote Control

The remote is a BoArduino from Adafruit attached to a clear breadboard with an Analog Control Knob and a Xbee Series 1 transmitter. The wiring is pretty Simple for the remote. The control knob is wired to the analog pins on the BoArduino along with a +5V and a Ground wire. The Xbee is wired from the RX and TX pins to the Digital 3 and Digital 2 pins respectively along with a +5 and a ground wire. Some of the extra black wires in the picture hold my breadboard wires in place so they don’t pull loose and are not needed.

Xbee Remote 2    Xbee Remote

The Sketch below is the code for the remote. Feel free to download and modify it. Suggestions for improvement are also welcome.

Remote Control Sketch

 

The Wireless Robot

The robot is Arduino powered and Xbee controlled. A program waits for Xbee transmitted commands and then determines which of four continuous motion servos to actuate. The frame is composed of components from an Open Beam kit. The nice thing about Open Beam is that the plastic Arduino mounting plate slides into the sides of each beam. This creates a secure and easy electronics mount. Just place a beam of the appropriate length on each side and secure in place with the Open Beam corner brackets.

Robot_Front Robot_Rear

The picture below shows how everything is connected. The program expects the left side servos to be connected to Pin 4 and the right side servos to be connected to Pin 8. In the picture below, you can see that both servos on the left share the same +5v, ground, and control wire as do the servos of the right. Digital Pins 2 and 3 are connected to the Xbee pins to the TX and RX pins respectively.

Robot_Top

The sketch below contains the program to control the robot via wireless commands received from the remote.

Remote Robot Sketch

This is a work in progress. It was a fun little project and it is quite rewarding to create a remote controlled robot. I plan to add a remote control arm for simple tasks. What would you add to the robot? Thanks for reading. Good Luck building!

– Justin

New Site Upgrade

I have been going through some upgrades to make it easier to posts about new projects so I decided to go with a web site that would faciliate sharing ideas and new projects. I hope you enjoy the new format we develop to share projects and ideas.

i have been tinkering for a while and finally have the time to post some things I have been working on. You will see them slowly start appearing here soon. .