def reopen(me, port = None) :
        me.blind_close()

        if  not port :
            port    = tz_usb.find_likely_COM_ports(vendor_id = USB_VENDOR_ID, product_id = USB_PRODUCT_ID)
            if  port :
                port    = port[0]
            pass

        if  not port :
            return(None)

        try :
            port    = int(port)
            cport   = port - 1
        except ValueError :
            cport   = port

        try :
            me.io   = serial.Serial(port = cport, baudrate = 19200, parity = "O", timeout = 0.001)                # note: PC program sets 8O1. serial.Serial() multiplies timeout by 1000 before passing to windows (This 1 mill is minimum for windows. I don't know about other OS's.)
        except serial.SerialException :
            return(False)

        return(True)
def main(ident) :
    import      TZCommandLineAtFile
    import      TZKeyReady
    try :
        import  tz_google_chart
        import  tz_browser
    except ImportError :
        tz_google_chart = None


    if  ident :
        sys.argv.insert(1, ident)
        sys.argv.insert(1, '--ident')

    program_name    = sys.argv.pop(0)

    TZCommandLineAtFile.expand_at_sign_command_line_files(sys.argv)


    ident       = ""
    port        = 0             # my COM port, not yours
    port_list   = 0
    verbose     = 0


    help_str    = """
%s (options) (output_files_base_name)

    I get the streaming data from a CMS50E Pulse Oximeter.

Options:

    --port  port_number     Set the COM port number
    --port_list             List possible ports (twice, list all available ports)
    --version               Print the program version number.


""" % ( os.path.basename(program_name) )


    oi  = tzlib.array_find(sys.argv, [ "--help", "-?", "?", "-h", "/h", "/?", "?" ] )
    if  oi >= 0 :
        print help_str
        sys.exit(254)


    while True :
        oi  = tzlib.array_find(sys.argv, [ "--ident", "-i" ] )
        if  oi < 0 :    break
        del sys.argv[oi]
        if  (oi >= len(sys.argv)) or not len(sys.argv[oi]) :
            print "Program IDENT info not given!"
            sys.exit(101)
        ident       = sys.argv.pop(oi)


    while True :
        oi  = tzlib.array_find(sys.argv, [ "--version", "-v" ] )
        if  oi < 0 :    break
        del sys.argv[oi]
        print "version", _program_version_str(ident)
        if  not sys.argv :
            sys.exit(0)
        pass


    while True :
        oi  = tzlib.array_find(sys.argv, [ "--port", "-p" ] )
        if  oi < 0 :    break
        del sys.argv[oi]
        if  (oi >= len(sys.argv)) or not len(sys.argv[oi]) :
            print "No COM port given!"
            sys.exit(102)
        port        = sys.argv.pop(oi)


    while True :
        oi  = tzlib.array_find(sys.argv, [ "--port_list" ] )
        if  oi < 0 :    break
        del sys.argv[oi]
        port_list  += 1

    while True :
        oi  = tzlib.array_find(sys.argv, [ "--verbose" ] )
        if  oi < 0 :    break
        del sys.argv[oi]
        verbose    += 1



    ofile_name      = None
    if  len(sys.argv) >= 1 :
        ofile_name  = sys.argv.pop(0)

        if  ofile_name.startswith('-') :
            print "Put the whole path or a dot/slash before the output file name. Dashes are confusing: [%s]" % ofile_name
            sys.exit(104)

        pass

    if  len(sys.argv) :
        print "I don't understand %s (--help for options)!" % ( sys.argv )
        sys.exit(104)



    if  port_list :
        tz_usb.find_likely_COM_ports(vendor_id = USB_VENDOR_ID, product_id = USB_PRODUCT_ID, list_level = port_list)


    if  not port :
        port    = tz_usb.find_likely_COM_ports(vendor_id = USB_VENDOR_ID, product_id = USB_PRODUCT_ID)
        if  port :
            print   "Using port", port[0],
            if  len(port) > 1 :
                print "Found ports", port,
            print
            port    = port[0]
        pass

    if  not port :
        print "Please tell me a COM port to use with the --port option (e.g. --port 2 )!"
        sys.exit(103)

    try :
        port    = int(port)
        cport   = port - 1
    except ValueError :
        cport   = port

    try :
        io  = serial.Serial(port = cport, baudrate = 19200, parity = "O", timeout = 0.001)                # note: PC program sets 8O1. serial.Serial() multiplies timeout by 1000 before passing to windows (This 1 mill is minimum for windows. I don't know about other OS's.)
    except serial.SerialException :
        print "Port %s [%s] cannot be opened!" % ( str(port), str(cport) )
        sys.exit(111)

    me      = a_comm(io)

    samples = a_recording()

    if  ofile_name :
        if  os.path.splitext(ofile_name)[1].lower() == ".csv" :
            fo  = output_files.a_file(ofile_name)
            fo.write(a_full_sample.csv_header + "\n")
        else    :
            fo  = None
            fn  = get_output_file_name(ofile_name, program_name = program_name)
            print "Outputting to: ", samples.open_write_file(fn)
        pass

    prg     = a_progress_rtn()
    stopped = 1000
    finger  = False
    lay     = []
    mx      = -10000
    mn      =  10000
    msa     = [ 64 ] * 300
    mss     = float(sum(msa))
    ts      = tzlib.elapsed_time()
    rx_when = ts
    png_drs = [ 7.5, 15.0, 30.0, 60.0, 120.0, 10 * 60.0, 15 * 60.0, 60 * 60.0, 2 * 60 * 60.0, 6 * 60 * 60.0, 12 * 60 * 60.0, ]
    png_di  = 0
    sb      = 0xf5

    me.start_usb()              # in case he's not turned it on (though we'll do this every half second of silence from the device, anyway

    print "Type ? for help"

    while True :
        try :
            s       = me.read_sample(progress_rtn = prg.show_progress, verbose = verbose)
            if  s   :
                yy  = s.y

                if  False :
                    msa.append(s.y)
                    mss        += s.y
                    mss        -= msa[0]
                    del(msa[0])
                else            :
                    mss         = 64
                if  False       :
                    yy          = ((s.y) * ((s.bc & 0xf) + 1)) / 4.5        # tends to flatten out in the middle when there is a change to low amplitude waves
                    if  False :
                        if  yy  < 0 :
                            yy  = -math.log(-yy + math.e)
                        else    :
                            yy  =  math.log( yy + math.e)
                        pass
                    pass

                mx  = max(mx, yy)
                mn  = min(mn, yy)

                if  s.ac & 3 :
                    print "@@@@ ac=%u" % s.ac
                    lay.append(s.ac)

                if  not  finger :
                    samples.append(a_finger_sample(True))
                samples.append(s)
                if  ofile_name  :
                    if  fo      :
                        fo.write("%s\n" % s.csv_str())
                    samples.write_new_samples()
                ys      = (' ' * int((100.0 * (yy - mn)) / max(1.0, (mx - mn)))) + '*'
                # avya  = [ ox for ox in samples.samples[-5 * SAMPLE_RATE : ] if hasattr(ox, 'y') ]
                # avy   = sum([ ox.y for ox in avya ]) / float(max(1, len(avya)))
				#dreamtcs might want to skip this
                print ( s.print_str() )               # (100.0 * yy) / (yy + (s.bc & 0xf)), ys )

                if  not finger :
                    finger  = True
                    samples.flush_file()
                    print "Finger"
                stopped = max(stopped - 10, 0)

                if  len(samples.samples) > png_drs[-1] * SAMPLE_RATE * 2 :
                    samples.flush_file()
                    samples.forget_old_samples(png_drs[-1] * SAMPLE_RATE)
                rx_when = tzlib.elapsed_time()
            t   = tzlib.elapsed_time()
            if  t - ts > 59 :
                ts  = t
                samples.flush_file()
            pass
        except   a_cms50_no_finger_exception :
            if  finger  :
                finger  = False
                samples.append(a_finger_sample(False))
                print "No finger"
                samples.flush_file()
            pass
        except   a_cms50_data_exception, msg :
            samples.flush_file()
            print msg                                   # those bits are not, apparently, dupes of each other
            if  not stopped :
                sys.exit(199)
            stopped    -= 1
        except ( a_cms50_exception, a_cms50_timeout_exception, ) :
            t   = tzlib.elapsed_time()
            if  t - rx_when > 0.5 :
                rx_when = t
                ts      = t
                mx      = -10000
                mn      =  10000
                samples.flush_file()
                me.start_usb()
            pass