Atmega16 development board – Firmware (part2)



   This is the 2nd part of “Atmega16 development board” project where I will describe the basic functionality of the embedded firmware. Apart from RF card interface all other schematic parts are software controlled. The welcome message and main menu can be seen in the pictures below:

Main menu

Welcome message







ADC menu



AD convertor: it contains 3 channels, 0,1 and 2. Channel “0″ is connected to the output of DA convertor. Channel “1″ reads the keyboard level and channel “2″ the RSSI signal from RF card. The successful read of one of the channels will be confirmed by an “OK” message and the value in Volts displayed on the last line.





IR read command

IR menu: has 2 options: Read CMD and send CMD. The first one is used to read an IR command from any remote control. There is a field “CMD name” where an 8 char name can be added by selecting the position (left/right keys) marked by “^” sign, then the letter with up/down keys. The message on the last line displays the current status:  “Wait” = waiting for the command, OK = command was successfully decoded and stored, Full – no free positions in the memory. There are 12 available positions for storing such commands. This feature of decoding IR streams was tested with lots of devices like TV, audio systems, DVD, AC and so on. It has a very good decoding rate (above 95%). 



IR send & manage commands

IR send command: after any command has been stored as explained in the previous paragraph, it can be retrieved using this feature and reused. The Freq field can be adjusted, but for devices using 30-40KHz, this field should be left as it is. The “>” sign will point to desired option by pressing up/down keys. “Read prev” field is one of the 4 options in that tab. The other 3 are: “Read next”, ”Send cmd” and “Delete”. CMD sent [ OK ] = the task was successfully performed.


DA convertor


 DA convertor: this feature outputs between 0 and 5 volts. The value is set in “Output field” then CMD = Start/Stop. To check the real voltage level the ADC menu can be used with conversion set for channel “0″. There is also a LED placed at the output of OP amp which will light accordingly. 





Frequency generator


 Frequency generator: It can generate up to 1,5MHz rectangular signals, 5V level. There are 2 scales: Hz and KHz. Using up/down + left/right keys the desired value can be set in “F” field. There is no feedback measurement to display the value generated but it can be read directly on JP6.






The last feature consist in controlling all above functions over UART interface. Using the below described protocol the user can access all tasks handling these features and not only.


General command: [@] [buffer_size] [task_id] [agent] [specific_data1] [specific_data2]

 All values are byte sized, no space in between.
“@” is the start character, buffer_size represents the total number of bytes contained by the command without the start character. Task_id can be taken from below list. Agent should be always set to “1″ = UART. It is useful for software identification. The last part is represented by specific_data, bytes describing the values for dedicated tasks control.

Task IDs:

  • ADC conversion     [10]
  • I2C write data       [20]
  • I2C read data         [30]
  • IR read command [40]
  • IR send command [50]
  • Signal generator   [70]


 1. ADC conversion:

CMD:  [@] [buffer_size = 5] [task_id = 10] [agent=1] [AD channel] [mode=0]


AD channel:

  • 0: pwm_output
  • 1: keyboard line
  • RSSI – RF card


  • 0 : single acquisition
  • 1 : free running mode (not used on over uart) 

Return: [ret_buffer_size = 4] [error] [value_lsb] [value_msb]


  • 0 : no error
  • 1 : not enough memory
  • 2 : acquisition fault 


2. I2C control

Test case 1: I2C Write 

CMD:  [@] [buffer_size] [task_id = 20] [agent=1] [device_addr] [memory_addr1] [memory_addr2] [device_nb] [data_size] [data1] [data2] … 



  • 0xA0 : for eeprom #0, SMD
  • ? : for eeprom #1, DIP (check datasheet) 

Memory_addr: memory address of device, on 16 bits:

  • memory_addr1 : LSB of address
  • memory_addr2 : MSB of address 

Device_nb (same role as device_addr)

  • 0 : memory #0, SMD
  • 1 : memory #1, DIP

Data_size: number of bytes to be written (max 4).

Return:  [ret_buffer_size] [error]


  • 0 : no error
  • 1 : not enough memory
  • 2 : out of range
  • 3 : unknown error 

Test case 2: I2C Read 

CMD:  [@] [buffer_size = 8] [task_id = 30] [agent=1] [device_addr] [memory_addr1] [memory_addr2] [device_nb] [data_size] 



  • 0xA0 : for eeprom #0, SMD, read from memory_addr
  • 0xA1 : for eeprom #0, SMD, read from counter position (ignore memory_addr)
  • ? : for eeprom #1, DIP (check datasheet) 

Return:  [ret_buffer_size] [error] [data_size] [data]

All fields are the same from Write test case except data_size = [1 .. 20]


3. IR control

Test case 1: Send pattern

 CMD:  [@] [buffer_size] [task_id = 50] [agent=1] [frequency_lsb] [frequency_msb] [bit_length_lsb] [bit_length_msb] [pattern_length] [pattern_bit1] [pattern_bit2] …


Frequency: the frequency of signal for each bit.

Bit_length: length of the bit in the pattern (measured in us)

Pattern_length: number of bits in the pattern.

Return:  [ret_buffer_size] [error]


  • 0 : no error
  • 1 : not enough memory
  • 2 : unknown error 

Test case 2: Read pattern

CMD:  [@] [buffer_size] [task_id = 40] [agent=1] 


There is no additional parameter added in this command. Just send it and the response contains the received pattern.

Return:  [ret_buffer_size] [error] [bit_length] [bit_1] [bit_2] …

 Fields in this test case have similar values with the ones in Send pattern test case


4. Signal generator

Test case 1: DA  convertor

CMD:  [@] [buffer_size = 8] [task_id = 70] [agent=1] [duty_cycle] [not_used] [scale] [command] [mode = 0]


Duty_cycle: duty cycle value between 0 and 255.

Not_used: dummy byte, value doesn’t matter.


  • 0 : Hz
  • 1 : KHz 


  • 0 : Stop PWM
  • 1 : Start PWM 


  • 0 : DA converter
  • 1 : Frequency Generator

 Return:  [ret_buffer_size] [error]


  • 0 : no error
  • 1 : unknown error 

Test case 2: Frequency Generator

CMD:  [@] [buffer_size = 8] [task_id = 70] [agent=1] [frequency_lsb] [frequency_msb] [scale] [command] [mode = 1]


Frequency: frequency value according to scale: Hz or KHz 

All other parameters may take the same values as in PWM test case.

Return:  [ret_buffer_size] [error]


  • 0 : no error
  • 1 : unknown error 

The binaries can be downloaded from here:

1. Firmware binary

2. EEPROM binary : for EEPROM formatting. It contains also some IR commands.


For any question please use “Contact form”.