Monday, May 11, 2015

Porch Couch

Howdy Campers

I give you porch couch. The magnificent and glorious addition to our small deck of nothingness. After multiple hours of planning and one, HUGE, Home depot run. We built this monstrosity.

Pretty sweet right?

Yeah.

-Max

Teaching Assistant for ECEN 1400

Howdy Campers,

Its been a while since my last post, and by that I mean a full year. So lets get to it.

During the fall semester of my Junior year, I was fortunate enough to be a Teaching Assistant for an introductory electrical course. The course, which is frequently said to be a weeder class for the ECEN department, was Introduction to Digital and Analog Electronics.

The content of the class was fairly simple by upper division standards, but could be very challenging to students who came into the major with little to no experience with circuits. I vividly remember pouring hours into this class my freshman year, despite having previous experience as an electrical hobbyist. The final project alone took over 120 hours to complete.

Now, as an upperclassman, I was tasked with assisting in the underclassmen's learning experience. My goal for the semester was to A) Learn how to teach,  and B) Make the "weeder" class as easy to follow as I could.

The first goal proved to be more difficult. I had come to realize that understanding the material, and conveying the material in a simple and elegant way, were two related, yet difficult to connect disciplines. After talking to the professor of the class and TA's of other classes, I compiled a strategy for teaching. Teaching mainly occurred during the lab hours, so I would continuously walk around the lab, asking questions when people looked like they were stuck. If they were having trouble answering, I would simplify the questions to relate to what they were learning in the classroom. If that didn't work, I either used a whiteboard to diagram the solution, or assisted them in producing the correct result.

A difficulty that faced this particular course was the clarity of documents. On noticing this challenge that students had to overcome, I took it upon myself to rewrite the majority of class documents and labs in LaTex. Not only did this help the current students, it would help students in future classes.

By the end of the semester, I was amazed at the improvement of students. They started not understanding the basic working of circuits and finished by designing full logic clocks on printed circuit boards. Most of them even worked!

Overall, my experience as a teaching assistant for Introduction to Digital and Analog Electronics was a positive one. I gained knowledge in areas where there was none, and began to understand the difficult job professors have to teach mind boggling concepts in a single semester.

-John "The second time around was easier" Dunn


Tuesday, October 28, 2014

DE0 and Assembly

Its been a while since the last post, but the future posts will definitely make up for that (be excited). As a small post, I can show you all something I've done for a class called Programming Digital Systems. PDS, as it is called, instructs on the architecture of embedded systems as well as the use of assembly as a language. Assembly is remarkably tedious, but very rewarding when functional. My future project, to be unveiled soon, will uses assembly exclusively.

Directional Arrow Scroll

/* John Dunn        */  
/* Oct, 28 2014        */
/*          */
/* This program goes through a series of screen states, then restarts. */
/* If PSHBTN1 or PSHBTN2 is presse the states are reversed.  */
/*          */
/* Register Usage:        */
/* - r5: Current State of Button after ldwio from r16   */
/* - r7: Delay Counter       */
/* - r8: Current State       */
/* - r9: State Counter (Starts at 8 and is checked for r9==0)  */
/* - r13: Direction indicator (0 is R2L, 1 is L2R)    */
/* - r14: Base Address of the current set of states (R2L or L2R)  */
/* - r15: HEX3_HEX0 Base Address      */
/* - r16: Pushbutton 1&2 Base Address     */

 .text
 .global _start
_start:
 movia r13, 0    /* Initially have go right to left. */ 
 movia  r14, R2L_STATES   
 movia  r15, 0x10000020 
 movia r16, 0x10000050   
     ldw  r8, 0(r14)   /* Load the STATE into r8. */
     addi  r9, r0, 8         /* Set our STATE counter to 8. */

CHECK_R2L_RESET:
 bne r13, r0, CHECK_L2R_RESET /* IF the Direction is L2R, GOTO CHECK_L2R_RESET. */
     beq  r9, r0, R2L_RESET    /* ELSE the Direction must be R2L. */
      /* See if the state counter is at 0. */
      /* If it is, GOTO R2L_RESET. */ 
 br DO_DISPLAY    
CHECK_L2R_RESET:
     beq  r9, r0, L2R_RESET    /* ELSE the Direction must be L2R. */
      /* See if the state counter is at 0. */
      /* If it is, GOTO L2R_RESET. */
 br DO_DISPLAY 

R2L_RESET:
     movia r14, R2L_STATES   /* Reset the State address back to */
      /* the base address for R2L_STATES. */
     ldw r8, 0(r14)   /* Load the first state into r8. */
     addi    r9, r0, 8   /* Reset the State Counter to 8. */
     br      DO_DISPLAY
L2R_RESET:
     movia r14, L2R_STATES   /* Reset the State address back to */
      /* the base address for L2R_STATES.*/
     ldw r8, 0(r14)   /* Load the first state into r8. */
 addi    r9, r0, 8   /* Reset the State Counter to 8. */
 br DO_DISPLAY

DO_DISPLAY:
 stwio r8, 0(r15)   /* Display the value in r8 */
     addi r14, r14, 4       /* Get address of next state*/
     ldwio r8, 0(r14)   /* Load the next state into r8*/
     subi r9, r9, 1         /* Decrement the state counter*/
 
 ldwio r5, 0(r16)   /* Load the current state of the Pushbuttons to r5. */ 
 beq r5, r0, NO_BUTTON  /* If a button isn't pressed, GOTO NO_BUTTON. */
 beq r13,r0,SET_DIR_L2R  /* If the Direction is R2L, GOTO SET_DIR_L2R. */

SET_DIR_R2L:
 addi r13,r0,0   /* Change r13 from 1 -> 0. */
 br L2R_R2L_SWITCH_RESET  
SET_DIR_L2R:
 addi  r13,r0,1   /* Change r13 from 0 -> 1. */
 br R2L_L2R_SWITCH_RESET

L2R_R2L_SWITCH_RESET:
 addi    r9, r0, 8   /* Reset the State Counter*/
     movia r14, R2L_STATES   /* Reset the State address back to the base address */
     ldw r8, 0(r14)   /* Load the first state into r8 */
 br WAIT
R2L_L2R_SWITCH_RESET:
 addi    r9, r0, 8   /* Reset the State Counter*/
     movia r14, L2R_STATES   /* Reset the State address back to the base address */
     ldw r8, 0(r14)   /* Load the first state into r8 */
 
WAIT:
 ldwio  r5, 0(r16)   /* Wait for the button to be released */
 bne r5, r0, WAIT

NO_BUTTON:
 movia r7, 250000   /* Here we will delay. */ 

DELAY: 
 subi r7, r7, 1
 bne r7, r0, DELAY
 br  CHECK_R2L_RESET:
 
 .data

R2L_STATES:  
 .word  0x00000079
 .word  0x00007949
 .word 0x00794949
 .word 0x79494940
 .word  0x49494000
 .word 0x49400000
 .word 0x40000000
 .word 0x00000000

L2R_STATES:
 .word  0x4F000000
 .word  0x494F0000
 .word 0x49494F00
 .word 0x4049494F
 .word  0x00404949
 .word 0x00004049
 .word 0x00000040
 .word 0x00000000
 .end

GOBUFFS Cheer Screen

/* John Dunn        */  
/* Oct, 28 2014        */
/*          */
/* This program goes through a series of screen states, then restarts. */
/*          */
/* Register Usage:        */
/* - r7: Delay Counter       */
/* - r8: Current State       */
/* - r9: State Counter (Starts at 23 and is tested for r9==0)  */
/* - r14: Base address of STATES      */
/* - r15: Base address of HEX3_HEX0     */

 .text
 .global _start
_start:

 movia  r14, STATES  
 movia  r15, 0x10000020 
     ldw  r8, 0(r14)   /* Load the STATE into r8. */
     addi  r9, r0, 23        /* Set our STATE counter to 23. */

DO_DISPLAY:
     beq  r9, r0, RESET     /* If we have finished all the states, GOTO RESET. */
 stwio r8, 0(r15)   /* Display the value in r8. */


     addi r14, r14, 4       /* Get address of next state. */
     ldw r8, 0(r14)   /* Load the next state into r8. */
     subi r9, r9, 1         /* Decrement the state counter. */

 movia r7, 500000   /* Here we will Delay. */ 
DELAY: 
 subi r7, r7, 1
 bne r7, r0, DELAY
 br  DO_DISPLAY
RESET:
     addi    r9, r0, 23   /* Reset the State Counter*/
     movia r14, STATES   /* Reset the State address back to the base address */
     ldw r8, 0(r14)   /* Load the first state into r8 */
     br      DO_DISPLAY

 .data
STATES:
 .word 0x00063000
 .word 0x00300600
 .word 0x06000030
 .word 0x30000006
 .word 0x303D3F06
 .word 0x00000000
 .word 0x303D3F06
 .word 0x00000000
 .word 0x0000007C
 .word 0x00007C3E
 .word 0x007C3E71
 .word 0x7C3E7171
 .word 0x3E71716D
 .word 0x71716D00
 .word 0x716D0000
 .word 0x6D000000
 .word 0x00000000
 .word 0x2908010D
 .word 0x30090906
 .word 0x1901080B
 .word 0x2908010D
 .word 0x30090906
 .word 0x1901080B
 .end
-John "Large Finite State Machines are Large" Dunn

Thursday, August 14, 2014

C++ Yahtzee Game

Second post in 1 day!

Wow, so many things to post, so little time! This time I'm going to be briefly explaining my final project for a summer class I took called Data Structures.

I've always been a fan of Yahtzee, since a kid my parents have engrained the full scorecard into my mind. Whether I'm in a pub or at a friends house, I still have the ability to write down a Yahtzee scorecard on nearly anything. So, when it came to doing a self created final project for a C++ Data Structures, I naturally jumped at the chance to emulate my favorite game. The purpose of the project was to create a program on your own design and do a complexity analysis. A complexity analysis is  simply a data representation of how a program performs if you increase the input size dramatically. For instance, in my Yahtzee program, I varied the number of players from 1 to 100, then counted the number of overall operations and operations of each statistically significant function. An operation counted as anything that accessed or changed a current data structure.

The backbone for this program are 4 main data structures. The first two structures are the most basic. They are structs called Dice and yahtStats. The Dice struct contains two arrays which are used to save and roll the dice.


struct Dice{
  array<int,5> dice;
  array<int,5> savedDice;
};


YahtStats contains most of the statistics involved with the program, including the number of operations. RollsPerNumber, which is an array of the yahtStats struct, is particularly interesting because it shows the distribution of each value of dice rolled over the course of the entire game.


struct yahtStats{
  int operations = 0;
  int autoPlay = 0;
  
  int mainOp = 0;
  int rollDiceOp = 0;
  int printDiceOp = 0;
  int printRollwithSavedOp = 0;
  int autoSaveDiceOp = 0;
  int saveDiceOp = 0;
  int getQtysOfDiceOp = 0;
  int autoConfirmScoreOp = 0;
  int confirmScoreOp = 0;
  int autoScoreTurnOp = 0;
  int scoreTurnOp = 0;
  int autoPlayTurnOp = 0;
  int playTurnOp = 0;
  
  int numPlayers = 0;
  int playerTurn = 0;
  int turnRolls = 0;
  bool keepRolling = true;
  int totalRolls = 0;
  int turns = 0;
  array<int,6> rollsPerNumber;
};


The next data structures are two classes called Scorecard and Score. Scorecard uses the object Score as a data type to fill a 2D array of width 18 and height of the number of players in the game.

Score has two attributes, score and hasBeenScored. ”score” contains the actual integer value of the Score, while hasBeenScored is a boolean field which is set to true if the score is set for the first time. The reason for this is to allow to check if scores equal to 0 have already been scored as 0, and are not just empty categories.

class scorecard{
private:
  int numPlay;
  Score ** playerScores;
  array<string,100> playerNames;
  
public:
  scorecard(int numPlayers);
  ~scorecard();
  
  void setNumPlay(int num);
  void setPlayerScore(int player,int section, int score);
  void setPlayerName(int player, string name);
  int getNumPlay();
  Score getPlayerScore(int player, int section);
  string getPlayerName(int player);
  void printDivider(int numPlayers);
  void print(int numPlayers);
  
};

class Score{
private:
  int score;
  bool hasBeenScored;

public:
  Score();
  ~Score();
  
  void setScore(int s);
  void setHasBeenScored(bool hBS);
  int getScore();
  bool getHasBeenScored();
  string getHasBeenScoredStr();
};
Below is a dependency chart for the main method. Simply put, the main method gathers the mode of which the user would like to play, either standard or auto-play, and the number of players. Based on these inputs, it iterates through either playTurn or autoPlayTurn enough times to fill the scorecard with scores.
The pseudocode for playTurn and autoPlayTurn are shown below.

void playTurn(yahtStats * stats, Dice * myDice, scorecard * myScorecard){
  1. Roll the dice between 1 and 3 times.
  2. Save the dice between 1 and 3 times.
  3. Score the turn.
}
void autoPlayTurn(yahtStats * stats, Dice * myDice, scorecard * myScorecard){
  1. Find a random number of rolls between 1 and 3.
  2. Iterates through for the number of rolls indicated by the randomly generated number.
  3. AutoSave the dice.
  4. autoScore the turn.
}

A critical portion of this project was to do a complexity analysis. I chose to do my analysis based on the number of players. Because my independent variable was linear, and each player had a set number of turns to complete, I hypothesized that the program's complexity would increase linearly. To test this, I made the auto-play mode. Since the outcome score-wise was irrelevant, I chose to randomize the player input at any opportunity. In this way, I simulated the average game with players. While convenient, it did not replace the high scores of an actual AI player. To keep track of the operations, I placed incrementing counters at places inside of each local function inside main.cpp.
 These counters can be found in the yahtStats struct.

Originally, I had the autoPlayTurn function print off the scorecard each time. For reference, the scorecard looked like something below.


By printing the scorecard each time a turn was finished, I printed off the scorecard numPlayers^2 times. This resulted in the following exponential complexity plot based on operations.
After removing the offending quadratic printing, the complexity plot became very linear, which proved my original hypothesis.

In the end, this project taught me the value of complexity analysis and data structures. It was good project to work on because it had a medium high code complexity and great "Fun Factor". For those of you who would like to try out the program, it is available here: Yahtzee.

-John "My computer is at 1% so I have to FINISH THIS QUI"

Friday, August 8, 2014

The Idea Forge in Review

Hello Readers,

Over the course of the summer I have learned much about how to manage groups of people to achieve a larger end goal. While there were a few hiccups along the way (the necessity of locking castors for tables, etc.), work on the Idea Forge has gone better than imagined. We have nearly completed construction of 20 whiteboards of two unique designs, three work tables, and seven design tables.

With each of these projects, the goal was to make something functional and visually stimulating. To show just how easy this is to accomplish, I have created a venn diagram illustration.


Sufficed to say, it was a challenge to make this happen. I was part of the second round of employees to come through the project, and as such, I had some catching up to do with the projects. After a short while though, we were organized as a group and were working as a well oiled machine.

Upon arrival, there were a few things mostly completed, including the whiteboards, and some things that needed lots of work, like the design and work tables.

The first issue we ran across with the design tables was squaring the frames. Made out of galvanized piping, the frames could be described as "artisnally crafted", each table is unique. It took almost a week of shifting and cranking with pipe wrenches to make the seven frames level and square enough to add on the steel angle bars that would serve as a rim for the specially designed wood table toppers. Even though we made the steel frames as square as possible, it was still necessary to muscle the bars to slot connecting bolts through to the galvanized base. We certainly do not envy those who have to manipulate those frames in the future. Given the opportunity, we should have gone with a more exact material, like fully cut and bored steel bars. This would have made the construction process 100% easier, even if it did put the tables on the far left of our Venn Diagram above. That being said, the final products with the galvanized piping look incredible and will be functional for many years to come.

The work tables presented a whole other host of issues. Breakdowns in communication between multiple supervisors had given us, the student workers, a limited view on the purpose of the tables. One minute we would hear the tables would see light construction work, like assembling small pieces of acrylic, and the next we would be expected to have the table support an entire engine block.

At some point as a group, we got frustrated enough that we confronted our superiors and had them detail specifically what they required. After this event, we were able to move forward with renewed purpose and energy. The design was finished shortly thereafter and we spent a whole day constructing the work table. Made from 80-20 aluminum, these work tables were lighter, stronger and more expensive, than their galvanized pipe counterparts. Since then we have constructed two additional tables, bringing the total number of work tables to three.

The most fun that I had working on these projects was designing and crafting the design table toppers. We ended up constructing three tables with sealed and stained Colorado beetle kill pine, two tables stained with gears branded into them, one table with a looping gear and chain design inlaid into the table, and a final table with an inlaid steampunk blimp.

Overall, this summer job has been an eye opening experience. It has confirmed my interest in the engineering field and peaked my desire to become involved with engineering management.

Please take a look at the pictures posted below. They show just some of the people who have put in the hard work necessary to make this project a success.

...

Thursday, July 3, 2014

Steampunk Lamp

Hey Guys!

Long time no real completed projects, so I figured give you the low down. Last month I had some pretty major jaw surgery, and while I was healthy enough to do some casual bike repair, I didn't have the patience for a full project. However, I now have the wonderful opportunity to help out my school in a management role for the new Idea Forge.

The Idea Forge, which has taken on a "Steampunk" theme, is a new project design and construction laboratory in the Fleming Law building. A group of 20-25 students, myself included, are designing worktables, whiteboards, and other furniture to be used in the construction and design rooms of the Idea Forge.

Before I had arrived, the group of students had to design these pieces of furniture from scratch, model them in SolidWorks, and test their designs before putting them into production. Upon arrival, I started working with the design table work crew. The tables were already roughly constructed, but not fully completed.

Today, I had the pleasure of working with Jeff Carlson on a steampunky lamp project that would help illuminate the design tables. In the end, we designed a lamp that utilized an Edison bulb and galvanized steel. What was really novel though was the repurposed valve connected to a dimmer switch inside of a 2" diameter pipe. The end result was quite satisfying.

-John "This job isn't really a job" Dunn


Wednesday, June 4, 2014

Robot Dot Printer

Hello all,

Well, the end of my sophomore year has finished, and with it, half of my college career...hopefully. At the tail end of every semester, design classes kick into high gear and students produce some extraordinary results. For the end of our electronics design lab, my partner and I decided to create a robot dot printer. For those who haven't seen our robot before, here he is, Geoff, with a face lift.

Figure 1: Geoff with his printer face.
Introduction
”Theoretically, this should work” was probably the most commonly used phrase in our final project days. The goal of our final project was to create a robot that is able to print discrete images using sharpies actuated by servo motors. To complete this goal, we had to construct a printer assembly that would be placed on the rear of our robot, and developed code for the Arduino to drive servos with pulse width modulation such that sharpies moved in a linear path.
Figure 2: Block diagram of our system.
We also had the idea to use a Sparkfun manufactured PWM shield (Fig. 3a)that had the ability to
drive the 8 servo motors. Unfortunately, luck was not on our side, because the board had a faulty powerpage3image1256
management system. To sidestep this issue, we settled for only using 6 servos, which was the maximum the arduino could provide. 

Design of Printer Assembly
Next, something that actually worked! Originally we had planned on using solenoids to actuate the Sharpies. After connection between the solenoids and markers became a dubious prospect at best, we opted for a more accurate, and more Arduino friendly method of actuation, the humble sub-micro servo. The servos allowed us to use PWM to accurately push and pull the Sharpies.
The first issue we ran across was constructing servo horns to connect servo and Sharpie. Using a laser cutter and some 1/8” acrylic, we were able to manufacture horns that fit our application wonderfully. A slot was cut along the length of the arm which allowed the Sharpie to side back and forth on its vertical path. This movement minimized the torque on the servo motors.
Figure 3: Printer Assembly. Due to the buggy nature of the PWM shield, we decided to remove the outside servo assemblies in favor of using the built-in PWM outputs of the Arduino. 

Figure 4: Connection between Sharpie and servo.
Figure 5: Printer assembly. By laser cutting the printer assembly, the servos were able to be press fit into the holes 
without any screws. This accuracy was accomplished through many iterations. 

PWM Servo Control
Servos are controlled by pulse width modulation. Different pulse widths are associated with different positions, shown in Fig. 6. In our robot, we use three positions: Storage (fully up), Set (down but not touching), and Print (down and touching). We ran across issues with power regulation when we tried to drive all 8 servos from PWM shield, so we defaulted to using the six PWM pins available on the Arduino. However, eight PWM outputs were required to control the six servos and two robot wheels. Two additional PWM outputs were made by manipulating Arduino digital output pins with strategic timer interrupts. This created a PWM signal suitable to be a voltage reference to the robot motor controller. 


Figure 6:
Explanation of pulse width modulation with servos. 

In order to print designs, servos would have to be in specific positions at specific times. The process of printing would be to 1) Push Sharpies down, 2) Move forward, 3) Change positions of Sharpies, 4) Repeat. Using a linked list method explained graphically in Fig. 7.
Figure 7: 
This diagram explains the basics of linked lists. A data structure was created print col that contained a list of values, 0 or 1, and a pointer, or link, to the next print col. At the start, the servos are given the list at the first print col. The dots indicate that the servos are in the up position. After all servos are positioned according to the current list, the robot moves forward an increment, then changes the position of Sharpies to the list in print col 2. This process is repeated until the print sequence is completed. 
Results
In order to have an operational robot dot printer, the Sharpies had to be properly calibrated. Calibration was as simple as manipulating the servo horns on the servo head such that the tip to be of the ground when the servo was in a high position, and on the ground in the low position. The results of a simple pattern print is shown in Fig. 8.
Figure 8: Results of  a simple pattern test.
-John "I've been in bed for a month because my face is broken" Dunn