總網頁瀏覽量

2014年11月16日 星期日

Arduino NFC/RFID = Arduino UNO + NFC Reader (PN532)


NFC/RFID 實驗在Arduino 上其實也很簡單, 這次利用PN532相容板來做實驗, 此塊板子支援 I2C 和 SPI介面, 我就來用 SPI 跟Arduino連接! 參考下圖:

Arduino       PN532
    D10  ------>  SS
    D11  ------>  MOSI
    D12  ------>  MISO
    D13  ------>  SCK
     5V  ------->  5V
    GND ------>  GND






Sketch 範例程式:

 #include <arduino.h>
#include <PN532.h>

#define SCK 13
#define MOSI 11
#define SS 10
#define MISO 12

PN532 nfc(SCK, MISO, MOSI, SS);

void setup(void) {
    Serial.begin(9600);
    Serial.println("Hello!");

    nfc.begin();

    uint32_t versiondata = nfc.getFirmwareVersion();
    if (! versiondata) {
        Serial.print("Didn't find PN53x board");
        while (1); // halt
    }
    // Got ok data, print it out!
    Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
    Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
    Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
    Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);

    // configure board to read RFID tags and cards
    nfc.SAMConfig();
}


void loop(void) {
    uint32_t id;
    // look for MiFare type cards
    id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);

    if (id != 0) {
        Serial.print("Read card #"); Serial.println(id);
    }
}


PN532 arduino library 下載點 here.

很簡單! 拿起 NFC tag 感應一下就會跑出 Card id.


2014年10月28日 星期二

傳統伺服馬達(Servo) 改造成 可回饋位置伺服馬達(Smart Servo) Servo Hacked!


幾個月前買了幾顆二手伺服馬達  HITEC HS-311, 今天就來Hacked成可以角度回饋伺服馬達!
市售HS-311 也有新舊版之分(難道是山寨之分?)如下圖.
           

外殼拆開後可以看出電路板走線及IC也不一樣(如下圖), 不過沒關係這種類比伺服馬達原理都一樣利用VR Encoder(可變電阻)來回授位置!


只要找到Encoder回授信號(電壓值)位置,焊條電線連接出來即可以取的馬達轉動位置電壓值,
利用此電壓值可以換算馬達目前處於哪個角度位置, 焊接位置請參考下圖!


焊接線完後整理外殼出線位置,讓回饋電線容易拉出及蓋上外殼,如下圖!



接下來開始寫程式量測回饋訊號電壓及算出角度,Arduino參考程式如下,程式不難容易理解,
把回饋線路接到Arduino A0位置, 主要針對角度 0, 45, 90, 135, 和 180度取得回饋電壓值!


#include <Servo.h>

//servo object
Servo myservo;

//servo position
int pos = 0;
//positions (in degrees) to send to the servo
int positions[] = {0, 45, 90, 135, 180};
int numPositions = 5;

int numMeasurements = 1;
//increase this value to read feedback multiple times and then calculate the arithmetic average

void setup()
{
  //control servo via pin 9
  myservo.attach(3, 650, 2350);
  //start serial comm. for debugging
  Serial.begin(9600);
}

void loop()
{
  int i = 0;
  //iterate over positions
  for(i = 0; i < numPositions; i++)
  {
    pos = positions[i];
    int j = 0;
    double sum = 0;
    double sensorValue = 0;
 
    Serial.print("SETTING:");
    Serial.println(pos);
    myservo.write(pos);
 
    //wait a bit, to give the servo time to reach the requested position
    delay(800);
 
    //read the feedback via A0, once or multiple times
    for(j = 0; j<numMeasurements; j++){
      sum += analogRead(A0);
    }
 
    //calculate average if numMeasurements > 1
    sensorValue = (sum/numMeasurements);
    Serial.print("READ:");
    Serial.println(sensorValue);
 
    //wait for three seconds
    delay(3000);
  }

}


如果調整修改好程式,基本上smart motor改造完成, 可以利用下面程式換算成角度,角度多少會有誤差幾度!

#include <Servo.h>
#include <math.h>

//servo object
Servo myservo;

//servo position
int pos = 0;
//positions (in degrees) to send to the servo
int positions[] = {0, 45, 90, 135, 180};
int numPositions = 5;

int numMeasurements = 5;

//HS-311 servo parameters
int zero_degrees = 98;  // HS-311 New version: 94; Old version: 98
double one_degree = 1.5111;//HS-311 New Version: 1.4889; Old version: 1.51111;

void setup()
{
  //control servo via pin 9
  myservo.attach(3, 650, 2350);
  //start serial comm. for debugging
  Serial.begin(9600);
}

void loop()
{
  int i = 0;
  //iterate over positions
  for(i = 0; i < numPositions; i++)
  {
    pos = positions[i];
    int j = 0;
    double sum = 0;
    double sensorValue = 0;
 
    Serial.println("SETTING:");
    Serial.println(pos);
    myservo.write(pos);
 
    //wait a bit, to give the servo time to reach the requested position
    delay(800);
 
    //read the feedback via A0, once or multiple times
    for(j = 0; j<numMeasurements; j++){
      sum += analogRead(A0);
    }
 
    //calculate average if numMeasurements > 1
    sensorValue = (sum/numMeasurements);
    Serial.println("READ:");
    Serial.println(calcH311ServoPosition(sensorValue));
 
    //wait for three seconds
    delay(3000);
  }

}

double calcH311ServoPosition(double val){
  val -= zero_degrees;
  val /= one_degree;
  val = floor(val);

  return val;
}


這樣就可以DIY製作出一顆可回授位置的伺服馬達!!











2014年10月7日 星期二

Kozig LED I2C介面的七段顯示器: 修改I2C Address

使用I2C 介面的七段顯示器顯示數字最方便不過了! 此款I2C LED Display 便宜又好用,這次來說明如何修改 I2C Address, 通常買來Address為 0x27.



步驟如下:

1.斷電情況下將SCL接到GND, SDA接A4.
2.接通電源,顯示 -51- 時,表示進入設定新地址模式.
3.再將原來SCL接GND改接到A5.
4.執行 SEG8B4A036A_SetAddress, (ztlib example)結束時會顯示新位置.
    (下載I2C LED 的 Arduino Library)
5. 移除電源,LED 模組已改成新位址!






Motoduino 把此I2C LED連接使用簡單化, 可以利用RJ11 電話線接到 IO Board 的 A4,A5孔位即可使用.




2014年9月27日 星期六

Arduino I2C LCD 20x4 lines Display


這來試試 LCD 20x4 lines, 利用Arduino加上 IO Board 接線方便許多!
可顯示的字元比 常用LCD 16x2 lines 多許多!




步驟一: 下載 I2C LCD library, 解壓縮後放入Arduino Libraries內

步驟二:  撰寫程式如下:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// set the LCD address to 0x20 for a 20 chars 4 line display

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
//假設 I2C address 0x27

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);  /

  lcd.begin(20,4);  
  for(int i = 0; i< 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight();

  lcd.setCursor(3,0); //Start at character 4 on line 0
  lcd.print("Motoduino Lab!");
  lcd.setCursor(2,1);
  lcd.print("www.motoduino.com");
  lcd.setCursor(0,2);
  lcd.print("20x4 LCD Display");
  lcd.setCursor(0,3);
  lcd.print("I2C Interface");

}/*--(end setup )---*/


void loop()
{

}



2014年9月25日 星期四

香蕉派 (Banana Pi) 搭配 MotoPiduino 使用 UART/Serial Console


最近拿到一塊 Banana Pi, 馬上就先拿來搭配MotoPiduino, 如果想要利用Serial Console 下命令, 則必須修改 debug 用的 UART Port. 在樹莓派 Raspberry Pi上 只有一個 UART0, 但是在Banana Pi上UART0是不在 26Pin GPIO上(對應Raspberry Pi GPIO)而是在 UART2, 所以就來把Debug UART0 改成 UART2位置,這樣就跟Raspberry 一樣debug UART位置GPIO 26pin.

步驟:

1.硬體接線請參考
 





二. 修改 inittab 檔案



三. 修改檔案 inittab 最後一行,  ttyS0 改成 ttyS2,  存檔後Banana Pi關機!


四. 接線換位置如下圖:

  

五. 重新啓動後初始化訊息還是會從UART0輸出,但是過二三十秒後, PC上的Serial Console (Putty 或 Serial Minitor軟體)會顯示 login 訊息, 此時輸入 bananapi,  password也是輸入bananapi, 就進入Console 模式.


http://www.motoduino.com


2014年8月3日 星期日

Raspberry Pi Software PWM Control = Raspberry Pi (樹莓派) + MotoPiduino + DC Motor

這個實驗主要利用 RPi.GPIO 的函數庫來實現 PWM 功能, 也就是用軟體模擬 PWM功能, Raspberry Pi只有一 IO 腳位有硬體 PWM, 如需要多個PWM功能可以利用 Softrware PWM.

一.  使用材料 : 
1.      MotoPiduino
2.      Raspberry Pi
3.      5V power
4.      5V DC Motor





二. 程式: 編寫Python 程式 motor_pwm.py 

import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode(GPIO.BOARD)

GPIO.setup(11, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)

p11=GPIO.PWM(11, 100)
p12=GPIO.PWM(12, 100)

p11.start(0)
p12.start(0)

try:
    while True:
        for i in range(0, 101):
          p11.ChangeDutyCycle(i)
          p12.ChangeDutyCycle(i)
          GPIO.output(13, False)
          GPIO.output(15, False)
          sleep(0.2)
        for i in range(100,-1,-1):
          p11.ChangeDutyCycle(i)
          p12.ChangeDutyCycle(i)
          GPIO.output(13, False)
          GPIO.output(15, False)
          sleep(0.2)

except KeyboardInterrupt:
        p11.stop()
        p12.stop()
        GPIO.output(11, 0)
        GPIO.output(12, 0)
        GPIO.output(13, 0)
        GPIO.output(15, 0)
        GPIO.cleanup()
          

三. 執行:
 $ sudo python motor_pwm.py


      Information : http://www.motoduino.com




2014年7月6日 星期日

android 手機遙控車 = Motoduino (Arduino + L293D) + bluetooth (藍牙) + 19cm 圓形車體

這次挑選一款品質還不錯的車體來做Android手機遙控車!

一.  使用材料 : (材料購買網站)
1.      Motoduino 或  Arduino + 馬達驅動板
2.      TTL藍芽模組
3.      9V電池一顆  電池釦線
4.      USB傳輸線 (下載程式用)
5.      小車體套件包

完成圖:
    




二. 安裝過程:


Step 1
        圖一是所有組裝材料首先可以先把車子底盤兩面的土黃色貼紙撕下,需要花點時間撕下因為黏膠很強,或不撕保持貼紙在上面也可以。




圖一


Step 2:
       利用螺絲及馬達固定鐵片先固定在車子底盤上,以及兩個舵輪如圖二圖三


圖二 (車體底部)



圖三 (車體頂部)

Step 3:
       四顆電池盒先固定於下層板(圖四),再利用最長的螺絲把馬達固定在L型鐵片上


圖四



Step 4:
       組裝最上層底板及利用兩根螺絲固定Motoduino於板子如圖五

圖五

Step 5:
       連接馬達線路如圖六。電池盒電線可以不用接到板子上,如果要接上提供馬達電源則需把J5的Jump跳到Ext. Vin的位置(板子內設為馬達電源板子提供)

圖六



Motoduino介紹網站: http://www.motoduino.com (source code下載處)




2014年5月2日 星期五

樹莓派PIR 紅外線人體感測( Motion Detection) = PIR Sensor + MotoPiduino + Raspberry Pi

由於一般市售PIR紅外線大都是 3.3V輸出,也就是感測到移動物體時輸出 3.3V, 沒感測到時輸出 0V, 所以在MotoPiduino 板子上直接接到數位IO腳位無法判讀輸出結果,因為未達5V電壓, 此MotoPiduino是把5V電壓轉換成 3.3V樹莓派可以運作的電位. 如此我們可以利用類比IO腳位來判讀是否偵測到移動物體.

一. 使用材料:
       1. Raspberry Pi
       2. MotoPiduino
       3. PIR 紅外線感測器
       4. S4A IO Board (option)

二. 接線:
      1. 把 PIR 接到 MotoPiduino A0 位置
       或
      直接接到 S4A IO Board 的 A0 孔位

三. 接線方式如圖:








四. I2C Library 軟體下載點:
1. 下載 ADS1015 (I2C) Library : https://github.com/m3m0ry/Adafruit-Raspberry-Pi-Python-Code
2. 編寫Python PIR 程式 my_PIR_sensor.py 如下(請該檔案建立在adafruit_ADS1x15目錄下)

import time, signal, sys
from Adafruit_ADS1x15 import ADS1x15

def signal_handler(signal, frame):
        print 'You pressed Ctrl+C!'
        sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
#print 'Press Ctrl+C to exit'

ADS1015 = 0x00  # 12-bit ADC

adc = ADS1x15(ic=ADS1015)

while True:
  # Read channel 0 in single-ended mode, +/-4.096V, 250sps
  volts = adc.readADCSingleEnded(0, 4096, 250) / 1000

  print "Channel 0 = %.6f" % (volts)
  if(volts > 3.0):
    print "Detected something..."
  else:
    print "detected nothing..."
 
  time.sleep(1)


五. 執行:
 $ sudo python my_PIR_sensor.py




Informatiom:  http://www.motoduino.com


2014年4月25日 星期五

樹莓派超音波測距 = Raspberry + Ultrasonic HC-SR04 + MotoPiduino


一. 使用材料:
       1. Raspberry Pi
       2. MotoPiduino
       3. 超音波 HC-SR04
       4. S4A IO Board (option)

二. 接線:
      1. 把 HC-SR04 接到 MotoPiduino D10 及 D11 位置, (樹莓派 GPIO8(TRIGGER) 和 GPIO10(ECHO) 位置)
       或
      直接接到 S4A IO Board 的 D10 D11孔位

三. 接線方式如圖:
     
      



4. 編寫程式:
# -----------------------

# Import required Python libraries
# -----------------------
import time
import RPi.GPIO as GPIO

# -----------------------
# Define some functions
# -----------------------

def measure():
  # This function measures a distance

  GPIO.output(GPIO_TRIGGER, True)
  time.sleep(0.00001)
  GPIO.output(GPIO_TRIGGER, False)
  start = time.time()
  
  while GPIO.input(GPIO_ECHO)==0:
    start = time.time()

  while GPIO.input(GPIO_ECHO)==1:
    stop = time.time()

  elapsed = stop-start
  distance = (elapsed * 34300)/2

  return distance

def measure_average():
  # This function takes 3 measurements and
  # returns the average.

  distance1=measure()
  time.sleep(0.1)
  distance2=measure()
  time.sleep(0.1)
  distance3=measure()
  distance = distance1 + distance2 + distance3
  distance = distance / 3
  return distance

# -----------------------
# Main Script
# -----------------------

# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)

# Define GPIO to use on Pi
GPIO_TRIGGER = 8
GPIO_ECHO    = 10

print "Ultrasonic Measurement"

# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

try:

  while True:

    distance = measure_average()
    print "Distance : %.1f" % distance
    time.sleep(1)

except KeyboardInterrupt:
  # User pressed CTRL-C
  # Reset GPIO settings
  GPIO.cleanup()


五. 相關資訊:
相關資訊: http://motoduino.com


2014年4月17日 星期四

樹莓派LCD顯示器 = Raspberry Pi + MotoPiduino + I2C LCD 16x2

這次來說明如何把I2C LCD1602接到 Raspberry 上顯示文字及IP address, I2C LCD好處只需要佔用2支IO腳位.

一. 使用材料:
       1. Raspberry Pi
       2. MotoPiduino
       3. I2C LCD1602
       4. S4A Sensor Board (option)

二. 接線:
      1. 把 LCD1602 接到 A4 (SDA) and A5 (SCL) 位置
       或
      直接接到 S4A IO Board 的 A4A5孔位

三. 接線方式如圖:
     





四. I2C LCD Library 軟體下載點:
1. 建立一個目錄及下載程式: https://github.com/paulbarber/raspi-gpio
2. 檢查LCD的 I2C 位置(需事先開啟I2C功能), 此例子為0x27, 如下圖:



     3. 修改 lcd_display.py 內的LCD ADDRESS 如下圖:

         


     4. 編寫LCD 測試程式 lcd_i2c_test.py 如下(請將該檔案建立在剛下載的Library目錄下)


       from lcd_display import lcd
       from subprocess import *

       my_lcd = lcd()

       cmd = "ip addr show wlan0 | grep inet | awk '{print $2}' | cut -d/ -f1"

       def run_cmd(cmd):
       p = Popen(cmd, shell=True, stdout=PIPE)
       output = p.communicate()[0]
       return output

       ipaddr = run_cmd(cmd)
       ipaddrstr = 'IP:' + ipaddr 
       my_lcd.display_string("Motoduino Lab", 1)
       my_lcd.display_string(ipaddrstr, 2)




五. 執行:
 $ sudo python lcd_i2c_test.py





相關資訊: http://motoduino.com