Raspberry Pi IO Interface Module Test
라즈베리파이와 연결해 외부 센서에서 데이터를 읽어오고 제어 신호를 GPIO로 출력합니다. 예전에 만든 IO 보드를 확장했습니다. Module에 기능과 Specification에 대한 자세한 설명은 링크를 참고하세요. 적당한 수준에서만 정보를 올립니다.
Technical Specification
- 라즈베리파이 연결: 40 pin 플랫 케이블
- 보드 전원: DC 12V, DC 5V 출력이 필요할 경우 DC 12V 전원 어댑터 연결
- 할당 가능한 GPIO 포트 26 Pin 전체 할당
- SPI(Serial Peropheral Interface) 예비 포트 추가 CE1 제어신호
- SPI CE0는 MCP3208 8ch 12Bit ADC(Analog to Digital Converter) 사용
- I2C 포트 4포트 확장 병렬연결
- UART 포트가 1port
- Actuator 제어용 5V 출력 4 port
- Actuator 제어용 12V 출력 4 port
- PCB 사이즈: 85mm * 88mm
- 커넥터 사이즈 Molex 5267(PCB)-커넥터 5264 타입
- ADC(Analog to Digital) port 8 포트로 확장(MCP3208, SPI 인터페이스)
- ADC 커넥터 연결 번호, GPIO 센서 입출력 번호, 액츄에이터 제어 출력 커넥터 번호를 GPIO 번호로 통일
보드의 장점은 보드의 커넥터와 출력 핀 넘버가 직관적이라는 사실이다. 아래 이미지를 보면 ADC0~ADC7 까지는 ADC 채널을 의미하고, 커넥터 번호는 BCM 번호(라즈베리파이 정식 핀 번호)를 의미한다. 파이선을 이용해 코딩할 때는 즉시 번호를 사용하여 제어하고, C 언어를 사용할 때는 $gpio readall 명령을 사용해 BCM 번호를 찾아 wiringPi 핀 번호를 찾아 코딩하면 된다.
테스트는 모든 포트를 테스트하지 않고 ADC, I2C, GPIO IO, 출력 포트 중 각각 1개만 테스트합니다. 소스 코드는 C언어로 구현하였고, 파이선 코드는 추가할 예정입니다. 소스코드에서 중요한 부분만 설명하고 결과를 첨부합니다. 소스코드를 카피하면 줄 바꿈 없이 카피되는 문제는 어떻게 고치고 있는 건지, 티스토리는 조속히 해결해 주세요.
I2C는 SSD1306 OLED 납땜을 하면 테스트합니다. 모두 연결했습니다. 우선 아래와 같은 명령으로 i2c-tools 패키지를 설치합니다. 설치 중 오류가 나면 당연히 $sudo apt-get update 명령어를 실행합니다.
$sudo apt-get install i2c-tools
$lsmod | grep i2c 명령으로 아래와 같이 커널 모듈 리스트를 확인합니다.
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ lsmod | grep i2c
i2c_bcm2708 4770 0
i2c_dev 5859 0
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $
$i2cdetect -y 1 명령어로 연결한 i2c 디바이스를 확인합니다. 위 과정을 순서대로 따라한 내용을 아래에 나타냅니다.
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ sudo apt-get install i2c-tools
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
libi2c-dev python-smbus
The following NEW packages will be installed:
i2c-tools
0 upgraded, 1 newly installed, 0 to remove and 475 not upgraded.
Need to get 51.3 kB of archives.
After this operation, 227 kB of additional disk space will be used.
Get:1 http://archive.raspberrypi.org/debian/ jessie/main i2c-tools armhf 3.1.1+svn-2 [51.3 kB]
Fetched 51.3 kB in 1s (45.1 kB/s)
Selecting previously unselected package i2c-tools.
(Reading database ... 127269 files and directories currently installed.)
Preparing to unpack .../i2c-tools_3.1.1+svn-2_armhf.deb ...
Unpacking i2c-tools (3.1.1+svn-2) ...
Processing triggers for man-db (2.7.0.2-5) ...
Setting up i2c-tools (3.1.1+svn-2) ...
/run/udev or .udevdb or .udev presence implies active udev. Aborting MAKEDEV invocation.
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ lsmod | grep i2c
i2c_bcm2708 4770 0
i2c_dev 5859 0
C언어로 작성된 OLED 구동 코드는 위에 설치한 ssd1306_i2c 디렉터리에 포함이 되어 있으니 참고하시기 바랍니다. 세밀하고 자세한 라즈베리파이 OLED 구동 설명을 참고하십시오.
이제부터는 파이선 코드를 설치하여 실습해보겠습니다.
아래와 같은 명령어를 사용하여 필요한 패키지를 설치합니다. 설치했다고도 나오고 설치하지 않는 패키지는 알아서 설치합니다.
sudo apt install -y python3-dev
sudo apt install -y python-smbus i2c-tools
sudo apt install -y python3-pil
sudo apt install -y python3-pip
sudo apt install -y python3-setuptools
sudo apt install -y python3-rpi.gpio
위 명령어를 실행하여 설치하는 과정을 아래에 나타냅니다. 마지막 i2c 주소를 나타내는 부분까지 하십시오.
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ python -V
Python 2.7.9
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ python3 -V
Python 3.4.2
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ sudo apt install -y python3-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
python3-dev is already the newest version.
python3-dev set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 475 not upgraded.
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ sudo apt install -y python-smbus i2c-tools
Reading package lists... Done
Building dependency tree
Reading state information... Done
i2c-tools is already the newest version.
The following NEW packages will be installed:
python-smbus
0 upgraded, 1 newly installed, 0 to remove and 475 not upgraded.
Need to get 9,462 B of archives.
After this operation, 58.4 kB of additional disk space will be used.
Get:1 http://archive.raspberrypi.org/debian/ jessie/main python-smbus armhf 3.1.1+svn-2 [9,462 B]
Fetched 9,462 B in 0s (15.6 kB/s)
Selecting previously unselected package python-smbus.
(Reading database ... 127286 files and directories currently installed.)
Preparing to unpack .../python-smbus_3.1.1+svn-2_armhf.deb ...
Unpacking python-smbus (3.1.1+svn-2) ...
Setting up python-smbus (3.1.1+svn-2) ...
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ sudo apt install -y python3-pil
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
python-pil-doc python3-pil-dbg
The following packages will be upgraded:
python3-pil
1 upgraded, 0 newly installed, 0 to remove and 474 not upgraded.
Need to get 0 B/279 kB of archives.
After this operation, 1,024 B of additional disk space will be used.
Reading changelogs... Done
(Reading database ... 127292 files and directories currently installed.)
Preparing to unpack .../python3-pil_2.6.1-2+deb8u4_armhf.deb ...
Unpacking python3-pil:armhf (2.6.1-2+deb8u4) over (2.6.1-2+deb8u2) ...
Setting up python3-pil:armhf (2.6.1-2+deb8u4) ...
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ sudo apt install -y python3-pip
Reading package lists... Done
Building dependency tree
Reading state information... Done
python3-pip is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 474 not upgraded.
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ sudo apt install -y python3-setuptools
Reading package lists... Done
Building dependency tree
Reading state information... Done
python3-setuptools is already the newest version.
python3-setuptools set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 474 not upgraded.
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ sudo apt install -y python3-rpi.gpio
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be upgraded:
python3-rpi.gpio
1 upgraded, 0 newly installed, 0 to remove and 473 not upgraded.
Need to get 0 B/28.2 kB of archives.
After this operation, 0 B of additional disk space will be used.
Reading changelogs... Done
(Reading database ... 127292 files and directories currently installed.)
Preparing to unpack .../python3-rpi.gpio_0.6.3~jessie-1_armhf.deb ...
Unpacking python3-rpi.gpio (0.6.3~jessie-1) over (0.6.2~jessie-1) ...
Setting up python3-rpi.gpio (0.6.3~jessie-1) ...
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi:~/all_sensortest/ssd1306_i2c $
Adafruit git 저장소의 코드를 카피하기 위해 Git 라이브러리를 설치합니다. 이후로 에러 나면서 진행이 안되므로 여기서 출입니다. 다른 포스팅으로 나중에 다시 실행하겠습니다.
GPIO Input, Output Test Code 테스트 코드 - 디지털 출력을 검사한다. wiringPi.h 파일을 인클루드하고 사용할 핀을 지정해 준다.
#define LIGHTSEN_OUT 2 이런 식으로.
메인루프 들어가서 PinMode 명령으로 INPUT을 지정해준다.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>
// Use GPIO Pin 17, which is Pin 0 for wiringPi library
#define LIGHTSEN_OUT 2 //gpio27
int main(void)
{
// sets up the wiringPi library
if (wiringPiSetup () < 0)
{
fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno));
return 1;
}
pinMode(LIGHTSEN_OUT, INPUT);
// display counter value every second.
while ( 1 )
{
//printf( "%d\n", eventCounter );
//eventCounter = 0;
if(digitalRead(LIGHTSEN_OUT) == 0)
printf("light full ! \n");
if(digitalRead(LIGHTSEN_OUT) == 1)
printf("dark \n");
delay( 200 ); // wait 1 second
}
return 0;
}
결과는
pi@raspberrypi:~/all_sensortest $ sudo ./lightdetect
light full !
light full !
light full !
light full !
dark
dark
dark
dark
SPI 포트 CE0는 ADC3208과 연동합니다. 아날로그 출력이 나옵니다.
소스코드는 아래와 같고 8ch ADC 값은 main 함수에서
unsigned char adcChannel_light = 0번 부터 7번 까지 지정해주면 ADC 값을 모두 읽을 수 있습니다.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <wiringPi.h>
#include <wiringPiSPI.h>
#define CS_MCP3208 8 //GPIO 8
#define SPI_CHANNEL 0
#define SPI_SPEED 1000000 //1Mhz
// spi communication with Rpi and get sensor data
int read_mcp3208_adc(unsigned char adcChannel)
{
unsigned char buff[3];
int adcValue = 0;
buff[0] = 0x06 | ((adcChannel & 0x07) >> 2);
buff[1] = ((adcChannel & 0x07) << 6);
buff[2] = 0x00;
digitalWrite(CS_MCP3208, 0);
wiringPiSPIDataRW(SPI_CHANNEL, buff, 3);
buff[1] = 0x0f & buff[1];
adcValue = (buff[1] << 8 ) | buff[2];
digitalWrite(CS_MCP3208, 1);
return adcValue;
}
int main(void) {
unsigned char adcChannel_light = 0;
int adcValue_light = 0;
float vout_light;
float vout_oftemp;
float percentrh = 0;
float supsiondo = 0;
printf("start");
if(wiringPiSetupGpio() == -1)
{
fprintf(stdout, "Unable to start wiringPi :%s\n", strerror(errno));
return 1;
}
if(wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1)
{
fprintf(stdout, "wiringPiSPISetup Failed :%s\n", strerror(errno));
return 1;
}
pinMode(CS_MCP3208, OUTPUT);
while(1)
{
adcValue_light = read_mcp3208_adc(adcChannel_light);
//printf("Humiity = %u temparature = %u\n", adcValue_humi, adcValue_temp);
printf("light sensor = %u\n", adcValue_light);
delay(100);
}
return 0;
}
결과는
pi@raspberrypi:~/all_sensortest $ sudo ./getlightsensor
startlight sensor = 108
light sensor = 107
light sensor = 107
light sensor = 3962
light sensor = 3966
light sensor = 3954
light sensor = 3962
light sensor = 3963
light sensor = 3963
light sensor = 3964
다음은 Serial Port 테스트인데 Serial to USB 보드 어떤 것이나 상관없습니다. 우선
$sudo raspi-config 명령으로 Seral port를 사용한다고 설정해야 합니다. 아래는 cp210x 계열인 CP2102 Micro USB to TTL 컨버터 모듈을 보여줍니다.
USB to Serial 보드의 RX를 IO Interface 보드 TX, TX -> RX로 엇갈리게 연결해야 합니다. 당연하지 않은가요? rx와 tx를 엇갈려야 양쪽이 정확히 데이터를 주고받게 됩니다.
USB를 컴퓨터에 연결하고 Putty를 실행하여 아래와 같이 설정합니다. Buadrate를 의미하는 Speed를 115200으로 설정함을 잊지 마세요. 컴퓨터의 COM 포트 번호는 제어판 > 시스템 > 장치관리자 > 포트에서 확인할 수 있다. 연결하고 라즈베리파이를 재부팅하면 부팅 메시지가 Putty 화면에 나오는 것을 확인할 수 있습니다.
마지막으로 액츄에이터 포트를 점검합니다. 아래 코드를 실행하면 J20, J19 커넥터에 연결된 LED에 불이 잘 들어옴을 확인합니다. 놀러 나간다. 놀이라고 해봤자 술 마시는 일뿐이 없다.
#include <signal.h> //Signal 사용 헤더파일
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h> //exit() 사용 헤더파일
#include <wiringPi.h>
#define FAN 24 // BCM_GPIO 6
void sig_handler(int signo); // 마지막 종료 함수
int main (void)
{
signal(SIGINT, (void *)sig_handler); //시그널 핸들러 함수
if (wiringPiSetup () == -1)
{
fprintf(stdout, "Unable to start wiringPi: %s\n", strerror(errno));
return 1 ;
}
pinMode (FAN, OUTPUT) ;
for (;;)
{
//printf("here - FAN on\n");
digitalWrite (FAN, 1) ; // On
delay(1000);
digitalWrite(FAN, 0);
delay(1000);
}
return 0 ;
}
void sig_handler(int signo)
{
printf("process stop\n");
digitalWrite (FAN, 0) ; // Off
exit(0);
}
여기까지 전부 테스트 했다. 언젠가 끝나겠지. 결국 파국으로 말이다. 이 시간도 결국 다 지나겠지.
'개발자 > 라즈베리파이4' 카테고리의 다른 글
라즈베리파이 spi & i2c 동시에 사용 문제? (0) | 2021.01.15 |
---|---|
10가지 Raspberry Pi 프로젝트 아이디어 (0) | 2021.01.13 |
라즈베리파이 ubidots 데이터 송신 (0) | 2021.01.12 |
Raspberry Pi와 인터페이싱 MPU6050 (가속도계 + 자이로 스코프) (4) | 2020.11.30 |
useradd 명령어로 리눅스 사용자 추가하기 (0) | 2020.11.25 |
Raspberry Pi와 인터페이싱하는 GPS 모듈 (4) | 2020.11.24 |
PCB 제작할 때 정해야 할 부분 RaspberryPi IO Interface Module (0) | 2020.11.20 |
라즈베리파이 OS 정보와 CPU 정보 확인 (0) | 2020.11.18 |
더욱 좋은 정보를 제공하겠습니다.~ ^^