วันพุธที่ 28 ธันวาคม พ.ศ. 2559

qt serial non-standard baudrate example, custom speed example ตัวอย่าง

เวลาที่เราต้องการใช้ serial port และ ใช้ baudrate ไม่มาตรฐาน ( custom baudrate, custom speed, non-standard baurate, non-standard speed ) ถ้าเป็นเครื่อง pc ทั่วไป ที่มี comport ติดมากับ mainboard ก็สามารถใช้ library ที่ Qt มีมาให้ได้ทันที แต่พอเป็น usb serial ต้องใช้วิธีเขียนอีกแบบนึง จึงจะสามารถใช้งาน custom speed ได้

กว่าจะหาวิธีที่ทำให้ rpi + qt + usb serial สามารถสื่อสารโดย custom speed  ได้ ค่อนข้างลำบาก (ข้อมูลค่อนข้างน้อย ใน google) ต้องรวบรวมข้อมูลจากหลายๆที่ แล้วมาทดลองทำดู ถึงจะได้ออกมา

ผู้เขียนเลือกใช้ usb serial ยี่ห้อ z-tek เวลาไปซื้อต้องบอกเจ้าของร้านว่าเอาของจริงเท่านั้น เพราะถ้าซื้อของปลอมมา จะใช้ไม่ได้ (ของปลอมทำเลียนแบบมีเยอะมาก และ ราคาก็ถูกกว่า) หรือถ้าใครมีความสามารถผลิต usb serial เองได้ โดยใช้ chipset ftdi ก็สามารถนำมาใช้ได้เหมือนกัน

มาดูตัวอย่าง code กันดีกว่า

#include <linux/serial.h>
#include <asm/termios.h>
#include <asm/ioctls.h>
#include <asm/termbits.h>
#include <stropts.h>
#include <QThread>

main(){
int fd;
fd = open("/dev/ttyUSB0",O_RDWR|O_NOCTTY);
struct termios2 tio;
ioctl(fd, TCGETS2, &tio);
tio.c_cflag &= ~CBAUD;
tio.c_cflag |= BOTHER;
tio.c_ispeed = ความเร็วที่ต้องการ;
tio.c_ospeed = ความเร็วที่ต้องการ;
tio.c_cflag |= PARENB; // even parity
tio.c_cflag &= ~CSTOPB; // 1 stop bit
tio.c_cflag &= ~CSIZE;
tio.c_cflag |= CS8;
ioctl(fd, TCGETS2, &tio);

char ping_cmd[] = {2,1};
char ping_rec[7];
write(fd, &ping_cmd, sizeof(ping_cmd) );
QThread::msleep(1000);
read(fd, &ping_rec, sizeof(ping_rec));
write(fd, &ping_rec, sizeof(ping_rec) );
}

เมื่อ compile ผ่านแล้ว เราก็ต่อสายสัญญาณ USB232 จาก rpi เข้ากับ RS232 ของ notebook โดยไขว้ขา 2 กับ 3 สลับกันไว้
แล้วก็เปิดโปรแกรมอะไรก็ได้ที่สามารถสื่อสารผ่าน comport ได้
ในที่นี้ผู้เขียนได้ตั้งโปรแกรม comport ที่เครื่อง notebook ไว้ว่า ถ้ามี 0x01 ผ่านเข้ามา ให้ส่ง 0x61 ออกไป ก็จะได้ผลดังรูปด้านล่าง


จอบอ

ที่มา
http://stackoverflow.com/questions/12646324/how-to-set-a-custom-baud-rate-on-linux





วันพุธที่ 21 ธันวาคม พ.ศ. 2559

qt checkbox ตัวอย่าง

เริ่มจากการลาก GroupBox มาวางไว้ก่อน

แล้วลาก checkbox ลงมา สามารถลากลงมาได้หลายอัน ตามต้องการ โดยวางให้อยู่ใน GroupBox

เวลาเขียน code ก็พิมพ์ตามนี้

if(ui->radioButton->ischeck())
{
  QmessageBox::infomation(0,"message1","message2");
}

โดย message1 คือ title ที่อยู่ข้างบน bar
และ message2 คือ ข้อความที่ต้องการโชว์

ที่มา
https://www.youtube.com/watch?v=0XuxnBqGpWI

qt เปิด window ใหม่, เปิดหน้าต่างใหม่

ถ้าเราต้องการเปิดหน้าต่างใหม่ โดยใช้การกดปุ่ม ให้ทำดังนี้
1. คลิกขวาที่โปรเจค กด add new

ฝั่งซ้าย เลือก qt , ฝั่งขวาเลือก qt designer from class แล้วกด choose


แล้วตั้งชื่อหน้าต่างใหม่ตามต้องการ ในที่นี้ตั้งชื่อว่า SecDialog
จะมีหน้าต่างใหม่ขึ้นมา กด Diaglog without button กด next



2. ใน mainwindow.cpp ให้เพิ่ม #include "SecDialog.h"
3. ไปที่ mainwindow.h เพิ่ม #include "SecDialog.h"
4. mainwindow.h ตรง private: ให้เพิ่ม SecDialog *secdialog;
5. แล้วก็ไปที่ mianwindow.ui ให้คลิกขวาที่ปุ่มที่ต้องการให้เปิดหน้าต่างใหม่ เลือกไปที่ go to slot, click() แล้วพิมพ์ดังนี้
secdialog = new SecDialog(this);
secdialog-> show();

จบ
ที่มา https://www.youtube.com/watch?v=tP70B-pdTH0

qt วาดภาพ ตัวอย่าง

เนื่องจากใน qt ไม่ได้มีเครื่องมืออำนวยความสะดวกในการวาดภาพเหมือนโปรแกรม mspaint
เราจึงต้องเขียน code เพื่อวาดภาพเอง

ทำดังนี้

1. ใน main.h ให้เพิ่ม code เข้าไปใน class
protected:
  void paintEvent(QPaintEvent *e);


2. ใน mainwindow.cpp ให้เพิ่ม #include <QtGui>
และเพิ่มฟังก์ชัน
void mainwindow::paintEvent(QPaintEvent *e)
{
  QPainter p;
  p.begin(this);
  p.drawrect(0,0,50,50);
  หรืออยากวาดอะไรก็วาดไปได้เลย
}

ที่มา
https://www.youtube.com/watch?v=xXV3_mktCmY

วันอาทิตย์ที่ 18 ธันวาคม พ.ศ. 2559

qt sleep ตัวอย่าง

#include <QThread>

และตอนใช้ ก็ใช้แบบนี้

QThread::sleep(xx); โดย xx คือ ตัวเลข ในหน่วยวินาที

หรือ

QThread::msleep(xx); โดย xx คือ ตัวเลข ในหน่วยมิลลิวินาที 1,000 มิลลิวินาที = 1 วินาที

หรือ

QThread::usleep(xx); โดย xx คือ ตัวเลข ในหน่วยไมโครวินาที 1,000,000 มิลลิวินาที = 1 วินาที

วันพุธที่ 24 สิงหาคม พ.ศ. 2559

เปลี่ยน logo ตอน boot

ผมได้พยายามลองเปลี่ยนโลโก้ตอน boot ขึ้นมาใหม่ แต่ว่าทำได้แค่ใกล้เคียงที่อยากได้ มีขั้นตอนดังนี้
1. sudo apt-get install fbi
2. copy รูปภาพที่ต้องการให้โชว์ตอน boot ลงใน /etc แล้วตั้งชื่อว่า splash.png
3. สร้าง script ที่ /etc/init.d/asplashscreen ดังนี้

#! /bin/sh ### BEGIN INIT INFO # Provides: asplashscreen # Required-Start: # Required-Stop: # Should-Start: # Default-Start: S # Default-Stop: # Short-Description: Show custom splashscreen # Description: Show custom splashscreen ### END INIT INFO do_start () { /usr/bin/fbi -T 1 -noverbose -a /etc/splash.png exit 0 } case "$1" in start|"") do_start ;; restart|reload|force-reload) echo "Error: argument '$1' not supported" >&2 exit 3 ;; stop) # No-op ;; status) exit 0 ;; *) echo "Usage: asplashscreen [start|stop]" >&2 exit 3 ;; esac :

4. sudo chmod a+x /etc/init.d/asplashscreen (ทำให้ script สามารถใช้งานได้)
5. sudo insserv a+x /etc/init.d/asplashscreen
6. sudo nano /boot/cmdline.txt
6.1 เพิ่ม logo.nologo quiet เข้าไปข้างหลังสุด
7. sudo nano /etc/rc.local
7.1 เพิ่ม clear ก่อน exit 0
8. sudo reboot

ผลที่ได้คือ เราจะไม่เห็นลูก raspberry ตอนเริ่ม และจะเห็น logo ของเราในเวลาถัดมา
enjoy!!!

วันจันทร์ที่ 11 กรกฎาคม พ.ศ. 2559

qt timer slot

ดูตามนี้เลยครับ ไม่มีเสียง ทำตามอย่างเดียวเลย
https://youtu.be/W1CTuOg2JLA

qt ตัวอย่างการส่ง serial port hex charactor, การรับค่า serial, การเปรียบเทียบ QByteArray กับ int

#include <QtSerialPort>
#include <QtSerialPort/QSerialPort>

void class::my_class()
{
    serial->setPortName("COM9");
    if (serial->isOpen()){
        serial->close();
        qDebug() << "serial close";
    }
    else{
        qDebug() << "serial already close.";
    }
    if (serial->open(QIODevice::ReadWrite)) {
        serial->setBaudRate(19200);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::EvenParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);          
    }
}

my_function()
{
    char buff[16];
    int hhh;
    for(hhh=0;hhh<=15;hhh++)
    {
        buff[0] = hhh;
        serial->write(buff,1);
    }
}


my_function2()
{
    QByteArray input;
    char buff[16];
    int hhh;
    for(hhh=0;hhh<=15;hhh++)
    {
        buff[0] = hhh;
        serial->write(buff,1);

        serial->waitForBytesWritten(100);
        serial->waitForReadyRead(100);
        input = serial->readAll();
        if (input == ""){
            qDebug() << "status" << hhh << " = Lost.";
        }else if( quint8(input[0]) == quint8(0x60+hhh)){
            qDebug() << "status" << hhh << " = Hot.";
        }
    }

    serial->flush();
}

วันศุกร์ที่ 29 เมษายน พ.ศ. 2559

RPI ป้องกัน sleep mode

ถ้าต้องการให้ RPI ไม่เข้า sleep mode (หน้าจอดับ ถ้าไม่มีการเคลื่อนไหวสักระยะ) ให้ทำดังนี้

1. sudo nano /etc/lightdm/lightdm.conf

2. ให้เพิ่มบรรทัดนี้เข้าไป
[SeatDefaults]
xserver-command=X -s 0 -dpms

3. restart

จอบอ.

ที่มา
http://raspberrypi.stackexchange.com/questions/4773/raspberry-pi-sleep-mode-how-to-avoid

แต่ถ้ายังไม่ได้ผล ให้ใช้วิธีนี้ครับ
sudo apt-get install xscreensaver
แล้วไปที่เมนู preferences (ด้านล่างซ้ายมือ jessie) ==> Screensaver
แล้วไปเลือก disable screen saver
จอบอ

ที่มา
http://stackoverflow.com/questions/30985964/how-to-disable-sleeping-on-raspberry-pi

วันพฤหัสบดีที่ 28 เมษายน พ.ศ. 2559

RPI LCD 7 นิ้ว touch screen ยี่ห้อ waveshare

วันนี้ผมได้ซื้อ LCD 7 นิ้ว touch screen ยี่ห้อ waveshare มาจาก thaieasylect ตอนนี้ก็ราคา 2,850 บาท บวก vat บวกค่าขนส่งก็ 3,1xx บาท





พอจะใช้งาน เราก็ต้องศึกษากันสักหน่อยว่าใช้งานยังไง
ก็เจอ เวปนี้ ที่ thaieasyelect เขาแนะนำมา
ซึ่งเขาก็บอกรายละเอียดที่สำคัญหลายอย่าง เช่น
- ต้องใช้ power supply 5V 2A ไม่งั้นจะจ่ายไฟไม่พอ
- ต้องลง driver เพิ่ม จึงจะใช้งานได้
- image ที่ให้มา เป็น image เปล่าที่ใช้กับจอ LCD นี้เท่านั้น อะไรที่เราเคยลงไว้ใน sd card จะหายหมด

ซึ่งตอนแรกผมก็ลองลง image ที่เขาให้มา แต่ว่าใช้ไม่ได้ จอไม่ขึ้นภาพ ก็เลยศึกษาต่อ
เห็นในหน้าเวปมีลิงค์ไปให้อ่าน manual ก็คลิกเข้าไป
พอเข้าไปดู ก็ถึงบางอ้อออออ ต้อง config ก่อน โดย
เข้าไปแก้ไข /boot/config.txt ดังนี้
ให้เพิ่ม
max_usb_current=1
และแก้ไข
hdmi_group=2
hdmi_mode=87
hdmi_cvt 1024 600 60 6 0 0 0
save แล้วก็นำออกมา เอาไปใส่ rpi
เมื่อ boot เสร็จแล้ว เราก็ควรทำให้มันเปิดหน้า startx ขึ้นมาอัตโนมัติ โดยใช้คำสั่งดังนี้
sudo raspi-config
เข้าไปเมนู Enable boot to desktop...
แล้วเลือก Login as user PI at the graphical desktop
เลือก finish เพื่อ restart

ทีนี้แสดงผลได้ละ สวยงาม



แต่พอลองแตะที่หน้าจอ เอ๊ะ!!! ใช้ไม่ได้
ก็ลองอ่านๆๆต่อไปจากของเดิม เจอมันบอกว่า ให้อ่าน manual firmware rev2.1 ก่อนนะก๊ะ  โอเค อ่านก็อ่าน

 เจอว่ามันมี driver ให้ download ก็เอามาลงที่เครื่องเรา



แล้วทำตามขั้นตอนต่อไป


เมื่อได้ไฟล์มาแล้ว ก็ remote เอาลงที่เครื่อง RPI ตรงไหนก็ได้ วางๆไปเถอะ
แล้วเราก็แตกไฟล์
- sudo tar zxvf filename.tar.gz

แล้วก็เข้าไปในโฟลเดอร์นั้นๆ
- cd dir_file_name

แล้วก็รันคำสั่ง
- sudo ./USB_TOUCH_CAP_7.0_RASBIAN

เมื่อรันเสร็จ เครื่องจะ restart อัตโนมัติ และเมื่อ boot ขึ้นมาใหม่ก็จะใช้งาน touch screen ได้เลย

จอบอ.

วันพฤหัสบดีที่ 21 เมษายน พ.ศ. 2559

qt แสดงรูป ด้วย qpixmap

ขั้นแรก เราต้องเข้าไปที่ mainwindow.ui เสียก่อน ด้วยการ double click เป็นหน้า ui ขึ้นมา
แล้วเพิ่ม qlabel เข้าไป ด้วยการลาก qlabel จากเมนูด้านซ้ายมือ เข้าไปใน ui
แล้วก็เพิ่มรูปภาพเข้าไป ด้วยการเลือกที่เมนู pixmap (property)
กลับมาที่หน้า mainwindow.cpp และ พิมพ์เพิ่ม
#include <QPixmap>
และเพิ่ม
QPixmap pix("path_of_your_pic/pic.png");
ui -> label -> setPixmap(pix);
เข้าไปในโปรแกรม ตรงส่วนที่ต้องการแสดงรูป
โดย label คือ ชื่อของ label ที่เราลากไปวางใน ui ตอนแรก


ที่มา

https://www.youtube.com/watch?v=pzzccU9mErg

qt เปลี่ยน title ของหน้าต่าง

this->setWindowTitle("change your title name.");

วันจันทร์ที่ 4 เมษายน พ.ศ. 2559

วิธีลง qt serial

ตอนแรกลองลง qt4 แล้วลง qt serial แต่ทำไม่ได้ ติดปัญหาว่าต้องเป็น qt5 ถึงจะลง qt serial ได้
จึงได้ทำใหม่ทั้งหมด
โดยการ upgrade เป็น raspbian jessie หรือจะโหลด image ใหม่เลยก็ได้ แล้วก็ลง qt5 ตาม ซึ่งใน link จะรวมถึงการลง qt serial ด้วยเลย

ต้องขอขอบคุณ Thai easy elect มากๆครับ ที่เผยแพร่ความรู้ให้คนที่มาเล่นที่หลัง

วันพฤหัสบดีที่ 31 มีนาคม พ.ศ. 2559

ตัวอย่าง python gui

ตย.1
from Tkinter import * // เพื่อโหลดโปรแกรมการวาดภาพขึ้นมา
master = Tk()  // กำหนดให้สิ่งที่เราจะวาด ชื่อว่า master
w = Canvas (master, width=300, height=200) // กำหนดขนาดสิ่งที่เราจะวาด
w.pack() // วาดภาพขึ้นจอ
mainloop() // main loop ไม่ทำไรเลย


ตย.2
from Tkinter import * // เพื่อโหลดโปรแกรมการวาดภาพขึ้นมา
w= Tk()  // กำหนดให้สิ่งที่เราจะวาด ชื่อว่า w
w.title("Test gui python") // กำหนดชื่อ title bar
w.geometry('800x480') // กำหนดขนาดของสิ่งที่จะวาด
exitButton = Button(w, text="Exit", height=2, width=6) กำหนดให้ปุ่ม exit button อยู่ใน w
exitButton.pack() วาดปุ่ม exit
mainloop() // main loop ไม่ทำไรเลย



ตย.3 ใช้ pygame ในการวางรูปภาพ
import pygame
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Test pygame.")  // ตั้งชื่อ title bar
screen = pygame.display.set_mode((500,500),0,32)  // วาด screen
pic1 = pygame.image.load("/home/pi/pic/xxx1.bmp").convert()  // โหลดรูป1
pic2 = pygame.image.load("/home/pi/pic/xxx2.bmp").convert()  // โหลดรูป2
while True: //  ทำซ้ำไม่มีวันจบ
  screen.blit(pic1,(0,0))  // วางรูปที่1
  screen.blit(pic2,(50,0))  // วางรูปที่ 2
  pygame.display.update() // update display


 ตย.4 ใช้ pygame เปิด Full screen
import pygame
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Test pygame.")  // ตั้งชื่อ title bar
screen = pygame.display.set_mode()  // วาด Full screen
pic1 = pygame.image.load("/home/pi/pic/xxx1.bmp").convert()  // โหลดรูป1
pic2 = pygame.image.load("/home/pi/pic/xxx2.bmp").convert()  // โหลดรูป2
while True: //  ทำซ้ำไม่มีวันจบ
  screen.blit(pic1,(0,0))  // วางรูปที่1
  screen.blit(pic2,(50,0))  // วางรูปที่ 2
  pygame.display.update() // update display


ตย.5
import pygame
import time
import thread
import sys

from pygame.locals import *
pygame.init()
pygame.display.set_caption("Sample")
screen = pygame.display.set_mode()
pic1=pygame.image.load("/home/pi/NIRAN/PY/image/pic1.jpg").convert()
pic_main=pygame.image.load("/home/pi/NIRAN/PY/image/main.png").convert()

def print_time(thread_name, delay):
  while True:
    count = 0;
    while count < 5:
      time.sleep(delay)
      count +=1
      print "%s: %s" %(thread_name,time.ctime(time.time()) )

try:
  thread.start_new_thread(print_time, ("Thread-1",2) )
  thread.start_new_thread(print_time, ("Thread-2",4) )
except:
  print "Error : unable to start thread."

while True:
  try:
    count_main =0;
    while count_main <1:
      screen.blit(pic_main,(115,0) )
      pygame.display.update()
      time.sleep(2)
      screen.fill([0,0,0])                      #clear screen
      screen.blit(pic1,(50,0))
      pygame.display.update()
      time.sleep(2)
      screen.fill([0,0,0])                     #clear screen
      count_main +=1
  except:
    print "Keyboard interrupt exit."
    thread.exit()

ที่มา
https://www.youtube.com/watch?v=El3j3hAPxr0

ถ้าอยากรู้คำสั่งเพิ่มเติมเกี่ยวกับ display ให้ไป ที่นี่
http://www.pygame.org/docs/ref/display.html

วันอังคารที่ 29 มีนาคม พ.ศ. 2559

ปิด console เพื่อทำเป็น serial port

พอดีว่ามีโปรเจคที่ต้องการใช้ serial port แต่ไม่อยากใช้ usb serial ก็เลยต้องหาเรื่องปิด console port

ที่เครื่อง RPI
sudo nano /boot/cmdline.txt
ลบข้อความนี้ออก console=ttyAMA0,115200 

จะเหลือข้อความประมาณนี้
dwc_otg.lpm_enable=0 rpitestmode=1 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait


แต่ดูเหมือนว่าจะยังไม่พอ ต้องทำเพิ่มอีก

sudo nano /etc/inittab
ให้เติมเครื่องหมาย # ข้างหน้าบรรทัดนี้
2:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
ซึ่งอยู่ที่บรรทัดสุดท้ายของไฟล์

จากนั้นให้ reboot

ถ้าจะลองว่าได้ผลมั้ย ก็ให้ลง minicom ดู
sudo apt-get install minicom
minicom -b 115200 -o -D /dev/ttyAMA0
แล้วต่อ serial port ตามรูป


ลองดูกันครับพี่น้องงงง

ปล.วิธีออกจาก minicom กด ctrl+a แล้วปล่อย แล้วกด q แล้ว enter


ที่มา
http://www.irrational.net/2012/04/19/using-the-raspberry-pis-serial-port/
http://www.hobbytronics.co.uk/raspberry-pi-serial-port

วันจันทร์ที่ 28 มีนาคม พ.ศ. 2559

วิธีแก้ ต่อ hdmi to vga กับ rpi แล้วใช้ไม่ได้

ก่อนหน้านี้ผมเจอปัญหาว่า ใช้ hdmi to vga แล้วมันใช้กับ rpi ไม่ได้ ลงทุนซื้อหลายรุ่นก็ไม่ได้ ไม่ยอมขึ้นจอ ขึ้นบ้างไม่ขึ้นบ้าง จนเลิกล้มไป ต้องหาจอที่มี hdmi มาต่อ

วันนี้ลองเล่นอีกที ได้ไปเจอเวปของ thaieasyelect ทำเอาตาสว่างเลย
คือมันจะมีคอนฟิกไว้ให้

ทำตามนี้เลยครับ จะมีการ download .zip ไม่ต้องตกใจนะครับ หรือจะไปเปิดในนี้ก็ได้ เพื่อความสบายใจ

# Force to display to HDMI even no HDMI device attach
hdmi_force_hotplug=1
# uncomment to use with computer monitor resolution 1024 x 768 @ 60Hz
#hdmi_group=2
#hdmi_mode=16
# uncomment to use with computer monitor resolution 1280 x 1024 @ 60Hz
#hdmi_group=2
#hdmi_mode=35
# uncomment to use with computer monitor resolution 1920 x 1080 @ 60Hz
#hdmi_group=2
#hdmi_mode=82
# uncomment to use with television monitor resolution 1920 x 1080 @ 60Hz
#hdmi_group=1
#hdmi_mode=16


สวัสดี