網頁

2021年6月30日

清除 Windows 10 的「網路 編號」網路名稱

 Windows 7 、Windows 10 如果改變了網路環境,例如:帶到不同的地方上網、閘道器改變、  .... 等等,都會讓網路序號 +1 累加 ,雖然不會影響功能,但是看久了,跑到 網路13 之類的還真有點不順眼。

處理方式: regedit
找到 https://hkey_local_machine/SOFTWARE/Microsoft/Windows%20NT/CurrentVersion/NetworkList/Profiles/ 位置,把裡面的項目都刪掉了,然後把網路卡關閉、重啟,這樣就又會回到預設值了。( 不過,往後只要偵測到網路變更,一樣會繼續累加喔。)

2021年6月25日

CentOS 6 使用 yum 更新套件

 CentOS 已經快走向尾聲了,今天為了測試,在舊電腦上面安裝了 CentOS 6 ,安裝完畢之後要用 # yum update ,卻發現 mirrorlist 的站台都不見了,畢竟 CentOS 6 已經被官方放生了。不過只要去修改 yum 的一些設定值,即可將 yum 的目的指向 vault.centos.org 去更新了。

  1. 修改 # vi /etc/yum.repos.d/CentOS-Base.repo
  2. 把裡面的 mirrorlist=..... 刪掉或註解掉。
  3. 把裡面的 mirror.centos.org 全部置換成 vault.centos.org
這樣就能正常 yum update 了。

2021年6月24日

SG90 角度旋轉伺服機 ( 舵機 )

「伺服機」,又可稱「伺服馬達」,也稱為「舵機」;但是又有別於馬達的功能,因為伺服機可以控制角度 or 控制旋轉圈數。可以控制角度的伺服機,就叫做「角度旋轉伺服機」、「角度旋轉舵機」;可以控制旋轉圈數的伺服機,就做較「連續旋轉伺服機」、「連續旋轉舵機」,或稱為「360度舵機」等類似的名詞。

這次的主角是 SG90 ,是一顆角度旋轉伺服機。


接線的方式很簡單,就是一般的 GVS 三條線。


看一下使用影片:


Arduino 程式語法

#include <Servo.h>

Servo servo_9;

void setup() {
  servo_9.attach(9);
}


void loop() {

  servo_9.write(180);
  delay(3000);
  servo_9.write(100);
  delay(3000);

}


角度旋轉伺服機要使用之前,要先確認手上這顆伺服機「能使用的角度範圍」。理論上這些角度旋轉舵機能從 0度 旋轉到 180度,但是畢竟 SG90 只是低成本的產品,精密度不算夠高,所以在可使用的角度範圍,可能會略為縮減,例如:2-180度。因為當 SG90 要轉到 0 度時,可能無法精確判斷到位,所以你會摸到 SG90 不斷地在轉動感(抖動),這就代表 SG90 還沒有精確到位,不斷地在修正,這會造成 SG90 開始發熱,減短使用壽命。所以拿到角度旋轉舵機時,建議從頭開始測試,轉到 0 度,是否精確到位,或是找到一個能精確到位不再移位的角度位置;相同道理,180 度也必須測試,才能知道精確的最大角度範圍。

上面影片中,可以看到角度從 90度,再往倒到170度的位置,但是實際的程式卻是從 100度 轉到 180度。為什麼會有這樣的誤差?

先回到上個步驟,我們測試可用範圍從 0度-180度的過程,然後固定在 90度,並且把槳片與螺絲鎖上去;誤差值就在這邊,槳片的齒輪、 SG90 旋轉軸的齒輪,並不夠到 360度那麼精確,鎖上去之後,90度就有了誤差,這就造成了我們要把槳片轉到垂直位置時,必須修正舵機角度為槳片的真實 90度的數值。

蜂鳴器

 Arduino 開放硬體中的「蜂鳴器」,有分為「有源蜂鳴器」、「無源蜂鳴器」;這個有源、無源,指的就是內建震盪源。從外表來看,很難分辨到底是有源蜂鳴器 or 無源蜂鳴器。盡管網路上有幾篇從外觀上的分辨來區分,但總是有些許落差。本篇就用實作,來分辨有源蜂鳴器 or 無源蜂鳴器。

1.接數位高電位,會正常發出逼逼聲的,就是有源蜂鳴器;而無源蜂鳴器,接數位高電位,不會發出正常的逼逼聲。

2.無論是有源蜂鳴器 or 無源蜂鳴器,兩者都可以唱歌。

3.音量差異,實作結果:有源蜂鳴器可以唱比較大聲,甚至容易破聲;而無源蜂鳴器發出的音量比有源蜂鳴器小聲。

 

1-數位高電壓,有源蜂鳴器可以發出逼逼聲

2-數位頻率,有源蜂鳴器較大聲,甚至破音

數位 6 號腳位發出聲音

void setup() {
  pinMode(6, OUTPUT);
}

void loop() {
  digitalWrite(6, HIGH);
  delay(2000);
  digitalWrite(6, LOW);
  delay(1000);

}

數位 4 號腳位不斷唱歌

#include "pitches.h"

int melody[] = {
  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  4, 8, 8, 4, 4, 4, 4, 4
};

void setup() {

}

void loop() {

    for (int thisNote = 0; thisNote < 8; thisNote++) {

    // to calculate the note duration, take one second divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(4, melody[thisNote], noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(4);
  }
}

 

2021年6月18日

兩片不太相同的 Arduino UNO 開發板

第一張照片出處:
https://qqtrading.com.my/arduino-uno-smd-r3-microcontroller-development-board-arduino-compatible?search=arduino%20uno


這兩片都是 Arduino UNO 相容開發板,看起來很像,差別在於那兩顆晶片。 

上圖左邊是副廠 CH340 + ATmega328p 表現貼裝(SMD) ,右邊是Arduino 原廠 ATmega16U2 + ATmega328p 雙排腳針封裝(DIP) 。

下圖都是我拍的,兩片都是副廠的,左圖是 CH340 + ATmega328p 表現貼裝(SMD) ,右圖是副廠 ATmega16U2 + ATmega328p 雙排腳針封裝(DIP)

看看兩種晶片的放大照。



用 LCM1602 IIC 液晶模組顯示文字

 這組液晶模組是包含 LCM 1602 IIC ,所以只有 5 隻腳,而且可以呈現文字,使用起來很方便。

但是要注意的是,LCM 1602 IIC 的  IO 腳位:
GND
VCC
SDA----Arduino A4
SCL----Arduino A5



模組背面有可變電阻,調整 LCD 的亮度,記得要調整一下。

如果看到方塊字,代表太暗,翻到背面調整一下,調到可以清晰看到文字。



參考網頁:
https://www.taiwaniot.com.tw/product/1602-%E8%97%8D%E5%BA%95%E7%99%BD%E5%AD%97-iici2c-6x2-%E8%83%8C%E5%85%89%E6%B6%B2%E6%99%B6%E6%A8%A1%E7%B5%84/
https://jimirobot.tw/arduino-tutorial-lcd1602-i2c-401/
https://blog.gtwang.org/iot/ywrobot-arduino-lcm-1602-iic-v1-lcd-display/
https://blog.jmaker.com.tw/lcd1602/

下面的範例是使用 jmaker 的範例,所以要額外安裝 LiquidCrystal_PCF8574 函式庫。

#include <LiquidCrystal_PCF8574.h>

LiquidCrystal_PCF8574 lcd(0x3F);  // 設定i2c位址,一般情況就是0x27和0x3F兩種

void setup()
{
  lcd.begin(16, 2); // 初始化LCD
  //lcd.begin(20, 4); // 如果是20x4的LCD就是用這行
 
  lcd.setBacklight(255);
  lcd.clear();
  lcd.setCursor(0, 0);  //設定游標位置 (字,行)
  lcd.print("*~ first line.");
  lcd.setCursor(0, 1);
  lcd.print("~* second line.");
} // setup()

void loop()
{
 
} // loop()

什麼是 I2C、IIC ?

Arduino 板子上面的接腳,數位(14)  + 類比(6) 總共才 20 隻腳。


如果要使用接腳很多的感測器,例如:LCD 1602 這種顯示模組,上面總共 16 隻腳,那 Arduino 的 IO 馬上就沒了。


所以,就開發出這種 I2C 的技術,把 16 隻腳位,變成 4 隻 IO 就可以控制了,這就是 I2C 或 IIC 。( 下圖,是上圖的背面 )


使用 MAX7219 驅動 8x8 矩陣式顯示器

本次的主角就是 8x8 矩陣顯示器:



不過如果只有 8x8 矩陣顯示器 是很難單獨運作的,必須要靠 MAX7219 這塊 IC 來處理字元的輸入與顯示。

組合在一起於是有了模組。



接線方式如下圖:


顯示結果如下影片:

參考網頁:
https://docs.labs.mediatek.com/resource/linkit7697-arduino/zh_tw/tutorial/driving-8x8-dot-matrices-with-max7219
https://forum.arduino.cc/t/max7219-led-matrix-rotate-text-8x8/438719
https://lastminuteengineers.com/max7219-dot-matrix-arduino-tutorial/
https://code.google.com/archive/p/arudino-maxmatrix-library/wikis/Example_Display_Characters.wiki
https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf

程式如下:

//
// Use one MAX7219 to control a 8x8 dot matrix
// http://www.icshop.com.tw/product_info.php/products_id/13181
//
// MAX7219 datasheet: https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf
//

// the MAX7219 address map (datasheet table 2)
#define MAX7219_DECODE_REG      (0x09)
#define MAX7219_INTENSITY_REG   (0x0A)
#define MAX7219_SCANLIMIT_REG   (0x0B)
#define MAX7219_SHUTDOWN_REG    (0X0C)
#define MAX7219_DISPLAYTEST_REG (0x0F)
#define MAX7219_DIGIT_REG(pos)  ((pos) + 1)
#define MAX7219_COLUMN_REG(pos) MAX7219_DIGIT_REG(pos)

// shutdown mode (datasheet table 3)
#define MAX7219_OFF             (0x0)
#define MAX7219_ON              (0x1)

// pin 13 of MAX7219 (CLK)
const int clock_pin = 8;
// pin 12 of MAX7219 (LOAD)
const int data_latch_pin = 9;
// pin 1 of MAX7219 (DIN)
const int data_input_pin = 10;

// number of columns of the display matrx
#define NUM_OF_COLUMNS  (8)
// for each character bitmap, it consumes 4 bytes
#define BYTE_PER_MAP    (5)

// matrix pattern for "Samba"
const byte char_pattern[] =
{
  B1000110, B1001001, B1001001, B0110010, B0000000, // S
  B0100000, B1010100, B1010100, B1111000, B0000000, // a
  B1111100, B0000100, B1111100, B0000100, B1111000, // m
  B1111111, B1000100, B1000100, B0111000, B0000000, // b
  B0100000, B1010100, B1010100, B1111000, B0000000, // a
  B0000000, B0000000, B0000000, B0000000, B0000000, // space
};

#define DISPLAY_STR_LENGTH  (sizeof(char_pattern) / BYTE_PER_MAP)

// update the register value of MAX7219
void set_register(byte address, byte value)  
{
  digitalWrite(data_latch_pin, LOW);
  shiftOut(data_input_pin, clock_pin, MSBFIRST, address);
  shiftOut(data_input_pin, clock_pin, MSBFIRST, value);
  digitalWrite(data_latch_pin, HIGH);
}

void clear_matrix()
{
  // clear the dot matrix
  for (int i = 0; i < NUM_OF_COLUMNS; i++)
  {
    set_register(MAX7219_COLUMN_REG(i), B00000000);
  }
}

void init_max7219()
{
  // disable test mode. datasheet table 10
  set_register(MAX7219_DISPLAYTEST_REG, MAX7219_OFF);
  // set medium intensity. datasheet table 7
  set_register(MAX7219_INTENSITY_REG, 0xf);
  // turn off display. datasheet table 3
  set_register(MAX7219_SHUTDOWN_REG, MAX7219_OFF);
  // drive 8 digits. datasheet table 8
  set_register(MAX7219_SCANLIMIT_REG, 7);
  // no decode mode for all positions. datasheet table 4
  set_register(MAX7219_DECODE_REG, B00000000);

  // clear matrix display
  clear_matrix();
}

void setup()  
{
  // init pin states
  pinMode(clock_pin, OUTPUT);
  pinMode(data_latch_pin, OUTPUT);    
  pinMode(data_input_pin, OUTPUT);

  // init MAX2719 states
  init_max7219();
}

unsigned int char_index = 0;

void loop()  
{
  int i;
 
  // turn off display first
  set_register(MAX7219_SHUTDOWN_REG, MAX7219_OFF);

  // display one bitmap
  for (i = 0; i < BYTE_PER_MAP; i++)
  {
    // starting from column 2
    set_register(MAX7219_COLUMN_REG(2 + i), char_pattern[char_index * BYTE_PER_MAP + i]);
  }

  // turn on display
  set_register(MAX7219_SHUTDOWN_REG, MAX7219_ON);

  // step to the next character
  char_index++;
  // wrap around the character if needed
  if (char_index >= DISPLAY_STR_LENGTH)
  {
    char_index = 0;
  }
 
  delay(666);
}




繪製 Arduino 電路圖

 如果要自己畫自己的 Arduino + 開放硬體 的電路圖,可以使用 Fritzing 這套軟體,不過

Version  0.9.6 之後就必須付費下載了。還好,官方網站仍然可以下載到 Version 0.9.3b 的免費版本



2021年6月15日

7段顯示器

先講心得:
單純的 7 段顯示器,其實就是把 8 顆 LED 燈做在一塊板子上,透過排列的方式表示數字。這種板子,訓練大腦思惟,入門的玩一次就好了,真的要用這塊板子顯示數字、溫度、各種文字訊息,太可怕了、太不方便了;所以才會有 MAX7219 這種 IC 來控制 8x8 矩陣顯示器、 8 位數顯示器( 如下圖,中間那塊 IC 就是 MAX7219 )。而如果要把這種 8 顆 LED、8x8 矩陣顯示器、MAX7219 給國小學生使用,難度較高。


 



 

參考網頁: https://blog.jmaker.com.tw/4digit7seg/

參考語法:https://create.arduino.cc/editor/jasonshow/a9703023-e24f-4e3f-b0a2-5e666ff9bed4/preview
( 上面網頁的輸出與圖不同,必須修改程式的輸出腳位為 6~12 。另外,圖片的店阻色環也標示錯誤,請參考我的影片才是 220 。 )


 

/*
//本範例會在七段顯示LED上從9倒數到0
//傑森創工製作
//https://www.facebook.com/jasonshow

//本例預設是用共陰的顯示器
//若用的是共陽,除了要把接地改成接到5V
//另外在每個數字的表現方法,也要把0和1反過來
//1表示LED on,0則是LED off

// 七段用到的Arduino pin: 6,7,8,9,10,11,12
// 右下角的點用pin 5

//Arduino完整學習套件賣場:https://bre.is/E221Yubs7


傑森創工賣場:https://goo.gl/EWoPQ4

傑森創工粉絲團:
https://www.facebook.com/jasonshow
 */


//以下的陣列包含了0-9各數字的表現方法
byte seven_seg_digits[10][7] = { { 1,1,1,1,1,1,0 },  // = 0
                               { 0,1,1,0,0,0,0 },  // = 1
                               { 1,1,0,1,1,0,1 },  // = 2
                               { 1,1,1,1,0,0,1 },  // = 3
                               { 0,1,1,0,0,1,1 },  // = 4
                               { 1,0,1,1,0,1,1 },  // = 5
                               { 1,0,1,1,1,1,1 },  // = 6
                               { 1,1,1,0,0,0,0 },  // = 7
                               { 1,1,1,1,1,1,1 },  // = 8
                               { 1,1,1,0,0,1,1 }   // = 9
                               };

void setup() {                
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);

  pinMode(10, OUTPUT);   
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  writeDot(0);  // 一開始右下角的點就是不顯示的
}

void writeDot(byte dot) {  //顯示右下角小數點
  digitalWrite(5, dot);
}
    
void sevenSegWrite(byte digit) {  //顯示特定數字的副程式
  byte pin = 6;  //我們的七段顯示是從pin6開始的
  for (byte segCount = 0; segCount < 7; ++segCount) {
    digitalWrite(pin, seven_seg_digits[digit][segCount]);
    ++pin;
  }
}

void loop() {
  //數字從9開始倒數,每個數字間隔1秒
  for (byte count = 10; count > 0; --count) {
   delay(1000);
   sevenSegWrite(count - 1);
  }
  delay(4000);
}


2021年6月12日

羅技 G102滑鼠拆下來的 RGB 燈

 這顆RGB燈,是從壞掉的滑鼠G102拆下來的,目前找到用Arduino讓它亮起來的方式,腳位定義:長(G)、短(+)、長(R)、短(B),這個是共陽;這顆 RGB 的效果比去電料行買一顆 $30 的還要好,色彩變化很鮮明、亮度很夠。( 256 x 256 x 256 = 16777216 ,所以官方公布1680 萬色 ) 



2021年6月7日

360度連續旋轉舵機、 直流減速馬達(TT 馬達)、130直流馬達

 360度連續旋轉舵機 



 

直流減速馬達(TT 馬達)


 

 

130直流馬達


 

2021年6月2日

開放硬體規格說明

 http://qqtrading.com.my/

這個網站的說明正確度相當高,比起殘體中文來的好閱讀,繪製的圖解說明也很清楚、容易了解。

L298n 直流馬達驅動板

 網路上很多規格都是天下一大抄,說明也不完整,目前找到下方這個圖片才是最完整的。



接線的模擬圖


在樹莓派上面用L298n驅動直流馬達

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
chan_list = [29,31,33,35]
GPIO.setup(chan_list,GPIO.OUT)
GPIO.output(29, GPIO.HIGH)
GPIO.output(33, GPIO.HIGH)
GPIO.output(31, GPIO.HIGH)
GPIO.output(35, GPIO.HIGH)


import RPi.GPIO as GPIO
# 匯入樹莓派上的 GPIO 模組,才能使用樹莓派上的腳位

GPIO.setmode(GPIO.BOARD)
# 設定樹莓派上面的腳位編號規則,這邊使用 BOARD編號方式。
# BOARD編號方式:1~40 號實體位置編號。
# 還有另一種 BCM 的腳位編號規則,就是樹莓派板子上面 GPIO後面的數字

chan_list = [29,31,33,35]
# 設定要使用的腳位編號。( 陣列 )
# 如果只要使用 1 隻腳位,可以用 channel = 29

GPIO.setup(chan_list,GPIO.OUT)
# 將 chan_list 腳位定義為 輸出( OUT ) 模式

GPIO.output(29, GPIO.HIGH)
# 設定 29 號腳位為 高電位

GPIO.output(33, GPIO.LOW)
# 設定 31 號腳位為 低電位

GPIO.output(31, GPIO.HIGH)
# 設定 33 號腳位為 高電位

GPIO.output(35, GPIO.LOW)
# 設定 35 號腳位為 低電位
# 29、31 為控制 A 馬達驅動,高低、低高、低低、高高,各會讓馬達有不同動作。
# 33、35 為控制 B 馬達驅動,高低、低高、低低、高高,各會讓馬達有不同動作。


參考資料:
腳位 https://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-header-and-pins/
樹莓派使用說明 https://dsalearning.github.io/aiot/raspberry-rpi-gpio/