انجمن‌های فارسی اوبونتو

کمک و پشتیبانی => سخت‌افزار => نویسنده: مصطفی بزاز در 21 مهر 1388، 06:20 ب‌ظ

عنوان: درایور مجازی پورت سریال
ارسال شده توسط: مصطفی بزاز در 21 مهر 1388، 06:20 ب‌ظ
من رو یه برنامه کار می‌کنم که روی پورت سریال ارسال و دریافت می‌کنه. برای اینکه کارم راحتتر باشه به جای پورت سریال واقعی و وصل کردن یه کابل loopback می‌خوام دو تا پورت سریال مجازی که به صورت نرم‌افزاری به هم متصل شدند استفاده کنم. روی ویندوز این کارو با استفاده از tcpcom انجام دادم. روی لینوکس چطور می‌شه این کارو انجام داد؟
عنوان: پاسخ به: درایور مجازی پورت سریال
ارسال شده توسط: سعید رسولی در 21 مهر 1388، 08:30 ب‌ظ
من رو یه برنامه کار می‌کنم که روی پورت سریال ارسال و دریافت می‌کنه. برای اینکه کارم راحتتر باشه به جای پورت سریال واقعی و وصل کردن یه کابل loopback می‌خوام دو تا پورت سریال مجازی که به صورت نرم‌افزاری به هم متصل شدند استفاده کنم. روی ویندوز این کارو با استفاده از tcpcom انجام دادم. روی لینوکس چطور می‌شه این کارو انجام داد؟
سریال منظورتون com هست یا usb ؟
با چه زبانی کار می‌کنید؟

توی گنو/لینوکس  فایل dev/ttyS0/ نمایندهٔ پورت com0 و فایل dev/ttyS1/ نمایندهٔ پورت com1 هست.
پس شما احتمالاً باید یه فایل از نوع character device بسازید و بجای اون فایل(ttyS0 یا ttyS1) استفاده کنید.
عنوان: پاسخ به: درایور مجازی پورت سریال
ارسال شده توسط: سعید رسولی در 21 مهر 1388، 09:13 ب‌ظ
فهمیدم. شما توی هر زبان برنامه‌نویسی کافیه فایل dev/ttyS0/ رو برای write یا append (مود w یا a) باز کنید. بعد هر چی خواستید روش رایت کنید و برای اینکه فرستاده بشه هر بار flush کنید.
مثلاً با این کد پایتون
f = file('/dev/ttyS0', 'w')
f.write('Hello')
f.flush()
f.write('World')
f.flush()
f.close()
حالا مثل این می‌مونه که یه سخت‌افزار خارجی به پورت com1 وصل شده و دو تا کلمهٔ Hello و World رو فرستاده!
توی C هم دقیقاً عین همین. با توابع fopen و fread و fflush و fclose (مثل کار با فایل‌‌های معمولی)

برای دریافت دیتا از پورت سریال(واقعی یا مجازی) هم توی پایتون از کتابخانهٔ serial میشه استفاده کرد. مثلاً این کد هر چی که به پورت com1 فرستاده بشه رو کاراکتر به کاراکتر چاپ میکنه(البته عدد معادلش رو).

from serial.serialposix import Serial
import sys

s = Serial(port='/dev/ttyS0', timeout=0.1)
s.open()

while True:
    c = s.read(1)
    if c!='':
      print ord(c), ## No Newline
      sys.stdout.flush() ## Because no newline printed at the end of output

تحت ++C هم این کد رو قبلاً نوشته بودم برای کار با پورت سریال:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>



int getRTS(int fd){
  int stat;
  ioctl(fd, TIOCMGET, &stat);// Read the RTS pin status
  return (stat & TIOCM_RTS)!=0;
}

void setRTS(int fd, bool enable){
  int cmd = TIOCM_RTS;
  if(enable)
    ioctl(fd, TIOCMBIS, &cmd); // Set the RTS pin.
  else
    ioctl(fd, TIOCMBIC, &cmd); // Unset the RTS pin.
}

int getDTR(int fd){
  int stat;
  ioctl(fd, TIOCMGET, &stat);// Read the DTR pin status
  return (stat & TIOCM_DTR)!=0;
}

void setDTR(int fd, bool enable){
  int cmd = TIOCM_DTR;
  if(enable)
    ioctl(fd, TIOCMBIS, &cmd); // Set the RTS pin.
  else
    ioctl(fd, TIOCMBIC, &cmd); // Unset the RTS pin.
}

int main()
{
  int fd;
  char buff[100];
  int i, wr, rd, n;
  fd=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
  if (fd == -1 ){
    perror("open_port: Unable to open /dev/ttyS0 – ");
    return 1;
  }
  fcntl(fd, F_SETFL,0);
  printf("Port 1 has been sucessfully opened and %d is the file description\n",fd);
  /*/////////////
  printf("\nRTS==%d\n", getRTS(fd));
  printf("Unsetting the RTS pin...\n");
  setRTS(fd, false);
  printf("RTS==%d\n", getRTS(fd));
  printf("Setting the RTS pin...\n");
  setRTS(fd, true);
  printf("RTS==%d\n", getRTS(fd));
  ///////
  printf("\nDTR==%d\n", getDTR(fd));
  printf("Unsetting the DTR pin...\n");
  setDTR(fd, false);
  printf("DTR==%d\n", getDTR(fd));
  printf("Setting the DTR pin...\n");
  setDTR(fd, true);
  printf("DTR==%d\n", getDTR(fd));
  printf("\n");
  *//////////////
  wr=write(fd, "ATZ\r", 5);
  read(fd, buff, 10);
  printf("Received %s\n", buff);
  ////////
  wr=write(fd, "ATM0L2\r", 4);
  read(fd, buff, 10);
  printf("Received %s\n", buff);
  ////////
  wr=write(fd, "ATDT9716129\r", 4);
  read(fd, buff, 10);
  printf("Received %s\n", buff);
  ////////
  //for(i=0; i<10000; i++)
  //  wr=write(fd, "A\n", 4);
  close(fd);
  return 0;
}

(تحت C هم فقط بجای bool بذارید int و بجای false بذارید 0 و بجای true بذارید 1)

پس شما نیاز به هیچ درایور یا ابزار خارجی ندارید. با امکانات پایه‌ای خود گنو/لینوکس به راحتی انجام میشه. :)
عنوان: پاسخ به: درایور مجازی پورت سریال
ارسال شده توسط: مصطفی بزاز در 21 مهر 1388، 09:46 ب‌ظ
من با جاوا کار می‌کنم. کتابخانه‌ی rxtx امکان لیست کردن پورت‌های سریال رو داره. و فقط به همین پورت‌ها میتونه وصل بشه.
الان چون کامپیوتر من فقط یک پورت سریال داره، فقط یک پورت رو لیست می‌کنه.  روی ویندوز بعد از نصب tcpcom دو پورت به کامپیوتر اضافه میشه. با تنظیماتی وجود داره هر دو تا رو به هم وصل می‌کنم و خیلی راحت هر دو تا توی برنامه لیست می‌شن.
حالا تو لینوکس هم یه همچین چیزی می‌خوام که دو تا پورت به من اضافه کنه که هر چی روی یکی از اونها نوشتم از دیگری دریافت کنم.
فعلا این رو پیدا کردم:http://tibbo.com/downloads/soi/vspdl.html (http://tibbo.com/downloads/soi/vspdl.html)
ولی موقع کامپایل کردن error میده. بازم سعی می‌کنم بتونم راش بندازم.
عنوان: پاسخ به: درایور مجازی پورت سریال
ارسال شده توسط: سعید رسولی در 22 مهر 1388، 03:53 ق‌ظ
فعلا این رو پیدا کردم:http://tibbo.com/downloads/soi/vspdl.html (http://tibbo.com/downloads/soi/vspdl.html)
ولی موقع کامپایل کردن error میده. بازم سعی می‌کنم بتونم راش بندازم.
خب چه اروری میده؟ (ارور میده که نشد سوال!)
احتمالاً پکیج devel یه سری کتابخونه‌هایی رو نیاز داره که نصب نیست و باید نصب کنید.
عنوان: پاسخ به: درایور مجازی پورت سریال
ارسال شده توسط: مصطفی بزاز در 22 مهر 1388، 10:27 ق‌ظ
مشکل پیدا کردن هدر کرنل داشت که بالاخره حل شد. هنوز وقت نکردم با تنظیماتش ور برم.
عنوان: پاسخ : پاسخ به: درایور مجازی پورت سریال
ارسال شده توسط: ali green در 27 تیر 1394، 02:11 ب‌ظ
فهمیدم. شما توی هر زبان برنامه‌نویسی کافیه فایل dev/ttyS0/ رو برای write یا append (مود w یا a) باز کنید. بعد هر چی خواستید روش رایت کنید و برای اینکه فرستاده بشه هر بار flush کنید.
مثلاً با این کد پایتون
f = file('/dev/ttyS0', 'w')
f.write('Hello')
f.flush()
f.write('World')
f.flush()
f.close()
حالا مثل این می‌مونه که یه سخت‌افزار خارجی به پورت com1 وصل شده و دو تا کلمهٔ Hello و World رو فرستاده!
توی C هم دقیقاً عین همین. با توابع fopen و fread و fflush و fclose (مثل کار با فایل‌‌های معمولی)

برای دریافت دیتا از پورت سریال(واقعی یا مجازی) هم توی پایتون از کتابخانهٔ serial میشه استفاده کرد. مثلاً این کد هر چی که به پورت com1 فرستاده بشه رو کاراکتر به کاراکتر چاپ میکنه(البته عدد معادلش رو).

from serial.serialposix import Serial
import sys

s = Serial(port='/dev/ttyS0', timeout=0.1)
s.open()

while True:
    c = s.read(1)
    if c!='':
      print ord(c), ## No Newline
      sys.stdout.flush() ## Because no newline printed at the end of output

تحت ++C هم این کد رو قبلاً نوشته بودم برای کار با پورت سریال:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>



int getRTS(int fd){
  int stat;
  ioctl(fd, TIOCMGET, &stat);// Read the RTS pin status
  return (stat & TIOCM_RTS)!=0;
}

void setRTS(int fd, bool enable){
  int cmd = TIOCM_RTS;
  if(enable)
    ioctl(fd, TIOCMBIS, &cmd); // Set the RTS pin.
  else
    ioctl(fd, TIOCMBIC, &cmd); // Unset the RTS pin.
}

int getDTR(int fd){
  int stat;
  ioctl(fd, TIOCMGET, &stat);// Read the DTR pin status
  return (stat & TIOCM_DTR)!=0;
}

void setDTR(int fd, bool enable){
  int cmd = TIOCM_DTR;
  if(enable)
    ioctl(fd, TIOCMBIS, &cmd); // Set the RTS pin.
  else
    ioctl(fd, TIOCMBIC, &cmd); // Unset the RTS pin.
}

int main()
{
  int fd;
  char buff[100];
  int i, wr, rd, n;
  fd=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
  if (fd == -1 ){
    perror("open_port: Unable to open /dev/ttyS0 – ");
    return 1;
  }
  fcntl(fd, F_SETFL,0);
  printf("Port 1 has been sucessfully opened and %d is the file description\n",fd);
  /*/////////////
  printf("\nRTS==%d\n", getRTS(fd));
  printf("Unsetting the RTS pin...\n");
  setRTS(fd, false);
  printf("RTS==%d\n", getRTS(fd));
  printf("Setting the RTS pin...\n");
  setRTS(fd, true);
  printf("RTS==%d\n", getRTS(fd));
  ///////
  printf("\nDTR==%d\n", getDTR(fd));
  printf("Unsetting the DTR pin...\n");
  setDTR(fd, false);
  printf("DTR==%d\n", getDTR(fd));
  printf("Setting the DTR pin...\n");
  setDTR(fd, true);
  printf("DTR==%d\n", getDTR(fd));
  printf("\n");
  *//////////////
  wr=write(fd, "ATZ\r", 5);
  read(fd, buff, 10);
  printf("Received %s\n", buff);
  ////////
  wr=write(fd, "ATM0L2\r", 4);
  read(fd, buff, 10);
  printf("Received %s\n", buff);
  ////////
  wr=write(fd, "ATDT9716129\r", 4);
  read(fd, buff, 10);
  printf("Received %s\n", buff);
  ////////
  //for(i=0; i<10000; i++)
  //  wr=write(fd, "A\n", 4);
  close(fd);
  return 0;
}

(تحت C هم فقط بجای bool بذارید int و بجای false بذارید 0 و بجای true بذارید 1)

پس شما نیاز به هیچ درایور یا ابزار خارجی ندارید. با امکانات پایه‌ای خود گنو/لینوکس به راحتی انجام میشه. :)
مرسی از راهنمایی هاتون عالی بود فقط یه سوال داشتم این کد هارو با ید کجا وارد کرد با eclips میشه؟
من با نرم افزار serial port terminal یه سری کامنت زدم تا به ماٰ‌ژولم برسه ولی اصلا پورت سریال رو شناسایی نمی کرد
باید چیکار کنم؟ رابط ماٰژول تا سیستم یک مبدل ftdi 232  هستش و ماژول esp8266