At least 99% of my blog entries contain original content I created. However, I was so impressed by something I stumbled upon tonight that I absolutely cannot resist sharing it. It’s a project which aims to output audio and video simultaneously from a single microcontroller. The author’s site has all the details, but if you watch the video below you’ll be amazed. (Just get through the 30 second narration at the beginning) Apparently the guy rendered video in horizontal lines from the software and outputted audio signals between horizontal lines! Amazing!
On second thought, this was no big deal in the 80’s, so why am I so impressed by it now? The 8-bit microcontrollers this guy is programming is likely on par with the PCs of the 80’s. I guess that in the 70’s this would have been amazing because it was cutting edge. In the 80’s this would have been boring because it was commonplace. In the 2000’s, this is amazing because no one in my generation is old enough to remember how amazing this was in the 70’s and 80’s!
After researching some similar projects I realized I’m becoming fascinated with chiptune synthesizing code, hardware, and music. It’s basically a type of code to tell a synthesizer how to synthesize the music, rather than having it play pre-recorded music. It’s like a merge of a programming language and MIDI. For non-technical people, it’s like giving a microchip the sheet music for all the different instruments of an orchestra and having the microchip play everything from the sheet music, rather than giving it a CD to play. Here’s some video of a PC-based front-end to the audio creation process. Notice how each line represents a time, and how certain codes in certain channels represent notes (hence the MIDI aspect). Numbers on the far right represent the location of the memory, and notice also how it goes back and forth, replaying certain areas when necessary (to safe space, hence the coding aspect).
I can’t describe my emotional state right now. It’s like I have an extreme nostalgia for an era I never even lived in. This chip level audio synthesis stuff sounds amazingly fun to me. (I’ve already bookmarked nolife-radio.com and 8bitFM.com) I feel drawn toward it… but I’m scared to get sucked in. I wish I were a college student in the 80’s studying electrical engineering. Here I am, having just gotten a master’s in molecular biology and microbiology, and I feel like I wasted six years of my life in the process. I’m about to start dental school in August. Hopefully when I look back from the future I won’t feel like I wasted another four years doing that.
Either way, I have an endless supply of possible projects to do this summer (not even going into the small list of projects I’m trying/expected to complete in the cardioneurophysiology lab I work in). I feel like I’m running out of time. I start dental school in August, and I dread the date. Not necessarily because I expect it to be difficult, but because I feel [however illogical, irrational, or ridiculous] that I’m actually doing something significant, working with my hands and working with my brain to do things that [almost] no one has done before, and doing things in a way that no one has ever thought of doing them. I feel like when I start resume classes, it’s another four years of people telling me how I should do things so I can be exactly like everyone else. How can you exercise creativity as a dental student? I’m sure there are ways, but it’s certainly leagues away from the projects engineering college students work on. As far as the career goes, if you’re an engineer the best case scenario is that you do something no one has ever done before. If you’re a dentist, the best case scenario is to do things exactly as everyone else does them. Maybe I’ll go crazy and change the wallpaper in my office every few months.
After a day of tinkering I finally figured out how to control a HD44780 display from an ATTiny2313 microcontroller. There are a lot of websites out there claiming to show you how to do this on similar AVRs. I tried about 10 of them and, intriguingly, only one of them worked! I think the problem is that many of those websites show code for an ATMega8 and I’m using an ATTiny2313. Since it took me so long to get this right I decided to share it on the internet for anyone else having a similar struggle.
You might recognize this LCD panel from some PC parallel port / LCD interface projects I worked on about 5 years ago. It’s a 20-column, 2-row, 8-bit parallel character LCD. This means that rather than telling each little square to light up to form individual letters, you can just output text to the microcontroller embedded in the display and it can draw the letters, move the cursor, or clear the screen. These are the connections I made were:
LCD1 -> GND
LCD2 -> +5V
LCD3 (contrast) -> GND
LCD4 (RS) -> AVR D0 (pin2)
LCD5 (R/W) -> AVR D1 (pin3)
LCD6 (ES) -> AVR D2 (pin6)
LCD 11-14 (data) -> AVR B0-B3 (pins 12-15)
The code to control this LCD from the ATTiny2313 was found on Martin Thomas’ page (dead link removed in 2019). I included the .h and .c files and successfully ran the following program on my AVR. I used the internal RC clock.
// modified the top of "lcd.h"
#define LCD_PORT PORTB /**< port for the LCD lines */#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */#define LCD_DATA0_PIN 0 /**< pin for 4bit data bit 0 */#define LCD_DATA1_PIN 1 /**< pin for 4bit data bit 1 */#define LCD_DATA2_PIN 2 /**< pin for 4bit data bit 2 */#define LCD_DATA3_PIN 3 /**< pin for 4bit data bit 3 */#define LCD_RS_PORT PORTD /**< port for RS line */#define LCD_RS_PIN 0 /**< pin for RS line */#define LCD_RW_PORT PORTD /**< port for RW line */#define LCD_RW_PIN 1 /**< pin for RW line */#define LCD_E_PORT PORTD /**< port for Enable line */#define LCD_E_PIN 2 /**< pin for Enable line */// AND A LITTLE LOWER, I CHANGED THIS LINE TO 4-BIT MODE
#define LCD_FUNCTION_8BIT 0 /* DB4: set 8BIT mode (0->4BIT mode) */
Here is video of the output. Notice how this display can show English (lowercase/uppercase/numbers) as well as the Japanese character set!
Note from Future Scott (ten years later, August, 2019):
The link to the downloadable source code from Martin Thomas’ page is no longer functional. These links do work:
Articles typically receive this designation when the technology they describe is no longer relevant, code
provided is later deemed to be of poor quality, or the topics discussed are better presented in future
articles. Articles like this are retained for the sake of preservation, but their content should be
critically assessed.
I realized that the C code from yesterday wasn’t showing-up properly because of textile, a rapid, inline, tag-based formatting system. While it’s fun and convenient to use, it’s not always practical. The problem I was having was that in C code, variable names (such as delay) were becoming irrevocably italicized, and nothing I did could prevent textile from ignoring code while styling text. The kicker is that I couldn’t disable it easily, because I’ve been writing in this style for over four years! I decided that the time was now to put my mad Python skills to the test and write code to handle the conversion from textile-format to raw HTML.
I accomplished this feat in a number of steps. Yeah, I could have done hours of research to find a “faster way”, but it simply wouldn’t have been as creative. In a nutshell, I backed-up the SQL database using PHPMyAdmin to a single “x.sql” file. I then wrote a pythons script to parse this [massive] file and output “o.sql”, the same data but with all of the textile tags I commonly used replaced by their HTML equivalent. It’s not 100% perfect, but it’s 99.999% perfect. I’ll accept that. The output? You’re viewing it! Here’s the code I used to do it:
## This Python script removes *SOME* textile formatting from Wordpress## backups in plain text SQL format (dumped from PHP MyAdmin). Specifically,## it corrects bold and itallic fonts and corrects links. It should be easy## to expand if you need to do something else with it.infile ='x.sql'replacements= ["r"," "],["n"," n "],["*:","* :"],["_:","_ :"],
["n","<br>n"],[">*","> *"],["*< ","* <"],
[">_","> _"],["_< ","_ <"],
[" *"," <b>"],["* "," "],[" _"," <i>"],["_ ","</i> "]
#These are the easy replacementsdeffixLinks(line):
## replace ["links":URL] with [<a href="https://swharden.com/static/2009/05/15/URL">links</a>]. ## words = line.split(" ")
for i inrange(len(words)):
word = words[i]
if'":'in word:
upto=1while (word.count('"')&lt;2):
word = words[i-upto]+" "+word
upto+=1 word_orig = word
extra="" word = word.split('":')
word[0]=word[0][1:]
for char in".),'":
if word[1][-1]==char: extra=char
iflen(extra)>0: word[1]=word[1][:-1]
word_new='<a href="https://swharden.com/static/2009/05/15/%s">%s</a>'%(word[1],word[0])+extra
line=line.replace(word_orig,word_new)
return line
defstripTextile(orig):
## Handle the replacements and link fixing for each line. ##ifnot orig.count("', '") ==13: return orig #non-normal post line=orig
temp = line.split
line = line.split("', '",5)[2]
iflen(line)&lt;10:return orig #non-normal post origline = line
line =" "+line
for replacement in replacements:
line = line.replace(replacement[0],replacement[1])
line=fixLinks(line)
line = orig.replace(origline,line)
return line
f=open(infile)
raw=f.readlines()
f.close
posts=0for raw_i inrange(len(raw)):
if raw[raw_i][:11]=="INSERT INTO":
if"wp_posts"in raw[raw_i]: #if it's a post, handle it! posts+=1print"on post",posts
raw[raw_i]=stripTextile(raw[raw_i])
print"WRITING..."out =""for line in raw:
out+=line
f=open('o.sql','w')
f.write(out)
f.close()
I certainly held my breath while the thing ran. As I previously mentioned, this thing modified SQL tables. Therefore, when I uploaded the “corrected” versions, I kept breaking the site until I got all the bugs worked out. Here’s an image from earlier today when my site was totally dead (0 blog posts)
A few months ago I wrote about a way I use PHP to generate apache-style access.log files since my web host blocks access to them. Since then I’ve forgotten it was even running! I now have some pretty cool-looking graphs generated by Python and Matplotlib. For details (and the messy script) check the original posting.
This image represents the number of requests (php pages) made per hour since I implemented the script. It might be a good idea to perform some linear data smoothing techniques (which I love writing about), but for now I’ll leave it as it is so it most accurately reflects the actual data.
Articles typically receive this designation when the technology they describe is no longer relevant, code
provided is later deemed to be of poor quality, or the topics discussed are better presented in future
articles. Articles like this are retained for the sake of preservation, but their content should be
critically assessed.
I recently had the desire to be able to see data from an ATMEL AVR microcontroller (the ATTiny2313) for development and debugging purposes. I wanted an easy way to have my microcontroller talk to my PC (and vise versa) with a minimum number of parts. The easiest way to do this was to utilize the UART capabilities of the ATTiny2313 to talk to my PC through the serial port. One problem is that the ATTiny2313(as with most microcontrollers) puts out 5V for “high” (on) and 0V for “low” (off). The RS-232 standard (which PC serial ports use) required -15V for high and +15v for low! Obviously the microcontroller needs some help to achieve this. The easiest way was to use the MAX232 serial level converter which costs about 3 bucks at DigiKey. Note that it requires a few 10uF capacitors to function properly.
Here’s a more general schematic:
I connected my ATTiny2313 to the MAX232 in a very standard way. (photo) MAX232 pins 13 and 14 go to the serial port, and the ATTiny2313 pins 2 and 3 go to the MAX232 pins 12 and 11 respectively. I will note that they used a oscillator value (3.6864MHz) different than mine (9.216MHz).
Determining the speed of serial communication is important. This is dependent on your oscillator frequency! I said I used a 9.216Mhz oscillator. First, a crystal or ceramic oscillator is required over the internal RC oscillator because the internal RC oscillator is not accurate enough for serial communication. The oscillator you select should be a perfect multiple of 1.8432MHz. Mine is 5x this value. Many people use 2x this value (3.6864Mhz) and that’s okay! You just have to make sure your microchip knows (1) to use the external oscillator (google around for how to burn the fuses on your chip to do this) and (2) what the frequency of your oscillator is and how fast it should be sending data. This is done by setting the UBRRL value. The formula to do this is here:
The datasheet of your microcontroller may list a lot of common crystal frequencies, bandwidths, and their appropriate UBRR values. However my datasheet lacked an entry for a 9.216MHz crystal, so I had to do the math myself. I Googled around and no “table” is available! Why not make one? (picture, below). Anyway, for my case I determined that if I set the UBRR value to 239, I could transmit data at 2800 baud (bits/second). This is slow enough to ensure accuracy, but fast enough to quickly dump a large amount of text to a PC terminal.
This will make your life easier. The page wormfood.net/avrbaudcalc.php has a chart of common crystals and the baud rates they work best with! Try to pick a combination that provides the least error possible…
This is the bare-minimum code to test out my setup. Just load the code (written in C, compiled with avr-gcc) onto your chip and it’s ready to go. Be sure you set your fuses to use an external oscillator and that you set your UBRRL value correctly.
Once you load it, it’s ready to roll! It continuously dumps letters to the serial port. To receive them, open HyperTerminal (on windows, under accessories) or minicom (on Linux, look it up!). Set your baud rate to 2800 (or whatever you selected) and you’re in business. This (picture below) is the output of the microcontroller to HyperTerminal on my PC. Forgive the image quality, I photographed the LCD screen instead of taking a screenshot.
This is the circuit which generates the output of the previous image. I have a few extra components. I have an LED which I used for debugging purposes, and also a switch (labeled “R”). The switch (when pressed) grounds pin 1 of the ATTiny2313 which resets it. If I want to program the chip, I hold “R” down and the PC can program it with the inline programmer “parallel port, straight-through, DAPA style). One cable going into the circuit is for the parallel port programmer, one cable is for the serial port (data transfer), and one is for power (5v which I stole from a USB port).
I hope you found this information useful. Feel free to contact me with any questions you may have, but realize that I’m no expert, and I’m merely documenting my successes chronologically on this website.