Ho notato che quando scrivi col write non fai scaricare il buffer sulla porta
Per sicurezza aggiungi:
serialPort1.BaseStream.Flush();
Ad ogni modo oggi ho provato il tuo codice e il problema è un altro, diciamo non immediato per un beginner di C#.
Nell'evento serialPort1_DataReceived non puoi accedere al controllo label3 perché sei su un altro thread e quindi l'istruzione
label3.Text = read;
non viene eseguita. Ti consiglio di mettere SEMPRE la spunta su tutte le voci nella colonna Thrown del menù Debug/Exceptions per vedere in debug tutti gli errori.
la lettura avviene correttamente, il problema è li, nell'aggiornamento dell'interfaccia!
Come FIX veloce ti posso dire di sostituire con
BeginInvoke(new Action(() => {
label3.Text = read;
}));
ma leggi su internet qualcosa a proposito dei thread e dell'accesso ai controlli.
Altro consiglio, non rallentare il programma con progressbar o menate simili se non servono.. più è veloce meglio è! Andava di moda 20 anni fa la progress bar, ora meno c'è meglio è.
Ciao