Tinker Board : PWM(서보모터) 제어

OS/Tinker Board 2018.09.02 16:13 Posted by 파란크리스마스

출처

Tinker Board S : PWM(서보모터) 제어

wiringPi라이브러리의 설치

$ git clone https://github.com/TinkerBoard/gpio_lib_c.git
$ cd gpio_lib_c/
$ chmod a+x build
$ sudo ./build
 
... 생략 ...
 
[Install Dynamic Lib]
 
GPIO Utility
[Compile] gpio.c
[Compile] readall.c
[Compile] pins.c
[Link]
[Install]
 
All Done.
 
NOTE: To compile programs with wiringPi, you need to add:
    -lwiringPi
  to your compile line(s) To use the Gertboard, MaxDetect, etc.
  code (the devLib), you need to also add:
    -lwiringPiDev
  to your compile line(s).

gpio readall

$ gpio readall
wiringPi: wiringPiSetup called
piGpioLayout: Hardware: Hardware        : Rockchip (Device Tree)
 
piGpioLayout: Revision string: Revision : 0000
piGpioLayout: last4Chars are: "0000"
piGpioLayoutOops: Returning revision: 2
piboardId: Revision string: Revision    : 0000
piBoardId: Old Way: revision is: 0000
piBoardId: 2: revision is: 0000
piboardId: Revision string: Revision    : 0000
piBoardId: Old Way: revision is: 0000
piBoardId: 2: revision is: 0000
 +-----+-----+---------+------+---+--Tinker--+---+------+---------+-----+-----+
 | CPU | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | CPU |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 | 252 |   8 |   SDA.1 |  I2C | 1 |  3 || 4  |   |      | 5v      |     |     |
 | 253 |   9 |   SCL.1 |  I2C | 1 |  5 || 6  |   |      | 0v      |     |     |
 |  17 |   7 | GPIO0C1 |   IN | 1 |  7 || 8  | 1 | SERL | TxD.1   | 15  | 161 |
 |     |     |      0v |      |   |  9 || 10 | 1 | SERL | RxD.1   | 16  | 160 |
 | 164 |   0 |  CTSN.4 | SERL | 1 | 11 || 12 | 0 | I2S  | I2S_CLK | 1   | 184 |
 | 166 |   2 |   TxD.4 | SERL | 1 | 13 || 14 |   |      | 0v      |     |     |
 | 167 |   3 |   RxD.4 | SERL | 1 | 15 || 16 | 1 | SERL | CTSN.1  | 4   | 162 |
 |     |     |    3.3v |      |   | 17 || 18 | 1 | SERL | RTSN.1  | 5   | 163 |
 | 257 |  12 |  MOSI.2 |  SPI | 0 | 19 || 20 |   |      | 0v      |     |     |
 | 256 |  13 |  MISO.2 |  SPI | 1 | 21 || 22 | 0 | IN   | GPIO5C3 | 6   | 171 |
 | 254 |  14 |  SCLK.2 |  SPI | 0 | 23 || 24 | 1 | SPI  | CE0.2   | 10  | 255 |
 |     |     |      0v |      |   | 25 || 26 | 1 | SPI  | CE1.2   | 11  | 251 |
 | 233 |  30 |   SDA.4 |  I2C | 1 | 27 || 28 | 1 | I2C  | SCL.4   | 31  | 234 |
 | 165 |  21 |  RTSN.4 | SERL | 1 | 29 || 30 |   |      | 0v      |     |     |
 | 168 |  22 | GPIO5C0 |   IN | 1 | 31 || 32 | 0 | OUT  | GPIO7C7 | 26  | 239 |
 | 238 |  23 |   PWM.2 |  PWM | 0 | 33 || 34 |   |      | 0v      |     |     |
 | 185 |  24 |  I2S_FS |  I2S | 0 | 35 || 36 | 1 | SERL | RxD.3   | 27  | 223 |
 | 224 |  25 |   TxD.3 | SERL | 1 | 37 || 38 | 1 | I2S  | I2S_SDI | 28  | 187 |
 |     |     |      0v |      |   | 39 || 40 | 0 | I2S  | I2S_SDO | 29  | 188 |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | CPU | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | CPU |
 +-----+-----+---------+------+---+--Tinker--+---+------+---------+-----+-----+

팅커 보드 용 Python GPIO 라이브러리 설치

$ wget http://github.com/TinkerBoard/gpio_lib_python/archive/sbc/tinkerboard/python.zip
$ sudo apt-get install python-dev
$ unzip python.zip
$ cd gpio_lib_python-sbc-tinkerboard-python/
$ sudo python setup.py install

py_gpio.c 소스 일부

PyMethodDef asuspi_gpio_methods[] = {
   {"setup", (PyCFunction)py_setup_channel, METH_VARARGS | METH_KEYWORDS, "Set up a GPIO channel or list of channels with a direction and (optional) pull/up down control\nchannel        - either board pin number ,RK number or ASUS number depending on which mode is set.\ndirection      - IN or OUT\n[pull_up_down] - PUD_OFF (default), PUD_UP or PUD_DOWN\n[initial]      - Initial value for an output channel"},
   {"cleanup", (PyCFunction)py_cleanup, METH_VARARGS | METH_KEYWORDS, "Clean up by resetting all GPIO channels that have been used by this program to INPUT with no pullup/pulldown and no event detection\n[channel] - individual channel or list/tuple of channels to clean up.  Default - clean every channel that has been used."},
   {"output", py_output_gpio, METH_VARARGS, "Output to a GPIO channel or list of channels\nchannel - either board pin number ,RK number or ASUS number depending on which mode is set.\nvalue   - 0/1 or False/True or LOW/HIGH"},
   {"input", py_input_gpio, METH_VARARGS, "Input from a GPIO channel.  Returns HIGH=1=True or LOW=0=False\nchannel - either board pin number ,RK number or ASUS number depending on which mode is set."},
   {"setmode", py_setmode, METH_VARARGS, "Set up numbering mode to use for channels.\nBOARD - Use ASUS Pi board numbers\nRK   - Use Broadcom GPIO 00..nn numbers"},
   {"getmode", py_getmode, METH_VARARGS, "Get numbering mode used for channel numbers.\nReturns BOARD, RK, ASUS or UNKNOWN"},
   {"add_event_detect", (PyCFunction)py_add_event_detect, METH_VARARGS | METH_KEYWORDS, "Enable edge detection events for a particular GPIO channel.\nchannel      - either board pin number ,RK number or ASUS number depending on which mode is set.\nedge         - RISING, FALLING or BOTH\n[callback]   - A callback function for the event (optional)\n[bouncetime] - Switch bounce timeout in ms for callback"},
   {"remove_event_detect", py_remove_event_detect, METH_VARARGS, "Remove edge detection for a particular GPIO channel\nchannel - either board pin number ,RK number or ASUS number depending on which mode is set."},
   {"event_detected", py_event_detected, METH_VARARGS, "Returns True if an edge has occured on a given GPIO.  You need to enable edge detection using add_event_detect() first.\nchannel - either board pin number ,RK number and ASUS number depending on which mode is set."},
   {"add_event_callback", (PyCFunction)py_add_event_callback, METH_VARARGS | METH_KEYWORDS, "Add a callback for an event already defined using add_event_detect()\nchannel      - either board pin number ,RK number or ASUS number depending on which mode is set.\ncallback     - a callback function"},
   {"wait_for_edge", (PyCFunction)py_wait_for_edge, METH_VARARGS | METH_KEYWORDS, "Wait for an edge.\nchannel      - either board pin number ,RK number or ASUS number depending on which mode is set.\nedge         - RISING, FALLING or BOTH\n[bouncetime] - time allowed between calls to allow for switchbounce"},
   {"gpio_function", py_gpio_function, METH_VARARGS, "Return the current GPIO function (IN, OUT, PWM, SERIAL, I2C, SPI)\nchannel - either board pin number ,RK number or ASUS number depending on which mode is set."},
   {"setwarnings", py_setwarnings, METH_VARARGS, "Enable or disable warning messages"},
   {"pwmWrite", py_pwmWrite, METH_VARARGS, "Writes the duty cycle to the PWM register for the given GPIO"},
   {"pwmToneWrite", py_pwmToneWrite, METH_VARARGS, "Creates a square wave with given frequency for the given GPIO"},
   {"pwmSetFrequency", py_pwmSetFrequency, METH_VARARGS, "Set up the frequency of PWM clock source."},
   {"pwmSetPeriod", py_pwmSetPeriod, METH_VARARGS, "Writes the period to the PWM register for the given GPIO."},
   {"setGpioDrive", py_setGpioDrive, METH_VARARGS, "Set up the drive strength for the given GPIO."},
   {"getGpioDrive", py_getGpioDrive, METH_VARARGS, "Return the current drive strength."},
   {NULL, NULL, 0, NULL}
};

PWM(서보모터) 제어 파이썬 예제

import ASUS.GPIO as GPIO
import time

GPIO.setmode(GPIO.ASUS)
GPIO.setwarnings(False)

myservo = 239

GPIO.setup(myservo,GPIO.OUT)
pwm = GPIO.PWM(myservo,50) # 50hz yani 20mslik periyod
pwm.start(2.5) # 0 derece

try:
        while True:
                print "0 derece"
                pwm.ChangeDutyCycle(2.5) #0 derece
                time.sleep(1) # wait 1sec
                print "90 derece"
                pwm.ChangeDutyCycle(7.5) #90 derece
                time.sleep(1)
                print "180 derece"
                pwm.ChangeDutyCycle(12.5) #180 derece
                time.sleep(1)
                print "90 derece"
                pwm.ChangeDutyCycle(7.5)
                time.sleep(1)
except KeyboardInterrupt:
        print "Hoscakal canim"
        GPIO.cleanup()

PWM(서보모터) 제어 Java 예제

import com.pi4j.wiringpi.Gpio;

public class ServoTest3 {
	
	private static int PIN_NUMBER = 239;
	
	public static void main(String[] args) throws Exception {
		//
		//GpioFactory.setDefaultProvider(new TinkerBoardGpioProvider());
		
		Gpio.wiringPiSetupGpio();

		Gpio.pinMode(PIN_NUMBER, Gpio.PWM_OUTPUT);
		Gpio.pwmSetMode(Gpio.PWM_MODE_MS);
		// 445 : 200 ~ 1000
		Gpio.pwmSetClock(445); // Gpio.pwmSetClock(400);
		Gpio.pwmSetRange(1024);
		
		int[] arr = {205, 570, 1000};

		while (true) {
			for (int i=0; i≪arr.length; i++) {
				Gpio.pwmWrite(PIN_NUMBER, arr[i]);
				Thread.sleep(300);
			}
		}
	}
}