Just a thought: this is AVR, and AVR is Harvard, and you use different instructions to access RAM and ROM. If the string is ending up in ROM, strncpy won't be able to see it. It's been long enough since I last used one that I can't remember exactly what happens in this situation.
If you copy bytes manually from bat to buffer, instead of using strncpy, do you get "Bat" on the screen? If you get garbage, this will be why.
I've got a project at home somewhere that does similar things. If I remember tonight, I'll dig it up and see what tricks it had to use.
char bat[] = "12345678";
char buffer[9];
strncpy( buffer, bat, 8 );
This will copy the first 8 bytes from bat to buffer, then stop. It won't append a zero, because strncpy is a nasty little function that loves to surprise you. If you
buffer[8] = 0;
yourself, then all should be good. But your memset is doing that, so I don't know what's going wrong.