A.S.P Δημοσ. 7 Δεκεμβρίου 2011 Δημοσ. 7 Δεκεμβρίου 2011 Καλησπέρα! Έχω δημιουργήσει ένα πρόγραμμα με το οποίο κάνει έλεγχο της USB (COM3,COM4,COM5,COM6) Ανάλογα με την COM που χρησιμοποιεί ο υπολογιστής για να τοποθετήσει την συσκευή με το usb devince που θέλω να κάνει έλεγχο το πρόγραμμα ! Έχω ένα Button , ένα timer , SerialPort και ένα εργαλείο κοντέρ που έχει Min Value = 0 , Μax Value =100.Τώρα το Button απλά ενεργοποιεί το Timer.To timer κάνει έλεγχο της θύρας μέσω του SerialPort και στην συνέχεια αποθηκεύει σε μια integer μεταβλητή τα στοιχεία που διαβάζει από την θύρα, που έχει τιμές από 0 έως 1023 που αντιστοιχεί στο value του κοντέρ με ένα πολλαπλασιασμό ώστε να του δίνει τις τιμές από 0% ως 100% (Conter.Value= iMeter * 0,097751710654936461388074291300098). Το πρόγραμμα αυτό στον υπολογιστή που το έγραψα λειτουργεί άψογα (Dekstop PC με Windows 7 x64). Τώρα έχω ένα Laptop με windows vista x32 , το οποίο όταν πάω να τρέξω το πρόγραμμα κολλάει σε στάδιο να μην μπορώ να κλείσω το πρόγραμμα. Το πρόγραμμα κολλάει όταν πάει να τρέξει το timer(που κάνει την ανάγνωση της θύρα). Το πρόβλημα μου όπως καταλαβαίνεται είναι στο ότι κολλάει το πρόγραμμα στο Laptop.Τι πρέπει να εξετάσω ώστε να βρω τι φταίει Ευχαριστώ πολύ!
Directx Δημοσ. 7 Δεκεμβρίου 2011 Δημοσ. 7 Δεκεμβρίου 2011 Δεν ασχολούμαι με Visual BASIC αλλά από την περιγραφή θα κοίταζα αν μπορώ να ορίσω το time-out της σειριακής ώστε να ελαχιστοποιήσω τον χρόνο που χρειάζεται το Λ.Σ. για να αποφανθεί αν υπάρχει επιτυχής επικοινωνία με την σειριακή. Επίσης θα μπορούσες να κοιτάξεις την επανασχεδίαση του προγράμματος ώστε είτε να τρέχει ασύγχρονα (με non-blocking ρουτίνες) ή σύγχρονα εντός κάποιας Thread (οπότε de facto ασύγχρονα) ώστε μέχρι να αποκριθεί η σειριακή να μην παίρνει μαζί της (να παγώνει δηλαδή) το κεντρικό UI Thread του προγράμματος (με αποτέλεσμα να φαίνεται ότι κολλάει κλπ στον χρήστη).
A.S.P Δημοσ. 7 Δεκεμβρίου 2011 Μέλος Δημοσ. 7 Δεκεμβρίου 2011 Δεν ασχολούμαι με Visual BASIC αλλά από την περιγραφή θα κοίταζα αν μπορώ να ορίσω το time-out της σειριακής ώστε να ελαχιστοποιήσω τον χρόνο που χρειάζεται το Λ.Σ. για να αποφανθεί αν υπάρχει επιτυχής επικοινωνία με την σειριακή. Επίσης θα μπορούσες να κοιτάξεις την επανασχεδίαση του προγράμματος ώστε είτε να τρέχει ασύγχρονα (με non-blocking ρουτίνες) ή σύγχρονα εντός κάποιας Thread (οπότε de facto ασύγχρονα) ώστε μέχρι να αποκριθεί η σειριακή να μην παίρνει μαζί της (να παγώνει δηλαδή) το κεντρικό UI Thread του προγράμματος (με αποτέλεσμα να φαίνεται ότι κολλάει κλπ στον χρήστη). Απάντηση: Πιστεύω πώς σε κατάλαβα , σχετικά με την ανταπόκριση της σειριακής πιστεύω ευθύνεται το πρόγραμμα . Διότι εξέτασα τον υπολογιστή και είδα ότι σταματάει μια υπηρεσία σειριακής COM, ακόμα όμως νομίζω ότι σταμάταγε και το Framework όταν εκτελούσε ενεργοποιείτε το timer. Αναφέρθηκες σε μια ωρολόγια ή μεθοδολογία που δεν την κατάλαβα σχετικά με την ασύγχρονη και σύγχρονή λειτουργία του προγράμματος. Σε ευχαριστώ!
Directx Δημοσ. 7 Δεκεμβρίου 2011 Δημοσ. 7 Δεκεμβρίου 2011 Blocking ονομάζουμε τις ρουτίνας εκείνες οι οποίες όταν καλούνται μπλοκάρουν την εκτέλεση του προγράμματος (δηλαδή της thread στην οποία εκτελούνται, δηλαδή την κεντρική thread του προγράμματος μας) μέχρι να ολοκληρώσουν τον σκοπό τους. Στην περίπτωση σου η ρουτίνα μπλοκάρει την εκτέλεση του προγράμματος μέχρι να απαντήσει εντός κάποιου χρονικού ορίου (time-out) η συγκεκριμένη Com. Non blocking ή ασύγχρονες ρουτίνες ονομάζουμε εκείνες που όταν καλούνται εκτελούνται σε ξεχωριστή thread και δεν μπλοκάρουν την εκτέλεση του προγράμματος αλλά ενημερώνουν μέσο διαφόρων μεθόδων callbacks κλπ για την εκτέλεση τους το πρόγραμμα όποτε χρειάζεται ως την ολοκλήρωση τους. Σε μια τέτοια περίπτωση η ασύγχρονη ρουτίνα θα ξεκίναγε μια thread αυτόματα η οποία θα περίμενε να απαντήσει εντός κάποιου χρονικού ορίου η συγκεκριμένη Com δίχως να παγώνει ταυτόχρονα το υπόλοιπο πρόγραμμα που θα μπορούσε μέχρι να ολοκληρωθεί η διαδικασία να ενημερώνει το χρήστη για την πρόοδο της ή να του δίνει την δυνατότητα ακύρωσης της αντί του να κολλάει όπως τώρα. Ο προγραμματισμός με ασύγχρονες ρουτίνες είναι συνήθως δύσκολος σε σχέση με τις σύγχρονες που είναι απλούστερες στην διαχείριση τους. Τέλος υπάρχει και μια συμβιβαστική μέθοδος όπου γράφουμε το πρόγραμμα με σύγχρονες ρουτίνες εντός ενός thread που δημιουργούμε μόνοι μας κρατώντας έτσι την πολυπλοκότητα σε χαμηλό επίπεδο. Όσον αφορά το time out συνήθως ορίζεται στα 30+/- δευτέρα οπότε αν ως τότε δεν υπάρξει απόκριση το λειτουργικό ενημερώνει την εφαρμογή/framework ότι η θύρα δεν ανταποκρίθηκε επιτυχώς. Τώρα, σε περιπτώσεις blocking εντολών συμφέρει να το έχουμε σε χαμηλή τιμή πάντα (για να μην παγώνει πολύ ώρα το πρόγραμμα) με κίνδυνο όμως μια υπηρεσία να αποκριθεί λίγο πιο αργά και να αστοχήσουμε θεωρώντας ότι δεν είναι διαθέσιμη. Περισσότερα δεν μπορώ να πω πέραν ότι έχω δει διαφορά παράξενα πράγματα με εικονικούς οδηγούς Com όταν πριν μερικά χρόνια χρειάσθηκε να προγραμματίσω επικοινωνία με εικονική θύρα Com σε IrDA (ορισμένες φορές ο οδηγός της θύρας κολλούσε εντελώς για δικούς του λόγους!!).
A.S.P Δημοσ. 7 Δεκεμβρίου 2011 Μέλος Δημοσ. 7 Δεκεμβρίου 2011 Blocking ονομάζουμε τις ρουτίνας ...................... Περισσότερα δεν μπορώ να πω πέραν ότι έχω δει διαφορά παράξενα πράγματα με εικονικούς οδηγούς Com όταν πριν μερικά χρόνια χρειάσθηκε να προγραμματίσω επικοινωνία με εικονική θύρα Com σε IrDA (ορισμένες φορές ο οδηγός της θύρας κολλούσε εντελώς για δικούς του λόγους!!). Σε ευχαριστώ και πάλι , βεβαία τώρα για το μάθημα που μου παρουσίασες. Σχετικά με τα τελευταία σου λόγια προσπάθησες με κάποιο άλλο τρόπο?
Directx Δημοσ. 7 Δεκεμβρίου 2011 Δημοσ. 7 Δεκεμβρίου 2011 Δυστυχώς όχι, ήταν θέμα οδηγού η ακόμα χειρότερα συσκευής οπότε λίγα πράγματα μπορούσαν να γίνουν δεδομένου ότι δεν υπήρχε αναβάθμιση για αυτόν ούτε μπορούσα να αλλάξω υλικό. Απλά ως αντίδοτο είχα ρυθμίσει το πρόγραμμα ώστε να δείχνει κατανόηση στην κατάσταση δοκιμάζοντας επανάληψη της σύνδεσης και της επικοινωνίας μερικές φορές ως ότου κρίνει ότι αυτή δεν ήταν εφικτή ή είχε πλέον αστοχήσει. Ήταν δηλαδή μια μορφή retry στις εντολές που έστελνα και αυτό διόρθωσε αρκετά την κατάσταση αλλά δεν εξάλειψε το φαινόμενο πλήρως. Αντίθετα όταν δούλευα μέσο καλωδίου η σύνδεση ήταν άψογη. Να έχεις υπόψη σου πάντως ότι ο προγραμματισμός serial είναι από τους πιο απαιτητικούς καθώς δεν ξέρεις πότε πως θα αντιδράσει ο οδηγός ή (και) η συσκευή με την οποία συνομιλείς, στην περίπτωση μου επρόκειτο για κινητό τηλέφωνο με irDA. Έκτοτε όταν ασχολούμαι (σπάνια) με τέτοιου είδους προγράμματα πάντα λαμβάνω υπόψη μου στο σχεδιασμό εκτός των άλλων και την προϋπόθεση του retry στις ρουτίνες μου.
Apoll Δημοσ. 8 Δεκεμβρίου 2011 Δημοσ. 8 Δεκεμβρίου 2011 Χρησιμοποίησε μια νέα κλάση να κάνει το διάβασμα από την σειριακή. Βάλτη σε άλλο thread ή πιο εύκολα σε background worker. Βάλε τον background worker να είναι προσβάσιμος από τον κώδικα. Αν θες να σου εμφανίζει τις τιμές από την σειριακή σε 'real time' στην οθόνη, θα χρειαστείς μια μεταβλήτη public shared στην κύρια κλάση που χρησιμοποιείς, που η κλάση με την οποία διαβάζεις την σειριακή θα βάζει τις τιμές. Με ένα event θα γράφεις την οθόνη την τιμή της μεταβλητής, και όλα τα τρέχουν χωρίς καθυστερήσεις. Φυσικά μην ξεχάσεις να κλείνεις τον background worker, να τον καθαρίζεις από την μνήμη, καθώς και τις σειριακές κλπ πριν κλείσει ακόμα η εφαρμογή. Βάλε try-catch blocks παντού ιδίως εκεί που διαβάζεις από την σειριακή, και φυσικά timeout. Αν χρησιμοποιείς MDI Parent form σε windows forms, βάλε την public shared μεταβλητή εκεί καθώς και την κλήση από τον background worker/thread να δουλεύουν μόλις ξεκινήσει το πρόγραμμα. Για να διαβάσεις από σειριακή με web εφαρμογή, θα πρέπει να την βάλεις σε web service. Κλείνωντας ένα singleton βρίσκει καλή χρήση στο συγκεκριμένο πρόβλημα επίσης. Αυτά από κάποιον που έγραψε αρκετές εφαρμογές να μαζεύει live δεδομένα από weighbridges μέχρι conveyor belts και μηχανήματα εξόρυξης κάρβουνου σε deep mines.
A.S.P Δημοσ. 8 Δεκεμβρίου 2011 Μέλος Δημοσ. 8 Δεκεμβρίου 2011 Χρησιμοποίησε μια νέα κλάση να κάνει το διάβασμα από την σειριακή. Βάλτη σε άλλο thread ή πιο εύκολα σε background worker. Βάλε τον background worker να είναι προσβάσιμος από τον κώδικα. Αν θες να σου εμφανίζει τις τιμές από την σειριακή σε 'real time' στην οθόνη, θα χρειαστείς μια μεταβλήτη public shared στην κύρια κλάση........................... Αυτά από κάποιον που έγραψε αρκετές εφαρμογές να μαζεύει live δεδομένα από weighbridges μέχρι conveyor belts και μηχανήματα εξόρυξης κάρβουνου σε deep mines. Σε ευχαριστώ! Να σου πω την αλήθεια δεν έχω φτιάξει εφαρμογές με Singleton και τα βιβλία μου δεν περιγράφουν κάτι σχετικά με την singleton, όμως βρήκα σχετικές πληροφορίες στο google...Σε ποία σημεία πιστεύεις πρέπει να χρησιμοποιήσω την singleton στο αρχικό πρόγραμμα ή μόνο για σύνδεση,ανάγνωση της σειριακής και ακόμα για να μεταφέρω τις μετρήσεις στα Κοντέρ που θα χρησιμοποιήσω το timer?.... ---------------------------------- Σχετικά με το Laptop έκανα εγκατάσταση της visual basic 2010, που δεν ήταν εγκατεστημένη πριν και το πρόγραμμα τρέχει σε start debugging, λειτουργεί με τις μετρήσεις κανονικά απλός μετά από κάποιες μετρήσεις τα χάνει και πετάει κάποια μηνύματα dll. A first chance exception of type 'System.FormatException' occurred in mscorlib.dll A first chance exception of type 'System.UnauthorizedAccessException' occurred in System.dll Και ένα μήνυμα σχετικά με την COM ότι δεν επιτρέπετε ή πρόσβαση,ενώ λειτουργεί κανονικά ξαφνικά τα εμφανίζει. ---------------------------------- Ευχαριστώ και πάλι ...
Apoll Δημοσ. 9 Δεκεμβρίου 2011 Δημοσ. 9 Δεκεμβρίου 2011 Η COM συνήθως 'απαγορεύει' την πρόσβαση αν είναι κλειστή και προσπαθείς να διαβάσεις, είτε είναι ανοιχτή και προσπαθείς να την ανοίξεις ξανά. (Ή όταν άλλη εφαρμογή την χρησιμοποιεί). Δεν έχεις βάλει σε try catch block τον κώδικα να δεις αναλύτικά τί σου αναφέρει; Βάλε διπλό try catch block με retry counter. Έτσι το σύστημα θα προσπαθεί μερικές φορές μέχρι να επαναφέρει το μύνημα. Αν θες στείλε κώδικα, σαββατοκύριακό είναι να του ρίξω μια ματία να σε βοηθήσω.
A.S.P Δημοσ. 11 Δεκεμβρίου 2011 Μέλος Δημοσ. 11 Δεκεμβρίου 2011 >Imports System.IO Imports System.IO.Ports Imports System.Threading Public Class Form1 Dim iMeter, iYvalue, iXvalue As Integer Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick Try SerialPort1.Open() SerialPort1.Write("1") iXvalue = SerialPort1.ReadLine() SerialPort1.Write("2") iYvalue = SerialPort1.ReadLine() SerialPort1.Write("0") SerialPort1.Close() Catch ex As System.UnauthorizedAccessException Timer1.Enabled = False MsgBox("Σφάλμα σύνδεσης! Κωδικός σφάλματος: CS002. Η θύρα 'COM' που έχετε επιλέξει χρησιμοποιείτε απο κάποιο αλλό πρόγραμμα. Κάντε επανεκκίνηση στο πρόγραμμα και επιλέξτε την θύρα COM που έχετε συνδέσει την συσκευή σας.", MsgBoxStyle.Critical, "Critical Error") Catch ex As System.IO.IOException Timer1.Enabled = False MsgBox("Σφάλμα σύνδεσης! Κωδικός σφάλματος: CS001. Παρακαλώ σιγουρευτείτε πως το USB καλώδιο που συνδέεται με την συσκευή σας είναι συνδεδεμένο.", MsgBoxStyle.Critical, "Critical Error") Catch ex As Exception Timer1.Enabled = False MsgBox(ex.Message) End Try ProgressBar1.Value = iXvalue * 0.0977517106549365 ProgressBar2.Value = iYvalue * 0.0977517106549365 End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRun.Click SerialPort1.Close() SerialPort1.PortName = cbCom.Text 'change com port to match your Arduino port SerialPort1.BaudRate = 9600 SerialPort1.DataBits = 8 SerialPort1.Parity = Parity.None SerialPort1.StopBits = StopBits.One SerialPort1.Handshake = Handshake.None SerialPort1.Encoding = System.Text.Encoding.Default 'very important! Timer1.Enabled = True End Sub End Class Ο κώδικας του προγράμματος, με λίγες τροποποιήσεις !
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα