Σελίδα 1 από 2 1 2 ΤελευταίαΤελευταία
Εμφάνιση αποτελεσμάτων : 1 έως 10 από 15

Θέμα: Arduino, βοήθεια σε κώδικα σειριακής επικοινωνίας...

  1. #1
    Μέλος Το avatar του χρήστη manolena
    Όνομα
    Μάνος
    Εγγραφή
    Dec 2006
    Περιοχή
    Ελευσίνα
    Μηνύματα
    2.709

    Προεπιλογή Arduino, βοήθεια σε κώδικα σειριακής επικοινωνίας...

    Καλημέρα σε όλους και καλή χρονιά!

    Το πρόβλημα έχει ως εξής: απο μια εξωτερική εξωτερική εφαρμογή που τρέχει στον υπολογιστή, στέλνω με το πάτημα ενός κουμπιού
    ένα string στη σειριακή που είναι συνδεδεμένο το project με έναν ATmega2560 που περιλαμβάνει μεταξύ των άλλων και ένα RTC της
    ST, το M41T80 (μέσες-άκρες παρόμοιο με αυτά της Dallas DS1307). Η επικοινωνία στο δίαυλο I²C είναι τεκμηριωμένη, όπως και στη
    σειριακή πόρτα (στέλνω διάφορα και τα διαβάζω πίσω απο το παράθυρο σειριακής του IDE).
    Το striing που στέλνω έχει συγκεκριμένο format: αρχίζει με το χαρακτήρα 't' και ακολουθούν 11 bytes με αριθμούς που υποδηλώνουν την
    ημερομηνία-ώρα του υπολογιστή, ο οποίος με αυτό τον τρόπο την στέλνει στην πλακέτα για να ενημερώσει το RTC της. Είναι λοιπόν
    κάπως έτσι: t311212135559 που σημαίνει: 31/12/12 13:55:59.
    Αυτό που κάνει η πλακέτα, είναι να υποδέχεται το παραπάνω string μόλις ανιχνευθεί ο χαρακτήρας t και να "φτιάξει" ένα ένα τα ακολουθώντα
    νούμερα σε bytes για να καταχωρηθούν στους registers του RTC. Ακολούθως, τα επιστρέφει στη σειριακή για aknowledge.
    Η ρουτίνα που κάνει αυτό είναι η εξής:
    Κώδικας:
    void processSyncMessage() 
    {
      if (Serial.available() > 0)
      {   
        Serial.readBytesUntil(TIME_HEADER, timeBuffer, TIME_MSG_LEN); //========>TIME_HEADER= 't', TIME_MSG_LEN = 12, το μήκος του buffer που υποδέχεται το string.
        daysOfMonth = (timeBuffer[2] << 8 | (timeBuffer[1]-48));  
        months = (timeBuffer[4] << 8 | (timeBuffer[3]-48));
        years = (timeBuffer[6] << 8 | (timeBuffer[5]-48));
        hours = (timeBuffer[8] << 8 | timeBuffer[7])-48;
        minutes = (timeBuffer[10] << 8 | timeBuffer[9])-48;
        seconds = (timeBuffer[12] << 8 | timeBuffer[11])-48;    
      }   
    }
    ενώ οι ρουτίνες εγγραφής και ανάγνωσης προς/ απο το RTC είναι αυτές:

    Κώδικας:
    // ===================================================================
    void setDateM41T80()          // 0-99
    {
       Wire.beginTransmission(M41T80_I2C_ADDRESS);
       Wire.write(0x00);
       Wire.write(decToBcd(msecond));
       Wire.write(decToBcd(seconds) & 0x7f);    // 0 to bit 7 starts the clock
       Wire.write(decToBcd(minutes));
       Wire.write(decToBcd(hours));      // If you want 12 hour am/pm you need to set
                                       // bit 6 (also need to change readDateDs1307)
       Wire.write(decToBcd(daysOfWeek));
       Wire.write(decToBcd(daysOfMonth));
       Wire.write(decToBcd(months));
       Wire.write(decToBcd(years));
       Wire.endTransmission();    
    }
    // ===================================================================
    void getDateM41T80()
    {
      Wire.beginTransmission(M41T80_I2C_ADDRESS);
      Wire.write(0x00);
      Wire.endTransmission(); 
      Wire.requestFrom(M41T80_I2C_ADDRESS, 8); 
      // A few of these need masks because certain bits are control bits
      msecond    = bcdToDec(Wire.read());
      seconds     = bcdToDec(Wire.read() & 0x7f);
      minutes     = bcdToDec(Wire.read());
      hours       = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
      daysOfWeek  = bcdToDec(Wire.read());
      daysOfMonth = bcdToDec(Wire.read());
      months      = bcdToDec(Wire.read());
      years       = bcdToDec(Wire.read());  
      Wire.endTransmission();    
    }
    // ===================================================================
    Το αποτέλεσμα όταν ξαναδιαβάζω το RTC (ανανεωμένο πλέον) με την εντολή:

    Serial.print(daysOfMonth); (και όλα τα υπόλοιπα month, year κτλ)

    είναι να παίρνω αυτό: 010202030509. Δηλαδή, φαίνεται οτι το πρώτο ψηφίο του κάθε πεδίου (ημερομηνία, μήνα, χρόνο κτλ)
    το μεταφράζει 0 στη μετατροπή του ASCII. Δεν ξέρω αν έχω κατατοπίσει πλήρως αλλά αν υπάρχει κάποιος να βοηθήσει, μπορώ να
    αναφερθώ σε περισσότερες λεπτομέρειες. Έχω πάντως την εντύπωση πως γίνεται κάτι λάθος στη μετατροπή του ASCII string σε
    byte και μετά στην αντίστροφη διαδικασία...

    Κάθε βοήθεια - πρόταση ευπρόσδεκτη, έχει κολλήσει όλο το σύστημα εδώ...

    0 Not allowed! Not allowed!

  2. #2
    Μέλος
    Όνομα
    Ανδρέας
    Εγγραφή
    Oct 2008
    Περιοχή
    Πάτρα
    Μηνύματα
    518

    Προεπιλογή

    Παιζει και να σου λεω βλακειες, αλλα υπαρχουν tables για μετατροπη απο ASCII σε bin. Επισης στο περιβαλλον προγραμματισου του arduino υπαρχει και η εντολη DEC που μετατρεπει οτι ειναι διπλα της σε δεκαδικο συστημα μοναδων και το καταχωρει καπου. Δηλαδη εκει που πας να γραψεις τις τιμες που πηρες απτο πισι στις αντιστοιχες μεταβλητες, αντι ξερω γω να γραψεις Serial.read(kati) γραφεις Serial.read(DEC(kati)) και το μετατρεπει σε δεκαδικο επιτοπου.

    παραδειγμα:
    http://arduino.cc/en/Serial/Print
    ισως βοηθησα

    0 Not allowed! Not allowed!

  3. #3
    Μέλος Το avatar του χρήστη manolena
    Όνομα
    Μάνος
    Εγγραφή
    Dec 2006
    Περιοχή
    Ελευσίνα
    Μηνύματα
    2.709

    Προεπιλογή

    Αντρέα,

    δοκίμασα το παράδειγμα. Το θέμα είναι το εξής: όταν αποθηκεύω byte προς byte το εισερχόμενο string σε έναν buffer (αποτελείται απο 12 char), αποθηκεύεται σαν ASCII κάθε element, δηλαδή:

    t311212135559-------------->

    buffer[0] = 0x74 (
    ASCII eq. του 't')
    buffer[1] = 0x51 (ASCII eq. του '3')
    buffer[2] = 0x49 (
    ASCII eq. του '1')
    buffer[3] =
    0x49 (ASCII eq. του '1')
    buffer[4] = 0x50 (ASCII eq. του '2')
    .................................................. .
    buffer[11] = 0x53 (ASCII eq. του '5')
    buffer[12] = 0x57 (ASCII eq. του '9')

    Αυτό λοιπόν που πρέπει τώρα να γίνει, είναι να κάνω κάθε char BCD ώστε να καταχωρηθεί στο RTC (έτσι προβλέπεται απο
    το Μ41Τ80) και μετά, να ξαναδιαβάσω έναν έναν τους registers του RTC και να τους μεταδώσω στη σειριακή σαν string αφού
    πρώτα τους ξανακάνω απο BCD, δεκαδικούς. Όταν λοιπόν επιστρέφουν, το string που διαβάζω έχει αυτή τη μορφή:

    t010202030509

    Σε αυτό το σημείο υποπτεύομαι το λάθος...

    0 Not allowed! Not allowed!

  4. #4
    Μέλος
    Όνομα
    Ανδρέας
    Εγγραφή
    Oct 2008
    Περιοχή
    Πάτρα
    Μηνύματα
    518

    Προεπιλογή

    Δοκιμασες να αποθκευσεις καθε ενα μπαιτ σε μια αλλη βοηθητικη μεταβλητη με την εντολη DEC μπροστα και μετα να το κανεις BCD και δεν σου δουλεψε?
    π.χ. καπως ετσι:

    for(i=0;i<=12;i++)
    {
    x[i] = (DEC buffer[i]);
    }

    Επισις ριξε μια ματια στα παραδειγματα κωδικα που εχει το Arduino IDE... Καπου εχει παραδειγματα για το πως να χειριζεσαι ASCII strings.

    0 Not allowed! Not allowed!

  5. #5
    Μέλος
    Όνομα
    Ανδρέας
    Εγγραφή
    Oct 2008
    Περιοχή
    Πάτρα
    Μηνύματα
    518

    Προεπιλογή

    Αυτο ενοω:


    /*
    Reading a serial ASCII-encoded string.

    This sketch demonstrates the Serial parseInt() function.
    It looks for an ASCII string of comma-separated values.
    It parses them into ints, and uses those to fade an RGB LED.

    Circuit: Common-anode RGB LED wired like so:
    * Red cathode: digital pin 3
    * Green cathode: digital pin 5
    * blue cathode: digital pin 6
    * anode: +5V

    created 13 Apr 2012
    by Tom Igoe

    This example code is in the public domain.
    */

    // pins for the LEDs:
    const int redPin = 3;
    const int greenPin = 5;
    const int bluePin = 6;

    void setup() {
    // initialize serial:
    Serial.begin(9600);
    // make the pins outputs:
    pinMode(redPin, OUTPUT);
    pinMode(greenPin, OUTPUT);
    pinMode(bluePin, OUTPUT);

    }

    void loop() {
    // if there's any serial available, read it:
    while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    int red = Serial.parseInt();
    // do it again:
    int green = Serial.parseInt();
    // do it again:
    int blue = Serial.parseInt();

    // look for the newline. That's the end of your
    // sentence:
    if (Serial.read() == '\n') {
    // constrain the values to 0 - 255 and invert
    // if you're using a common-cathode LED, just use "constrain(color, 0, 255);"
    red = 255 - constrain(red, 0, 255);
    green = 255 - constrain(green, 0, 255);
    blue = 255 - constrain(blue, 0, 255);

    // fade the red, green, and blue legs of the LED:
    analogWrite(redPin, red);
    analogWrite(greenPin, green);
    analogWrite(bluePin, blue);

    // print the three numbers in one string as hexadecimal:
    Serial.print(red, HEX);
    Serial.print(green, HEX);
    Serial.println(blue, HEX);
    }
    }
    }

    Κοιτα την εντολη Serial.parseInt() ισως ειναι αυτο που ψαχνεις

    0 Not allowed! Not allowed!

  6. #6
    Μέλος Το avatar του χρήστη manolena
    Όνομα
    Μάνος
    Εγγραφή
    Dec 2006
    Περιοχή
    Ελευσίνα
    Μηνύματα
    2.709

    Προεπιλογή

    Παράθεση Αρχικό μήνυμα από andrewsweet4 Εμφάνιση μηνυμάτων
    Δοκιμασες να αποθκευσεις καθε ενα μπαιτ σε μια αλλη βοηθητικη μεταβλητη με την εντολη DEC μπροστα και μετα να το κανεις BCD και δεν σου δουλεψε?
    π.χ. καπως ετσι:

    for(i=0;i<=12;i++)
    {
    x[i] = (DEC buffer[i]);
    }

    Επισις ριξε μια ματια στα παραδειγματα κωδικα που εχει το Arduino IDE... Καπου εχει παραδειγματα για το πως να χειριζεσαι ASCII strings.
    Ναι, το έκανα ήδη αυτό, είναι ακριβώς ίδιο με την εντολή:

    Serial.readBytesUntil(TIME_HEADER, timeBuffer, TIME_MSG_LEN);

    σε συνδυασμό και με βοηθητικό καταχωρητή βέβαια...

    0 Not allowed! Not allowed!

  7. #7
    Μέλος
    Όνομα
    Ανδρέας
    Εγγραφή
    Oct 2008
    Περιοχή
    Πάτρα
    Μηνύματα
    518

    Προεπιλογή

    Ελα το'χω! Υπαρχει ετοιμη βιβλιοθηκη για αυτο που θες. λεγεται atoi() (ascii to integer) και σαν ορισμα παιρνει την τιμη σε ascii και την επιστρεφει σε δεκαδικο.
    π.χ.

    int x = atoi(incoming_data)

    δεν χρειαζεται να τη συμπεριλαβεις νομιζω στην αρχη στο προγραμμα. Ειναι μερος της βιβλιοθηκης stdlib.h που ενοειται οτι συμπεριλαβανεται αυτοματα σε καθε sketch στο Arduino IDE

    πηγη: http://arduino.cc/forum/index.php/topic,117267.0.html

    0 Not allowed! Not allowed!

  8. #8
    Μέλος Το avatar του χρήστη manolena
    Όνομα
    Μάνος
    Εγγραφή
    Dec 2006
    Περιοχή
    Ελευσίνα
    Μηνύματα
    2.709

    Προεπιλογή

    Διαβάζω ακριβώς αυτό εδώ και λίγη ώρα!!!! Επανέρχομαι με εξελίξεις!

    0 Not allowed! Not allowed!

  9. #9
    Μέλος Το avatar του χρήστη spiroscfu
    Όνομα
    Σπύρος
    Εγγραφή
    Aug 2010
    Περιοχή
    Κέρκυρα
    Μηνύματα
    4.652

    Προεπιλογή

    Μάνο σίγουρα με το atoi θα είναι ευκολότερο, επίσης υπάρχουν και τα atol, atoi32.

    Δεν καταλαβαίνω κάτι όμως, το δευτερο και τρίτο byte το έχεις για τις ημέρες

    Κώδικας:
     daysOfMonth = (timeBuffer[2] << 8 | (timeBuffer[1]-48));
    κάνοντας του shift 8 bit αριστερά όμως, δεν το μηδενίζεις ή μεταφέρεις τα δεδομένα του στην τέταρτη θέση [3] ?


    edit:
    στα γράφω μήπως σου ξέφυγε.

    Το striing που στέλνω έχει συγκεκριμένο format: αρχίζει με το χαρακτήρα 't' και ακολουθούν 11 bytes με αριθμούς
    όχι 11 άλλα 12, ο πίνακας που φτιάχνεις έχει 13 θέσεις (η πρώτη είναι το [0] και η 13 το [12])

    0 Not allowed! Not allowed!
    Τελευταία επεξεργασία από το χρήστη spiroscfu : 05-01-13 στις 17:34

  10. Ένα μέλος ευχαρίστησε τον spiroscfu για αυτό το χρήσιμο μήνυμα:

    manolena (05-01-13)

  11. #10
    Μέλος Το avatar του χρήστη manolena
    Όνομα
    Μάνος
    Εγγραφή
    Dec 2006
    Περιοχή
    Ελευσίνα
    Μηνύματα
    2.709

    Προεπιλογή

    Άντε ρε Σπύρο κι έλεγα κι εγώ θα φανεί, δεν θα φανεί...

    Λοιπόν για το πρώτο:

    daysOfMonth = (timeBuffer[2] << 8 | (timeBuffer[1]-48 );

    Εδώ, το 48 που αφαιρώ έμεινε απο σπόντα σε προηγούμενες δοκιμές, προσπαθώντας να δω αν έχει να κάνει με ASCII format (αφαιρώντας 48 απο 48-127 έχεις τα ASCII ισοδύναμα), ενώ το shift 8 το μηδενίζει... η εντολή είναι προς το παρόν:

    daysOfMonth = ((timeBuffer[1] << 4) | (timeBuffer[1]));

    Για το δεύτερο, έχεις δίκιο, συνολικά τα bytes είναι 12, με 13 θέσεις εννοείται.
    Το timeBuffer[0] περιέχει τον χαρακτήρα 't' και δεν χρησιμοποιείται.
    Το
    timeBuffer[1] περιέχει τις δεκάδες ημέρες του μήνα.
    Το timeBuffer[2] περιέχει τις μονάδες ημέρες του μήνα.
    Το timeBuffer[3] περιέχει τις δεκάδες των μηνών.
    Το timeBuffer[4] περιέχει τις μονάδες των μηνών.
    Το timeBuffer[5] περιέχει τις δεκάδες των ετών.
    Το timeBuffer[6] περιέχει τις μονάδες των ετών.
    Το timeBuffer[7] περιέχει τις δεκάδες των ωρών.
    Το timeBuffer[8] περιέχει τις μονάδες των ωρών.
    Το timeBuffer[9] περιέχει τις δεκάδες των λεπτών.
    Το timeBuffer[10] περιέχει τις μονάδες των λεπτών.
    Το timeBuffer[11] περιέχει τις δεκάδες των δευτερολέπτων.
    Το timeBuffer[12] περιέχει τις μονάδες των δευτερολέπτων.

    Έκανα το παρακάτω: shift 4 θέσεις αριστερά το byte των δεκάδων και αντί για OR, προσέθεσα αριθμητικά το επόμενο byte των μονάδων, δηλ.:

    daysOfMonth = ((timeBuffer[1] << 4) + timeBuffer[2]);

    Τώρα λοιπόν το
    daysOfMonth περιέχει τις δεκάδες αριστερά και τις μονάδες δεξιά, όπως έρχονται απο τον σειριακό δίαυλο. Το θέμα είναι,
    επειδή έρχονται ASCII, πρέπει λογικά να τα κάνω DEC για να καταχωρηθούν μέσω της Wire.write(decToBcd(daysOfMonth)) στον RTC.
    H ρουτίνα decToBcd(byte) καθώς και η αντίστροφή της, δουλεύουν σωστά, είναι απο ανακύκλωση:

    Κώδικας:
    // ===================================================================
    byte decToBcd(byte val)
    {
      return ( (val/10*16) + (val%10) );
    }
    // ===================================================================
    byte bcdToDec(byte val)
    {
      return ( (val/16*10) + (val%16) ); 
    }
    // ===================================================================


    Βέβαια, για χρήση μόνο στο RTC.




    0 Not allowed! Not allowed!

Σελίδα 1 από 2 1 2 ΤελευταίαΤελευταία

Παρόμοια Θέματα

  1. Απαντήσεις: 46
    Τελευταίο Μήνυμα: 30-04-17, 01:38
  2. Απαντήσεις: 82
    Τελευταίο Μήνυμα: 10-04-17, 20:21
  3. Πρόβλημα με ανέβασμα κώδικα σε Arduino mega
    By NIKPAPAZOGLOU in forum Μικροελεγκτές
    Απαντήσεις: 24
    Τελευταίο Μήνυμα: 12-03-16, 19:56
  4. Βοήθεια σε κώδικα Arduino
    By ΚΩΣΤΑΣ2 in forum Μικροελεγκτές
    Απαντήσεις: 12
    Τελευταίο Μήνυμα: 27-02-16, 22:03
  5. Σκάλωμα με κώδικα σε arduino
    By enterpc in forum Μικροελεγκτές
    Απαντήσεις: 4
    Τελευταίο Μήνυμα: 17-09-11, 10:00

Tags for this Thread

Δικαιώματα - Επιλογές

  • Δημιουργία θεμάτων: Όχι
  • Υποβολή μηνυμάτων: Όχι
  • Σύναψη αρχείων: Όχι
  • Επεξεργασία μηνυμάτων: Όχι
  •  
  • BB code: σε λειτουργία
  • Smilies: σε λειτουργία
  • [IMG]: σε λειτουργία
  • [VIDEO] code is σε λειτουργία
  • HTML: εκτός λειτουργίας