วันนี้ขอนอกเรื่อง 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 ดูว่าข้อมูลที่รับได้ เป็นอย่างไรบ้าง
blog นี้จะกล่าวถึง Raspberry Pi Raspbian เป็นหลัก โดยจะอธิบายทั้งการใช้ windows และ Linux ในการเชื่อมต่อ วิธีอ่าน : ให้เริ่มอ่านตั้งแต่หัวข้อแรกๆขึ้นมา(ให้ดูที่ "คลังบทความ" ทางด้านขวามือ จะมี วัน-เวลา ไล่เรียงอยู่) ไม่งั้นอาจจะงงได้ สำหรับมือใหม่ หรือท่านใดที่ไม่เข้าใจ สามารถ mail มาถามกันได้ครับ ที่ kongimi1980@gmail.com หรือที่ line : 0814282425
วันอาทิตย์ที่ 11 พฤศจิกายน พ.ศ. 2561
วันพุธที่ 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
================================
========= 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
========== 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
========================================
============== 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
ซึ่งถ้าเรายังไม่มีโปรแกรม 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 อะไร
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 เด้งขึ้นมา ก็ให้เราเพิ่มคำสั่งเข้าไป
โดยมีรูปแบบการคำสั่ง ดังนี้
โดยการเรียกใช้งาน ทำดังนี้
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
ติดตั้ง nodejs, nodered, mqtt broker, mongodb บน rpi
ติดตั้ง node js
1. sudo apt-get update
2. ให้ไป download Linux Binaries (ARM) จากที่นี่มา https://nodejs.org/en/download/ ให้เลือกให้ตรงกับ rpi ของเราว่าเป็น ARM รุ่นไหน สามารถทดสอบได้โดยพิมพ์ uname -m ใน rpi
ในกรณีของผม เป็น ARMv6 download file ลงมาเป็นชื่อ node-v8.12.0-linux-armv6l.tar.xz
3. copy file ไว้ใน rpi
4. แตก file โดยใช้คำสั่ง tar -xvf node-v8.12.0-linux-armv6l.tar.xz
5. cd node-v8.12.0-linux-armv6l
6. sudo cp -R * /usr/local/
7. node --version เพื่อดู version
8. npm --version เพื่อดู version
9. sudo apt-get install -y nodejs
ติดตั้ง node red
1. sudo npm install -g --unsafe-perm node-red
2. sudo npm install -g node-red-admin
3. พิมพ์ node-red เพื่อ start node red, ให้ลองเปิด browser แล้วใส่ ip:1880 ต้องเข้า node red ได้
ทำ auto start เมื่อ boot
1. nano nodered.service
2. ใส่ข้อความต่อไปนี้ลงไป
3. save แล้วปิด
4. sudo cp nodered.service /etc/systemd/system/nodered.service
5. sudo systemctl enable nodered.service
6. sudo systemctl daemon-reload
7. sudo systemctl start nodered.service
8. sudo systemctl status nodered.service ต้องไม่มี Error
ป้องกัน node red จากคนอื่น ด้วยการทำ Authentication
1. node-red-admin hash-pw ให้ใส่ password ลงไป มันจะสร้างชุดข้อมูลมาชุดนึง ให้ copy ไว้
2. nano .node-red/settings.js ให้หาคำว่า adminAuth แล้ว uncomment ออกทั้งชุดปีกกา, แล้วใส่ password ใหม่ลงไป
adminAuth: {
type: "credentials",
users: [{
username: "admin",
password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
permissions: "*"
}]
},
3. sudo service nodered stop
4. sudo service nodered start
5.ให้เปิด browser แล้วเข้า localhost:1880 คราวนี้จะมีการให้ใส่ user name และ password
ให้ใส่ user name = amin และ password ตามที่เราตั้งไว้
6.ติดตั้ง dashboard, npm install node-red-dashboard
(https://www.youtube.com/watch?v=RA06ee3jahM )
ติดตั้ง mqtt broker
1. sudo apt-get install mosquitto mosquitto-clients
2. sudo mosquitto_passwd -c /etc/mosquitto/passwd pi
3. ใส่ password ลงไป
4. sudo nano /etc/mosquitto/conf.d/default.conf
5. ใส่ข้อความต่อไปนี้ลงไป
allow_anonymous false
password_file /etc/mosquitto/passwd
6. sudo systemctl restart mosquitto
7.ทดสอบ โดยเปิด terminal แล้วพิมพ์
mosquitto_sub -t "test" -u "pi" -P "passwdที่เราตั้งไว้"
8.แล้วเปิด terminal อีกอันขึ้นมาใหม่ พิมพ์
mosquitto_pub -t "test" -u "pi" -P "passwdที่เราตั้งไว้" -m "hello world"
จะเห็นข้อความที่ส่งจาก pub ไปที่ sub ว่า "hello world"
ติดตั้ง mongoDB
1. sudo apt-get install mongodb-server
2. sudo service mongodb start
ทำให้ node red รู้จัก mongodb
1. cd ~/.node-red/
2. sudo npm install node-red-node-mongodb
3. sudo service mongodb stop
4. sudo service mongodb start
5. sudo service nodered stop
6. sudo service nodered start
ถ้าต้องการใช้งาน gpio ของ rpi ให้ทำดังนี้
ไปที่ manage palette
เลือก tap install
ให้พิมพ์ gpio แล้วกด istall ที่ตัว node-red-node-pi-gpio
1. sudo apt-get update
2. ให้ไป download Linux Binaries (ARM) จากที่นี่มา https://nodejs.org/en/download/ ให้เลือกให้ตรงกับ rpi ของเราว่าเป็น ARM รุ่นไหน สามารถทดสอบได้โดยพิมพ์ uname -m ใน rpi
ในกรณีของผม เป็น ARMv6 download file ลงมาเป็นชื่อ node-v8.12.0-linux-armv6l.tar.xz
3. copy file ไว้ใน rpi
4. แตก file โดยใช้คำสั่ง tar -xvf node-v8.12.0-linux-armv6l.tar.xz
5. cd node-v8.12.0-linux-armv6l
6. sudo cp -R * /usr/local/
7. node --version เพื่อดู version
8. npm --version เพื่อดู version
9. sudo apt-get install -y nodejs
ติดตั้ง node red
1. sudo npm install -g --unsafe-perm node-red
2. sudo npm install -g node-red-admin
3. พิมพ์ node-red เพื่อ start node red, ให้ลองเปิด browser แล้วใส่ ip:1880 ต้องเข้า node red ได้
ทำ auto start เมื่อ boot
1. nano nodered.service
2. ใส่ข้อความต่อไปนี้ลงไป
[Unit]
Description=My service
After=network.target
[Service]
ExecStart=/usr/bin/env node-red-pi $NODE_OPTIONS $NODE_RED_OPTIONS
WorkingDirectory=/home/pi
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi
[Install]
WantedBy=multi-user.target
3. save แล้วปิด
4. sudo cp nodered.service /etc/systemd/system/nodered.service
5. sudo systemctl enable nodered.service
6. sudo systemctl daemon-reload
7. sudo systemctl start nodered.service
8. sudo systemctl status nodered.service ต้องไม่มี Error
ป้องกัน node red จากคนอื่น ด้วยการทำ Authentication
1. node-red-admin hash-pw ให้ใส่ password ลงไป มันจะสร้างชุดข้อมูลมาชุดนึง ให้ copy ไว้
2. nano .node-red/settings.js ให้หาคำว่า adminAuth แล้ว uncomment ออกทั้งชุดปีกกา, แล้วใส่ password ใหม่ลงไป
adminAuth: {
type: "credentials",
users: [{
username: "admin",
password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
permissions: "*"
}]
},
3. sudo service nodered stop
4. sudo service nodered start
5.ให้เปิด browser แล้วเข้า localhost:1880 คราวนี้จะมีการให้ใส่ user name และ password
ให้ใส่ user name = amin และ password ตามที่เราตั้งไว้
6.ติดตั้ง dashboard, npm install node-red-dashboard
(https://www.youtube.com/watch?v=RA06ee3jahM )
ติดตั้ง mqtt broker
1. sudo apt-get install mosquitto mosquitto-clients
2. sudo mosquitto_passwd -c /etc/mosquitto/passwd pi
3. ใส่ password ลงไป
4. sudo nano /etc/mosquitto/conf.d/default.conf
5. ใส่ข้อความต่อไปนี้ลงไป
allow_anonymous false
password_file /etc/mosquitto/passwd
6. sudo systemctl restart mosquitto
7.ทดสอบ โดยเปิด terminal แล้วพิมพ์
mosquitto_sub -t "test" -u "pi" -P "passwdที่เราตั้งไว้"
8.แล้วเปิด terminal อีกอันขึ้นมาใหม่ พิมพ์
mosquitto_pub -t "test" -u "pi" -P "passwdที่เราตั้งไว้" -m "hello world"
จะเห็นข้อความที่ส่งจาก pub ไปที่ sub ว่า "hello world"
ติดตั้ง mongoDB
1. sudo apt-get install mongodb-server
2. sudo service mongodb start
ทำให้ node red รู้จัก mongodb
1. cd ~/.node-red/
2. sudo npm install node-red-node-mongodb
3. sudo service mongodb stop
4. sudo service mongodb start
5. sudo service nodered stop
6. sudo service nodered start
ถ้าต้องการใช้งาน gpio ของ rpi ให้ทำดังนี้
ไปที่ manage palette
เลือก tap install
ให้พิมพ์ gpio แล้วกด istall ที่ตัว node-red-node-pi-gpio
วันพฤหัสบดีที่ 12 กรกฎาคม พ.ศ. 2561
qt load font
เนื่องจากลูกค้าต้องการให้ใช้ font สวยๆ ตามที่เขาต้องการ จึงต้องทำการ load font ขึ้นมาใช้
ในตอนแรกเขียน code แบบนี้
QFont myFont("font1name", 30);
ซึ่งก็ใช้ได้ผลดี ในตอนทดสอบ, โดยการเรียกจาก Terminal (./myApp -platform xcb)
แต่... หลังจากที่ทดลอง restart rpi แล้ว และโปรแกรมถูกเรียกโดยสคริปท์ autorun ปรากฎว่า font ที่เราโหลดไว้ ไม่ยอมแสดง, แสดงเป็น font อื่นซะงั้น
จึงได้ไปลอง post ถามในกลุ่ม raspberry pi thailand ดู ซึ่งก็ได้คนใจดี มาช่วยตอบคำถามให้ โดยบอกว่าให้ลองใช้ QFontDatabase และ copy font ไปไว้ใน folder เดียวกันกับ Application ของเรา
ก็เลยไปค้นหาดูว่า QFontDatabase เขาใช้กันยังไง ก็ได้มาแบบนี้
#include <QFontDatabase>
.
.
.
QString myFont;
int loadedFontID = QFontDatabase::addApplicationFont("./fontFile.ttf");
QStringList loadedFontFamilies = QFontDatabase::applicationFontFamilies(loadedFontID);
if(!loadedFontFamilies.empty())
myFont = loadedFontFamilies.at(0);
QFont P(myFont, 90, QFont::Normal, false);
myLabel->setFont(P);
ก็ลองทดสอบ reboot ดู Font ก็แสดงออกมาได้อย่างถูกต้อง
ต้องขอขอบคุณผู้มีน้ำใจช่วยเหลือ ถึงแม้ว่าจะไม่รู้จักกันมาก่อนก็ตามที
ในตอนแรกเขียน code แบบนี้
QFont myFont("font1name", 30);
ซึ่งก็ใช้ได้ผลดี ในตอนทดสอบ, โดยการเรียกจาก Terminal (./myApp -platform xcb)
แต่... หลังจากที่ทดลอง restart rpi แล้ว และโปรแกรมถูกเรียกโดยสคริปท์ autorun ปรากฎว่า font ที่เราโหลดไว้ ไม่ยอมแสดง, แสดงเป็น font อื่นซะงั้น
จึงได้ไปลอง post ถามในกลุ่ม raspberry pi thailand ดู ซึ่งก็ได้คนใจดี มาช่วยตอบคำถามให้ โดยบอกว่าให้ลองใช้ QFontDatabase และ copy font ไปไว้ใน folder เดียวกันกับ Application ของเรา
ก็เลยไปค้นหาดูว่า QFontDatabase เขาใช้กันยังไง ก็ได้มาแบบนี้
#include <QFontDatabase>
.
.
.
QString myFont;
int loadedFontID = QFontDatabase::addApplicationFont("./fontFile.ttf");
QStringList loadedFontFamilies = QFontDatabase::applicationFontFamilies(loadedFontID);
if(!loadedFontFamilies.empty())
myFont = loadedFontFamilies.at(0);
QFont P(myFont, 90, QFont::Normal, false);
myLabel->setFont(P);
ก็ลองทดสอบ reboot ดู Font ก็แสดงออกมาได้อย่างถูกต้อง
ต้องขอขอบคุณผู้มีน้ำใจช่วยเหลือ ถึงแม้ว่าจะไม่รู้จักกันมาก่อนก็ตามที
วันศุกร์ที่ 6 กรกฎาคม พ.ศ. 2561
php set max file size
ได้มีโอกาสทำเวป และได้ใช้ php
มีการใช้ upload file ด้วย ซึ่งตอนแรกไม่รู้ว่า php มีการจำกัดขนาดไฟล์ไว้ด้วย และไฟล์ที่เราจะ upload ก็ใหญ่ จึงทำยังไงก็ไม่ได้ จนมีคนมาบอก ถึงใช้งานได้
วิธีกำหนดขนาดไฟล์ ที่จะ upload ดังนี้
1.เข้าไปที่ /etc/php5/apache2/php.ini
2.ให้มองหาคำว่า post_max_size แล้วแก้ไขตัวเลข ขนาดไฟล์ตามต้องการ
ตัวเลขนี้ คือตัวเลขที่จะทำการ upload ใน 1 ครั้ง จะกี่ไฟล์ก็ได้ แต่ขนาดไฟล์รวมกันทั้งหมด ต้องไม่เกินที่เรากำหนด
3.ให้มองหาคำว่า upload_max_filesize
ตัวเลขนี้ คือขนาดของไฟล์ 1 ไฟล์ ที่ต้องการ upload
ถ้าเราจะ upload file หลายๆไฟล์ ก็ให้มองหาคำว่า max_file_uploads
แก้ไขเสร็จแล้ว ให้ Restart Rpi หรือ sudo /etc/init.d/apache2 restart
มีการใช้ upload file ด้วย ซึ่งตอนแรกไม่รู้ว่า php มีการจำกัดขนาดไฟล์ไว้ด้วย และไฟล์ที่เราจะ upload ก็ใหญ่ จึงทำยังไงก็ไม่ได้ จนมีคนมาบอก ถึงใช้งานได้
วิธีกำหนดขนาดไฟล์ ที่จะ upload ดังนี้
1.เข้าไปที่ /etc/php5/apache2/php.ini
2.ให้มองหาคำว่า post_max_size แล้วแก้ไขตัวเลข ขนาดไฟล์ตามต้องการ
ตัวเลขนี้ คือตัวเลขที่จะทำการ upload ใน 1 ครั้ง จะกี่ไฟล์ก็ได้ แต่ขนาดไฟล์รวมกันทั้งหมด ต้องไม่เกินที่เรากำหนด
3.ให้มองหาคำว่า upload_max_filesize
ตัวเลขนี้ คือขนาดของไฟล์ 1 ไฟล์ ที่ต้องการ upload
ถ้าเราจะ upload file หลายๆไฟล์ ก็ให้มองหาคำว่า max_file_uploads
แก้ไขเสร็จแล้ว ให้ Restart Rpi หรือ sudo /etc/init.d/apache2 restart
วันพุธที่ 20 มิถุนายน พ.ศ. 2561
autorun gui application
สวัสดีครับ เงียบหายกันไปนาน (เหมือนเคย)
ได้มีโอกาสทำ application ที่ต้องแสดงบนหน้าจอ ( GUI Application )
และต้อง auto run เมื่อเปิดขึ้นมาใหม่
วิธีการทำ auto run มีดังนี้
ได้มีโอกาสทำ application ที่ต้องแสดงบนหน้าจอ ( GUI Application )
และต้อง auto run เมื่อเปิดขึ้นมาใหม่
วิธีการทำ auto run มีดังนี้
sudo nano /home/pi/.config/lxsession/LXDE/autostart
หรือถ้าในนี้ไม่มี ก็อาจจะไปอยู่ที่
/etc/xdg/lxsession/LXDE-pi/autostart
และเพิ่มบรรทัดสุดท้ายเข้าไป ยกตัวอย่าง เช่น
โปรแกรมของเรา ชื่อ myApp อยู่ใน folder /home/pi/ ก็ให้เพิ่มเข้าไปดังนี้
@/home/pi/myApp
เสร็จแล้ว ง่ายๆ แต่หาให้เจอว่าทำยังไง มันยาก 555
ที่มา
http://www.raspberry-projects.com/pi/pi-operating-systems/raspbian/auto-running-programs-gui
https://learn.sparkfun.com/tutorials/how-to-run-a-raspberry-pi-program-on-startup/all
วันศุกร์ที่ 30 มีนาคม พ.ศ. 2561
LCD20*4 i2c c qt
วันนี้ได้มีโอกาศใช้งาน LCD20*4 กับภาษา C ก็เลยอยากกระจายความสะดวกให้คนที่ทำทีหลัง โดยการเอา source code มาวางให้ครับ
โดยผมใช้ ภาษา C Qt Creator cross-compile บน linux ubuntu16.04 กับ rpi-3b และต่อ LCD ด้วย I2C
//============== mylcd.h =================//
#ifndef MYLCD_H
#define MYLCD_H
#define I2C_ADDR_LCD1 0x26 // LCD I2C Address
#define LCD_CHR 1 // Mode sending data
#define LCD_CMD 0 // Mode sending command
#define LINE1 0x80 // 1st line
#define LINE2 0xc0 // 2nd line
#define LINE3 0x94 // 1st line
#define LINE4 0xd4 // 2nd line
#define LCD_BACKLIGHT 0x08 // on
//#define LCD_BACKLIGHT 0x00 // off
#define ENABLE 0b00000100 // enable bit
void typeInt(int i);
void typeFloat(float myFloat);
void lcdLoc(int line); // move cursor
void ClrLcd(void); // clr LCD return home
void typeln(const char *s);
void typeChar(char val);
void lcd_init(void);
void lcd_byte(int bits, int mode);
void lcd_toggle_enable(int bits);
int fd;
#endif // MYLCD_H
//============== main.c =================//
#include <QCoreApplication>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <stdlib.h>
#include <stdio.h>
#include <mylcd.h>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
if(wiringPiSetup()==-1){
qDebug() << "can't open wiring pi";
}
else
{
qDebug() << "open wiring pi!!!";
}
fd = wiringPiI2CSetup(I2C_ADDR_LCD1);
lcd_init();
char array1[] = "Hello world!";
while(1)
{
ClrLcd();
lcdLoc(LINE1);
typeln("Using wiringPi");
lcdLoc(LINE2);
typeln("Niran editor");
lcdLoc(LINE3);
typeln("I2c programmed");
lcdLoc(LINE4);
typeln("In C not python");
delay(2000);
ClrLcd();
lcdLoc(LINE1);
typeln(array1);
delay(2000);
ClrLcd();
typeln("Int ");
int value = 20125;
typeInt(value);
delay(2000);
lcdLoc(LINE2);
typeln("Float ");
float Floatvalue = 10045.25989;
typeFloat(Floatvalue);
}
return a.exec();
}
void typeln(const char *s){
while(*s){
lcd_byte(*(s++), LCD_CHR);
}
}
// float to string
void typeFloat(float myFloat){
char buffer[20];
sprintf(buffer,"%4.2f", myFloat);
typeln(buffer);
}
// int to string
void typeInt(int i){
char array1[20];
sprintf(array1,"%d", i);
typeln(array1);
}
void ClrLcd(void){
lcd_byte(0x01,LCD_CMD);
lcd_byte(0x02,LCD_CMD);
}
void lcdLoc(int line){
lcd_byte(line, LCD_CMD);
}
void typeChar(char val){
lcd_byte(val,LCD_CHR);
}
void lcd_byte(int bits, int mode){
int bits_high;
int bits_low;
bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT;
bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT;
wiringPiI2CReadReg8(fd,bits_high);
lcd_toggle_enable(bits_high);
wiringPiI2CReadReg8(fd,bits_low);
lcd_toggle_enable(bits_low);
}
void lcd_toggle_enable(int bits){
delay(10);
wiringPiI2CReadReg8(fd,(bits|ENABLE));
delay(10);
wiringPiI2CReadReg8(fd,(bits|~ENABLE));
delay(10);
}
void lcd_init(){
lcd_byte(0x33,LCD_CMD);
lcd_byte(0x32,LCD_CMD);
lcd_byte(0x06,LCD_CMD);
lcd_byte(0x0C,LCD_CMD);
lcd_byte(0x28,LCD_CMD);
lcd_byte(0x01,LCD_CMD);
delay(500);
}
โดยผมใช้ ภาษา C Qt Creator cross-compile บน linux ubuntu16.04 กับ rpi-3b และต่อ LCD ด้วย I2C
//============== mylcd.h =================//
#ifndef MYLCD_H
#define MYLCD_H
#define I2C_ADDR_LCD1 0x26 // LCD I2C Address
#define LCD_CHR 1 // Mode sending data
#define LCD_CMD 0 // Mode sending command
#define LINE1 0x80 // 1st line
#define LINE2 0xc0 // 2nd line
#define LINE3 0x94 // 1st line
#define LINE4 0xd4 // 2nd line
#define LCD_BACKLIGHT 0x08 // on
//#define LCD_BACKLIGHT 0x00 // off
#define ENABLE 0b00000100 // enable bit
void typeInt(int i);
void typeFloat(float myFloat);
void lcdLoc(int line); // move cursor
void ClrLcd(void); // clr LCD return home
void typeln(const char *s);
void typeChar(char val);
void lcd_init(void);
void lcd_byte(int bits, int mode);
void lcd_toggle_enable(int bits);
int fd;
#endif // MYLCD_H
//============== main.c =================//
#include <QCoreApplication>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <stdlib.h>
#include <stdio.h>
#include <mylcd.h>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
if(wiringPiSetup()==-1){
qDebug() << "can't open wiring pi";
}
else
{
qDebug() << "open wiring pi!!!";
}
fd = wiringPiI2CSetup(I2C_ADDR_LCD1);
lcd_init();
char array1[] = "Hello world!";
while(1)
{
ClrLcd();
lcdLoc(LINE1);
typeln("Using wiringPi");
lcdLoc(LINE2);
typeln("Niran editor");
lcdLoc(LINE3);
typeln("I2c programmed");
lcdLoc(LINE4);
typeln("In C not python");
delay(2000);
ClrLcd();
lcdLoc(LINE1);
typeln(array1);
delay(2000);
ClrLcd();
typeln("Int ");
int value = 20125;
typeInt(value);
delay(2000);
lcdLoc(LINE2);
typeln("Float ");
float Floatvalue = 10045.25989;
typeFloat(Floatvalue);
}
return a.exec();
}
void typeln(const char *s){
while(*s){
lcd_byte(*(s++), LCD_CHR);
}
}
// float to string
void typeFloat(float myFloat){
char buffer[20];
sprintf(buffer,"%4.2f", myFloat);
typeln(buffer);
}
// int to string
void typeInt(int i){
char array1[20];
sprintf(array1,"%d", i);
typeln(array1);
}
void ClrLcd(void){
lcd_byte(0x01,LCD_CMD);
lcd_byte(0x02,LCD_CMD);
}
void lcdLoc(int line){
lcd_byte(line, LCD_CMD);
}
void typeChar(char val){
lcd_byte(val,LCD_CHR);
}
void lcd_byte(int bits, int mode){
int bits_high;
int bits_low;
bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT;
bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT;
wiringPiI2CReadReg8(fd,bits_high);
lcd_toggle_enable(bits_high);
wiringPiI2CReadReg8(fd,bits_low);
lcd_toggle_enable(bits_low);
}
void lcd_toggle_enable(int bits){
delay(10);
wiringPiI2CReadReg8(fd,(bits|ENABLE));
delay(10);
wiringPiI2CReadReg8(fd,(bits|~ENABLE));
delay(10);
}
void lcd_init(){
lcd_byte(0x33,LCD_CMD);
lcd_byte(0x32,LCD_CMD);
lcd_byte(0x06,LCD_CMD);
lcd_byte(0x0C,LCD_CMD);
lcd_byte(0x28,LCD_CMD);
lcd_byte(0x01,LCD_CMD);
delay(500);
}
สมัครสมาชิก:
บทความ (Atom)