שְׁאֵלָה:
שליחת כמויות גדולות של נתונים סדרתיים
Steven10172
2014-02-14 13:58:55 UTC
view on stackexchange narkive permalink

אז בתחומי הרובוטיקה לפעמים אתה זקוק למספר לוחות ו / או מחשבים המקושרים יחד כדי לשתף מידע או לשמור נתונים סטטיסטיים. נכון לעכשיו אני צריך לשלוח כמה משתנים שונים על חיבור סדרתי ותהיתי מה הדרך הטובה ביותר לעשות כאלה? לשלוח נתונים. האם מישהו מכיר דרך אחרת שעשויה להיות יעילה יותר?

אנא זכור שבעצם אצטרך לשלוח את הנתונים עבור 4 מנועים, מדחס, טמפרטורות שונות, דברים אקראיים ושלושת החלקים של הזרוע.

שֵׁשׁ תשובות:
#1
+9
Steven10172
2014-02-14 13:58:55 UTC
view on stackexchange narkive permalink

כשהמחשבות האישיות שלי על סטרוקטס הן הדרך היעילה ביותר לשלוח משתנים רבים ושונים, בניתי ספרייה כדי להקל על שליחת מבנים ומשתנים על סדרתי. קוד מקור

בספריה זו הוא מאפשר לשלוח באמצעות סדרתי בקלות. השתמשתי עם חומרה ותוכנה סדרתית. בדרך כלל משתמשים בזה בשילוב עם xbee כך שאוכל לשלוח את הנתונים באופן אלחוטי לרובוט וממנו.

בעת שליחת נתונים זה הופך אותו לפשוט כיוון שהוא מאפשר לשלוח משתנה או מבנה (זה לא לא אכפת).

הנה דוגמה לשליחת תו פשוט על הסידורי:

  // שלח את המשתנה charVariable מעל סדרתי .// כדי לשלוח את המשתנה עליך להעביר מופע של הסידרה לשימוש, // הפניה למשתנה שיש לשלוח ולגודל המשתנה שנשלח .// אם תרצה תוכל לציין 2 נוספים בסוף ארגומנטים המשנים את // קידומת ברירת המחדל ותו הסיומת המשמשים בעת ניסיון לשחזר את המשתנה // בקצה המקבל. אם מצוינים קידומת ותו סיומת הם יצטרכו // להתאים בקצה המקבל אחרת נתונים לא יישלחו כראוי acrosschar charVariable = 'c'; // הגדר את המשתנה שיש לשלוח דרך serialStreamSend :: sendObject (Serial, &charVariable, sizeof (charVariable)); // ציין קידומת ותו סיומת StreamSend :: sendObject (Serial, &charVariable, sizeof (charVariable), 'a', 'z');  

דוגמה לשליחת אינט פשוט דרך הסדרה:

  int intVariable = 13496; // הגדר את ה- int שיישלח דרך serialStreamSend :: sendObject (xbeeSerial, &intVariable, sizeof (intVariable)); // ציין קידומת ותו סיומת StreamSend :: sendObject (xbeeSerial, &intVariable, sizeof (intVariable), 'p');  

דוגמה למשלוח מבנה על סדרתי:

  // הגדר את המבנה שיש לשלוח המבנה הסדרתי SIMPLE_STRUCT {
char char משתנה; int int-variable [7]; boolean boolVariable;}; SIMPLE_STRUCT simpleStruct; simpleStruct.charVariable = 'z'; // הגדר את charVariable במבנה ל- z // מלא את מערך intVariable במבנה עם מספרים 0 עד 6for (int i = 0; i<7; i ++) {simpleStruct.intVariable [i] = i;} // שלח את struct לאובייקט xbeeSerial שהוא סדרת תוכנה שהוגדרה //. במקום להשתמש ב- xbeeSerial תוכלו להשתמש בסידורי אשר ירמז על // סדרת החומרה, ובמגה תוכלו לציין Serial, Serial1, Serial2, Serial3.StreamSend :: sendObject (xbeeSerial, &simpleStruct, sizeof (simpleStruct)); // Send זהה לעיל עם קידומת וסיומת שונה מערכי ברירת המחדל // שהוגדרו ב- StreamSend. כאשר מציינים מתי קידומת ותו סיומת לשלוח // עליכם לוודא שבקצה המקבל הם תואמים אחרת הנתונים // לא יוכלו להיקרא בקצה השני. StreamSend :: sendObject (xbeeSerial, &simpleStruct, sizeof (simpleStruct), '3', 'u');  

דוגמאות קבלה:

קבלת תו שהיה שלח באמצעות Streamsend:

  char charVariable; // הגדר את המשתנה לאן יונחו הנתונים // קרא את הנתונים מהאובייקט הסידורי ושמור אותם ל- charVariable פעם אחת // הנתונים התקבלו byte packetResults = StreamSend :: receiveObject (Serial, &charVariable, sizeof (charVariable)) ; // בנה מחדש את התו המגיע מהסידרה ל charVariable שיש לו סיומת מותאמת אישית // וקידומת של packet zbyteResults = StreamSend :: receiveObject (Serial, &charVariable, sizeof (charVariable), 'a', 'z') ;  

קבלת int שנשלח באמצעות StreamSend:

  int intVariable; // הגדר את המשתנה היכן יונחו הנתונים // בנה מחדש את int מ- xbeeSerial למשתנה intVariablebyte packetResults = StreamSend :: receiveObject (xbeeSerial, &intVariable, sizeof (intVariable));
// בנה מחדש את הנתונים ל- intVariable שנשלחו עם קידומת מותאמת אישית // של j וסיומת של pbyte packetResults = StreamSend :: receiveObject (xbeeSerial, &intVariable, sizeof (intVariable), 'j', 'p');  קוד> 

קבלת מבנה שנשלח באמצעות StreamSend:

  // הגדר את המבנה שהנתונים יועברו למבנה SIMPLE_STRUCT {char charVariable ; int int-variable [7]; boolean boolVariable;}; SIMPLE_STRUCT simpleStruct; // צור מבנה לאחסון הנתונים ב // שחזר את הנתונים מ- xbeeSerial לאובייקט simpleStructbyte packetResults = StreamSend :: receiveObject (xbeeSerial, &simpleStruct, sizeof (simpleStruct)); // שחזר את הנתונים מ- xbeeSerial לאובייקט פשוט יותר יש // קידומת של 3 וסיומת של packetResults = StreamSend :: receiveObject (xbeeSerial, &simpleStruct, sizeof (simpleStruct), '3', 'p');  

ברגע שאתה קרא את הנתונים באמצעות StreamSend :: receiveObject () אתה צריך לדעת אם הנתונים היו טובים, לא נמצאו או רעים.

טוב = מוצלח

לא נמצא = לא נמצא תו קידומת בזרם שצוין

רע = איכשהו נמצא תו קידומת, אך הנתונים אינם שלמים. בדרך כלל זה אומר שלא נמצאה תו סיומות או שהנתונים לא היו בגודל הנכון.

בדיקת תוקף הנתונים:

  // ברגע שאתה מתקשר ל- StreamSend :: receiveObject () הוא מחזיר בית של הסטטוס // איך הדברים התנהלו. אם אתה מפעיל את זה למרות שחלק מפונקציות הבדיקה זה // יידע אותך כיצד התנהלה העסקה (StreamSend :: isPacketGood (packetResults)) {// החבילה הייתה טובה} אחרת {// החבילה הייתה גרועה} אם StreamSend :: isPacketCorrupt (packetResults)) {// החבילה הייתה מושחתת} אחר {// החבילה לא נמצאה או שהיא הייתה טובה} אם (StreamSend :: isPacketNotFound (packetResults)) {// החבילה לא נמצאה לאחר מקסימום מספר נסיונות} עוד {
// החבילה נמצאה, אך יכולה להיות מושחתת}  

SteamSend Class:

  #include "Arduino.h" #ifndef STREAMSEND_H # הגדר STREAMSEND_H # הגדר PACKET_NOT_FOUND 0 # הגדר BAD_PACKET 1 # הגדר GOOD_PACKET 2 // הגדר את הגודל המקסימלי של המאגר הסידורי או את כמות הנתונים שברצונך לשלוח + 2 // עליך להוסיף 2 כדי לאפשר את הקידומת וסיומת מרחב תווים לשליחה. # הגדר MAX_SIZE 64 קלאס StreamSend {פרטי: static int getWrapperSize () {return sizeof (char) * 2; } בתים סטטיים קבלת אובייקט (זרם &ostream, void * ptr, unsigned int objSize, unsigned int loopSize); בתים סטטיים קבלת אובייקט (זרם &ostream, void * ptr, לא חתום obj objize, int חתום int loopSize, char קידומת Char, סיומת char char); char charly_prefixChar; // ערך ברירת המחדל הוא תו סטטי _suffixChar; // ערך ברירת המחדל הוא e static int _maxLoopsToWait; public: static void sendObject (Stream &ostream, void * ptr, unsigned int objSize); static void sendObject (זרם &ostream, void * ptr, un חתום int objSize, char קידומת Char, סיומת char Char); בתים סטטיים קבלת אובייקט (זרם &ostream, ריק * ptr, לא חתום obj objize); בתים סטטיים קבלת אובייקט (זרם &ostream, חלל * ptr, int objSize לא חתום, char קידומת Char, סיומת char Char); סטטי בוליאני isPacketNotFound (const byte packetStatus); סטטי בוליאני isPacketCorrupt (const byte packetStatus); סטטי בוליאני isPacketGood (const byte packetStatus); סטטי ריק ריק setPrefixChar (ערך char const) {_prefixChar = value; } ריק ריק סטטי SuffixChar (const char value) {_suffixChar = value; } סטטי ריק ריק setMaxLoopsToWait (ערך const int) {_maxLoopsToWait = value; } char const char getPrefixChar () {return _prefixChar; } char const char getSuffixChar () {return _suffixChar; } const int int getMaxLoopsToWait () {return _maxLoopsToWait; }}; // קבוע מראש כמה משתני ברירת מחדל // ניתן לשנות כשרואים לנכון
char StreamSend :: _ prefixChar = 's'; // התחלת תו לפני שליחת נתונים על פני Serialchar StreamSend :: _ suffixChar = 'e'; // תו מסתיים לאחר שנשלח כל הנתונים StreamSend :: _ maxLoopsToWait = -1; // מוגדר כ -1 עבור גודל האובייקט והעטיפה הנוכחיים / ** * sendObject * * ממיר את האובייקט לבתים ושולח אותו לזרם * * @param זרם כדי לשלוח נתונים אל * @param ptr למבנה למילוי * @ גודל param של struct * @param תו שיש לשלוח לפני זרם הנתונים (אופציונלי) * @ param תו לשליחה אחרי זרם הנתונים (אופציונלי) * / void StreamSend :: sendObject (Stream &ostream, void * ptr, לא חתום int objSize) { sendObject (ostream, ptr, objSize, _prefixChar, _suffixChar);} void StreamSend :: sendObject (Stream &ostream, void * ptr, unsigned int objSize, char prefixChar, char suffixChar) {if (MAX_SIZE > = objSize) // וודא שהאובייקט לא גדול מדי בתים * b = (בתים *) ptr; // צור מערך ptr של הבתים לשליחת ostream.write ((byte) prefixChar); // כתוב את תו הסיומת כדי לסמן את תחילתו של זרם // עקוב אחר כל הבייטים הנשלחים וכתוב אותם לזרם עבור (unsigned int i = 0; i<objSize; i ++) {ostream.write (b [i]) ; // כתוב כל בייט לזרם} ostream.write ((בתים) סיומת Char); // כתוב את תו הקידומת כדי לסמן את סוף הזרם}} / ** * קבל אובייקט * * מקבל את הנתונים מהזרם ושומר לאובייקט שסופק * * @param זרם לקרוא נתונים מ * @param ptr למבנה למילוי * @param גודל המבנה * @param תו שיש לשלוח לפני זרם הנתונים (אופציונלי) * @param תו לשליחה אחרי זרם הנתונים (אופציונלי) * / בתים StreamSend :: receiveObject (זרם &ostream, ריק * ptr, לא חתום obj objize ) {return receiveObject (ostream, ptr, objSize, _prefixChar, _suffixChar);}
בתים StreamSend :: receiveObject (זרם &ostream, חלל * ptr, לא חתום int objSize, char קידומת Char, סיומת char) {return קבלObject (ostream, ptr, objSize, 0, קידומת Char, סיומת Char);} בתים StreamSend :: קבל אובייקט (Stream & void * ptr, int objSize לא חתום, int loopSize לא חתום, prefixChar char, char סיומת char) {int maxLoops = (_maxLoopsToWait == -1)? (objSize + getWrapperSize ()): _maxLoopsToWait; if (loopSize > = maxLoops) {return PACKET_NOT_FOUND; } אם (ostream.available () > = (objSize + getWrapperSize ())) {// חבילה עומדת בדרישת גודל מינימאלית אם (ostream.read ()! = (byte) prefixChar) {// תו הקידומת לא נמצא // דרוך שוב בקוד וקרא את החזרת char הבאה, קבלObject (ostream, ptr, objSize, loopSize + 1, prefixChar, suffixChar); } נתוני char [objSize]; // צור מערך char tmp של הנתונים מ- Stream ostream.readBytes (data, objSize); // קרא את מספר הבתים memcpy (ptr, data, objSize); // העתק את הבתים למבנה אם (ostream.read ()! = (בתים) סיומת צ'אר) {// תו הסיומת לא נמצא החזר BAD_PACKET; } להחזיר GOOD_PACKET; } להחזיר PACKET_NOT_FOUND; // תו הקידומת לא נמצא ולכן לא זוהתה מנות} StreamSend בוליאני :: isPacketNotFound (const byte packetStatus) {return (packetStatus == PACKET_NOT_FOUND);} StreamSend בוליאני :: isPacketCorrupt (const byte packetStatus) {return (packetStatus == BAD_ );} StreamSend בוליאני :: isPacketGood (const byte packetStatus) {return (packetStatus == GOOD_PACKET);} # endif  
תשובות לכל קוד, כמו תשובות לכל הקישורים לא מיואשות. אלא אם כן בקוד שלך יש _טונות_ של תגובות, אני ממליץ לשים הסבר מה קורה
@TheDoctor, עדכנתי את הקוד. אמורות להיות עוד הערות עכשיו
#2
+1
TheDoctor
2014-02-14 20:20:15 UTC
view on stackexchange narkive permalink

אם אתה באמת רוצה לשלוח אותו מהר , אני ממליץ על Full Duplex Serial (FDX). זה אותו פרוטוקול שמשתמשים ב- USB ובאתר, וזה הרבה יותר מהיר מ- UART. החיסרון הוא שלרוב נדרשת חומרה חיצונית כדי להקל על קצב הנתונים הגבוה. שמעתי ש התוכנה החדשהSreial תומכת ב- FDX, אך ייתכן שהדבר יהיה איטי יותר מאשר UART החומרה. למידע נוסף על פרוטוקולי תקשורת, ראה כיצד לחבר שני ארדואינו ללא מגנים?

נשמע זה מעניין. אצטרך לבדוק את זה יותר.
איך "[סדרתי דופלקס מלא] (http://wcscnet.com/Tutorials/SerialComm/Page1.htm)" יכול להיות "הרבה יותר מהיר מ- UART" כאשר מדובר, למעשה, בתקשורת UART רגילה?
UART היא תקשורת בקצב קבוע. FDX שולח נתונים במהירות האפשרית ושולח שוב את הנתונים שלא הגיעו אליהם.
אשמח לברר פרטים נוספים על פרוטוקול זה. האם תוכל להוסיף קישור לתשובתך המתאר פרוטוקול מהיר יותר מ- UART? האם אתה מדבר על הרעיון הכללי של [בקשה חוזרת אוטומטית] (http: //en.wikipedia .org / wiki / automatic_repeat_request) באמצעות [ACK-NAK] (http://en.wikibooks.org/wiki/Serial_Programming/Error_Correction_Methods), או שיש לך פרוטוקול ספציפי שיש לך בראש? אף אחד מהגוגל שלי לא מחפש "FDX "או" סדרת דופלקס מלאה "תואמים את התיאור שלך.
#3
+1
80HD
2014-02-15 11:09:46 UTC
view on stackexchange narkive permalink

שליחת מבנה היא פשוטה למדי.

אתה יכול להכריז על המבנה כרגיל, ואז להשתמש ב- memcpy (@ myStruct, @ myArray) כדי להעתיק את הנתונים למיקום חדש ואז להשתמש במשהו הדומה לקוד שלמטה כדי לכתוב את הנתונים. כזרם נתונים.

  char לא חתום myArraySender [##]; // הפוך את ## לגדול מספיק כדי להתאים ל- structmemcpy (&myStruct, &myArraySender); // להעתיק נתונים גולמיים ממבנה למערך הזמני digitalWrite (frameStartPin, High); // לציין למקבל כי הנתונים הם comingserial.write (sizeof myStruct); // ספר למקלט כמה בתים ל- rxSerial.write (&myArraySender, גודל myStruct); // כתוב bytesdigitalWrite) frameStartPin, Low); // נעשה המציין שידור 

אז אתה יכול לצרף שגרת הפסקה לסיכה במכשיר השני שעושה את הפעולות הבאות:

  char len ללא תנודות, tempBuff [##]; // נדיף מכיוון שההפרעה לא תתרחש במרווחים צפויים.attachInterrupt (0, readSerial, Rising); 

// אמור ל- mcu להתקשר ל- fxn כשהוא pinhigh. זה יקרה כמעט בכל רגע. אם זה לא רצוי, הסר את ההפרעה ופשוט צפה בתווים חדשים בלולאת ההנהלה הראשית שלך (aka, UART polling). sizeof myArrayReceiver]; בעוד (i< (sizeof myArrayReceiver)) tempBuff [i] = Serial.read (); memcpy (&tempbuff, &myArrayReceiver); Serial.flush ();}

תחביר ושימוש במצביעים יצטרכו בדיקה מסוימת. משכתי כל הלילה אז אני בטוח שהקוד הנ"ל אפילו לא יתכנס, אבל הרעיון קיים. מלא את המבנה שלך, העתק אותו, השתמש באיתות מחוץ לטווח כדי למנוע שגיאות מסגור, כתוב את הנתונים. בצד השני, קבל את הנתונים, העתק אותם למבנה ואז הנתונים נגישים באמצעות שיטות גישה רגילות של חברים.

השימוש בשדות סיביות יעבוד גם כן, רק שים לב שהכישוכים נראים לאחור. לדוגמה, ניסיון לכתוב 0011 1101, עלול לגרום להופעה 1101 0011 בקצה השני אם המכונות שונות בסדר בתים.

אם שלמות הנתונים חשובה, תוכל גם להוסיף בדיקת בדיקה כדי לוודא שאתה לא מעתיק נתוני אשפה שלא מיושרים. זו בדיקה מהירה ויעילה שאני ממליץ עליה.

#4
+1
JRobert
2014-03-03 04:57:17 UTC
view on stackexchange narkive permalink

אם אתה יכול לסבול את נפח הנתונים, איתור באגים בתקשורת הוא כל כך הרבה יותר קל בעת שליחת מחרוזות מאשר בעת שליחה בינארית; sprintf () / sscanf () והגרסאות שלהם הם החברים שלך כאן. כלול את התקשורת בפונקציות ייעודיות במודול משלהם (קובץ .cpp); אם תצטרך לבצע אופטימיזציה של הערוץ מאוחר יותר - לאחר ש יש לך מערכת עובדת - תוכל להחליף את המודול מבוסס המחרוזת בזה שמקודד להודעות קטנות יותר.

תוכל להפוך את החיים הרבה יותר קלים אם אתה מקפיד על מפרט פרוטוקול בהעברה ומפרש אותם בצורה רופפת יותר בקליטה, בהתייחס לרוחבי שדות, לתחומים, לסיומי קו, לאפסים חסרי משמעות, לנוכחות שלטים + וכו '

במקור הקוד נכתב כדי להחזיר נתונים בלולאה מייצבת של Quadcopter כך שהיה צריך להיות מהיר למדי.
#5
  0
Newbie97
2014-02-15 10:23:43 UTC
view on stackexchange narkive permalink

אין לי אישורים רשמיים כאן, אך מניסיוני הדברים עברו די ביעילות כשאני בוחרת עמדת תווים מסוימת שתכיל את מצב המשתנה, כך שתוכל לתאר את שלוש התווים הראשונים כטמפרטורה, ושלושת הבאים כזווית של סרוו, וכן הלאה. בסוף השליחה הייתי שומר את המשתנים בנפרד ואז משלב אותם במחרוזת כדי לשלוח סדרתי. בקצה הקבלה הייתי בוחר את המחרוזת, מקבל את שלוש התווים הראשונים והופך אותם לכל סוג משתנה שאני צריך ואז עושה זאת שוב כדי לקבל את ערך המשתנה הבא. מערכת זו עובדת בצורה הטובה ביותר כאשר אתה יודע בוודאות את כמות תווים שכל משתנה ייקח, ואתה תמיד מחפש את אותם המשתנים (אשר אני מקווה שהוא נתון) בכל פעם שהנתונים הטוריים עוברים דרך.

אתה יכול לבחור משתנה אחד שיאחרון באורך לא מוגדר ו ואז קבל את המשתנה הזה מהתו הראשון שלו עד סוף המחרוזת. נכון, מחרוזת הנתונים הסדרתית עשויה להתארך ממש תלוי בסוגי המשתנה ובכמות העצומה שלהם, אך זו המערכת בה אני משתמש ועד כה החיסרון היחיד שפגעתי בו הוא אורך הסדרתי, כך שזה החיסרון היחיד שאני יודע על.

באיזה סוג של פונקציות אתה משתמש כדי לשמור x כמות תווים ב- int / float / char?
אולי אתה לא מבין את זה, אבל מה שאתה מתאר הוא * בדיוק * איך 'מבנה' מאורגן בזיכרון (מבלי להתייחס לריפוד) ואני מתאר לעצמי שפונקציות העברת הנתונים שבהן אתה משתמש יהיו דומות לאלו שנדונו בתשובה של סטיבן] ( http://arduino.stackexchange.com/questions/203/sending-large-amounts-of-serial-data#204).
@AsheeshR למעשה היו לי תחושות שכאלה יכולות להיות, אך באופן אישי אני נוטה לפגוע בקיר כשמנסים לעצב מחדש את המבנים ואז לקרוא אותם שוב בצד השני. לכן חשבתי שאני פשוט אעשה את הדבר המחרוזת הזה, כדי שאוכל לבצע ניפוי באגים בקלות אם הדברים נקראים לא נכון, וכדי שאוכל אפילו לקרוא את הנתונים הסדרתיים בעצמי אם אני מייעד אותם כמו "MOTORa023 MOTORb563" וכן הלאה, בלי החללים.
@Steven10172 טוב אני מודה שאני לא עוקב אחר הפונקציות הספציפיות, אלא מחפש את הפונקציה המסוימת בכל פעם. [מחרוזת ל- int,] (http://www.cplusplus.com/forum/general/13135/) [מחרוזת לצוף,] (http://stackoverflow.com/questions/1012571/stdstring-to-float-or -כפול) ו [מחרוזת לשרף] (http://stackoverflow.com/questions/13294067/how-to-convert-string-to-char-array-in-c). זכור כי אני משתמש בשיטות אלה ב- C ++ רגיל ולא ניסיתי אותן בעצמי ב- Arduino IDE.
#6
  0
Guru Subramani
2017-05-24 21:03:58 UTC
view on stackexchange narkive permalink

שלח נתוני מבנה על פני סדרתי

שום דבר לא מפואר. שולח מבנה. הוא משתמש בתו בריחה '^' כדי לתחום את הנתונים.

קוד ארדואינו

  typedef struct {float ax1; לצוף ay1; לצוף az1; לצוף gx1; לצוף gy1; לצוף gz1; צף ax2; לצוף ay2; לצוף az2; לצוף gx2; לצוף gy2; float gz2;} __attribute __ ((__ ארוז __)) data_packet_t; data_packet_t dp; תבנית <typename T> בטל sendData (T נתונים) {לא חתום uBufSize ארוך = sizeof (נתונים); char pBuffer [uBufSize]; memcpy (pBuffer, &dp, uBufSize); Serial.write ('^'); עבור (int i = 0; i<uBufSize; i ++) {if (pBuffer [i] == '^') {Serial.write ('^'); } Serial.write (pBuffer [i]); }} הגדרת חלל () {Serial.begin (57600);} loop loop () {dp.ax1 = 0.03; // שימו לב שלא מילאתי ​​את האחרים. יותר מדי עבודה. ; psendData<data_packet_t> (dp);}  

קוד פייתון:

  ייבא סדרתי מהעתק יבוא copyfrom struct יבוא * ser = serial.Serial (# port = '/ dev / cu.usbmodem1412 ', port =' / dev / ttyUSB0 ', # port =' / dev / cu.usbserial-AL034MCJ ', baudrate = 57600) def get_next_data_block (next_f): אם אין hasattr (get_next_data_block, "data_block") : get_next_data_block.data_block = [] בעוד (1): נסה: current_item = next_f () if current_item == '^': next_item = next_f () if next_item == '^': get_next_data_block.data_block.append (next_item) אחר: out = copy (get_next_data_block.data_block) get_next_data_block.data_block = [] get_next_data_block.data_block.append (next_item) חזור החוצה אחר: get_next_data_block.data_block.append (הנוכחי_פריט) למעט: b reakfor i בטווח (1000): # רק כדי שהתוכנית תסתיים - יכול להיות תוך זמן לולאה data_ = get_next_data_block (ser.read) נסה: הדפס פרוק ('= ffffffffffff', '' .join (data_))
למעט: המשך  


שאלה ותשובה זו תורגמה אוטומטית מהשפה האנגלית.התוכן המקורי זמין ב- stackexchange, ואנו מודים לו על רישיון cc by-sa 3.0 עליו הוא מופץ.
Loading...