Like others have said, you need to provide the UniqueID of the control to the __doPostback() method.
__doPostBack('<%= btn.UniqueID %>', '');
On the server, the submitted form values are identified by the name attribute of the fields in the page.
The reason why UniqueID works is because UniqueID and name are in fact the same thing when the server control is rendered in HTML.
Here's an article that describes what is the UniqueID:
The UniqueID property is also used to provide value for the HTML
"name" attribute of input fields (checkboxes, dropdown lists, and
hidden fields). UniqueID also plays major role in postbacks. The
UniqueID property of a server control, which supports postbacks,
provides data for the __EVENTTARGET hidden field. The ASP.NET Runtime
then uses the __EVENTTARGET field to find the control which triggered
the postback and then calls its RaisePostBackEvent method.