Lio con tamaño variables char

Espero no liar más el asunto, pero intentaré explicar un poco.
Efectivamente, es muy probable que el programa te funcione, pero cabría la posibilidad de que en un momento determinado te corrompa alguna variable de tu programa.
En c, cualquier puntero ocupa lo mismo dependiendo de la arquitectura de la memoria. En arduino, creo que dos bytes, lo que vendría a ser un unsigned int conteniendo una dirección de memoria. El declarar un tipo de variable para el puntero, es para que el compilador nos avise si mezclamos churras con merinas, y para las funciones de incremento/decremento (si incrementamos un puntero a char, aumentará la dirección que contiene en 1, si es un puntero a int, en 2...). Ahora viene la pregunta interesante: ¿A qué dirección apunta el puntero?. Pues potencialmente a cualquier punto de la memoria que le indiquemos, de ahí su peligro. Si lo declaramos, sencillamente, apunta a 0000h o, lo que es lo mismo, es un puntero nulo.
Cuando inicializamos un puntero o declaramos un array, la variable realmente contiene un puntero al tipo de datos del array; pero además ese puntero señala a una posición de memoria en la que hemos reservado un determinado espacio o incluso hemos escrito un contenido.
En el caso de la declaración un tanto rara que has hecho (char pi3[0]) supongo que pi3 apunta a una dirección de memoria no nula, pero reserva 0 bytes en esa zona, con lo que si se almacena algo "a continuación", cuando escribes usando un puntero a esa zona, cabe la posibilidad de que estés machacando esa potencial variable. Una solución sería declarar un tamaño de seguridad de buffer, suficiente para lo que vayas a escribir en él (char pi3[20]), aunque si no vas a usar para nada el tipo char, no veo porqué no puedes declarar directamente byte dato3[20] y ahorrarte esa conversión de char* a byte* (dato3 es un byte * pero además apunta a una zona de 20 bytes reservados).
Lo corto aquí, porque como dije al principio, no sé si estoy aclarando o liando más. Saludos.