Friday, December 7, 2012

STM32 Single-Player Pong with Wii Nunchuk

I am just finishing up a class about embedded devices. For our final project, my partner and I have to write C code to interface with an STM32F100x microcontroller. Since the start of the semester, we have been writing drivers for various peripheral devices, such as a Wii Nunchuk and an LCD screen. Check out our demo video for the 1-player pong game we are currently creating:

Monday, July 9, 2012

Introducing TripleStack

A preliminary version of TripleStack: https://github.com/jdolitsky/TripleStack

TripleStack is a mini web framework based on node.js and socket.io. It is an inclusive program that sets up 3 servers running on 3 different ports. One server handles all incoming requests on port 80 (stop httpd), another server retrieves actual files on port 81, and the third is a socket.io server. Additionally, there is client-side javascript included to easily make socket calls and store responses. Updates coming soon.

TripleStack startup page

Wednesday, February 29, 2012

Twitter account automation using PHP, cron, and the Twitter API

Code example makes use of themattharris tmhOAuth library:
https://github.com/themattharris/tmhOAuth

1.) Sign into the Twitter developers site using the account you want to automate

2.) Create a new app by hovering over your user name in the top right corner and clicking "My Applications"

3.) In the 'Settings' tab, change permissions of your app to "Read, Write and Access direct messages"

4.) In the 'Details' tab, at the bottom of the page, click "Create my access token"

5.) Copy and paste your consumer key, consumer secret, access token and access token secret from the 'Details' tab into the appropriate location in the example code

6.) In the code, change your outgoing tweets by modifying the $possibilities array and adding more levels of customization/randomization

7.) Test your script on the command line or browser:
# php /path/to/file/twitter.php (command line) 
or
http://mywebsite.com/twitter.php (browser)

8.) If the script prints out "200 (your message)", then everything has succeeded. Check your account on the Twitter website to make sure you have posted a new status.

9.) Once your script is working and complete, setup a cron job on the command line (replace path to script and PHP based on your configuration/OS):
# crontab -e
*/5 * * * * /usr/local/bin/php /path/to/file/twitter.php


This cron job is set to run every 5 minutes. Your Twitter account will now be posting random tweets every 5 minutes.

This method is especially powerful when used with additional resources from the Twitter REST API.

Code

<?php

// themattharris tmhOAuth library
require 'tmhOAuth.php';

// credentials from https://dev.twitter.com/
$tmhOAuth = new tmhOAuth(array(
  'consumer_key' 
    => 'xxxxxxxxxxxxxxxxxxxxxx',
  'consumer_secret' 
    => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  'user_token' 
    => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  'user_secret' 
    => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
));

// all possible statuses
$possibilities = array('Random status 1 #hashtag1',
                       'Random status 2 #hashtag2',
                       'Random status 3 #hashtag3',
                       'Random status 4 #hashtag4',
                       'Random status 5 #hashtag5',
                       'Random status 6 #hashtag6',
                       'Random status 7 #hashtag7',
                       'Random status 8 #hashtag8');

// pick a status randomly
$posIndex = array_rand($possibilities,1);
$msg = $possibilities[$posIndex];

// always limit the message to 140 characters
$out = substr($msg, 0, 140);

// post status to authenticated user's profile
$code = $tmhOAuth->request('POST', 
                           $tmhOAuth->url('1/statuses/update'),  
                           array('status' => $out));

// echo response code/error and the message sent
echo $code.'  '.$out;

?>

Sunday, February 26, 2012

Dynamic PHP user property creation based on database field names

Minimal code defining a workable user class/mini MVC. Upon creation, the SiteUser object defines public properties based off of database field names and data.

If you change anything about your database table (remove or add fields, change schema) the class will still create properties based on the current database table field names and values.

Another benefit is that you only need to hit the database for user data one time, when they're first logging in. All user data (first name, last name, etc.) is then stored in the session as part of the SiteUser object.

<?php

// connect to database
// ...

session_start();

class SiteUser {
    function __construct($data) {
        $this->data = $data;

        // saves entire object as session variable
        // (maintains all user properties)
        $_SESSION['SiteUser'] = $this;
        
        // sets all properties of SiteUser based
        // on all field names from database
        foreach ($this->data as $key => $value) {
            $this->{$key} = $value;
        }
    }

    function __toString() {
        return json_encode($this->data);
    }

    // other user functions, refer to properties
    // like '$this->userId' based on field names
    // from the database
    // ex.)
    function writeComment($text) {
        // a comments table with 3 fields, 
        // commentId (not null), posterId, and commentText
        $query = 'INSERT INTO comments VALUES(NULL, '
                          .$this->userId.', "'.$text.'");';
        mysql_query($query);
    }
}

// get user ID from somewhere ...
$userId = 1;

$query = "SELECT * FROM userTable WHERE userId=$userId;";
$response = mysql_fetch_assoc(mysql_query($query));

$new_user = new SiteUser($response);

// prints out all user data in JSON
echo $new_user;

echo '<br><br>';

// access user's first name etc. (based on db field names)
echo $new_user->firstName;

// write new comment on behalf of user,
// get comment from somewhere
$comment = $_REQUEST['comment'];
$new_user->writeComment($comment);

?>

Shell script to (1) log into remote box, (2) connect to MySQL db, and (3) show all tables

Requires expect (on RedHat: "su", "yum install expect")

Run as follows: expect /path/to/file/myScript.sh

set timeout -1
spawn ssh username@myserver.com
expect "*?assword:*"
send -- "password"
expect "*#*"
send -- "mysql -u db_username -p\r"
expect "*?assword:*"
send -- "db_password"
expect "*>*"
send -- "use my_database;\r"
expect "*>*"
send -- "show tables;\n"
interact +++ return
expect eof

to exit MySQL
press ctrl+c

to close connection
type "+++"
press ctrl+c

Continual rotating background image with jQuery

Example:
http://jsfiddle.net/Wz8Py/


















makes use of this jQuery plug-in:
http://code.google.com/p/jqueryrotate

image will be forced into square dimensions, so use an image that is a square


<div style="z-index:-2;position:fixed;width:100%;height:100%;">
<img id="mainImg" src="http://2.bp.blogspot.com/-IuwcSwf0v8Y/TlvC9WmS_nI/AAAAAAAAAGU/KG0IOybyrWQ/s1600/3d_space_33-3D-Space-Wallpapers.jpg" style="display:none;"/>
</div>
<div id="dog" style="background:url(http://gif-favicon.com/images/animals/dog-face-transparent-background-0250-10015.gif);width:250px;height:223px;margin:0 auto;position:fixed;z-index:-1;"></div>


<script>
var count 0;
function rotateImg({            
    $('#mainImg').rotate(count);

    $('#dog').rotate(-count*20);
    
    // how fast to rotate image
    count += .12;
    
    if (count >= 360{
        count 0.0;
    }
}
$(document).ready(function({
    // affects how much the image will overlap screen size
    var enlarge 2.6;

    var docWidth $(document).width();
    var imgSize enlarge*docWidth;   
    var mLeft -(imgSize-docWidth)/2
    var docHeight $(document).height();
    var mTop (docHeight imgSize)/2;
   

    $('#mainImg').css('width',imgSize);
    $('#mainImg').css('height',imgSize);
    $('#mainImg').css('display','inline');
    $('#mainImg').css('margin-left',mLeft);
    $('#mainImg').css('margin-top',mTop);  

    var loop 0;
    
    // refresh rate
    var time 5;
    
    setInterval(function({
            rotateImg();
    }time);
    
    var dogLeft (docWidth $('#dog').width())/2;
    var dogTop (docHeight $('#dog').height())/2;
    
    $('#dog').css('margin-left'dogLeft);
    $('#dog').css('margin-top'dogTop);
    

    $(window).resize(function({
            docWidth $(document).width();
            imgSize enlarge*docWidth;
            mLeft -(imgSize-docWidth)/2;  
            docHeight $(document).height();   
            mTop (docHeight imgSize)/2;  
        
            $('#mainImg').css('width',imgSize);
            $('#mainImg').css('height',imgSize);
            $('#mainImg').css('display','inline');
            $('#mainImg').css('margin-left',mLeft);
            $('#mainImg').css('margin-top',mTop)

            dogLeft (docWidth $('#dog').width())/2;
            dogTop (docHeight $('#dog').height())/2;
    
            $('#dog').css('margin-left'dogLeft);
            $('#dog').css('margin-top'dogTop);     
    
    });
});

</script>