The personal website of Scott W Harden

ATTiny2313 Controlling a HD44780 LCD with AVR-GCC

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.

// ATTiny2313 / HD44780 LCD INTERFACE
#include <stdlib.h>;
#include <avr/io.h>;
#include <util/delay.h>;
#include "lcd.h"
#include "lcd.c"

int main(void)
{
    int i=0;
    lcd_init(LCD_DISP_ON);
    lcd_clrscr();
    lcd_puts("ATTiny 2313 LCD Demo");
    lcd_puts("  www.SWHarden.com  ");
    _delay_ms(1000);
    lcd_clrscr();
    for (;;) {
        lcd_putc(i);
        i++;
        _delay_ms(50);
    }
}
// modified the top of "lcd.h"
#define LCD_PORT         PORTB        /**&lt; port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**&lt; port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**&lt; port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**&lt; port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**&lt; port for 4bit data bit 3 */
#define LCD_DATA0_PIN    0            /**&lt; pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    1            /**&lt; pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    2            /**&lt; pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    3            /**&lt; pin for 4bit data bit 3  */
#define LCD_RS_PORT      PORTD     /**&lt; port for RS line         */
#define LCD_RS_PIN       0            /**&lt; pin  for RS line         */
#define LCD_RW_PORT      PORTD     /**&lt; port for RW line         */
#define LCD_RW_PIN       1            /**&lt; pin  for RW line         */
#define LCD_E_PORT       PORTD     /**&lt; port for Enable line     */
#define LCD_E_PIN        2            /**&lt; 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-&gt;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:

A more recent project which uses these displays is:

Markdown source code last modified on January 18th, 2021
---
title: ATTiny2313 Controlling a HD44780 LCD with AVR-GCC
date: 2009-05-17 20:27:44
---

# ATTiny2313 Controlling a HD44780 LCD with AVR-GCC

__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.

<div class="text-center img-border">

[![](attiny_2313_lcd_hd44780_thumb.jpg)](attiny_2313_lcd_hd44780.jpg)
[![](attiny_2313_lcd_hd44780_2_thumb.jpg)](attiny_2313_lcd_hd44780_2.jpg)

</div>

__You might recognize this LCD panel__ from some [PC parallel port / LCD interface projects](http://www.swharden.com/blog/old-stuff-of-interest/#lcd) 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 -&gt; GND
*   LCD2 -&gt; +5V
*   LCD3 (contrast) -&gt; GND
*   LCD4 (RS) -&gt; AVR D0 (pin2)
*   LCD5 (R/W) -&gt; AVR D1 (pin3)
*   LCD6 (ES) -&gt; AVR D2 (pin6)
*   LCD 11-14 (data) -&gt; 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.

```c
// ATTiny2313 / HD44780 LCD INTERFACE
#include <stdlib.h>;
#include <avr/io.h>;
#include <util/delay.h>;
#include "lcd.h"
#include "lcd.c"

int main(void)
{
    int i=0;
    lcd_init(LCD_DISP_ON);
    lcd_clrscr();
    lcd_puts("ATTiny 2313 LCD Demo");
    lcd_puts("  www.SWHarden.com  ");
    _delay_ms(1000);
    lcd_clrscr();
    for (;;) {
        lcd_putc(i);
        i++;
        _delay_ms(50);
    }
}
```

```c
// modified the top of "lcd.h"
#define LCD_PORT         PORTB        /**&lt; port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**&lt; port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**&lt; port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**&lt; port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**&lt; port for 4bit data bit 3 */
#define LCD_DATA0_PIN    0            /**&lt; pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    1            /**&lt; pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    2            /**&lt; pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    3            /**&lt; pin for 4bit data bit 3  */
#define LCD_RS_PORT      PORTD     /**&lt; port for RS line         */
#define LCD_RS_PIN       0            /**&lt; pin  for RS line         */
#define LCD_RW_PORT      PORTD     /**&lt; port for RW line         */
#define LCD_RW_PIN       1            /**&lt; pin  for RW line         */
#define LCD_E_PORT       PORTD     /**&lt; port for Enable line     */
#define LCD_E_PIN        2            /**&lt; 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-&gt;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!

![](https://www.youtube.com/embed/mMEwFSkr1Ko)

<blockquote>

**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:

* https://senzor.robotika.sk/sensorwiki/index.php/AVR_lcd.c 

* https://senzor.robotika.sk/sensorwiki/index.php/AVR_lcd.h 

A more recent project which uses these displays is:

* https://www.swharden.com/wp/2017-04-29-precision-pressure-meter-project/ 

</blockquote>

Removing Textile Markup From Wordpress Entries

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","&lt;br&gt;n"],["&gt;*","&gt; *"],["*&lt; ","* &lt;"],
                ["&gt;_","&gt; _"],["_&lt; ","_ &lt;"],
                [" *"," &lt;b&gt;"],["* "," "],[" _"," &lt;i&gt;"],["_ ","&lt;/i&gt; "]
                #These are the easy replacements

def fixLinks(line):
    ## replace ["links":URL] with [&lt;a href="URL"&gt;links&lt;/a&gt;]. ##
    words = line.split(" ")
    for i in range(len(words)):
        word = words[i]
        if '":' in word:
            upto=1
            while (word.count('"')&amp;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
            if len(extra)&gt;0: word[1]=word[1][:-1]
            word_new='&lt;a href="%s"&gt;%s&lt;/a&gt;'%(word[1],word[0])+extra
            line=line.replace(word_orig,word_new)
    return line

def stripTextile(orig):
    ## Handle the replacements and link fixing for each line. ##
    if not orig.count("', '") == 13: return orig #non-normal post
    line=orig
    temp = line.split
    line = line.split("', '",5)[2]
    if len(line)&amp;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=0
for raw_i in range(len(raw)):
    if raw[raw_i][:11]=="INSERT INTO":
        if "wp_posts" in raw[raw_i]: #if it's a post, handle it!
            posts+=1
            print "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)

Markdown source code last modified on January 18th, 2021
---
title: Removing Textile Markup From Wordpress Entries
date: 2009-05-15 17:56:32
tags: old
---

# Removing Textile Markup From Wordpress Entries

__I realized that the C code from yesterday wasn't showing-up properly__ because of [textile](http://wordpress.org/tags/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](http://en.wikipedia.org/wiki/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:

```python
## 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","&lt;br&gt;n"],["&gt;*","&gt; *"],["*&lt; ","* &lt;"],
                ["&gt;_","&gt; _"],["_&lt; ","_ &lt;"],
                [" *"," &lt;b&gt;"],["* "," "],[" _"," &lt;i&gt;"],["_ ","&lt;/i&gt; "]
                #These are the easy replacements

def fixLinks(line):
    ## replace ["links":URL] with [&lt;a href="URL"&gt;links&lt;/a&gt;]. ##
    words = line.split(" ")
    for i in range(len(words)):
        word = words[i]
        if '":' in word:
            upto=1
            while (word.count('"')&amp;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
            if len(extra)&gt;0: word[1]=word[1][:-1]
            word_new='&lt;a href="%s"&gt;%s&lt;/a&gt;'%(word[1],word[0])+extra
            line=line.replace(word_orig,word_new)
    return line

def stripTextile(orig):
    ## Handle the replacements and link fixing for each line. ##
    if not orig.count("', '") == 13: return orig #non-normal post
    line=orig
    temp = line.split
    line = line.split("', '",5)[2]
    if len(line)&amp;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=0
for raw_i in range(len(raw)):
    if raw[raw_i][:11]=="INSERT INTO":
        if "wp_posts" in raw[raw_i]: #if it's a post, handle it!
            posts+=1
            print "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)

<div class="text-center img-border">

[![](hostingwork_thumb.jpg)](hostingwork.jpg)

</div>

Simple Case AVR/PC Serial Communication via MAX232

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.

AVR Baud Calculator

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.

#include <avr/io.h>  
#include <avr/interrupt.h>  
#include <util/delay.h>  

int main (void)  
{  
  unsigned char data=0;  
  UBRRL = 239;  
  UCSRB = (1 < < RXEN) | (1 << TXEN);  
  UCSRC = (1 < < UCSZ1) | (1 << UCSZ0);  

  for (;;)  
  {  
    if (data>'Z'||data< 'A')  
    {  
      UDR = 10; UDR = 13; data='A';_delay_ms(100);  
    }  

    UDR = data;  
    data += 1;  
    _delay_ms(100);  
  }  
}  

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.

Markdown source code last modified on January 18th, 2021
---
title: Simple Case AVR/PC Serial Communication via MAX232
date: 2009-05-14 11:00:19
tags: microcontroller, circuit, old
---

# Simple Case AVR/PC Serial Communication via MAX232

__I recently had the desire__ to be able to see data from an ATMEL AVR microcontroller (the [ATTiny2313](http://www.SWHarden.com/blog/images/attiny-2313.gif)) 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](http://en.wikipedia.org/wiki/UART) capabilities of the [ATTiny2313](http://www.SWHarden.com/blog/images/attiny-2313.gif) to talk to my PC through the serial port. One problem is that the [ATTiny2313](http://www.SWHarden.com/blog/images/attiny-2313.gif)(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](http://en.wikipedia.org/wiki/MAX232) which [costs about 3 bucks at DigiKey](http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&amp;name=MAX232CPE%2B-ND). Note that it requires a few 10uF capacitors to function properly.

<div class="text-center img-border">

[![](serialcircuit_thumb.jpg)](serialcircuit.png)

</div>

__Here's a more general schematic:__


<div class="text-center">

![](max232_serial_microcontroller.gif)

</div>

__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:

<div class="text-center">

![](ubrrformula.gif)

</div>

__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.

<div class="text-center">

![](ubrr-table.gif)

</div>

## AVR Baud Calculator

This will make your life easier. The page <a href="http://www.wormfood.net/avrbaudcalc.php">wormfood.net/avrbaudcalc.php</a> 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.

```c
#include <avr/io.h>  
#include <avr/interrupt.h>  
#include <util/delay.h>  

int main (void)  
{  
  unsigned char data=0;  
  UBRRL = 239;  
  UCSRB = (1 < < RXEN) | (1 << TXEN);  
  UCSRC = (1 < < UCSZ1) | (1 << UCSZ0);  

  for (;;)  
  {  
    if (data>'Z'||data< 'A')  
    {  
      UDR = 10; UDR = 13; data='A';_delay_ms(100);  
    }  
    
    UDR = data;  
    data += 1;  
    _delay_ms(100);  
  }  
}  
```

__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.

<div class="text-center img-border">

[![](avr_serial_console_thumb.jpg)](avr_serial_console.jpg)

</div>

__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](https://wikis.mit.edu/confluence/download/attachments/20512/dapa.png)).  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).

<div class="text-center img-border">

[![](avr_max232_thumb.jpg)](avr_max232.jpg)

</div>

__I hope you found this__ information useful.  Feel free to [contact me](http://www.swharden.com/blog/send-scott-a-message/) with any questions you may have, but realize that I'm no expert, and I'm merely documenting my successes chronologically on this website.

PHP-Generated Apache-Style Access Logs

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.

This code has been updated: 2009-08-04-generate-apache-style-http-access-logs-via-sql-and-php

Markdown source code last modified on January 18th, 2021
---
title: PHP-Generated Apache-Style Access Logs
date: 2009-05-14 13:33:22
---

# PHP-Generated Apache-Style Access Logs

__A few months ago__ I wrote about a way [I use PHP to generate apache-style access.log files](2009-01-22-using-php-to-create-apache-style-accesslog/) 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](http://www.python.org) and [Matplotlib](http://matplotlib.sourceforge.net/).  For details (and the messy script) check the original posting.

[![](graph_time_thumb.jpg)](graph_time.png)

__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](http://www.swharden.com/blog/2008-11-17-linear-data-smoothing-in-python/) (which I love writing about), but for now I'll leave it as it is so it most accurately reflects the actual data.

This code has been updated:
[2009-08-04-generate-apache-style-http-access-logs-via-sql-and-php](2009-08-04-generate-apache-style-http-access-logs-via-sql-and-php)
May 12th, 2009

Electronic Components have Arrived

I placed another online order to DigiKey yesterday. They have virtually every electronic component available for next-day delivery. How awesome is that? The frustrating thing is that I'm always trying to get my order in before 6pm CMT so that my package will ship same day, so I rush, and I always forget something! It never fails. 30 minutes after I place an order, I always remember something else I wish I'd added to the order (to save on shipping). So, instead of buying it when I want it (now) I wait a few more days to think of some more stuff to add. The last couple weeks I've placed 3 orders totaling about $30. You never think you're spending a lot, but all the sudden you realize that all these 40-cent parts add up when you go to check out. Shipping is usually under $3, which makes me happy. What did I get? I got a couple MAX232 chips so I can easialy shuffle data back and forth from my PC to an AVR chip using the serial port using a simple terminal application like hyperterminal. This will allow me to do some pretty fancy stuff and certainly help with the prototyping/debugging/development steps of my various microcontroller-based projects.

Some of the things which I forgot to order include a few 1F supercapacitors for my solar-powered QRSS beacon project and a random collection of parts needed to build a DIY AVR microcontroller programmer with a USB PC interface and I also wanted to buy at least one ATMega8 microcontroller because they seem to be a good step above the ATTiny 2313 chips I already have and are at the center of so many microcontroller projects. I'm sure there are are few more items I need, but can't think of them right now, so they don't make the list.

A little random, but worth noting is a cool website I found earlier which details (in a very basic way) the various types of HF antennas and does a good job (IMHO) of explaining the basic theory behind them. The page can be found at deltadx.net.

As an aside, I encourage everyone to take a couple minutes out of your day and browse the Wikipedia entry describing the JPEG compression algorithm. Seriously, it's an educational, enlightening, and entertaining read.

Markdown source code last modified on January 18th, 2021
---
title: Random Junk In'da Mail!
date: 2009-05-12 11:49:58
---

# Electronic Components have Arrived

 __I placed another online order__ to [DigiKey](www.digikey.com) yesterday.  They have virtually every electronic component available for next-day delivery.  How awesome is that?  The frustrating thing is that I'm always trying to get my order in before 6pm CMT so that my package will ship same day, so I rush, and I always forget something!  It never fails.  30 minutes after I place an order, I always remember something else I wish I'd added to the order (to save on shipping).  So, instead of buying it when I want it (now) I wait a few more days to think of some more stuff to add.  The last couple weeks I've placed 3 orders totaling about $30.  You never think you're spending a lot, but all the sudden you realize that all these 40-cent parts add up when you go to check out. Shipping is usually under $3, which makes me happy.  What did I get?  I got a couple [MAX232 chips](http://focus.ti.com/lit/ds/symlink/max232.pdf) so I can easialy [shuffle data back and forth from my PC to an AVR chip using the serial port](http://blog.jeffmurry.com/2008/11/14/hello-world--uart--serial-comm-with-pc.aspx) using a simple terminal application like hyperterminal.  This will [allow me to do some pretty fancy stuff](http://www.societyofrobots.com/microcontroller_uart_50_robot.shtml) and certainly help with the prototyping/debugging/development steps of my various microcontroller-based projects.

<div class="text-center">

[![](rs232_03_thumb.jpg)](rs232_03.jpg)

</div>

__Some of the things which I forgot to order__ include [a few 1F supercapacitors for my solar-powered QRSS beacon project](http://www.solarfreaks.com/rc-solar-car-t19-20.html#p439) and a [random collection of parts](http://www.ladyada.net/make/usbtinyisp/parts.html) needed to build [a DIY AVR microcontroller programmer with a USB PC interface](http://www.ladyada.net/make/usbtinyisp/use.html) and I also wanted to buy at least one [ATMega8 microcontroller](http://www.solarbotics.com/assets/images/atmega8l/atmega8l_pl.jpg) because they seem to be a good step above the [ATTiny 2313 chips](http://home.scarlet.be/kvandepitte/Mijn%20afbeeldingen/nixies/attiny2313.jpg) I already have and are at the center of so [many microcontroller projects](http://hackaday.com/tag/atmega/).  I'm sure there are are few more items I need, but can't think of them right now, so they don't make the list.

__A little random, but worth noting__ is a cool website I found earlier which details (in a very basic way) the various types of HF antennas and does a good job (IMHO) of explaining the basic theory behind them.  The page can be found at [deltadx.net](http://www.deltadx.net/ABCDx/Sections/Antennas.htm).

<div class="text-center img-border">

[![](squareant_thumb.jpg)](squareant.jpg)

</div>

__As an aside,__ I encourage everyone to take a couple minutes out of your day [and browse the Wikipedia entry describing the JPEG compression algorithm](http://en.wikipedia.org/wiki/JPEG).  Seriously, it's an educational, enlightening, and entertaining read.
Pages