วันอาทิตย์ที่ 11 พฤศจิกายน พ.ศ. 2561

arduino rf433MHz Wireless RF Transmitter and Receive Module

วันนี้ขอนอกเรื่อง raspberrypi บ้าง บันทึกไว้กันลืม กันหายด้วย

ทำตามเวปที่เขาสอนไว้ การต่อสายสัญญาณ ก็ทำตามได้อยู่ แต่ code มันไม่ได้ตามที่เราอยากได้ จึงต้อง modify code เอง

อธิบายหลักการของ code
ในการส่งข้อมูลของเจ้าตัวนี้ จะส่งซ้ำๆ หลายๆหน เพื่อความชัวร์ของข้อมูล แต่ก็ทำให้เราเขียน code ยากหน่อย เพราะต้องกรองเอาตัวที่ซ้ำออกไป
วิธีการกรองก็คือ ต้องใส่หมายเลขจำนวน byte ที่ส่ง มาด้วย ยกตัวอย่างเช่น
ต้องการส่งคำว่า "HELLO" เราก็ต้องส่ง 0H , 1E, 2L, 3L, 4O คือ มีตัวเลขนำหน้าอักษรที่เราจะส่งแปะติดมาด้วย แล้วก็ต้องปิดท้ายด้วย 0xFF เพื่อให้รู้ว่าหมดข้อมูลแล้ว
ดังนั้นข้อมูลที่เราต้องส่งจริงๆก็คือ 0H , 1E, 2L, 3L, 4O, 5(0xff)


code ข้างล่างนี้ เป็น code ของตัวส่ง

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(9600);
  mySwitch.enableTransmit(10);
}

void send_string(const char *str){
  int i=0;
  for(char *p=str; *p; p++){
    mySwitch.send((i<<8)+*p,16);
    i++;
  }
  mySwitch.send((i<<8)+255,16);
}

void loop() {
  send_string("Hello");
  delay(1000);
}

ส่วน code ของภาครับ ก็ต้องกรองเอาตัวที่ไม่ใช่ข้อมูลจริงๆออกไป

code ต่อไปนี้ เป็นของตัวรับ

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

uint16_t recv_code[5];
static uint8_t last_byte_number;

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2
}

int receiveValue(){
  if(!mySwitch.available())
    return 1;
  uint16_t code = mySwitch.getReceivedValue();
  uint8_t this_byte_number = code >> 8;
  code = code&0xff;
  if(code == 0xff){
    last_byte_number = this_byte_number;
    mySwitch.resetAvailable();
    Serial.print("\n");
    return 3;
  }else{
    if(code != 0){
      recv_code[this_byte_number] = code;
      mySwitch.resetAvailable();
      Serial.print(this_byte_number);
      Serial.print((char)recv_code[this_byte_number]);
    }
  }
  return 2;
}

void loop() {
  int c = receiveValue();
  if(c==3){
    for(int i=0; i<last_byte_number;i++){
      Serial.write((char)recv_code[i]);
    }
  }
}

พอเราเขียน code และ upload เรียบร้อยแล้ว เราก็เปิด Serial Monitor ดูว่าข้อมูลที่รับได้ เป็นอย่างไรบ้าง

วันพุธที่ 19 กันยายน พ.ศ. 2561

GCP FileZilla

เราต้องมี GCP (google cloud platform) ก่อน

เราต้องการโหลดไฟล์อะไรสักอย่าง เช่น รูปภาพ หรือ vdo ขึ้น GCP
ก่อนอื่น เราต้อง download puttygen.exe และ filezilla มาก่อน
เปิดโปรแกรม puttygen
- กด generate
- วนเมาส์ในที่ว่างไปเรื่อยๆ จนสีเขียวขึ้นเต็ม bar จะมี key ออกมา
- ใส่ key comment (จะเป็นชื่อ user ของเรา)
- ใส่ key passphrase (password)
- ใส่ confirm passphrase ให้เหมือนเดิม
- กด save privare key

ไปที่ browser เข้า GCP cloud.google.com
- ไปที่ vm instance, metadata
- ไปที่ ssh keys
- กด edit
- กด +add item
- กลับไปที่หน้า puttygen, ให้ copy key 
- นำมาวางในช่องว่าง ในหน้า ssh keys 
- กด save

ไปที่ FileZilla
- กด Edit, Settings
- ไปที่ SFTP
- กด add key file 
- เลือกไฟล์ที่เรา save ไว้ตอนแรก
- กด ok จะเด้งกลับไปที่หน้าหลัก
- ในช่อง host: ให้ใส่ sftp://xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx คือ IP ของ GCP)
- ใส่ user name และ password
- กด quick connect 

เพียงเท่านี้เราก็สามารถ ftp ได้แล้ว

วันอังคารที่ 18 กันยายน พ.ศ. 2561

tcp server

พอดีมีงานที่ต้องใช้งาน TCP/IP ก็เลยต้องมาเรียนรู้กันสักหน่อย


================================
========= test_network_server.pro  =======
================================QT -= gui
QT += network

CONFIG += c++11 console

CONFIG -= app_bundle

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp \
    myserver.cpp

HEADERS += \
    myserver.h

target.path = /home/pi/Pump
INSTALLS += target


================================
===========  main.cpp  ==============
================================
#include <QCoreApplication>
#include <myserver.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    myServer mServer;

    return a.exec();
}


================================
===========  myserver.h  ============
================================#ifndef MYSERVER_H
#define MYSERVER_H

#include <QObject>
#include <QDebug>
#include <QTcpServer>
#include <QTcpSocket>

class myServer : public QObject
{
    Q_OBJECT
public:
    explicit myServer(QObject *parent = nullptr);

signals:


public slots:
    void newConnection();

private:
    QTcpServer *server;
};

#endif // MYSERVER_H


================================
===========  myserver.cpp  ===========
================================
#include "myserver.h"

myServer::myServer(QObject *parent) : QObject(parent)
{
    server = new QTcpServer(this);
    connect(server,SIGNAL(newConnection()),this,SLOT(newConnection()));
    if(!server->listen(QHostAddress::Any,1234)){
        qDebug()<<"Server could not start";
    }
    else{
        qDebug()<<"Server started";
    }
}

void myServer::newConnection(){
    QTcpSocket *socket = server->nextPendingConnection();
    socket->write("hello client\r\n");
    socket->flush();
    socket->waitForBytesWritten(3000);

    socket->close();
}

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

tcp client

==================================
========== test_network_client.pro  ========
==================================
QT -= gui
QT += network

CONFIG += c++11 console
CONFIG -= app_bundle

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp \
    sockettest.cpp

target.path = /home/pi/Pump
INSTALLS += target

HEADERS += \
    sockettest.h


==================================
==============  main.cpp  ============
==================================
#include <QCoreApplication>
#include "sockettest.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    SocketTest cTest;
    cTest.Connect();

    return a.exec();
}

==================================
============  sockettest.h  ============
==================================
#ifndef SOCKETTEST_H
#define SOCKETTEST_H

#include <QObject>
#include <QTcpSocket>
#include <QDebug>


class SocketTest : public QObject
{
    Q_OBJECT
public:
    explicit SocketTest(QObject *parent = nullptr);
    void Connect();

signals:

public slots:

private:
    QTcpSocket *socket;
};

#endif // SOCKETTEST_H


==================================
============  sockettest.cpp  ============
==================================
#include "sockettest.h"

SocketTest::SocketTest(QObject *parent) : QObject(parent)
{

}

void SocketTest::Connect(){
    socket = new QTcpSocket(this);

    socket->connectToHost("10.0.0.227", 1234);
    if(socket->waitForConnected(3000)){
        qDebug() << "Connected";
        socket->write("hello server\r\n\r\n");
        socket->waitForBytesWritten(1000);
        socket->waitForReadyRead(3000);
        qDebug() << "Reading" << socket->bytesAvailable();
        qDebug() << socket->readAll();
        socket->close();
    }
    else{
        qDebug() << "Not connected.";
    }
}

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

tcp client using signal and slot

เพื่อให้เราไม่พลาดการสื่อสาร จำเป็นต้องใช้ signal and slot


========================================
============== signalSocket.pro ===============
========================================QT -= gui
QT += network

CONFIG += c++11 console
CONFIG -= app_bundle

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp \
    sockettest.cpp

HEADERS += \
    sockettest.h

target.path = /home/pi/Pump
INSTALLS += target



========================================
================ main.cpp =================
========================================#include <QCoreApplication>
#include <sockettest.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    SocketTest mTest;
    mTest.Test();

    return a.exec();
}


========================================
=============== sockettest.h =================
========================================#ifndef SOCKETTEST_H
#define SOCKETTEST_H

#include <QObject>
#include <QDebug>
#include <QTcpSocket>
#include <QAbstractSocket>

class SocketTest : public QObject
{
    Q_OBJECT
public:
    explicit SocketTest(QObject *parent = nullptr);
    void Test();

signals:

public slots:
    void connected();
    void disconnected();
    void bytesWritten (qint64 bytes);
    void readyRead();

private:
    QTcpSocket *socket;
};

#endif // SOCKETTEST_H




========================================
============== sockettest.cpp =================
========================================
#include "sockettest.h"

SocketTest::SocketTest(QObject *parent) : QObject(parent)
{

}

void SocketTest::Test(){
    socket = new QTcpSocket(this);
    connect(socket,SIGNAL(connected()),this,SLOT(connected()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()));
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));
    connect(socket,SIGNAL(bytesWritten(qint64)),this,SLOT(bytesWritten(qint64)));

    qDebug() << "Connecting...";
    //socket->connectToHost("voidrealms.com",80);
    socket->connectToHost("10.0.0.227",1234);
    if(!socket->waitForConnected(1000)){
        qDebug() << "Error " << socket->errorString();
    }
}

void SocketTest::connected()
{
    qDebug() << "Connected";
}

void SocketTest::disconnected()
{
    qDebug() << "Disconnected";
    socket->close();
}

void SocketTest::bytesWritten (qint64 bytes)
{
    qDebug() << "we wrote: " << bytes;
}

void SocketTest::readyRead()
{
    qDebug() << "Reading...";
    qDebug() << socket->readAll();
}

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

linux telnet

เราเขียนโปรแกรม server แล้ว เราก็ต้องทดสอบด้วย client
ซึ่งถ้าเรายังไม่มีโปรแกรม client เราก็ต้องใช้ telnet
ซึ่งใน linux มีติดตั้ง telnet ให้อยู่แล้ว เราสามารถใช้ได้เลย
วิธีการใช้ คือ
tenet x.x.x.x abcd
โดย x.x.x.x คือ ip ของ server
abcd คือ port ที่ใช้ในการสื่อสาร

ยกตัวอย่างว่า server ของเรามี ip = 10.0.0.227 และเปิด port 1234 ไว้สำหรับสื่อสาร
ดังนั้นเวลาที่เราจะใช้ telnet ที่เครื่อง client เราก็ต้องพิมพ์ telnet 10.0.0.227 1234
หรือเราจะแทนด้วยชื่อก็ได้ ยกตัวอย่างเช่น google.com 80

หา ip ของ raspberrypi

วันนี้ได้อ่านบทความของ inex
https://onedrive.live.com/view.aspx?resid=4142DB2998C8B0BD!46607&ithint=file%2cpptx&app=PowerPoint&authkey=!ADmc4oR3YQ4YSFs

มีวิธีหา ip ของ raspberry pi แบบง่ายๆ มาฝากกัน

download program angryipscan จาก http://angryip.org/download/#windows
แล้วก็เปิดเลยครับ กด start ก็จะรู้เลยว่ามี raspberrypi ของเราอยู่ที่ ip อะไร

การใช้ crontab

crontab คือ การตั้งเวลาสำหรับเรียกใช้โปรแกรมอะไรก็ได้ ตามระยะเวลาที่ตั้งไว้ ยกตัวอย่างเช่น ต้องการ backup file ทุกๆ 1 วัน ก็ตั้ง crontab ให้ backup file ทุกๆ 1 วัน

โดยการเรียกใช้งาน ทำดังนี้

crontab -e

จะมีข้อความขึ้นมาให้เราเลือกว่า เราจะใช้ editor อะไร ตัวผมถนัด nano ก็เลือก nano

เมื่อ editor เด้งขึ้นมา ก็ให้เราเพิ่มคำสั่งเข้าไป

โดยมีรูปแบบการคำสั่ง ดังนี้

# * * * * *  command to execute
# ┬ ┬ ┬ ┬ ┬
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ └───── day of week (0 - 7) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
# │ │ │ └────────── month (1 - 12)
# │ │ └─────────────── day of month (1 - 31)
# │ └──────────────────── hour (0 - 23)
# └───────────────────────── min (0 - 59)
 
ถ้าเราต้องการ backup data ทุกวัน ก็เขียนคำสั่ง ดังนี้
0 0 * * * /home/pi/backup.sh
 
ถ้าเราต้องการดูว่าใน crontab ทำอะไรบ้าง ให้พิมพ์
crontab -l
 
ถ้าเราต้องการรัน script อะไรสักอย่างตอน reboot ให้พิมพ์
@reboot python /home/pi/myScript.py