All Files Pages
Serial protocol for programming PIC's and EEPROM's with Arduino


All address and data values in the protocol are sent in hexadecimal. The main notable exceptions are the data payloads to the READBIN and WRITEBIN commands that use a compact binary representation instead of hexadecimal.

Address space

All commands in this protocol use a flat address space. For example, on the PIC16F628A, program memory runs from 0x0000 to 0x07FF (hex), config memory runs from 0x2000 to 0x2007, and EEPROM runs from 0x2100 to 0x217F. These flat addresses are converted into the correct low-level addressing format by ProgramPIC.

Flat addressing was chosen to simplify the host implementation which will have flat addresses (multiplied by 2 typically) in the hex file. The host does not need to be concerned about the details of switching between addressing modes. If ProgramPIC needs to reset the device to go backwards in memory or switch to a different memory type, then it takes care of that detail internally.

The current implementation of ProgramPIC uses a flat 32-bit address space internally to allow for future expansion. The host should assume 32-bit flat addressing also.

The DEVICE and SETDEVICE commands are used to retrieve information about the flat address ranges that the device uses for program, config, and data memory. If the device type is unknown to ProgramPIC, then the host may still be able to issue some commands but the results will be unreliable. It is best in this case for the host to issue an error along the lines of "Unsupported device, ID = NNNN".

Command format

Commands are sent from the host to ProgramPIC in text format, with responses also in text except for certain select binary commands.

A command from the host is a line of ASCII characters, terminated by either a CR (0x0D) or LF (0x0A) character. The line may be up to 64 characters in length, not including the terminator. Additional characters beyond the first 64 are discarded. Fields on a line are separated by either SPACE (0x20) or TAB (0x09) characters, and there can be leading or trailing white space. Blank lines are ignored.

The command is converted to upper case when received by ProgramPIC and before being processed further. Thus, "read", "READ", and "rEaD" are all equivalent to "READ". The following are some examples of commands:

READ 2007
READ 0000-03FF

Commands from the host may be terminated with any combination of CR, LF, or CRLF. Text responses from ProgramPIC are always terminated with CRLF.

Most commands can be issued directly to ProgramPIC using a serial communications program, such as the Serial Monitor in the Arduino IDE (make sure to select "Newline" or "Carriage return" line endings). This allows for simple testing and debugging of ProgramPIC but is not suitable for the bulk reads and writes involved in programming a hex file into a PIC. A separate dedicated host program is recommended for bulk operations.

Unknown commands

If the command is not recognized by ProgramPIC, then it must respond with the line "NOTSUPPORTED", terminated by CRLF. Normal command responses are typically "OK" or "ERROR"; the latter indicating that the command is known but it has failed for some reason.


The PROGRAM_PIC_VERSION command returns information about ProgramPIC itself rather than the PIC in the programming socket. The currently valid response is a single line of text containing ProgramPIC 1.0, terminated by CRLF.

This command can be used by the host to determine if the Arduino is running a valid version of ProgramPIC or some other sketch. If the host does not receive a valid response within 3 seconds, it should assume that it is not talking to an instance of ProgramPIC.

Note: this command must return exactly the characters ProgramPIC 1.0 to be compatible with this version of the protocol. The version response should not be used for vendor-specific strings or settings. A separate command should be used for that purpose.

In the future, version strings of the form ProgramPIC 1.x, where x is a number greater than zero, will be used for extensions to this protocol that remain backwards-compatible. That is, existing commands continue to work as defined here, but new commands may be available. A hypothetical ProgramPIC 2.x version number would indicate a completely new protocol that is not backwards-compatible.

Hosts that implement version 1.0 of the protocol should recognize any higher version, such as 1.1 and 1.2, and continue to operate normally. Hosts that implement version 1.x of the protocol should abort with an error if ProgramPIC responds with version 2.0 or higher.


The HELP command returns a list of all commands that are understood by ProgramPIC with a brief description. The help details are terminated by a line containing a period.

This command is intended primarily for interactive use via the Serial Monitor in the Arduino IDE. It is not intended to be machine-parsable. Hosts should use the protocol version number to determine whether a command is supported or not.


The DEVICE command is used to retrieve information about the PIC device that is in the programming socket. The device is forcibly reset, important device data is read, and then the device is powered down. A line that starts with a period terminates the returned data. The following is an example of the output:

DeviceID: 1066
DeviceName: pic16f628a
ProgramRange: 0000-07FF
ConfigRange: 2000-2007
DataRange: 2100-217F
ConfigWord: 3FFF

If the programming socket is empty, or the VPP programming voltage is not available, or the PIC cannot be read for some reason (e.g. code protection is enabled), then the DEVICE command will respond with a single line containing ERROR.

Older PIC's do not report a device identifier. These will be reported as DeviceID: 0000 (with exactly 4 zeroes). The SETDEVICE command must be used by the host to manually specify the device type.

It is required that this command be used before attempting to read or write from the PIC to detect the type of PIC in the programming socket and to ensure that ProgramPIC is using the correct address ranges for program, config, and data memory.

The following information is provided for all PIC types, including those that are not recognized by their device identifier:

If ProgramPIC recognizes the PIC type, then it will also return the following extra information:

If the device identifier is not recognized by ProgramPIC, then it may still be possible to issue some commands, but the result will be unreliable; particularly if the host attempts to write data to the PIC device. Thus, if the DeviceName field is not present and DeviceID is non-zero, then the host should report an error along the lines of "Unsupported device, ID = NNNN".

If the DeviceID is zero (PIC present but identifier not available), then the host can use DEVICES to obtain a list of all supported devices, and use SETDEVICE to select a specific device type.

The attribute names and values are case-sensitive unless specified otherwise.

Note: if the device locates config memory somewhere other than 0x2000 in flat address space, then the "DEVICE" command will be able to find it and then report the correct range. Using a command like "READ 2007" to read the configuration word is not advisable until the host has retrieved the ConfigRange and determined that the configuration word is indeed located at 0x2007.


The SETDEVICE command manually sets the device that ProgramPIC will assume is in the programming socket. This command should be used if DEVICE finds a PIC device in the socket but is unable to determine the device identifier.

This command takes a single argument which is the name of the PIC device to set. For example:

SETDEVICE pic16f84

The command responds with "ERROR" if the device name is not recognized, or with a list of device properties otherwise:

DeviceName: pic16f84
ProgramRange: 0000-03FF
ConfigRange: 2000-2007
DataRange: 2100-213F

Any combination of upper and lower case can be used in the device name: "PIC16F84" and "Pic16f84" will also match the canonical version, "pic16f84".


The DEVICES command returns a list of all PIC device names that are supported by ProgramPIC, separated by commas, and terminated by a line starting with a period. White space and newlines in the returned list are not significant. The following is an example output:

pic12f629*, pic12f630*, pic12f675*, pic12f676*, pic16f84, pic16f84a*,
pic16f87*, pic16f88*, pic16f627*, pic16f627a*, pic16f628*, pic16f628a*,

If the name ends with an asterisk (*), then the device can be autodetected by DEVICE. A name without an asterisk can only be selected by using SETDEVICE.


The READ command reads words from the device and returns them to the host in ASCII format after a line that says "OK". Each word is separated by spaces or newlines, and the entire response is terminated with a line containing a period. Words are transmitted MSB-first in the hexadecimal representation. Data words will be printed as 16-bit values even though typically only the bottom 8 bits are significant.

The argument to the command is either a single address in hexadecimal or a range of addresses in the form "START-END". All memory locations in the range are read and sent back to the host.

If the address range is badly formatted, out of bounds, start is greater than end, or start and end do not fall within the same memory area (prograrm, config, or data), then the READ command will respond with the line "ERROR".

The following are some examples of reading from a blank PIC16F628A:

READ 0000
READ 2006
READ 2060
READ 0000-000A
READ 000A-0000
READ 0000-217F


The READBIN command is identical to READ except that after sending the "OK" response, it packs the data into an efficient binary form for faster transmission to the host. This command is recommended for host applications that read bulk data from a PIC.

The response format is a sequence of one or more binary "packets". Each packet starts with a length byte that specifies the number of bytes that follow. The length must not exceed 64 and must be a multiple of 2. A length of zero terminates the response and ProgramPIC returns to waiting for the next command.

After the packet length will be an even number of bytes, as specified by the length. Each pair of bytes specifies the value of a single word in the response, LSB-first.

If READBIN gives an "ERROR" response, its operation will be identical to READ.


The WRITE command is used to write words to program, config, or data memory. The arguments are the starting address plus one or more word values in hexadecimal, MSB-first. For example:

WRITE 0100 1234 1A3F
WRITE 2100 11 22 33 44

Because of ProgramPIC's 64 character limit on commands, it is recommended that no more than 8 words be sent in a single request.

Some devices have preserved bits in the configuration word (e.g. PIC12F675) which will be protected by the WRITE command. To disable this protection and force the value to be written regardless, use the FORCE option:


The command will respond with "OK" if the words were written, or "ERROR" if one of the following occurs:

The host should verify the address range before it sends the command so that the only error case to be handled is a failed write.

Note: the device should be bulk-erased with ERASE before performing write operations.


The WRITEBIN command is identical to WRITE except that it packs the data into an efficient binary form for faster transmission from the host to ProgramPIC. This command is recommended for host applications that write bulk data to a PIC.

The command starts by sending the starting address to ProgramPIC (the FORCE option can also be used):


At this point, the command responds with "OK" or "ERROR". An error occurs if the starting address is out of range or the command is badly formatted.

If the command responds with "OK", then the host is clear to send a single binary packet to ProgramPIC using the same packet format as READBIN.

ProgramPIC writes the words in the packet to memory and responds with either "OK" or "ERROR". If the response is "ERROR" then the write has failed and the host must stop sending further packets. If the response is "OK", then the host can send another packet to be written into subsequent addresses.

A packet length of zero terminates the WRITEBIN data transfer and ProgramPIC responds with "OK" to acknowledge the terminating packet.

The following is the binary version of "WRITE 0100 1234 1A3F". For ease of discussion, the packets are shown as hex values within angle brackets. In reality they are sent as raw bytes:

<<04 34 12 3F 1A>> // first packet
<<00>> // terminating packet

Unlike READBIN which streams packet data, the host must stop and wait for a response after every written packet. This implements a simple form of flow control to prevent the faster host from overwhelming ProgramPIC with lots of data and overflowing the serial buffers. It will also cause the process to abort early if there is an error, so the host does not have to wait for the entire hexfile to be sent to ProgramPIC before detecting a problem.

If the binary packet length exceeds 64, then additional bytes beyond the first 64 will be discarded. If the packet length is odd, then the extra byte will be discarded. Hosts should never send a binary packet with a length greater than 64 or an odd packet length.

In addition, the length of the first packet must never be 0x0A (10 decimal) or ProgramPIC may become confused between 0x0A used as an LF line terminator in a CRLF pair and 0x0A used as a packet length. If the host needs to write exactly 10 bytes (5 words), then it can either split the packet into two smaller packets or use WRITE instead.

ProgramPIC will discard any 0x0A bytes that occur before the first packet. Subsequent packets can have a length byte of 0x0A.

Note: the device should be bulk-erased with ERASE before performing write operations.


The ERASE command performs a bulk erase on all program, config, and data memory in the device. Code and data protection will be disabled. Reserved words (e.g. OSCCAL values) are automatically preserved and written back to program memory afterwards; the host does not need to worry about preserving these values. The command will respond with either "OK" or "ERROR".


If the device has reserved words, then the host can ask that they be erased as well by using the NOPRESERVE option:


If NOPRESERVE is given and the device does not have reserved words, then the command will act identically to ERASE. The host should only use NOPRESERVE if it is about to send new data for the reserved words.

Some devices, particularly large EEPROMS in the 24LCXX family, can take longer to erase than the standard 3 second host timeout. The ERASE command should send the line PENDING to the host at least once every two seconds to tell the host that the operation is still in progress. Once the erase completes, the sketch will respond with OK or ERROR.


The PWROFF command turns off the power to the programming socket. ProgramPIC responds with the line "OK". The power will be re-applied automatically when the next command that needs to talk to the programming socket is issued.

This command should be sent by the host once it has completed the programming process. It will then be safe for the user to remove the device from the programming socket and/or replace it with a new device.

The host may also issue this command if it wishes to force the device to reset. Normally this isn't necessary because DEVICE will reset the device automatically.

ProgramPIC may itself remove power from the programming socket for various reasons: inactivity timeout or a reset is required to complete the current operation.

Recommended sequence of commands

The following is the recommended sequence of commands that the host should send to read or program a PIC device: