Kemarin, mumpung hari libur aku setup program timbangan digital baru di kantor.
Program yang lama merupakan program DOS yang aku tulis dengan menggunakan Clipper, program ini berjalan dengan baik di linux dengan bantuan dosemu.
Program baru merupakan program Windows. Salah satu improvement dalam program ini adalah support untuk beberapa jenis indikator. Program diinstall di linux dengan wine versi 1.1.20.
Beberapa catatan dalam instalasi program ini di wine:
Program yang lama merupakan program DOS yang aku tulis dengan menggunakan Clipper, program ini berjalan dengan baik di linux dengan bantuan dosemu.
Program baru merupakan program Windows. Salah satu improvement dalam program ini adalah support untuk beberapa jenis indikator. Program diinstall di linux dengan wine versi 1.1.20.
Beberapa catatan dalam instalasi program ini di wine:
- Pencetakan slip bukti timbangan dan laporan-2 menggunakan printer Dot Matrix. Apabila pencetakan dilakukan lewat printer driver, pencetakan dengan printer dot matrix akan menjadi sangat lambat plus hasil buruk plus boros pita... :)
Oleh karena itu, program ini melakukan pencetakan langsung melalui printer port lpt1. Di windows, hal ini tidak menjadi suatu permasalahan, di linux dengan wine, maka lpt1 akan dimap ke /dev/lp0.
Masalahnya, owner dari device ini adalah root dan group lp. Secara default user-user di Ubuntu (..nggak tahu untuk distro lainnya) tidak termasuk dalam group lp. Maka, jika kita dalam wine berusaha mencetak ke lpt1 akan selalu ditolak. Silahkan coba perintah-perintah di bawah ini:
$wine cmd
C:\>dir > lpt1
Kalau respon yang kita dapat adalah printer kita mencetak isi C:\, maka selamat! Tapi jika yang anda dapatkan adalah error message: Access denied, silahkan baca lebih lanjut.
Lalu apa solusinya? menjalankan wine sebagai root? ha..ha..,ya enggaklah, itu kan solusi bodoh (yang sayangnya sering kali aku lihat dilakukan orang-orang). Solusi paling tepat adalah memasukkan user ke dalam group lp:
$sudo usermod -a -G lp bambang
Awas: perubahan ini hanya efektif setelah anda logoff dan login kembali!
Setelah itu, silahkankan anda masuk lagi ke command prompt wine dan coba cetak isi directory ke printer anda - Masalah lain, pada modul setting konfigurasi Indikator (Indikator adalah alat pembaca hasil timbangan yang terkonek ke komputer kita melalui serial port), program berusaha mencari serial port apa saja yang ada di komputer kita.
Pencarian serial ports ini dilakukan pada registry window:
HKLM\HARDWARE\DEVICEMAP\SERIALCOMM
Masalahnya, di wine (sampai dengan versi pada waktu blog ini ditulis: 1.1.21), registry key ini tidak ada! Penambahan secara manual tidak bisa dilakukan karena ini merupakan volatile key, yang artinya registry key ini secara otomatis akan diupdate oleh windows (atau wine) dengan melakukan pengecekan terhadap hardware yang ada.
Ada 2 solusi untuk masalah ini:- Cek terlebih dahulu registry key tsb. ada atau tidak. Jika ada, go ahead! Silahkan tanya ke om Windows, serial port apa saja yang ada di komputer ini. Tapi jika registry key ini tidak ada (yang artinya anda sedang jalan di wine yang belum terpatch, ya nggak usah tanya ke windows. Di program saya, pilihan setting com port ini melalui sebuah combobox. Program ini dibuat dengan Delphi7 dan komponen TComPort, ini yang saya lakukan:
// Serial Port
try
CPort.EnumComPorts(Self.CBSerialPort.Items);
except
if IWSDataModule.ComPorts = '' then begin
MessageDlg( 'Gagal membaca registry key HKLM\HARDWARE\DEVICEMAPPING\SERIALCOMM.'
+ #13#10'Apakah program ini dijalankan di wine? Set Serial Port yang ada di file '
+ ChangeFileExt( ParamStr(0) , '.ini'), mtError,[mbAbort],0);
Abort;
end;
Self.CBSerialPort.Items.Clear;
Str := IWSDataModule.ComPorts;
while Str <> '' do begin
i := Pos( ',' , Str );
if i <> 0 then begin
Str1 := Trim(Copy( Str,1,i -1 ));
Str := Trim(Copy(Str,i+1,Length(Str)-i ));
end
else begin
Str1 := Trim( Str);
Str := '';
end;
Self.CBSerialPort.Items.Add(UpperCase(Str1));
end;
end;
Self.CBSerialPort.ItemIndex := Self.CBSerialPort.Items.IndexOf(SerialPortIndikator); - Patch wine anda! Tentu saja ini hanya bisa dilakukan kalau kita install wine melalui source code (inilah alasan utama kenapa aku nggak mau install wine pakai cara gampang dengan install package jadinya). Patch agar supaya Wine melisting serial port apa saja yang ada ke registry key HKLM/HARDWARE/DEVICEMAP/SERIALCOMM tsb. dapat anda dapatkan di:
http://www.nabble.com/create-DEVICEMAP%5CSERIALCOMM-registry-entries-td20693044.html
Hanya saja masalahnya patch ini gagal diappliedkan ke wine versi 1.1.21, untuk itu berdasarkan patch tsb. saya buat patch di bawah ini, patch dilakukan terhadap file dlls/kernel32/oldconfig.c:
--- oldconfig.old.c 2009-05-10 12:39:08.000000000 +0700
+++ oldconfig.c 2009-05-10 12:53:06.000000000 +0700
@@ -331,8 +331,8 @@
}
-/* create the hardware registry branch */
-static void create_hardware_branch(void)
+/* create the scsi registry branch */
+static void create_scsi_branch(void)
{
/* The following mostly will work on Linux, but should not cause
* problems on other systems. */
@@ -454,6 +454,149 @@
}
+/* create SERIALCOMM branch containing keys for /dev/ttyS* */
+void create_serialcomm_branch(void)
+{
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING nameU;
+ WCHAR dataW[50];
+ DWORD length;
+ DWORD disp;
+ HANDLE targetKey;
+ struct dirent * dent;
+ DIR * dir;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ char deviceprefix[5] = "cuad";
+#else
+ char deviceprefix[5] = "ttyS";
+#endif
+ int portmap[256];
+ int isdevice[256];
+ char readlinkbuf[261];
+ char keyname[] = "\\Device\\Serial999";
+ char keydata[] = "COM999";
+ const char * wineprefixdir;
+ char * dosdevicepath = 0;
+ static const char dosdevdirsuffix[] = "/dosdevices";
+ int suffixlength = 11;
+ int pathlength = 0;
+ int index = 0;
+ int numbytes = 0;
+ int devnumber = 0;
+ int portnumber = 0;
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &nameU;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ /* Ensure there is HARDWARE\\DEVICEMAP\\SERIALCOMM key */
+ if(!RtlCreateUnicodeStringFromAsciiz( &nameU, "Machine\\HARDWARE\\DEVICEMAP\\SERIALCOMM" ) ||
+ NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
+ NULL, REG_OPTION_VOLATILE, &disp ))
+ {
+ ERR("Cannot create DEVICEMAP\\SERIALCOMM registry key\n" );
+ return;
+ }
+ RtlFreeUnicodeString( &nameU );
+
+ /*initialise portmap and devices arrays to -1*/
+ for(index = 0; index < wineprefixdir =" wine_get_config_dir();" pathlength =" strlen(wineprefixdir)" dosdevicepath =" HeapAlloc(GetProcessHeap()," dir =" opendir(" dent =" readdir(dir)))">d_name, deviceprefix, 4) == 0)
+ {
+ /*d_name is null terminated already*/
+ devnumber = strtol(dent->d_name + 4, NULL, 10);
+ /*which COM port will this device map onto*/
+ portmap[devnumber] = devnumber + 1;
+ isdevice[devnumber] = 1;
+ }
+ }
+ }
+ closedir(dir);
+
+ /* Enumerate all dosdevices/com* symlinks */
+ dir = opendir(dosdevicepath);
+ if(dir)
+ {
+ dosdevicepath[pathlength -1] = '/';
+ while((dent = readdir(dir)))
+ {
+ if(strncmp(dent->d_name, "com", 3) == 0)
+ {
+ portnumber = strtol(dent->d_name + 3, NULL, 10);
+ if(portnumber <> 256)
+ {
+ continue;
+ }
+ else
+ {
+ /* get the symlink target
+ * strtol the last chars
+ * check and set portmap entry */
+ memcpy(dosdevicepath + pathlength, dent->d_name, strlen(dent->d_name) + 1);
+ numbytes = readlink(dosdevicepath, readlinkbuf, 261);
+ if(numbytes > 0 && numbytes < devnumber =" strtol(readlinkbuf" index =" 0;" index =" 0;">
Cara untuk mengapplykan patch tsb. di atas:- Save patch tsb. dengan nama devicemap_serialcomm.diff ke directory dlls/kernel32
- masuk ke directory dlls/kernet32 dan lakukan patch dengan command:
patch -i nama devicemap_serialcomm.diff
- Cek terlebih dahulu registry key tsb. ada atau tidak. Jika ada, go ahead! Silahkan tanya ke om Windows, serial port apa saja yang ada di komputer ini. Tapi jika registry key ini tidak ada (yang artinya anda sedang jalan di wine yang belum terpatch, ya nggak usah tanya ke windows. Di program saya, pilihan setting com port ini melalui sebuah combobox. Program ini dibuat dengan Delphi7 dan komponen TComPort, ini yang saya lakukan:
Halo Pak Bambang,
ReplyDeleteNama saya ronny, saya mohon bantuannya untuk masalah membaca serial port dengan wine..
1. saya punya program untuk membaca mesin ukur kulit yg keluar datanya melalui serial port dan program tsb saya buat dengan vfp 9, bila dengan windows program tsb gak ada mslh. sedangkan program ini saya mau coba jalankan di ubuntu dengan bantuan wine.
waktu saya jalankan program tsb tidak mengeluarkan data sama sekali...,mohon bantuannya pak...
ini email saya pak... trironny@gmail.com
Halo Ronny, apakah wine anda sudah dipatch seperti yang aku tulis di atas?
ReplyDeleteCoba jalankan wine regedit dan check registry key HKLM\HARDWARE\DEVICEMAP\SERIALCOMM ada atau tidak? Jika belum ada patch terlebih dahulu wine-nya seperti yang aku tulis di atas.
Goodluck!
Halo Pak Bambang, wine saya belum di patch.. cm sekedar info bahwa saya mencoba dengan laptop saya yg dimana gak ada serial portnya dan saya menggunakan usb to serial converter, apakah dengan di patch tersebut akan tetap keluar serial comm nya di registry..mohon maaf masih belajar pak..
ReplyDeleteyang kedua, gimana cara jalanin patchnya pak.. saya gak ngerti sama sekali...
oh iya pak versi wine saya 1.0.1, soalnya script patchnya yg bapak tulis agak terpotong di blognya bapak...
terima kasi sebelumnya, mohon maaf kalo banyak tanya pak..maklum masih belajar dengan ubuntu+wine
thanks 4 all
ronny tri
Haloo Pak Bambang,
ReplyDeletesaya udah coba patch wine saya tetapi gak bisa detect usb to serial saya. bahkan saya juga upgrade wine saya ke versi 1.1.37 dan di regeditnya langsung keluar serialcommnya tetapi juga gak detect usb to serial saya, selain itu juga saya coba di pc desktop yg ada serialcommnya juga gak mau detect...
mohon bantuannya pak bambang..
thanks 4 all
ronny tri
Halo Ronny,
ReplyDeleteSebelumnya sorry, saat ini aku sedang pakai window$, sehingga apa yang aku tulis di bawah ini hanya pemikiranku saja dan belum aku coba.
Coba dicek dulu usb - serialnya didetect sebagai apa: coba usbnya dicopot dan kemudian dipasang lagi, setelah itu ketikkan perintah: dmesg di terminal, dan coba dibaca outputnya.
Misalnya, diketemukan devicenya adalah /dev/ttyUSB0, maka kemudian anda buat softlink mappingnya di directory ~/.wine/dosdevices dengan perintah sbb:
ln -s /dev/ttyUSB0 com1:
Halo pak bambang,
ReplyDeleteyang bapak kasih untuk buat simbolik link udah saya coba pak, cuman apa perlu di kasih titik 2(:), kalo pake titik 2 belum saya coba. dan cara itu gak berhasil pak..
termasuk, user saya sudah saya masukkan di group dialout, tetapi tetep belum berhasil..
mohon bantuannya pak, barangkali ada ide dari yg cara pertama bapak dengan menggunakan usb to serial..
thanks 4 all
ronny tri
Halo Ronny,
ReplyDeleteDari output dmesg, apakah betul com portnya sudah terdetek sebagai /dev/tty ?
Sudah dicoba dicek dengan program ala hyperterminal seperti di Windows? Untuk linux bisa dicoba: gtkterm atau cutecom.
halo pak bambang, kalo boleh saya pingin nyobain program timbangan elektroniknya seperti apa itu ?
ReplyDeletejika berkenan tolong di kirim ke email jhery_adm@yahoo.com
terimakasih...
salam
heri
Pak Bambang saya yusak, saya ingin bertanya saya juga ingin belajar tentang koneksi timbangan, saya menggunakan Delphi 7 untuk membuat aplikasinya namun saya belum bisa memasukan nilai angka pada timbangan ke program. jika boleh untuk menampilkan data dari timbangan ke edit1.text pada aplikasi saya bagaimana yea pak?? jika boleh saya minta codingnya..
ReplyDeleteterimakasih pak...
Pak bambang saya sedang belajar membuat program timbangan menggunakan delphi 7, tapi saya sudah mandek karena belum bisa koneksi ke timbangannya, mohon pencerahanya bagaimana membuat coding untuk koneksi ke program yang saya buat. agar niali yang ada pada timbangan dapat mincul pada edit1.text.
ReplyDeleteterimakasih pak...
Pada prinsipnya, kita mengcapture data yang dikirim ke serial port. Untuk mengcapture datanya saya menggunakan komponen TComPort, tentu saja sebelumnya kita harus mengetahui format data yang diterima lewat serial port, supaya dapat memparsing datanya. Selanjutnya jika kita telah terima datanya terserah kita mau ditampilkan di TEdit atau disimpan sebagai record database.
Deletecara parsingnya gmn ya pak? saya pake fungsi pos dan posex lalu ditampilkan di editbox. tapi editbox ini kadang kosong. seolah berkelip/blink. gimana cara mengatasi kedipan itu dengan data yg benar(parsingan yg utuh misal 1450). thanks
ReplyDeletesaya minta bantuannya "saya punya masalah hasil data timbangan dengan extension "DBF" gimana caranya agar bisa di buka di excel atau word sebelumnya trim's Gan ....atas ilmu
ReplyDelete