Assorted Coding Projects
Ever since I discovered that useful coding could be performed by an average person and not just by professionals for official purposes, I have been interested in finding ways to put it to use and learning useful coding languages and techniques. The first language that I encountered was Visual Basic, through which I attempted mainly to write code for games. One of my first successful programs, though not written by me alone - I had help from the person who was teaching me the language - was a simulated bowling alley. The user of the program could bowl down a lane, choosing when to launch the ball, and if the ball was aligned with the center, they would get a strike. It was a simple program, but any programming experience helps with building the mindset needed for coding and provides tools that will be valuable in future projects.
I tried to make an online video game but was in way over my head and had no idea of the real limitations of Visual Basic in the ways that I intended to use it, so I failed to complete that project, despite learning much from it about basic, core coding functions. Redeeming my ties with Visual Basic, during the car ride back from my First Robotics Tech Challenge competition that I had participated in with my team, I coded the game Pong in a few hours. I recently dug up my code for pong and found an old executable file as well that I had exported. As far as I can tell looking back, the code considers the angle that the ball impacts surfaces at, as well as whether it bounces off of one of the sliders’ corners or a flat surface when determining the reflection angle.
Two players could control the sliders using arrow and WSAD keys on the keyboard, and the game would display a “You Lose” banner on the side that had failed to deflect the ball every time. For added difficulty, I included code that would slowly move the sliders closer to each other, reducing the gap and thus the time between impacts. I know that if I had an internet connection during that car ride, I would have found some generic Pong impact noises and coded them into my program form to play during each ball impact, just for fun and more authenticity.
Since then I have branched out through C and C++ to windows batch and script files and math-oriented coding like Excel data processing and Matlab coding, while also trying my hand at mechatronics-geared languages like Robot C for FTC and Arduino for other microcontroller projects. I aim to continue improving my coding skills through research online as I have been doing, while always working on new projects to test and improve my skills.
C & C++
Following Visual Basic, the next language that I was exposed to was C, which I learned in my computer-engineering classes. C felt far more natural and rudimentary than Visual Basic which is why, to this day, it remains my favorite language. In some cases, I enjoy using C++ functions to shorten my work and remove clutter from my code, but even those functions are based in C. I enjoyed coding for such assignments in my classes as preparing a blackjack game to be played against a computer dealer, performing image manipulation by pixel value, programming a Pololu 3pi robot to traverse a maze, and coding an environment that enables a user to set a password according to given security rules requiring the use of certain types of characters.
In my free time, I coded Einstein’s Quiz in C and then exported it as an executable file so that I could share it with friends. The quiz is meant to be difficult to follow and solve but using basic logic and taking each clue one step at a time will always end the quiz at the same answer, if it can be completed. Using the 15 questions given in the original Einstein’s Quiz, which can be found online as well as its answer, I wrote a program in the C language using knowledge that I had gained from only my first C-coding engineering-computers class. The program delivers the quiz questions and tracks the amount of time that has elapsed since the quiz was started, awaiting an answer from the user and reporting the time that they took to complete it after they submit their answer.
Since some of the magic of the quiz is lost once the answer is known, I also included an option to submit one’s own variables into the quiz, of which there are 25, arranged into five categories. This way, anyone who had taken the quiz before could take it again with new variables and be forced to rethink through the logic, and the program would tell them if the answer was correct rather than allowing them to cheat and look online. This program was simple enough to code, but it took me a long time to iron out the kinks, teaching me a lot of code-organization skills and shortcuts along the way, so I am very proud of the final working product.
During the process of exporting thousands of bitmap images from Creo Parametric’s model-animation tool for conversion into videos for this site, I encountered an export-error that took me days to understand. I was told by Adobe Premiere that an error had occurred, and the file could not be exported. I searched for the error code online and was told that one of my input files was corrupted. Since bitmap images are stored at nearly 100 times the size of their PNG counterparts, I converted every bitmap to a PNG in order to save on storage and reduce the time that Premiere would take to load every file. I had assumed that these conversions were at fault for the corruption that Premiere was catching, so I started by re-converting them in case it was a one-time corruption error, which didn’t solve the problem.
Next, I checked the metadata of a known-to-be-working PNG image and compared it to one from the group that was causing the error. I found that there was a large amount of extra metadata attached to each image exported by Creo that could not be interpreted, while all working images had only the necessary data fields, so I went down a different path that I do not regret taking despite it ultimately not being the correct solution.
I dug up one of my old coding projects for my Computers in Engineering class which was designed to use C++ headers to manipulate bitmap images at the pixel level. I spent most of my time over two days re-organizing, researching and replacing code in the program to have it take an input bitmap file, read every pixel value and write each to a new blank Bitmap object, which would then be exported as an entirely new bitmap file containing virtually the same image as the original. I initially intended to pair this program written in C++ with a batch file that I had previously written, which parses through a folder, taking in the paths of every file as a variable one at a time, and executes some command with the path, in my case beginning a new instance of my C++ program and sending the path to it as an input. When I did this, however, it attempted to open 7000 instances of my new C++ program by the tens per second and bogged down my computer by attempting to simultaneously read and write 7000 bitmap images at two million pixels per image.
I quit this futile attempt after a half of an hour and found that it had only completed operating on around 1000 of the images and was beginning to open new instances of the program for the new bitmaps that my program had written in addition to the original bitmaps, since the output folder was within the original folder. I scrapped this idea and instead moved on to code the parsing function into my C++ program in the form of a while loop, executing one bitmap-rewrite at a time, and ditching the batch file entirely. It took several hours to get the code to work correctly, but when it finally functioned, it got all 7000 images done in less than a half of an hour.
I was deeply saddened to find that Adobe Premiere still had a problem with even my new images and I was forced to finally do what I should have begun with, finally leading me to the real problem. I was able to narrow down the location that the export failed to a certain percentage of the way through the encoding process and proceeded with the assumption that the percentage would be somewhat linearly proportional to the fraction given by the name of the culprit corrupted frame, where all frames were named in order by number, over the total number of frames. I didn’t want to search through all 7000 frames, so I started at the frame given by my calculation and began sifting in both directions away from frame 1120, which was 16% (where the program failed) of the way through 7000. Sure enough, I found a single frame that Premiere couldn’t load no matter what I did to it, so I copied its contents to a paint file and saved it as an entirely new image. Premiere accepted this new image and allowed me to complete my export.
So, in the end, my bitmap-rewriting program was completely useless for the application that it was meant for. It forced me to learn new file input-output techniques and apply my coding knowledge to a real problem, however, so I can accept having spent a lot of time working on it nonetheless.
In a very similar project, and more for fun and testing my coding skill than to solve an existing problem, I took that very same image manipulation code that I had written for class and wrote a separate program during my free time in 2017 for a different image editing purpose. The website Reddit had just completed their 3-day-long April Fools day project, a massively successful online image canvas prepared by Reddit allowed to be edited by any Reddit user. Participants were told that they could, using any Reddit account made before a certain date, change the color of any one pixel on a 1000x1000-pixel canvas to one of the 16 colors represented in 4-bit bitmap encoding, once per every five minutes.
Over the course of the 72-hour period that it spanned, 1.1 million users placed a total of 16.5 million pixels. I took part in the creation of the canvas and ended up placing a total of 18 pixels, one of which ended up remaining on the final canvas, and the connection that I had to the project, though small, motivated me to do something more with it once it had concluded, as many other users did. A Steam application for PC called Wallpaper Engine, which had at the time just recently been released, was designed to allow anything from videos to interactive programs and web browsers to run within the Desktop background on one’s computer. A few hours into the creation of the r/place canvas, I came up with the idea to create a time-lapse video from images of the canvas and upload it to Wallpaper Engine as a video background for others to use.
I attempted to write my own small batch file code to take screenshots of my computer screen once every few minutes, with the canvas centered on screen, but I was late to the party by more than a day, and my code fell short in many ways. I found that other people had gotten on board nearly instantly after the project commenced and used APIs to get and save updated canvases once every 5 seconds, so I allowed them to do the work of gathering the images instead since my time-lapse would have fallen short with my own images. Luckily for me, they made their images publicly available in a zipped file download, which ended up filling 149 gigabytes of storage on my computer.
This was when I wrote a batch script using ImageMagick’s convert function to efficiently parse through a folder and covert every one of the 49772 bitmap images to lossless PNGs for the purpose of more realistic storage and speeding up loading times. In their PNG state, they only took up and still take up 10.8 gigabytes of space on my drive which is far more manageable than 149 gigabytes.
The canvas for the image was 1000x1000 pixels, but most computer monitors at the time were 1080p monitors with a resolution of 1920 by 1080 pixels. I wanted the canvas to serve as a background for such computers, and I didn’t want to throw a boring black backdrop behind it, so I instead settled on writing a C++ program to fill that space and rewrite all 49772 images. I hadn’t touched my image-manipulation code in over a year at that point, so it took me a few days in my free time to write and execute the image-rewriting. I chose for my program to read each image as a 1000x1000 array of pixel values, then copy over each value to the 1000x1000 pixel section at the center of a new 1920x1080 pixel image. It then read the leftmost edge’s pixel values and applied each pixel’s color value to every pixel directly to its left, and did the same with the other three sides, effectively stretching the edge pixels to fill the rest of the frame. I then stretched the corner pixels to fill the remaining unassigned corner sections, so that no pixel was left unchanged.
One problem that I encountered was that I kept getting an error message saying that I was attempting to write pixel data to an area of the image array that didn’t exist. I was stuck with this problem for a while before walking through the program step by step and finding that I had my columns and rows swapped in two important for loops. With this, the program was completed, and I ran it for a few hours, letting it rewrite all of the images as bitmaps. Sadly, the C++ headers that I was using to manipulate my images required bitmap input and output files, otherwise I would have preferred to use PNG files for their storage-size benefits. This new set of images took up 309.8 gigabytes of space on my hard drive, so I once again converted them all to PNGs, at this point reaching 480 gigabytes in total used storage. I eventually deleted all of the bitmaps, but not before ensuring that none of the PNGs were corrupted or constructed incorrectly.
I also had the issue of accidentally translating the 4-bit bitmap inputs in my program to 24-bit bitmaps improperly, since 24-bit was the default encoding method used by my bitmap headers, which completely screwed up the color representations. I fixed this problem easily, but it was a funny mistake that resulted in some interesting looking images, with a color-value-swap occurring every few images.
Having exported all of the images intended for the final video, I moved them into an Adobe Premiere project, but found that in a 60-fps video, the entire time-lapse would cover 13.8 minutes. I decided to cut the time-lapse in half, removing every other image, to shorten it to 6.9 minutes in length and speed it up by a factor of two. I desired to pair a song with it and knew of no 14-minute songs but had one in mind that was almost exactly seven minutes long and it fit perfectly with my new video. In order to perform the splitting of the 49000 files to speed up the video, I wrote another batch file that parsed every file in a folder and copied every “n”th file, in order by name, into a new folder, where “n” was a specified integer, in this case two. I have used this batch file on multiple other occasions for similar purposes.
Once I settled an issue with the project’s field progression setting, changing it from the default “lower-field-first” to “progressive scan” to match my image import settings, I exported the video using the highest quality that I could achieve with Adobe Premiere using the widely accepted h.264 encoder to ensure that my video would be compatible with Wallpaper Engine. Within a few days of uploading my new wallpaper to Steam, a few hundred people had subscribed to use it as their computer background, and currently in 2019 it has reached over 1500 total subscribers. It is, by both rating and subscriber count, the most popular r/place-based wallpaper on the platform. The hard work that I did to make a good product both went to good use with thousands of people and taught me new ways to use old tools.
The final important C-program that I wrote, which is extremely simple yet conceptually fun, is a good transition into the Arduino codes that I have written because I wrote a program with an identical purpose for Arduino as well. When I began coding my Nixie Tube clock, I quickly found issues with the accuracy of my Arduino Mega’s ability to keep accurate time. I could watch on screen as my Arduino counted seconds next to my computer time (with its very accurate clock) and notice the divergence of the two within less than 30 seconds. As this amount of error is unacceptable when trying to program a clock, nearly 1% error causing the Arduino to be behind by one second per every 129 seconds, I thought that I could correct it by finding the factor that related the two times – real time and fake time, as I called them in my programs.
So, treating my computer’s clock as real time and my Arduino’s clock as fake time, I wrote two programs both called micros, based on the built-in micros function in the Arduino libraries. In C, run as an executable, I wrote a never-ending while-loop which on each cycle displays the number of microseconds elapsed since program-start. Using the “gettimeofday” function belonging to the sys/time.h header to call the time to a variable at the beginning of the program and once during each cycle, I could subtract the beginning time from the current time in microseconds and display the value to the screen. This program kept one of my computer’s four processor cores at 40% capacity and another at 25% during its duration, which translated to higher temperatures and noticeably sped up my fans. This is likely due to the fact, judging based on the time between numbers displayed by the console, that it was displaying a new number on average 10,400 time per second.
The next step would have been much simpler if I could have figured out how to read serial COM ports from within a C program, but at the time I didn’t have a clue that such a thing was even possible. It is possible to pipe the Arduino’s serial output through PowerShell and into the current CMD terminal and combine it with the data coming from the Micros program running simultaneously and export it into a file for analysis. Instead, since I didn’t know that was an option, I ran the computer and Arduino separately, with my Arduino printing to the serial monitor running its micros program and my C micros program running in the terminal, then wrote another batch file to take screenshots once per hour when possible. I later went through every screenshot manually, in order, and entered the most recent number displayed on both monitors in each image into an Excel table. I used Arduino’s built-in Micros function as a replacement for time.h’s gettimeofday to write the code for the Arduino, but everything else was the same, except for the Arduino’s measly output rate of a few hundred number-updates per second.
Using Excel, I processed those numbers which were taken over the course of 11 days, hoping to settle on some consistent factor that would keep the clock accurate. While the generated divergence-curve did converge to a consistent factor value, I noticed while it was being created that the difference in rates between the Arduino clock and my computer clock would fluctuate throughout the day, peaking at night and falling during the day. The only thing that I could think of to attribute this to was changes in temperature in the room, and sure enough, upon researching official accurate clock modules, I found that they are all paired with a thermometer to track and consider temperature fluctuations, which must affect the resonance-rate of the quartz timing crystal.
With my factor determined though, I pressed on, hoping that it would still prove accurate throughout the year. I predicted after a few days of running my working Nixie clock next to my computer that it would only diverge from real time by less than a minute per year, which I could live with, but when I ran the clock in the summer it was off by almost 30 seconds in less than a week. Thus, I switched to a two-dollar eBay-bought Arduino temperature/time module called the ds3231 which in its five months running thus far has diverged by only roughly 10 seconds.
Arduino Mega has made my Nixie clock possible, since it required many output-pins and the capacity to run my clock program, which stores and will be able to display the date, temperature and time, and uses the date to determine daylight saving time and weekday. My roommates and I used Arduino Nano to control our RFID door-lock during my junior year in college, giving me more exposure to Arduino. It really has come in handy knowing how to code in Arduino’s language, and not just in classes. The similarities between the Arduino language and C made it easy for me to pick up after taking a few C-based classes. Though I barely did any of the coding for the door lock, I did look at the code that was written and was able to understand its logic. I plan to model, code and assemble a similar RFID locking mechanism for my living unit in the coming year.