تكشف مجموعة تطوير PMSOptical عن 44 دالة C مُصدَّرة من ملف DLL واحد على Windows، وتغطي الاتصال التسلسلي والإيثرنت، والتحكّم بالموضع المطلق، وقراءة الحالة، ومزايا بطاقة التحكم المشفّرة، وعائلة واجهة كاملة متوازية لعدسات المحرك المزدوج. سير العمل الأساسي هو أربع استدعاءات: فتح → منزل → حركة → انتظار. ويُحصل على مقبض بـ PMSOptical_OpenComm("COM1", 9600) للتسلسلي، أو PMSOptical_OpenSocket("192.168.1.200", 4196) لـ TCP.
يُوثّق هذا الدليل عائلات الدوال، وتسلسل الاستدعاء الموصى به، والقيود الأربعة للدمج التي تسبب معظم مشاكل الدمج الأول، بما فيها ما يهمّ لسلامة الآلة: لا تحتوي مجموعة التطوير على توقف اضطراري برمجي قابل للاستخدام.
| البند | القيمة |
|---|---|
| الدوال المُصدَّرة | 44 (24 أحادية المحرك، 20 ثنائية المحرك) |
| المنصة | Windows x64 / x86 (DLL) |
| الاتصال | تسلسلي بـ 9600 بود، أو TCP على المنفذ 4196 |
| نوع المقبض | PMSHANDLE (void*) — تحقّق دائماً من كونه فارغاً |
| التسلسل الأساسي | فتح → GoHome → MoveTo(pulse) → WaitForOpticalFinished → GetPos → Close |
| مهلة الانتظار الافتراضية في الواجهة | 100000 مللي ثانية (100 ثانية) |
| الدوال غير المُنفَّذة | 8، بما فيها Stop وStop2 |
| ارتباطات اللغات | C++ أصلي؛ وC# عبر P/Invoke؛ ولغات أخرى عبر ctypes/cffi (بلا ارتباط رسمي) |
PMSOptical-SDK/
├── Doc/
│ ├── POMEAS electric lens development documents V4.4.7.pdf (English)
│ ├── encrypted / non-encrypted development documents V4.4.7 (control-card comparison)
│ └── dual-motor control card operation manual V1.5
├── SDK/
│ ├── include/PMSOpticalDll.h 44 exported functions
│ ├── x64/{Release,Debug}/PMSOpticalDll.dll + .lib
│ │ └── OP/*.txt per-model pulse tables
│ └── x86/{Release,Debug}/ same, 32-bit
└── demo/
└── x64/PMSOpticalDemo.exe + .ini MFC demo application
يجب أن يوجد ملف DLL بجانب الملف التنفيذي أو على متغير النظام PATH.
| الطريقة | الدالة | المعاملات |
|---|---|---|
| تسلسلي | PMSOptical_OpenComm(char* comname, int nBaud) | comname مثل "COM1"؛ nBaud = 9600 |
| إيثرنت | PMSOptical_OpenSocket(char* ip, int nPort) | ip مثل "192.168.1.200"؛ nPort = 4196 |
| استعلام الحالة | PMSOptical_IsOpened(PMSHANDLE, bool&) | — |
| إغلاق | PMSOptical_Close(PMSHANDLE&) | يُمرَّر المقبض بالمرجع |
للاتصال الشبكي، يجب أن يكون حاسوب المضيف وبطاقة تحكم العدسة على نفس الشبكة الفرعية — يجب أن تتطابق الأجزاء الثلاثة الأولى من العنوان، مثل 192.168.1.xxx. ويُحصَل على قناع الشبكة الفرعية تلقائياً.
#include "PMSOpticalDll.h"
PMSHANDLE h = PMSOptical_OpenComm("COM2", 9600); // serial
// PMSHANDLE h = PMSOptical_OpenSocket("192.168.1.200", 4196); // Ethernet
if (!h) { /* connection failed */ }
| # | الدالة | الغرض |
|---|---|---|
| 1 | PMSOptical_OpenSocket(char* ip, int nPort) | فتح عبر إيثرنت، وإرجاع مقبض الجهاز |
| 2 | PMSOptical_OpenComm(char* comname, int nBaud) | فتح عبر التسلسلي، وإرجاع مقبض الجهاز |
| 3 | PMSOptical_IsOpened(PMSHANDLE, bool& bIsOpened) | الإبلاغ عما إذا كان المقبض مفتوحاً |
| 4 | PMSOptical_Close(PMSHANDLE&) | إغلاق المقبض |
تمرّر الدالتان 3 و4 نتيجتهما ومقبضها بالمرجع. هذا متعمَّد: يلاحظ الترويسة أن التوقيعات صِيغت هكذا لتوافق P/Invoke في C#.
| # | الدالة | الغرض | مُنفَّذة |
|---|---|---|---|
| 5 | GoHome(PMSHANDLE) | العودة إلى الأصل | نعم |
| 6 | IsHomed(PMSHANDLE, bool&) | الإبلاغ عما إذا اكتملت العودة إلى المنزل | لا — موسومة غير مُنفَّذة |
| 7 | MoveTo(PMSHANDLE, int nPulse) | الحركة إلى موضع نبضي مطلق | نعم |
| 8 | Stop(PMSHANDLE) | التوقف فوراً | لا — موسومة غير مُنفَّذة |
| 9 | JogStart(PMSHANDLE, int nJogSpeed) | تحريك تدريجي (سرعة موجبة أو سالبة) | لا — موسومة غير مُنفَّذة |
| 10 | JogStop(PMSHANDLE) | إيقاف الحركة التدريجية | لا — موسومة غير مُنفَّذة |
| 11 | GetPos(PMSHANDLE, int& nCurPulse) | قراءة الموضع الحالي | نعم |
| 12 | GetMaxPos(PMSHANDLE, int& nMaxPulse) | قراءة أقصى نبضة (إجمالي السفر) | نعم |
| 13 | GetStatus(PMSHANDLE, int& nStatus) | قراءة حالة الحركة: 0 يتحرك، 1 توقّف، 2 فشل التهيئة | نعم |
| 14 | WaitForOpticalFinished(PMSHANDLE, int nTimeOut = 100000) | حظر until انتهاء حركة التكبير | نعم |
| 15 | GetVer(PMSHANDLE, char* Ver) | قراءة إصدار البرنامج الثابت | نعم |
تلفّ WaitForOpticalFinished منطق استطلاع الحالة داخلياً — تستطلع استعلام الحالة وتراقب مؤشر التوقف — بمهلة افتراضية قدرها 100000 مللي ثانية. وفي معظم التطبيقات ينبغي استدعاؤها بدل كتابة حلقة استطلاع خاصة بك.
متاحة فقط عند تزويد العدسة ببطاقة التحكم المشفّرة (يُدل عليها encrypt في اسم ملف جدول النبضات).
| # | الدالة | الغرض |
|---|---|---|
| 16 | EncryptCommStatus(PMSHANDLE, bool& IsConnected) | ما إذا كانت البطاقة المشفّرة متصلة |
| 17 | EncryptReadTimes(PMSHANDLE, int& nTimes) | قراءة عدّاد دورات التكبير |
| 18 | EncryptWriteTimes(PMSHANDLE, int nTimes) | كتابة عدّاد دورات التكبير |
| 19 | EncryptAddTimes(PMSHANDLE) | زيادة عدّاد دورات التكبير |
| 20 | EncryptReadFlashMaxPos(PMSHANDLE, int&) | قراءة أقصى نبضة المخزّنة في Flash |
| 21 | EncryptWriteFlashMaxPos(PMSHANDLE, int) | كتابة أقصى نبضة إلى Flash |
| 22 | EncryptCheckHomeStatus(PMSHANDLE, bool& bHasStatus, bool& bNowStatus) | حالة العودة إلى المنزل ومفتاح الحد |
| 23 | EncryptReadFlashLensInfo(PMSHANDLE, unsigned char buf[64]) | قراءة معلومات العدسة (كتلة 64 بايت ثابتة) |
| 24 | EncryptWriteFlashLensInfo(PMSHANDLE, unsigned char buf[64]) | كتابة معلومات العدسة (ASCII قابل للطباعة فقط) |
ما الذي تصلح له البطاقة المشفّرة فعلاً: تخزّن عدّاد دورات التكبير وكتلة هوية العدسة بطول 64 بايت في Flash المتحكّم. وهذا يدعم تتبّع أصول المعدّات وإحصاءات الاستخدام والتعريف بالعدسة الأصلية — وهو مفيد مباشرةً للمندمجين والأساطيل المؤجَّرة وعمليات ما بعد البيع.
كل دالة أعلاه لها نسخة متوازية بلاحقة 2 ومعامل إضافي unsigned char u8lensnum = 0 يختار المحرك 1 أو المحرك 2.
| أحادي المحرك | ثنائي المحرك | الغرض |
|---|---|---|
GoHome | GoHome2(h, u8lensnum) | إعادة المحرك المختار إلى منزله |
IsHomed | IsHomed2(h, bool&, u8lensnum) | غير مُنفَّذة |
MoveTo | MoveTo2(h, nPulse, u8lensnum) | تحريك المحرك المختار إلى موضع مطلق |
Stop | Stop2(h, u8lensnum) | غير مُنفَّذة |
JogStart / JogStop | JogStart2 / JogStop2 | غير مُنفَّذة |
GetPos | GetPos2(h, int&, u8lensnum) | قراءة الموضع |
GetMaxPos | GetMaxPos2(h, int&, u8lensnum) | قراءة إجمالي السفر |
GetStatus | GetStatus2(h, int&, u8lensnum) | قراءة الحالة |
WaitForOpticalFinished | WaitForOpticalFinished2(h, nTimeOut, u8lensnum) | انتظار الاكتمال |
GetVer | GetVer2(h, char*, u8lensnum) | قراءة إصدار البرنامج الثابت |
Encrypt* (9 دوال) | Encrypt*2(h, …, u8lensnum) | مجموعة البطاقة المشفّرة كاملة |
تزاوج عدسات المحرك المزدوج محرك تكبير بمحرك ضبط بؤري مستقل — مثل عدسة تكبير 12.5X بضبط بؤري مدعوم 12 مم، أو 12.5X بمحرك مزدوج بمحور ضبط 3 مم.
// Dual motor: motor 0 = zoom, motor 1 = focus trim
PMSOptical_GoHome2(h, 0);
PMSOptical_MoveTo2(h, 4600, 0); // zoom to 1X (see the model pulse table)
PMSOptical_WaitForOpticalFinished2(h, 100000, 0);
Open (serial or Ethernet)
|
GoHome() -> WaitForOpticalFinished(timeout)
|
GetMaxPos() -> validate total travel, and confirm the link is alive
|
+-- MoveTo(pulse)
| -> WaitForOpticalFinished(timeout) (or poll GetStatus until it returns 1)
| -> GetPos() -> compare with target (closed loop)
+-- repeat for the next magnification
|
Close()
يحدّد مخطط التدفق المرجعي للصانع ثلاث قواعد لمسار الاستطلاع:
أثناء قيادة بطاقة التحكم للمحرك، تُعلّق الاتصالات. قد لا يُرجع استعلام الحالة أي شيء على الإطلاق. تعامل مع هذا بأسلوب المهلة وإعادة المحاولة، أو باستدعاء WaitForOpticalFinished. لا تعتبره عطلاً ولا تُعِد تشغيل الاتصال.
إذا تساوت النبضة المطلوبة مع النبضة الحالية، فلا تتحرك العدسة ولا تبلّغ عن نجاح. لا تستخدم أبداً «إرسال الأمر» كاختبار لحياة الرابط. استخدم GetMaxPos أو GetPos بدلاً من ذلك.
عند التشغيل تعود العدسة إلى منزلها، ولا تقبل أي أمر خلال تلك النافذة. يجب أن ينتظر التطبيق المضيف 35 ثانية على الأقل قبل فتح الاتصال وإصدار الأوامر. وعدم مراعاة ذلك سبب شائع لتقارير «الجهاز لا يستجيب» التي ليست أعطالاً في الواقع.
كل من Stop وStop2 موسومتان غير مُنفَّذة في الترويسة، إلى جانب IsHomed وJogStart وJogStop ونظيراتها ثنائية المحرك — ثمان دوال في المجموع. لا تبنِ وظيفة سلامة عليها. حدّد الاكتمال بـ GetStatus أو WaitForOpticalFinished، ونفّذ التوقف الاضطراري بدائرة عتاد — قطع الطاقة أو إشارة تداخل خارجية.
| المتطلّب | التوصية |
|---|---|
| تحكّم بالتكبير فقط | بطاقة قياسية |
| عدّ الدورات، وفحص الأصالة، وفوترة التأجير | بطاقة مشفّرة (EncryptReadTimes، EncryptReadFlashLensInfo) |
| أسطول مختلط | لاحظ أن البطاقتين تستخدمان جداول نبضات مختلفة — تغيير البطاقة يعني تغيير الجدول |
يُوزَّع برنامج SDK الرسمي على ملفات DLL لـ Windows فقط (x64 وx86). على المنصات الأخرى، نفّذ البروتوكول التسلسلي مباشرة — هو خمسة أوامر ASCII عادية بلا اعتماد على منصة، فيعمل على أي مضيف بمنفذ تسلسلي أو مقبس TCP.
نعم، عبر ctypes أو cffi، لأن الدوال المُصدَّرة تستخدم ربط C. لا يوجد ارتباط رسمي لـ Python، فتكتب الغلاف بنفسك. لاحظ أن PMSHANDLE مؤشّر void* ويجب تمرير معاملات bool& بـ ctypes.byref.
تقنياً نعم، لكن لا تفعل. كلاهما يتناول نفس سجلّات الأجهزة، والخلط بينهما — خصوصاً حول مرجع العودة إلى المنزل — يُنتج حالة غير متسقة. اختر منهجاً واحداً لكل مشروع.
الافتراضي 100000 مللي ثانية. اضبطه على ضعف مدة أطول سفر تكبير على أجهزتك على الأقل. والرقم المرجعي في الدليل هو 10 ثوانٍ أو أكثر.
لا، ولا ينبغي وصفها كذلك. توفّر مجموعة التطوير واجهة تحكّم بصري قابلة للبرمجة — الموضع والحالة والقراءة المرتدة. يمكن دمجها في بنية رؤية بالذكاء الاصطناعي، حيث تصدر البرمجيات الإشرافية أمر تكبير جديداً بناءً على نتيجة فحص، لكن مجموعة التطوير نفسها لا تحتوي قدرات ذكاء اصطناعي أو تحليل صور. والصياغة الدقيقة هي أن عدسات التكبير المحرّكة يمكن دمجها في سير عمل رؤية آلية يتحكّم به الذكاء الاصطناعي.
اثنتان تستحقان المعرفة. يُعرّف GetVer2 معامله بـ u8lennum — خطأ إملائي لا يؤثر على الاستدعاء، لكن يستحسن توحيده في غلافك. والدوال الثماني غير المُنفَّذة المذكورة أعلاه يجب ألا يُعتمد عليها.
MoveTo
أدخل بريدك الإلكتروني فقط لتتصلك آخر الأخبار والمستجدّات من بيومياس. ابقَ على تواصل مع بيومياس وكن أوّل من يعلم بأحدث الابتكارات في عالم البصريات.