2022年5月22日 星期日

Tinker Board 2S GPIO Input/Output Sample

Tinker Board 2S 的Image檔已經有GPIO SDK不用另外下載。

Python 安裝方法如下:

cd /usr/local/share/gpio_lib_python_rk3399

sudo python setup.py install

sudo python3 setup.py install


以下目錄有範例程式:

cd /usr/local/share/gpio_lib_python_rk3399/test/ 

(PS. 一開始我下載到Tinker Board的Library,就會出現錯誤訊息)


Tinker Board GPIO  PIN說明:



目前測試起來跟樹莓派的語法相同:

測試一個3PIN搖頭開關輸入

import ASUS.GPIO as GPIO
import time

#關閉警示
GPIO.setwarnings(False)
#設定Pin No為BOARD
GPIO.setmode(GPIO.BOARD)
#宣告Input Pin
inPort=3
GPIO.setup(inPort,GPIO.IN)
GPIO.add_event_detect(inPort, GPIO.BOTH)
#宣告一個 GND Pin
lowGnd=5
GPIO.setup(lowGnd,GPIO.OUT)
GPIO.output(lowGnd,GPIO.LOW)

#偵測Input迴圈
while True:
if GPIO.event_detected(inPort):
inputVal=GPIO.input(inPort)
print('Val:'+str(inputVal))
else:
print ('--')
time.sleep(0.5)




測試LED閃爍

import ASUS.GPIO as GPIO
import time

#關閉警示
GPIO.setwarnings(False)
#設定Pin No為BOARD
GPIO.setmode(GPIO.BOARD)
#宣告LED PIN
lightP=32
GPIO.setup(lightP,GPIO.OUT)

#開關LED迴圈
while True:
GPIO.output(lightP,GPIO.HIGH)
time.sleep(1)
GPIO.output(lightP,GPIO.LOW)
time.sleep(1)



2022年5月17日 星期二

Tinker Board S2 初始安裝

相較於數莓派 我覺得稍微麻煩一點,爬了些文才完成遠端。

我是買有emmc的版本,設定步驟如下:

1) 用USB type C傳輸線連接tinker board與PC。

2) 板子接上12V的電 (坦白說12V的電讓我顧慮蠻久的,不能用GPIO供電整合其他控制元件上就稍嫌麻煩) 

3) 這時電腦應該會出現找到新的儲存設備(可能還會跳出要求要格式化的提醒)

4) 下載Tinker Board S2 img檔解壓縮(我是下載Debian版本)

5) 下載etcher 載完後安裝;然後選擇img檔,再選擇儲存設備,就可以開始燒錄了。

6) 燒錄完成後,移除USB線。

7) 因為還不能遠端,所以Tiker Board要接上螢幕、鍵盤、滑鼠(我接上螢幕後還沒有畫面,是拔掉電源重新啟動後,螢幕才出現畫面)。


1) 若已接上有線網路,應該可以在preference/ Advance Network Configuration 中看到;

    無線網路設定也可以在這各視窗進行,設定時需要 預設帳號/密碼 (linaro/linaro)

2) 接著啟動LXTerminal查看ip: sudo ifconfig


這樣就完成初步設定,可以進行遠端設定


2022年5月16日 星期一

Flask 網頁 透過下拉選單(select) 顯示不同圖片

還在摸索Flask中,感覺比較大的好處是直接就包含web Server了,

不用另外設定(Ngix, Apache..)。

不太確定有沒有前後端分離的概念,目前測試感覺都是由Flask包好再傳到前端,

速度似乎稍微慢一點。(也有可能是我還不會設定...)


範例程式:

從localhost:8080/ 頁面中的下拉選擇圖片並按下送出後,

進入另一個頁面顯示所選擇的圖片。

由於想要在顯示圖片時,也顯示下拉選單中的圖片名稱,

但不知道Python如何顯示,所以使用Jquery將選單文字加到隱藏欄位,

用Post表單的方式將文字帶出來。



Flask程式目錄下有:

- templete資料夾: 存放html檔案

- static資料夾:存放CSS、圖片、JS檔案...

- 其他就是python檔 


檔案如下:

- python檔sample.py

- 首頁 index.html(存在template中)

- 圖片頁 showImg.html(存在template中)

- CSS檔 sample.css(存在static/css中)

- 圖片檔 sample.css(存在static/images中 請自行找圖喔)

- 另外還有JQuery檔(請自行下載)


python檔: sample.py

PS. 安裝Flask (pip install flask)

from flask import render_template (存取template html資料)

from flask import request (若有透過POST, GET 傳值 則需要request)



import time
import flask
from flask import render_template
from flask import request
import netFunc

#--Flask
app = flask.Flask(__name__)

#首頁路徑Function
@app.route('/')
def index():
    #下拉選單的資料
    imgs=[
        {'val':'cat','text':'貓'},
        {'val':'flower','text':'花'},
        {'val':'rabit','text':'兔子'}
    ]
    #顯示為template中的index.html
    return render_template('index.html',**locals())

#當路徑為submit時,執行的function
@app.route('/p', methods=['POST'])
def showImg():
    #取得圖片選單的value,並加上完整路徑
    imgName=request.values['imgPick']
    imgurl='./images/'+imgName+'.jpg'
    #取得隱藏欄位的value
    imgText=request.values['tmptext']
    return render_template('showImg.html',**locals())


if __name__=='__main__':
    ip='localhost'
    app.run(host=ip,port=8080,debug=True)



首頁 index.html

<!DOCTYPE html>
<html lang='zh-TW'>
<head>
      <meta charset="utf-8" />
      <title>This Sample Page</title>
      <link type="text/css" rel="stylesheet"
          href="{{ url_for('static',filename='css/sample.css')}}" />
      <script src="{{url_for('static',filename='js/jquery-3.5.1.min.js')}}" ></script>
</head>
<body>
      <!--建立POST 方法的表單,並在送出後,將路徑加上submit-->
      <form method="post" action="/p">
            <label>選擇圖片</label>
            <div id="func">
                  <select id="picker" name="imgPick" onchange="getSelect()">
                        {% for i in imgs %}
                        <option value={{i.val}} >{{i.text}}</option>
                        {% endfor %}
                  </select>
                  <!--透過隱藏的欄位記錄選項文字-->
                  <input type="text" name="tmptext" id="tmptext" style="display:none ;"></input>
                  <button type="submit">確認</button>
            </div>
           
      </form>

</body>
</html>

<script>
      //一進入頁面就先取得選單文字並帶入表單tmptext
      $(document).ready(function(){
            selectText=$('#picker').find(':selected').text()
            $('#tmptext').val(selectText)
      })

      //透過JS取得選擇的選項文字
      function getSelect(){
            selectText=$('#picker').find(':selected').text()
            $('#tmptext').val(selectText)
      }
</script>


圖片頁 showImg.html

<!DOCTYPE html>
<html lang='zh-TW'>
<head>
      <meta charset="utf-8" />
      <title>This Sample Page</title>
      <link type="text/css" rel="stylesheet"
          href="{{ url_for('static',filename='css/sample.css')}}" />
      <script src="{{url_for('static',filename='js/jquery-3.5.1.min.js')}}" ></script>
</head>
<body>
    <div id="show">
    <a href="/">回前頁</a>
        <label >所選擇圖片為-{{imgText}}</label>
        <!--圖片會根據Python回傳得imgurl顯示-->
        <img src="{{url_for('static',filename=imgurl)}}" />
    </div>

</body>
</html>


CSS檔 sample.css


form{
    display: block;
    width: 50%;
    height: auto;
    margin: 1px auto;
    padding: 10px;
}

#func{
    margin-top: 10px;
}
label{
    font-size: 18pt;
    color: rgb(3, 84, 84);
    margin: 10px;
}

#picker{
    color: rgb(133, 50, 6);
    font-size: 14pt;
}

button{
    background-color: rgb(3, 84, 84);
    color: white;
}
#show{
    display: block;
    width: 50%;
    height: auto;
    margin: 1px auto;
    padding: 10px;
    margin-top: 10px;
    margin-bottom: 10px;
}
#show a{
    display: block;
    width: 80px;
    line-height: 30px;
    font-size: 14pt;
    text-decoration: none;
    background-color: rgb(200,210,220);
    color: rgb(80,80,80);
    border-radius: 5px;
    text-align: center;
}
#show a:hover{
    background-color: rgb(129, 168, 160);
    color: white;
    border-radius: 5px;
}
#show label{
    margin-top: 10px;
    margin-bottom: 10px;
}
img{
    margin: 10px;
}



2022年5月12日 星期四

JS取得Select選單的值與文字+onchange事件

 下拉選單html sample:

    <select id='fruit' onchange='getInfo(this)'>

            <option value=apple>Apple</option>

            <option value=banana>Banana</option>

            <option value=lemon>Lemon</option>

        </select>


Jquery取得Value:

    $('#fruit').val()

Jquery取得選取的文字:

    $('#fruit').find(':selected').text()


當選單變更選項時觸發事件範例如下:

<html lang="zh-TW">
<head>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<!--取得Selecet資料Function-->
<script>
function getInfo(){
fruit=$('#fruit').val()
fruitName=$('#fruit').find(':selected').text()
showInfo='Val:'+fruit+'|Name:'+fruitName
$('#info').text(showInfo)
}
</script>
</head>
<body>
<!--Select Sample-->
<select id='fruit' onchange='getInfo()'>
<option value=''>-Choose One-</option>
<option value=apple>Apple</option>
<option value=banana>Banana</option>
<option value=lemon>Lemon</option>
</select>
<div>
<label>Info:</label>
<label id='info'></label>
</div>
</body>
</html>



MySQL 移除重複資料

資料表[data]欄位: [id] [A欄][B欄] [C欄][D欄]

當有多筆資料的A, B, C三個欄位相同時,只保留一筆的語法。


原本以為用用A, B, C 三個欄位group by ,找出count > 1的資料即為重複的所有資料筆數。

語法:

SELECT *

FROM data

GROUP BY A, B, C

HAVING count(id)  > 1


但是發現這樣找出來的資料僅顯示一筆資料,其他筆數不會顯示。

例如: 

[1][蘋果][日本][50g][0210]

[2][香蕉][台灣][500g][0220]

[3][蘋果][日本][50g][0310]

[4][蘋果][日本][50g][0410]

[5][香蕉][台灣][500g][0310]


以上五筆資料,透過上述語法查詢 結果如下:

[1][蘋果][日本][50g][0210]

[2][香蕉][台灣][500g][0220]


這個結果反而是重複筆數中要保留的資料!

另外要保留的是,不重複的資料,也就是只有一筆的資料

語法:

SELECT *

FROM data

GROUP BY A, B, C

HAVING count(id)  = 1


因此兩種結果是要保留的,因此就是排除以上兩種結果的資料,

剩下的就是要刪除的,可先用Select選出來檢查。

SELECT * FROM data

WHERE 

id NOT IN 

( SELECT id FROM data GROUP BY A, B, C HAVING count(id) > 1 ) 

AND

id NOT IN 

( SELECT id FROM data GROUP BY A, B, C HAVING count(id) = 1 )


確認以上篩選出的結果是要刪除得,再把SELECT改成DELETE就可以了。


---------------------------------------------------------------------------------

篩選出某個欄位重複值的資料

SELECT * FROM table WHERE colName IN (SELECT colName FROM table GROUP BY colName HAVING count(colName ) > 1) ORDER BY colName 


2022年3月30日 星期三

Ubuntu Crontab 排程執行設定

輸入sudo crontab -e
進入如下crontab 設定畫面

下例設定為每天17點執行 launcher.sh 這個檔案,並將執行紀錄寫入 /logs/cronlog.txt 
00 17 * * * sudo sh /home/ubuntu/launcher.sh > home/ubuntu/logs/cronlog.txt 2>&1


設定參數為 mm hh dom (day of month) mom(month) dow(day of week),
若要設定每週一的17:30分執行,則如下: 
30 17 * * 1 sudo .....
可貼到這個crontab grur進行確認。

檢視crontab 是否執行
輸入:
grep CRON /var/log/syslog*

查看所設定時間點的動作,如下圖:
在4:00:01 出現(CRON) info (No MTA installed, discarding output)

查看原設定的logs/檔案不存在,因此檢查cronlog的設定是否正常。
sudo nano /etc/rsyslog.d/50-default.conf
- 移除cron.log 前面的註解


重新啟動syslog服務
sudo /etc/init.d/rsyslog restart
重新啟動cron服務
sudo service cron restart

2021年1月5日 星期二

數莓派 遠端連線固定IP設定

網路設定檔案路徑: /etc/dhcpcd.conf 

打開檔案後可以看到如下範例的段落:

# Example static IP configuration:

#interface eth0

interface eth0

static ip_address=192.168.2.188

#static ip_address=192.168.0.10/24

#static ip6_address=fd51:42f8:caae:d92e::ff/64

#static routers=192.168.0.1

#static domain_name_servers=192.168.0.1 8.8.8.8 fd51:42f8:caae:d92e::1


interface eth0 指的是有線網路卡

static ip_address=192.168.xx.xx 就根據要連線的電腦網段去設定。


例如我要連線的電腦網段是192.168.2.xx,就將數莓派有線網路卡IP設為192.168.2.188;

後續樹莓派只要連上網路線,其他電腦就可以直接ssh或VNC這個IP連到數莓派了。


若要設定的是無線網路IP,就將eth0 改為wlan0。

但若會使用多個無線網路,例如:家裡、辦公室、手機網路,可能就會發生IP衝突或網段不同的問題。


*查看數莓派目前網路參數

$sudo ifconfig


安裝windows 遠端桌面

sudo apt-get -y install xrdp