OK, that makes a little more sense 🙂
As for an infinite loop - not that you need it here, but I'll get to that - just remove the while clause.
It's perfectly valid to say:
repeat
-- do something
end repeat
and it will run ad infinitum - although you can still use an 'exit repeat' statement within the block to break out.
In this case, though, you don't want a repeat loop at all. What you want is an idle handler.
idle handlers run periodically, on a schedule you define, so on that basis your script would look more like:
set use_port to "/dev/cu.usbmodemfa131"
on idle
if (get serialport list) contains use_port then
set myPort to serialport openuse_portbps rate 9600 data bits 8 parity 0 stop bits 1 handshake 0
if myPort ≠-1 then -- check the port opened correctly
tell application "Mail"
set x to unread count of inbox
end tell
if x > 0 then
set mailStatus to "M"
else
set mailStatus to "N"
end if
serialport writemailStatustomyPort
serialport closemyPort
end if
end if
return 3 -- check again in 3 seconds
end idle
This differs from your original in that the script kind of 'wakes up', performs its tasks, and then goes to sleep for the duration (defined as the return value at the end of the idle handler). No spinning wheels, wasted CPU cycles, etc.
One variation that you might consider, depending on your application, is to separate the serial port open/close logic from the idle handler. As written, this script periodically (every 3 seconds) opens the port, writes a character, and closes the port again. It might be better for the script to open the port once (at the beginning), and leave the port open until you quit. In that case the script might look more like:
global myPort
on run
set use_port to "/dev/cu.usbmodemfa131"
if (get serialport list) contains use_port then
set myPort to serialport openuse_portbps rate 9600 data bits 8 parity 0 stop bits 1 handshake 0
if myPort = -1 then -- check the port opened correctly
display alert "Ooops, unable to open the serial port " & use_port
tell me to quit
end if
else
display alert "Oops. Serial port not found"
tell me to quit
end if
end run
on idle
tell application "Mail"
set x to unread count of inbox
end tell
if x > 0 then
set mailStatus to "M"
else
set mailStatus to "N"
end if
serialport writemailStatustomyPort
return 3 -- check again in 3 seconds
end idle
on quit
try
serialport closemyPort
end try
continue quit
end quit
In this version, the logic is broken into three distinct parts - the 'run' handler is executed when the script starts, and opens the serial port (or gracefully exits if the port can't be opened).
The comes the idle handler - this is run periodically to check the mail status and write the data to the serial port (this block might warrant some check to ensure the port is open/available, but I'll leave that to you).
Finally comes the quit handler which executes when the script quits. This simply closes the port so that it's not left open.
You'll need to decide whether it's better to periodically open/close the port, or open it once and keep it open for the duration.