C 陣列

      在〈C 陣列〉中尚無留言

使用 Java 控製 GPIO 是個好選項,但近來 Java 已退出流行, Kotlin 及 Python 取而代之,所以使用 Python 控制樹莓派的 GPIO 變成重要的工具。

遠端開發

在 Linux 環境中開發程式,其實是蠻不智的選擇,尤其在只有文字介面的 Server 版本中,只能使用 vim 等編輯器撰寫程式。此法除了展現自已強大的程式功力外,我也想不出有任何益處,開發效率低,除錯煩鎖,純粹給自已找麻煩。

最佳的方式是在 Windows 上寫程式,然後直接在樹莓派上執行,這是最理想的開發環境。

Pycharm 是個不錯的選擇,但需要付費的 Professional 版本才支援 ssh 遠端控製。還好微軟的 VS Code 可以免費支援遠端控製。

Server & Client

在 Windows 撰寫程式,然後在 Linux 中執行,我們稱 Windows 為 Client(客戶端),Linux 為 Server(伺服器端)。

ssh 設定

Windows(Client) 建立 RSA key

ssh 預設使用明碼進行通訊,很容易被攔截,所以需建立 RSA 加密 key。

請先在 Windows (Client) 開啟 Terminal,輸入如下指令

ssh-keygen -t rsa

然後需要輸入的地方全都按 Enter 即可,如此 ssh 登入 Server 時就不用密碼了。

C:\Users\mahal>ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\mahal/.ssh/id_rsa): 直接按 Enter
Enter passphrase (empty for no passphrase): 直接按 Enter
Enter same passphrase again: 直接按 Enter
Your identification has been saved in C:\Users\mahal/.ssh/id_rsa.
Your public key has been saved in C:\Users\mahal/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:gIvlMBcIxCNejQr........... mahal@DESKTOP-1GN5AIU
The key's randomart image is:
+---[RSA 3072]----+
|^Xo==            |
|#*O+ =           |
|OBOo=..          |
|+=oB=...         |
|...+o. .S        |
|.   . . E        |
|       .         |
|                 |
|                 |
+----[SHA256]-----+

C:\Users\mahal>

Linux(Server)

將 C:\Users\登入帳號\.ssh\id_rsa.pub copy 到 Linux 家目錄下,然後輸入底下指令

cd
mkdir .ssh
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys

todo

VS Code 設定

在 VS Code 的 Extention 中查詢 remote,然後安裝 Remote – SSH。安裝時會在左方的工具列出現 Remote Explorer 圖示,表示安裝成功。

選取左邊的 Remote Explorer,再點選 SSH 的齒輸圖示,然後選取 C:\Users\xxx\.ssh\config

然後在 config 輸入如下

# Read more about SSH config files: https://linux.die.net/man/5/ssh_config
Host Linux #(Linux 名稱,自已指定)
    HostName 192.168.2.40 #(Linux ip)
    User thomas #(登入帳號)

退出 VS Code ,然後再重新進入 VS Code,就可以看到 Linux  的選項,選取 “->”  符號,就可以跟 Server 進行連線了。

操作 Linux

點選 Terminal 的 “+”,再選取 New Termianl,即可對 Linux 下執一般的指令。

建立虛擬環境

GPIO 所需的 gpiod 或 gpiozero 套件已安裝在系統中,但如果使用 python3 -m venv .venv 是無法把 這二個套件 copy 到虛擬環境中,需加上 –system-site-packages 參數,請在 Terminal 輸入如下指令。

cd
mkdir -p ./python/light
cd ./python/light
python3 -m venv --system-site-packages .venv

接下來 File/Open Folder,選取 ~/python/light,然後按下 Ctrl+Shift+P, 選取 interpreter,再選取  ./.venv/bin/python,開啟新的 Terminal 即可進入新的虛擬環境。

測試程式

在 VS Code 開啟新的 test.py 檔,代碼如下

#! /home/thomas/python/light/.venv/bin/python
print("hello")

Linux 下執行

這種方式是直接在 Linux 執行程式。請在 VS Code 的 Terminal 更改 test.py 的權限如下

chmod 755 ./test.py

進入 Linux 下,直接執行如下指令即可執行

cd ~/python/light
./test.py

Windows 下執行

在 Windows 下也可以直接下達執行指令,但請注意真正執行的機器是 Linux,執行後的結果再由 Linux  ssh 傳回 Windows 螢幕顯示。

安裝 GPIO套件

pi 5 Bookworm 控制 GPIO 有二個套件分別為 gpiod 及 gpiozero,系統已安裝完成,所以無需再手動安裝。經過實測,gpiozero 語法比較精簡且好用。

而早期 pi4 可以使用 RPI.GPIO 套件,但無法使用 pip 安裝在虛擬環境中,需使用 apt-get 安裝在系統環境中,指令如下。

sudo apt update
sudo apt install python3-rpi.gpio

硬体 GPIO 線路圖

樹莓派上有 40 根可以安插杜邦線的接腳,這是 GPIO 通用界面 (General Purpose Input/Output)。

各個接腳的 pin 腳編號及 GPIO 編號如下

請注意,以 pin 11 接腳而言,Python 定義它的 GPIO 編號為 17,但在 Java 則定義為 GPIO 0,完全依使用的語言自行定義的號碼。

為什麼要使用陣列

當大量同類型資料需要儲存時,就必需使用陣列

陣列宣告

int score[3]

超出範圍,會產生不可預期的當機

陣列初始值

int score[]={1,2,3,4,5};

int score[5]={0};

使用迴圈設定陣列

分別設定score, 使用for加總後算出平均值

一維陣列空間大小

sizeof(a) : 是算出整個陣列的大小

氣泡排序法

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void getData(int *);
void printData(int *);
void sort(int *);

int n=30000;
int main(){
	int *d=new int[n];
	getData(d);
	//printData(d);
	timespec t1, t2;
	clock_gettime(CLOCK_REALTIME, &t1);
	sort(d);
	clock_gettime(CLOCK_REALTIME, &t2);
	//printData(d);
	printf("總花費時間 : %0.3f 微秒", ((t2.tv_sec-t1.tv_sec)*1000000000+(t2.tv_nsec-t1.tv_nsec))/1000.0f);
}
void getData(int *d){
	srand(time(NULL));
	for (int i=0;i<n;i++){
		d[i]=rand();
	}
}
void printData(int *d){
	for (int i=0;i<n;i++){
		printf("%d ", d[i]);
	}
	printf("\n");
}
void sort(int *d){
	for (int i=0;i<=n-2;i++){
		for (int j=i+1;j<=n-1;j++){ if (d[i]>d[j]){
				int tmp=d[i];
				d[i]=d[j];
				d[j]=tmp;
			}
		}
	}
}

字元陣列

字元陣列類似字串,但字串最後會加入 \0, 用sizeof時 \0不會計算

宣告 :
char str[]={‘h’, ‘e’,’l’,’l’,’o’};
char str[]=”123456″;ç自動加  \0, 總長度是7
printf(“%s\n”,str);ç不用使用c_str(),因為char是基本型態,沒有c_str的函數
用此方法後,str=”abcd”會錯誤,
需使用strcpy(str, “123456”),此需include <string.h>
string a=”abcd”;
printf(“%s\n”, a.c_str()); çstring需使用c_str()轉成字元陣列。%s是印字元陣列

中文字元陣列

char str[]=”這是abc”; strlen(str)的結果是7, 取出中文字時,一定要取2byte, 不然會變成亂碼
中英文混雜時,就要先判斷char 是否大於127, 若是的話,就是中文,需再緊接取第二個字元
char str[]=”這是abc”;

   for(int i=0;i<strlen(str);i++){
      if((int)str[i]<0){
         printf("%c%c\n", str[i], str[i+1]);
         i++;
      }
      else{
         printf("%c\n", str[i]);
      }
   }

多維陣列宣告

int score[500][11], 共500列,11行

int t[5][4]={0};
   for (int i=0;i<5;i++){
      for (int j=0;j<4;j++){
         printf("%d ", t[i][j]);
      }
      printf("\n");
   }

二維字元陣列

char s[3][5]={“abcd”, “efgh”,”ijkl”}; ç3可以省略,但5絕對不能省

   for (int i=0;i<3;i++){
      printf("%s\n", s[i]);
   }

由此說明每個字串長度都一樣,所以需要指標

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *