如何在masOS安裝Google Gemini CLI

作者:順哥

email:palmbear@gmail.com

參考資料 1:Gemini CLI GitHub,https://github.com/google-gemini/gemini-cli

參考資料 2:【Gemini CLI 安裝/使用教學】Mac版|程式安裝+指令大補帖,https://www.youtube.com/watch?v=AO2tuyNFXkEGemini

參考資料 3:CLI 橫空出世 | 不只免費,軟體還開源 | 完整安裝 可呼叫Google Search,https://www.youtube.com/watch?v=ws1ee6aKB7Q

一、簡介

Gemini CLI 是一款基於 Gemini AI 技術的命令列工具,支持繁體中文輸入與輸出,方便用戶在終端環境中快速進行自然語言交互。它能處理繁體中文的文本生成、問題回答、文本摘要和翻譯等功能,操作簡潔直觀,適合開發者和專業用戶用於自動化腳本、資料處理及快速查詢。

二、安裝環境

1. Macbook pro M1
2. macOS 15.6.1
3. brew
4. node.js

三、參考Gemini CLI GitHub及各「參考資料」,實際的安裝程序如下:

  1. 步驟一:打開終端機,安裝 Gemini CLI1

使用 brew 直接安裝:`brew install gemini-cli`

2. 步驟二:執行 Gemini CLI

安裝完成後,輸入 `gemini` 直接執行 Gemini CLI ,會出現下圖:

3. 步驟三:登入 Gemini CLI

我使用第一種方法,就是使用Google 帳號登入,最簡單。

(使用上下鍵可以在選項中移動,按下 “Enter" 鍵,選擇)

登入後就可以直接使用了。

三、問題

執行Gemini CLI後,出現這段文字,指的是「你現在是在"home"目錄下執行Gemini CLI,推薦在『特定專案』目錄下執行Gemini CLI。」(如下圖)

登入Gemini CLI後,我直接問 Gemini:

「我收到『You are running Gemini CLI in your home directory. It is recommended to run in a project-specific directory.』這段訊息,執行Gemini CLI對我有什麼壞處?

他把問題的壞處說明後,直接提出最佳解決方法。(如下圖)

我接著請Gemini「請為我建立一個目錄「Gemini Test Project」,並且在這個目錄下重新啟動Gemini」。

但基於AI的本分,可以幫我建立目錄,但不能直接幫我執行這個操作。

執行 `/quit` 離開 Gemini,出現下圖。

因為macOS的目錄名稱中間不能有空白,所以重新建立「Gemini_test」目錄,在執行 Gemini CLI。

在 macOS Monterey 12.4 環境,使用 Micropython 在 ESP32 SSD1306 顯示 圖形


作者:順哥
email:palmbear@gmail.com

資料來源:
1.image2cpp
2.| ESP32 教學 | MicroPython | I2C OLED Image 顯示圖像 | 209 |
3.SSD1306.py


Table of Contents

[TOC]


前言

測試在 macOS Monterey 12.4 環境,使用 Micropython 在 ESP32 用 SSD1306 OLED 顯示 image 圖形。


Step 1:使用的圖形

在 google網站搜尋一張看起來順眼,個人使用無版權的黑色的熊熊圖(png檔),就用這張圖來做測試,這張圖的原始尺寸為 “981 x 562″。
網頁畫面:


Step 2:將圖形轉換成 byte arrays

因為在macOS上找不到適當軟體可以使用,在 google網站上找到這個
image2ccp

這個網站可以將 image 轉換為 byte arrays(或將您的 byte arrays 轉換回 image),然後給 OLED 顯示出來。
網頁畫面:

  1. 選擇圖形 Select image:
    點選「選擇檔案」,上傳圖形檔。
    網頁畫面:
  2. 圖形設定 image Settings:
    在「畫布尺寸」 Canvas size(s) 欄位中,填入 OLED 的像數規格,我使用 “128 x 64″ ,所以在這裡我們填入 “128″ 及 “64″ ,圖形的原始尺寸為 “981 x 562″,這個網站可以將圖形直接轉成我們需要的大小。
    接下來選擇 “stretch to fill canvas" 「拉伸填充畫布」。
    網頁畫面:
  3. 圖形預覽 Preview:
    隨即就會在「圖形預覽」Preview,看到圖形。
  4. 輸出 Output:
    在「代碼輸出格式」"Code output format" 欄位中,填入 “plain bytes" ,
    接下來在「繪製模式」"Draw mode" 欄位中,填入 “Vertical – 1 bit per pixel" ,
    最後按下 “Generate code" 擷取碼,並將16進位的碼 Copy 下來。
    網頁畫面:

Step 3:測試程式碼

我使用 資料來源2 的程式碼,SSD1306 module 使用 資料來源3 ,並依照自己的ESP32接腳,改用SoftI2C,我的程式碼如下:

from machine import Pin, SoftI2C #從machine 匯入 Pin, SoftI2C
import ssd1306 #匯入 ssd1306模組
import framebuf #匯入 fram3buf模組

i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=400000) # 建立 i2c 物件

oled=ssd1306.SSD1306_I2C(128, 64, i2c) #建立 oled096 物件,第 1 個參數與第 2 個參數設定為 OLED 模組的像素,第 3 個參數為 I2C 的物件名稱

# img64 是一個 bytearrays 的列表(List) 
img64 = [
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 
0x3f, 0x1f, 0x1f, 0x0f, 0x07, 0x07, 0x07, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 
0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 
0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0f, 0x0f, 0x1f, 
0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x7f, 0x7f, 
0x7f, 0x3f, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x07, 0x2f, 0x7f, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xc3, 0xf7, 
0xff, 0xff, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x08, 0x38, 0xf8, 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 
0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xfc, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 
0x80, 0x80, 0x80, 0xc0, 0xc0, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0x20, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x80, 0xc0, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x0f, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x02, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xfc, 
0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf8, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x1f, 0x3f, 
0x7f, 0x3f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xc1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 
0xc0, 0xe0, 0xf0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xfc, 0xfe, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xfe, 0xf8, 0xf8, 0xf8, 0xf8, 0xf0, 0xf8, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
0xf0, 0xf0, 0xf0, 0xf0, 0xf8, 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xfc, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 
0x87, 0x9f, 0xff, 0xff, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
0xf0, 0xf0, 0xf0, 0xf8, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 
0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1, 0xc3, 0xc3, 
0xe7, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
]

img064b = bytearray(img64)  # 將 img64 轉成 bytearray 型態,並取名 img64b
imgbuf=framebuf.FrameBuffer(img064b,128,64,framebuf.MONO_VLSB) #framebuf 第 1 個參數為影像資料的 bytearray名稱,第 2、3 個參數是影像的寬度與高度,第 4 個參數是像素形式與排列,MONO_VLSB 是指 單色+垂直+LSB
oled.blit(imgbuf, 0, 0) #blit方法,是將imgbuf 物件,由指定的 X,Y 位置,依序開始填入 OLED 記憶體
oled.invert(1) #以反白螢幕方式顯示圖形畫面
oled.show() #顯示螢幕畫面

程式說明

  1. 因為 framebuf 使用的資料型態是 bytearray,所以將 img64 轉成 bytearray 型態,並取名 img64b。
  2. 我們在轉檔時時是採用單色與垂直方向排列(Vertical)的方式存檔,所以預設轉出陣列就是 1btye 會有 8 像素,資料排列也就照著直線方式一條一條轉換,img64 原始資料共有 1024 個 bytes,換算成像素也就是1024×8=8192個像素,與我們OLED 的像素128*64=8192 Pixel 是相符的。
  3. mgbuf 為新建立的 framebuf 物件,framebuf 第 1 個參數為影像資料的 byte 序列,第 2、3 個參數分別為影像的寬度與高度,第 4 個參數就是像素形式與排列,MONO_VLSB 是指 單色+垂直+LSB(如果是其他形式可以填入framebuf.MONO_HLSB、framebuf.RGB565、framebuf.GS4_HMSB等。
  4. blit 這個方法也是源自 framebuf,將建立好的 imgbuf 物件,由指定的 X,Y 位置,依序開始填入 OLED 記憶體內。
    Micropython framebuf 模組的官方說明

成果

完成畫面:

我使用的硬體:

測試影片


tags: Micropython ESP32 Macbook pro 2021 macOS 12.4 Monterey

MacBook Pro Monterey,使用 Arduino IDE 燒錄 ESP8266 會出現燒錄錯誤 “pyserial or esptool directories not found next to this upload.py tool.”

資料來源:https://www.tweaking4all.com/forum/arduino/macos-aruino-ide-how-to-fix-pyserial-or-esptool-directories-not-found-next-to-this-upload-py-tool-error-esp8266/

錯誤訊息如下:

pyserial or esptool directories not found next to this upload.py tool.
An error occurred while uploading the sketch

macOS版本:Monterey 12.3.1

ESP8266 Core version:2.6.3

aArduino IDE version:1.8.19

解決方法:

  1. 打開這個檔案
    file~/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/tools/pyserial/serial/tools/list_ports_osx.py
  2. 註釋掉這兩行
iokit = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/IOKit.framework/IOKit')    
cf = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation')

加入這兩行:

iokit = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/IOKit.framework/IOKit')
cf = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation')

修改完成後,程式碼應該像下面這樣子才對:

from serial.tools import list_ports_common

#iokit = ctypes.cdll.LoadLibrary(ctypes.util.find_library('IOKit'))
#cf = ctypes.cdll.LoadLibrary(ctypes.util.find_library('CoreFoundation'))
iokit = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/IOKit.framework/IOKit')
cf = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation')

kIOMasterPortDefault = ctypes.c_void_p.in_dll(iokit, "kIOMasterPortDefault")
kCFAllocatorDefault = ctypes.c_void_p.in_dll(cf, "kCFAllocatorDefault")
這樣就可以正常燒錄了!
Done!

Apple 的 iCloud 實在太棒了!

原先想說會搬移舊資料會很傷腦筋,結果一點都不費力,只要登入iClloud就可以了,完全都不需要額外做什麼。

就是要花時間而已!

Macbook Pro星期六晚上帶回家,到今天晚上,過了2天,我的新Macbook Pro經由iColud就已經同步完成了。

但是,不是所有資料都下載到新Macbook Pro,只是有用到的會自動下載下來,其他就等你什麼時候會用到,需要用到時,再下載下來就可以了,不用擔心空間不夠用。

整理舊資料,只要刪除,就會同步刪除iCloud的檔案。

但是,如果要保存資料,要另外儲存在其他外接硬碟或隨身碟,再刪除喔!

真的太好用了!

有使用Apple的產品建議一定要購買iCloud,真的超級方便。


tags: Macbook pro 2021 macOS 12.3.1 Monterey

在Arduino 使用ESP32與網路同步時間,獲取日期及時間

作者:順哥
email:palmbear@gmail.com

資料來源:
https://randomnerdtutorials.com/esp32-date-time-ntp-client-server-arduino/

Table of Contents

[TOC]

前言

如何使用 ESP32 和 Arduino IDE 從 NTP Server 同步日期和時間?

獲取日期和時間在Aiot應用中很有用。要從 NTP Server獲取時間,ESP32需要連接 Internet,而且不需要額外的硬體(如 RTC 時鐘)。


NTP(Network Time Protocol, 網路時間協議)

NTP想要將所有參與電腦的協調世界時(UTC)時間同步到ms的誤差內。NTP通常可以在internet保持幾十毫秒的誤差,並且在理想的區域網路環境中可以實現超過1毫秒的精度。

MCU與NTP Server同步示意圖:
資料來源:randomnerdtutorials.com


硬體

  1. AI Thinker ESP32-S(NODMCU-32 V1.2)
  2. ESP32擴展板
  3. USB充電傳輸線

軟體

  1. Arduino IDE 2.0.0 RC5 for MacOS:
  2. 需要的Library:

<WiFi.h>
<time.h>


程式碼

  1. 使用 ESP32 加上 ESP32擴展板,程式碼如下:
/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-date-time-ntp-client-server-arduino/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <WiFi.h>
#include <time.h>

const char* ssid     = "Your wifi ssid";
const char* password = "your password";

const char* ntpServer = "time.google.com";
const long  gmtOffset_sec = 28800; //台灣時區+8hr,28800=8*60*60
const int   daylightOffset_sec = 0;  //台灣無日光節約時間

void setup(){
  Serial.begin(115200);

  // Connect to Wi-Fi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");

  // Init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

void loop(){
  delay(5000);
  printLocalTime();
}

void printLocalTime(){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %Y %m %d %H:%M:%S"); //%A-Sunday,%Y-2022,%m-3,%d-27,%H:%M:%S-21:10:02
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); //%A-Sunday,%B-March,%d-27,%Y-2022,%H:%M:%S-21:10:02
  Serial.print("Day of week: "); //顯示英文 星期
  Serial.println(&timeinfo, "%A"); //Day of week: Sunday
  Serial.print("Month: "); //顯示英文 月份
  Serial.println(&timeinfo, "%B"); //Month: March
  Serial.print("Day of Month: "); //顯示英文 日
  Serial.println(&timeinfo, "%d"); //Day of Month: 27
  Serial.print("Year: "); //顯示英文 西元年
  Serial.println(&timeinfo, "%Y"); //Year: 2022
  Serial.print("Hour: "); //顯示英文 時 24小時制
  Serial.println(&timeinfo, "%H"); //Hour: 21
  Serial.print("Hour (12 hour format): "); //顯示英文 時 12小時制
  Serial.println(&timeinfo, "%I"); //Hour (12 hour format): 9
  Serial.print("Minute: "); //顯示英文 分
  Serial.println(&timeinfo, "%M"); //Minute: 01
  Serial.print("Second: "); //顯示英文 秒
  Serial.println(&timeinfo, "%S"); //Second: 24

  Serial.println("Time variables"); //時間變數Time variables
  char timeHour[3]; //宣告時間小時變數:timeHour
  strftime(timeHour,3, "%H", &timeinfo);
  Serial.println(timeHour); //顯示時數:22
  char timeWeekDay[10]; //宣告時間星期變數:timeWeekDay
  strftime(timeWeekDay,10, "%A", &timeinfo);
  Serial.println(timeWeekDay); //顯示星期:Sunday
  Serial.println("*****************************************************");

}

tags: NTP Arduino ESP32 ESP8266 Wio terminal

How to remove and reinstall Node-Red in macOS Big Sur 11.4

資料來源:
1. https://www.hackster.io/daquilnp/3-steps-to-installing-node-red-and-bean-nodes-on-mac-os-ebaee2
2.https://stackoverflow.com/questions/11177954/how-do-i-completely-uninstall-node-js-and-reinstall-from-beginning-mac-os-x?newreg=c6cfabe02a584b76a1812859f2575651
3.https://stackabuse.com/how-to-uninstall-node-js-from-mac-osx/
4.https://diyprojects.io/installing-using-node-red-macos-windows/

Uninstall Node-red

原本已經參考這位大神(資料來源1)他的安裝步驟,安裝完成Node-Red,因 使用過程中,Tensorfolw coco ssd 節點啟動不起來,移除也無法移除,只要重新安裝。

第一次刪除重新安裝步驟(失敗):(參考益師傅Node-red Windows版災難復原)

1.將隱藏檔案顯示出來

Shift + Command + .
這樣就可以顯示出隱藏的檔案囉,只要再按一次就可以重新隱藏。(參考MacUknow

Mac 隱藏檔案

2.備份.Node-Red 檔案夾的這三個檔案

(1)flows.json:這是原本流程頁簽內所有的流程的檔案,重安裝完成後匯入 Node-Red。
(2)package.json:這是原本已安裝節點的檔案,重安裝完成後匯入 Node-Red
(3)settings.js:這是Node_Red 的設定檔,存放著使用者帳號、密碼,重安裝完成後,將帳號、密碼相關資料複製到新的 settings.js 檔案中。

3.刪除.Node-Red 相關檔案夾
(1)刪除.node-Red 檔案夾
(2)刪除.node-gyd 檔案夾
(3)刪除.nmp 檔案夾

4.重新開機。

5.重新安裝Node-Red

使用大神安裝檔安裝,會把 Node-Red 與 Light Blue Bean節點一起安裝,但是我主要是安裝 Node-Red ,Light Blue Bean節點一起安裝,只要不用其實沒有什麼關係,或者安裝完成 Node-Red 後,再把它移除,以免與想要使用的節點衝到。

打開 安裝檔的目錄按滑鼠右鍵 > 服務 > 終端機視窗打開 ,

安裝完成後,Tensorfolw coco ssd 節點仍然啟動不起來,只好再次刪除重裝!!!

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

第二次刪除重新安裝步驟:(參考資料來源2資料來源3

1.將隱藏檔案顯示出來

Shift + Command + .
這樣就可以顯示出隱藏的檔案囉,只要再按一次就可以重新隱藏。(參考MacUknow

2.備份.Node-Red 檔案夾的這三個檔案(先前已完成)

3.刪除 Node-Red 所有相關檔案夾
(1)刪除.node-Red 檔案夾
(2)刪除.node-gyd 檔案夾
(3)刪除.nmp 檔案夾
(4)再參考資料來源2資料來源3 手動刪除資料夾或檔案。
下面這些可能就是所有的檔案,但是作者不確定,但我刪除這些就沒問題了。

Uninstall Node-red 手動刪除檔案清單

這樣刪除後就算是手動乾淨移除 Node-red了!

Install Node-red

參考 資料來源4 進行安裝:

1.先安裝 Node.js :前往官方網站下載 安裝檔,請下載14.17.5 LTS 版本,或者是參考 這裡 使用 Command Line 手動安裝。

Node.js官方下載點
Node-red Command Line 安裝

2.安裝 Node-red

(1)打開終端機輸入下面程式碼

sudo npm install -g --unsafe-perm node-red

您必須在 sudo 的 npm 命令之前執行。 -g 表示將上傳到 npm 目錄,並且可用於所有 node.js。 –unsafe-perm 允許在出現錯誤時繼續安裝。

(2)安裝完成後,打開終端機輸入下面程式碼:

killall Finder

重新啟動 Finder

(3)啟動 Node-red:再次打開終端機輸入下面程式碼:

node-red
啟動 Node-red

(4)最後打開瀏覽器,輸入:http://127.0.0.1:1880

Done !

ESP32 CAM With CH340燒錄 MicroPython in MacOS

資料來源:
1. https://lemariva.com/blog/2019/09/micropython-how-about-taking-photo-esp32
2. https://github.com/espressif/esptool
3. http://twarm.com/commerce/product_info.php?products_id=1323

硬體:
1. ESP32 CAM
2. MicroUSB傳輸線
3. 雙母頭杜邦線

軟體:
1. MicroPython 燒錄檔,下載連結:https://micropython.org/resources/firmware/esp32-20210623-v1.16.bin
2. esptool.py,一個可以燒錄ESP32CAM的 Free Software ,使用說明及安裝
3. Thonny ,Python IDE,可進行Python程式設計,也可以直接將程式碼燒錄到ESP32CAM,下載連結:https://thonny.org/

ESP32 CAM(副廠,內建USB-TTL介面),硬體相關資料如資料來源3

ESP32 CAM 接腳圖

將MicroUSB傳輸線連接到ESP32CAM,並將ESP32CAM的GPIO 0及GND短路,這樣就可以準備燒錄了。

將ESO32CAM的GPIO 0及GND短路
接線連接特寫

前往放置燒錄檔案bin檔所在位置的目錄,在目錄內點擊右鍵從終端機打開

先找出你使用的序列阜,

ls -l /dev/cu.*

先抹除ESP32 CAM的flash,我們使用esptool.py來燒錄。
如果你的USB TTL 是 CH340 請用這個

esptool.py --port /dev/cu.usbserial-1420 erase_flash

如果是 CP210x 請用下面的

esptool.py --port /dev/cu.SLAB_USBtoUART erase_flash

再寫入ESP32 CAM

#燒錄Micropython
esptool.py --chip esp32 --port /dev/cu.usbserial-1420 --baud 460800 write_flash -z 0x1000 <改成你的檔案(esp32-20210618-v1.16.bin)>

#燒錄Circuitpython
esptool.py --port /dev/cu.SLAB_USBtoUART --baud 460800 write_flash -z 0X1000 adafruit-circuitpython-adafruit_metro_esp32s2-en_US-6.3.0.bin
ESP32 CAM燒錄中
ESP32 CAM燒錄完成

韌體燒錄完畢,拆下GPIO 0及GND之間的短路線材,按下RST鍵,重新啟動ESP32CAM,即可使用 Thonny 來寫程式了。

參考資料3的燒錄流程

依照 資料來源3 的硬體資料說明,燒錄要一直按著「Flash」鍵,但是 esptool 燒錄,整個使用過程完全不需要按任何按鍵就完成燒錄了。

安裝 Thonny 完成後,開啟 Thonny 就會看到下面畫面,就代表 Thonny 已經與ESP32CAM完成連接了,並顯示你燒錄的 MicroPython 版本。

Thonny與ESP32CAM完成連接

如果沒有出現,起點選上方工具列點選 Run > Select Interpreter ,如下圖:

接著會出現下面視窗,選取你要連接的USBserial Port,在按下「OK」鍵,

這樣應該就可以連上 ESP32CAM了!

在Mac OS 安裝Labelimg程式

Labelimg 是一個資料標記的程式,網址是

https://github.com/tzutalin/labelImg/tree/v1.8.1

可以作為影像物件辨識或偵測(Object Detection)的資料標記的處理程式。

1.從上面的網址,點擊綠色的按鍵,在點擊 Download ZIP 下載 LabelImg-1.8.1.zip,並解壓放到你要放的目錄下,我把它放在根目錄下。

因為我的 Macbook Pro 安裝 Anaconda 所以我直接在 Anacomda 環境下的命令列下直接安裝,而沒有按照作者建議的Mac OS 安裝方法,一方面也是用作者建議的方法,一直都無法安裝成功,所以看到Windows 環境的安裝方法中,是在 Anaconda 環境下安裝,同樣是 Anacona ,一定可以使用同樣的方法安裝,果不其然,就安裝完成。

conda install pyqt=5
pyrcc5 -o resources.py resources.qrc
python labelImg.py

上面執行完成後,就會開啟 LabelImg 程式,進行資料標記了。

但是為了使用方便,按照作者的更新訊息,

NEW Python 3 Virtualenv + Binary This avoids a lot of the QT / Python version issues, and gives you a nice .app file with a new SVG Icon in your /Applications folder. You can consider this script: build-tools/build-for-macos.sh

brew install python3
pip install pipenv
pipenv --three
pipenv shell
pip install py2app
pip install PyQt5 lxml
make qt5py3
rm -rf build dist
python setup.py py2app -A
mv "dist/labelImg.app" /Applications

這樣就可以把 LabelImg 程式變成 Mac OS 的應用程式,這樣就可以輕鬆使用了,不需要每次使用時,都要用終端機命令列重新執行一遍。