728x90

출처 : Raspberry Pi + Arduino + SPI - MitchTech | MitchTech

배선

소스 - Arduino (Slave)

// Written by Nick Gammon
// February 2011
/**
 * Send arbitrary number of bits at whatever clock rate (tested at 500 KHZ and 500 HZ).
 * This script will capture the SPI bytes, when a '\n' is recieved it will then output
 * the captured byte stream via the serial.
 */

#include <SPI.h>

char buf [100];
volatile byte pos;
volatile boolean process_it;

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

  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);
  
  // turn on SPI in slave mode
  SPCR |= _BV(SPE);
  
  // get ready for an interrupt 
  pos = 0;   // buffer empty
  process_it = false;

  // now turn on interrupts
  SPI.attachInterrupt();

}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR;  // grab byte from SPI Data Register
  
  // add to buffer if room
  if (pos < sizeof buf)
    {
    buf [pos++] = c;
    
    // example: newline means time to process buffer
    if (c == '\n')
      process_it = true;
      
    }  // end of room available
}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  if (process_it)
    {
    buf [pos] = 0;  
    Serial.println (buf);
    pos = 0;
    process_it = false;
    }  // end of flag set
    
}  // end of loop

소스 - Raspberry PI (Master)

/*
 * SPI testing utility (using spidev driver)
 *
 * Copyright (c) 2007  MontaVista Software, Inc.
 * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 *
 * Cross-compile with cross-gcc -I/path/to/cross-kernel/include
 */

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static void pabort(const char *s)
{
	perror(s);
	abort();
}

static const char *device = "/dev/spidev0.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
static uint16_t delay;

static void transfer(int fd)
{
	int ret;
	uint8_t tx[] = {
        0x48, 0x45, 0x4C, 0x4C, 0x4F,
        0x20, 
        0x57, 0x4F, 0x52, 0x4C, 0x44,
        0x0A 
	};
	uint8_t rx[ARRAY_SIZE(tx)] = {0, };
	struct spi_ioc_transfer tr = {
		.tx_buf = (unsigned long)tx,
		.rx_buf = (unsigned long)rx,
		.len = ARRAY_SIZE(tx),
		.delay_usecs = delay,
		.speed_hz = speed,
		.bits_per_word = bits,
	};

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	if (ret < 1)
		pabort("can't send spi message");

    /*
	for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
		if (!(ret % 6))
			puts("");
		printf("%.2X ", rx[ret]);
	}
	puts("");
    */
}

static void print_usage(const char *prog)
{
	printf("Usage: %s [-DsbdlHOLC3]\n", prog);
	puts("  -D --device   device to use (default /dev/spidev1.1)\n"
	     "  -s --speed    max speed (Hz)\n"
	     "  -d --delay    delay (usec)\n"
	     "  -b --bpw      bits per word \n"
	     "  -l --loop     loopback\n"
	     "  -H --cpha     clock phase\n"
	     "  -O --cpol     clock polarity\n"
	     "  -L --lsb      least significant bit first\n"
	     "  -C --cs-high  chip select active high\n"
	     "  -3 --3wire    SI/SO signals shared\n");
	exit(1);
}

static void parse_opts(int argc, char *argv[])
{
	while (1) {
		static const struct option lopts[] = {
			{ "device",  1, 0, 'D' },
			{ "speed",   1, 0, 's' },
			{ "delay",   1, 0, 'd' },
			{ "bpw",     1, 0, 'b' },
			{ "loop",    0, 0, 'l' },
			{ "cpha",    0, 0, 'H' },
			{ "cpol",    0, 0, 'O' },
			{ "lsb",     0, 0, 'L' },
			{ "cs-high", 0, 0, 'C' },
			{ "3wire",   0, 0, '3' },
			{ "no-cs",   0, 0, 'N' },
			{ "ready",   0, 0, 'R' },
			{ NULL, 0, 0, 0 },
		};
		int c;

		c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);

		if (c == -1)
			break;

		switch (c) {
		case 'D':
			device = optarg;
			break;
		case 's':
			speed = atoi(optarg);
			break;
		case 'd':
			delay = atoi(optarg);
			break;
		case 'b':
			bits = atoi(optarg);
			break;
		case 'l':
			mode |= SPI_LOOP;
			break;
		case 'H':
			mode |= SPI_CPHA;
			break;
		case 'O':
			mode |= SPI_CPOL;
			break;
		case 'L':
			mode |= SPI_LSB_FIRST;
			break;
		case 'C':
			mode |= SPI_CS_HIGH;
			break;
		case '3':
			mode |= SPI_3WIRE;
			break;
		case 'N':
			mode |= SPI_NO_CS;
			break;
		case 'R':
			mode |= SPI_READY;
			break;
		default:
			print_usage(argv[0]);
			break;
		}
	}
}

int main(int argc, char *argv[])
{
	int ret = 0;
	int fd;

	parse_opts(argc, argv);

	fd = open(device, O_RDWR);
	if (fd < 0)
		pabort("can't open device");

	/*
	 * spi mode
	 */
	ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
	if (ret == -1)
		pabort("can't set spi mode");

	ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
	if (ret == -1)
		pabort("can't get spi mode");

	/*
	 * bits per word
	 */
	ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't set bits per word");

	ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
	if (ret == -1)
		pabort("can't get bits per word");

	/*
	 * max speed hz
	 */
	ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't set max speed hz");

	ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
	if (ret == -1)
		pabort("can't get max speed hz");

	printf("spi mode: %d\n", mode);
	printf("bits per word: %d\n", bits);
	printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

	transfer(fd);

	close(fd);

	return ret;
}

컴파일

$ gcc spidev_test.c -o spidev_test

실행

$ sudo ./spidev_test
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

결과

728x90
728x90

출처 : Analog Read Serial

배선

소스

/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Graphical representation is available using serial plotter (Tools > Serial Plotter menu)
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 1:
  int sensorValue = analogRead(A1);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}

결과

728x90
728x90

출처 : Raspberry Pi SPI and I2C Tutorial
Use the Adafruit PCA9685 with a Raspberry PI, in Java Raspberry PI to drive up to 16 servos
JavaScript Robotics: Servo - PCA9685

I2C on Pi

$ sudo raspi-config

i2c device 활성화

$ sudo vi /etc/modules

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

i2c-bcm2708
i2c-dev

gpio commands

$ gpio -v
gpio version: 2.32
Copyright (c) 2012-2015 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty
 
Raspberry Pi Details:
  Type: Model B, Revision: 03, Memory: 512MB, Maker: Egoman 
  * Device tree is enabled.
  * This Raspberry Pi supports user-level GPIO access.
    -> See the man-page for more details
    -> ie. export WIRINGPI_GPIOMEM=1
$ gpio readall
 +-----+-----+---------+------+---+-Model B2-+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5V      |     |     |
 |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT0 | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |  28 |  17 | GPIO.17 |   IN | 0 | 51 || 52 | 0 | IN   | GPIO.18 | 18  | 29  |
 |  30 |  19 | GPIO.19 |   IN | 0 | 53 || 54 | 0 | IN   | GPIO.20 | 20  | 31  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+-Model B2-+---+------+---------+-----+-----+

detect I2C chips

출처 : i2cdetect(8): detect I2C chips - Linux man page

$ ls /dev/*i2c*
/dev/i2c-1
$ sudo apt-get install -y i2c-tools
$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- -- 

배선

PCA9685Gpio.java

출처 : wyliodrin-server-nodejs/libs/raspberrypi/java/pi4j/examples/PCA9685GpioExample.java

package com.bluexmas.arm;

import java.io.IOException;

/**
 * sudo java -cp .:pi4j-core.jar:pi4j-device.jar:pi4j-gpio-extension.jar:pi4j-service.jar com.bluexmas.arm.PCA9685Gpio
 */
import java.math.BigDecimal;

import com.pi4j.gpio.extension.pca.PCA9685GpioProvider;
import com.pi4j.gpio.extension.pca.PCA9685Pin;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinPwmOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CFactory;
import com.pi4j.io.i2c.I2CFactory.UnsupportedBusNumberException;

public class PCA9685Gpio {
	
	private static final int SERVO_DURATION_MIN = 650;
	private static final int SERVO_DURATION_NEUTRAL = 1500;
	private static final int SERVO_DURATION_MAX = 2100;
	
	private static PCA9685Gpio instance = null;
	
	private PCA9685GpioProvider gpioProvider = null;
	
	private PCA9685Gpio() throws IOException, UnsupportedBusNumberException {		
		System.out.println("<--Pi4J--> PCA9685 PWM Example ... started.");
		// This would theoretically lead into a resolution of 5 microseconds per
		// step:
		// 4096 Steps (12 Bit)
		// T = 4096 * 0.000005s = 0.02048s
		// f = 1 / T = 48.828125
		BigDecimal frequency = new BigDecimal("48.828");
		// Correction factor: actualFreq / targetFreq
		// e.g. measured actual frequency is: 51.69 Hz
		// Calculate correction factor: 51.65 / 48.828 = 1.0578
		// --> To measure actual frequency set frequency without correction
		// factor(or set to 1)
		BigDecimal frequencyCorrectionFactor = new BigDecimal("1.0578");
		// Create custom PCA9685 GPIO provider
		I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1);
		gpioProvider = new PCA9685GpioProvider(bus, 0x40, frequency, frequencyCorrectionFactor);
		// Define outputs in use for this example
		GpioPinPwmOutput[] myOutputs = provisionPwmOutputs(gpioProvider);
		// Reset outputs
		gpioProvider.reset();
	}
	
	public static PCA9685Gpio getInstance() throws IOException, UnsupportedBusNumberException {
		if (instance==null) instance = new PCA9685Gpio();
		return instance;
	}
	
	public void setPwm(Pin pin, int duration) {
		gpioProvider.setPwm(pin, duration);
	}
	
	public void shutdown() {
		gpioProvider.shutdown();
	}
	
	private static GpioPinPwmOutput[] provisionPwmOutputs(final PCA9685GpioProvider gpioProvider) {
		GpioController gpio = GpioFactory.getInstance();
		GpioPinPwmOutput myOutputs[] = { 
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_00, "Pulse 00"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_01, "Pulse 01"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_02, "Pulse 02"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_03, "Pulse 03"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_04, "Pulse 04"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_05, "Pulse 05"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_06, "Pulse 06"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_07, "Pulse 07"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_08, "Pulse 08"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_09, "Pulse 09"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_10, "Always ON"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_11, "Always OFF"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_12, "Servo pulse MIN"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_13, "Servo pulse NEUTRAL"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_14, "Servo pulse MAX"),
				gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_15, "not used") };
		return myOutputs;
	}

	public static void main(String[] args) throws Exception {
		
		PCA9685Gpio test = PCA9685Gpio.getInstance();
		
		test.setPwm(PCA9685Pin.PWM_00, SERVO_DURATION_MIN);
		// Set 1.5ms pulse (R/C Servo neutral position)
		Thread.sleep(2000);
		test.setPwm(PCA9685Pin.PWM_00, SERVO_DURATION_NEUTRAL);
		// Set 2.1ms pulse (R/C Servo maximum position)
		Thread.sleep(2000);
		test.setPwm(PCA9685Pin.PWM_00, SERVO_DURATION_MAX);
		Thread.sleep(2000);
		test.setPwm(PCA9685Pin.PWM_00, SERVO_DURATION_MIN);
		Thread.sleep(2000);
		test.shutdown();
	}
	
}

실행

$ sudo java -cp .:pi4j-core.jar:pi4j-gpio-extension.jar com.bluexmas.arm.PCA9685Gpio
<--Pi4J--> PCA9685 PWM Example ... started.

728x90
728x90

출처 : java - read temperature from DHT11, using pi4j - Stack Overflow

pi4j 다운로드

$ mkdir pi4j
$ cd pi4j
$ wget http://get.pi4j.com/download/pi4j-1.0.zip
--2016-07-09 16:59:31--  http://get.pi4j.com/download/pi4j-1.0.zip
Resolving get.pi4j.com (get.pi4j.com)... 54.231.114.185
Connecting to get.pi4j.com (get.pi4j.com)|54.231.114.185|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3807428 (3.6M) [application/zip]
Saving to: ‘pi4j-1.0.zip.1’
 
pi4j-1.0.zip.1      100%[=====================>]   3.63M   544KB/s   in 6.4s   
 
2016-07-09 16:59:38 (581 KB/s) - ‘pi4j-1.0.zip.1’ saved [3807428/3807428]
 
$ unzip pi4j-1.0.zip 

핀 연결

   

DHT11.java

import java.util.List;
import java.util.ArrayList;

import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.GpioUtil;

public class DHT11 {
	private static final int MAXTIMINGS = 85;
	private int[] dht11_dat = { 0, 0, 0, 0, 0 };

	public DHT11() {

	    // setup wiringPi
	    if (Gpio.wiringPiSetup() == -1) {
	        System.out.println(" ==>> GPIO SETUP FAILED");
	        return;
	    }

	   GpioUtil.export(3, GpioUtil.DIRECTION_OUT);            
	}

	public void getTemperature() {
	   int laststate = Gpio.HIGH;
	   int j = 0;
	   dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
	   StringBuilder value = new StringBuilder();

	   Gpio.pinMode(3, Gpio.OUTPUT);
	   Gpio.digitalWrite(3, Gpio.LOW);
	   Gpio.delay(18);

	   Gpio.digitalWrite(3, Gpio.HIGH);        
	   Gpio.pinMode(3, Gpio.INPUT);

	   for (int i = 0; i < MAXTIMINGS; i++) {
	      int counter = 0;
	      while (Gpio.digitalRead(3) == laststate) {
	          counter++;
	          Gpio.delayMicroseconds(1);
	          if (counter == 255) {
	              break;
	          }
	      }

	      laststate = Gpio.digitalRead(3);

	      if (counter == 255) {
	          break;
	      }

	      /* ignore first 3 transitions */
	      if ((i >= 4) && (i % 2 == 0)) {
	         /* shove each bit into the storage bytes */
	         dht11_dat[j / 8] <<= 1;
	         if (counter > 16) {
	             dht11_dat[j / 8] |= 1;
	         }
	         j++;
	       }
	    }
	    // check we read 40 bits (8bit x 5 ) + verify checksum in the last
	    // byte
	    if ((j >= 40) && checkParity()) {
	        float h = (float)((dht11_dat[0] << 8) + dht11_dat[1]) / 10;
	        if ( h > 100 )
	        {
	            h = dht11_dat[0];   // for DHT11
	        }
	        float c = (float)(((dht11_dat[2] & 0x7F) << 8) + dht11_dat[3]) / 10;
	        if ( c > 125 )
	        {
	            c = dht11_dat[2];   // for DHT11
	        }
	        if ( (dht11_dat[2] & 0x80) != 0 )
	        {
	            c = -c;
	        }
	        float f = c * 1.8f + 32;
	        System.out.println( "Humidity = " + h + " Temperature = " + c + "(" + f + "f)");
	    }else  {
	        System.out.println( "Data not good, skip" );
	    }

	}

	private boolean checkParity() {
	  return (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF));
	}



	public static void main (String ars[]) throws Exception {

	    DHT11 dht = new DHT11();

	    for (int i=0; i<10; i++) {
	       Thread.sleep(2000);
	       dht.getTemperature();
	    }

	    System.out.println("Done!!");

	}
}

컴파일

$ javac -cp pi4j-1.0/lib/pi4j-core.jar DHT11.java 

실행

$ sudo java -cp .:pi4j-1.0/lib/pi4j-core.jar DHT11 
Humidity = 56.0 Temperature = 32.0(89.6f)
Data not good, skip
Humidity = 53.0 Temperature = 31.0(87.8f)
Data not good, skip
Humidity = 52.0 Temperature = 31.0(87.8f)
Humidity = 52.0 Temperature = 31.0(87.8f)
Data not good, skip
Humidity = 51.0 Temperature = 31.0(87.8f)
Humidity = 51.0 Temperature = 31.0(87.8f)
Data not good, skip
Done!!

GPIO 핀 배열

728x90
728x90

출처 : rpi_HC-SR501/src/main/java/org/jboss/summit2015/hcsr501/MotionSensor.java

pi4j 다운로드

$ mkdir pi4j
$ cd pi4j
$ wget http://get.pi4j.com/download/pi4j-1.0.zip
--2016-07-09 16:59:31--  http://get.pi4j.com/download/pi4j-1.0.zip
Resolving get.pi4j.com (get.pi4j.com)... 54.231.114.185
Connecting to get.pi4j.com (get.pi4j.com)|54.231.114.185|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3807428 (3.6M) [application/zip]
Saving to: ‘pi4j-1.0.zip.1’
 
pi4j-1.0.zip.1      100%[=====================>]   3.63M   544KB/s   in 6.4s   
 
2016-07-09 16:59:38 (581 KB/s) - ‘pi4j-1.0.zip.1’ saved [3807428/3807428]
 
$ unzip pi4j-1.0.zip 

핀 배치

MotionSensor.java

import com.pi4j.io.gpio.*;
import com.pi4j.io.gpio.trigger.GpioCallbackTrigger;

import java.util.concurrent.Callable;

/**
 * Use the pi4j classes to watch a gpio trigger. This uses the pin number scheme as outlined in:
 * http://pi4j.com/pins/model-2b-rev1.html
 */
public class MotionSensor {
    public static void main(String[] args) throws InterruptedException {

        System.out.printf("PIR Module Test (CTRL+C to exit)\n");

        // create gpio controller
        final GpioController gpio = GpioFactory.getInstance();
        // provision gpio pin #29, (header pin 40) as an input pin with its internal pull down resistor enabled
        final GpioPinDigitalInput pir = gpio.provisionDigitalInputPin(RaspiPin.GPIO_29);
        System.out.printf("Ready\n");

        // create a gpio callback trigger on the gpio pin
        Callable<Void> callback = () -> {
            System.out.println(" --> GPIO TRIGGER CALLBACK RECEIVED ");
            return null;
        };
        // create a gpio callback trigger on the PIR device pin for when it's state goes high
        pir.addTrigger(new GpioCallbackTrigger(PinState.HIGH, callback));

        // stop all GPIO activity/threads by shutting down the GPIO controller
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.out.println("Interrupted, stopping...\n");
                gpio.shutdown();
            }
        });

        // keep program running until user aborts (CTRL-C)
        for (;;) {
            Thread.sleep(100);
        }

    }
}

컴파일

$ javac -cp pi4j-1.0/lib/pi4j-core.jar MotionSensor.java 

실행

$ sudo java -cp .:pi4j-1.0/lib/pi4j-core.jar MotionSensor
PIR Module Test (CTRL+C to exit)
Ready
 --> GPIO TRIGGER CALLBACK RECEIVED 
 --> GPIO TRIGGER CALLBACK RECEIVED 
^CInterrupted, stopping...

GPIO 핀 배열

728x90
728x90

출처 : Rednics Blog - 보안이 적용되지 않은 간단한 웹 어플리케이션 생성

WEB-INF\web.xml

	<!-- 스프링 스큐리티 관련 설정 / 시작 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/iot-datasource.xml <!-- DB 접속 정보 -->
			/WEB-INF/iot-mybatis.xml    <!-- 사용자조회에서 사용 -->
			/WEB-INF/iot-security.xml   <!-- 스프링 스큐리티 설정 -->
		</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy
		</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 스프링 스큐리티 관련 설정 / 종료 -->

WEB-INF\iot-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:security="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.2.xsd">

	<!-- 참고 사이트 http://springsource.tistory.com/77 -->

	<security:http pattern="/*.html" security="none" />
	<security:http pattern="/resources/**/*" security="none" />
	<security:http pattern="/login.do" security="none" />
	<security:http pattern="/loginfailed.do" security="none" />
	<security:http pattern="/logout.do" security="none" />
	
	<security:http auto-config="true">
		<security:intercept-url pattern="/favicon.ico" access="ROLE_ANONYMOUS" />
		<security:intercept-url pattern="/**" access="ROLE_USER" />
		<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />

		<security:form-login login-page="/login.do" default-target-url="/ShoppingMall2.do" authentication-failure-url="/loginfailed.do" />
		<security:logout logout-success-url="/logout.do" />
	</security:http>

	<security:authentication-manager>
		<security:authentication-provider>

			<security:jdbc-user-service
				data-source-ref="dataSource"
				users-by-username-query="select user_id username, pass password, 1 as enabled from tbluser where user_id = ?"
				authorities-by-username-query="select user_id username, 'ROLE_USER' authority from tbluser where user_id = ?" />

		</security:authentication-provider>
	</security:authentication-manager>
</beans>

Controller

package com.iot.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class LoginController {

	@RequestMapping(value = "/login.do", method = RequestMethod.GET)
	public String login(ModelMap modelMap) throws Exception {
		return "/login";
	}

	@RequestMapping(value = "/loginfailed.do", method = RequestMethod.GET)
	public String loginfailed(ModelMap modelMap) throws Exception {
		return "/loginfailed";
	}
	
	@RequestMapping(value = "/logout.do", method = RequestMethod.GET)
	public String logout(ModelMap modelMap) throws Exception {
		return "/logout";
	}
}

WEB-INF\jsp\login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Page</title>
<style>
.errorblock {
	color: #ff0000;
	background-color: #ffEEEE;
	border: 3px solid #ff0000;
	padding: 8px;
	margin: 16px;
}
</style>
</head>
<body onload='document.f.j_username.focus();'>
	<h3>Login with Username and Password (Custom Page)</h3>
 
	<c:if test="${not empty error}">
		<div class="errorblock">
			Your login attempt was not successful, try again.<br /> Caused :
			${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message}
		</div>
	</c:if>
 
	<form name='f' action="<c:url value='j_spring_security_check' />"
		method='POST'>
 
		<table>
			<tr>
				<td>사용자ID:</td>
				<td><input type='text' name='j_username' value=''>
				</td>
			</tr>
			<tr>
				<td>암호:</td>
				<td><input type='password' name='j_password' />
				</td>
			</tr>
			<tr>
				<td colspan='2'><input name="submit" type="submit"
					value="submit" />
				</td>
			</tr>
			<tr>
				<td colspan='2'><input name="reset" type="reset" />
				</td>
			</tr>
		</table>
 
	</form>
</body>
</html>

AuthenticationToken 확장

출처 : Syaku (샤쿠) | 스프링 시큐리티 커스텀 로그인 : Spring Security

IotAuthenticationToken.java

package com.iot.handler;

import java.util.Collection;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;

import com.iot.domain.UserInfo;

public class IotAuthenticationToken extends UsernamePasswordAuthenticationToken {

	// ----------------------------------- PRIVATE ATTRIBUTES
	private UserInfo userInfo = null;
	private String login_type;
	
	// ----------------------------------- CONSTRUCTOR
	public IotAuthenticationToken(
	    Object principal, 
	    Object credentials, 
	    Collection<? extends GrantedAuthority> authorities, 
	    UserInfo userInfo, 
	    String login_type
	) {
		super(principal, credentials, authorities);
		this.userInfo = userInfo;
		this.login_type = login_type;
	}

	// ----------------------------------- GET/SET TERS
	public UserInfo getUserInfo() {
		return userInfo;
	}

	public void setUserInfo(UserInfo userInfo) {
		this.userInfo = userInfo;
	}

	public String getLogin_type() {
		return login_type;
	}

	public void setLogin_type(String login_type) {
		this.login_type = login_type;
	}
}

IotAuthenticationProvider.java

package com.iot.handler;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import com.iot.domain.UserInfo;
import com.iot.service.UserInfoService;

@Component
public class IotAuthenticationProvider implements AuthenticationProvider {
	
	@Autowired
	private UserInfoService service;

	@Autowired
	private HttpSession session;

	// ---------------------------------- PUBLIC METHODS
	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		
		String username = authentication.getName();
		String password = (String) authentication.getCredentials();
		UserInfo userInfo = null;
		Collection<? extends GrantedAuthority> authorities;
		
		try {
			IotAuthDets authDetails = (IotAuthDets) authentication.getDetails();
			userInfo = service.selectUserInfo(username);

			if(userInfo!=null && userInfo.getDelete_yn().equals("Y")){
				throw new UsernameNotFoundException("User details not found with this username: " + username);
			}
			if (userInfo == null) {
				throw new UsernameNotFoundException("User details not found with this username: " + username);
			}

			if (!password.equals(userInfo.getPassword())) {
				throw new BadCredentialsException("비밀번호가 일치하지 않습니다.");
			}
			
			authorities = getAuthorities(userInfo.getAuthority());
			userInfo.setAuthorities(authorities);

			return new CMXAuthenticationToken(
					(authDetails.isSublogin() ? "sub," + userInfo.getUser_id() + "@" + userInfo.getKira_user() : userInfo.getUser_id()), 
					authentication.getCredentials(), 
					authorities, 
					userInfo,
					authDetails.getLoginType()
			);
			
		} catch (UsernameNotFoundException e) {
			throw new UsernameNotFoundException(e.getMessage());
		} catch (BadCredentialsException e) {
			throw new BadCredentialsException(e.getMessage());
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}
	
	private List<GrantedAuthority> getAuthorities(String role) {
		List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
		authList.add(new SimpleGrantedAuthority("ROLE_USER"));
		
		if (role != null && role.trim().length() > 0) {
			if (role.equals("A")) {
				authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
			} else if (role.equals("S")) {
				authList.add(new SimpleGrantedAuthority("ROLE_MBER_MANAGER"));
			}
		}
		
		return authList;
	}

	@Override
	public boolean supports(Class<? extends Object> authentication) {
		return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication) && authentication.equals(UsernamePasswordAuthenticationToken.class);
	}
}

iot-security.xml

	<bean id="iotAuthenticationProvider" class="com.iot.handler.IotAuthenticationProvider"/>
	<security:authentication-manager alias="authenticationManager">
		<security:authentication-provider ref="iotAuthenticationProvider" />
	</security:authentication-manager>

JSP에서 로그인 정보 조회

출처 : Spring Security에서 화면에 사용자 정보, 권한에 따른 동적 메뉴 화면 구성 및 로그아웃 구성하기

<%@ page import="org.springframework.security.core.context.SecurityContextHolder"%> 
<%@ page import="org.springframework.security.core.Authentication"%>
<%@ page import="com.iot.handler.IotAuthenticationToken"%>
<%@ page import="com.iot.domain.UserInfo"%>

<%
Authentication auth = (Authentication)request.getUserPrincipal();
IotAuthenticationToken iotAuth = null;
if (auth!=null && auth instanceof IotAuthenticationToken) {
	iotAuth = (IotAuthenticationToken)auth;
}

// <sec:authentication property="userInfo" />
// <sec:authentication property="userInfo.email" />
System.out.println("user_info = " + iotAuth.getUserInfo());

// <sec:authentication property="login_type"/>
System.out.println("login_type = " + iotAuth.getLogin_type());
%>

<c:set> security값 설정

출처 : How to set value from<security:authentication/> to the parameter with <c:set>

<c:set var="login_type"><sec:authentication property="login_type"/></c:set>

로그인 타입 : ${login_type}

<c:if test="${login_type == 'LOGIN_TYPE_DAUM' || login_type == 'LOGIN_TYPE_DAUM'}">
	다음로그인
</c:if>

-

-

-

-

-

-

-->
728x90
728x90

출처 : Spring 3 MVC: Tiles Plugin Tutorial with Example in Eclipse

WEB-INF\web.xml

	<context-param>
		<param-name>spring.profiles.active</param-name>
		<param-value>tiles3</param-value>
	</context-param>

WEB-INF\intel4-tiles.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	

	<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".html" />
		<property name="templateMode" value="HTML5" />
		<property name="cacheable" value="true" />
	</bean>
	
	<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
		<property name="templateResolver" ref="templateResolver" />
	</bean>
	<bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
		<property name="templateEngine" ref="templateEngine" />
		<property name="order" value="1" />
		<property name="viewNames" value="thymeleaf/*" />
	</bean>

	<!-- Resolves view names to Tiles definitions -->
	<beans profile="tiles3">
		<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
			<property name="order" value="0"/>
		</bean>
	
		<!-- Configures Tiles 3-->
		<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
			<property name="definitions">
				<list>
					<value>/WEB-INF/jsp/tiles/tiles.xml</value>
					<!-- 
					<value>/WEB-INF/jsp/service/tiles.xml</value>
					<value>/WEB-INF/jsp/spiderview/tiles.xml</value>
					<value>/WEB-INF/jsp/spiderlive/tiles.xml</value>
					<value>/WEB-INF/jsp/customer/tiles.xml</value>
					<value>/WEB-INF/jsp/news/tiles.xml</value>
					<value>/WEB-INF/jsp/recruit/tiles.xml</value>
					<value>/WEB-INF/jsp/company/tiles.xml</value>
					<value>/WEB-INF/jsp/admin/tiles.xml</value>
					 -->
				</list>
			</property>
		</bean>
	</beans>

</beans>

WEB-INF\jsp\tiles\tiles.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC 
	"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">	

<tiles-definitions>
	
	<definition name="/*.blank" template="/WEB-INF/jsp/common/layout/blankLayout.jsp">
		<put-attribute name="content"	value="/WEB-INF/jsp/admin/{1}.jsp"/>
	</definition> 
	
	<definition name="/*" template="/WEB-INF/jsp/tiles/web_layout.jsp">
		<put-attribute name="header" value="/WEB-INF/jsp/tiles/web_header.jsp" />
		<put-attribute name="main" value="/WEB-INF/jsp/{1}.jsp" />
		<put-attribute name="footer" value="/WEB-INF/jsp/tiles/web_footer.jsp" />	
	</definition>
	
</tiles-definitions>

WEB-INF\jsp\tiles\web_layout.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>

<!DOCTYPE HTML>
<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0 minimal-ui"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black">
</head>

<body>

	<!-- head -->
	<tiles:insertAttribute name="header" />
	
	<!-- content -->
	<tiles:insertAttribute name="main" />

	<!-- footer -->
	<tiles:insertAttribute name="footer" />
	
</body>
</html>
728x90
728x90

pagination.js 파일

// 페이지 생성 함수
// 인자1 : JQuery 객체 - 페이지 정보를 출력될 객체
// 인자2 : 전체 페이지수
// 인자3 : 현재 페이지수
// 인자4 : 페이지 호출시 호출할 함수
function genPageNum(id_pagenum, totalPage, curPage, event) {
	
	// 블럭에 표시 페이지수
	var block_size = 10;
	
	// 초기화
	id_pagenum.empty();
	
	// 현재 블럭
	var block = Math.floor((curPage-1) / block_size);
	
	// 현재 블럭의 시작 페이지
	var block_start_pagenum = 10 * block;
	
	// 현재 블럭에서 마지막 페이지 
	var loop_count = block_size;

	// 현재 블럭에서 마지막 페이지 구하기
	if (block == Math.floor(totalPage / block_size) && (totalPage % block_size) > 0)  {
		loop_count = totalPage % block_size;
	}
	
	// 이전블럭 표시 (curPage > 10 이상이면 표시)
	if (curPage > block_size) {
		id_pagenum.append(
				"[<b><a href='javascript:listDevice("+
				(block * block_size) +
				", last_device_type);'>Prev</a></b>]");
	}
	
	// 페이지 수 만큼 반복
	for (pagenum = 1; pagenum <= loop_count; pagenum++) {
		// 현재 페이지 처리
		if ((pagenum + (block * block_size)) == curPage) {
			id_pagenum.append(
					"<b><font color=\"red\">"+(pagenum + (block * block_size))+"</font></b>");
		}
		// 현재 페이지 외 처리
		else {
			id_pagenum.append(
					"[<b><a href='javascript:pagination__page_move("+
					(pagenum + (block * block_size)) +
					"," + event+ ");'>"+
					(pagenum + (block * block_size)) +
					"</a></b>]");
		}
	}
	
	// 다음블럭 처리
	if (block < Math.floor(totalPage / block_size)) {
		id_pagenum.append(
				"[<b><a href='javascript:pagination__page_move("+
				(1 + ((block+1) * block_size)) +
				"," + event+ ");'>Next</a></b>]");
	}
}

// 페이지 선택시 호출 되는 함수
function pagination__page_move(pagenum, event) {
	if (event!=undefined) {
		event(pagenum);
	}
}

인자4에 전달될 함수 예제

function stock_page_move(pagenum) {
	listDevice(pagenum, last_device_type);
}

페이지 자동 생성 함수 호출

genPageNum($('#pagenum', currentDoc), result.totalPage, result.CurPage, stock_page_move);
728x90

+ Recent posts