Skip to content

s881215/Automatic-Solar-Tracking-System

Repository files navigation

☀️ Automatic Solar Tracking System (8051 + BH1750 + SG90)

本專案使用 8051 MCU 讀取 GY-302(BH1750)日照感測器的照度(lux),並透過 SG90 舵機調整太陽能板/感測器朝向,以在光線不足時自動「掃描找光」、找到足夠亮度後停止,並把照度資料以 UART 串列傳輸送到 PC 端由 MATLAB接收與分析。


目錄


功能特色

  • 固定週期追光:每隔固定時間(預設約 10 秒)啟動一次追光流程(由 Timer0 觸發)。
  • 閥值判斷:照度 sunlight小於 threshold 才開始轉動;達到/超過 threshold 則停止。
  • 方向決策(簡單但有效):轉動過程若偵測到照度明顯下降,代表走錯方向,會自動 反轉方向
  • 角度保護:舵機角度限制在 0°~180°,避免機構卡死。
  • 資料回傳:每次更新照度後,會將 BH1750 的 2-byte 原始資料透過 UART 傳到 MATLAB 端做即時監測/記錄。

系統架構

        +---------------------+            +----------------------+
        |      8051 MCU       |  UART Tx   |   PC / MATLAB (User) |
        |                     +----------->|  接收、繪圖、存檔、分析 |
        |  - Timer0: 週期觸發  |            +----------------------+
        |  - Timer2: PWM舵機   |
        |  - Bit-bang I2C     |
        +----+-----------+----+
             |           |
         I2C |           | PWM
             |           |
     +-------v----+   +--v------+
     | GY-302      |   | SG90    |
     | (BH1750 lux)|   | Servo   |
     +------------+   +---------+

硬體清單

  • MCU:8051 系列(本程式使用 REG_MPC82G516.h 的暫存器定義)
  • 光照感測器:GY-302(BH1750)
  • 舵機:SG90(0°~180°)
  • PC:MATLAB(用 AutomaticSolarTrackingSystem.m 接收 UART 資料)
  • 電源與周邊:
    • 舵機建議獨立 5V 供電(≥ 1A,視負載而定)
    • I2C 拉高電阻(多數 GY-302 模組已內建)
    • MCU 與舵機/感測器需 共地(GND common)

接線與腳位

以原始程式為準(請參考 i2c.c/main.c 的腳位定義)

I2C(軟體模擬 / Bit-bang)

  • SDA = P2.0
  • SCL = P2.1

(定義於 i2c.c

sbit SDA = P2^0;
sbit SCL = P2^1;

舵機 PWM

  • PWM_OUT = P1.0(定義於 main.c
sbit pwm_out = P1^0;

UART

  • 程式設定鮑率 9600TH1=217; 等設定)
  • 8051 UART 腳位通常為:
    • TXD = P3.1
    • RXD = P3.0 (實際仍以你的 8051 版本/板子腳位為準)

追光控制策略

1) 週期觸發(每 N 秒)

  • Timer0 以固定週期進入中斷,累加 count
  • count == 1000 時設定 tracking=1,主迴圈呼叫 TRACKINGv2()

程式碼邏輯(節錄):

void timer0() interrupt 1{
    // every 10ms enter ISR
    count++;
    if(count==1000){
        count=0;
        tracking=1;
    }
}

依註解:10ms * 1000 = 10s
若你想改成 N 秒:可調整 count 的門檻或 Timer0 的 reload 值。


2) 閥值 threshold(決定是否掃描)

  • 預設:
#define threshold 250.0   // unit : lux
  • sunlight < threshold:開始掃描
  • sunlight >= threshold:停止掃描,等待下一次週期到來

3) 掃描與方向反轉策略(核心)

追光函式 TRACKINGv2() 的核心邏輯:

  • 初始角度:angle_per_step = 90°
  • 每一步轉動:step = 2°
  • 初始方向:direction = +1(固定從同一側開始)
  • 每次更新照度後:
    • 若新照度比前一次還小,且下降幅度 > 3 lux
      → 判定走錯方向,執行 direction = -direction 反轉

關鍵判斷(節錄):

if (sunlight < sunlight_pre && (sunlight_pre - sunlight) > 3.0) {
    direction = -direction;
}

4) 角度保護

if (angle_per_step > 180) { angle_per_step = 180; direction = -1; }
if (angle_per_step < 0)   { angle_per_step = 0;   direction = 1;  }

韌體程式架構

檔案結構

.
├── main.c      						  # 追光策略、Timer0/Timer2/UART、舵機控制
├── i2c.c       						  # 軟體 I2C (START/STOP/ACK/READ/WRITE) + delay
├── i2c.h       						  # I2C API 宣告 + 8051 暫存器 header
└── AutomaticSolarTrackingSystem.m        # MATLAB 串列接收與 lux 轉換

main.c 重點說明

  • TIMER_INIT()
    • Timer2:用於 PWM(舵機脈衝)
    • Timer1:UART baud rate
    • Timer0:固定週期觸發追光
  • PWM_INIT()
    • 設定 duty_cycle 初值、PWM 輸出腳位模式、啟動 Timer2
  • SERVO(angle)
    • 將角度映射成脈衝寬度:
      • pulse_us ≈ 500 + angle*(100/9)(約 0°→500us,180°→2500us)
  • GET_GY302()
    • 透過 I2C 對 BH1750 下命令並讀回 2-byte 感測值
  • TRACKINGv2()
    • 實作「閥值 + 掃描 + 方向反轉」策略,並在每次更新時送出 UART 資料

i2c.c 重點說明

  • START() / STOP():I2C 起始/停止條件
  • WRITE_ADDRESS(addr, RW):送出 7-bit address + R/W bit
    • 程式使用 addr=35(十進位)→ 0x23(BH1750 常見地址)
  • READ_DATA(&rdata_h, &rdata_l):連續讀 2 bytes

串列通訊格式

  • UART:9600 bps
  • 每次更新照度會依序送出:
    1. rdata_h(高位元組)
    2. rdata_l(低位元組)

MATLAB 端照度換算:

GY = (data(1)*256 + data(2)) / 1.2;  % lux

如何編譯與燒錄

依你的開發環境調整(常見為 Keil C51 / SDCC)

  1. main.c / i2c.c 加入同一個專案
  2. 確認 include path 能找到 i2c.hREG_MPC82G516.h
  3. 設定晶振頻率/編譯器選項(與你的板子一致)
  4. 產生 HEX 後燒錄至 8051
  5. 連接 UART 到 PC(USB-TTL),開啟 MATLAB 執行 AutomaticSolarTrackingSystem.m

MATLAB 接收與後續處理建議

1) 直接接收(附件 AutomaticSolarTrackingSystem.m

  • COM6、9600 bps 連線
  • 每次讀 2 bytes,轉換為 lux,持續顯示與累積在 GY_val
scom=serial('COM6','BaudRate',9600,'Timeout',4000);
fopen(scom);
while(1)
    data=fread(scom,2);
    GY=(data(1)*256+data(2))/1.2;
    GY_val=[GY_val GY];
    disp(GY);
end

記得把 COM6 改成你實際的 COM Port(Windows 裝置管理員可查)。


2) 建議的後續處理(推薦你在 MATLAB 端加上的功能)

(A) 即時繪圖(Real-time Plot)

  • animatedline + drawnow 做即時曲線
  • 方便觀察追光前/追光中/追光後的照度變化

(B) 加上時間戳與資料紀錄

  • tic/tocdatetime('now') 記錄每筆資料時間
  • 匯出成 CSVwritetable)或 MAT 檔(save
  • 日後可分析不同日期/時段的光照與追光表現

(C) 濾波與穩態判斷

  • lux 做移動平均(moving average)或中值濾波,降低雜訊造成誤判反轉
  • 例如:
    • 追光停止後的穩態 lux
    • 達到 threshold 所需時間(lock time)
    • 反轉次數(代表方向判斷是否太敏感)

(D) 自動調參(threshold / step / 反轉門檻)

  • 收集一段時間的 lux 分佈(histogram)
  • 根據「白天/陰天」動態調整 threshold(例如以某百分位數作為門檻)
  • 評估不同 step(每步角度)對「搜尋速度 vs 精度」的影響

常見問題

1) 舵機抖動或 MCU 重啟

  • 舵機瞬間電流很大,建議:
    • 舵機用獨立 5V 供電
    • MCU 與舵機 共地
    • 供電端加電容(例如 100uF + 0.1uF)

2) 讀不到 BH1750 / 數值不變

  • 檢查:
    • SDA/SCL 是否接對、是否需要外接上拉
    • 感測器位址是否為 0x23(程式用十進位 35)
    • I2C 線太長可能造成波形變差

3) MATLAB 一直卡住或讀不到資料

  • 確認:
    • COM Port 是否正確
    • 鮑率是否一致(本韌體為 9600)
    • 是否有其他軟體占用該串口
    • fread(scom,2) 是 blocking,若想更順暢可加 timeout 或檢查 BytesAvailable

作者

  • Chen-Ting Li

About

MCU project

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published